[e66fd66] | 1 | // dear imgui: Renderer 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 Binding (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: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
|
---|
| 9 |
|
---|
| 10 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
|
---|
| 11 | // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
|
---|
| 12 | // https://github.com/ocornut/imgui
|
---|
| 13 |
|
---|
| 14 | // CHANGELOG
|
---|
| 15 | // (minor and older changes stripped away, please see git history for details)
|
---|
| 16 | // 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.
|
---|
| 17 | // 2020-07-10: OpenGL: Added support for glad2 OpenGL loader.
|
---|
| 18 | // 2020-05-08: OpenGL: Made default GLSL version 150 (instead of 130) on OSX.
|
---|
| 19 | // 2020-04-21: OpenGL: Fixed handling of glClipControl(GL_UPPER_LEFT) by inverting projection matrix.
|
---|
| 20 | // 2020-04-12: OpenGL: Fixed context version check mistakenly testing for 4.0+ instead of 3.2+ to enable ImGuiBackendFlags_RendererHasVtxOffset.
|
---|
| 21 | // 2020-03-24: OpenGL: Added support for glbinding 2.x OpenGL loader.
|
---|
| 22 | // 2020-01-07: OpenGL: Added support for glbinding 3.x OpenGL loader.
|
---|
| 23 | // 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.
|
---|
| 24 | // 2019-09-22: OpenGL: Detect default GL loader using __has_include compiler facility.
|
---|
| 25 | // 2019-09-16: OpenGL: Tweak initialization code to allow application calling ImGui_ImplOpenGL3_CreateFontsTexture() before the first NewFrame() call.
|
---|
| 26 | // 2019-05-29: OpenGL: Desktop GL only: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
---|
| 27 | // 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
---|
| 28 | // 2019-03-29: OpenGL: Not calling glBindBuffer more than necessary in the render loop.
|
---|
| 29 | // 2019-03-15: OpenGL: Added a GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early.
|
---|
| 30 | // 2019-03-03: OpenGL: Fix support for ES 2.0 (WebGL 1.0).
|
---|
| 31 | // 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.
|
---|
| 32 | // 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
|
---|
| 33 | // 2019-02-01: OpenGL: Using GLSL 410 shaders for any version over 410 (e.g. 430, 450).
|
---|
| 34 | // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
|
---|
| 35 | // 2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT) / GL_CLIP_ORIGIN.
|
---|
| 36 | // 2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments indicative that any loader can be used.
|
---|
| 37 | // 2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and Android. GLSL version default to "#version 300 ES".
|
---|
| 38 | // 2018-07-30: OpenGL: Support for GLSL 300 ES and 410 core. Fixes for Emscripten compilation.
|
---|
| 39 | // 2018-07-10: OpenGL: Support for more GLSL versions (based on the GLSL version string). Added error output when shaders fail to compile/link.
|
---|
| 40 | // 2018-06-08: Misc: Extracted imgui_impl_opengl3.cpp/.h away from the old combined GLFW/SDL+OpenGL3 examples.
|
---|
| 41 | // 2018-06-08: OpenGL: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
|
---|
| 42 | // 2018-05-25: OpenGL: Removed unnecessary backup/restore of GL_ELEMENT_ARRAY_BUFFER_BINDING since this is part of the VAO state.
|
---|
| 43 | // 2018-05-14: OpenGL: Making the call to glBindSampler() optional so 3.2 context won't fail if the function is a NULL pointer.
|
---|
| 44 | // 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".
|
---|
| 45 | // 2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context.
|
---|
| 46 | // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can call it yourself.
|
---|
| 47 | // 2018-01-07: OpenGL: Changed GLSL shader version from 330 to 150.
|
---|
| 48 | // 2017-09-01: OpenGL: Save and restore current bound sampler. Save and restore current polygon mode.
|
---|
| 49 | // 2017-05-01: OpenGL: Fixed save and restore of current blend func state.
|
---|
| 50 | // 2017-05-01: OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE.
|
---|
| 51 | // 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle.
|
---|
| 52 | // 2016-07-29: OpenGL: Explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752)
|
---|
| 53 |
|
---|
| 54 | //----------------------------------------
|
---|
| 55 | // OpenGL GLSL GLSL
|
---|
| 56 | // version version string
|
---|
| 57 | //----------------------------------------
|
---|
| 58 | // 2.0 110 "#version 110"
|
---|
| 59 | // 2.1 120 "#version 120"
|
---|
| 60 | // 3.0 130 "#version 130"
|
---|
| 61 | // 3.1 140 "#version 140"
|
---|
| 62 | // 3.2 150 "#version 150"
|
---|
| 63 | // 3.3 330 "#version 330 core"
|
---|
| 64 | // 4.0 400 "#version 400 core"
|
---|
| 65 | // 4.1 410 "#version 410 core"
|
---|
| 66 | // 4.2 420 "#version 410 core"
|
---|
| 67 | // 4.3 430 "#version 430 core"
|
---|
| 68 | // ES 2.0 100 "#version 100" = WebGL 1.0
|
---|
| 69 | // ES 3.0 300 "#version 300 es" = WebGL 2.0
|
---|
| 70 | //----------------------------------------
|
---|
| 71 |
|
---|
| 72 | #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
---|
| 73 | #define _CRT_SECURE_NO_WARNINGS
|
---|
| 74 | #endif
|
---|
| 75 |
|
---|
| 76 | #include "imgui.h"
|
---|
| 77 | #include "imgui_impl_opengl3.h"
|
---|
| 78 | #include <stdio.h>
|
---|
| 79 | #if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
|
---|
| 80 | #include <stddef.h> // intptr_t
|
---|
| 81 | #else
|
---|
| 82 | #include <stdint.h> // intptr_t
|
---|
| 83 | #endif
|
---|
| 84 |
|
---|
| 85 | // GL includes
|
---|
| 86 | #if defined(IMGUI_IMPL_OPENGL_ES2)
|
---|
| 87 | #include <GLES2/gl2.h>
|
---|
| 88 | #elif defined(IMGUI_IMPL_OPENGL_ES3)
|
---|
| 89 | #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV))
|
---|
| 90 | #include <OpenGLES/ES3/gl.h> // Use GL ES 3
|
---|
| 91 | #else
|
---|
| 92 | #include <GLES3/gl3.h> // Use GL ES 3
|
---|
| 93 | #endif
|
---|
| 94 | #else
|
---|
| 95 | // About Desktop OpenGL function loaders:
|
---|
| 96 | // Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
|
---|
| 97 | // Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
|
---|
| 98 | // You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
|
---|
| 99 | #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
|
---|
| 100 | #include <GL/gl3w.h> // Needs to be initialized with gl3wInit() in user's code
|
---|
| 101 | #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
|
---|
| 102 | #include <GL/glew.h> // Needs to be initialized with glewInit() in user's code.
|
---|
| 103 | #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
---|
| 104 | #include <glad/glad.h> // Needs to be initialized with gladLoadGL() in user's code.
|
---|
| 105 | #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
|
---|
| 106 | #include <glad/gl.h> // Needs to be initialized with gladLoadGL(...) or gladLoaderLoadGL() in user's code.
|
---|
| 107 | #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
|
---|
| 108 | #ifndef GLFW_INCLUDE_NONE
|
---|
| 109 | #define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors.
|
---|
| 110 | #endif
|
---|
| 111 | #include <glbinding/Binding.h> // Needs to be initialized with glbinding::Binding::initialize() in user's code.
|
---|
| 112 | #include <glbinding/gl/gl.h>
|
---|
| 113 | using namespace gl;
|
---|
| 114 | #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3)
|
---|
| 115 | #ifndef GLFW_INCLUDE_NONE
|
---|
| 116 | #define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors.
|
---|
| 117 | #endif
|
---|
| 118 | #include <glbinding/glbinding.h>// Needs to be initialized with glbinding::initialize() in user's code.
|
---|
| 119 | #include <glbinding/gl/gl.h>
|
---|
| 120 | using namespace gl;
|
---|
| 121 | #else
|
---|
| 122 | #include IMGUI_IMPL_OPENGL_LOADER_CUSTOM
|
---|
| 123 | #endif
|
---|
| 124 | #endif
|
---|
| 125 |
|
---|
| 126 | // Desktop GL 3.2+ has glDrawElementsBaseVertex() which GL ES and WebGL don't have.
|
---|
| 127 | #if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_2)
|
---|
| 128 | #define IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
---|
| 129 | #endif
|
---|
| 130 |
|
---|
| 131 | // Desktop GL 3.3+ has glBindSampler()
|
---|
| 132 | #if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_3)
|
---|
| 133 | #define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
---|
| 134 | #endif
|
---|
| 135 |
|
---|
| 136 | // OpenGL Data
|
---|
| 137 | static GLuint g_GlVersion = 0; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2)
|
---|
| 138 | static char g_GlslVersionString[32] = ""; // Specified by user or detected based on compile time GL settings.
|
---|
| 139 | static GLuint g_FontTexture = 0;
|
---|
| 140 | static GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
|
---|
| 141 | static GLint g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; // Uniforms location
|
---|
| 142 | static GLuint g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, g_AttribLocationVtxColor = 0; // Vertex attributes location
|
---|
| 143 | static unsigned int g_VboHandle = 0, g_ElementsHandle = 0;
|
---|
| 144 |
|
---|
| 145 | // Functions
|
---|
| 146 | bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
---|
| 147 | {
|
---|
| 148 | // Query for GL version (e.g. 320 for GL 3.2)
|
---|
| 149 | #if !defined(IMGUI_IMPL_OPENGL_ES2)
|
---|
| 150 | GLint major, minor;
|
---|
| 151 | glGetIntegerv(GL_MAJOR_VERSION, &major);
|
---|
| 152 | glGetIntegerv(GL_MINOR_VERSION, &minor);
|
---|
| 153 | g_GlVersion = (GLuint)(major * 100 + minor * 10);
|
---|
| 154 | #else
|
---|
| 155 | g_GlVersion = 200; // GLES 2
|
---|
| 156 | #endif
|
---|
| 157 |
|
---|
| 158 | // Setup back-end capabilities flags
|
---|
| 159 | ImGuiIO& io = ImGui::GetIO();
|
---|
| 160 | io.BackendRendererName = "imgui_impl_opengl3";
|
---|
| 161 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
---|
| 162 | if (g_GlVersion >= 320)
|
---|
| 163 | io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
---|
| 164 | #endif
|
---|
| 165 |
|
---|
| 166 | // Store GLSL version string so we can refer to it later in case we recreate shaders.
|
---|
| 167 | // Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure.
|
---|
| 168 | #if defined(IMGUI_IMPL_OPENGL_ES2)
|
---|
| 169 | if (glsl_version == NULL)
|
---|
| 170 | glsl_version = "#version 100";
|
---|
| 171 | #elif defined(IMGUI_IMPL_OPENGL_ES3)
|
---|
| 172 | if (glsl_version == NULL)
|
---|
| 173 | glsl_version = "#version 300 es";
|
---|
| 174 | #elif defined(__APPLE__)
|
---|
| 175 | if (glsl_version == NULL)
|
---|
| 176 | glsl_version = "#version 150";
|
---|
| 177 | #else
|
---|
| 178 | if (glsl_version == NULL)
|
---|
| 179 | glsl_version = "#version 130";
|
---|
| 180 | #endif
|
---|
| 181 | IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersionString));
|
---|
| 182 | strcpy(g_GlslVersionString, glsl_version);
|
---|
| 183 | strcat(g_GlslVersionString, "\n");
|
---|
| 184 |
|
---|
| 185 | // Debugging construct to make it easily visible in the IDE and debugger which GL loader has been selected.
|
---|
| 186 | // The code actually never uses the 'gl_loader' variable! It is only here so you can read it!
|
---|
| 187 | // If auto-detection fails or doesn't select the same GL loader file as used by your application,
|
---|
| 188 | // you are likely to get a crash below.
|
---|
| 189 | // You can explicitly select a loader by using '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
|
---|
| 190 | const char* gl_loader = "Unknown";
|
---|
| 191 | IM_UNUSED(gl_loader);
|
---|
| 192 | #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
|
---|
| 193 | gl_loader = "GL3W";
|
---|
| 194 | #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
|
---|
| 195 | gl_loader = "GLEW";
|
---|
| 196 | #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
---|
| 197 | gl_loader = "GLAD";
|
---|
| 198 | #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
|
---|
| 199 | gl_loader = "GLAD2";
|
---|
| 200 | #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
|
---|
| 201 | gl_loader = "glbinding2";
|
---|
| 202 | #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3)
|
---|
| 203 | gl_loader = "glbinding3";
|
---|
| 204 | #elif defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
|
---|
| 205 | gl_loader = "custom";
|
---|
| 206 | #else
|
---|
| 207 | gl_loader = "none";
|
---|
| 208 | #endif
|
---|
| 209 |
|
---|
| 210 | // Make an arbitrary GL call (we don't actually need the result)
|
---|
| 211 | // IF YOU GET A CRASH HERE: it probably means that you haven't initialized the OpenGL function loader used by this code.
|
---|
| 212 | // Desktop OpenGL 3/4 need a function loader. See the IMGUI_IMPL_OPENGL_LOADER_xxx explanation above.
|
---|
| 213 | GLint current_texture;
|
---|
| 214 | glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);
|
---|
| 215 |
|
---|
| 216 | return true;
|
---|
| 217 | }
|
---|
| 218 |
|
---|
| 219 | void ImGui_ImplOpenGL3_Shutdown()
|
---|
| 220 | {
|
---|
| 221 | ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
---|
| 222 | }
|
---|
| 223 |
|
---|
| 224 | void ImGui_ImplOpenGL3_NewFrame()
|
---|
| 225 | {
|
---|
| 226 | if (!g_ShaderHandle)
|
---|
| 227 | ImGui_ImplOpenGL3_CreateDeviceObjects();
|
---|
| 228 | }
|
---|
| 229 |
|
---|
| 230 | static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
|
---|
| 231 | {
|
---|
| 232 | // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
|
---|
| 233 | glEnable(GL_BLEND);
|
---|
| 234 | glBlendEquation(GL_FUNC_ADD);
|
---|
| 235 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
---|
| 236 | glDisable(GL_CULL_FACE);
|
---|
| 237 | glDisable(GL_DEPTH_TEST);
|
---|
| 238 | glEnable(GL_SCISSOR_TEST);
|
---|
| 239 | #ifdef GL_POLYGON_MODE
|
---|
| 240 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
---|
| 241 | #endif
|
---|
| 242 |
|
---|
| 243 | // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
|
---|
| 244 | bool clip_origin_lower_left = true;
|
---|
| 245 | #if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
|
---|
| 246 | GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)¤t_clip_origin);
|
---|
| 247 | if (current_clip_origin == GL_UPPER_LEFT)
|
---|
| 248 | clip_origin_lower_left = false;
|
---|
| 249 | #endif
|
---|
| 250 |
|
---|
| 251 | // Setup viewport, orthographic projection matrix
|
---|
| 252 | // 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.
|
---|
| 253 | glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
|
---|
| 254 | float L = draw_data->DisplayPos.x;
|
---|
| 255 | float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
---|
| 256 | float T = draw_data->DisplayPos.y;
|
---|
| 257 | float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
---|
| 258 | if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left
|
---|
| 259 | const float ortho_projection[4][4] =
|
---|
| 260 | {
|
---|
| 261 | { 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
---|
| 262 | { 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
---|
| 263 | { 0.0f, 0.0f, -1.0f, 0.0f },
|
---|
| 264 | { (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f },
|
---|
| 265 | };
|
---|
| 266 | glUseProgram(g_ShaderHandle);
|
---|
| 267 | glUniform1i(g_AttribLocationTex, 0);
|
---|
| 268 | glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
|
---|
| 269 |
|
---|
| 270 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
---|
| 271 | if (g_GlVersion >= 330)
|
---|
| 272 | glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
|
---|
| 273 | #endif
|
---|
| 274 |
|
---|
| 275 | (void)vertex_array_object;
|
---|
| 276 | #ifndef IMGUI_IMPL_OPENGL_ES2
|
---|
| 277 | glBindVertexArray(vertex_array_object);
|
---|
| 278 | #endif
|
---|
| 279 |
|
---|
| 280 | // Bind vertex/index buffers and setup attributes for ImDrawVert
|
---|
| 281 | glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
|
---|
| 282 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
|
---|
| 283 | glEnableVertexAttribArray(g_AttribLocationVtxPos);
|
---|
| 284 | glEnableVertexAttribArray(g_AttribLocationVtxUV);
|
---|
| 285 | glEnableVertexAttribArray(g_AttribLocationVtxColor);
|
---|
| 286 | glVertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos));
|
---|
| 287 | glVertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv));
|
---|
| 288 | glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col));
|
---|
| 289 | }
|
---|
| 290 |
|
---|
| 291 | // OpenGL3 Render function.
|
---|
| 292 | // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
|
---|
| 293 | // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
|
---|
| 294 | void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
---|
| 295 | {
|
---|
| 296 | // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
---|
| 297 | int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
---|
| 298 | int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
---|
| 299 | if (fb_width <= 0 || fb_height <= 0)
|
---|
| 300 | return;
|
---|
| 301 |
|
---|
| 302 | // Backup GL state
|
---|
| 303 | GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture);
|
---|
| 304 | glActiveTexture(GL_TEXTURE0);
|
---|
| 305 | GLuint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_program);
|
---|
| 306 | GLuint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&last_texture);
|
---|
| 307 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
---|
| 308 | GLuint last_sampler; if (g_GlVersion >= 330) { glGetIntegerv(GL_SAMPLER_BINDING, (GLint*)&last_sampler); } else { last_sampler = 0; }
|
---|
| 309 | #endif
|
---|
| 310 | GLuint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer);
|
---|
| 311 | #ifndef IMGUI_IMPL_OPENGL_ES2
|
---|
| 312 | GLuint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object);
|
---|
| 313 | #endif
|
---|
| 314 | #ifdef GL_POLYGON_MODE
|
---|
| 315 | GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
---|
| 316 | #endif
|
---|
| 317 | GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
|
---|
| 318 | GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
|
---|
| 319 | GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb);
|
---|
| 320 | GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb);
|
---|
| 321 | GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha);
|
---|
| 322 | GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha);
|
---|
| 323 | GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb);
|
---|
| 324 | GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha);
|
---|
| 325 | GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
|
---|
| 326 | GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
|
---|
| 327 | GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
|
---|
| 328 | GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
---|
| 329 |
|
---|
| 330 | // Setup desired GL state
|
---|
| 331 | // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)
|
---|
| 332 | // The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
|
---|
| 333 | GLuint vertex_array_object = 0;
|
---|
| 334 | #ifndef IMGUI_IMPL_OPENGL_ES2
|
---|
| 335 | glGenVertexArrays(1, &vertex_array_object);
|
---|
| 336 | #endif
|
---|
| 337 | ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
|
---|
| 338 |
|
---|
| 339 | // Will project scissor/clipping rectangles into framebuffer space
|
---|
| 340 | ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
---|
| 341 | ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
---|
| 342 |
|
---|
| 343 | // Render command lists
|
---|
| 344 | for (int n = 0; n < draw_data->CmdListsCount; n++)
|
---|
| 345 | {
|
---|
| 346 | const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
---|
| 347 |
|
---|
| 348 | // Upload vertex/index buffers
|
---|
| 349 | glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);
|
---|
| 350 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW);
|
---|
| 351 |
|
---|
| 352 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
---|
| 353 | {
|
---|
| 354 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
---|
| 355 | if (pcmd->UserCallback != NULL)
|
---|
| 356 | {
|
---|
| 357 | // User callback, registered via ImDrawList::AddCallback()
|
---|
| 358 | // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
---|
| 359 | if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
---|
| 360 | ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
|
---|
| 361 | else
|
---|
| 362 | pcmd->UserCallback(cmd_list, pcmd);
|
---|
| 363 | }
|
---|
| 364 | else
|
---|
| 365 | {
|
---|
| 366 | // Project scissor/clipping rectangles into framebuffer space
|
---|
| 367 | ImVec4 clip_rect;
|
---|
| 368 | clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
|
---|
| 369 | clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
|
---|
| 370 | clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
|
---|
| 371 | clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
|
---|
| 372 |
|
---|
| 373 | if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
|
---|
| 374 | {
|
---|
| 375 | // Apply scissor/clipping rectangle
|
---|
| 376 | glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
|
---|
| 377 |
|
---|
| 378 | // Bind texture, Draw
|
---|
| 379 | glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
|
---|
| 380 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
---|
| 381 | if (g_GlVersion >= 320)
|
---|
| 382 | 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);
|
---|
| 383 | else
|
---|
| 384 | #endif
|
---|
| 385 | glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)));
|
---|
| 386 | }
|
---|
| 387 | }
|
---|
| 388 | }
|
---|
| 389 | }
|
---|
| 390 |
|
---|
| 391 | // Destroy the temporary VAO
|
---|
| 392 | #ifndef IMGUI_IMPL_OPENGL_ES2
|
---|
| 393 | glDeleteVertexArrays(1, &vertex_array_object);
|
---|
| 394 | #endif
|
---|
| 395 |
|
---|
| 396 | // Restore modified GL state
|
---|
| 397 | glUseProgram(last_program);
|
---|
| 398 | glBindTexture(GL_TEXTURE_2D, last_texture);
|
---|
| 399 | #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
---|
| 400 | if (g_GlVersion >= 330)
|
---|
| 401 | glBindSampler(0, last_sampler);
|
---|
| 402 | #endif
|
---|
| 403 | glActiveTexture(last_active_texture);
|
---|
| 404 | #ifndef IMGUI_IMPL_OPENGL_ES2
|
---|
| 405 | glBindVertexArray(last_vertex_array_object);
|
---|
| 406 | #endif
|
---|
| 407 | glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
---|
| 408 | glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
|
---|
| 409 | glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha);
|
---|
| 410 | if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
|
---|
| 411 | if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
|
---|
| 412 | if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
|
---|
| 413 | if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
|
---|
| 414 | #ifdef GL_POLYGON_MODE
|
---|
| 415 | glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
|
---|
| 416 | #endif
|
---|
| 417 | glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
|
---|
| 418 | glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
|
---|
| 419 | }
|
---|
| 420 |
|
---|
| 421 | bool ImGui_ImplOpenGL3_CreateFontsTexture()
|
---|
| 422 | {
|
---|
| 423 | // Build texture atlas
|
---|
| 424 | ImGuiIO& io = ImGui::GetIO();
|
---|
| 425 | unsigned char* pixels;
|
---|
| 426 | int width, height;
|
---|
| 427 | 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.
|
---|
| 428 |
|
---|
| 429 | // Upload texture to graphics system
|
---|
| 430 | GLint last_texture;
|
---|
| 431 | glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
---|
| 432 | glGenTextures(1, &g_FontTexture);
|
---|
| 433 | glBindTexture(GL_TEXTURE_2D, g_FontTexture);
|
---|
| 434 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
---|
| 435 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
---|
| 436 | #ifdef GL_UNPACK_ROW_LENGTH
|
---|
| 437 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
---|
| 438 | #endif
|
---|
| 439 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
---|
| 440 |
|
---|
| 441 | // Store our identifier
|
---|
| 442 | io.Fonts->TexID = (ImTextureID)(intptr_t)g_FontTexture;
|
---|
| 443 |
|
---|
| 444 | // Restore state
|
---|
| 445 | glBindTexture(GL_TEXTURE_2D, last_texture);
|
---|
| 446 |
|
---|
| 447 | return true;
|
---|
| 448 | }
|
---|
| 449 |
|
---|
| 450 | void ImGui_ImplOpenGL3_DestroyFontsTexture()
|
---|
| 451 | {
|
---|
| 452 | if (g_FontTexture)
|
---|
| 453 | {
|
---|
| 454 | ImGuiIO& io = ImGui::GetIO();
|
---|
| 455 | glDeleteTextures(1, &g_FontTexture);
|
---|
| 456 | io.Fonts->TexID = 0;
|
---|
| 457 | g_FontTexture = 0;
|
---|
| 458 | }
|
---|
| 459 | }
|
---|
| 460 |
|
---|
| 461 | // 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.
|
---|
| 462 | static bool CheckShader(GLuint handle, const char* desc)
|
---|
| 463 | {
|
---|
| 464 | GLint status = 0, log_length = 0;
|
---|
| 465 | glGetShaderiv(handle, GL_COMPILE_STATUS, &status);
|
---|
| 466 | glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length);
|
---|
| 467 | if ((GLboolean)status == GL_FALSE)
|
---|
| 468 | fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s!\n", desc);
|
---|
| 469 | if (log_length > 1)
|
---|
| 470 | {
|
---|
| 471 | ImVector<char> buf;
|
---|
| 472 | buf.resize((int)(log_length + 1));
|
---|
| 473 | glGetShaderInfoLog(handle, log_length, NULL, (GLchar*)buf.begin());
|
---|
| 474 | fprintf(stderr, "%s\n", buf.begin());
|
---|
| 475 | }
|
---|
| 476 | return (GLboolean)status == GL_TRUE;
|
---|
| 477 | }
|
---|
| 478 |
|
---|
| 479 | // If you get an error please report on GitHub. You may try different GL context version or GLSL version.
|
---|
| 480 | static bool CheckProgram(GLuint handle, const char* desc)
|
---|
| 481 | {
|
---|
| 482 | GLint status = 0, log_length = 0;
|
---|
| 483 | glGetProgramiv(handle, GL_LINK_STATUS, &status);
|
---|
| 484 | glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length);
|
---|
| 485 | if ((GLboolean)status == GL_FALSE)
|
---|
| 486 | fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! (with GLSL '%s')\n", desc, g_GlslVersionString);
|
---|
| 487 | if (log_length > 1)
|
---|
| 488 | {
|
---|
| 489 | ImVector<char> buf;
|
---|
| 490 | buf.resize((int)(log_length + 1));
|
---|
| 491 | glGetProgramInfoLog(handle, log_length, NULL, (GLchar*)buf.begin());
|
---|
| 492 | fprintf(stderr, "%s\n", buf.begin());
|
---|
| 493 | }
|
---|
| 494 | return (GLboolean)status == GL_TRUE;
|
---|
| 495 | }
|
---|
| 496 |
|
---|
| 497 | bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
---|
| 498 | {
|
---|
| 499 | // Backup GL state
|
---|
| 500 | GLint last_texture, last_array_buffer;
|
---|
| 501 | glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
---|
| 502 | glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
---|
| 503 | #ifndef IMGUI_IMPL_OPENGL_ES2
|
---|
| 504 | GLint last_vertex_array;
|
---|
| 505 | glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
|
---|
| 506 | #endif
|
---|
| 507 |
|
---|
| 508 | // Parse GLSL version string
|
---|
| 509 | int glsl_version = 130;
|
---|
| 510 | sscanf(g_GlslVersionString, "#version %d", &glsl_version);
|
---|
| 511 |
|
---|
| 512 | const GLchar* vertex_shader_glsl_120 =
|
---|
| 513 | "uniform mat4 ProjMtx;\n"
|
---|
| 514 | "attribute vec2 Position;\n"
|
---|
| 515 | "attribute vec2 UV;\n"
|
---|
| 516 | "attribute vec4 Color;\n"
|
---|
| 517 | "varying vec2 Frag_UV;\n"
|
---|
| 518 | "varying vec4 Frag_Color;\n"
|
---|
| 519 | "void main()\n"
|
---|
| 520 | "{\n"
|
---|
| 521 | " Frag_UV = UV;\n"
|
---|
| 522 | " Frag_Color = Color;\n"
|
---|
| 523 | " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
---|
| 524 | "}\n";
|
---|
| 525 |
|
---|
| 526 | const GLchar* vertex_shader_glsl_130 =
|
---|
| 527 | "uniform mat4 ProjMtx;\n"
|
---|
| 528 | "in vec2 Position;\n"
|
---|
| 529 | "in vec2 UV;\n"
|
---|
| 530 | "in vec4 Color;\n"
|
---|
| 531 | "out vec2 Frag_UV;\n"
|
---|
| 532 | "out vec4 Frag_Color;\n"
|
---|
| 533 | "void main()\n"
|
---|
| 534 | "{\n"
|
---|
| 535 | " Frag_UV = UV;\n"
|
---|
| 536 | " Frag_Color = Color;\n"
|
---|
| 537 | " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
---|
| 538 | "}\n";
|
---|
| 539 |
|
---|
| 540 | const GLchar* vertex_shader_glsl_300_es =
|
---|
| 541 | "precision mediump float;\n"
|
---|
| 542 | "layout (location = 0) in vec2 Position;\n"
|
---|
| 543 | "layout (location = 1) in vec2 UV;\n"
|
---|
| 544 | "layout (location = 2) in vec4 Color;\n"
|
---|
| 545 | "uniform mat4 ProjMtx;\n"
|
---|
| 546 | "out vec2 Frag_UV;\n"
|
---|
| 547 | "out vec4 Frag_Color;\n"
|
---|
| 548 | "void main()\n"
|
---|
| 549 | "{\n"
|
---|
| 550 | " Frag_UV = UV;\n"
|
---|
| 551 | " Frag_Color = Color;\n"
|
---|
| 552 | " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
---|
| 553 | "}\n";
|
---|
| 554 |
|
---|
| 555 | const GLchar* vertex_shader_glsl_410_core =
|
---|
| 556 | "layout (location = 0) in vec2 Position;\n"
|
---|
| 557 | "layout (location = 1) in vec2 UV;\n"
|
---|
| 558 | "layout (location = 2) in vec4 Color;\n"
|
---|
| 559 | "uniform mat4 ProjMtx;\n"
|
---|
| 560 | "out vec2 Frag_UV;\n"
|
---|
| 561 | "out vec4 Frag_Color;\n"
|
---|
| 562 | "void main()\n"
|
---|
| 563 | "{\n"
|
---|
| 564 | " Frag_UV = UV;\n"
|
---|
| 565 | " Frag_Color = Color;\n"
|
---|
| 566 | " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
---|
| 567 | "}\n";
|
---|
| 568 |
|
---|
| 569 | const GLchar* fragment_shader_glsl_120 =
|
---|
| 570 | "#ifdef GL_ES\n"
|
---|
| 571 | " precision mediump float;\n"
|
---|
| 572 | "#endif\n"
|
---|
| 573 | "uniform sampler2D Texture;\n"
|
---|
| 574 | "varying vec2 Frag_UV;\n"
|
---|
| 575 | "varying vec4 Frag_Color;\n"
|
---|
| 576 | "void main()\n"
|
---|
| 577 | "{\n"
|
---|
| 578 | " gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n"
|
---|
| 579 | "}\n";
|
---|
| 580 |
|
---|
| 581 | const GLchar* fragment_shader_glsl_130 =
|
---|
| 582 | "uniform sampler2D Texture;\n"
|
---|
| 583 | "in vec2 Frag_UV;\n"
|
---|
| 584 | "in vec4 Frag_Color;\n"
|
---|
| 585 | "out vec4 Out_Color;\n"
|
---|
| 586 | "void main()\n"
|
---|
| 587 | "{\n"
|
---|
| 588 | " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
|
---|
| 589 | "}\n";
|
---|
| 590 |
|
---|
| 591 | const GLchar* fragment_shader_glsl_300_es =
|
---|
| 592 | "precision mediump float;\n"
|
---|
| 593 | "uniform sampler2D Texture;\n"
|
---|
| 594 | "in vec2 Frag_UV;\n"
|
---|
| 595 | "in vec4 Frag_Color;\n"
|
---|
| 596 | "layout (location = 0) out vec4 Out_Color;\n"
|
---|
| 597 | "void main()\n"
|
---|
| 598 | "{\n"
|
---|
| 599 | " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
|
---|
| 600 | "}\n";
|
---|
| 601 |
|
---|
| 602 | const GLchar* fragment_shader_glsl_410_core =
|
---|
| 603 | "in vec2 Frag_UV;\n"
|
---|
| 604 | "in vec4 Frag_Color;\n"
|
---|
| 605 | "uniform sampler2D Texture;\n"
|
---|
| 606 | "layout (location = 0) out vec4 Out_Color;\n"
|
---|
| 607 | "void main()\n"
|
---|
| 608 | "{\n"
|
---|
| 609 | " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
|
---|
| 610 | "}\n";
|
---|
| 611 |
|
---|
| 612 | // Select shaders matching our GLSL versions
|
---|
| 613 | const GLchar* vertex_shader = NULL;
|
---|
| 614 | const GLchar* fragment_shader = NULL;
|
---|
| 615 | if (glsl_version < 130)
|
---|
| 616 | {
|
---|
| 617 | vertex_shader = vertex_shader_glsl_120;
|
---|
| 618 | fragment_shader = fragment_shader_glsl_120;
|
---|
| 619 | }
|
---|
| 620 | else if (glsl_version >= 410)
|
---|
| 621 | {
|
---|
| 622 | vertex_shader = vertex_shader_glsl_410_core;
|
---|
| 623 | fragment_shader = fragment_shader_glsl_410_core;
|
---|
| 624 | }
|
---|
| 625 | else if (glsl_version == 300)
|
---|
| 626 | {
|
---|
| 627 | vertex_shader = vertex_shader_glsl_300_es;
|
---|
| 628 | fragment_shader = fragment_shader_glsl_300_es;
|
---|
| 629 | }
|
---|
| 630 | else
|
---|
| 631 | {
|
---|
| 632 | vertex_shader = vertex_shader_glsl_130;
|
---|
| 633 | fragment_shader = fragment_shader_glsl_130;
|
---|
| 634 | }
|
---|
| 635 |
|
---|
| 636 | // Create shaders
|
---|
| 637 | const GLchar* vertex_shader_with_version[2] = { g_GlslVersionString, vertex_shader };
|
---|
| 638 | g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
|
---|
| 639 | glShaderSource(g_VertHandle, 2, vertex_shader_with_version, NULL);
|
---|
| 640 | glCompileShader(g_VertHandle);
|
---|
| 641 | CheckShader(g_VertHandle, "vertex shader");
|
---|
| 642 |
|
---|
| 643 | const GLchar* fragment_shader_with_version[2] = { g_GlslVersionString, fragment_shader };
|
---|
| 644 | g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
|
---|
| 645 | glShaderSource(g_FragHandle, 2, fragment_shader_with_version, NULL);
|
---|
| 646 | glCompileShader(g_FragHandle);
|
---|
| 647 | CheckShader(g_FragHandle, "fragment shader");
|
---|
| 648 |
|
---|
| 649 | g_ShaderHandle = glCreateProgram();
|
---|
| 650 | glAttachShader(g_ShaderHandle, g_VertHandle);
|
---|
| 651 | glAttachShader(g_ShaderHandle, g_FragHandle);
|
---|
| 652 | glLinkProgram(g_ShaderHandle);
|
---|
| 653 | CheckProgram(g_ShaderHandle, "shader program");
|
---|
| 654 |
|
---|
| 655 | g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
|
---|
| 656 | g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
|
---|
| 657 | g_AttribLocationVtxPos = (GLuint)glGetAttribLocation(g_ShaderHandle, "Position");
|
---|
| 658 | g_AttribLocationVtxUV = (GLuint)glGetAttribLocation(g_ShaderHandle, "UV");
|
---|
| 659 | g_AttribLocationVtxColor = (GLuint)glGetAttribLocation(g_ShaderHandle, "Color");
|
---|
| 660 |
|
---|
| 661 | // Create buffers
|
---|
| 662 | glGenBuffers(1, &g_VboHandle);
|
---|
| 663 | glGenBuffers(1, &g_ElementsHandle);
|
---|
| 664 |
|
---|
| 665 | ImGui_ImplOpenGL3_CreateFontsTexture();
|
---|
| 666 |
|
---|
| 667 | // Restore modified GL state
|
---|
| 668 | glBindTexture(GL_TEXTURE_2D, last_texture);
|
---|
| 669 | glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
---|
| 670 | #ifndef IMGUI_IMPL_OPENGL_ES2
|
---|
| 671 | glBindVertexArray(last_vertex_array);
|
---|
| 672 | #endif
|
---|
| 673 |
|
---|
| 674 | return true;
|
---|
| 675 | }
|
---|
| 676 |
|
---|
| 677 | void ImGui_ImplOpenGL3_DestroyDeviceObjects()
|
---|
| 678 | {
|
---|
| 679 | if (g_VboHandle) { glDeleteBuffers(1, &g_VboHandle); g_VboHandle = 0; }
|
---|
| 680 | if (g_ElementsHandle) { glDeleteBuffers(1, &g_ElementsHandle); g_ElementsHandle = 0; }
|
---|
| 681 | if (g_ShaderHandle && g_VertHandle) { glDetachShader(g_ShaderHandle, g_VertHandle); }
|
---|
| 682 | if (g_ShaderHandle && g_FragHandle) { glDetachShader(g_ShaderHandle, g_FragHandle); }
|
---|
| 683 | if (g_VertHandle) { glDeleteShader(g_VertHandle); g_VertHandle = 0; }
|
---|
| 684 | if (g_FragHandle) { glDeleteShader(g_FragHandle); g_FragHandle = 0; }
|
---|
| 685 | if (g_ShaderHandle) { glDeleteProgram(g_ShaderHandle); g_ShaderHandle = 0; }
|
---|
| 686 |
|
---|
| 687 | ImGui_ImplOpenGL3_DestroyFontsTexture();
|
---|
| 688 | }
|
---|