Lagrange
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Modules Pages
GLContext.h
1/*
2 * Copyright 2019 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <lagrange/ui/api.h>
15
16// GLEW must come before GLFW
17#if defined(__EMSCRIPTEN__)
18#include <webgl/webgl2.h>
19#include <GL/gl.h>
20#else
21#include <GL/gl3w.h>
22#endif
23// Do not change the order
24#include <GLFW/glfw3.h>
25
26#include <functional>
27#include <memory>
28#include <stack>
29#include <string>
30#include <string_view>
31#include <thread>
32#include <unordered_map>
33
34#ifdef _DEBUG
35#include <lagrange/utils/assert.h>
36#include <cassert>
37#endif
38
39
40namespace lagrange {
41namespace ui {
42
43/*
44 OpenGL Validation Layer
45*/
46
47#ifdef _DEBUG
48
49bool checkGLError(const char* label);
50#define LA_GL(x) \
51 do { \
52 x; \
53 checkGLError(LA_ASSERT_FUNCTION); \
54 } while (0)
55#else
56
57#define LA_GL(x) \
58 do { \
59 x; \
60 } while (0)
61#endif
62
63struct LA_UI_API GLState
64{
65 GLState();
66
67 static void push();
68 static void pop();
69
70 template <class F, class... Args>
71 void operator()(F func, Args... args)
72 {
73 void* func_void_ptr = reinterpret_cast<void*>(func);
74 void* enable_ptr = reinterpret_cast<void*>(glEnable);
75 void* disable_ptr = reinterpret_cast<void*>(glDisable);
76
77 if (func_void_ptr == enable_ptr) {
78 set_toggle(true, args...);
79 } else if (func_void_ptr == disable_ptr) {
80 set_toggle(false, args...);
81 } else {
82 auto it = values.find(func_void_ptr);
83 if (it != values.end()) {
84#ifdef _DEBUG
85 assert(values[func_void_ptr].size() > 0);
86#endif
87
88 values[func_void_ptr].top() = [=]() { LA_GL(func(args...)); };
89 }
90 }
91 // Run
92 LA_GL(func(args...));
93 }
94
95 static GLState& get();
96
97 static int major_version;
98 static int minor_version;
99 static std::string get_glsl_version_string();
100
101 static bool on_opengl_thread();
102
103 static std::string_view get_enum_string(GLenum value);
104
105private:
106 // Discard
107 template <class T, class... Args>
108 void set_toggle(bool val, T discard_val, [[maybe_unused]] Args... args)
109 {
110 (void)(val);
111 (void)(discard_val);
112 }
113
114 void set_toggle(bool val) { (void)(val); }
115
116 // Discard extra parameters
117 template <class... Args>
118 void set_toggle(bool val, GLenum name, [[maybe_unused]] Args... args)
119 {
120 set_toggle(val, name);
121 }
122 template <class... Args>
123 void set_toggle(bool val, int name, [[maybe_unused]] Args... args)
124 {
125 set_toggle(val, GLenum(name));
126 }
127
128 void set_toggle(bool val, GLenum name)
129 {
130 auto& stack = toggles[name];
131 while (stack.size() < m_stack_level) stack.push(glIsEnabled(name));
132 stack.top() = val;
133 }
134
135 template <class F>
136 std::stack<std::function<void(void)>>& get_stack(F func)
137 {
138 const void* func_void_ptr = reinterpret_cast<const void*>(func);
139 return values[func_void_ptr];
140 }
141
142
143 std::unordered_map<const void*, std::stack<std::function<void(void)>>> values;
144 std::unordered_map<GLenum, std::stack<bool>> toggles;
145
146
147 static std::unique_ptr<GLState> m_instance;
148 size_t m_stack_level;
149 std::thread::id m_gl_thread_id;
150};
151
152struct LA_UI_API GLScope
153{
154 GLScope(bool push = true);
155 ~GLScope();
156
157
158 static GLScope current() { return GLScope(false); }
159
160 template <class F, class... Args>
161 void operator()(F func, Args... args)
162 {
163 GLState::get()(func, args...);
164 }
165
166private:
167 bool m_push;
168};
169
170} // namespace ui
171} // namespace lagrange
Lagrange UI Viewer and mini 3D engine.
Definition: AcceleratedPicking.h:23
Main namespace for Lagrange.
Definition: AABBIGL.h:30
Definition: project.cpp:27
Definition: GLContext.h:153
Definition: GLContext.h:64