├── .gitignore
├── LICENSE
├── README.md
├── repo
└── screenshot.png
└── src
├── Dependencies
├── include
│ ├── ImGui
│ │ ├── imconfig.h
│ │ ├── imgui.h
│ │ ├── imgui_impl_opengl3.cpp
│ │ ├── imgui_impl_opengl3.h
│ │ ├── imgui_impl_opengl3_loader.h
│ │ ├── imgui_impl_win32.cpp
│ │ ├── imgui_impl_win32.h
│ │ ├── imgui_internal.h
│ │ ├── imgui_stdlib.h
│ │ ├── imstb_rectpack.h
│ │ ├── imstb_textedit.h
│ │ └── imstb_truetype.h
│ └── MinHook.h
└── lib
│ ├── imgui.lib
│ └── libMinHook-x64.lib
├── GUI.cpp
├── GUI.h
├── Hook.cpp
├── Hook.h
├── OpenGL-Hk.sln
├── OpenGL-Hk.vcxproj
├── OpenGL-Hk.vcxproj.filters
└── main.cpp
/.gitignore:
--------------------------------------------------------------------------------
1 | x64/
2 | build/
3 | .vs/
4 |
5 | OpenGL-Hk.vcxproj.user
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 aXXo-dev
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OpenGL-Hk
2 |
3 | ## What is this?
4 |
5 | A proof of concept (POC) OpenGL hook I made because many people came to me for question regarding a video I had released
6 | on YouTube about it.
7 |
8 | 
9 |
10 | ## How does it work?
11 |
12 | It works by hooking the `wglSwapBuffers` function from OpenGL's library exports.
13 |
14 | DISCLAMER: Trying to compile this project for 32-bit using the included libraries will not work. Though the process of hooking OpenGL remains the same.
15 |
--------------------------------------------------------------------------------
/repo/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/axxo1337/OpenGL-Hk/59d2efbd57360023d58b9ce663d5cf64887c236f/repo/screenshot.png
--------------------------------------------------------------------------------
/src/Dependencies/include/ImGui/imconfig.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------------------------
2 | // DEAR IMGUI COMPILE-TIME OPTIONS
3 | // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
4 | // You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
5 | //-----------------------------------------------------------------------------
6 | // 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)
7 | // 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.
8 | //-----------------------------------------------------------------------------
9 | // You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
10 | // files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
11 | // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
12 | // Call IMGUI_CHECKVERSION() from your .cpp file to verify that the data structures your files are using are matching the ones imgui.cpp is using.
13 | //-----------------------------------------------------------------------------
14 |
15 | #pragma once
16 |
17 | //---- Define assertion handler. Defaults to calling assert().
18 | // 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.
19 | //#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
20 | //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
21 |
22 | //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
23 | // 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.
24 | // DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
25 | // for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
26 | //#define IMGUI_API __declspec( dllexport )
27 | //#define IMGUI_API __declspec( dllimport )
28 |
29 | //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
30 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
31 | //#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87+ disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This is automatically done by IMGUI_DISABLE_OBSOLETE_FUNCTIONS.
32 |
33 | //---- Disable all of Dear ImGui or don't implement standard windows/tools.
34 | // It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
35 | //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
36 | //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
37 | //#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty.
38 |
39 | //---- Don't implement some functions to reduce linkage requirements.
40 | //#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)
41 | //#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)
42 | //#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)
43 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
44 | //#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).
45 | //#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)
46 | //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
47 | //#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
48 | //#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.
49 | //#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().
50 | //#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
51 |
52 | //---- Include imgui_user.h at the end of imgui.h as a convenience
53 | //#define IMGUI_INCLUDE_IMGUI_USER_H
54 |
55 | //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
56 | //#define IMGUI_USE_BGRA_PACKED_COLOR
57 |
58 | //---- 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...)
59 | //#define IMGUI_USE_WCHAR32
60 |
61 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
62 | // By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
63 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
64 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
65 | //#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined.
66 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
67 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
68 | //#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined.
69 |
70 | //---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
71 | // 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.h.
72 | //#define IMGUI_USE_STB_SPRINTF
73 |
74 | //---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
75 | // 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).
76 | // On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
77 | //#define IMGUI_ENABLE_FREETYPE
78 |
79 | //---- Use FreeType+lunasvg library to render OpenType SVG fonts (SVGinOT)
80 | // Requires lunasvg headers to be available in the include path + program to be linked with the lunasvg library (not provided).
81 | // Only works in combination with IMGUI_ENABLE_FREETYPE.
82 | // (implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
83 | //#define IMGUI_ENABLE_FREETYPE_LUNASVG
84 |
85 | //---- Use stb_truetype to build and rasterize the font atlas (default)
86 | // The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
87 | //#define IMGUI_ENABLE_STB_TRUETYPE
88 |
89 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
90 | // This will be inlined as part of ImVec2 and ImVec4 class declarations.
91 | /*
92 | #define IM_VEC2_CLASS_EXTRA \
93 | constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
94 | operator MyVec2() const { return MyVec2(x,y); }
95 |
96 | #define IM_VEC4_CLASS_EXTRA \
97 | constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
98 | operator MyVec4() const { return MyVec4(x,y,z,w); }
99 | */
100 | //---- ...Or use Dear ImGui's own very basic math operators.
101 | //#define IMGUI_DEFINE_MATH_OPERATORS
102 |
103 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
104 | // Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
105 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
106 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
107 | //#define ImDrawIdx unsigned int
108 |
109 | //---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
110 | //struct ImDrawList;
111 | //struct ImDrawCmd;
112 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
113 | //#define ImDrawCallback MyImDrawCallback
114 |
115 | //---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase)
116 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
117 | //#define IM_DEBUG_BREAK IM_ASSERT(0)
118 | //#define IM_DEBUG_BREAK __debugbreak()
119 |
120 | //---- Debug Tools: Enable slower asserts
121 | //#define IMGUI_DEBUG_PARANOID
122 |
123 | //---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files)
124 | /*
125 | namespace ImGui
126 | {
127 | void MyFunction(const char* name, MyMatrix44* mtx);
128 | }
129 | */
130 |
--------------------------------------------------------------------------------
/src/Dependencies/include/ImGui/imgui_impl_opengl3.cpp:
--------------------------------------------------------------------------------
1 | // dear imgui: Renderer Backend for modern OpenGL with shaders / programmatic pipeline
2 | // - Desktop GL: 2.x 3.x 4.x
3 | // - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
4 | // This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
5 |
6 | // Implemented features:
7 | // [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
8 | // [x] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only).
9 |
10 | // About WebGL/ES:
11 | // - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
12 | // - This is done automatically on iOS, Android and Emscripten targets.
13 | // - For other targets, the define needs to be visible from the imgui_impl_opengl3.cpp compilation unit. If unsure, define globally or in imconfig.h.
14 |
15 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
16 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
17 | // Learn about Dear ImGui:
18 | // - FAQ https://dearimgui.com/faq
19 | // - Getting Started https://dearimgui.com/getting-started
20 | // - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
21 | // - Introduction, links and more at the top of imgui.cpp
22 |
23 | // CHANGELOG
24 | // (minor and older changes stripped away, please see git history for details)
25 | // 2024-01-09: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" and variants, fixing regression on distros missing a symlink.
26 | // 2023-11-08: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" instead of "libGL.so.1", accommodating for NetBSD systems having only "libGL.so.3" available. (#6983)
27 | // 2023-10-05: OpenGL: Rename symbols in our internal loader so that LTO compilation with another copy of gl3w is possible. (#6875, #6668, #4445)
28 | // 2023-06-20: OpenGL: Fixed erroneous use glGetIntegerv(GL_CONTEXT_PROFILE_MASK) on contexts lower than 3.2. (#6539, #6333)
29 | // 2023-05-09: OpenGL: Support for glBindSampler() backup/restore on ES3. (#6375)
30 | // 2023-04-18: OpenGL: Restore front and back polygon mode separately when supported by context. (#6333)
31 | // 2023-03-23: OpenGL: Properly restoring "no shader program bound" if it was the case prior to running the rendering function. (#6267, #6220, #6224)
32 | // 2023-03-15: OpenGL: Fixed GL loader crash when GL_VERSION returns NULL. (#6154, #4445, #3530)
33 | // 2023-03-06: OpenGL: Fixed restoration of a potentially deleted OpenGL program, by calling glIsProgram(). (#6220, #6224)
34 | // 2022-11-09: OpenGL: Reverted use of glBufferSubData(), too many corruptions issues + old issues seemingly can't be reproed with Intel drivers nowadays (revert 2021-12-15 and 2022-05-23 changes).
35 | // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
36 | // 2022-09-27: OpenGL: Added ability to '#define IMGUI_IMPL_OPENGL_DEBUG'.
37 | // 2022-05-23: OpenGL: Reworking 2021-12-15 "Using buffer orphaning" so it only happens on Intel GPU, seems to cause problems otherwise. (#4468, #4825, #4832, #5127).
38 | // 2022-05-13: OpenGL: Fixed state corruption on OpenGL ES 2.0 due to not preserving GL_ELEMENT_ARRAY_BUFFER_BINDING and vertex attribute states.
39 | // 2021-12-15: OpenGL: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports with some Intel HD drivers.
40 | // 2021-08-23: OpenGL: Fixed ES 3.0 shader ("#version 300 es") use normal precision floats to avoid wobbly rendering at HD resolutions.
41 | // 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.
42 | // 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).
43 | // 2021-06-25: OpenGL: Use OES_vertex_array extension on Emscripten + backup/restore current state.
44 | // 2021-06-21: OpenGL: Destroy individual vertex/fragment shader objects right after they are linked into the main shader.
45 | // 2021-05-24: OpenGL: Access GL_CLIP_ORIGIN when "GL_ARB_clip_control" extension is detected, inside of just OpenGL 4.5 version.
46 | // 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
47 | // 2021-04-06: OpenGL: Don't try to read GL_CLIP_ORIGIN unless we're OpenGL 4.5 or greater.
48 | // 2021-02-18: OpenGL: Change blending equation to preserve alpha in output buffer.
49 | // 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state.
50 | // 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state.
51 | // 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)
52 | // 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.
53 | // 2020-07-10: OpenGL: Added support for glad2 OpenGL loader.
54 | // 2020-05-08: OpenGL: Made default GLSL version 150 (instead of 130) on OSX.
55 | // 2020-04-21: OpenGL: Fixed handling of glClipControl(GL_UPPER_LEFT) by inverting projection matrix.
56 | // 2020-04-12: OpenGL: Fixed context version check mistakenly testing for 4.0+ instead of 3.2+ to enable ImGuiBackendFlags_RendererHasVtxOffset.
57 | // 2020-03-24: OpenGL: Added support for glbinding 2.x OpenGL loader.
58 | // 2020-01-07: OpenGL: Added support for glbinding 3.x OpenGL loader.
59 | // 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.
60 | // 2019-09-22: OpenGL: Detect default GL loader using __has_include compiler facility.
61 | // 2019-09-16: OpenGL: Tweak initialization code to allow application calling ImGui_ImplOpenGL3_CreateFontsTexture() before the first NewFrame() call.
62 | // 2019-05-29: OpenGL: Desktop GL only: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
63 | // 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
64 | // 2019-03-29: OpenGL: Not calling glBindBuffer more than necessary in the render loop.
65 | // 2019-03-15: OpenGL: Added a GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early.
66 | // 2019-03-03: OpenGL: Fix support for ES 2.0 (WebGL 1.0).
67 | // 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.
68 | // 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
69 | // 2019-02-01: OpenGL: Using GLSL 410 shaders for any version over 410 (e.g. 430, 450).
70 | // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
71 | // 2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT) / GL_CLIP_ORIGIN.
72 | // 2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments indicative that any loader can be used.
73 | // 2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and Android. GLSL version default to "#version 300 ES".
74 | // 2018-07-30: OpenGL: Support for GLSL 300 ES and 410 core. Fixes for Emscripten compilation.
75 | // 2018-07-10: OpenGL: Support for more GLSL versions (based on the GLSL version string). Added error output when shaders fail to compile/link.
76 | // 2018-06-08: Misc: Extracted imgui_impl_opengl3.cpp/.h away from the old combined GLFW/SDL+OpenGL3 examples.
77 | // 2018-06-08: OpenGL: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
78 | // 2018-05-25: OpenGL: Removed unnecessary backup/restore of GL_ELEMENT_ARRAY_BUFFER_BINDING since this is part of the VAO state.
79 | // 2018-05-14: OpenGL: Making the call to glBindSampler() optional so 3.2 context won't fail if the function is a nullptr pointer.
80 | // 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".
81 | // 2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context.
82 | // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can call it yourself.
83 | // 2018-01-07: OpenGL: Changed GLSL shader version from 330 to 150.
84 | // 2017-09-01: OpenGL: Save and restore current bound sampler. Save and restore current polygon mode.
85 | // 2017-05-01: OpenGL: Fixed save and restore of current blend func state.
86 | // 2017-05-01: OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE.
87 | // 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle.
88 | // 2016-07-29: OpenGL: Explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752)
89 |
90 | //----------------------------------------
91 | // OpenGL GLSL GLSL
92 | // version version string
93 | //----------------------------------------
94 | // 2.0 110 "#version 110"
95 | // 2.1 120 "#version 120"
96 | // 3.0 130 "#version 130"
97 | // 3.1 140 "#version 140"
98 | // 3.2 150 "#version 150"
99 | // 3.3 330 "#version 330 core"
100 | // 4.0 400 "#version 400 core"
101 | // 4.1 410 "#version 410 core"
102 | // 4.2 420 "#version 410 core"
103 | // 4.3 430 "#version 430 core"
104 | // ES 2.0 100 "#version 100" = WebGL 1.0
105 | // ES 3.0 300 "#version 300 es" = WebGL 2.0
106 | //----------------------------------------
107 |
108 | #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
109 | #define _CRT_SECURE_NO_WARNINGS
110 | #endif
111 |
112 | #include "imgui.h"
113 | #ifndef IMGUI_DISABLE
114 | #include "imgui_impl_opengl3.h"
115 | #include
116 | #include // intptr_t
117 | #if defined(__APPLE__)
118 | #include
119 | #endif
120 |
121 | // Clang/GCC warnings with -Weverything
122 | #if defined(__clang__)
123 | #pragma clang diagnostic push
124 | #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
125 | #pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
126 | #pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used
127 | #pragma clang diagnostic ignored "-Wnonportable-system-include-path"
128 | #pragma clang diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
129 | #endif
130 | #if defined(__GNUC__)
131 | #pragma GCC diagnostic push
132 | #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
133 | #pragma GCC diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx'
134 | #pragma GCC diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
135 | #endif
136 |
137 | // GL includes
138 | #if defined(IMGUI_IMPL_OPENGL_ES2)
139 | #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV))
140 | #include // Use GL ES 2
141 | #else
142 | #include // Use GL ES 2
143 | #endif
144 | #if defined(__EMSCRIPTEN__)
145 | #ifndef GL_GLEXT_PROTOTYPES
146 | #define GL_GLEXT_PROTOTYPES
147 | #endif
148 | #include
149 | #endif
150 | #elif defined(IMGUI_IMPL_OPENGL_ES3)
151 | #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV))
152 | #include // Use GL ES 3
153 | #else
154 | #include // Use GL ES 3
155 | #endif
156 | #elif !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
157 | // Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
158 | // Helper libraries are often used for this purpose! Here we are using our own minimal custom loader based on gl3w.
159 | // In the rest of your app/engine, you can use another loader of your choice (gl3w, glew, glad, glbinding, glext, glLoadGen, etc.).
160 | // If you happen to be developing a new feature for this backend (imgui_impl_opengl3.cpp):
161 | // - You may need to regenerate imgui_impl_opengl3_loader.h to add new symbols. See https://github.com/dearimgui/gl3w_stripped
162 | // - You can temporarily use an unstripped version. See https://github.com/dearimgui/gl3w_stripped/releases
163 | // Changes to this backend using new APIs should be accompanied by a regenerated stripped loader version.
164 | #define IMGL3W_IMPL
165 | #include "imgui_impl_opengl3_loader.h"
166 | #endif
167 |
168 | // Vertex arrays are not supported on ES2/WebGL1 unless Emscripten which uses an extension
169 | #ifndef IMGUI_IMPL_OPENGL_ES2
170 | #define IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
171 | #elif defined(__EMSCRIPTEN__)
172 | #define IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
173 | #define glBindVertexArray glBindVertexArrayOES
174 | #define glGenVertexArrays glGenVertexArraysOES
175 | #define glDeleteVertexArrays glDeleteVertexArraysOES
176 | #define GL_VERTEX_ARRAY_BINDING GL_VERTEX_ARRAY_BINDING_OES
177 | #endif
178 |
179 | // Desktop GL 2.0+ has extension and glPolygonMode() which GL ES and WebGL don't have..
180 | #if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3)
181 | #define IMGUI_IMPL_OPENGL_HAS_EXTENSIONS // has glGetIntegerv(GL_NUM_EXTENSIONS)
182 | #define IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE // has glPolygonMode()
183 | #endif
184 |
185 | // Desktop GL 2.1+ and GL ES 3.0+ have glBindBuffer() with GL_PIXEL_UNPACK_BUFFER target.
186 | #if !defined(IMGUI_IMPL_OPENGL_ES2)
187 | #define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_BUFFER_PIXEL_UNPACK
188 | #endif
189 |
190 | // Desktop GL 3.1+ has GL_PRIMITIVE_RESTART state
191 | #if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_1)
192 | #define IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
193 | #endif
194 |
195 | // Desktop GL 3.2+ has glDrawElementsBaseVertex() which GL ES and WebGL don't have.
196 | #if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_2)
197 | #define IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
198 | #endif
199 |
200 | // Desktop GL 3.3+ and GL ES 3.0+ have glBindSampler()
201 | #if !defined(IMGUI_IMPL_OPENGL_ES2) && (defined(IMGUI_IMPL_OPENGL_ES3) || defined(GL_VERSION_3_3))
202 | #define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
203 | #endif
204 |
205 | // [Debugging]
206 | //#define IMGUI_IMPL_OPENGL_DEBUG
207 | #ifdef IMGUI_IMPL_OPENGL_DEBUG
208 | #include
209 | #define GL_CALL(_CALL) do { _CALL; GLenum gl_err = glGetError(); if (gl_err != 0) fprintf(stderr, "GL error 0x%x returned from '%s'.\n", gl_err, #_CALL); } while (0) // Call with error check
210 | #else
211 | #define GL_CALL(_CALL) _CALL // Call without error check
212 | #endif
213 |
214 | // OpenGL Data
215 | struct ImGui_ImplOpenGL3_Data
216 | {
217 | GLuint GlVersion; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2)
218 | char GlslVersionString[32]; // Specified by user or detected based on compile time GL settings.
219 | bool GlProfileIsES2;
220 | bool GlProfileIsES3;
221 | bool GlProfileIsCompat;
222 | GLint GlProfileMask;
223 | GLuint FontTexture;
224 | GLuint ShaderHandle;
225 | GLint AttribLocationTex; // Uniforms location
226 | GLint AttribLocationProjMtx;
227 | GLuint AttribLocationVtxPos; // Vertex attributes location
228 | GLuint AttribLocationVtxUV;
229 | GLuint AttribLocationVtxColor;
230 | unsigned int VboHandle, ElementsHandle;
231 | GLsizeiptr VertexBufferSize;
232 | GLsizeiptr IndexBufferSize;
233 | bool HasClipOrigin;
234 | bool UseBufferSubData;
235 |
236 | ImGui_ImplOpenGL3_Data() { memset((void*)this, 0, sizeof(*this)); }
237 | };
238 |
239 | // Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
240 | // It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
241 | static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_GetBackendData()
242 | {
243 | return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
244 | }
245 |
246 | // OpenGL vertex attribute state (for ES 1.0 and ES 2.0 only)
247 | #ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
248 | struct ImGui_ImplOpenGL3_VtxAttribState
249 | {
250 | GLint Enabled, Size, Type, Normalized, Stride;
251 | GLvoid* Ptr;
252 |
253 | void GetState(GLint index)
254 | {
255 | glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &Enabled);
256 | glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_SIZE, &Size);
257 | glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_TYPE, &Type);
258 | glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &Normalized);
259 | glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &Stride);
260 | glGetVertexAttribPointerv(index, GL_VERTEX_ATTRIB_ARRAY_POINTER, &Ptr);
261 | }
262 | void SetState(GLint index)
263 | {
264 | glVertexAttribPointer(index, Size, Type, (GLboolean)Normalized, Stride, Ptr);
265 | if (Enabled) glEnableVertexAttribArray(index); else glDisableVertexAttribArray(index);
266 | }
267 | };
268 | #endif
269 |
270 | // Functions
271 | bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
272 | {
273 | ImGuiIO& io = ImGui::GetIO();
274 | IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
275 |
276 | // Initialize our loader
277 | #if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
278 | if (imgl3wInit() != 0)
279 | {
280 | fprintf(stderr, "Failed to initialize OpenGL loader!\n");
281 | return false;
282 | }
283 | #endif
284 |
285 | // Setup backend capabilities flags
286 | ImGui_ImplOpenGL3_Data* bd = IM_NEW(ImGui_ImplOpenGL3_Data)();
287 | io.BackendRendererUserData = (void*)bd;
288 | io.BackendRendererName = "imgui_impl_opengl3";
289 |
290 | // Query for GL version (e.g. 320 for GL 3.2)
291 | #if defined(IMGUI_IMPL_OPENGL_ES2)
292 | // GLES 2
293 | bd->GlVersion = 200;
294 | bd->GlProfileIsES2 = true;
295 | #else
296 | // Desktop or GLES 3
297 | GLint major = 0;
298 | GLint minor = 0;
299 | glGetIntegerv(GL_MAJOR_VERSION, &major);
300 | glGetIntegerv(GL_MINOR_VERSION, &minor);
301 | if (major == 0 && minor == 0)
302 | {
303 | // Query GL_VERSION in desktop GL 2.x, the string will start with "."
304 | const char* gl_version = (const char*)glGetString(GL_VERSION);
305 | sscanf(gl_version, "%d.%d", &major, &minor);
306 | }
307 | bd->GlVersion = (GLuint)(major * 100 + minor * 10);
308 | #if defined(GL_CONTEXT_PROFILE_MASK)
309 | if (bd->GlVersion >= 320)
310 | glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &bd->GlProfileMask);
311 | bd->GlProfileIsCompat = (bd->GlProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0;
312 | #endif
313 |
314 | #if defined(IMGUI_IMPL_OPENGL_ES3)
315 | bd->GlProfileIsES3 = true;
316 | #endif
317 |
318 | bd->UseBufferSubData = false;
319 | /*
320 | // Query vendor to enable glBufferSubData kludge
321 | #ifdef _WIN32
322 | if (const char* vendor = (const char*)glGetString(GL_VENDOR))
323 | if (strncmp(vendor, "Intel", 5) == 0)
324 | bd->UseBufferSubData = true;
325 | #endif
326 | */
327 | #endif
328 |
329 | #ifdef IMGUI_IMPL_OPENGL_DEBUG
330 | printf("GlVersion = %d\nGlProfileIsCompat = %d\nGlProfileMask = 0x%X\nGlProfileIsES2 = %d, GlProfileIsES3 = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", bd->GlVersion, bd->GlProfileIsCompat, bd->GlProfileMask, bd->GlProfileIsES2, bd->GlProfileIsES3, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
331 | #endif
332 |
333 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
334 | if (bd->GlVersion >= 320)
335 | io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
336 | #endif
337 |
338 | // Store GLSL version string so we can refer to it later in case we recreate shaders.
339 | // Note: GLSL version is NOT the same as GL version. Leave this to nullptr if unsure.
340 | if (glsl_version == nullptr)
341 | {
342 | #if defined(IMGUI_IMPL_OPENGL_ES2)
343 | glsl_version = "#version 100";
344 | #elif defined(IMGUI_IMPL_OPENGL_ES3)
345 | glsl_version = "#version 300 es";
346 | #elif defined(__APPLE__)
347 | glsl_version = "#version 150";
348 | #else
349 | glsl_version = "#version 130";
350 | #endif
351 | }
352 | IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(bd->GlslVersionString));
353 | strcpy(bd->GlslVersionString, glsl_version);
354 | strcat(bd->GlslVersionString, "\n");
355 |
356 | // Make an arbitrary GL call (we don't actually need the result)
357 | // IF YOU GET A CRASH HERE: it probably means the OpenGL function loader didn't do its job. Let us know!
358 | GLint current_texture;
359 | glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);
360 |
361 | // Detect extensions we support
362 | bd->HasClipOrigin = (bd->GlVersion >= 450);
363 | #ifdef IMGUI_IMPL_OPENGL_HAS_EXTENSIONS
364 | GLint num_extensions = 0;
365 | glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
366 | for (GLint i = 0; i < num_extensions; i++)
367 | {
368 | const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, i);
369 | if (extension != nullptr && strcmp(extension, "GL_ARB_clip_control") == 0)
370 | bd->HasClipOrigin = true;
371 | }
372 | #endif
373 |
374 | return true;
375 | }
376 |
377 | void ImGui_ImplOpenGL3_Shutdown()
378 | {
379 | ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
380 | IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
381 | ImGuiIO& io = ImGui::GetIO();
382 |
383 | ImGui_ImplOpenGL3_DestroyDeviceObjects();
384 | io.BackendRendererName = nullptr;
385 | io.BackendRendererUserData = nullptr;
386 | io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
387 | IM_DELETE(bd);
388 | }
389 |
390 | void ImGui_ImplOpenGL3_NewFrame()
391 | {
392 | ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
393 | IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplOpenGL3_Init()?");
394 |
395 | if (!bd->ShaderHandle)
396 | ImGui_ImplOpenGL3_CreateDeviceObjects();
397 | }
398 |
399 | static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
400 | {
401 | ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
402 |
403 | // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
404 | glEnable(GL_BLEND);
405 | glBlendEquation(GL_FUNC_ADD);
406 | glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
407 | glDisable(GL_CULL_FACE);
408 | glDisable(GL_DEPTH_TEST);
409 | glDisable(GL_STENCIL_TEST);
410 | glEnable(GL_SCISSOR_TEST);
411 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
412 | if (bd->GlVersion >= 310)
413 | glDisable(GL_PRIMITIVE_RESTART);
414 | #endif
415 | #ifdef IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE
416 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
417 | #endif
418 |
419 | // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
420 | #if defined(GL_CLIP_ORIGIN)
421 | bool clip_origin_lower_left = true;
422 | if (bd->HasClipOrigin)
423 | {
424 | GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)¤t_clip_origin);
425 | if (current_clip_origin == GL_UPPER_LEFT)
426 | clip_origin_lower_left = false;
427 | }
428 | #endif
429 |
430 | // Setup viewport, orthographic projection matrix
431 | // 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.
432 | GL_CALL(glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
433 | float L = draw_data->DisplayPos.x;
434 | float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
435 | float T = draw_data->DisplayPos.y;
436 | float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
437 | #if defined(GL_CLIP_ORIGIN)
438 | if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left
439 | #endif
440 | const float ortho_projection[4][4] =
441 | {
442 | { 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
443 | { 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
444 | { 0.0f, 0.0f, -1.0f, 0.0f },
445 | { (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f },
446 | };
447 | glUseProgram(bd->ShaderHandle);
448 | glUniform1i(bd->AttribLocationTex, 0);
449 | glUniformMatrix4fv(bd->AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
450 |
451 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
452 | if (bd->GlVersion >= 330 || bd->GlProfileIsES3)
453 | glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 and GL ES 3.0 may set that otherwise.
454 | #endif
455 |
456 | (void)vertex_array_object;
457 | #ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
458 | glBindVertexArray(vertex_array_object);
459 | #endif
460 |
461 | // Bind vertex/index buffers and setup attributes for ImDrawVert
462 | GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, bd->VboHandle));
463 | GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bd->ElementsHandle));
464 | GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxPos));
465 | GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxUV));
466 | GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxColor));
467 | GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, pos)));
468 | GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, uv)));
469 | GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, col)));
470 | }
471 |
472 | // OpenGL3 Render function.
473 | // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly.
474 | // This is in order to be able to run within an OpenGL engine that doesn't do so.
475 | void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
476 | {
477 | // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
478 | int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
479 | int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
480 | if (fb_width <= 0 || fb_height <= 0)
481 | return;
482 |
483 | ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
484 |
485 | // Backup GL state
486 | GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture);
487 | glActiveTexture(GL_TEXTURE0);
488 | GLuint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_program);
489 | GLuint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&last_texture);
490 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
491 | GLuint last_sampler; if (bd->GlVersion >= 330 || bd->GlProfileIsES3) { glGetIntegerv(GL_SAMPLER_BINDING, (GLint*)&last_sampler); } else { last_sampler = 0; }
492 | #endif
493 | GLuint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer);
494 | #ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
495 | // This is part of VAO on OpenGL 3.0+ and OpenGL ES 3.0+.
496 | GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
497 | ImGui_ImplOpenGL3_VtxAttribState last_vtx_attrib_state_pos; last_vtx_attrib_state_pos.GetState(bd->AttribLocationVtxPos);
498 | ImGui_ImplOpenGL3_VtxAttribState last_vtx_attrib_state_uv; last_vtx_attrib_state_uv.GetState(bd->AttribLocationVtxUV);
499 | ImGui_ImplOpenGL3_VtxAttribState last_vtx_attrib_state_color; last_vtx_attrib_state_color.GetState(bd->AttribLocationVtxColor);
500 | #endif
501 | #ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
502 | GLuint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object);
503 | #endif
504 | #ifdef IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE
505 | GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
506 | #endif
507 | GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
508 | GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
509 | GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb);
510 | GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb);
511 | GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha);
512 | GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha);
513 | GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb);
514 | GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha);
515 | GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
516 | GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
517 | GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
518 | GLboolean last_enable_stencil_test = glIsEnabled(GL_STENCIL_TEST);
519 | GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
520 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
521 | GLboolean last_enable_primitive_restart = (bd->GlVersion >= 310) ? glIsEnabled(GL_PRIMITIVE_RESTART) : GL_FALSE;
522 | #endif
523 |
524 | // Setup desired GL state
525 | // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)
526 | // The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
527 | GLuint vertex_array_object = 0;
528 | #ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
529 | GL_CALL(glGenVertexArrays(1, &vertex_array_object));
530 | #endif
531 | ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
532 |
533 | // Will project scissor/clipping rectangles into framebuffer space
534 | ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
535 | ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
536 |
537 | // Render command lists
538 | for (int n = 0; n < draw_data->CmdListsCount; n++)
539 | {
540 | const ImDrawList* cmd_list = draw_data->CmdLists[n];
541 |
542 | // Upload vertex/index buffers
543 | // - OpenGL drivers are in a very sorry state nowadays....
544 | // During 2021 we attempted to switch from glBufferData() to orphaning+glBufferSubData() following reports
545 | // of leaks on Intel GPU when using multi-viewports on Windows.
546 | // - After this we kept hearing of various display corruptions issues. We started disabling on non-Intel GPU, but issues still got reported on Intel.
547 | // - We are now back to using exclusively glBufferData(). So bd->UseBufferSubData IS ALWAYS FALSE in this code.
548 | // We are keeping the old code path for a while in case people finding new issues may want to test the bd->UseBufferSubData path.
549 | // - See https://github.com/ocornut/imgui/issues/4468 and please report any corruption issues.
550 | const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
551 | const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
552 | if (bd->UseBufferSubData)
553 | {
554 | if (bd->VertexBufferSize < vtx_buffer_size)
555 | {
556 | bd->VertexBufferSize = vtx_buffer_size;
557 | GL_CALL(glBufferData(GL_ARRAY_BUFFER, bd->VertexBufferSize, nullptr, GL_STREAM_DRAW));
558 | }
559 | if (bd->IndexBufferSize < idx_buffer_size)
560 | {
561 | bd->IndexBufferSize = idx_buffer_size;
562 | GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize, nullptr, GL_STREAM_DRAW));
563 | }
564 | GL_CALL(glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data));
565 | GL_CALL(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data));
566 | }
567 | else
568 | {
569 | GL_CALL(glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW));
570 | GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW));
571 | }
572 |
573 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
574 | {
575 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
576 | if (pcmd->UserCallback != nullptr)
577 | {
578 | // User callback, registered via ImDrawList::AddCallback()
579 | // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
580 | if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
581 | ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
582 | else
583 | pcmd->UserCallback(cmd_list, pcmd);
584 | }
585 | else
586 | {
587 | // Project scissor/clipping rectangles into framebuffer space
588 | ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
589 | ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
590 | if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
591 | continue;
592 |
593 | // Apply scissor/clipping rectangle (Y is inverted in OpenGL)
594 | GL_CALL(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)));
595 |
596 | // Bind texture, Draw
597 | GL_CALL(glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()));
598 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
599 | if (bd->GlVersion >= 320)
600 | GL_CALL(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));
601 | else
602 | #endif
603 | GL_CALL(glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))));
604 | }
605 | }
606 | }
607 |
608 | // Destroy the temporary VAO
609 | #ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
610 | GL_CALL(glDeleteVertexArrays(1, &vertex_array_object));
611 | #endif
612 |
613 | // Restore modified GL state
614 | // This "glIsProgram()" check is required because if the program is "pending deletion" at the time of binding backup, it will have been deleted by now and will cause an OpenGL error. See #6220.
615 | if (last_program == 0 || glIsProgram(last_program)) glUseProgram(last_program);
616 | glBindTexture(GL_TEXTURE_2D, last_texture);
617 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
618 | if (bd->GlVersion >= 330 || bd->GlProfileIsES3)
619 | glBindSampler(0, last_sampler);
620 | #endif
621 | glActiveTexture(last_active_texture);
622 | #ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
623 | glBindVertexArray(last_vertex_array_object);
624 | #endif
625 | glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
626 | #ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
627 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer);
628 | last_vtx_attrib_state_pos.SetState(bd->AttribLocationVtxPos);
629 | last_vtx_attrib_state_uv.SetState(bd->AttribLocationVtxUV);
630 | last_vtx_attrib_state_color.SetState(bd->AttribLocationVtxColor);
631 | #endif
632 | glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
633 | glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha);
634 | if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
635 | if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
636 | if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
637 | if (last_enable_stencil_test) glEnable(GL_STENCIL_TEST); else glDisable(GL_STENCIL_TEST);
638 | if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
639 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
640 | if (bd->GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); else glDisable(GL_PRIMITIVE_RESTART); }
641 | #endif
642 |
643 | #ifdef IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE
644 | // Desktop OpenGL 3.0 and OpenGL 3.1 had separate polygon draw modes for front-facing and back-facing faces of polygons
645 | if (bd->GlVersion <= 310 || bd->GlProfileIsCompat)
646 | {
647 | glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]);
648 | glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]);
649 | }
650 | else
651 | {
652 | glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
653 | }
654 | #endif // IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE
655 |
656 | glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
657 | glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
658 | (void)bd; // Not all compilation paths use this
659 | }
660 |
661 | bool ImGui_ImplOpenGL3_CreateFontsTexture()
662 | {
663 | ImGuiIO& io = ImGui::GetIO();
664 | ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
665 |
666 | // Build texture atlas
667 | unsigned char* pixels;
668 | int width, height;
669 | 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.
670 |
671 | // Upload texture to graphics system
672 | // (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
673 | GLint last_texture;
674 | GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
675 | GL_CALL(glGenTextures(1, &bd->FontTexture));
676 | GL_CALL(glBindTexture(GL_TEXTURE_2D, bd->FontTexture));
677 | GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
678 | GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
679 | #ifdef GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
680 | GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
681 | #endif
682 | GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
683 |
684 | // Store our identifier
685 | io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
686 |
687 | // Restore state
688 | GL_CALL(glBindTexture(GL_TEXTURE_2D, last_texture));
689 |
690 | return true;
691 | }
692 |
693 | void ImGui_ImplOpenGL3_DestroyFontsTexture()
694 | {
695 | ImGuiIO& io = ImGui::GetIO();
696 | ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
697 | if (bd->FontTexture)
698 | {
699 | glDeleteTextures(1, &bd->FontTexture);
700 | io.Fonts->SetTexID(0);
701 | bd->FontTexture = 0;
702 | }
703 | }
704 |
705 | // 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.
706 | static bool CheckShader(GLuint handle, const char* desc)
707 | {
708 | ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
709 | GLint status = 0, log_length = 0;
710 | glGetShaderiv(handle, GL_COMPILE_STATUS, &status);
711 | glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length);
712 | if ((GLboolean)status == GL_FALSE)
713 | fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s! With GLSL: %s\n", desc, bd->GlslVersionString);
714 | if (log_length > 1)
715 | {
716 | ImVector buf;
717 | buf.resize((int)(log_length + 1));
718 | glGetShaderInfoLog(handle, log_length, nullptr, (GLchar*)buf.begin());
719 | fprintf(stderr, "%s\n", buf.begin());
720 | }
721 | return (GLboolean)status == GL_TRUE;
722 | }
723 |
724 | // If you get an error please report on GitHub. You may try different GL context version or GLSL version.
725 | static bool CheckProgram(GLuint handle, const char* desc)
726 | {
727 | ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
728 | GLint status = 0, log_length = 0;
729 | glGetProgramiv(handle, GL_LINK_STATUS, &status);
730 | glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length);
731 | if ((GLboolean)status == GL_FALSE)
732 | fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! With GLSL %s\n", desc, bd->GlslVersionString);
733 | if (log_length > 1)
734 | {
735 | ImVector buf;
736 | buf.resize((int)(log_length + 1));
737 | glGetProgramInfoLog(handle, log_length, nullptr, (GLchar*)buf.begin());
738 | fprintf(stderr, "%s\n", buf.begin());
739 | }
740 | return (GLboolean)status == GL_TRUE;
741 | }
742 |
743 | bool ImGui_ImplOpenGL3_CreateDeviceObjects()
744 | {
745 | ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
746 |
747 | // Backup GL state
748 | GLint last_texture, last_array_buffer;
749 | glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
750 | glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
751 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_BUFFER_PIXEL_UNPACK
752 | GLint last_pixel_unpack_buffer;
753 | if (bd->GlVersion >= 210) { glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &last_pixel_unpack_buffer); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); }
754 | #endif
755 | #ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
756 | GLint last_vertex_array;
757 | glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
758 | #endif
759 |
760 | // Parse GLSL version string
761 | int glsl_version = 130;
762 | sscanf(bd->GlslVersionString, "#version %d", &glsl_version);
763 |
764 | const GLchar* vertex_shader_glsl_120 =
765 | "uniform mat4 ProjMtx;\n"
766 | "attribute vec2 Position;\n"
767 | "attribute vec2 UV;\n"
768 | "attribute vec4 Color;\n"
769 | "varying vec2 Frag_UV;\n"
770 | "varying vec4 Frag_Color;\n"
771 | "void main()\n"
772 | "{\n"
773 | " Frag_UV = UV;\n"
774 | " Frag_Color = Color;\n"
775 | " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
776 | "}\n";
777 |
778 | const GLchar* vertex_shader_glsl_130 =
779 | "uniform mat4 ProjMtx;\n"
780 | "in vec2 Position;\n"
781 | "in vec2 UV;\n"
782 | "in vec4 Color;\n"
783 | "out vec2 Frag_UV;\n"
784 | "out vec4 Frag_Color;\n"
785 | "void main()\n"
786 | "{\n"
787 | " Frag_UV = UV;\n"
788 | " Frag_Color = Color;\n"
789 | " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
790 | "}\n";
791 |
792 | const GLchar* vertex_shader_glsl_300_es =
793 | "precision highp float;\n"
794 | "layout (location = 0) in vec2 Position;\n"
795 | "layout (location = 1) in vec2 UV;\n"
796 | "layout (location = 2) in vec4 Color;\n"
797 | "uniform mat4 ProjMtx;\n"
798 | "out vec2 Frag_UV;\n"
799 | "out vec4 Frag_Color;\n"
800 | "void main()\n"
801 | "{\n"
802 | " Frag_UV = UV;\n"
803 | " Frag_Color = Color;\n"
804 | " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
805 | "}\n";
806 |
807 | const GLchar* vertex_shader_glsl_410_core =
808 | "layout (location = 0) in vec2 Position;\n"
809 | "layout (location = 1) in vec2 UV;\n"
810 | "layout (location = 2) in vec4 Color;\n"
811 | "uniform mat4 ProjMtx;\n"
812 | "out vec2 Frag_UV;\n"
813 | "out vec4 Frag_Color;\n"
814 | "void main()\n"
815 | "{\n"
816 | " Frag_UV = UV;\n"
817 | " Frag_Color = Color;\n"
818 | " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
819 | "}\n";
820 |
821 | const GLchar* fragment_shader_glsl_120 =
822 | "#ifdef GL_ES\n"
823 | " precision mediump float;\n"
824 | "#endif\n"
825 | "uniform sampler2D Texture;\n"
826 | "varying vec2 Frag_UV;\n"
827 | "varying vec4 Frag_Color;\n"
828 | "void main()\n"
829 | "{\n"
830 | " gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n"
831 | "}\n";
832 |
833 | const GLchar* fragment_shader_glsl_130 =
834 | "uniform sampler2D Texture;\n"
835 | "in vec2 Frag_UV;\n"
836 | "in vec4 Frag_Color;\n"
837 | "out vec4 Out_Color;\n"
838 | "void main()\n"
839 | "{\n"
840 | " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
841 | "}\n";
842 |
843 | const GLchar* fragment_shader_glsl_300_es =
844 | "precision mediump float;\n"
845 | "uniform sampler2D Texture;\n"
846 | "in vec2 Frag_UV;\n"
847 | "in vec4 Frag_Color;\n"
848 | "layout (location = 0) out vec4 Out_Color;\n"
849 | "void main()\n"
850 | "{\n"
851 | " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
852 | "}\n";
853 |
854 | const GLchar* fragment_shader_glsl_410_core =
855 | "in vec2 Frag_UV;\n"
856 | "in vec4 Frag_Color;\n"
857 | "uniform sampler2D Texture;\n"
858 | "layout (location = 0) out vec4 Out_Color;\n"
859 | "void main()\n"
860 | "{\n"
861 | " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
862 | "}\n";
863 |
864 | // Select shaders matching our GLSL versions
865 | const GLchar* vertex_shader = nullptr;
866 | const GLchar* fragment_shader = nullptr;
867 | if (glsl_version < 130)
868 | {
869 | vertex_shader = vertex_shader_glsl_120;
870 | fragment_shader = fragment_shader_glsl_120;
871 | }
872 | else if (glsl_version >= 410)
873 | {
874 | vertex_shader = vertex_shader_glsl_410_core;
875 | fragment_shader = fragment_shader_glsl_410_core;
876 | }
877 | else if (glsl_version == 300)
878 | {
879 | vertex_shader = vertex_shader_glsl_300_es;
880 | fragment_shader = fragment_shader_glsl_300_es;
881 | }
882 | else
883 | {
884 | vertex_shader = vertex_shader_glsl_130;
885 | fragment_shader = fragment_shader_glsl_130;
886 | }
887 |
888 | // Create shaders
889 | const GLchar* vertex_shader_with_version[2] = { bd->GlslVersionString, vertex_shader };
890 | GLuint vert_handle = glCreateShader(GL_VERTEX_SHADER);
891 | glShaderSource(vert_handle, 2, vertex_shader_with_version, nullptr);
892 | glCompileShader(vert_handle);
893 | CheckShader(vert_handle, "vertex shader");
894 |
895 | const GLchar* fragment_shader_with_version[2] = { bd->GlslVersionString, fragment_shader };
896 | GLuint frag_handle = glCreateShader(GL_FRAGMENT_SHADER);
897 | glShaderSource(frag_handle, 2, fragment_shader_with_version, nullptr);
898 | glCompileShader(frag_handle);
899 | CheckShader(frag_handle, "fragment shader");
900 |
901 | // Link
902 | bd->ShaderHandle = glCreateProgram();
903 | glAttachShader(bd->ShaderHandle, vert_handle);
904 | glAttachShader(bd->ShaderHandle, frag_handle);
905 | glLinkProgram(bd->ShaderHandle);
906 | CheckProgram(bd->ShaderHandle, "shader program");
907 |
908 | glDetachShader(bd->ShaderHandle, vert_handle);
909 | glDetachShader(bd->ShaderHandle, frag_handle);
910 | glDeleteShader(vert_handle);
911 | glDeleteShader(frag_handle);
912 |
913 | bd->AttribLocationTex = glGetUniformLocation(bd->ShaderHandle, "Texture");
914 | bd->AttribLocationProjMtx = glGetUniformLocation(bd->ShaderHandle, "ProjMtx");
915 | bd->AttribLocationVtxPos = (GLuint)glGetAttribLocation(bd->ShaderHandle, "Position");
916 | bd->AttribLocationVtxUV = (GLuint)glGetAttribLocation(bd->ShaderHandle, "UV");
917 | bd->AttribLocationVtxColor = (GLuint)glGetAttribLocation(bd->ShaderHandle, "Color");
918 |
919 | // Create buffers
920 | glGenBuffers(1, &bd->VboHandle);
921 | glGenBuffers(1, &bd->ElementsHandle);
922 |
923 | ImGui_ImplOpenGL3_CreateFontsTexture();
924 |
925 | // Restore modified GL state
926 | glBindTexture(GL_TEXTURE_2D, last_texture);
927 | glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
928 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_BUFFER_PIXEL_UNPACK
929 | if (bd->GlVersion >= 210) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, last_pixel_unpack_buffer); }
930 | #endif
931 | #ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
932 | glBindVertexArray(last_vertex_array);
933 | #endif
934 |
935 | return true;
936 | }
937 |
938 | void ImGui_ImplOpenGL3_DestroyDeviceObjects()
939 | {
940 | ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
941 | if (bd->VboHandle) { glDeleteBuffers(1, &bd->VboHandle); bd->VboHandle = 0; }
942 | if (bd->ElementsHandle) { glDeleteBuffers(1, &bd->ElementsHandle); bd->ElementsHandle = 0; }
943 | if (bd->ShaderHandle) { glDeleteProgram(bd->ShaderHandle); bd->ShaderHandle = 0; }
944 | ImGui_ImplOpenGL3_DestroyFontsTexture();
945 | }
946 |
947 | //-----------------------------------------------------------------------------
948 |
949 | #if defined(__GNUC__)
950 | #pragma GCC diagnostic pop
951 | #endif
952 | #if defined(__clang__)
953 | #pragma clang diagnostic pop
954 | #endif
955 |
956 | #endif // #ifndef IMGUI_DISABLE
957 |
--------------------------------------------------------------------------------
/src/Dependencies/include/ImGui/imgui_impl_opengl3.h:
--------------------------------------------------------------------------------
1 | // dear imgui: Renderer Backend for modern OpenGL with shaders / programmatic pipeline
2 | // - Desktop GL: 2.x 3.x 4.x
3 | // - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
4 | // This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
5 |
6 | // Implemented features:
7 | // [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
8 | // [x] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only).
9 |
10 | // About WebGL/ES:
11 | // - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
12 | // - This is done automatically on iOS, Android and Emscripten targets.
13 | // - For other targets, the define needs to be visible from the imgui_impl_opengl3.cpp compilation unit. If unsure, define globally or in imconfig.h.
14 |
15 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
16 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
17 | // Learn about Dear ImGui:
18 | // - FAQ https://dearimgui.com/faq
19 | // - Getting Started https://dearimgui.com/getting-started
20 | // - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
21 | // - Introduction, links and more at the top of imgui.cpp
22 |
23 | // About GLSL version:
24 | // The 'glsl_version' initialization parameter should be nullptr (default) or a "#version XXX" string.
25 | // On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es"
26 | // Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp.
27 |
28 | #pragma once
29 | #include "imgui.h" // IMGUI_IMPL_API
30 | #ifndef IMGUI_DISABLE
31 |
32 | // Backend API
33 | IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
34 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
35 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
36 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
37 |
38 | // (Optional) Called by Init/NewFrame/Shutdown
39 | IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture();
40 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture();
41 | IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
42 | IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
43 |
44 | // Specific OpenGL ES versions
45 | //#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten
46 | //#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android
47 |
48 | // 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.
49 | #if !defined(IMGUI_IMPL_OPENGL_ES2) \
50 | && !defined(IMGUI_IMPL_OPENGL_ES3)
51 |
52 | // Try to detect GLES on matching platforms
53 | #if defined(__APPLE__)
54 | #include
55 | #endif
56 | #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__))
57 | #define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
58 | #elif defined(__EMSCRIPTEN__) || defined(__amigaos4__)
59 | #define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
60 | #else
61 | // Otherwise imgui_impl_opengl3_loader.h will be used.
62 | #endif
63 |
64 | #endif
65 |
66 | #endif // #ifndef IMGUI_DISABLE
67 |
--------------------------------------------------------------------------------
/src/Dependencies/include/ImGui/imgui_impl_opengl3_loader.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------------------------
2 | // About imgui_impl_opengl3_loader.h:
3 | //
4 | // We embed our own OpenGL loader to not require user to provide their own or to have to use ours,
5 | // which proved to be endless problems for users.
6 | // Our loader is custom-generated, based on gl3w but automatically filtered to only include
7 | // enums/functions that we use in our imgui_impl_opengl3.cpp source file in order to be small.
8 | //
9 | // YOU SHOULD NOT NEED TO INCLUDE/USE THIS DIRECTLY. THIS IS USED BY imgui_impl_opengl3.cpp ONLY.
10 | // THE REST OF YOUR APP SHOULD USE A DIFFERENT GL LOADER: ANY GL LOADER OF YOUR CHOICE.
11 | //
12 | // IF YOU GET BUILD ERRORS IN THIS FILE (commonly macro redefinitions or function redefinitions):
13 | // IT LIKELY MEANS THAT YOU ARE BUILDING 'imgui_impl_opengl3.cpp' OR INCUDING 'imgui_impl_opengl3_loader.h'
14 | // IN THE SAME COMPILATION UNIT AS ONE OF YOUR FILE WHICH IS USING A THIRD-PARTY OPENGL LOADER.
15 | // (e.g. COULD HAPPEN IF YOU ARE DOING A UNITY/JUMBO BUILD, OR INCLUDING .CPP FILES FROM OTHERS)
16 | // YOU SHOULD NOT BUILD BOTH IN THE SAME COMPILATION UNIT.
17 | // BUT IF YOU REALLY WANT TO, you can '#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM' and imgui_impl_opengl3.cpp
18 | // WILL NOT BE USING OUR LOADER, AND INSTEAD EXPECT ANOTHER/YOUR LOADER TO BE AVAILABLE IN THE COMPILATION UNIT.
19 | //
20 | // Regenerate with:
21 | // python gl3w_gen.py --output ../imgui/backends/imgui_impl_opengl3_loader.h --ref ../imgui/backends/imgui_impl_opengl3.cpp ./extra_symbols.txt
22 | //
23 | // More info:
24 | // https://github.com/dearimgui/gl3w_stripped
25 | // https://github.com/ocornut/imgui/issues/4445
26 | //-----------------------------------------------------------------------------
27 |
28 | /*
29 | * This file was generated with gl3w_gen.py, part of imgl3w
30 | * (hosted at https://github.com/dearimgui/gl3w_stripped)
31 | *
32 | * This is free and unencumbered software released into the public domain.
33 | *
34 | * Anyone is free to copy, modify, publish, use, compile, sell, or
35 | * distribute this software, either in source code form or as a compiled
36 | * binary, for any purpose, commercial or non-commercial, and by any
37 | * means.
38 | *
39 | * In jurisdictions that recognize copyright laws, the author or authors
40 | * of this software dedicate any and all copyright interest in the
41 | * software to the public domain. We make this dedication for the benefit
42 | * of the public at large and to the detriment of our heirs and
43 | * successors. We intend this dedication to be an overt act of
44 | * relinquishment in perpetuity of all present and future rights to this
45 | * software under copyright law.
46 | *
47 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
48 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
49 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
50 | * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
51 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
52 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
53 | * OTHER DEALINGS IN THE SOFTWARE.
54 | */
55 |
56 | #ifndef __gl3w_h_
57 | #define __gl3w_h_
58 |
59 | // Adapted from KHR/khrplatform.h to avoid including entire file.
60 | #ifndef __khrplatform_h_
61 | typedef float khronos_float_t;
62 | typedef signed char khronos_int8_t;
63 | typedef unsigned char khronos_uint8_t;
64 | typedef signed short int khronos_int16_t;
65 | typedef unsigned short int khronos_uint16_t;
66 | #ifdef _WIN64
67 | typedef signed long long int khronos_intptr_t;
68 | typedef signed long long int khronos_ssize_t;
69 | #else
70 | typedef signed long int khronos_intptr_t;
71 | typedef signed long int khronos_ssize_t;
72 | #endif
73 |
74 | #if defined(_MSC_VER) && !defined(__clang__)
75 | typedef signed __int64 khronos_int64_t;
76 | typedef unsigned __int64 khronos_uint64_t;
77 | #elif (defined(__clang__) || defined(__GNUC__)) && (__cplusplus < 201100)
78 | #include
79 | typedef int64_t khronos_int64_t;
80 | typedef uint64_t khronos_uint64_t;
81 | #else
82 | typedef signed long long khronos_int64_t;
83 | typedef unsigned long long khronos_uint64_t;
84 | #endif
85 | #endif // __khrplatform_h_
86 |
87 | #ifndef __gl_glcorearb_h_
88 | #define __gl_glcorearb_h_ 1
89 | #ifdef __cplusplus
90 | extern "C" {
91 | #endif
92 | /*
93 | ** Copyright 2013-2020 The Khronos Group Inc.
94 | ** SPDX-License-Identifier: MIT
95 | **
96 | ** This header is generated from the Khronos OpenGL / OpenGL ES XML
97 | ** API Registry. The current version of the Registry, generator scripts
98 | ** used to make the header, and the header can be found at
99 | ** https://github.com/KhronosGroup/OpenGL-Registry
100 | */
101 | #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
102 | #ifndef WIN32_LEAN_AND_MEAN
103 | #define WIN32_LEAN_AND_MEAN 1
104 | #endif
105 | #include
106 | #endif
107 | #ifndef APIENTRY
108 | #define APIENTRY
109 | #endif
110 | #ifndef APIENTRYP
111 | #define APIENTRYP APIENTRY *
112 | #endif
113 | #ifndef GLAPI
114 | #define GLAPI extern
115 | #endif
116 | /* glcorearb.h is for use with OpenGL core profile implementations.
117 | ** It should should be placed in the same directory as gl.h and
118 | ** included as .
119 | **
120 | ** glcorearb.h includes only APIs in the latest OpenGL core profile
121 | ** implementation together with APIs in newer ARB extensions which
122 | ** can be supported by the core profile. It does not, and never will
123 | ** include functionality removed from the core profile, such as
124 | ** fixed-function vertex and fragment processing.
125 | **
126 | ** Do not #include both and either of or
127 | ** in the same source file.
128 | */
129 | /* Generated C header for:
130 | * API: gl
131 | * Profile: core
132 | * Versions considered: .*
133 | * Versions emitted: .*
134 | * Default extensions included: glcore
135 | * Additional extensions included: _nomatch_^
136 | * Extensions removed: _nomatch_^
137 | */
138 | #ifndef GL_VERSION_1_0
139 | typedef void GLvoid;
140 | typedef unsigned int GLenum;
141 |
142 | typedef khronos_float_t GLfloat;
143 | typedef int GLint;
144 | typedef int GLsizei;
145 | typedef unsigned int GLbitfield;
146 | typedef double GLdouble;
147 | typedef unsigned int GLuint;
148 | typedef unsigned char GLboolean;
149 | typedef khronos_uint8_t GLubyte;
150 | #define GL_COLOR_BUFFER_BIT 0x00004000
151 | #define GL_FALSE 0
152 | #define GL_TRUE 1
153 | #define GL_TRIANGLES 0x0004
154 | #define GL_ONE 1
155 | #define GL_SRC_ALPHA 0x0302
156 | #define GL_ONE_MINUS_SRC_ALPHA 0x0303
157 | #define GL_FRONT 0x0404
158 | #define GL_BACK 0x0405
159 | #define GL_FRONT_AND_BACK 0x0408
160 | #define GL_POLYGON_MODE 0x0B40
161 | #define GL_CULL_FACE 0x0B44
162 | #define GL_DEPTH_TEST 0x0B71
163 | #define GL_STENCIL_TEST 0x0B90
164 | #define GL_VIEWPORT 0x0BA2
165 | #define GL_BLEND 0x0BE2
166 | #define GL_SCISSOR_BOX 0x0C10
167 | #define GL_SCISSOR_TEST 0x0C11
168 | #define GL_UNPACK_ROW_LENGTH 0x0CF2
169 | #define GL_PACK_ALIGNMENT 0x0D05
170 | #define GL_TEXTURE_2D 0x0DE1
171 | #define GL_UNSIGNED_BYTE 0x1401
172 | #define GL_UNSIGNED_SHORT 0x1403
173 | #define GL_UNSIGNED_INT 0x1405
174 | #define GL_FLOAT 0x1406
175 | #define GL_RGBA 0x1908
176 | #define GL_FILL 0x1B02
177 | #define GL_VENDOR 0x1F00
178 | #define GL_RENDERER 0x1F01
179 | #define GL_VERSION 0x1F02
180 | #define GL_EXTENSIONS 0x1F03
181 | #define GL_LINEAR 0x2601
182 | #define GL_TEXTURE_MAG_FILTER 0x2800
183 | #define GL_TEXTURE_MIN_FILTER 0x2801
184 | typedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
185 | typedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
186 | typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
187 | typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
188 | typedef void (APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);
189 | typedef void (APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
190 | typedef void (APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
191 | typedef void (APIENTRYP PFNGLENABLEPROC) (GLenum cap);
192 | typedef void (APIENTRYP PFNGLFLUSHPROC) (void);
193 | typedef void (APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
194 | typedef void (APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
195 | typedef GLenum (APIENTRYP PFNGLGETERRORPROC) (void);
196 | typedef void (APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);
197 | typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
198 | typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);
199 | typedef void (APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
200 | #ifdef GL_GLEXT_PROTOTYPES
201 | GLAPI void APIENTRY glPolygonMode (GLenum face, GLenum mode);
202 | GLAPI void APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
203 | GLAPI void APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
204 | GLAPI void APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
205 | GLAPI void APIENTRY glClear (GLbitfield mask);
206 | GLAPI void APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
207 | GLAPI void APIENTRY glDisable (GLenum cap);
208 | GLAPI void APIENTRY glEnable (GLenum cap);
209 | GLAPI void APIENTRY glFlush (void);
210 | GLAPI void APIENTRY glPixelStorei (GLenum pname, GLint param);
211 | GLAPI void APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
212 | GLAPI GLenum APIENTRY glGetError (void);
213 | GLAPI void APIENTRY glGetIntegerv (GLenum pname, GLint *data);
214 | GLAPI const GLubyte *APIENTRY glGetString (GLenum name);
215 | GLAPI GLboolean APIENTRY glIsEnabled (GLenum cap);
216 | GLAPI void APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
217 | #endif
218 | #endif /* GL_VERSION_1_0 */
219 | #ifndef GL_VERSION_1_1
220 | typedef khronos_float_t GLclampf;
221 | typedef double GLclampd;
222 | #define GL_TEXTURE_BINDING_2D 0x8069
223 | typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
224 | typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
225 | typedef void (APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
226 | typedef void (APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
227 | #ifdef GL_GLEXT_PROTOTYPES
228 | GLAPI void APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
229 | GLAPI void APIENTRY glBindTexture (GLenum target, GLuint texture);
230 | GLAPI void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
231 | GLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures);
232 | #endif
233 | #endif /* GL_VERSION_1_1 */
234 | #ifndef GL_VERSION_1_3
235 | #define GL_TEXTURE0 0x84C0
236 | #define GL_ACTIVE_TEXTURE 0x84E0
237 | typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
238 | #ifdef GL_GLEXT_PROTOTYPES
239 | GLAPI void APIENTRY glActiveTexture (GLenum texture);
240 | #endif
241 | #endif /* GL_VERSION_1_3 */
242 | #ifndef GL_VERSION_1_4
243 | #define GL_BLEND_DST_RGB 0x80C8
244 | #define GL_BLEND_SRC_RGB 0x80C9
245 | #define GL_BLEND_DST_ALPHA 0x80CA
246 | #define GL_BLEND_SRC_ALPHA 0x80CB
247 | #define GL_FUNC_ADD 0x8006
248 | typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
249 | typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
250 | #ifdef GL_GLEXT_PROTOTYPES
251 | GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
252 | GLAPI void APIENTRY glBlendEquation (GLenum mode);
253 | #endif
254 | #endif /* GL_VERSION_1_4 */
255 | #ifndef GL_VERSION_1_5
256 | typedef khronos_ssize_t GLsizeiptr;
257 | typedef khronos_intptr_t GLintptr;
258 | #define GL_ARRAY_BUFFER 0x8892
259 | #define GL_ELEMENT_ARRAY_BUFFER 0x8893
260 | #define GL_ARRAY_BUFFER_BINDING 0x8894
261 | #define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
262 | #define GL_STREAM_DRAW 0x88E0
263 | #define GL_PIXEL_UNPACK_BUFFER 0x88EC
264 | #define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
265 | typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
266 | typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
267 | typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
268 | typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
269 | typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
270 | #ifdef GL_GLEXT_PROTOTYPES
271 | GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer);
272 | GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
273 | GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
274 | GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
275 | GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
276 | #endif
277 | #endif /* GL_VERSION_1_5 */
278 | #ifndef GL_VERSION_2_0
279 | typedef char GLchar;
280 | typedef khronos_int16_t GLshort;
281 | typedef khronos_int8_t GLbyte;
282 | typedef khronos_uint16_t GLushort;
283 | #define GL_BLEND_EQUATION_RGB 0x8009
284 | #define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
285 | #define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
286 | #define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
287 | #define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
288 | #define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
289 | #define GL_BLEND_EQUATION_ALPHA 0x883D
290 | #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
291 | #define GL_FRAGMENT_SHADER 0x8B30
292 | #define GL_VERTEX_SHADER 0x8B31
293 | #define GL_COMPILE_STATUS 0x8B81
294 | #define GL_LINK_STATUS 0x8B82
295 | #define GL_INFO_LOG_LENGTH 0x8B84
296 | #define GL_CURRENT_PROGRAM 0x8B8D
297 | #define GL_UPPER_LEFT 0x8CA2
298 | typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
299 | typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
300 | typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
301 | typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
302 | typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
303 | typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
304 | typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
305 | typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
306 | typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
307 | typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
308 | typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
309 | typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
310 | typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
311 | typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
312 | typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
313 | typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
314 | typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
315 | typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer);
316 | typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
317 | typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
318 | typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
319 | typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
320 | typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
321 | typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
322 | typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
323 | #ifdef GL_GLEXT_PROTOTYPES
324 | GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
325 | GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader);
326 | GLAPI void APIENTRY glCompileShader (GLuint shader);
327 | GLAPI GLuint APIENTRY glCreateProgram (void);
328 | GLAPI GLuint APIENTRY glCreateShader (GLenum type);
329 | GLAPI void APIENTRY glDeleteProgram (GLuint program);
330 | GLAPI void APIENTRY glDeleteShader (GLuint shader);
331 | GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader);
332 | GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index);
333 | GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index);
334 | GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
335 | GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
336 | GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
337 | GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
338 | GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
339 | GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
340 | GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
341 | GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer);
342 | GLAPI GLboolean APIENTRY glIsProgram (GLuint program);
343 | GLAPI void APIENTRY glLinkProgram (GLuint program);
344 | GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
345 | GLAPI void APIENTRY glUseProgram (GLuint program);
346 | GLAPI void APIENTRY glUniform1i (GLint location, GLint v0);
347 | GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
348 | GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
349 | #endif
350 | #endif /* GL_VERSION_2_0 */
351 | #ifndef GL_VERSION_3_0
352 | typedef khronos_uint16_t GLhalf;
353 | #define GL_MAJOR_VERSION 0x821B
354 | #define GL_MINOR_VERSION 0x821C
355 | #define GL_NUM_EXTENSIONS 0x821D
356 | #define GL_FRAMEBUFFER_SRGB 0x8DB9
357 | #define GL_VERTEX_ARRAY_BINDING 0x85B5
358 | typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data);
359 | typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data);
360 | typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
361 | typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
362 | typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
363 | typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
364 | #ifdef GL_GLEXT_PROTOTYPES
365 | GLAPI const GLubyte *APIENTRY glGetStringi (GLenum name, GLuint index);
366 | GLAPI void APIENTRY glBindVertexArray (GLuint array);
367 | GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
368 | GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);
369 | #endif
370 | #endif /* GL_VERSION_3_0 */
371 | #ifndef GL_VERSION_3_1
372 | #define GL_VERSION_3_1 1
373 | #define GL_PRIMITIVE_RESTART 0x8F9D
374 | #endif /* GL_VERSION_3_1 */
375 | #ifndef GL_VERSION_3_2
376 | #define GL_VERSION_3_2 1
377 | typedef struct __GLsync *GLsync;
378 | typedef khronos_uint64_t GLuint64;
379 | typedef khronos_int64_t GLint64;
380 | #define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
381 | #define GL_CONTEXT_PROFILE_MASK 0x9126
382 | typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
383 | typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
384 | #ifdef GL_GLEXT_PROTOTYPES
385 | GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
386 | #endif
387 | #endif /* GL_VERSION_3_2 */
388 | #ifndef GL_VERSION_3_3
389 | #define GL_VERSION_3_3 1
390 | #define GL_SAMPLER_BINDING 0x8919
391 | typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
392 | #ifdef GL_GLEXT_PROTOTYPES
393 | GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler);
394 | #endif
395 | #endif /* GL_VERSION_3_3 */
396 | #ifndef GL_VERSION_4_1
397 | typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data);
398 | typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data);
399 | #endif /* GL_VERSION_4_1 */
400 | #ifndef GL_VERSION_4_3
401 | typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
402 | #endif /* GL_VERSION_4_3 */
403 | #ifndef GL_VERSION_4_5
404 | #define GL_CLIP_ORIGIN 0x935C
405 | typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint *param);
406 | typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64 *param);
407 | #endif /* GL_VERSION_4_5 */
408 | #ifndef GL_ARB_bindless_texture
409 | typedef khronos_uint64_t GLuint64EXT;
410 | #endif /* GL_ARB_bindless_texture */
411 | #ifndef GL_ARB_cl_event
412 | struct _cl_context;
413 | struct _cl_event;
414 | #endif /* GL_ARB_cl_event */
415 | #ifndef GL_ARB_clip_control
416 | #define GL_ARB_clip_control 1
417 | #endif /* GL_ARB_clip_control */
418 | #ifndef GL_ARB_debug_output
419 | typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
420 | #endif /* GL_ARB_debug_output */
421 | #ifndef GL_EXT_EGL_image_storage
422 | typedef void *GLeglImageOES;
423 | #endif /* GL_EXT_EGL_image_storage */
424 | #ifndef GL_EXT_direct_state_access
425 | typedef void (APIENTRYP PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat *params);
426 | typedef void (APIENTRYP PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble *params);
427 | typedef void (APIENTRYP PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, void **params);
428 | typedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param);
429 | typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void **param);
430 | #endif /* GL_EXT_direct_state_access */
431 | #ifndef GL_NV_draw_vulkan_image
432 | typedef void (APIENTRY *GLVULKANPROCNV)(void);
433 | #endif /* GL_NV_draw_vulkan_image */
434 | #ifndef GL_NV_gpu_shader5
435 | typedef khronos_int64_t GLint64EXT;
436 | #endif /* GL_NV_gpu_shader5 */
437 | #ifndef GL_NV_vertex_buffer_unified_memory
438 | typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result);
439 | #endif /* GL_NV_vertex_buffer_unified_memory */
440 | #ifdef __cplusplus
441 | }
442 | #endif
443 | #endif
444 |
445 | #ifndef GL3W_API
446 | #define GL3W_API
447 | #endif
448 |
449 | #ifndef __gl_h_
450 | #define __gl_h_
451 | #endif
452 |
453 | #ifdef __cplusplus
454 | extern "C" {
455 | #endif
456 |
457 | #define GL3W_OK 0
458 | #define GL3W_ERROR_INIT -1
459 | #define GL3W_ERROR_LIBRARY_OPEN -2
460 | #define GL3W_ERROR_OPENGL_VERSION -3
461 |
462 | typedef void (*GL3WglProc)(void);
463 | typedef GL3WglProc (*GL3WGetProcAddressProc)(const char *proc);
464 |
465 | /* gl3w api */
466 | GL3W_API int imgl3wInit(void);
467 | GL3W_API int imgl3wInit2(GL3WGetProcAddressProc proc);
468 | GL3W_API int imgl3wIsSupported(int major, int minor);
469 | GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc);
470 |
471 | /* gl3w internal state */
472 | union ImGL3WProcs {
473 | GL3WglProc ptr[59];
474 | struct {
475 | PFNGLACTIVETEXTUREPROC ActiveTexture;
476 | PFNGLATTACHSHADERPROC AttachShader;
477 | PFNGLBINDBUFFERPROC BindBuffer;
478 | PFNGLBINDSAMPLERPROC BindSampler;
479 | PFNGLBINDTEXTUREPROC BindTexture;
480 | PFNGLBINDVERTEXARRAYPROC BindVertexArray;
481 | PFNGLBLENDEQUATIONPROC BlendEquation;
482 | PFNGLBLENDEQUATIONSEPARATEPROC BlendEquationSeparate;
483 | PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate;
484 | PFNGLBUFFERDATAPROC BufferData;
485 | PFNGLBUFFERSUBDATAPROC BufferSubData;
486 | PFNGLCLEARPROC Clear;
487 | PFNGLCLEARCOLORPROC ClearColor;
488 | PFNGLCOMPILESHADERPROC CompileShader;
489 | PFNGLCREATEPROGRAMPROC CreateProgram;
490 | PFNGLCREATESHADERPROC CreateShader;
491 | PFNGLDELETEBUFFERSPROC DeleteBuffers;
492 | PFNGLDELETEPROGRAMPROC DeleteProgram;
493 | PFNGLDELETESHADERPROC DeleteShader;
494 | PFNGLDELETETEXTURESPROC DeleteTextures;
495 | PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays;
496 | PFNGLDETACHSHADERPROC DetachShader;
497 | PFNGLDISABLEPROC Disable;
498 | PFNGLDISABLEVERTEXATTRIBARRAYPROC DisableVertexAttribArray;
499 | PFNGLDRAWELEMENTSPROC DrawElements;
500 | PFNGLDRAWELEMENTSBASEVERTEXPROC DrawElementsBaseVertex;
501 | PFNGLENABLEPROC Enable;
502 | PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray;
503 | PFNGLFLUSHPROC Flush;
504 | PFNGLGENBUFFERSPROC GenBuffers;
505 | PFNGLGENTEXTURESPROC GenTextures;
506 | PFNGLGENVERTEXARRAYSPROC GenVertexArrays;
507 | PFNGLGETATTRIBLOCATIONPROC GetAttribLocation;
508 | PFNGLGETERRORPROC GetError;
509 | PFNGLGETINTEGERVPROC GetIntegerv;
510 | PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
511 | PFNGLGETPROGRAMIVPROC GetProgramiv;
512 | PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog;
513 | PFNGLGETSHADERIVPROC GetShaderiv;
514 | PFNGLGETSTRINGPROC GetString;
515 | PFNGLGETSTRINGIPROC GetStringi;
516 | PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation;
517 | PFNGLGETVERTEXATTRIBPOINTERVPROC GetVertexAttribPointerv;
518 | PFNGLGETVERTEXATTRIBIVPROC GetVertexAttribiv;
519 | PFNGLISENABLEDPROC IsEnabled;
520 | PFNGLISPROGRAMPROC IsProgram;
521 | PFNGLLINKPROGRAMPROC LinkProgram;
522 | PFNGLPIXELSTOREIPROC PixelStorei;
523 | PFNGLPOLYGONMODEPROC PolygonMode;
524 | PFNGLREADPIXELSPROC ReadPixels;
525 | PFNGLSCISSORPROC Scissor;
526 | PFNGLSHADERSOURCEPROC ShaderSource;
527 | PFNGLTEXIMAGE2DPROC TexImage2D;
528 | PFNGLTEXPARAMETERIPROC TexParameteri;
529 | PFNGLUNIFORM1IPROC Uniform1i;
530 | PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv;
531 | PFNGLUSEPROGRAMPROC UseProgram;
532 | PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer;
533 | PFNGLVIEWPORTPROC Viewport;
534 | } gl;
535 | };
536 |
537 | GL3W_API extern union ImGL3WProcs imgl3wProcs;
538 |
539 | /* OpenGL functions */
540 | #define glActiveTexture imgl3wProcs.gl.ActiveTexture
541 | #define glAttachShader imgl3wProcs.gl.AttachShader
542 | #define glBindBuffer imgl3wProcs.gl.BindBuffer
543 | #define glBindSampler imgl3wProcs.gl.BindSampler
544 | #define glBindTexture imgl3wProcs.gl.BindTexture
545 | #define glBindVertexArray imgl3wProcs.gl.BindVertexArray
546 | #define glBlendEquation imgl3wProcs.gl.BlendEquation
547 | #define glBlendEquationSeparate imgl3wProcs.gl.BlendEquationSeparate
548 | #define glBlendFuncSeparate imgl3wProcs.gl.BlendFuncSeparate
549 | #define glBufferData imgl3wProcs.gl.BufferData
550 | #define glBufferSubData imgl3wProcs.gl.BufferSubData
551 | #define glClear imgl3wProcs.gl.Clear
552 | #define glClearColor imgl3wProcs.gl.ClearColor
553 | #define glCompileShader imgl3wProcs.gl.CompileShader
554 | #define glCreateProgram imgl3wProcs.gl.CreateProgram
555 | #define glCreateShader imgl3wProcs.gl.CreateShader
556 | #define glDeleteBuffers imgl3wProcs.gl.DeleteBuffers
557 | #define glDeleteProgram imgl3wProcs.gl.DeleteProgram
558 | #define glDeleteShader imgl3wProcs.gl.DeleteShader
559 | #define glDeleteTextures imgl3wProcs.gl.DeleteTextures
560 | #define glDeleteVertexArrays imgl3wProcs.gl.DeleteVertexArrays
561 | #define glDetachShader imgl3wProcs.gl.DetachShader
562 | #define glDisable imgl3wProcs.gl.Disable
563 | #define glDisableVertexAttribArray imgl3wProcs.gl.DisableVertexAttribArray
564 | #define glDrawElements imgl3wProcs.gl.DrawElements
565 | #define glDrawElementsBaseVertex imgl3wProcs.gl.DrawElementsBaseVertex
566 | #define glEnable imgl3wProcs.gl.Enable
567 | #define glEnableVertexAttribArray imgl3wProcs.gl.EnableVertexAttribArray
568 | #define glFlush imgl3wProcs.gl.Flush
569 | #define glGenBuffers imgl3wProcs.gl.GenBuffers
570 | #define glGenTextures imgl3wProcs.gl.GenTextures
571 | #define glGenVertexArrays imgl3wProcs.gl.GenVertexArrays
572 | #define glGetAttribLocation imgl3wProcs.gl.GetAttribLocation
573 | #define glGetError imgl3wProcs.gl.GetError
574 | #define glGetIntegerv imgl3wProcs.gl.GetIntegerv
575 | #define glGetProgramInfoLog imgl3wProcs.gl.GetProgramInfoLog
576 | #define glGetProgramiv imgl3wProcs.gl.GetProgramiv
577 | #define glGetShaderInfoLog imgl3wProcs.gl.GetShaderInfoLog
578 | #define glGetShaderiv imgl3wProcs.gl.GetShaderiv
579 | #define glGetString imgl3wProcs.gl.GetString
580 | #define glGetStringi imgl3wProcs.gl.GetStringi
581 | #define glGetUniformLocation imgl3wProcs.gl.GetUniformLocation
582 | #define glGetVertexAttribPointerv imgl3wProcs.gl.GetVertexAttribPointerv
583 | #define glGetVertexAttribiv imgl3wProcs.gl.GetVertexAttribiv
584 | #define glIsEnabled imgl3wProcs.gl.IsEnabled
585 | #define glIsProgram imgl3wProcs.gl.IsProgram
586 | #define glLinkProgram imgl3wProcs.gl.LinkProgram
587 | #define glPixelStorei imgl3wProcs.gl.PixelStorei
588 | #define glPolygonMode imgl3wProcs.gl.PolygonMode
589 | #define glReadPixels imgl3wProcs.gl.ReadPixels
590 | #define glScissor imgl3wProcs.gl.Scissor
591 | #define glShaderSource imgl3wProcs.gl.ShaderSource
592 | #define glTexImage2D imgl3wProcs.gl.TexImage2D
593 | #define glTexParameteri imgl3wProcs.gl.TexParameteri
594 | #define glUniform1i imgl3wProcs.gl.Uniform1i
595 | #define glUniformMatrix4fv imgl3wProcs.gl.UniformMatrix4fv
596 | #define glUseProgram imgl3wProcs.gl.UseProgram
597 | #define glVertexAttribPointer imgl3wProcs.gl.VertexAttribPointer
598 | #define glViewport imgl3wProcs.gl.Viewport
599 |
600 | #ifdef __cplusplus
601 | }
602 | #endif
603 |
604 | #endif
605 |
606 | #ifdef IMGL3W_IMPL
607 | #ifdef __cplusplus
608 | extern "C" {
609 | #endif
610 |
611 | #include
612 |
613 | #define GL3W_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
614 |
615 | #if defined(_WIN32)
616 | #ifndef WIN32_LEAN_AND_MEAN
617 | #define WIN32_LEAN_AND_MEAN 1
618 | #endif
619 | #include
620 |
621 | static HMODULE libgl;
622 | typedef PROC(__stdcall* GL3WglGetProcAddr)(LPCSTR);
623 | static GL3WglGetProcAddr wgl_get_proc_address;
624 |
625 | static int open_libgl(void)
626 | {
627 | libgl = LoadLibraryA("opengl32.dll");
628 | if (!libgl)
629 | return GL3W_ERROR_LIBRARY_OPEN;
630 | wgl_get_proc_address = (GL3WglGetProcAddr)GetProcAddress(libgl, "wglGetProcAddress");
631 | return GL3W_OK;
632 | }
633 |
634 | static void close_libgl(void) { FreeLibrary(libgl); }
635 | static GL3WglProc get_proc(const char *proc)
636 | {
637 | GL3WglProc res;
638 | res = (GL3WglProc)wgl_get_proc_address(proc);
639 | if (!res)
640 | res = (GL3WglProc)GetProcAddress(libgl, proc);
641 | return res;
642 | }
643 | #elif defined(__APPLE__)
644 | #include
645 |
646 | static void *libgl;
647 | static int open_libgl(void)
648 | {
649 | libgl = dlopen("/System/Library/Frameworks/OpenGL.framework/OpenGL", RTLD_LAZY | RTLD_LOCAL);
650 | if (!libgl)
651 | return GL3W_ERROR_LIBRARY_OPEN;
652 | return GL3W_OK;
653 | }
654 |
655 | static void close_libgl(void) { dlclose(libgl); }
656 |
657 | static GL3WglProc get_proc(const char *proc)
658 | {
659 | GL3WglProc res;
660 | *(void **)(&res) = dlsym(libgl, proc);
661 | return res;
662 | }
663 | #else
664 | #include
665 |
666 | static void *libgl;
667 | static GL3WglProc (*glx_get_proc_address)(const GLubyte *);
668 |
669 | static int open_libgl(void)
670 | {
671 | // While most systems use libGL.so.1, NetBSD seems to use that libGL.so.3. See https://github.com/ocornut/imgui/issues/6983
672 | libgl = dlopen("libGL.so", RTLD_LAZY | RTLD_LOCAL);
673 | if (!libgl)
674 | libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL);
675 | if (!libgl)
676 | libgl = dlopen("libGL.so.3", RTLD_LAZY | RTLD_LOCAL);
677 | if (!libgl)
678 | return GL3W_ERROR_LIBRARY_OPEN;
679 | *(void **)(&glx_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB");
680 | return GL3W_OK;
681 | }
682 |
683 | static void close_libgl(void) { dlclose(libgl); }
684 |
685 | static GL3WglProc get_proc(const char *proc)
686 | {
687 | GL3WglProc res;
688 | res = glx_get_proc_address((const GLubyte *)proc);
689 | if (!res)
690 | *(void **)(&res) = dlsym(libgl, proc);
691 | return res;
692 | }
693 | #endif
694 |
695 | static struct { int major, minor; } version;
696 |
697 | static int parse_version(void)
698 | {
699 | if (!glGetIntegerv)
700 | return GL3W_ERROR_INIT;
701 | glGetIntegerv(GL_MAJOR_VERSION, &version.major);
702 | glGetIntegerv(GL_MINOR_VERSION, &version.minor);
703 | if (version.major == 0 && version.minor == 0)
704 | {
705 | // Query GL_VERSION in desktop GL 2.x, the string will start with "."
706 | if (const char* gl_version = (const char*)glGetString(GL_VERSION))
707 | sscanf(gl_version, "%d.%d", &version.major, &version.minor);
708 | }
709 | if (version.major < 2)
710 | return GL3W_ERROR_OPENGL_VERSION;
711 | return GL3W_OK;
712 | }
713 |
714 | static void load_procs(GL3WGetProcAddressProc proc);
715 |
716 | int imgl3wInit(void)
717 | {
718 | int res = open_libgl();
719 | if (res)
720 | return res;
721 | atexit(close_libgl);
722 | return imgl3wInit2(get_proc);
723 | }
724 |
725 | int imgl3wInit2(GL3WGetProcAddressProc proc)
726 | {
727 | load_procs(proc);
728 | return parse_version();
729 | }
730 |
731 | int imgl3wIsSupported(int major, int minor)
732 | {
733 | if (major < 2)
734 | return 0;
735 | if (version.major == major)
736 | return version.minor >= minor;
737 | return version.major >= major;
738 | }
739 |
740 | GL3WglProc imgl3wGetProcAddress(const char *proc) { return get_proc(proc); }
741 |
742 | static const char *proc_names[] = {
743 | "glActiveTexture",
744 | "glAttachShader",
745 | "glBindBuffer",
746 | "glBindSampler",
747 | "glBindTexture",
748 | "glBindVertexArray",
749 | "glBlendEquation",
750 | "glBlendEquationSeparate",
751 | "glBlendFuncSeparate",
752 | "glBufferData",
753 | "glBufferSubData",
754 | "glClear",
755 | "glClearColor",
756 | "glCompileShader",
757 | "glCreateProgram",
758 | "glCreateShader",
759 | "glDeleteBuffers",
760 | "glDeleteProgram",
761 | "glDeleteShader",
762 | "glDeleteTextures",
763 | "glDeleteVertexArrays",
764 | "glDetachShader",
765 | "glDisable",
766 | "glDisableVertexAttribArray",
767 | "glDrawElements",
768 | "glDrawElementsBaseVertex",
769 | "glEnable",
770 | "glEnableVertexAttribArray",
771 | "glFlush",
772 | "glGenBuffers",
773 | "glGenTextures",
774 | "glGenVertexArrays",
775 | "glGetAttribLocation",
776 | "glGetError",
777 | "glGetIntegerv",
778 | "glGetProgramInfoLog",
779 | "glGetProgramiv",
780 | "glGetShaderInfoLog",
781 | "glGetShaderiv",
782 | "glGetString",
783 | "glGetStringi",
784 | "glGetUniformLocation",
785 | "glGetVertexAttribPointerv",
786 | "glGetVertexAttribiv",
787 | "glIsEnabled",
788 | "glIsProgram",
789 | "glLinkProgram",
790 | "glPixelStorei",
791 | "glPolygonMode",
792 | "glReadPixels",
793 | "glScissor",
794 | "glShaderSource",
795 | "glTexImage2D",
796 | "glTexParameteri",
797 | "glUniform1i",
798 | "glUniformMatrix4fv",
799 | "glUseProgram",
800 | "glVertexAttribPointer",
801 | "glViewport",
802 | };
803 |
804 | GL3W_API union ImGL3WProcs imgl3wProcs;
805 |
806 | static void load_procs(GL3WGetProcAddressProc proc)
807 | {
808 | size_t i;
809 | for (i = 0; i < GL3W_ARRAY_SIZE(proc_names); i++)
810 | imgl3wProcs.ptr[i] = proc(proc_names[i]);
811 | }
812 |
813 | #ifdef __cplusplus
814 | }
815 | #endif
816 | #endif
817 |
--------------------------------------------------------------------------------
/src/Dependencies/include/ImGui/imgui_impl_win32.cpp:
--------------------------------------------------------------------------------
1 | // dear imgui: Platform Backend for Windows (standard windows API for 32-bits AND 64-bits applications)
2 | // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
3 |
4 | // Implemented features:
5 | // [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
6 | // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
7 | // [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]
8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
9 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
10 |
11 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
12 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
13 | // Learn about Dear ImGui:
14 | // - FAQ https://dearimgui.com/faq
15 | // - Getting Started https://dearimgui.com/getting-started
16 | // - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
17 | // - Introduction, links and more at the top of imgui.cpp
18 |
19 | #include "imgui.h"
20 | #ifndef IMGUI_DISABLE
21 | #include "imgui_impl_win32.h"
22 | #ifndef WIN32_LEAN_AND_MEAN
23 | #define WIN32_LEAN_AND_MEAN
24 | #endif
25 | #include
26 | #include // GET_X_LPARAM(), GET_Y_LPARAM()
27 | #include
28 | #include
29 |
30 | // Configuration flags to add in your imconfig.h file:
31 | //#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.
32 |
33 | // Using XInput for gamepad (will load DLL dynamically)
34 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
35 | #include
36 | typedef DWORD (WINAPI *PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*);
37 | typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
38 | #endif
39 |
40 | // CHANGELOG
41 | // (minor and older changes stripped away, please see git history for details)
42 | // 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
43 | // 2023-09-25: Inputs: Synthesize key-down event on key-up for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit it (same behavior as GLFW/SDL).
44 | // 2023-09-07: Inputs: Added support for keyboard codepage conversion for when application is compiled in MBCS mode and using a non-Unicode window.
45 | // 2023-04-19: Added ImGui_ImplWin32_InitForOpenGL() to facilitate combining raw Win32/Winapi with OpenGL. (#3218)
46 | // 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen. (#2702)
47 | // 2023-02-15: Inputs: Use WM_NCMOUSEMOVE / WM_NCMOUSELEAVE to track mouse position over non-client area (e.g. OS decorations) when app is not focused. (#6045, #6162)
48 | // 2023-02-02: Inputs: Flipping WM_MOUSEHWHEEL (horizontal mouse-wheel) value to match other backends and offer consistent horizontal scrolling direction. (#4019, #6096, #1463)
49 | // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
50 | // 2022-09-28: Inputs: Convert WM_CHAR values with MultiByteToWideChar() when window class was registered as MBCS (not Unicode).
51 | // 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
52 | // 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
53 | // 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
54 | // 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
55 | // 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.
56 | // 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.
57 | // 2022-01-12: Inputs: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
58 | // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
59 | // 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness.
60 | // 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages.
61 | // 2021-08-02: Inputs: Fixed keyboard modifiers being reported when host window doesn't have focus.
62 | // 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).
63 | // 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).
64 | // 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).
65 | // 2021-03-23: Inputs: Clearing keyboard down array when losing focus (WM_KILLFOCUS).
66 | // 2021-02-18: Added ImGui_ImplWin32_EnableAlphaCompositing(). Non Visual Studio users will need to link with dwmapi.lib (MinGW/gcc: use -ldwmapi).
67 | // 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.
68 | // 2021-01-25: Inputs: Dynamically loading XInput DLL.
69 | // 2020-12-04: Misc: Fixed setting of io.DisplaySize to invalid/uninitialized data when after hwnd has been closed.
70 | // 2020-03-03: Inputs: Calling AddInputCharacterUTF16() to support surrogate pairs leading to codepoint >= 0x10000 (for more complete CJK inputs)
71 | // 2020-02-17: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(), ImGui_ImplWin32_GetDpiScaleForMonitor() helper functions.
72 | // 2020-01-14: Inputs: Added support for #define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD/IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT.
73 | // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
74 | // 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter().
75 | // 2019-01-17: Misc: Using GetForegroundWindow()+IsChild() instead of GetActiveWindow() to be compatible with windows created in a different thread or parent.
76 | // 2019-01-17: Inputs: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages.
77 | // 2019-01-15: Inputs: Added support for XInput gamepads (if ImGuiConfigFlags_NavEnableGamepad is set by user application).
78 | // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
79 | // 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
80 | // 2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads).
81 | // 2018-06-08: Misc: Extracted imgui_impl_win32.cpp/.h away from the old combined DX9/DX10/DX11/DX12 examples.
82 | // 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoMouseCursorChange flag.
83 | // 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling).
84 | // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
85 | // 2018-02-06: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set).
86 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
87 | // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support.
88 | // 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert.
89 | // 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag.
90 | // 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read.
91 | // 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging.
92 | // 2016-11-12: Inputs: Only call Win32 ::SetCursor(nullptr) when io.MouseDrawCursor is set.
93 |
94 | struct ImGui_ImplWin32_Data
95 | {
96 | HWND hWnd;
97 | HWND MouseHwnd;
98 | int MouseTrackedArea; // 0: not tracked, 1: client are, 2: non-client area
99 | int MouseButtonsDown;
100 | INT64 Time;
101 | INT64 TicksPerSecond;
102 | ImGuiMouseCursor LastMouseCursor;
103 | UINT32 KeyboardCodePage;
104 |
105 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
106 | bool HasGamepad;
107 | bool WantUpdateHasGamepad;
108 | HMODULE XInputDLL;
109 | PFN_XInputGetCapabilities XInputGetCapabilities;
110 | PFN_XInputGetState XInputGetState;
111 | #endif
112 |
113 | ImGui_ImplWin32_Data() { memset((void*)this, 0, sizeof(*this)); }
114 | };
115 |
116 | // Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
117 | // It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
118 | // FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
119 | // FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
120 | static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData()
121 | {
122 | return ImGui::GetCurrentContext() ? (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
123 | }
124 |
125 | // Functions
126 | static void ImGui_ImplWin32_UpdateKeyboardCodePage()
127 | {
128 | // Retrieve keyboard code page, required for handling of non-Unicode Windows.
129 | ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
130 | HKL keyboard_layout = ::GetKeyboardLayout(0);
131 | LCID keyboard_lcid = MAKELCID(HIWORD(keyboard_layout), SORT_DEFAULT);
132 | if (::GetLocaleInfoA(keyboard_lcid, (LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE), (LPSTR)&bd->KeyboardCodePage, sizeof(bd->KeyboardCodePage)) == 0)
133 | bd->KeyboardCodePage = CP_ACP; // Fallback to default ANSI code page when fails.
134 | }
135 |
136 | static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
137 | {
138 | ImGuiIO& io = ImGui::GetIO();
139 | IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
140 |
141 | INT64 perf_frequency, perf_counter;
142 | if (!::QueryPerformanceFrequency((LARGE_INTEGER*)&perf_frequency))
143 | return false;
144 | if (!::QueryPerformanceCounter((LARGE_INTEGER*)&perf_counter))
145 | return false;
146 |
147 | // Setup backend capabilities flags
148 | ImGui_ImplWin32_Data* bd = IM_NEW(ImGui_ImplWin32_Data)();
149 | io.BackendPlatformUserData = (void*)bd;
150 | io.BackendPlatformName = "imgui_impl_win32";
151 | io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
152 | io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
153 |
154 | bd->hWnd = (HWND)hwnd;
155 | bd->TicksPerSecond = perf_frequency;
156 | bd->Time = perf_counter;
157 | bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
158 | ImGui_ImplWin32_UpdateKeyboardCodePage();
159 |
160 | // Set platform dependent data in viewport
161 | ImGui::GetMainViewport()->PlatformHandleRaw = (void*)hwnd;
162 | IM_UNUSED(platform_has_own_dc); // Used in 'docking' branch
163 |
164 | // Dynamically load XInput library
165 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
166 | bd->WantUpdateHasGamepad = true;
167 | const char* xinput_dll_names[] =
168 | {
169 | "xinput1_4.dll", // Windows 8+
170 | "xinput1_3.dll", // DirectX SDK
171 | "xinput9_1_0.dll", // Windows Vista, Windows 7
172 | "xinput1_2.dll", // DirectX SDK
173 | "xinput1_1.dll" // DirectX SDK
174 | };
175 | for (int n = 0; n < IM_ARRAYSIZE(xinput_dll_names); n++)
176 | if (HMODULE dll = ::LoadLibraryA(xinput_dll_names[n]))
177 | {
178 | bd->XInputDLL = dll;
179 | bd->XInputGetCapabilities = (PFN_XInputGetCapabilities)::GetProcAddress(dll, "XInputGetCapabilities");
180 | bd->XInputGetState = (PFN_XInputGetState)::GetProcAddress(dll, "XInputGetState");
181 | break;
182 | }
183 | #endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
184 |
185 | return true;
186 | }
187 |
188 | IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd)
189 | {
190 | return ImGui_ImplWin32_InitEx(hwnd, false);
191 | }
192 |
193 | IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd)
194 | {
195 | // OpenGL needs CS_OWNDC
196 | return ImGui_ImplWin32_InitEx(hwnd, true);
197 | }
198 |
199 | void ImGui_ImplWin32_Shutdown()
200 | {
201 | ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
202 | IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
203 | ImGuiIO& io = ImGui::GetIO();
204 |
205 | // Unload XInput library
206 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
207 | if (bd->XInputDLL)
208 | ::FreeLibrary(bd->XInputDLL);
209 | #endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
210 |
211 | io.BackendPlatformName = nullptr;
212 | io.BackendPlatformUserData = nullptr;
213 | io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad);
214 | IM_DELETE(bd);
215 | }
216 |
217 | static bool ImGui_ImplWin32_UpdateMouseCursor()
218 | {
219 | ImGuiIO& io = ImGui::GetIO();
220 | if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
221 | return false;
222 |
223 | ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
224 | if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
225 | {
226 | // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
227 | ::SetCursor(nullptr);
228 | }
229 | else
230 | {
231 | // Show OS mouse cursor
232 | LPTSTR win32_cursor = IDC_ARROW;
233 | switch (imgui_cursor)
234 | {
235 | case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break;
236 | case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break;
237 | case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break;
238 | case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break;
239 | case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break;
240 | case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break;
241 | case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break;
242 | case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break;
243 | case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break;
244 | }
245 | ::SetCursor(::LoadCursor(nullptr, win32_cursor));
246 | }
247 | return true;
248 | }
249 |
250 | static bool IsVkDown(int vk)
251 | {
252 | return (::GetKeyState(vk) & 0x8000) != 0;
253 | }
254 |
255 | static void ImGui_ImplWin32_AddKeyEvent(ImGuiKey key, bool down, int native_keycode, int native_scancode = -1)
256 | {
257 | ImGuiIO& io = ImGui::GetIO();
258 | io.AddKeyEvent(key, down);
259 | io.SetKeyEventNativeData(key, native_keycode, native_scancode); // To support legacy indexing (<1.87 user code)
260 | IM_UNUSED(native_scancode);
261 | }
262 |
263 | static void ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
264 | {
265 | // Left & right Shift keys: when both are pressed together, Windows tend to not generate the WM_KEYUP event for the first released one.
266 | if (ImGui::IsKeyDown(ImGuiKey_LeftShift) && !IsVkDown(VK_LSHIFT))
267 | ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, false, VK_LSHIFT);
268 | if (ImGui::IsKeyDown(ImGuiKey_RightShift) && !IsVkDown(VK_RSHIFT))
269 | ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, false, VK_RSHIFT);
270 |
271 | // Sometimes WM_KEYUP for Win key is not passed down to the app (e.g. for Win+V on some setups, according to GLFW).
272 | if (ImGui::IsKeyDown(ImGuiKey_LeftSuper) && !IsVkDown(VK_LWIN))
273 | ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftSuper, false, VK_LWIN);
274 | if (ImGui::IsKeyDown(ImGuiKey_RightSuper) && !IsVkDown(VK_RWIN))
275 | ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightSuper, false, VK_RWIN);
276 | }
277 |
278 | static void ImGui_ImplWin32_UpdateKeyModifiers()
279 | {
280 | ImGuiIO& io = ImGui::GetIO();
281 | io.AddKeyEvent(ImGuiMod_Ctrl, IsVkDown(VK_CONTROL));
282 | io.AddKeyEvent(ImGuiMod_Shift, IsVkDown(VK_SHIFT));
283 | io.AddKeyEvent(ImGuiMod_Alt, IsVkDown(VK_MENU));
284 | io.AddKeyEvent(ImGuiMod_Super, IsVkDown(VK_APPS));
285 | }
286 |
287 | static void ImGui_ImplWin32_UpdateMouseData()
288 | {
289 | ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
290 | ImGuiIO& io = ImGui::GetIO();
291 | IM_ASSERT(bd->hWnd != 0);
292 |
293 | HWND focused_window = ::GetForegroundWindow();
294 | const bool is_app_focused = (focused_window == bd->hWnd);
295 | if (is_app_focused)
296 | {
297 | // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
298 | if (io.WantSetMousePos)
299 | {
300 | POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
301 | if (::ClientToScreen(bd->hWnd, &pos))
302 | ::SetCursorPos(pos.x, pos.y);
303 | }
304 |
305 | // (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured)
306 | // This also fills a short gap when clicking non-client area: WM_NCMOUSELEAVE -> modal OS move -> gap -> WM_NCMOUSEMOVE
307 | if (!io.WantSetMousePos && bd->MouseTrackedArea == 0)
308 | {
309 | POINT pos;
310 | if (::GetCursorPos(&pos) && ::ScreenToClient(bd->hWnd, &pos))
311 | io.AddMousePosEvent((float)pos.x, (float)pos.y);
312 | }
313 | }
314 | }
315 |
316 | // Gamepad navigation mapping
317 | static void ImGui_ImplWin32_UpdateGamepads()
318 | {
319 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
320 | ImGuiIO& io = ImGui::GetIO();
321 | ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
322 | //if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
323 | // return;
324 |
325 | // Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow.
326 | // Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
327 | if (bd->WantUpdateHasGamepad)
328 | {
329 | XINPUT_CAPABILITIES caps = {};
330 | bd->HasGamepad = bd->XInputGetCapabilities ? (bd->XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS) : false;
331 | bd->WantUpdateHasGamepad = false;
332 | }
333 |
334 | io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
335 | XINPUT_STATE xinput_state;
336 | XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
337 | if (!bd->HasGamepad || bd->XInputGetState == nullptr || bd->XInputGetState(0, &xinput_state) != ERROR_SUCCESS)
338 | return;
339 | io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
340 |
341 | #define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
342 | #define MAP_BUTTON(KEY_NO, BUTTON_ENUM) { io.AddKeyEvent(KEY_NO, (gamepad.wButtons & BUTTON_ENUM) != 0); }
343 | #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)); }
344 | MAP_BUTTON(ImGuiKey_GamepadStart, XINPUT_GAMEPAD_START);
345 | MAP_BUTTON(ImGuiKey_GamepadBack, XINPUT_GAMEPAD_BACK);
346 | MAP_BUTTON(ImGuiKey_GamepadFaceLeft, XINPUT_GAMEPAD_X);
347 | MAP_BUTTON(ImGuiKey_GamepadFaceRight, XINPUT_GAMEPAD_B);
348 | MAP_BUTTON(ImGuiKey_GamepadFaceUp, XINPUT_GAMEPAD_Y);
349 | MAP_BUTTON(ImGuiKey_GamepadFaceDown, XINPUT_GAMEPAD_A);
350 | MAP_BUTTON(ImGuiKey_GamepadDpadLeft, XINPUT_GAMEPAD_DPAD_LEFT);
351 | MAP_BUTTON(ImGuiKey_GamepadDpadRight, XINPUT_GAMEPAD_DPAD_RIGHT);
352 | MAP_BUTTON(ImGuiKey_GamepadDpadUp, XINPUT_GAMEPAD_DPAD_UP);
353 | MAP_BUTTON(ImGuiKey_GamepadDpadDown, XINPUT_GAMEPAD_DPAD_DOWN);
354 | MAP_BUTTON(ImGuiKey_GamepadL1, XINPUT_GAMEPAD_LEFT_SHOULDER);
355 | MAP_BUTTON(ImGuiKey_GamepadR1, XINPUT_GAMEPAD_RIGHT_SHOULDER);
356 | MAP_ANALOG(ImGuiKey_GamepadL2, gamepad.bLeftTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD, 255);
357 | MAP_ANALOG(ImGuiKey_GamepadR2, gamepad.bRightTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD, 255);
358 | MAP_BUTTON(ImGuiKey_GamepadL3, XINPUT_GAMEPAD_LEFT_THUMB);
359 | MAP_BUTTON(ImGuiKey_GamepadR3, XINPUT_GAMEPAD_RIGHT_THUMB);
360 | MAP_ANALOG(ImGuiKey_GamepadLStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
361 | MAP_ANALOG(ImGuiKey_GamepadLStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
362 | MAP_ANALOG(ImGuiKey_GamepadLStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
363 | MAP_ANALOG(ImGuiKey_GamepadLStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
364 | MAP_ANALOG(ImGuiKey_GamepadRStickLeft, gamepad.sThumbRX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
365 | MAP_ANALOG(ImGuiKey_GamepadRStickRight, gamepad.sThumbRX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
366 | MAP_ANALOG(ImGuiKey_GamepadRStickUp, gamepad.sThumbRY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
367 | MAP_ANALOG(ImGuiKey_GamepadRStickDown, gamepad.sThumbRY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
368 | #undef MAP_BUTTON
369 | #undef MAP_ANALOG
370 | #endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
371 | }
372 |
373 | void ImGui_ImplWin32_NewFrame()
374 | {
375 | ImGuiIO& io = ImGui::GetIO();
376 | ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
377 | IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplWin32_Init()?");
378 |
379 | // Setup display size (every frame to accommodate for window resizing)
380 | RECT rect = { 0, 0, 0, 0 };
381 | ::GetClientRect(bd->hWnd, &rect);
382 | io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
383 |
384 | // Setup time step
385 | INT64 current_time = 0;
386 | ::QueryPerformanceCounter((LARGE_INTEGER*)¤t_time);
387 | io.DeltaTime = (float)(current_time - bd->Time) / bd->TicksPerSecond;
388 | bd->Time = current_time;
389 |
390 | // Update OS mouse position
391 | ImGui_ImplWin32_UpdateMouseData();
392 |
393 | // Process workarounds for known Windows key handling issues
394 | ImGui_ImplWin32_ProcessKeyEventsWorkarounds();
395 |
396 | // Update OS mouse cursor with the cursor requested by imgui
397 | ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
398 | if (bd->LastMouseCursor != mouse_cursor)
399 | {
400 | bd->LastMouseCursor = mouse_cursor;
401 | ImGui_ImplWin32_UpdateMouseCursor();
402 | }
403 |
404 | // Update game controllers (if enabled and available)
405 | ImGui_ImplWin32_UpdateGamepads();
406 | }
407 |
408 | // 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)
409 | #define IM_VK_KEYPAD_ENTER (VK_RETURN + 256)
410 |
411 | // Map VK_xxx to ImGuiKey_xxx.
412 | static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
413 | {
414 | switch (wParam)
415 | {
416 | case VK_TAB: return ImGuiKey_Tab;
417 | case VK_LEFT: return ImGuiKey_LeftArrow;
418 | case VK_RIGHT: return ImGuiKey_RightArrow;
419 | case VK_UP: return ImGuiKey_UpArrow;
420 | case VK_DOWN: return ImGuiKey_DownArrow;
421 | case VK_PRIOR: return ImGuiKey_PageUp;
422 | case VK_NEXT: return ImGuiKey_PageDown;
423 | case VK_HOME: return ImGuiKey_Home;
424 | case VK_END: return ImGuiKey_End;
425 | case VK_INSERT: return ImGuiKey_Insert;
426 | case VK_DELETE: return ImGuiKey_Delete;
427 | case VK_BACK: return ImGuiKey_Backspace;
428 | case VK_SPACE: return ImGuiKey_Space;
429 | case VK_RETURN: return ImGuiKey_Enter;
430 | case VK_ESCAPE: return ImGuiKey_Escape;
431 | case VK_OEM_7: return ImGuiKey_Apostrophe;
432 | case VK_OEM_COMMA: return ImGuiKey_Comma;
433 | case VK_OEM_MINUS: return ImGuiKey_Minus;
434 | case VK_OEM_PERIOD: return ImGuiKey_Period;
435 | case VK_OEM_2: return ImGuiKey_Slash;
436 | case VK_OEM_1: return ImGuiKey_Semicolon;
437 | case VK_OEM_PLUS: return ImGuiKey_Equal;
438 | case VK_OEM_4: return ImGuiKey_LeftBracket;
439 | case VK_OEM_5: return ImGuiKey_Backslash;
440 | case VK_OEM_6: return ImGuiKey_RightBracket;
441 | case VK_OEM_3: return ImGuiKey_GraveAccent;
442 | case VK_CAPITAL: return ImGuiKey_CapsLock;
443 | case VK_SCROLL: return ImGuiKey_ScrollLock;
444 | case VK_NUMLOCK: return ImGuiKey_NumLock;
445 | case VK_SNAPSHOT: return ImGuiKey_PrintScreen;
446 | case VK_PAUSE: return ImGuiKey_Pause;
447 | case VK_NUMPAD0: return ImGuiKey_Keypad0;
448 | case VK_NUMPAD1: return ImGuiKey_Keypad1;
449 | case VK_NUMPAD2: return ImGuiKey_Keypad2;
450 | case VK_NUMPAD3: return ImGuiKey_Keypad3;
451 | case VK_NUMPAD4: return ImGuiKey_Keypad4;
452 | case VK_NUMPAD5: return ImGuiKey_Keypad5;
453 | case VK_NUMPAD6: return ImGuiKey_Keypad6;
454 | case VK_NUMPAD7: return ImGuiKey_Keypad7;
455 | case VK_NUMPAD8: return ImGuiKey_Keypad8;
456 | case VK_NUMPAD9: return ImGuiKey_Keypad9;
457 | case VK_DECIMAL: return ImGuiKey_KeypadDecimal;
458 | case VK_DIVIDE: return ImGuiKey_KeypadDivide;
459 | case VK_MULTIPLY: return ImGuiKey_KeypadMultiply;
460 | case VK_SUBTRACT: return ImGuiKey_KeypadSubtract;
461 | case VK_ADD: return ImGuiKey_KeypadAdd;
462 | case IM_VK_KEYPAD_ENTER: return ImGuiKey_KeypadEnter;
463 | case VK_LSHIFT: return ImGuiKey_LeftShift;
464 | case VK_LCONTROL: return ImGuiKey_LeftCtrl;
465 | case VK_LMENU: return ImGuiKey_LeftAlt;
466 | case VK_LWIN: return ImGuiKey_LeftSuper;
467 | case VK_RSHIFT: return ImGuiKey_RightShift;
468 | case VK_RCONTROL: return ImGuiKey_RightCtrl;
469 | case VK_RMENU: return ImGuiKey_RightAlt;
470 | case VK_RWIN: return ImGuiKey_RightSuper;
471 | case VK_APPS: return ImGuiKey_Menu;
472 | case '0': return ImGuiKey_0;
473 | case '1': return ImGuiKey_1;
474 | case '2': return ImGuiKey_2;
475 | case '3': return ImGuiKey_3;
476 | case '4': return ImGuiKey_4;
477 | case '5': return ImGuiKey_5;
478 | case '6': return ImGuiKey_6;
479 | case '7': return ImGuiKey_7;
480 | case '8': return ImGuiKey_8;
481 | case '9': return ImGuiKey_9;
482 | case 'A': return ImGuiKey_A;
483 | case 'B': return ImGuiKey_B;
484 | case 'C': return ImGuiKey_C;
485 | case 'D': return ImGuiKey_D;
486 | case 'E': return ImGuiKey_E;
487 | case 'F': return ImGuiKey_F;
488 | case 'G': return ImGuiKey_G;
489 | case 'H': return ImGuiKey_H;
490 | case 'I': return ImGuiKey_I;
491 | case 'J': return ImGuiKey_J;
492 | case 'K': return ImGuiKey_K;
493 | case 'L': return ImGuiKey_L;
494 | case 'M': return ImGuiKey_M;
495 | case 'N': return ImGuiKey_N;
496 | case 'O': return ImGuiKey_O;
497 | case 'P': return ImGuiKey_P;
498 | case 'Q': return ImGuiKey_Q;
499 | case 'R': return ImGuiKey_R;
500 | case 'S': return ImGuiKey_S;
501 | case 'T': return ImGuiKey_T;
502 | case 'U': return ImGuiKey_U;
503 | case 'V': return ImGuiKey_V;
504 | case 'W': return ImGuiKey_W;
505 | case 'X': return ImGuiKey_X;
506 | case 'Y': return ImGuiKey_Y;
507 | case 'Z': return ImGuiKey_Z;
508 | case VK_F1: return ImGuiKey_F1;
509 | case VK_F2: return ImGuiKey_F2;
510 | case VK_F3: return ImGuiKey_F3;
511 | case VK_F4: return ImGuiKey_F4;
512 | case VK_F5: return ImGuiKey_F5;
513 | case VK_F6: return ImGuiKey_F6;
514 | case VK_F7: return ImGuiKey_F7;
515 | case VK_F8: return ImGuiKey_F8;
516 | case VK_F9: return ImGuiKey_F9;
517 | case VK_F10: return ImGuiKey_F10;
518 | case VK_F11: return ImGuiKey_F11;
519 | case VK_F12: return ImGuiKey_F12;
520 | case VK_F13: return ImGuiKey_F13;
521 | case VK_F14: return ImGuiKey_F14;
522 | case VK_F15: return ImGuiKey_F15;
523 | case VK_F16: return ImGuiKey_F16;
524 | case VK_F17: return ImGuiKey_F17;
525 | case VK_F18: return ImGuiKey_F18;
526 | case VK_F19: return ImGuiKey_F19;
527 | case VK_F20: return ImGuiKey_F20;
528 | case VK_F21: return ImGuiKey_F21;
529 | case VK_F22: return ImGuiKey_F22;
530 | case VK_F23: return ImGuiKey_F23;
531 | case VK_F24: return ImGuiKey_F24;
532 | case VK_BROWSER_BACK: return ImGuiKey_AppBack;
533 | case VK_BROWSER_FORWARD: return ImGuiKey_AppForward;
534 | default: return ImGuiKey_None;
535 | }
536 | }
537 |
538 | // Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
539 | #ifndef WM_MOUSEHWHEEL
540 | #define WM_MOUSEHWHEEL 0x020E
541 | #endif
542 | #ifndef DBT_DEVNODES_CHANGED
543 | #define DBT_DEVNODES_CHANGED 0x0007
544 | #endif
545 |
546 | // Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
547 | // Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
548 | // When implementing your own backend, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs.
549 | // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
550 | // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
551 | // Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags.
552 | // 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.
553 | // 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.
554 | #if 0
555 | // Copy this line into your .cpp file to forward declare the function.
556 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
557 | #endif
558 |
559 | // See https://learn.microsoft.com/en-us/windows/win32/tablet/system-events-and-mouse-messages
560 | // Prefer to call this at the top of the message handler to avoid the possibility of other Win32 calls interfering with this.
561 | static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
562 | {
563 | LPARAM extra_info = ::GetMessageExtraInfo();
564 | if ((extra_info & 0xFFFFFF80) == 0xFF515700)
565 | return ImGuiMouseSource_Pen;
566 | if ((extra_info & 0xFFFFFF80) == 0xFF515780)
567 | return ImGuiMouseSource_TouchScreen;
568 | return ImGuiMouseSource_Mouse;
569 | }
570 |
571 | IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
572 | {
573 | if (ImGui::GetCurrentContext() == nullptr)
574 | return 0;
575 |
576 | ImGuiIO& io = ImGui::GetIO();
577 | ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
578 |
579 | switch (msg)
580 | {
581 | case WM_MOUSEMOVE:
582 | case WM_NCMOUSEMOVE:
583 | {
584 | // We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
585 | ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
586 | const int area = (msg == WM_MOUSEMOVE) ? 1 : 2;
587 | bd->MouseHwnd = hwnd;
588 | if (bd->MouseTrackedArea != area)
589 | {
590 | TRACKMOUSEEVENT tme_cancel = { sizeof(tme_cancel), TME_CANCEL, hwnd, 0 };
591 | TRACKMOUSEEVENT tme_track = { sizeof(tme_track), (DWORD)((area == 2) ? (TME_LEAVE | TME_NONCLIENT) : TME_LEAVE), hwnd, 0 };
592 | if (bd->MouseTrackedArea != 0)
593 | ::TrackMouseEvent(&tme_cancel);
594 | ::TrackMouseEvent(&tme_track);
595 | bd->MouseTrackedArea = area;
596 | }
597 | POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) };
598 | if (msg == WM_NCMOUSEMOVE && ::ScreenToClient(hwnd, &mouse_pos) == FALSE) // WM_NCMOUSEMOVE are provided in absolute coordinates.
599 | break;
600 | io.AddMouseSourceEvent(mouse_source);
601 | io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
602 | break;
603 | }
604 | case WM_MOUSELEAVE:
605 | case WM_NCMOUSELEAVE:
606 | {
607 | const int area = (msg == WM_MOUSELEAVE) ? 1 : 2;
608 | if (bd->MouseTrackedArea == area)
609 | {
610 | if (bd->MouseHwnd == hwnd)
611 | bd->MouseHwnd = nullptr;
612 | bd->MouseTrackedArea = 0;
613 | io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
614 | }
615 | break;
616 | }
617 | case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
618 | case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
619 | case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
620 | case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
621 | {
622 | ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
623 | int button = 0;
624 | if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
625 | if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
626 | if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
627 | if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
628 | if (bd->MouseButtonsDown == 0 && ::GetCapture() == nullptr)
629 | ::SetCapture(hwnd);
630 | bd->MouseButtonsDown |= 1 << button;
631 | io.AddMouseSourceEvent(mouse_source);
632 | io.AddMouseButtonEvent(button, true);
633 | return 0;
634 | }
635 | case WM_LBUTTONUP:
636 | case WM_RBUTTONUP:
637 | case WM_MBUTTONUP:
638 | case WM_XBUTTONUP:
639 | {
640 | ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
641 | int button = 0;
642 | if (msg == WM_LBUTTONUP) { button = 0; }
643 | if (msg == WM_RBUTTONUP) { button = 1; }
644 | if (msg == WM_MBUTTONUP) { button = 2; }
645 | if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
646 | bd->MouseButtonsDown &= ~(1 << button);
647 | if (bd->MouseButtonsDown == 0 && ::GetCapture() == hwnd)
648 | ::ReleaseCapture();
649 | io.AddMouseSourceEvent(mouse_source);
650 | io.AddMouseButtonEvent(button, false);
651 | return 0;
652 | }
653 | case WM_MOUSEWHEEL:
654 | io.AddMouseWheelEvent(0.0f, (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA);
655 | return 0;
656 | case WM_MOUSEHWHEEL:
657 | io.AddMouseWheelEvent(-(float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA, 0.0f);
658 | return 0;
659 | case WM_KEYDOWN:
660 | case WM_KEYUP:
661 | case WM_SYSKEYDOWN:
662 | case WM_SYSKEYUP:
663 | {
664 | const bool is_key_down = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN);
665 | if (wParam < 256)
666 | {
667 | // Submit modifiers
668 | ImGui_ImplWin32_UpdateKeyModifiers();
669 |
670 | // Obtain virtual key code
671 | // (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.)
672 | int vk = (int)wParam;
673 | if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
674 | vk = IM_VK_KEYPAD_ENTER;
675 | const ImGuiKey key = ImGui_ImplWin32_VirtualKeyToImGuiKey(vk);
676 | const int scancode = (int)LOBYTE(HIWORD(lParam));
677 |
678 | // Special behavior for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit the key down event.
679 | if (key == ImGuiKey_PrintScreen && !is_key_down)
680 | ImGui_ImplWin32_AddKeyEvent(key, true, vk, scancode);
681 |
682 | // Submit key event
683 | if (key != ImGuiKey_None)
684 | ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode);
685 |
686 | // Submit individual left/right modifier events
687 | if (vk == VK_SHIFT)
688 | {
689 | // Important: Shift keys tend to get stuck when pressed together, missing key-up events are corrected in ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
690 | if (IsVkDown(VK_LSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, is_key_down, VK_LSHIFT, scancode); }
691 | if (IsVkDown(VK_RSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, is_key_down, VK_RSHIFT, scancode); }
692 | }
693 | else if (vk == VK_CONTROL)
694 | {
695 | if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftCtrl, is_key_down, VK_LCONTROL, scancode); }
696 | if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); }
697 | }
698 | else if (vk == VK_MENU)
699 | {
700 | if (IsVkDown(VK_LMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftAlt, is_key_down, VK_LMENU, scancode); }
701 | if (IsVkDown(VK_RMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightAlt, is_key_down, VK_RMENU, scancode); }
702 | }
703 | }
704 | return 0;
705 | }
706 | case WM_SETFOCUS:
707 | case WM_KILLFOCUS:
708 | io.AddFocusEvent(msg == WM_SETFOCUS);
709 | return 0;
710 | case WM_INPUTLANGCHANGE:
711 | ImGui_ImplWin32_UpdateKeyboardCodePage();
712 | return 0;
713 | case WM_CHAR:
714 | if (::IsWindowUnicode(hwnd))
715 | {
716 | // You can also use ToAscii()+GetKeyboardState() to retrieve characters.
717 | if (wParam > 0 && wParam < 0x10000)
718 | io.AddInputCharacterUTF16((unsigned short)wParam);
719 | }
720 | else
721 | {
722 | wchar_t wch = 0;
723 | ::MultiByteToWideChar(bd->KeyboardCodePage, MB_PRECOMPOSED, (char*)&wParam, 1, &wch, 1);
724 | io.AddInputCharacter(wch);
725 | }
726 | return 0;
727 | case WM_SETCURSOR:
728 | // This is required to restore cursor when transitioning from e.g resize borders to client area.
729 | if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor())
730 | return 1;
731 | return 0;
732 | case WM_DEVICECHANGE:
733 | #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
734 | if ((UINT)wParam == DBT_DEVNODES_CHANGED)
735 | bd->WantUpdateHasGamepad = true;
736 | #endif
737 | return 0;
738 | }
739 | return 0;
740 | }
741 |
742 |
743 | //--------------------------------------------------------------------------------------------------------
744 | // DPI-related helpers (optional)
745 | //--------------------------------------------------------------------------------------------------------
746 | // - Use to enable DPI awareness without having to create an application manifest.
747 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps.
748 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc.
749 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime,
750 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies.
751 | //---------------------------------------------------------------------------------------------------------
752 | // This is the scheme successfully used by GLFW (from which we borrowed some of the code) and other apps aiming to be highly portable.
753 | // ImGui_ImplWin32_EnableDpiAwareness() is just a helper called by main.cpp, we don't call it automatically.
754 | // If you are trying to implement your own backend for your own engine, you may ignore that noise.
755 | //---------------------------------------------------------------------------------------------------------
756 |
757 | // Perform our own check with RtlVerifyVersionInfo() instead of using functions from as they
758 | // require a manifest to be functional for checks above 8.1. See https://github.com/ocornut/imgui/issues/4200
759 | static BOOL _IsWindowsVersionOrGreater(WORD major, WORD minor, WORD)
760 | {
761 | typedef LONG(WINAPI* PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*, ULONG, ULONGLONG);
762 | static PFN_RtlVerifyVersionInfo RtlVerifyVersionInfoFn = nullptr;
763 | if (RtlVerifyVersionInfoFn == nullptr)
764 | if (HMODULE ntdllModule = ::GetModuleHandleA("ntdll.dll"))
765 | RtlVerifyVersionInfoFn = (PFN_RtlVerifyVersionInfo)GetProcAddress(ntdllModule, "RtlVerifyVersionInfo");
766 | if (RtlVerifyVersionInfoFn == nullptr)
767 | return FALSE;
768 |
769 | RTL_OSVERSIONINFOEXW versionInfo = { };
770 | ULONGLONG conditionMask = 0;
771 | versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
772 | versionInfo.dwMajorVersion = major;
773 | versionInfo.dwMinorVersion = minor;
774 | VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
775 | VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
776 | return (RtlVerifyVersionInfoFn(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask) == 0) ? TRUE : FALSE;
777 | }
778 |
779 | #define _IsWindowsVistaOrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0600), LOBYTE(0x0600), 0) // _WIN32_WINNT_VISTA
780 | #define _IsWindows8OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0) // _WIN32_WINNT_WIN8
781 | #define _IsWindows8Point1OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0603), LOBYTE(0x0603), 0) // _WIN32_WINNT_WINBLUE
782 | #define _IsWindows10OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0A00), LOBYTE(0x0A00), 0) // _WIN32_WINNT_WINTHRESHOLD / _WIN32_WINNT_WIN10
783 |
784 | #ifndef DPI_ENUMS_DECLARED
785 | typedef enum { PROCESS_DPI_UNAWARE = 0, PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS;
786 | typedef enum { MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2, MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE;
787 | #endif
788 | #ifndef _DPI_AWARENESS_CONTEXTS_
789 | DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
790 | #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE (DPI_AWARENESS_CONTEXT)-3
791 | #endif
792 | #ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
793 | #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (DPI_AWARENESS_CONTEXT)-4
794 | #endif
795 | typedef HRESULT(WINAPI* PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); // Shcore.lib + dll, Windows 8.1+
796 | typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib + dll, Windows 8.1+
797 | typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update)
798 |
799 | // Helper function to enable DPI awareness without setting up a manifest
800 | void ImGui_ImplWin32_EnableDpiAwareness()
801 | {
802 | if (_IsWindows10OrGreater())
803 | {
804 | static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process
805 | if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext"))
806 | {
807 | SetThreadDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
808 | return;
809 | }
810 | }
811 | if (_IsWindows8Point1OrGreater())
812 | {
813 | static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
814 | if (PFN_SetProcessDpiAwareness SetProcessDpiAwarenessFn = (PFN_SetProcessDpiAwareness)::GetProcAddress(shcore_dll, "SetProcessDpiAwareness"))
815 | {
816 | SetProcessDpiAwarenessFn(PROCESS_PER_MONITOR_DPI_AWARE);
817 | return;
818 | }
819 | }
820 | #if _WIN32_WINNT >= 0x0600
821 | ::SetProcessDPIAware();
822 | #endif
823 | }
824 |
825 | #if defined(_MSC_VER) && !defined(NOGDI)
826 | #pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps(). MinGW will require linking with '-lgdi32'
827 | #endif
828 |
829 | float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor)
830 | {
831 | UINT xdpi = 96, ydpi = 96;
832 | if (_IsWindows8Point1OrGreater())
833 | {
834 | static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
835 | static PFN_GetDpiForMonitor GetDpiForMonitorFn = nullptr;
836 | if (GetDpiForMonitorFn == nullptr && shcore_dll != nullptr)
837 | GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor");
838 | if (GetDpiForMonitorFn != nullptr)
839 | {
840 | GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
841 | IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
842 | return xdpi / 96.0f;
843 | }
844 | }
845 | #ifndef NOGDI
846 | const HDC dc = ::GetDC(nullptr);
847 | xdpi = ::GetDeviceCaps(dc, LOGPIXELSX);
848 | ydpi = ::GetDeviceCaps(dc, LOGPIXELSY);
849 | IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
850 | ::ReleaseDC(nullptr, dc);
851 | #endif
852 | return xdpi / 96.0f;
853 | }
854 |
855 | float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd)
856 | {
857 | HMONITOR monitor = ::MonitorFromWindow((HWND)hwnd, MONITOR_DEFAULTTONEAREST);
858 | return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor);
859 | }
860 |
861 | //---------------------------------------------------------------------------------------------------------
862 | // Transparency related helpers (optional)
863 | //--------------------------------------------------------------------------------------------------------
864 |
865 | #if defined(_MSC_VER)
866 | #pragma comment(lib, "dwmapi") // Link with dwmapi.lib. MinGW will require linking with '-ldwmapi'
867 | #endif
868 |
869 | // [experimental]
870 | // Borrowed from GLFW's function updateFramebufferTransparency() in src/win32_window.c
871 | // (the Dwm* functions are Vista era functions but we are borrowing logic from GLFW)
872 | void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
873 | {
874 | if (!_IsWindowsVistaOrGreater())
875 | return;
876 |
877 | BOOL composition;
878 | if (FAILED(::DwmIsCompositionEnabled(&composition)) || !composition)
879 | return;
880 |
881 | BOOL opaque;
882 | DWORD color;
883 | if (_IsWindows8OrGreater() || (SUCCEEDED(::DwmGetColorizationColor(&color, &opaque)) && !opaque))
884 | {
885 | HRGN region = ::CreateRectRgn(0, 0, -1, -1);
886 | DWM_BLURBEHIND bb = {};
887 | bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
888 | bb.hRgnBlur = region;
889 | bb.fEnable = TRUE;
890 | ::DwmEnableBlurBehindWindow((HWND)hwnd, &bb);
891 | ::DeleteObject(region);
892 | }
893 | else
894 | {
895 | DWM_BLURBEHIND bb = {};
896 | bb.dwFlags = DWM_BB_ENABLE;
897 | ::DwmEnableBlurBehindWindow((HWND)hwnd, &bb);
898 | }
899 | }
900 |
901 | //---------------------------------------------------------------------------------------------------------
902 |
903 | #endif // #ifndef IMGUI_DISABLE
904 |
--------------------------------------------------------------------------------
/src/Dependencies/include/ImGui/imgui_impl_win32.h:
--------------------------------------------------------------------------------
1 | // dear imgui: Platform Backend for Windows (standard windows API for 32-bits AND 64-bits applications)
2 | // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
3 |
4 | // Implemented features:
5 | // [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
6 | // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
7 | // [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]
8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
9 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
10 |
11 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
12 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
13 | // Learn about Dear ImGui:
14 | // - FAQ https://dearimgui.com/faq
15 | // - Getting Started https://dearimgui.com/getting-started
16 | // - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
17 | // - Introduction, links and more at the top of imgui.cpp
18 |
19 | #pragma once
20 | #include "imgui.h" // IMGUI_IMPL_API
21 | #ifndef IMGUI_DISABLE
22 |
23 | IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
24 | IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd);
25 | IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
26 | IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();
27 |
28 | // Win32 message handler your application need to call.
29 | // - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on from this helper.
30 | // - You should COPY the line below into your .cpp code to forward declare the function and then you can call it.
31 | // - Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
32 |
33 | #if 0
34 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
35 | #endif
36 |
37 | // DPI-related helpers (optional)
38 | // - Use to enable DPI awareness without having to create an application manifest.
39 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps.
40 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc.
41 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime,
42 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies.
43 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness();
44 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd
45 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor
46 |
47 | // Transparency related helpers (optional) [experimental]
48 | // - Use to enable alpha compositing transparency with the desktop.
49 | // - Use together with e.g. clearing your framebuffer with zero-alpha.
50 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd
51 |
52 | #endif // #ifndef IMGUI_DISABLE
53 |
--------------------------------------------------------------------------------
/src/Dependencies/include/ImGui/imgui_stdlib.h:
--------------------------------------------------------------------------------
1 | // dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.)
2 | // This is also an example of how you may wrap your own similar types.
3 |
4 | // Changelog:
5 | // - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
6 |
7 | // See more C++ related extension (fmt, RAII, syntaxis sugar) on Wiki:
8 | // https://github.com/ocornut/imgui/wiki/Useful-Extensions#cness
9 |
10 | #pragma once
11 |
12 | #include
13 |
14 | namespace ImGui
15 | {
16 | // ImGui::InputText() with std::string
17 | // Because text input needs dynamic resizing, we need to setup a callback to grow the capacity
18 | IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr);
19 | IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr);
20 | IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr);
21 | }
22 |
--------------------------------------------------------------------------------
/src/Dependencies/include/ImGui/imstb_rectpack.h:
--------------------------------------------------------------------------------
1 | // [DEAR IMGUI]
2 | // This is a slightly modified version of stb_rect_pack.h 1.01.
3 | // Grep for [DEAR IMGUI] to find the changes.
4 | //
5 | // stb_rect_pack.h - v1.01 - public domain - rectangle packing
6 | // Sean Barrett 2014
7 | //
8 | // Useful for e.g. packing rectangular textures into an atlas.
9 | // Does not do rotation.
10 | //
11 | // Before #including,
12 | //
13 | // #define STB_RECT_PACK_IMPLEMENTATION
14 | //
15 | // in the file that you want to have the implementation.
16 | //
17 | // Not necessarily the awesomest packing method, but better than
18 | // the totally naive one in stb_truetype (which is primarily what
19 | // this is meant to replace).
20 | //
21 | // Has only had a few tests run, may have issues.
22 | //
23 | // More docs to come.
24 | //
25 | // No memory allocations; uses qsort() and assert() from stdlib.
26 | // Can override those by defining STBRP_SORT and STBRP_ASSERT.
27 | //
28 | // This library currently uses the Skyline Bottom-Left algorithm.
29 | //
30 | // Please note: better rectangle packers are welcome! Please
31 | // implement them to the same API, but with a different init
32 | // function.
33 | //
34 | // Credits
35 | //
36 | // Library
37 | // Sean Barrett
38 | // Minor features
39 | // Martins Mozeiko
40 | // github:IntellectualKitty
41 | //
42 | // Bugfixes / warning fixes
43 | // Jeremy Jaussaud
44 | // Fabian Giesen
45 | //
46 | // Version history:
47 | //
48 | // 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
49 | // 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
50 | // 0.99 (2019-02-07) warning fixes
51 | // 0.11 (2017-03-03) return packing success/fail result
52 | // 0.10 (2016-10-25) remove cast-away-const to avoid warnings
53 | // 0.09 (2016-08-27) fix compiler warnings
54 | // 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
55 | // 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
56 | // 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
57 | // 0.05: added STBRP_ASSERT to allow replacing assert
58 | // 0.04: fixed minor bug in STBRP_LARGE_RECTS support
59 | // 0.01: initial release
60 | //
61 | // LICENSE
62 | //
63 | // See end of file for license information.
64 |
65 | //////////////////////////////////////////////////////////////////////////////
66 | //
67 | // INCLUDE SECTION
68 | //
69 |
70 | #ifndef STB_INCLUDE_STB_RECT_PACK_H
71 | #define STB_INCLUDE_STB_RECT_PACK_H
72 |
73 | #define STB_RECT_PACK_VERSION 1
74 |
75 | #ifdef STBRP_STATIC
76 | #define STBRP_DEF static
77 | #else
78 | #define STBRP_DEF extern
79 | #endif
80 |
81 | #ifdef __cplusplus
82 | extern "C" {
83 | #endif
84 |
85 | typedef struct stbrp_context stbrp_context;
86 | typedef struct stbrp_node stbrp_node;
87 | typedef struct stbrp_rect stbrp_rect;
88 |
89 | typedef int stbrp_coord;
90 |
91 | #define STBRP__MAXVAL 0x7fffffff
92 | // Mostly for internal use, but this is the maximum supported coordinate value.
93 |
94 | STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
95 | // Assign packed locations to rectangles. The rectangles are of type
96 | // 'stbrp_rect' defined below, stored in the array 'rects', and there
97 | // are 'num_rects' many of them.
98 | //
99 | // Rectangles which are successfully packed have the 'was_packed' flag
100 | // set to a non-zero value and 'x' and 'y' store the minimum location
101 | // on each axis (i.e. bottom-left in cartesian coordinates, top-left
102 | // if you imagine y increasing downwards). Rectangles which do not fit
103 | // have the 'was_packed' flag set to 0.
104 | //
105 | // You should not try to access the 'rects' array from another thread
106 | // while this function is running, as the function temporarily reorders
107 | // the array while it executes.
108 | //
109 | // To pack into another rectangle, you need to call stbrp_init_target
110 | // again. To continue packing into the same rectangle, you can call
111 | // this function again. Calling this multiple times with multiple rect
112 | // arrays will probably produce worse packing results than calling it
113 | // a single time with the full rectangle array, but the option is
114 | // available.
115 | //
116 | // The function returns 1 if all of the rectangles were successfully
117 | // packed and 0 otherwise.
118 |
119 | struct stbrp_rect
120 | {
121 | // reserved for your use:
122 | int id;
123 |
124 | // input:
125 | stbrp_coord w, h;
126 |
127 | // output:
128 | stbrp_coord x, y;
129 | int was_packed; // non-zero if valid packing
130 |
131 | }; // 16 bytes, nominally
132 |
133 |
134 | STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
135 | // Initialize a rectangle packer to:
136 | // pack a rectangle that is 'width' by 'height' in dimensions
137 | // using temporary storage provided by the array 'nodes', which is 'num_nodes' long
138 | //
139 | // You must call this function every time you start packing into a new target.
140 | //
141 | // There is no "shutdown" function. The 'nodes' memory must stay valid for
142 | // the following stbrp_pack_rects() call (or calls), but can be freed after
143 | // the call (or calls) finish.
144 | //
145 | // Note: to guarantee best results, either:
146 | // 1. make sure 'num_nodes' >= 'width'
147 | // or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
148 | //
149 | // If you don't do either of the above things, widths will be quantized to multiples
150 | // of small integers to guarantee the algorithm doesn't run out of temporary storage.
151 | //
152 | // If you do #2, then the non-quantized algorithm will be used, but the algorithm
153 | // may run out of temporary storage and be unable to pack some rectangles.
154 |
155 | STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
156 | // Optionally call this function after init but before doing any packing to
157 | // change the handling of the out-of-temp-memory scenario, described above.
158 | // If you call init again, this will be reset to the default (false).
159 |
160 |
161 | STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
162 | // Optionally select which packing heuristic the library should use. Different
163 | // heuristics will produce better/worse results for different data sets.
164 | // If you call init again, this will be reset to the default.
165 |
166 | enum
167 | {
168 | STBRP_HEURISTIC_Skyline_default=0,
169 | STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
170 | STBRP_HEURISTIC_Skyline_BF_sortHeight
171 | };
172 |
173 |
174 | //////////////////////////////////////////////////////////////////////////////
175 | //
176 | // the details of the following structures don't matter to you, but they must
177 | // be visible so you can handle the memory allocations for them
178 |
179 | struct stbrp_node
180 | {
181 | stbrp_coord x,y;
182 | stbrp_node *next;
183 | };
184 |
185 | struct stbrp_context
186 | {
187 | int width;
188 | int height;
189 | int align;
190 | int init_mode;
191 | int heuristic;
192 | int num_nodes;
193 | stbrp_node *active_head;
194 | stbrp_node *free_head;
195 | stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
196 | };
197 |
198 | #ifdef __cplusplus
199 | }
200 | #endif
201 |
202 | #endif
203 |
204 | //////////////////////////////////////////////////////////////////////////////
205 | //
206 | // IMPLEMENTATION SECTION
207 | //
208 |
209 | #ifdef STB_RECT_PACK_IMPLEMENTATION
210 | #ifndef STBRP_SORT
211 | #include
212 | #define STBRP_SORT qsort
213 | #endif
214 |
215 | #ifndef STBRP_ASSERT
216 | #include
217 | #define STBRP_ASSERT assert
218 | #endif
219 |
220 | #ifdef _MSC_VER
221 | #define STBRP__NOTUSED(v) (void)(v)
222 | #define STBRP__CDECL __cdecl
223 | #else
224 | #define STBRP__NOTUSED(v) (void)sizeof(v)
225 | #define STBRP__CDECL
226 | #endif
227 |
228 | enum
229 | {
230 | STBRP__INIT_skyline = 1
231 | };
232 |
233 | STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
234 | {
235 | switch (context->init_mode) {
236 | case STBRP__INIT_skyline:
237 | STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
238 | context->heuristic = heuristic;
239 | break;
240 | default:
241 | STBRP_ASSERT(0);
242 | }
243 | }
244 |
245 | STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
246 | {
247 | if (allow_out_of_mem)
248 | // if it's ok to run out of memory, then don't bother aligning them;
249 | // this gives better packing, but may fail due to OOM (even though
250 | // the rectangles easily fit). @TODO a smarter approach would be to only
251 | // quantize once we've hit OOM, then we could get rid of this parameter.
252 | context->align = 1;
253 | else {
254 | // if it's not ok to run out of memory, then quantize the widths
255 | // so that num_nodes is always enough nodes.
256 | //
257 | // I.e. num_nodes * align >= width
258 | // align >= width / num_nodes
259 | // align = ceil(width/num_nodes)
260 |
261 | context->align = (context->width + context->num_nodes-1) / context->num_nodes;
262 | }
263 | }
264 |
265 | STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
266 | {
267 | int i;
268 |
269 | for (i=0; i < num_nodes-1; ++i)
270 | nodes[i].next = &nodes[i+1];
271 | nodes[i].next = NULL;
272 | context->init_mode = STBRP__INIT_skyline;
273 | context->heuristic = STBRP_HEURISTIC_Skyline_default;
274 | context->free_head = &nodes[0];
275 | context->active_head = &context->extra[0];
276 | context->width = width;
277 | context->height = height;
278 | context->num_nodes = num_nodes;
279 | stbrp_setup_allow_out_of_mem(context, 0);
280 |
281 | // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
282 | context->extra[0].x = 0;
283 | context->extra[0].y = 0;
284 | context->extra[0].next = &context->extra[1];
285 | context->extra[1].x = (stbrp_coord) width;
286 | context->extra[1].y = (1<<30);
287 | context->extra[1].next = NULL;
288 | }
289 |
290 | // find minimum y position if it starts at x1
291 | static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
292 | {
293 | stbrp_node *node = first;
294 | int x1 = x0 + width;
295 | int min_y, visited_width, waste_area;
296 |
297 | STBRP__NOTUSED(c);
298 |
299 | STBRP_ASSERT(first->x <= x0);
300 |
301 | #if 0
302 | // skip in case we're past the node
303 | while (node->next->x <= x0)
304 | ++node;
305 | #else
306 | STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
307 | #endif
308 |
309 | STBRP_ASSERT(node->x <= x0);
310 |
311 | min_y = 0;
312 | waste_area = 0;
313 | visited_width = 0;
314 | while (node->x < x1) {
315 | if (node->y > min_y) {
316 | // raise min_y higher.
317 | // we've accounted for all waste up to min_y,
318 | // but we'll now add more waste for everything we've visted
319 | waste_area += visited_width * (node->y - min_y);
320 | min_y = node->y;
321 | // the first time through, visited_width might be reduced
322 | if (node->x < x0)
323 | visited_width += node->next->x - x0;
324 | else
325 | visited_width += node->next->x - node->x;
326 | } else {
327 | // add waste area
328 | int under_width = node->next->x - node->x;
329 | if (under_width + visited_width > width)
330 | under_width = width - visited_width;
331 | waste_area += under_width * (min_y - node->y);
332 | visited_width += under_width;
333 | }
334 | node = node->next;
335 | }
336 |
337 | *pwaste = waste_area;
338 | return min_y;
339 | }
340 |
341 | typedef struct
342 | {
343 | int x,y;
344 | stbrp_node **prev_link;
345 | } stbrp__findresult;
346 |
347 | static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
348 | {
349 | int best_waste = (1<<30), best_x, best_y = (1 << 30);
350 | stbrp__findresult fr;
351 | stbrp_node **prev, *node, *tail, **best = NULL;
352 |
353 | // align to multiple of c->align
354 | width = (width + c->align - 1);
355 | width -= width % c->align;
356 | STBRP_ASSERT(width % c->align == 0);
357 |
358 | // if it can't possibly fit, bail immediately
359 | if (width > c->width || height > c->height) {
360 | fr.prev_link = NULL;
361 | fr.x = fr.y = 0;
362 | return fr;
363 | }
364 |
365 | node = c->active_head;
366 | prev = &c->active_head;
367 | while (node->x + width <= c->width) {
368 | int y,waste;
369 | y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
370 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
371 | // bottom left
372 | if (y < best_y) {
373 | best_y = y;
374 | best = prev;
375 | }
376 | } else {
377 | // best-fit
378 | if (y + height <= c->height) {
379 | // can only use it if it first vertically
380 | if (y < best_y || (y == best_y && waste < best_waste)) {
381 | best_y = y;
382 | best_waste = waste;
383 | best = prev;
384 | }
385 | }
386 | }
387 | prev = &node->next;
388 | node = node->next;
389 | }
390 |
391 | best_x = (best == NULL) ? 0 : (*best)->x;
392 |
393 | // if doing best-fit (BF), we also have to try aligning right edge to each node position
394 | //
395 | // e.g, if fitting
396 | //
397 | // ____________________
398 | // |____________________|
399 | //
400 | // into
401 | //
402 | // | |
403 | // | ____________|
404 | // |____________|
405 | //
406 | // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
407 | //
408 | // This makes BF take about 2x the time
409 |
410 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
411 | tail = c->active_head;
412 | node = c->active_head;
413 | prev = &c->active_head;
414 | // find first node that's admissible
415 | while (tail->x < width)
416 | tail = tail->next;
417 | while (tail) {
418 | int xpos = tail->x - width;
419 | int y,waste;
420 | STBRP_ASSERT(xpos >= 0);
421 | // find the left position that matches this
422 | while (node->next->x <= xpos) {
423 | prev = &node->next;
424 | node = node->next;
425 | }
426 | STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
427 | y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
428 | if (y + height <= c->height) {
429 | if (y <= best_y) {
430 | if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
431 | best_x = xpos;
432 | //STBRP_ASSERT(y <= best_y); [DEAR IMGUI]
433 | best_y = y;
434 | best_waste = waste;
435 | best = prev;
436 | }
437 | }
438 | }
439 | tail = tail->next;
440 | }
441 | }
442 |
443 | fr.prev_link = best;
444 | fr.x = best_x;
445 | fr.y = best_y;
446 | return fr;
447 | }
448 |
449 | static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
450 | {
451 | // find best position according to heuristic
452 | stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
453 | stbrp_node *node, *cur;
454 |
455 | // bail if:
456 | // 1. it failed
457 | // 2. the best node doesn't fit (we don't always check this)
458 | // 3. we're out of memory
459 | if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
460 | res.prev_link = NULL;
461 | return res;
462 | }
463 |
464 | // on success, create new node
465 | node = context->free_head;
466 | node->x = (stbrp_coord) res.x;
467 | node->y = (stbrp_coord) (res.y + height);
468 |
469 | context->free_head = node->next;
470 |
471 | // insert the new node into the right starting point, and
472 | // let 'cur' point to the remaining nodes needing to be
473 | // stiched back in
474 |
475 | cur = *res.prev_link;
476 | if (cur->x < res.x) {
477 | // preserve the existing one, so start testing with the next one
478 | stbrp_node *next = cur->next;
479 | cur->next = node;
480 | cur = next;
481 | } else {
482 | *res.prev_link = node;
483 | }
484 |
485 | // from here, traverse cur and free the nodes, until we get to one
486 | // that shouldn't be freed
487 | while (cur->next && cur->next->x <= res.x + width) {
488 | stbrp_node *next = cur->next;
489 | // move the current node to the free list
490 | cur->next = context->free_head;
491 | context->free_head = cur;
492 | cur = next;
493 | }
494 |
495 | // stitch the list back in
496 | node->next = cur;
497 |
498 | if (cur->x < res.x + width)
499 | cur->x = (stbrp_coord) (res.x + width);
500 |
501 | #ifdef _DEBUG
502 | cur = context->active_head;
503 | while (cur->x < context->width) {
504 | STBRP_ASSERT(cur->x < cur->next->x);
505 | cur = cur->next;
506 | }
507 | STBRP_ASSERT(cur->next == NULL);
508 |
509 | {
510 | int count=0;
511 | cur = context->active_head;
512 | while (cur) {
513 | cur = cur->next;
514 | ++count;
515 | }
516 | cur = context->free_head;
517 | while (cur) {
518 | cur = cur->next;
519 | ++count;
520 | }
521 | STBRP_ASSERT(count == context->num_nodes+2);
522 | }
523 | #endif
524 |
525 | return res;
526 | }
527 |
528 | static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
529 | {
530 | const stbrp_rect *p = (const stbrp_rect *) a;
531 | const stbrp_rect *q = (const stbrp_rect *) b;
532 | if (p->h > q->h)
533 | return -1;
534 | if (p->h < q->h)
535 | return 1;
536 | return (p->w > q->w) ? -1 : (p->w < q->w);
537 | }
538 |
539 | static int STBRP__CDECL rect_original_order(const void *a, const void *b)
540 | {
541 | const stbrp_rect *p = (const stbrp_rect *) a;
542 | const stbrp_rect *q = (const stbrp_rect *) b;
543 | return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
544 | }
545 |
546 | STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
547 | {
548 | int i, all_rects_packed = 1;
549 |
550 | // we use the 'was_packed' field internally to allow sorting/unsorting
551 | for (i=0; i < num_rects; ++i) {
552 | rects[i].was_packed = i;
553 | }
554 |
555 | // sort according to heuristic
556 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
557 |
558 | for (i=0; i < num_rects; ++i) {
559 | if (rects[i].w == 0 || rects[i].h == 0) {
560 | rects[i].x = rects[i].y = 0; // empty rect needs no space
561 | } else {
562 | stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
563 | if (fr.prev_link) {
564 | rects[i].x = (stbrp_coord) fr.x;
565 | rects[i].y = (stbrp_coord) fr.y;
566 | } else {
567 | rects[i].x = rects[i].y = STBRP__MAXVAL;
568 | }
569 | }
570 | }
571 |
572 | // unsort
573 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
574 |
575 | // set was_packed flags and all_rects_packed status
576 | for (i=0; i < num_rects; ++i) {
577 | rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
578 | if (!rects[i].was_packed)
579 | all_rects_packed = 0;
580 | }
581 |
582 | // return the all_rects_packed status
583 | return all_rects_packed;
584 | }
585 | #endif
586 |
587 | /*
588 | ------------------------------------------------------------------------------
589 | This software is available under 2 licenses -- choose whichever you prefer.
590 | ------------------------------------------------------------------------------
591 | ALTERNATIVE A - MIT License
592 | Copyright (c) 2017 Sean Barrett
593 | Permission is hereby granted, free of charge, to any person obtaining a copy of
594 | this software and associated documentation files (the "Software"), to deal in
595 | the Software without restriction, including without limitation the rights to
596 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
597 | of the Software, and to permit persons to whom the Software is furnished to do
598 | so, subject to the following conditions:
599 | The above copyright notice and this permission notice shall be included in all
600 | copies or substantial portions of the Software.
601 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
602 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
603 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
604 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
605 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
606 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
607 | SOFTWARE.
608 | ------------------------------------------------------------------------------
609 | ALTERNATIVE B - Public Domain (www.unlicense.org)
610 | This is free and unencumbered software released into the public domain.
611 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
612 | software, either in source code form or as a compiled binary, for any purpose,
613 | commercial or non-commercial, and by any means.
614 | In jurisdictions that recognize copyright laws, the author or authors of this
615 | software dedicate any and all copyright interest in the software to the public
616 | domain. We make this dedication for the benefit of the public at large and to
617 | the detriment of our heirs and successors. We intend this dedication to be an
618 | overt act of relinquishment in perpetuity of all present and future rights to
619 | this software under copyright law.
620 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
621 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
622 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
623 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
624 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
625 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
626 | ------------------------------------------------------------------------------
627 | */
628 |
--------------------------------------------------------------------------------
/src/Dependencies/include/MinHook.h:
--------------------------------------------------------------------------------
1 | /*
2 | * MinHook - The Minimalistic API Hooking Library for x64/x86
3 | * Copyright (C) 2009-2017 Tsuda Kageyu.
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions
8 | * are met:
9 | *
10 | * 1. Redistributions of source code must retain the above copyright
11 | * notice, this list of conditions and the following disclaimer.
12 | * 2. Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | *
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
20 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | */
28 |
29 | #pragma once
30 |
31 | #if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__)
32 | #error MinHook supports only x86 and x64 systems.
33 | #endif
34 |
35 | #include
36 |
37 | // MinHook Error Codes.
38 | typedef enum MH_STATUS
39 | {
40 | // Unknown error. Should not be returned.
41 | MH_UNKNOWN = -1,
42 |
43 | // Successful.
44 | MH_OK = 0,
45 |
46 | // MinHook is already initialized.
47 | MH_ERROR_ALREADY_INITIALIZED,
48 |
49 | // MinHook is not initialized yet, or already uninitialized.
50 | MH_ERROR_NOT_INITIALIZED,
51 |
52 | // The hook for the specified target function is already created.
53 | MH_ERROR_ALREADY_CREATED,
54 |
55 | // The hook for the specified target function is not created yet.
56 | MH_ERROR_NOT_CREATED,
57 |
58 | // The hook for the specified target function is already enabled.
59 | MH_ERROR_ENABLED,
60 |
61 | // The hook for the specified target function is not enabled yet, or already
62 | // disabled.
63 | MH_ERROR_DISABLED,
64 |
65 | // The specified pointer is invalid. It points the address of non-allocated
66 | // and/or non-executable region.
67 | MH_ERROR_NOT_EXECUTABLE,
68 |
69 | // The specified target function cannot be hooked.
70 | MH_ERROR_UNSUPPORTED_FUNCTION,
71 |
72 | // Failed to allocate memory.
73 | MH_ERROR_MEMORY_ALLOC,
74 |
75 | // Failed to change the memory protection.
76 | MH_ERROR_MEMORY_PROTECT,
77 |
78 | // The specified module is not loaded.
79 | MH_ERROR_MODULE_NOT_FOUND,
80 |
81 | // The specified function is not found.
82 | MH_ERROR_FUNCTION_NOT_FOUND
83 | }
84 | MH_STATUS;
85 |
86 | // Can be passed as a parameter to MH_EnableHook, MH_DisableHook,
87 | // MH_QueueEnableHook or MH_QueueDisableHook.
88 | #define MH_ALL_HOOKS NULL
89 |
90 | #ifdef __cplusplus
91 | extern "C" {
92 | #endif
93 |
94 | // Initialize the MinHook library. You must call this function EXACTLY ONCE
95 | // at the beginning of your program.
96 | MH_STATUS WINAPI MH_Initialize(VOID);
97 |
98 | // Uninitialize the MinHook library. You must call this function EXACTLY
99 | // ONCE at the end of your program.
100 | MH_STATUS WINAPI MH_Uninitialize(VOID);
101 |
102 | // Creates a Hook for the specified target function, in disabled state.
103 | // Parameters:
104 | // pTarget [in] A pointer to the target function, which will be
105 | // overridden by the detour function.
106 | // pDetour [in] A pointer to the detour function, which will override
107 | // the target function.
108 | // ppOriginal [out] A pointer to the trampoline function, which will be
109 | // used to call the original target function.
110 | // This parameter can be NULL.
111 | MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal);
112 |
113 | // Creates a Hook for the specified API function, in disabled state.
114 | // Parameters:
115 | // pszModule [in] A pointer to the loaded module name which contains the
116 | // target function.
117 | // pszTarget [in] A pointer to the target function name, which will be
118 | // overridden by the detour function.
119 | // pDetour [in] A pointer to the detour function, which will override
120 | // the target function.
121 | // ppOriginal [out] A pointer to the trampoline function, which will be
122 | // used to call the original target function.
123 | // This parameter can be NULL.
124 | MH_STATUS WINAPI MH_CreateHookApi(
125 | LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal);
126 |
127 | // Creates a Hook for the specified API function, in disabled state.
128 | // Parameters:
129 | // pszModule [in] A pointer to the loaded module name which contains the
130 | // target function.
131 | // pszTarget [in] A pointer to the target function name, which will be
132 | // overridden by the detour function.
133 | // pDetour [in] A pointer to the detour function, which will override
134 | // the target function.
135 | // ppOriginal [out] A pointer to the trampoline function, which will be
136 | // used to call the original target function.
137 | // This parameter can be NULL.
138 | // ppTarget [out] A pointer to the target function, which will be used
139 | // with other functions.
140 | // This parameter can be NULL.
141 | MH_STATUS WINAPI MH_CreateHookApiEx(
142 | LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget);
143 |
144 | // Removes an already created hook.
145 | // Parameters:
146 | // pTarget [in] A pointer to the target function.
147 | MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget);
148 |
149 | // Enables an already created hook.
150 | // Parameters:
151 | // pTarget [in] A pointer to the target function.
152 | // If this parameter is MH_ALL_HOOKS, all created hooks are
153 | // enabled in one go.
154 | MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget);
155 |
156 | // Disables an already created hook.
157 | // Parameters:
158 | // pTarget [in] A pointer to the target function.
159 | // If this parameter is MH_ALL_HOOKS, all created hooks are
160 | // disabled in one go.
161 | MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget);
162 |
163 | // Queues to enable an already created hook.
164 | // Parameters:
165 | // pTarget [in] A pointer to the target function.
166 | // If this parameter is MH_ALL_HOOKS, all created hooks are
167 | // queued to be enabled.
168 | MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget);
169 |
170 | // Queues to disable an already created hook.
171 | // Parameters:
172 | // pTarget [in] A pointer to the target function.
173 | // If this parameter is MH_ALL_HOOKS, all created hooks are
174 | // queued to be disabled.
175 | MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget);
176 |
177 | // Applies all queued changes in one go.
178 | MH_STATUS WINAPI MH_ApplyQueued(VOID);
179 |
180 | // Translates the MH_STATUS to its name as a string.
181 | const char * WINAPI MH_StatusToString(MH_STATUS status);
182 |
183 | #ifdef __cplusplus
184 | }
185 | #endif
186 |
187 |
--------------------------------------------------------------------------------
/src/Dependencies/lib/imgui.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/axxo1337/OpenGL-Hk/59d2efbd57360023d58b9ce663d5cf64887c236f/src/Dependencies/lib/imgui.lib
--------------------------------------------------------------------------------
/src/Dependencies/lib/libMinHook-x64.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/axxo1337/OpenGL-Hk/59d2efbd57360023d58b9ce663d5cf64887c236f/src/Dependencies/lib/libMinHook-x64.lib
--------------------------------------------------------------------------------
/src/GUI.cpp:
--------------------------------------------------------------------------------
1 | #include "GUI.h"
2 |
3 | static bool is_init{};
4 | static bool do_draw{true};
5 |
6 | //
7 | // Management functions
8 | //
9 |
10 | bool GUI::init(HWND wnd_handle)
11 | {
12 | if (is_init)
13 | return false;
14 |
15 | ImGui::CreateContext();
16 | ImGuiIO& io = ImGui::GetIO(); (void)io;
17 | ImGui::StyleColorsDark();
18 | ImGui_ImplWin32_Init(wnd_handle);
19 | ImGui_ImplOpenGL3_Init();
20 |
21 | is_init = true;
22 |
23 | return false;
24 | }
25 |
26 | void GUI::shutdown()
27 | {
28 | if (!is_init)
29 | return;
30 |
31 | ImGui_ImplOpenGL3_Shutdown();
32 | ImGui_ImplWin32_Shutdown();
33 | ImGui::DestroyContext();
34 |
35 | is_init = false;
36 | }
37 |
38 | //
39 | // Global functions
40 | //
41 |
42 | void GUI::draw()
43 | {
44 | if (!do_draw)
45 | return;
46 |
47 | printf("TEST\n");
48 |
49 | ImGui_ImplOpenGL3_NewFrame();
50 | ImGui_ImplWin32_NewFrame();
51 | ImGui::NewFrame();
52 | ImGui::Begin("OpenGL-Hk");
53 | {
54 | ImGui::Text("Hello, World!");
55 | }
56 | ImGui::End();
57 | ImGui::EndFrame();
58 | ImGui::Render();
59 | ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
60 | }
61 |
62 | //
63 | // Get & Set functions
64 | //
65 |
66 | bool GUI::getIsInit()
67 | {
68 | return is_init;
69 | }
70 |
71 | bool GUI::getDoDraw()
72 | {
73 | return do_draw;
74 | }
75 |
76 | void GUI::setDoDraw(bool new_value)
77 | {
78 | do_draw = new_value;
79 | }
80 |
--------------------------------------------------------------------------------
/src/GUI.h:
--------------------------------------------------------------------------------
1 | #ifndef GUI_H_
2 | #define GUI_H_
3 |
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | namespace GUI
12 | {
13 | //
14 | // Management functions
15 | //
16 |
17 | bool init(HWND wnd_handle);
18 | void shutdown();
19 |
20 | //
21 | // Global functions
22 | //
23 |
24 | void draw();
25 |
26 | //
27 | // Get & Set functions
28 | //
29 |
30 | bool getIsInit();
31 | bool getDoDraw();
32 |
33 | void setDoDraw(bool new_value);
34 | }
35 |
36 | #endif
--------------------------------------------------------------------------------
/src/Hook.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "Hook.h"
5 | #include "GUI.h"
6 |
7 | typedef BOOL(__stdcall* TWglSwapBuffers) (HDC hDc);
8 |
9 | static bool is_init{};
10 | static HWND wnd_handle{};
11 | static WNDPROC origin_wndproc{};
12 | void* p_swap_buffers{};
13 | TWglSwapBuffers origin_wglSwapBuffers{};
14 |
15 | static LRESULT __stdcall WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
16 | static bool __stdcall wglSwapBuffers(HDC hDc);
17 |
18 | //
19 | // Management functions
20 | //
21 |
22 | bool Hook::init()
23 | {
24 | if (is_init)
25 | return false;
26 |
27 | /* WndProc */
28 | {
29 | // Older versions of mincraft
30 | wnd_handle = FindWindowA("LWJGL", nullptr);
31 |
32 | /* If failed to get window handle, attempt using window class used by more recent versions of minecraft */
33 | if (!wnd_handle)
34 | {
35 | wnd_handle = FindWindowA("GLFW30", nullptr);
36 |
37 | /* At this point cannot find minecraft window */
38 | if (!wnd_handle)
39 | {
40 | printf("[-] Failed to get window handle\n");
41 | return true;
42 | }
43 | }
44 |
45 | origin_wndproc = (WNDPROC)SetWindowLongPtrW(wnd_handle, GWLP_WNDPROC, (LONG_PTR)WndProc);
46 | }
47 |
48 | MH_Initialize();
49 |
50 | /* wglSwapBuffers */
51 | {
52 | p_swap_buffers = (void*)GetProcAddress(GetModuleHandleA("opengl32.dll"), "wglSwapBuffers");
53 |
54 | if (p_swap_buffers == nullptr)
55 | {
56 | printf("[-] Failed to get wglSwapBuffers' address\n");
57 | return true;
58 | }
59 |
60 | MH_CreateHook(p_swap_buffers, &wglSwapBuffers, (LPVOID*)&origin_wglSwapBuffers);
61 | }
62 |
63 | MH_EnableHook(MH_ALL_HOOKS);
64 |
65 | is_init = true;
66 |
67 | return false;
68 | }
69 |
70 | void Hook::shutdown()
71 | {
72 | if (!is_init)
73 | return;
74 |
75 | SetWindowLongPtrW(wnd_handle, GWLP_WNDPROC, (LONG_PTR)origin_wndproc);
76 | MH_DisableHook(MH_ALL_HOOKS);
77 | MH_RemoveHook(MH_ALL_HOOKS);
78 |
79 | is_init = false;
80 | }
81 |
82 | //
83 | // Get functions
84 | //
85 |
86 | bool Hook::getIsInit()
87 | {
88 | return is_init;
89 | }
90 |
91 | //
92 | // Hooks
93 | //
94 |
95 | extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
96 | LRESULT __stdcall WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
97 | {
98 | if (GUI::getIsInit())
99 | {
100 | /* If VK_INSERT, change menu draw state */
101 | if (msg == WM_KEYDOWN && wParam == VK_INSERT)
102 | GUI::setDoDraw(!GUI::getDoDraw());
103 |
104 | if (GUI::getDoDraw() && ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
105 | return true;
106 | }
107 |
108 | return CallWindowProcA(origin_wndproc, hWnd, msg, wParam, lParam);
109 | }
110 |
111 | bool __stdcall wglSwapBuffers(HDC hDc)
112 | {
113 | HGLRC origin_context{ wglGetCurrentContext() };
114 | static HGLRC new_context{};
115 |
116 | if (static bool was_init{}; was_init == false)
117 | {
118 | new_context = wglCreateContext(hDc);
119 | wglMakeCurrent(hDc, new_context);
120 |
121 | GLint viewport[4];
122 | glGetIntegerv(GL_VIEWPORT, viewport);
123 | glViewport(0, 0, viewport[2], viewport[3]);
124 | glMatrixMode(GL_PROJECTION);
125 | glLoadIdentity();
126 | glOrtho(0, viewport[2], viewport[3], 0, -1, 1);
127 | glMatrixMode(GL_MODELVIEW);
128 | glLoadIdentity();
129 | glDisable(GL_DEPTH_TEST);
130 |
131 | GUI::init(wnd_handle);
132 |
133 | was_init = true;
134 | }
135 | else
136 | {
137 | wglMakeCurrent(hDc, new_context);
138 | GUI::draw();
139 | }
140 |
141 | wglMakeCurrent(hDc, origin_context);
142 |
143 | return origin_wglSwapBuffers(hDc);
144 | }
145 |
--------------------------------------------------------------------------------
/src/Hook.h:
--------------------------------------------------------------------------------
1 | #ifndef HOOK_H_
2 | #define HOOK_H_
3 |
4 | #include
5 |
6 | #include
7 |
8 | namespace Hook
9 | {
10 | //
11 | // Management functions
12 | //
13 |
14 | bool init();
15 | void shutdown();
16 |
17 | //
18 | // Get functions
19 | //
20 |
21 | bool getIsInit();
22 | }
23 |
24 | #endif
--------------------------------------------------------------------------------
/src/OpenGL-Hk.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.32112.339
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenGL-Hk", "OpenGL-Hk.vcxproj", "{F79D457C-9DD1-429F-A949-BBB72B02F574}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {F79D457C-9DD1-429F-A949-BBB72B02F574}.Debug|x64.ActiveCfg = Debug|x64
17 | {F79D457C-9DD1-429F-A949-BBB72B02F574}.Debug|x64.Build.0 = Debug|x64
18 | {F79D457C-9DD1-429F-A949-BBB72B02F574}.Debug|x86.ActiveCfg = Debug|Win32
19 | {F79D457C-9DD1-429F-A949-BBB72B02F574}.Debug|x86.Build.0 = Debug|Win32
20 | {F79D457C-9DD1-429F-A949-BBB72B02F574}.Release|x64.ActiveCfg = Release|x64
21 | {F79D457C-9DD1-429F-A949-BBB72B02F574}.Release|x64.Build.0 = Release|x64
22 | {F79D457C-9DD1-429F-A949-BBB72B02F574}.Release|x86.ActiveCfg = Release|Win32
23 | {F79D457C-9DD1-429F-A949-BBB72B02F574}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {7EF777DD-4C3D-4BDE-96A4-A98B7FE44874}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/src/OpenGL-Hk.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 16.0
23 | Win32Proj
24 | {f79d457c-9dd1-429f-a949-bbb72b02f574}
25 | OpenGLHk
26 | 10.0
27 |
28 |
29 |
30 | Application
31 | true
32 | v143
33 | Unicode
34 |
35 |
36 | Application
37 | false
38 | v143
39 | true
40 | Unicode
41 |
42 |
43 | DynamicLibrary
44 | true
45 | v143
46 | Unicode
47 |
48 |
49 | DynamicLibrary
50 | false
51 | v143
52 | true
53 | Unicode
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | true
75 |
76 |
77 | false
78 |
79 |
80 | true
81 |
82 |
83 | false
84 |
85 |
86 |
87 | Level3
88 | true
89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
90 | true
91 |
92 |
93 | Console
94 | true
95 |
96 |
97 |
98 |
99 | Level3
100 | true
101 | true
102 | true
103 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
104 | true
105 |
106 |
107 | Console
108 | true
109 | true
110 | true
111 |
112 |
113 |
114 |
115 | Level3
116 | true
117 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
118 | true
119 | stdcpp17
120 | true
121 | $(SolutionDir)Dependencies\include
122 |
123 |
124 | Windows
125 | true
126 | $(SolutionDir)Dependencies\lib
127 | $(CoreLibraryDependencies);%(AdditionalDependencies);opengl32.lib;imgui.lib;libMinHook-x64.lib
128 |
129 |
130 |
131 |
132 | Level3
133 | true
134 | true
135 | true
136 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
137 | true
138 | stdcpp17
139 | true
140 | $(SolutionDir)Dependencies\include
141 |
142 |
143 | Windows
144 | true
145 | true
146 | true
147 | $(SolutionDir)Dependencies\lib
148 | $(CoreLibraryDependencies);%(AdditionalDependencies);opengl32.lib;imgui.lib;libMinHook-x64.lib
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
--------------------------------------------------------------------------------
/src/OpenGL-Hk.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Dependencies\ImGui
7 |
8 |
9 | Dependencies\ImGui
10 |
11 |
12 | Hook
13 |
14 |
15 | GUI
16 |
17 |
18 |
19 |
20 | {d5c61b2e-fc4a-4f14-9689-1376e19ca7a7}
21 |
22 |
23 | {4a96feb9-c21a-48c4-abe6-93c8405d4ed5}
24 |
25 |
26 | {db35df7d-97f2-45a5-ad23-88cb3816d874}
27 |
28 |
29 | {1a2b9cf3-1b07-4ef6-abad-9589822a24e9}
30 |
31 |
32 |
33 |
34 | Dependencies\ImGui
35 |
36 |
37 | Dependencies\ImGui
38 |
39 |
40 | Dependencies\ImGui
41 |
42 |
43 | Dependencies\ImGui
44 |
45 |
46 | Dependencies\ImGui
47 |
48 |
49 | Dependencies\ImGui
50 |
51 |
52 | Dependencies\ImGui
53 |
54 |
55 | Dependencies\ImGui
56 |
57 |
58 | Dependencies\ImGui
59 |
60 |
61 | Dependencies\ImGui
62 |
63 |
64 | Hook
65 |
66 |
67 | GUI
68 |
69 |
70 | Dependencies
71 |
72 |
73 |
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 |
6 | #include "Hook.h"
7 |
8 | void __stdcall MainThread(HINSTANCE instance)
9 | {
10 | if (Hook::init())
11 | goto _shutdown;
12 |
13 | while (!GetAsyncKeyState(VK_END))
14 | {
15 | std::this_thread::sleep_for(std::chrono::milliseconds(25));
16 | }
17 |
18 | _shutdown:
19 | Hook::shutdown();
20 | FreeLibrary(instance);
21 | }
22 |
23 | bool __stdcall DllMain(HINSTANCE instance, DWORD reason, LPVOID p_reserved)
24 | {
25 | if (reason == DLL_PROCESS_ATTACH)
26 | {
27 | DisableThreadLibraryCalls(instance);
28 |
29 | AllocConsole();
30 | freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
31 |
32 | /* Create, join and detach thread */
33 | if (static std::thread main_thread([instance] { MainThread(instance); }); main_thread.joinable())
34 | main_thread.detach();
35 | }
36 | else if (reason == DLL_PROCESS_DETACH)
37 | {
38 | FreeConsole();
39 | fclose(stdout);
40 | }
41 |
42 | return true;
43 | }
44 |
--------------------------------------------------------------------------------