Lagrange
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#else
20#include <GL/gl3w.h>
21#endif
22// Do not change the order
23#include <GLFW/glfw3.h>
24
25#include <functional>
26#include <memory>
27#include <stack>
28#include <string>
29#include <string_view>
30#include <thread>
31#include <unordered_map>
32
33#ifdef _DEBUG
34#include <lagrange/utils/assert.h>
35#include <cassert>
36#endif
37
38
39namespace lagrange {
40namespace ui {
41
42/*
43 OpenGL Validation Layer
44*/
45
46#ifdef _DEBUG
47
48bool checkGLError(const char* label);
49#define LA_GL(x) \
50 do { \
51 x; \
52 checkGLError(LA_ASSERT_FUNCTION); \
53 } while (0)
54#else
55
56#define LA_GL(x) \
57 do { \
58 x; \
59 } while (0)
60#endif
61
62struct LA_UI_API GLState
63{
64 GLState();
65
66 static void push();
67 static void pop();
68
69 template <class F, class... Args>
70 void operator()(F func, Args... args)
71 {
72 void* func_void_ptr = reinterpret_cast<void*>(func);
73 void* enable_ptr = reinterpret_cast<void*>(glEnable);
74 void* disable_ptr = reinterpret_cast<void*>(glDisable);
75
76 if (func_void_ptr == enable_ptr) {
77 set_toggle(true, args...);
78 } else if (func_void_ptr == disable_ptr) {
79 set_toggle(false, args...);
80 } else {
81 auto it = values.find(func_void_ptr);
82 if (it != values.end()) {
83#ifdef _DEBUG
84 assert(values[func_void_ptr].size() > 0);
85#endif
86
87 values[func_void_ptr].top() = [=]() { LA_GL(func(args...)); };
88 }
89 }
90 // Run
91 LA_GL(func(args...));
92 }
93
94 static GLState& get();
95
96 static int major_version;
97 static int minor_version;
98 static std::string get_glsl_version_string();
99
100 static bool on_opengl_thread();
101
102 static std::string_view get_enum_string(GLenum value);
103
104private:
105 // Discard
106 template <class T, class... Args>
107 void set_toggle(bool val, T discard_val, [[maybe_unused]] Args... args)
108 {
109 (void)(val);
110 (void)(discard_val);
111 }
112
113 void set_toggle(bool val) { (void)(val); }
114
115 // Discard extra parameters
116 template <class... Args>
117 void set_toggle(bool val, GLenum name, [[maybe_unused]] Args... args)
118 {
119 set_toggle(val, name);
120 }
121 template <class... Args>
122 void set_toggle(bool val, int name, [[maybe_unused]] Args... args)
123 {
124 set_toggle(val, GLenum(name));
125 }
126
127 void set_toggle(bool val, GLenum name)
128 {
129 auto& stack = toggles[name];
130 while (stack.size() < m_stack_level) stack.push(glIsEnabled(name));
131 stack.top() = val;
132 }
133
134 template <class F>
135 std::stack<std::function<void(void)>>& get_stack(F func)
136 {
137 const void* func_void_ptr = reinterpret_cast<const void*>(func);
138 return values[func_void_ptr];
139 }
140
141
142 std::unordered_map<const void*, std::stack<std::function<void(void)>>> values;
143 std::unordered_map<GLenum, std::stack<bool>> toggles;
144
145
146 static std::unique_ptr<GLState> m_instance;
147 size_t m_stack_level;
148 std::thread::id m_gl_thread_id;
149};
150
151struct LA_UI_API GLScope
152{
153 GLScope(bool push = true);
154 ~GLScope();
155
156
157 static GLScope current() { return GLScope(false); }
158
159 template <class F, class... Args>
160 void operator()(F func, Args... args)
161 {
162 GLState::get()(func, args...);
163 }
164
165private:
166 bool m_push;
167};
168
169} // namespace ui
170} // namespace lagrange
Lagrange UI Viewer and mini 3D engine.
Definition: AcceleratedPicking.h:22
Main namespace for Lagrange.
Definition: AABBIGL.h:30
Definition: project.cpp:27
Definition: GLContext.h:152
Definition: GLContext.h:63