1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 **************************************************************************/
26 // File: vogl_state_vector.cpp
27 #include "vogl_state_vector.h"
28 #include "vogl_sort.h"
29 #include "gl_pname_defs.inc"
30 #include "vogl_growable_array.h"
32 #define VOGL_CONTEXT_STATE_DEBUG 0
34 #if VOGL_CONTEXT_STATE_DEBUG
35 #warning VOGL_CONTEXT_STATE_DEBUG enabled
38 //----------------------------------------------------------------------------------------------------------------------
39 // vogl_get_state_type_name
40 //----------------------------------------------------------------------------------------------------------------------
41 const char *vogl_get_state_type_name(vogl_state_type s)
74 //----------------------------------------------------------------------------------------------------------------------
75 // vogl_get_state_type_from_name
76 //----------------------------------------------------------------------------------------------------------------------
77 vogl_state_type vogl_get_state_type_from_name(const char *pName)
81 if (vogl_strcmp(pName, "invalid") == 0)
83 else if (vogl_strcmp(pName, "boolean") == 0)
85 else if (vogl_strcmp(pName, "GLenum") == 0)
87 else if (vogl_strcmp(pName, "int32") == 0)
89 else if (vogl_strcmp(pName, "uint32") == 0)
91 else if (vogl_strcmp(pName, "int64_t") == 0)
93 else if (vogl_strcmp(pName, "uint64_t") == 0)
95 else if (vogl_strcmp(pName, "float") == 0)
97 else if (vogl_strcmp(pName, "double") == 0)
99 else if (vogl_strcmp(pName, "pointer") == 0)
105 //----------------------------------------------------------------------------------------------------------------------
106 // vogl_get_state_type_size
107 //----------------------------------------------------------------------------------------------------------------------
108 uint vogl_get_state_type_size(vogl_state_type s)
117 return sizeof(GLboolean);
119 return sizeof(GLenum);
121 return sizeof(int32);
123 return sizeof(uint32);
125 return sizeof(int64_t);
127 return sizeof(uint64_t);
129 return sizeof(float);
131 return sizeof(double);
133 return sizeof(uint64_t);
140 //----------------------------------------------------------------------------------------------------------------------
141 // vogl_state_data::vogl_state_data
142 //----------------------------------------------------------------------------------------------------------------------
143 vogl_state_data::vogl_state_data()
145 m_data_type(cSTInvalid),
151 //----------------------------------------------------------------------------------------------------------------------
152 // vogl_state_data::vogl_state_data
153 //----------------------------------------------------------------------------------------------------------------------
154 vogl_state_data::vogl_state_data(GLenum enum_val, uint index, uint n, vogl_state_type data_type, bool indexed_variant)
155 : m_id(enum_val, index, indexed_variant),
156 m_data_type(data_type),
158 m_data(n * vogl_get_state_type_size(data_type))
163 //----------------------------------------------------------------------------------------------------------------------
164 // vogl_state_data::vogl_state_data
165 //----------------------------------------------------------------------------------------------------------------------
166 vogl_state_data::vogl_state_data(GLenum enum_val, uint index, const void *pData, uint element_size, bool indexed_variant)
168 m_data_type(cSTInvalid),
173 init(enum_val, index, pData, element_size, indexed_variant);
176 //----------------------------------------------------------------------------------------------------------------------
177 // vogl_state_data::init
178 //----------------------------------------------------------------------------------------------------------------------
179 void vogl_state_data::init(GLenum enum_val, uint index, uint n, vogl_state_type data_type, bool indexed_variant)
183 m_id.set(enum_val, index, indexed_variant);
184 m_data_type = data_type;
187 uint data_type_size = vogl_get_state_type_size(data_type);
189 #if VOGL_CONTEXT_STATE_DEBUG
190 m_data.resize((n + 1) * data_type_size);
191 memset(m_data.get_ptr() + (n * data_type_size), 0xCF, data_type_size);
193 m_data.resize(n * data_type_size);
197 //----------------------------------------------------------------------------------------------------------------------
198 // vogl_state_data::init
199 //----------------------------------------------------------------------------------------------------------------------
200 bool vogl_state_data::init(GLenum enum_val, uint index, const void *pData, uint element_size, bool indexed_variant)
204 const char *pName = g_gl_enums.find_name(enum_val);
206 int pname_def_index = g_gl_enums.find_pname_def_index(enum_val);
207 if (pname_def_index < 0)
209 vogl_warning_printf("%s: Unable to find pname def for GL enum %s\n", VOGL_METHOD_NAME, pName);
213 const gl_pname_def_t &pname_def = g_gl_pname_defs[pname_def_index];
215 VOGL_ASSERT(pname_def.m_gl_enum == enum_val);
217 vogl_state_type state_type = static_cast<vogl_state_type>(pname_def.m_type);
219 if (state_type == cSTInvalid)
222 vogl_warning_printf("%s: Can't determine type of GL enum %s\n", VOGL_METHOD_NAME, pName);
226 uint n = g_gl_enums.get_pname_count(enum_val);
233 uint state_type_size = vogl_get_state_type_size(state_type);
234 VOGL_ASSERT(state_type_size);
236 init(enum_val, index, n, state_type, indexed_variant);
238 void *pDst = m_data.get_ptr();
239 if (state_type != cSTPointer)
241 if (element_size == state_type_size)
242 memcpy(pDst, pData, state_type_size * n);
243 else if ((state_type == cSTGLboolean) && (element_size == sizeof(GLint)))
245 for (uint i = 0; i < n; i++)
246 static_cast<GLboolean *>(pDst)[i] = static_cast<const GLint *>(pData)[i];
250 VOGL_VERIFY(!"element_size is invalid");
255 VOGL_VERIFY(element_size == sizeof(void *));
257 // Convert from native 32/64 ptrs to 64-bit values
258 const void *const *pSrc_ptrs = static_cast<const void *const *>(pData);
259 uint64_t *pDst_u64 = static_cast<uint64_t *>(pDst);
260 for (uint i = 0; i < n; i++)
261 pDst_u64[i] = reinterpret_cast<uint64_t>(pSrc_ptrs[i]);
267 //----------------------------------------------------------------------------------------------------------------------
268 // vogl_state_data::debug_check
269 //----------------------------------------------------------------------------------------------------------------------
270 void vogl_state_data::debug_check()
274 #if VOGL_CONTEXT_STATE_DEBUG
277 const uint data_type_size = get_data_type_size();
278 VOGL_ASSERT((data_type_size) && ((m_data.size() / data_type_size) == (m_num_elements + 1)));
279 const uint8 *p = get_data_ptr<const uint8>() + m_num_elements * data_type_size;
281 for (uint i = 0; i < data_type_size; i++)
282 VOGL_ASSERT(p[i] == 0xCF);
287 //----------------------------------------------------------------------------------------------------------------------
288 // vogl_state_data::swap
289 //----------------------------------------------------------------------------------------------------------------------
290 void vogl_state_data::swap(vogl_state_data &other)
294 std::swap(m_id, other.m_id);
295 std::swap(m_data_type, other.m_data_type);
296 std::swap(m_num_elements, other.m_num_elements);
297 m_data.swap(other.m_data);
300 //----------------------------------------------------------------------------------------------------------------------
301 // vogl_state_data::is_equal
302 //----------------------------------------------------------------------------------------------------------------------
303 bool vogl_state_data::is_equal(const vogl_state_data &rhs) const
307 if (m_id != rhs.m_id)
309 if (m_data_type != rhs.m_data_type)
311 if (m_num_elements != rhs.m_num_elements)
314 uint total_size = get_data_type_size() * m_num_elements;
315 if ((m_data.size() < total_size) || (rhs.m_data.size() < total_size))
321 if (memcmp(m_data.get_ptr(), rhs.m_data.get_ptr(), total_size) != 0)
327 //----------------------------------------------------------------------------------------------------------------------
328 // vogl_state_data::get_bool
329 //----------------------------------------------------------------------------------------------------------------------
330 void vogl_state_data::get_bool(bool *pVals) const
338 for (uint i = 0; i < m_num_elements; i++)
339 pVals[i] = get_element<GLboolean>(i);
344 for (uint i = 0; i < m_num_elements; i++)
345 pVals[i] = get_element<GLenum>(i) != 0;
350 for (uint i = 0; i < m_num_elements; i++)
351 pVals[i] = get_element<int32>(i) != 0;
356 for (uint i = 0; i < m_num_elements; i++)
357 pVals[i] = get_element<uint32>(i) != 0;
362 for (uint i = 0; i < m_num_elements; i++)
363 pVals[i] = get_element<int64_t>(i) != 0;
368 for (uint i = 0; i < m_num_elements; i++)
369 pVals[i] = get_element<uint64_t>(i) != 0;
374 for (uint i = 0; i < m_num_elements; i++)
375 pVals[i] = get_element<float>(i) != 0.0f;
380 for (uint i = 0; i < m_num_elements; i++)
381 pVals[i] = get_element<double>(i) != 0.0f;
386 for (uint i = 0; i < m_num_elements; i++)
387 pVals[i] = get_element<GLuint64>(i) != 0;
391 case cTotalStateTypes:
404 //----------------------------------------------------------------------------------------------------------------------
405 // vogl_state_data::get_uint64
406 // OK, GL itself is not type safe, unsigned vs. signed are mixed everywhere. And the pname table marks a ton of unsigned stuff as signed ints.
407 // So none of these methods clamp or do anything fancy on ints - I assume you know what you're doing.
408 //----------------------------------------------------------------------------------------------------------------------
409 void vogl_state_data::get_uint64(uint64_t *pVals) const
417 for (uint i = 0; i < m_num_elements; i++)
418 pVals[i] = get_element<GLboolean>(i);
423 for (uint i = 0; i < m_num_elements; i++)
424 pVals[i] = get_element<GLenum>(i);
429 for (uint i = 0; i < m_num_elements; i++)
430 pVals[i] = static_cast<int64_t>(get_element<int32>(i));
435 for (uint i = 0; i < m_num_elements; i++)
436 pVals[i] = get_element<uint32>(i);
441 for (uint i = 0; i < m_num_elements; i++)
442 pVals[i] = get_element<int64_t>(i);
448 for (uint i = 0; i < m_num_elements; i++)
449 pVals[i] = get_element<uint64_t>(i);
454 for (uint i = 0; i < m_num_elements; i++)
456 double v = get_element<float>(i);
457 v = trunc((v < 0.0f) ? (v - .5f) : (v + .5f));
458 v = math::clamp<double>(v, static_cast<double>(cINT64_MIN), static_cast<double>(cUINT64_MAX));
460 pVals[i] = static_cast<int64_t>(v);
462 pVals[i] = static_cast<uint64_t>(v);
468 for (uint i = 0; i < m_num_elements; i++)
470 double v = get_element<double>(i);
471 v = trunc((v < 0.0f) ? (v - .5f) : (v + .5f));
472 v = math::clamp<double>(v, static_cast<double>(cINT64_MIN), static_cast<double>(cUINT64_MAX));
474 pVals[i] = static_cast<int64_t>(v);
476 pVals[i] = static_cast<uint64_t>(v);
481 case cTotalStateTypes:
494 //----------------------------------------------------------------------------------------------------------------------
495 // vogl_state_data::get_uint
496 //----------------------------------------------------------------------------------------------------------------------
497 void vogl_state_data::get_uint(uint *pVals) const
505 for (uint i = 0; i < m_num_elements; i++)
506 pVals[i] = get_element<GLboolean>(i);
511 for (uint i = 0; i < m_num_elements; i++)
512 pVals[i] = get_element<GLenum>(i);
517 for (uint i = 0; i < m_num_elements; i++)
518 pVals[i] = get_element<int32>(i);
523 for (uint i = 0; i < m_num_elements; i++)
524 pVals[i] = get_element<uint32>(i);
529 for (uint i = 0; i < m_num_elements; i++)
530 pVals[i] = static_cast<uint>(get_element<int64_t>(i));
536 for (uint i = 0; i < m_num_elements; i++)
537 pVals[i] = static_cast<uint>(get_element<uint64_t>(i));
542 for (uint i = 0; i < m_num_elements; i++)
544 double v = get_element<float>(i);
545 v = trunc((v < 0.0f) ? (v - .5f) : (v + .5f));
546 v = math::clamp<double>(v, static_cast<double>(cINT32_MIN), static_cast<double>(cUINT32_MAX));
548 pVals[i] = static_cast<int32>(v);
550 pVals[i] = static_cast<uint32>(v);
556 for (uint i = 0; i < m_num_elements; i++)
558 double v = get_element<double>(i);
559 v = trunc((v < 0.0f) ? (v - .5f) : (v + .5f));
560 v = math::clamp<double>(v, static_cast<double>(cINT32_MIN), static_cast<double>(cUINT32_MAX));
562 pVals[i] = static_cast<int32>(v);
564 pVals[i] = static_cast<uint32>(v);
569 case cTotalStateTypes:
582 //----------------------------------------------------------------------------------------------------------------------
583 // vogl_state_data::get_int64
584 //----------------------------------------------------------------------------------------------------------------------
585 void vogl_state_data::get_int64(int64_t *pVals) const
593 for (uint i = 0; i < m_num_elements; i++)
594 pVals[i] = get_element<GLboolean>(i);
599 for (uint i = 0; i < m_num_elements; i++)
600 pVals[i] = get_element<GLenum>(i);
605 for (uint i = 0; i < m_num_elements; i++)
606 pVals[i] = get_element<int32>(i);
611 for (uint i = 0; i < m_num_elements; i++)
612 pVals[i] = get_element<uint32>(i);
617 for (uint i = 0; i < m_num_elements; i++)
618 pVals[i] = get_element<int64_t>(i);
624 for (uint i = 0; i < m_num_elements; i++)
625 pVals[i] = get_element<uint64_t>(i);
630 for (uint i = 0; i < m_num_elements; i++)
632 double v = get_element<float>(i);
633 v = trunc((v < 0.0f) ? (v - .5f) : (v + .5f));
634 v = math::clamp<double>(v, static_cast<double>(cINT64_MIN), static_cast<double>(cUINT64_MAX));
636 pVals[i] = static_cast<uint64_t>(v);
638 pVals[i] = static_cast<int64_t>(v);
644 for (uint i = 0; i < m_num_elements; i++)
646 double v = get_element<double>(i);
647 v = trunc((v < 0.0f) ? (v - .5f) : (v + .5f));
648 v = math::clamp<double>(v, static_cast<double>(cINT64_MIN), static_cast<double>(cUINT64_MAX));
650 pVals[i] = static_cast<uint64_t>(v);
652 pVals[i] = static_cast<int64_t>(v);
657 case cTotalStateTypes:
670 //----------------------------------------------------------------------------------------------------------------------
671 // vogl_state_data::get_int
672 //----------------------------------------------------------------------------------------------------------------------
673 void vogl_state_data::get_int(int *pVals) const
681 for (uint i = 0; i < m_num_elements; i++)
682 pVals[i] = get_element<GLboolean>(i);
687 for (uint i = 0; i < m_num_elements; i++)
688 pVals[i] = get_element<GLenum>(i);
693 for (uint i = 0; i < m_num_elements; i++)
694 pVals[i] = get_element<int32>(i);
699 for (uint i = 0; i < m_num_elements; i++)
700 pVals[i] = get_element<uint32>(i);
705 for (uint i = 0; i < m_num_elements; i++)
706 pVals[i] = static_cast<int>(get_element<int64_t>(i));
712 for (uint i = 0; i < m_num_elements; i++)
713 pVals[i] = static_cast<int>(get_element<uint64_t>(i));
718 for (uint i = 0; i < m_num_elements; i++)
720 double v = get_element<float>(i);
721 v = trunc((v < 0.0f) ? (v - .5f) : (v + .5f));
722 v = math::clamp<double>(v, static_cast<double>(cINT32_MIN), static_cast<double>(cUINT32_MAX));
724 pVals[i] = static_cast<uint32>(v);
726 pVals[i] = static_cast<int32>(v);
732 for (uint i = 0; i < m_num_elements; i++)
734 double v = get_element<double>(i);
735 v = trunc((v < 0.0f) ? (v - .5f) : (v + .5f));
736 v = math::clamp<double>(v, static_cast<double>(cINT32_MIN), static_cast<double>(cUINT32_MAX));
738 pVals[i] = static_cast<uint32>(v);
740 pVals[i] = static_cast<int32>(v);
745 case cTotalStateTypes:
758 //----------------------------------------------------------------------------------------------------------------------
759 // vogl_state_data::get_pointer
760 //----------------------------------------------------------------------------------------------------------------------
761 void vogl_state_data::get_pointer(void **ppVals) const
765 vogl::growable_array<uint64_t, 16> temp(m_num_elements);
767 get_uint64(temp.get_ptr());
769 for (uint i = 0; i < m_num_elements; i++)
771 uint64_t v = temp[i];
772 ppVals[i] = *reinterpret_cast<void **>(&v);
776 //----------------------------------------------------------------------------------------------------------------------
777 // vogl_state_data::get_double
778 //----------------------------------------------------------------------------------------------------------------------
779 void vogl_state_data::get_double(double *pVals) const
787 for (uint i = 0; i < m_num_elements; i++)
788 pVals[i] = static_cast<double>(get_element<GLboolean>(i));
793 for (uint i = 0; i < m_num_elements; i++)
794 pVals[i] = static_cast<double>(get_element<GLenum>(i));
799 for (uint i = 0; i < m_num_elements; i++)
800 pVals[i] = static_cast<double>(get_element<int32>(i));
805 for (uint i = 0; i < m_num_elements; i++)
806 pVals[i] = static_cast<double>(get_element<uint32>(i));
811 for (uint i = 0; i < m_num_elements; i++)
812 pVals[i] = static_cast<double>(get_element<int64_t>(i));
818 for (uint i = 0; i < m_num_elements; i++)
819 pVals[i] = static_cast<double>(get_element<uint64_t>(i));
824 for (uint i = 0; i < m_num_elements; i++)
825 pVals[i] = static_cast<double>(get_element<float>(i));
830 for (uint i = 0; i < m_num_elements; i++)
831 pVals[i] = get_element<double>(i);
835 case cTotalStateTypes:
845 //----------------------------------------------------------------------------------------------------------------------
846 // vogl_state_data::get_float
847 //----------------------------------------------------------------------------------------------------------------------
848 void vogl_state_data::get_float(float *pVals) const
852 vogl::growable_array<double, 16> temp(m_num_elements);
854 get_double(temp.get_ptr());
856 for (uint i = 0; i < m_num_elements; i++)
857 pVals[i] = static_cast<float>(temp[i]);
860 //----------------------------------------------------------------------------------------------------------------------
861 // vogl_state_data::serialize
862 //----------------------------------------------------------------------------------------------------------------------
863 bool vogl_state_data::serialize(json_node &node) const
867 const char *pEnum_name = g_gl_enums.find_name(m_id.m_enum_val);
868 dynamic_string enum_name;
870 enum_name.set(pEnum_name);
872 enum_name.format("0x%X", m_id.m_enum_val);
874 node.add_key_value("enum", enum_name.get_ptr());
875 node.add_key_value("index", m_id.m_index);
876 node.add_key_value("indexed_variant", m_id.m_indexed_variant);
878 node.add_key_value("data_type", vogl_get_state_type_name(m_data_type));
879 json_node &values_node = node.add_array("values");
881 // >=, not ==, in case of VOGL_CONTEXT_STATE_DEBUG
882 VOGL_ASSERT(m_data.size_in_bytes() >= m_num_elements * get_data_type_size());
884 for (uint i = 0; i < m_num_elements; i++)
886 const void *pElement = m_data.get_ptr() + i * get_data_type_size();
892 const GLboolean *pVal = reinterpret_cast<const GLboolean *>(pElement);
893 values_node.add_value(*pVal ? true : false);
898 const GLenum *pVal = reinterpret_cast<const GLenum *>(pElement);
900 const char *pValue_enum_name = g_gl_enums.find_name(*pVal);
901 dynamic_string value_enum_name;
902 if (pValue_enum_name)
903 value_enum_name.set(pValue_enum_name);
905 value_enum_name.format("0x%X", *pVal);
907 values_node.add_value(value_enum_name);
912 const int32 *pVal = reinterpret_cast<const int32 *>(pElement);
913 values_node.add_value(*pVal);
918 const uint32 *pVal = reinterpret_cast<const uint32 *>(pElement);
919 values_node.add_value(*pVal);
924 const int64_t *pVal = reinterpret_cast<const int64_t *>(pElement);
925 values_node.add_value(*pVal);
930 const float *pVal = reinterpret_cast<const float *>(pElement);
931 values_node.add_value(*pVal);
936 const double *pVal = reinterpret_cast<const double *>(pElement);
937 values_node.add_value(*pVal);
944 vogl_sprintf_s(buf, sizeof(buf), "0x%" PRIX64, *reinterpret_cast<const uint64_t *>(pElement));
945 values_node.add_value(buf);
951 values_node.add_value(0);
960 //----------------------------------------------------------------------------------------------------------------------
961 // vogl_state_data::deserialize
962 //----------------------------------------------------------------------------------------------------------------------
963 bool vogl_state_data::deserialize(const json_node &node)
967 dynamic_string key_str(node.value_as_string("enum"));
969 uint64_t gl_enum = 0;
970 if (key_str.begins_with("0x"))
971 gl_enum = string_to_uint64(key_str.get_ptr(), gl_enums::cUnknownEnum);
973 gl_enum = g_gl_enums.find_enum(key_str.get_ptr());
975 if ((gl_enum == gl_enums::cUnknownEnum) || (gl_enum > cUINT32_MAX))
977 vogl_warning_printf("%s: Unknown/invalid GL enum \"%s\"\n", VOGL_METHOD_NAME, key_str.get_ptr());
981 int index = node.value_as_int("index", -1);
984 vogl_warning_printf("%s: Expected index for GL enum \"%s\"\n", VOGL_METHOD_NAME, key_str.get_ptr());
988 bool indexed_variant = node.value_as_bool("indexed_variant", false);
990 dynamic_string state_type_str(node.value_as_string("data_type"));
992 vogl_state_type state_type = vogl_get_state_type_from_name(state_type_str.get_ptr());
993 if (state_type == cSTInvalid)
995 vogl_warning_printf("%s: Unknown state_type for GL enum \"%s\"\n", VOGL_METHOD_NAME, key_str.get_ptr());
999 const json_node *pValues_array = node.find_child_array("values");
1002 vogl_warning_printf("%s: Can't find values array for GL enum \"%s\"\n", VOGL_METHOD_NAME, key_str.get_ptr());
1006 uint num_elements = pValues_array->size();
1007 uint state_type_size = vogl_get_state_type_size(state_type);
1009 vogl_state_data state;
1010 init(static_cast<GLenum>(gl_enum), index, num_elements, state_type, indexed_variant);
1012 for (uint element_index = 0; element_index < num_elements; element_index++)
1014 void *pElement = m_data.get_ptr() + element_index * state_type_size;
1020 GLboolean *pVal = reinterpret_cast<GLboolean *>(pElement);
1021 *pVal = pValues_array->value_as_bool(element_index);
1026 const char *pStr = pValues_array->value_as_string_ptr(element_index);
1029 vogl_warning_printf("%s: Failed converting value %u of GL enum \"%s\"\n", VOGL_METHOD_NAME, element_index, key_str.get_ptr());
1033 uint64_t gl_enum = 0;
1034 if ((pStr[0] == '0') && (pStr[1] == 'x'))
1035 gl_enum = string_to_uint64(pStr, gl_enums::cUnknownEnum);
1037 gl_enum = g_gl_enums.find_enum(dynamic_string(pStr));
1039 if ((gl_enum == gl_enums::cUnknownEnum) || (gl_enum > cUINT32_MAX))
1041 vogl_error_printf("%s: Unknown/invalid GL enum \"%s\"\n", VOGL_METHOD_NAME, pStr);
1045 GLenum *pVal = reinterpret_cast<GLenum *>(pElement);
1046 *pVal = static_cast<GLenum>(gl_enum);
1052 int32 *pVal = reinterpret_cast<int32 *>(pElement);
1053 *pVal = pValues_array->value_as_int(element_index);
1058 uint32 *pVal = reinterpret_cast<uint32 *>(pElement);
1060 int64_t v = pValues_array->value_as_int64(element_index);
1061 *pVal = static_cast<uint32>(math::clamp<int64_t>(v, 0, cUINT32_MAX));
1067 int64_t *pVal = reinterpret_cast<int64_t *>(pElement);
1068 *pVal = pValues_array->value_as_int64(element_index);
1073 float *pVal = reinterpret_cast<float *>(pElement);
1074 *pVal = pValues_array->value_as_float(element_index);
1079 double *pVal = reinterpret_cast<double *>(pElement);
1080 *pVal = pValues_array->value_as_double(element_index);
1086 const char *pStr = pValues_array->value_as_string_ptr(element_index);
1089 vogl_warning_printf("%s: Failed converting value %u of GL enum \"%s\"\n", VOGL_METHOD_NAME, element_index, key_str.get_ptr());
1093 uint64_t *pVal = reinterpret_cast<uint64_t *>(pElement);
1096 const char *pBuf = pStr;
1097 string_ptr_to_uint64(pBuf, val);
1115 //----------------------------------------------------------------------------------------------------------------------
1116 // vogl_state_vector::vogl_state_vector
1117 //----------------------------------------------------------------------------------------------------------------------
1118 vogl_state_vector::vogl_state_vector()
1123 //----------------------------------------------------------------------------------------------------------------------
1124 // vogl_state_vector::clear
1125 //----------------------------------------------------------------------------------------------------------------------
1126 void vogl_state_vector::clear()
1133 //----------------------------------------------------------------------------------------------------------------------
1134 // vogl_state_vector::find
1135 //----------------------------------------------------------------------------------------------------------------------
1136 const vogl_state_data *vogl_state_vector::find(GLenum enum_val, uint index, bool indexed_variant) const
1140 return m_states.find_value(vogl_state_id(enum_val, index, indexed_variant));
1143 //----------------------------------------------------------------------------------------------------------------------
1144 // vogl_state_vector::serialize
1145 //----------------------------------------------------------------------------------------------------------------------
1146 bool vogl_state_vector::serialize(json_node &node, vogl_blob_manager &blob_manager) const
1150 VOGL_NOTE_UNUSED(blob_manager);
1152 json_node &node_array = node.add_array("states");
1154 for (state_map::const_iterator it = m_states.begin(); it != m_states.end(); ++it)
1156 const vogl_state_data &data = it->second;
1158 if (!data.serialize(node_array.add_object()))
1165 //----------------------------------------------------------------------------------------------------------------------
1166 // vogl_state_vector::deserialize
1167 //----------------------------------------------------------------------------------------------------------------------
1168 bool vogl_state_vector::deserialize(const json_node &node, const vogl_blob_manager &blob_manager)
1172 VOGL_NOTE_UNUSED(blob_manager);
1176 const json_node *pNode_array = node.find_child_array("states");
1180 for (uint value_index = 0; value_index < pNode_array->size(); value_index++)
1182 const json_node *pState_node = pNode_array->get_child(value_index);
1186 vogl_state_data state;
1187 if (!state.deserialize(*pState_node))
1192 vogl_warning_printf("%s: vogl_state_vector::deserialize: Ignoring duplicate state 0x%X index %u\n", VOGL_METHOD_NAME, state.get_enum_val(), state.get_index());
1199 //----------------------------------------------------------------------------------------------------------------------
1200 // vogl_state_vector::deserialize
1201 //----------------------------------------------------------------------------------------------------------------------
1202 bool vogl_state_vector::deserialize(const char *pChild_name, const json_node &parent_node, const vogl_blob_manager &blob_manager)
1208 const json_node *pChild_node = parent_node.find_child_object(pChild_name);
1212 return deserialize(*pChild_node, blob_manager);
1215 //----------------------------------------------------------------------------------------------------------------------
1216 // vogl_state_vector::operator==
1217 //----------------------------------------------------------------------------------------------------------------------
1218 bool vogl_state_vector::operator==(const vogl_state_vector &rhs) const
1222 if (m_states.size() != rhs.m_states.size())
1225 VOGL_ASSERT(m_states.debug_check());
1226 VOGL_ASSERT(rhs.m_states.debug_check());
1228 const_iterator lhs_it(begin());
1229 const_iterator rhs_it(rhs.begin());
1230 for (; lhs_it != end(); ++lhs_it, ++rhs_it)
1232 if (rhs_it == rhs.end())
1238 const vogl_state_data &lhs = lhs_it->second;
1239 const vogl_state_data &rhs = rhs_it->second;
1241 if (lhs.get_id() != rhs.get_id())
1244 if (lhs.get_enum_val() == GL_TIMESTAMP)
1247 if (!lhs.is_equal(rhs))
1254 //----------------------------------------------------------------------------------------------------------------------
1255 // vogl_state_vector::insert
1256 //----------------------------------------------------------------------------------------------------------------------
1257 bool vogl_state_vector::insert(GLenum enum_val, uint index, const void *pData, uint element_size, bool indexed_variant)
1261 vogl_state_data state_data;
1262 if (!state_data.init(enum_val, index, pData, element_size, indexed_variant))
1265 return insert(state_data);
1268 //----------------------------------------------------------------------------------------------------------------------
1269 // vogl_state_vector::insert
1270 //----------------------------------------------------------------------------------------------------------------------
1271 bool vogl_state_vector::insert(const vogl_state_data &state_data)
1275 return m_states.insert(state_data.get_id(), state_data).second;