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_gl_utils.h
27 #ifndef VOGL_GL_UTILS_H
28 #define VOGL_GL_UTILS_H
31 #include "TypeTraits.h"
33 #include "vogl_ctypes.h"
35 #include "vogl_hash_map.h"
36 #include "vogl_command_line_params.h"
38 #include "vogl_json.h"
39 #include "vogl_value.h"
40 #include "vogl_growable_array.h"
41 #include "vogl_matrix.h"
43 //----------------------------------------------------------------------------------------------------------------------
45 //----------------------------------------------------------------------------------------------------------------------
51 class vogl_context_info;
52 class vogl_blob_manager;
53 class vogl_context_desc;
55 typedef vogl::map<GLenum, int> GLenum_to_int_map;
57 //----------------------------------------------------------------------------------------------------------------------
59 //----------------------------------------------------------------------------------------------------------------------
60 #define vogl_printf vogl::console::info
61 #define vogl_message_printf vogl::console::message
62 #define vogl_debug_printf vogl::console::debug
63 #define vogl_warning_printf vogl::console::warning
64 #define vogl_error_printf vogl::console::error
65 #define vogl_log_printf vogl::console::info
66 #define vogl_header1_printf vogl::console::header1
68 #define vogl_printf_once(x, ...) \
70 static bool __printed_msg##__LINE__; \
71 if (!__printed_msg##__LINE__) \
73 __printed_msg##__LINE__ = true; \
74 vogl::console::info(x, __VA_ARGS__); \
77 #define vogl_message_printf_once(x, ...) \
79 static bool __printed_msg##__LINE__; \
80 if (!__printed_msg##__LINE__) \
82 __printed_msg##__LINE__ = true; \
83 vogl::console::message(x, __VA_ARGS__); \
86 #define vogl_debug_printf_once(x, ...) \
88 static bool __printed_msg##__LINE__; \
89 if (!__printed_msg##__LINE__) \
91 __printed_msg##__LINE__ = true; \
92 vogl::console::debug(x, __VA_ARGS__); \
95 #define vogl_warning_printf_once(x, ...) \
97 static bool __printed_msg##__LINE__; \
98 if (!__printed_msg##__LINE__) \
100 __printed_msg##__LINE__ = true; \
101 vogl::console::warning(x, __VA_ARGS__); \
104 #define vogl_error_printf_once(x, ...) \
106 static bool __printed_msg##__LINE__; \
107 if (!__printed_msg##__LINE__) \
109 __printed_msg##__LINE__ = true; \
110 vogl::console::error(x, __VA_ARGS__); \
113 #define vogl_log_printf_once(x, ...) \
115 static bool __printed_msg##__LINE__; \
116 if (!__printed_msg##__LINE__) \
118 __printed_msg##__LINE__ = true; \
119 vogl::console::info(x, __VA_ARGS__); \
123 //----------------------------------------------------------------------------------------------------------------------
124 // cast_val_to_uint64
125 //----------------------------------------------------------------------------------------------------------------------
126 template <typename T>
127 static inline uint64_t cast_val_to_uint64(const T &value)
131 if (n > sizeof(uint64_t))
132 n = sizeof(uint64_t);
133 memcpy(&res, &value, n);
137 //----------------------------------------------------------------------------------------------------------------------
138 // type/format/texture helpers
139 //----------------------------------------------------------------------------------------------------------------------
140 uint32_t vogl_get_gl_type_size(uint32_t ogl_type);
141 uint vogl_get_image_format_channels(GLenum format);
142 void vogl_get_image_format_info(GLenum format, GLenum type, uint &num_channels, uint &bits_per_element, uint &bits_per_pixel);
144 // vogl_get_image_size() reads the current pixel unpack state!
145 size_t vogl_get_image_size(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth);
146 size_t vogl_get_tex_target_image_size(GLenum target, GLint level, GLenum format, GLenum type);
147 uint vogl_get_image_format_size_in_bytes(GLenum format, GLenum type);
149 size_t vogl_determine_glMap1_size(GLenum target, GLint stride, GLint order);
150 size_t vogl_determine_glMap2_size(GLenum target, GLint ustride, GLint uorder, GLint vstride, GLint vorder);
152 //----------------------------------------------------------------------------------------------------------------------
153 // struct vogl_enum_desc
154 //----------------------------------------------------------------------------------------------------------------------
155 struct vogl_enum_desc
157 inline vogl_enum_desc()
161 inline vogl_enum_desc(uint64_t value, const char *pPrefix, const char *pSpec_type, const char *pGL_type, const char *pMacro_name)
162 : m_value(value), m_prefix(pPrefix), m_spec_type(pSpec_type), m_gl_type(pGL_type), m_macro_name(pMacro_name)
168 vogl::dynamic_string m_prefix;
169 vogl::dynamic_string m_spec_type;
170 vogl::dynamic_string m_gl_type;
171 vogl::dynamic_string m_macro_name;
173 // Priorities are only used when trying to determine the best enum string to return given a value.
174 // TODO: Move this to voglgen to avoid the runtime init cost.
184 sort_priority_t m_sort_priority;
186 void init_sort_priority();
188 bool operator<(const vogl_enum_desc &rhs) const;
191 typedef vogl::vector<vogl_enum_desc> vogl_enum_desc_vec;
193 //----------------------------------------------------------------------------------------------------------------------
194 // vogl_spec_type_value_enum_key
195 //----------------------------------------------------------------------------------------------------------------------
196 struct vogl_spec_type_and_value_enum_key
198 inline vogl_spec_type_and_value_enum_key()
202 inline vogl_spec_type_and_value_enum_key(const char *pSpec_type, uint64_t value)
203 : m_spec_type(pSpec_type), m_value(value)
208 vogl::dynamic_string m_spec_type;
211 inline bool operator==(const vogl_spec_type_and_value_enum_key &rhs) const
213 return (m_spec_type == rhs.m_spec_type) && (m_value == rhs.m_value);
216 inline operator size_t() const
218 return vogl::fast_hash_obj(m_value) ^ static_cast<size_t>(m_spec_type.get_hash());
222 //----------------------------------------------------------------------------------------------------------------------
223 // enum vogl_state_type
224 // TODO: Rename this to vogl_pname_type or something
225 //----------------------------------------------------------------------------------------------------------------------
228 // These enums MUST me consistent with the types in pname_defs.h
242 //----------------------------------------------------------------------------------------------------------------------
244 //----------------------------------------------------------------------------------------------------------------------
247 VOGL_NO_COPY_OR_ASSIGNMENT_OP(gl_enums);
252 // pPreferred_prefix should usually be "gl", or it can be "glx", "wgl", etc.
253 // TODO: Add a helper that takes a GL entrypoint and param index from vogl_trace_packet::ctype_to_json_value()
254 const char *find_name(uint64_t gl_enum, const char *pPreferred_prefix = NULL) const;
256 const char *find_name(const char *pSpec_type, uint64_t gl_enum, const char *pPreferred_prefix = NULL) const;
258 const char *find_name(uint64_t gl_enum, gl_entrypoint_id_t entrypoint_id, int param_index) const;
260 const char *find_gl_name(uint64_t gl_enum) const
262 return find_name(gl_enum, "gl");
264 const char *find_glx_name(uint64_t gl_enum) const
266 return find_name(gl_enum, "glx");
268 const char *find_gl_error_name(GLenum gl_enum) const
270 return find_name("ErrorCode", gl_enum);
273 // Finds the name of a GL internal/base image format, if this fails then it just calls find_gl_name().
274 const char *find_gl_image_format_name(GLenum gl_enum) const;
276 // Returns -1 on failure
279 cUnknownEnum = 0xFFFFFFFFFFFFFFF0ULL
281 uint64_t find_enum(const dynamic_string &str) const;
283 // This is driven via the pname table, but it may also call GL!
284 int get_pname_count(uint64_t gl_enum) const;
286 // This is driven via the pname table, but it may also call GL!
287 int get_pname_type(uint64_t gl_enum) const;
289 // Maps a GL enum to a pname definition index, or returns cInvalidIndex on failure.
290 int find_pname_def_index(uint64_t gl_enum) const;
293 uint16_t m_gl_enum_to_pname_def_index[0x10000];
295 typedef vogl::hash_map<dynamic_string, uint64_t> gl_enum_name_hash_map;
296 gl_enum_name_hash_map m_enum_name_hash_map;
298 typedef vogl::hash_map<uint64_t, vogl_enum_desc_vec> gl_enum_value_to_enum_desc_hash_map;
299 gl_enum_value_to_enum_desc_hash_map m_enum_value_hash_map;
301 typedef vogl::hash_map<vogl_spec_type_and_value_enum_key, vogl_enum_desc_vec> gl_spec_type_and_value_to_enum_desc_hash_map_t;
302 gl_spec_type_and_value_to_enum_desc_hash_map_t m_spec_type_and_enum_value_hash_map;
304 typedef vogl::hash_map<GLenum, const char *> vogl_image_format_hashmap_t;
305 vogl_image_format_hashmap_t m_image_formats;
307 void init_enum_descs();
308 void add_enum(const char *pPrefix, const char *pSpec_type, const char *pGL_type, const char *pName, uint64_t value);
309 void init_image_formats();
312 extern gl_enums g_gl_enums;
314 GLenum vogl_get_json_value_as_enum(const json_node &node, const char *pKey, GLenum def = 0);
315 GLenum vogl_get_json_value_as_enum(const json_value &val, GLenum def = 0);
317 //----------------------------------------------------------------------------------------------------------------------
318 // Client side array tables
319 //----------------------------------------------------------------------------------------------------------------------
320 struct vogl_client_side_array_desc_t
322 gl_entrypoint_id_t m_entrypoint;
323 uint m_is_enabled; // glIsEnabled
324 uint m_get_binding; // glGetIntegerv - this gets the snapshotted binding
325 uint m_get_pointer; // glGetPointerv
326 uint m_get_size; // will be 0 if there is no associated glGet
327 uint m_get_stride; // glGetIntegerv
328 uint m_get_type; // glGetIntegerv
331 #define VOGL_CLIENT_SIDE_ARRAY_DESC(id, entrypoint, is_enabled, get_binding, get_pointer, get_size, get_stride, get_type) id,
332 enum vogl_client_side_array_desc_id_t
334 #include "vogl_client_side_array_descs.inc"
335 VOGL_NUM_CLIENT_SIDE_ARRAY_DESCS
337 #undef VOGL_CLIENT_SIDE_ARRAY_DESC
339 extern const vogl_client_side_array_desc_t g_vogl_client_side_array_descs[];
341 //----------------------------------------------------------------------------------------------------------------------
342 // Misc GL helpers/wrappers
343 //----------------------------------------------------------------------------------------------------------------------
344 GLuint vogl_get_bound_gl_buffer(GLenum target);
347 GLint vogl_get_gl_integer(GLenum pname);
348 vec4I vogl_get_gl_vec4I(GLenum pname);
349 GLint vogl_get_gl_integer_indexed(GLenum pname, uint index);
350 GLint64 vogl_get_gl_integer64(GLenum pname);
351 GLint64 vogl_get_gl_integer64_indexed(GLenum pname, uint index);
352 GLboolean vogl_get_gl_boolean(GLenum pname);
353 GLboolean vogl_get_gl_boolean_indexed(GLenum pname, uint index);
354 GLfloat vogl_get_gl_float(GLenum pname);
355 vec4F vogl_get_gl_vec4F(GLenum pname);
356 matrix44F vogl_get_gl_matrix44F(GLenum pname);
357 GLdouble vogl_get_gl_double(GLenum pname);
358 vec4D vogl_get_gl_vec4D(GLenum pname);
359 matrix44D vogl_get_gl_matrix44D(GLenum pname);
361 void vogl_reset_pixel_store_states();
362 void vogl_reset_pixel_transfer_states();
364 bool vogl_copy_buffer_to_image(void *pDst, uint dst_size, uint width, uint height, GLuint format = GL_RGB, GLuint type = GL_UNSIGNED_BYTE, bool flip_image = false, GLuint framebuffer = 0, GLuint read_buffer = GL_BACK, GLuint pixel_pack_buffer = 0);
366 //----------------------------------------------------------------------------------------------------------------------
367 // Entrypoint helpers
368 //----------------------------------------------------------------------------------------------------------------------
370 inline bool vogl_is_make_current_entrypoint(gl_entrypoint_id_t id)
372 return (id == VOGL_ENTRYPOINT_glXMakeCurrent);
375 inline bool vogl_is_swap_buffers_entrypoint(gl_entrypoint_id_t id)
377 return (id == VOGL_ENTRYPOINT_glXSwapBuffers);
380 bool vogl_is_draw_entrypoint(gl_entrypoint_id_t id);
381 bool vogl_is_clear_entrypoint(gl_entrypoint_id_t id);
383 //----------------------------------------------------------------------------------------------------------------------
385 //----------------------------------------------------------------------------------------------------------------------
386 extern bool g_gl_get_error_enabled;
388 // Returns *true* if there was an error.
389 bool vogl_check_gl_error_internal(bool suppress_error_message = false, const char *pFile = "", uint line = 0, const char *pFunc = "");
390 #define vogl_check_gl_error() (g_gl_get_error_enabled ? vogl_check_gl_error_internal(false, __FILE__, __LINE__, __PRETTY_FUNCTION__) : false)
391 #define vogl_check_gl_error_suppress_message() (g_gl_get_error_enabled ? vogl_check_gl_error_internal(true, __FILE__, __LINE__, __PRETTY_FUNCTION__) : false)
393 #define VOGL_CHECK_GL_ERROR \
396 bool prev_gl_error = vogl_check_gl_error(); \
397 VOGL_ASSERT(!prev_gl_error); \
398 VOGL_NOTE_UNUSED(prev_gl_error); \
401 void vogl_enable_gl_get_error();
402 void vogl_disable_gl_get_error();
403 bool vogl_is_gl_get_error_enabled();
405 //----------------------------------------------------------------------------------------------------------------------
407 //----------------------------------------------------------------------------------------------------------------------
408 GLenum vogl_get_binding_from_target(GLenum target);
409 GLenum vogl_get_object_category_from_binding(GLenum binding);
410 GLenum vogl_get_object_category_from_target(GLenum target);
411 GLenum vogl_get_target_from_binding(GLenum binding);
413 void vogl_bind_object(GLenum target, GLuint handle);
414 GLuint vogl_get_bound_object(GLenum target);
416 void vogl_debug_message_control(const vogl_context_info &context_info, GLenum err_code, bool enabled);
418 // NOTE: Don't use this for anything other than debugging!
419 GLenum vogl_determine_texture_target(const vogl_context_info &context_info, GLuint handle);
421 int vogl_gl_get_uniform_size_in_GLints(GLenum type);
422 int vogl_gl_get_uniform_size_in_bytes(GLenum type);
423 int vogl_gl_get_uniform_base_type(GLenum type);
425 //----------------------------------------------------------------------------------------------------------------------
426 // class vogl_binding_state
427 //----------------------------------------------------------------------------------------------------------------------
428 class vogl_binding_state
435 saved_binding(GLenum target, GLenum handle)
436 : m_target(target), m_handle(handle)
439 void set(GLenum target, GLenum handle)
449 vogl::growable_array<saved_binding, 16> m_bindings;
456 ~vogl_binding_state()
463 VOGL_FUNC_TRACER m_bindings.clear();
466 void save(GLenum target)
470 GLuint handle = vogl_get_bound_object(target);
471 m_bindings.enlarge(1)->set(target, handle);
478 // TODO: the valid stuff to save depends on the context version, argh
479 // TODO: Add GL4 texture types!
480 static const GLenum s_texture_targets[] =
483 GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_1D_ARRAY,
484 GL_TEXTURE_2D_ARRAY, GL_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP,
485 GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BUFFER, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY
488 m_bindings.reserve(VOGL_ARRAY_SIZE(s_texture_targets) + 8);
489 for (uint i = 0; i < VOGL_ARRAY_SIZE(s_texture_targets); i++)
490 save(s_texture_targets[i]);
497 static const GLenum s_buffer_targets[] =
499 GL_ARRAY_BUFFER, GL_ATOMIC_COUNTER_BUFFER, GL_COPY_READ_BUFFER,
500 GL_COPY_WRITE_BUFFER, GL_DRAW_INDIRECT_BUFFER, GL_DISPATCH_INDIRECT_BUFFER,
501 GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER,
502 GL_SHADER_STORAGE_BUFFER, GL_TEXTURE_BUFFER,
503 GL_TRANSFORM_FEEDBACK_BUFFER, GL_UNIFORM_BUFFER
504 // TODO: GL_QUERY_BUFFER
507 m_bindings.reserve(VOGL_ARRAY_SIZE(s_buffer_targets) + 8);
508 for (uint i = 0; i < VOGL_ARRAY_SIZE(s_buffer_targets); i++)
509 save(s_buffer_targets[i]);
516 for (uint i = 0; i < m_bindings.size(); i++)
517 vogl_bind_object(m_bindings[i].m_target, m_bindings[i].m_handle);
521 //----------------------------------------------------------------------------------------------------------------------
522 // class vogl_scoped_binding_state
523 //----------------------------------------------------------------------------------------------------------------------
524 class vogl_scoped_binding_state
526 vogl_binding_state m_saved_state;
529 vogl_scoped_binding_state()
533 vogl_scoped_binding_state(GLenum target)
535 VOGL_FUNC_TRACER m_saved_state.save(target);
537 vogl_scoped_binding_state(GLenum target0, GLenum target1)
539 VOGL_FUNC_TRACER m_saved_state.save(target0);
540 m_saved_state.save(target1);
542 vogl_scoped_binding_state(GLenum target0, GLenum target1, GLenum target2)
544 VOGL_FUNC_TRACER m_saved_state.save(target0);
545 m_saved_state.save(target1);
546 m_saved_state.save(target2);
548 vogl_scoped_binding_state(GLenum target0, GLenum target1, GLenum target2, GLenum target3)
550 VOGL_FUNC_TRACER m_saved_state.save(target0);
551 m_saved_state.save(target1);
552 m_saved_state.save(target2);
553 m_saved_state.save(target3);
556 ~vogl_scoped_binding_state()
558 VOGL_FUNC_TRACER restore();
563 VOGL_FUNC_TRACER m_saved_state.clear();
566 void save(GLenum target)
568 VOGL_FUNC_TRACER m_saved_state.save(target);
573 VOGL_FUNC_TRACER m_saved_state.save_textures();
577 VOGL_FUNC_TRACER m_saved_state.save_buffers();
582 VOGL_FUNC_TRACER m_saved_state.restore();
583 m_saved_state.clear();
587 //----------------------------------------------------------------------------------------------------------------------
588 // enum vogl_generic_state_types_t
589 //----------------------------------------------------------------------------------------------------------------------
590 enum vogl_generic_state_type
592 cGSTPixelStore, // pixel pack, unpack
593 cGSTPixelTransfer, // GL_INDEX_OFFSET, RGBA scale/biases, etc.
594 cGSTReadBuffer, // this is a per-framebuffer state!
595 cGSTDrawBuffer, // this is a per-framebuffer state!
597 cGSTClientActiveTexture,
599 cGSTARBVertexProgram,
600 cGSTARBFragmentProgram,
604 //----------------------------------------------------------------------------------------------------------------------
605 // class vogl_state_saver
606 //----------------------------------------------------------------------------------------------------------------------
607 class vogl_state_saver
616 template <typename T>
617 saved_state(vogl_generic_state_type state_type, GLenum pname, T data)
618 : m_state_type(state_type), m_pname(pname), m_value(data)
623 template <typename T>
624 void set(vogl_generic_state_type state_type, GLenum pname, T data)
626 VOGL_FUNC_TRACER m_state_type = state_type;
631 vogl_generic_state_type m_state_type;
645 VOGL_FUNC_TRACER m_states.clear();
646 m_draw_buffers.clear();
649 void save(vogl_generic_state_type type);
653 vogl::growable_array<saved_state, 64> m_states;
654 vogl::growable_array<GLenum, 32> m_draw_buffers;
657 //----------------------------------------------------------------------------------------------------------------------
658 // class vogl_scoped_state
659 //----------------------------------------------------------------------------------------------------------------------
660 class vogl_scoped_state_saver
662 vogl_state_saver m_state;
665 vogl_scoped_state_saver()
669 vogl_scoped_state_saver(vogl_generic_state_type type)
671 VOGL_FUNC_TRACER save(type);
673 vogl_scoped_state_saver(vogl_generic_state_type type0, vogl_generic_state_type type1)
675 VOGL_FUNC_TRACER save(type0);
678 vogl_scoped_state_saver(vogl_generic_state_type type0, vogl_generic_state_type type1, vogl_generic_state_type type2)
680 VOGL_FUNC_TRACER save(type0);
684 vogl_scoped_state_saver(vogl_generic_state_type type0, vogl_generic_state_type type1, vogl_generic_state_type type2, vogl_generic_state_type type3)
686 VOGL_FUNC_TRACER save(type0);
692 ~vogl_scoped_state_saver()
694 VOGL_FUNC_TRACER restore();
699 VOGL_FUNC_TRACER m_state.clear();
702 void save(vogl_generic_state_type type)
704 VOGL_FUNC_TRACER m_state.save(type);
708 VOGL_FUNC_TRACER m_state.restore();
713 //----------------------------------------------------------------------------------------------------------------------
714 // vogl_json_serialize_vec
715 //----------------------------------------------------------------------------------------------------------------------
716 template <typename T>
717 inline bool vogl_json_serialize_vec(json_node &node, vogl_blob_manager &blob_manager, const char *pKey, const T &vec)
721 json_node &array_node = node.add_array(pKey);
722 for (uint i = 0; i < vec.size(); i++)
724 json_node &obj_node = array_node.add_object();
725 if (!vec[i].serialize(obj_node, blob_manager))
731 //----------------------------------------------------------------------------------------------------------------------
732 // vogl_json_serialize_ptr_vec
733 //----------------------------------------------------------------------------------------------------------------------
734 template <typename T>
735 inline bool vogl_json_serialize_ptr_vec(json_node &node, vogl_blob_manager &blob_manager, const char *pKey, const T &vec)
739 json_node &array_node = node.add_array(pKey);
740 for (uint i = 0; i < vec.size(); i++)
742 json_node &obj_node = array_node.add_object();
745 if (!vec[i]->serialize(obj_node, blob_manager))
752 //----------------------------------------------------------------------------------------------------------------------
753 // vogl_json_serialize_ptr_vec
754 //----------------------------------------------------------------------------------------------------------------------
755 template <typename T, typename U>
756 inline bool vogl_json_serialize_ptr_vec(json_node &node, vogl_blob_manager &blob_manager, const char *pKey, const T &vec, const U &p0)
760 json_node &array_node = node.add_array(pKey);
761 for (uint i = 0; i < vec.size(); i++)
763 json_node &obj_node = array_node.add_object();
766 if (!vec[i]->serialize(obj_node, blob_manager, p0))
773 //----------------------------------------------------------------------------------------------------------------------
774 // vogl_json_deserialize_vec
775 //----------------------------------------------------------------------------------------------------------------------
776 template <typename T>
777 inline bool vogl_json_deserialize_vec(const json_node &node, const vogl_blob_manager &blob_manager, const char *pKey, T &vec)
781 const json_node *pArray_node = node.find_child_array(pKey);
788 vec.resize(pArray_node->size());
790 for (uint i = 0; i < pArray_node->size(); i++)
792 const json_node *pObj_node = pArray_node->get_value_as_object(i);
795 if (!vec[i].deserialize(*pObj_node, blob_manager))
801 //----------------------------------------------------------------------------------------------------------------------
802 // vogl_json_deserialize_ptr_vec
803 //----------------------------------------------------------------------------------------------------------------------
804 template <typename T>
805 inline bool vogl_json_deserialize_ptr_vec(const json_node &node, const vogl_blob_manager &blob_manager, const char *pKey, T &vec)
809 const json_node *pArray_node = node.find_child_array(pKey);
818 for (uint i = 0; i < pArray_node->size(); i++)
820 const json_node *pObj_node = pArray_node->get_value_as_object(i);
824 typename T::value_type pObj = vogl_new(typename Loki::TypeTraits<typename T::value_type>::PointeeType);
826 if (!pObj->deserialize(*pObj_node, blob_manager))
837 //----------------------------------------------------------------------------------------------------------------------
838 // vogl_json_deserialize_ptr_vec
839 //----------------------------------------------------------------------------------------------------------------------
840 template <typename T, typename U>
841 inline bool vogl_json_deserialize_ptr_vec(const json_node &node, const vogl_blob_manager &blob_manager, const char *pKey, T &vec, const U &p0)
845 const json_node *pArray_node = node.find_child_array(pKey);
854 for (uint i = 0; i < pArray_node->size(); i++)
856 const json_node *pObj_node = pArray_node->get_value_as_object(i);
860 typename T::value_type pObj = vogl_new(typename Loki::TypeTraits<typename T::value_type>::PointeeType);
862 if (!pObj->deserialize(*pObj_node, blob_manager, p0))
873 //----------------------------------------------------------------------------------------------------------------------
874 // vogl_json_deserialize_obj
875 //----------------------------------------------------------------------------------------------------------------------
876 template <typename T>
877 bool vogl_json_deserialize_obj(const json_node &node, const vogl_blob_manager &blob_manager, const char *pKey, T &obj)
881 const json_node *pNode = node.find_child_object(pKey);
884 return obj.deserialize(*pNode, blob_manager);
887 //----------------------------------------------------------------------------------------------------------------------
888 // vogl_json_deserialize_array
889 //----------------------------------------------------------------------------------------------------------------------
890 template <typename T>
891 bool vogl_json_deserialize_array(const json_node &node, const vogl_blob_manager &blob_manager, const char *pKey, T &obj)
895 const json_node *pNode = node.find_child_array(pKey);
898 return obj.deserialize(*pNode, blob_manager);
901 //----------------------------------------------------------------------------------------------------------------------
902 // vogl_json_serialize_vec4F
903 // TODO: Add roundtrip checking, and/or move this to common code somewhere
904 //----------------------------------------------------------------------------------------------------------------------
905 inline bool vogl_json_serialize_vec4F(json_node &dst_node, const vec4F &vec)
909 dst_node.init_array();
910 for (uint j = 0; j < 4; j++)
911 dst_node.add_value(vec[j]);
915 //----------------------------------------------------------------------------------------------------------------------
916 // vogl_json_deserialize_vec4
917 // TODO: Add roundtrip checking, and/or move this to common code somewhere
918 //----------------------------------------------------------------------------------------------------------------------
919 inline bool vogl_json_deserialize_vec4F(const json_node &src_node, vec4F &vec)
923 if ((!src_node.is_array()) || (src_node.size() != 4))
926 for (uint j = 0; j < 4; j++)
928 if (src_node[j].is_object_or_array())
930 vec[j] = src_node[j].as_float();
936 //----------------------------------------------------------------------------------------------------------------------
937 // vogl_format_debug_output_arb
938 //----------------------------------------------------------------------------------------------------------------------
939 void vogl_format_debug_output_arb(char out_str[], size_t out_str_size, GLenum source, GLenum type, GLuint id, GLenum severity, const char *msg);
940 void vogl_generic_arb_debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *pUser_param);
941 void vogl_enable_generic_context_debug_messages();
943 //----------------------------------------------------------------------------------------------------------------------
945 //----------------------------------------------------------------------------------------------------------------------
946 typedef GLXContext vogl_gl_context;
947 typedef Display *vogl_gl_display;
948 typedef GLXFBConfig vogl_gl_fb_config;
949 typedef GLXDrawable vogl_gl_drawable;
953 eCHCDebugContextFlag = 1,
954 cCHCCoreProfileFlag = 2,
955 cCHCCompatProfileFlag = 4,
958 vogl_gl_context vogl_create_context(vogl_gl_display display, vogl_gl_fb_config fb_config, vogl_gl_context share_context, uint major_ver, uint minor_ver, uint flags, vogl_context_desc *pDesc = NULL);
959 vogl_gl_context vogl_get_current_context();
960 vogl_gl_display vogl_get_current_display();
961 vogl_gl_drawable vogl_get_current_drawable();
963 // vogl_get_current_fb_config() assumes a context is current.
964 vogl_gl_fb_config vogl_get_current_fb_config(uint screen = 0);
966 void vogl_make_current(vogl_gl_display display, vogl_gl_drawable drawable, vogl_gl_context context);
968 void vogl_destroy_context(vogl_gl_display display, vogl_gl_context context);
970 //----------------------------------------------------------------------------------------------------------------------
971 // vogl_get_max_supported_mip_levels
972 //----------------------------------------------------------------------------------------------------------------------
973 int vogl_get_max_supported_mip_levels();
975 #endif // VOGL_GL_UTILS_H