Branch data Line data Source code
1 : : #pragma once
2 : :
3 : : /*
4 : : MIT License
5 : :
6 : : Copyright (c) 2014-2024 Stephane Cuillerdier (aka aiekick)
7 : :
8 : : Permission is hereby granted, free of charge, to any person obtaining a copy
9 : : of this software and associated documentation files (the "Software"), to deal
10 : : in the Software without restriction, including without limitation the rights
11 : : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 : : copies of the Software, and to permit persons to whom the Software is
13 : : furnished to do so, subject to the following conditions:
14 : :
15 : : The above copyright notice and this permission notice shall be included in all
16 : : copies or substantial portions of the Software.
17 : :
18 : : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 : : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 : : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 : : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 : : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 : : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 : : SOFTWARE.
25 : : */
26 : :
27 : : // ezGL is part of the ezLibs project : https://github.com/aiekick/ezLibs.git
28 : :
29 : :
30 : : /*
31 : : * this class will manage uniforms
32 : : * will parse a code and filter uniforms code
33 : : * uniform widgets
34 : : *
35 : : */
36 : :
37 : : #include <map>
38 : : #include <string>
39 : : #include <cassert>
40 : : #include <fstream>
41 : : #include <functional>
42 : : #include <unordered_map>
43 : :
44 : : namespace ez {
45 : : namespace gl {
46 : :
47 : : class UniformParsingDatas {
48 : : public:
49 : : std::string uniform_line;
50 : : std::string uniform_type;
51 : : std::string widget_type;
52 : : std::string uniform_name;
53 : : std::string uniform_comment; // les \\n serait remaplce par des \n pour affichage
54 : : std::string uniform_comment_original; // les \\n reste des \\n
55 : : std::string uniform_param_line;
56 : : std::vector<std::string> params;
57 : : bool valid = false;
58 : :
59 : : public:
60 : : UniformParsingDatas() = default;
61 : 23 : UniformParsingDatas(const std::string& vUniformString) {
62 : 23 : valid = m_ParseUniformString(vUniformString);
63 : 23 : }
64 : 0 : std::string getFinalUniformCode() const {
65 : 0 : if (uniform_comment_original.empty()) {
66 : 0 : return "uniform " + uniform_type + " " + uniform_name + ";";
67 : 0 : } else {
68 : 0 : return "uniform " + uniform_type + " " + uniform_name + "; // " + uniform_comment_original;
69 : 0 : }
70 : 0 : }
71 : 23 : bool isValid() const {
72 : 23 : return valid;
73 : 23 : }
74 : :
75 : : private:
76 : 44 : size_t m_IgnoreComments(const std::string& vUniformString, const size_t& vPos) {
77 [ + + ]: 44 : if (vPos != std::string::npos) {
78 : 42 : char c = vUniformString[vPos];
79 [ + + ][ + + ]: 42 : if (c == '/' || c == ' ') {
80 : 26 : auto next_space = vUniformString.find_first_of(" /", vPos);
81 : 26 : auto start_pos = vUniformString.find("/*", vPos);
82 [ + + ]: 26 : if (next_space >= start_pos) {
83 : 2 : auto start_not_pos = vUniformString.find("*/", vPos);
84 [ - + ]: 2 : if (start_not_pos < start_pos) {
85 : 0 : return vPos;
86 : 0 : }
87 [ + - ]: 2 : if (start_pos != std::string::npos) {
88 : 2 : auto end_pos = vUniformString.find("*/", start_pos);
89 [ + - ]: 2 : if (end_pos != std::string::npos) {
90 : 2 : end_pos += 2;
91 : 2 : return end_pos;
92 : 2 : }
93 : 2 : }
94 : 2 : }
95 : 26 : }
96 : 42 : }
97 : 42 : return vPos;
98 : 44 : }
99 : 23 : bool m_ParseUniformString(const std::string& vUniformString) {
100 [ + + ]: 23 : if (vUniformString.empty()) {
101 : 1 : return false;
102 : 1 : }
103 : :
104 : 22 : uniform_line = vUniformString;
105 : :
106 : : // we wnat to get all theses
107 : : // uniform type(widget:params) name; comment
108 : :
109 : 22 : bool uniform_found = false;
110 : 22 : bool type_found = false;
111 : 22 : bool name_found = false;
112 : :
113 : 22 : auto first_comment = vUniformString.find("//");
114 : 22 : auto pos = vUniformString.find("uniform");
115 [ + + ][ + + ]: 22 : if (first_comment != std::string::npos && first_comment < pos) {
116 : 2 : return false;
117 : 2 : }
118 : :
119 [ + + ][ + - ]: 20 : if (first_comment > pos && pos != std::string::npos) {
120 : 18 : uniform_found = true;
121 : 18 : pos += std::string("uniform").size();
122 : :
123 : 18 : pos = m_IgnoreComments(vUniformString, pos);
124 : :
125 : : // type and params
126 : 18 : auto type_pos = vUniformString.find_first_of("abcdefghijklmnopqrstuvwxyz(", pos);
127 [ + - ]: 18 : if (type_pos != std::string::npos) {
128 [ - + ]: 18 : if (vUniformString[type_pos] == '(') {
129 [ # # ][ # # ]: 0 : return (uniform_found && type_found && name_found);
[ # # ]
130 : 0 : }
131 : : // pos = type_pos;
132 : 18 : size_t first_parenthesis_pos = vUniformString.find('(', type_pos + 1);
133 [ + + ]: 18 : if (first_parenthesis_pos != std::string::npos) {
134 : 6 : first_parenthesis_pos += 1;
135 : 6 : uniform_type = vUniformString.substr(type_pos, first_parenthesis_pos - (type_pos + 1));
136 [ + - ]: 6 : if (!uniform_type.empty()) {
137 : 6 : type_found = true;
138 : 6 : }
139 : 6 : first_parenthesis_pos = m_IgnoreComments(vUniformString, first_parenthesis_pos);
140 : 6 : size_t last_parenthesis_pos = vUniformString.find_first_of("()", first_parenthesis_pos);
141 [ + - ]: 6 : if (last_parenthesis_pos != std::string::npos) {
142 [ + - ]: 6 : if (vUniformString[last_parenthesis_pos] == ')') {
143 : 6 : uniform_param_line = vUniformString.substr(first_parenthesis_pos, last_parenthesis_pos - first_parenthesis_pos);
144 : 6 : pos = last_parenthesis_pos + 1;
145 : 6 : } else {
146 [ # # ][ # # ]: 0 : return (uniform_found && type_found && name_found);
[ # # ]
147 : 0 : }
148 : 6 : } else {
149 [ # # ][ # # ]: 0 : return (uniform_found && type_found && name_found);
[ # # ]
150 : 0 : }
151 : 12 : } else {
152 : 12 : size_t nextSpace = vUniformString.find_first_of(" /", type_pos + 1);
153 [ + + ]: 12 : if (nextSpace != std::string::npos) {
154 : 11 : uniform_type = vUniformString.substr(type_pos, nextSpace - type_pos);
155 [ + - ]: 11 : if (!uniform_type.empty()) {
156 : 11 : type_found = true;
157 : 11 : }
158 [ + + ]: 11 : if (vUniformString[nextSpace] == ' ') {
159 : 10 : pos = nextSpace + 1;
160 : 10 : }
161 [ + + ]: 11 : if (vUniformString[nextSpace] == '/') {
162 : 1 : pos = nextSpace;
163 : 1 : }
164 : 11 : }
165 : 12 : }
166 : 18 : }
167 : 18 : }
168 : :
169 : : // name
170 : 20 : pos = m_IgnoreComments(vUniformString, pos);
171 : 20 : size_t coma_pos = vUniformString.find_first_of(";\n\r/[", pos);
172 [ + + ]: 20 : if (coma_pos != std::string::npos) {
173 : 17 : size_t namePos = vUniformString.find_first_of("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", pos);
174 [ + + ]: 17 : if (namePos != std::string::npos) {
175 [ + + ]: 16 : if (namePos < coma_pos) {
176 : 15 : uniform_name = vUniformString.substr(namePos, coma_pos - namePos);
177 : 15 : m_replace_string(uniform_name, " ", "_");
178 [ + - ]: 15 : if (!uniform_type.empty()) {
179 : 15 : name_found = true;
180 : 15 : }
181 : 15 : }
182 : 16 : }
183 : :
184 [ + + ][ + - ]: 17 : if (vUniformString[coma_pos] != ';' && vUniformString[coma_pos] != '[' && vUniformString[coma_pos] != '/') {
[ - + ]
185 [ # # ][ # # ]: 0 : return (uniform_found && type_found && name_found);
[ # # ]
186 : 0 : }
187 : 17 : } else {
188 [ + + ][ + - ]: 3 : return (uniform_found && type_found && name_found);
[ - + ]
189 : 3 : }
190 : :
191 [ + + ]: 17 : if (uniform_name.empty()) {
192 [ + - ][ + + ]: 2 : return (uniform_found && type_found && name_found);
[ - + ]
193 : 2 : }
194 : :
195 : : // array
196 : : /*size_t arrayPos = vUniformString.find_first_of('[');
197 : : if (arrayPos != std::string::npos) {
198 : : arrayPos += 1;
199 : : size_t endArray = vUniformString.find_first_of("[]", arrayPos);
200 : : if (endArray != std::string::npos) {
201 : : if (vUniformString[endArray] == ']') {
202 : : array = vUniformString.substr(arrayPos, endArray - arrayPos);
203 : : pos = endArray + 1;
204 : : } else {
205 : : return (uniform_found && type_found && name_found);
206 : : }
207 : : } else {
208 : : return (uniform_found && type_found && name_found);
209 : : }
210 : : }*/
211 : :
212 : : // comment
213 : 15 : coma_pos = vUniformString.find_first_of(";\n\r");
214 [ + - ]: 15 : if (coma_pos != std::string::npos) {
215 [ + - ]: 15 : if (vUniformString[coma_pos] == ';') {
216 : 15 : coma_pos += 1;
217 : 15 : std::string afterComaStr = vUniformString.substr(coma_pos);
218 [ + + ]: 15 : if (!afterComaStr.empty()) {
219 : 8 : size_t uniform_comment_pos = afterComaStr.find("//");
220 [ + + ]: 8 : if (uniform_comment_pos == std::string::npos) {
221 : 6 : uniform_comment_pos = afterComaStr.find("/*");
222 : 6 : }
223 [ + - ]: 8 : if (uniform_comment_pos != std::string::npos) {
224 : 8 : uniform_comment_pos += 2;
225 : 8 : uniform_comment_original = afterComaStr.substr(uniform_comment_pos);
226 : 8 : m_replace_string(uniform_comment_original, "*/", ""); // win
227 : 8 : uniform_comment = uniform_comment_original;
228 : 8 : m_replace_string(uniform_comment, "\\n", "\n"); // win
229 : 8 : m_replace_string(uniform_comment, "\\r", "\r"); // unix
230 : 8 : }
231 : 8 : }
232 : 15 : } else {
233 [ # # ][ # # ]: 0 : return (uniform_found && type_found && name_found);
[ # # ]
234 : 0 : }
235 : 15 : }
236 : :
237 : 15 : m_replace_string(uniform_type, " ", "");
238 : 15 : m_replace_string(widget_type, " ", "");
239 : 15 : m_replace_string(uniform_name, " ", "");
240 : 15 : m_replace_string(uniform_param_line, " ", "");
241 : :
242 : 15 : m_replace_string(uniform_type, "\t", "");
243 : 15 : m_replace_string(widget_type, "\t", "");
244 : 15 : m_replace_string(uniform_name, "\t", "");
245 : 15 : m_replace_string(uniform_param_line, "\t", "");
246 : :
247 : 15 : m_replace_string(uniform_type, "\r", "");
248 : 15 : m_replace_string(widget_type, "\r", "");
249 : 15 : m_replace_string(uniform_name, "\r", "");
250 : 15 : m_replace_string(uniform_param_line, "\r", "");
251 : :
252 : : /// parse params
253 : :
254 : 15 : std::string word;
255 : 15 : bool first_word = true;
256 [ + + ]: 55 : for (auto c : uniform_param_line) {
257 [ + + ]: 55 : if (c != ':') {
258 : 48 : word += c;
259 : 48 : } else {
260 [ + + ]: 7 : if (first_word) {
261 [ + + ]: 3 : if (m_is_content_string(word)) {
262 : 2 : widget_type = word;
263 : 2 : first_word = false;
264 : 2 : } else {
265 : 1 : widget_type = "slider";
266 : 1 : params.push_back(word);
267 : 1 : first_word = false;
268 : 1 : }
269 : 4 : } else {
270 : 4 : params.push_back(word);
271 : 4 : }
272 : 7 : word.clear();
273 : 7 : }
274 : 55 : }
275 [ + + ]: 15 : if (!word.empty()) {
276 [ + + ]: 6 : if (first_word) {
277 [ + - ]: 3 : if (m_is_content_string(word)) {
278 : 3 : widget_type = word;
279 : 3 : }
280 : 3 : } else {
281 : 3 : params.push_back(word);
282 : 3 : }
283 : 6 : }
284 : :
285 [ + - ][ + - ]: 15 : return (uniform_found && type_found && name_found);
[ + - ]
286 : 15 : }
287 : 219 : bool m_replace_string(::std::string& vStr, const ::std::string& vOldStr, const ::std::string& vNewStr) {
288 : 219 : bool found = false;
289 : 219 : size_t pos = 0;
290 [ + + ]: 233 : while ((pos = vStr.find(vOldStr, pos)) != ::std::string::npos) {
291 : 14 : found = true;
292 : 14 : vStr.replace(pos, vOldStr.length(), vNewStr);
293 : 14 : pos += vNewStr.length();
294 : 14 : }
295 : 219 : return found;
296 : 219 : }
297 : 6 : bool m_is_content_string(const std::string& vStr) {
298 : 6 : auto num_pos = vStr.find_first_of("0123456789.");
299 : 6 : auto str_pos = vStr.find_first_of("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
300 : 6 : return (str_pos < num_pos);
301 : 6 : }
302 : : };
303 : :
304 : : /*
305 : : * class used for expsoe internal function of Uniforms class for test
306 : : */
307 : : class UniformStrings {
308 : : public:
309 : : // uniform pos, uniform line, uniform end
310 : : typedef std::unordered_map<size_t, UniformParsingDatas> UniformStringsContainer;
311 : :
312 : : private:
313 : : UniformStringsContainer m_uniform_strings;
314 : :
315 : : public:
316 : 0 : std::string parse_and_filter_code(const std::string& vCode) {
317 : 0 : std::string final_code = vCode;
318 : 0 : auto _uniform_strings = m_get_uniform_strings(final_code);
319 : 0 : if (!_uniform_strings.empty()) {
320 : 0 : final_code = m_filter_code(final_code, _uniform_strings);
321 : 0 : }
322 : 0 : return final_code;
323 : 0 : }
324 : 0 : const UniformStringsContainer& get_uniform_strings() {
325 : 0 : return m_uniform_strings;
326 : 0 : }
327 : 0 : UniformStringsContainer& get_uniforms_strings_ref() {
328 : 0 : return m_uniform_strings;
329 : 0 : }
330 : :
331 : : protected:
332 : 0 : UniformStringsContainer m_get_uniform_strings(const std::string& vCode) {
333 : 0 : UniformStringsContainer res;
334 : 0 : size_t uniform_pos = 0U;
335 : 0 : while (uniform_pos != std::string::npos) {
336 : 0 : uniform_pos = vCode.find("uniform", uniform_pos);
337 : 0 : if (uniform_pos != std::string::npos) {
338 : 0 : size_t end_line_pos = vCode.find_first_of("\n\r", uniform_pos);
339 : 0 : if (end_line_pos != std::string::npos) {
340 : 0 : auto uniform_line = vCode.substr(uniform_pos, end_line_pos - uniform_pos);
341 : 0 : res[uniform_pos] = UniformParsingDatas(uniform_line);
342 : 0 : uniform_pos = end_line_pos;
343 : 0 : }
344 : 0 : ++uniform_pos;
345 : 0 : }
346 : 0 : }
347 : 0 : return res;
348 : 0 : }
349 : :
350 : : // will replace bad glsl uniform code (code with declarative uniform syntax) to good uniform code
351 : 0 : std::string m_filter_code(const std::string& vCode, const UniformStringsContainer& vContainer) {
352 : 0 : std::string final_code = vCode;
353 : 0 : size_t offset = 0;
354 : 0 : for (auto _uniform_datas : vContainer) {
355 : 0 : const auto& datas = _uniform_datas.second;
356 : 0 : if (!datas.widget_type.empty()) {
357 : 0 : const auto& uniform_code = datas.getFinalUniformCode();
358 : 0 : size_t pos = _uniform_datas.first - offset;
359 : 0 : final_code.replace(pos, datas.uniform_line.size(), uniform_code);
360 : 0 : offset += datas.uniform_line.size() - uniform_code.size(); // le nouveau code sera forcemment plus court
361 : 0 : assert(offset != std::string::npos);
362 : 0 : }
363 : 0 : }
364 : 0 : #ifdef _DEBUG
365 : 0 : m_save_string_to_file(final_code, "debug/shader.glsl");
366 : 0 : #endif
367 : 0 : return final_code;
368 : 0 : }
369 : :
370 : : #ifdef _DEBUG
371 : : void m_save_string_to_file(const std::string& vString, const std::string& vFilePathName) {
372 : : std::ofstream fileWriter(vFilePathName, std::ios::out);
373 : : if (!fileWriter.bad()) {
374 : : fileWriter << vString;
375 : : fileWriter.close();
376 : : }
377 : : }
378 : : #endif
379 : : };
380 : :
381 : : class IUniform {
382 : : public:
383 : : typedef std::function<bool(IUniform*)> IUniformDrawWidgetFunctor;
384 : :
385 : : protected:
386 : : std::string m_name;
387 : : GLint m_loc = -1;
388 : : GLuint m_channels = 1U;
389 : : bool m_used = false;
390 : : bool m_showed = false;
391 : : std::string m_type;
392 : : std::string m_widget;
393 : : IUniformDrawWidgetFunctor m_draw_widget_functor = nullptr;
394 : : UniformParsingDatas m_uniform_parsing_datas;
395 : :
396 : : public:
397 : 0 : void set_uniform_parsing_datas(const UniformParsingDatas& vUniformParsingDatas) {
398 : 0 : m_uniform_parsing_datas = vUniformParsingDatas;
399 : 0 : }
400 : 0 : void set_draw_widget_functor(const IUniformDrawWidgetFunctor& vUniformDrawWidgetFunctor) {
401 : 0 : m_draw_widget_functor = vUniformDrawWidgetFunctor;
402 : 0 : }
403 : 0 : virtual bool draw_widget() {
404 : 0 : if (m_draw_widget_functor != nullptr) {
405 : 0 : return m_draw_widget_functor(this);
406 : 0 : }
407 : 0 : return true;
408 : 0 : };
409 : 0 : const char* get_general_help() {
410 : 0 : return u8R"(
411 : 0 : general syntax is :
412 : 0 : - uniform type(widget:params) name; // simple or multiline comment
413 : 0 : )";
414 : 0 : }
415 : 0 : virtual const char* get_help() {
416 : 0 : return "";
417 : 0 : };
418 : 0 : virtual bool upload_sampler(int32_t& /*texture_slot_id*/) {
419 : 0 : return false;
420 : 0 : };
421 : 0 : virtual bool upload_scalar() {
422 : 0 : return false;
423 : 0 : };
424 : : };
425 : :
426 : : class UniformTime : public IUniform {
427 : : private:
428 : : bool m_play = false;
429 : : float m_time = 0.0f;
430 : :
431 : : public:
432 : 0 : bool upload_scalar() override {
433 : 0 : if (m_loc > 0) {
434 : 0 : glUniform1fv(m_loc, 1, &m_time);
435 : 0 : CheckGLErrors;
436 : 0 : return true;
437 : 0 : }
438 : 0 : return false;
439 : 0 : }
440 : 0 : void play(bool vFlag) {
441 : 0 : m_play = vFlag;
442 : 0 : }
443 : 0 : const char* get_help() override {
444 : 0 : return u8R"(
445 : 0 : buffer uniform syantax :(default is optional)
446 : 0 : - uniform float(time:default) name;
447 : 0 : )";
448 : 0 : }
449 : : };
450 : :
451 : : class UniformBuffer : public IUniform {
452 : : private:
453 : : std::array<float, 3U> m_size = {};
454 : : int32_t m_sampler2D = -1; // sampler2D
455 : :
456 : : public:
457 : 0 : UniformBuffer() {
458 : 0 : m_widget = "buffer";
459 : 0 : }
460 : 0 : bool upload_scalar() override {
461 : 0 : if (m_loc > 0) {
462 : 0 : switch (m_channels) {
463 : 0 : case 2U: glUniform2fv(m_loc, 1, m_size.data()); break;
464 : 0 : case 3U: glUniform3fv(m_loc, 1, m_size.data()); break;
465 : 0 : }
466 : 0 : CheckGLErrors;
467 : 0 : return true;
468 : 0 : }
469 : 0 : return false;
470 : 0 : }
471 : 0 : bool upload_sampler(int32_t& texture_slot_id) override {
472 : 0 : if (m_loc > 0) {
473 : 0 : glActiveTexture(GL_TEXTURE0 + texture_slot_id);
474 : 0 : CheckGLErrors;
475 : 0 : glBindTexture(GL_TEXTURE_2D, m_sampler2D);
476 : 0 : CheckGLErrors;
477 : 0 : glUniform1i(m_loc, texture_slot_id);
478 : 0 : CheckGLErrors;
479 : 0 : ++texture_slot_id;
480 : 0 : return true;
481 : 0 : }
482 : 0 : return false;
483 : 0 : }
484 : 0 : const char* get_help() override {
485 : 0 : return u8R"(
486 : 0 : buffer uniform syantax :
487 : 0 : - resolution :
488 : 0 : - vec2 resolution => uniform vec2(buffer) name;
489 : 0 : - vec3 resolution => uniform vec2(buffer) name; (like shadertoy resolution)
490 : 0 : - sampler2D back buffer : (target is optional. n is the fbo attachment id frrm 0 to 7)
491 : 0 : - uniform sampler2D(buffer) name; => for target == 0
492 : 0 : - uniform sampler2D(buffer:target=n) name; => for target == n
493 : 0 : )";
494 : 0 : }
495 : : };
496 : :
497 : : class UniformSlider : public IUniform {
498 : : public:
499 : 0 : const char* get_help() override {
500 : 0 : return u8R"(
501 : 0 : float slider uniform syntax : (default and step are otionals)
502 : 0 : - uniform float(inf:sup:default:step) name;
503 : 0 : - uniform vec2(inf:sup:default:step) name;
504 : 0 : - uniform vec3(inf:sup:default:step) name;
505 : 0 : - uniform vec4(inf:sup:default:step) name;
506 : 0 : - uniform int(inf:sup:default:step) name;
507 : 0 : - uniform ivec2(inf:sup:default:step) name;
508 : 0 : - uniform ivec3(inf:sup:default:step) name;
509 : 0 : - uniform ivec4(inf:sup:default:step) name;
510 : 0 : )";
511 : 0 : }
512 : : };
513 : : class UniformFloatSlider : public UniformSlider {
514 : : private:
515 : : std::array<float, 4U> m_datas_f;
516 : :
517 : : public:
518 : 0 : bool upload_scalar() override {
519 : 0 : if (m_loc > 0) {
520 : 0 : switch (m_channels) {
521 : 0 : case 1U: glUniform2fv(m_loc, 1, m_datas_f.data()); break;
522 : 0 : case 2U: glUniform2fv(m_loc, 1, m_datas_f.data()); break;
523 : 0 : case 3U: glUniform3fv(m_loc, 1, m_datas_f.data()); break;
524 : 0 : case 4U: glUniform2fv(m_loc, 1, m_datas_f.data()); break;
525 : 0 : }
526 : 0 : CheckGLErrors;
527 : 0 : return true;
528 : 0 : }
529 : 0 : return false;
530 : 0 : }
531 : : };
532 : :
533 : : class UniformIntSlider : public UniformSlider {
534 : : private:
535 : : std::array<int32_t, 4U> m_datas_i;
536 : :
537 : : public:
538 : 0 : bool upload_scalar() override {
539 : 0 : if (m_loc > 0) {
540 : 0 : switch (m_channels) {
541 : 0 : case 1U: glUniform2iv(m_loc, 1, m_datas_i.data()); break;
542 : 0 : case 2U: glUniform2iv(m_loc, 1, m_datas_i.data()); break;
543 : 0 : case 3U: glUniform3iv(m_loc, 1, m_datas_i.data()); break;
544 : 0 : case 4U: glUniform2iv(m_loc, 1, m_datas_i.data()); break;
545 : 0 : }
546 : 0 : CheckGLErrors;
547 : 0 : return true;
548 : 0 : }
549 : 0 : return false;
550 : 0 : }
551 : : };
552 : :
553 : : class UniformsManager : public UniformStrings {
554 : : public:
555 : : typedef std::map<std::string, IUniform*> UniformsContainer;
556 : :
557 : : private:
558 : : UniformsContainer m_uniforms;
559 : :
560 : : public:
561 : 0 : const UniformsContainer& get_uniforms() {
562 : 0 : return m_uniforms;
563 : 0 : }
564 : 0 : UniformsContainer& get_uniforms_ref() {
565 : 0 : return m_uniforms;
566 : 0 : }
567 : : };
568 : :
569 : : } // namespace gl
570 : : } // namespace ez
|