cgv
Loading...
Searching...
No Matches
gl_context.cxx
1#include <cgv/base/group.h>
2#include "gl_context.h"
3#include "gl_tools.h"
4#include <cgv_gl/gl/wgl.h>
5#ifdef _WIN32
6#undef TA_LEFT
7#undef TA_TOP
8#undef TA_RIGHT
9#undef TA_BOTTOM
10#endif
11#include <cgv/base/base.h>
12#include <cgv/base/action.h>
13#include <cgv/render/drawable.h>
14#include <cgv/render/shader_program.h>
15#include <cgv/render/attribute_array_binding.h>
16#include <cgv/render/vertex_buffer.h>
17#include <cgv/render/textured_material.h>
18#include <cgv/utils/scan.h>
19#include <cgv/media/image/image_writer.h>
20#include <cgv/gui/event_handler.h>
21#include <cgv/math/ftransform.h>
22#include <cgv/math/geom.h>
23#include <cgv/math/inv.h>
24#include <cgv/type/standard_types.h>
25#include <cgv/os/clipboard.h>
26
27using namespace cgv::base;
28using namespace cgv::type;
29using namespace cgv::type::info;
30using namespace cgv::gui;
31using namespace cgv::os;
32using namespace cgv::math;
33using namespace cgv::media::font;
34using namespace cgv::media::illum;
35
36namespace cgv {
37 namespace render {
38 namespace gl {
39
41{
42#ifdef _WIN32
51#else
60#endif
61 std::vector<int> attrib_list;
62 int version = 0;
63 if (cc.version_major < 1)
64 version = 46;
65 else
66 version = 10 * cc.version_major + (cc.version_minor >= 0 ? cc.version_minor : 0);
67 if ((version > 30 && cc.forward_compatible) || cc.debug) {
68 attrib_list.push_back(CONTEXT_FLAGS);
69 attrib_list.push_back(
70 (cc.forward_compatible ? CONTEXT_FORWARD_COMPATIBLE_BIT : 0) +
71 (cc.debug ? CONTEXT_DEBUG_BIT : 0));
72 }
73 if (cc.version_major > 0) {
75 attrib_list.push_back(cc.version_major);
76 }
77 if (cc.version_minor >= 0) {
79 attrib_list.push_back(cc.version_minor);
80 }
81 if (version > 31) {
83 attrib_list.push_back(
85 }
86 attrib_list.push_back(0);
87 return attrib_list;
88}
89
90GLenum map_to_gl(PrimitiveType primitive_type)
91{
92 static const GLenum gl_primitive_type[] = {
93 GLenum(-1),
105 GL_QUADS,
109 };
110 return gl_primitive_type[primitive_type];
111}
112
114{
115 static const GLenum gl_material_side[] = {
116 GLenum(0),
117 GL_FRONT,
118 GL_BACK,
120 };
122}
123
125{
126 static const GLenum gl_access_type[] = {
130 };
132}
133
135{
136 static const GLenum gl_blend_func[] = {
137 GL_ZERO,
138 GL_ONE,
156 };
158}
159
161{
162 static const GLenum gl_compare_func[] = {
163 GL_LEQUAL,
164 GL_GEQUAL,
165 GL_LESS,
167 GL_EQUAL,
169 GL_ALWAYS,
171 };
173}
174
175static const GLenum gl_depth_format_ids[] =
176{
181};
182
183static const GLenum gl_color_buffer_format_ids[] =
184{
185 GL_RGB,
186 GL_RGBA
187};
188
189static const char* depth_formats[] =
190{
191 "[D]",
192 "uint16[D]",
193 "uint32[D:24]",
194 "uint32[D]",
195 0
196};
197
198static const char* color_buffer_formats[] =
199{
200 "[R,G,B]",
201 "[R,G,B,A]",
202 0
203};
204
206{
207 static const GLenum gl_texture_type[] = {
208 GLenum(0),
217 };
219}
220
221GLenum get_tex_bind(TextureType texture_type)
222{
223 static const GLenum gl_tex_binding[] = {
224 GLenum(0),
234 };
236}
237
239{
240 static const GLenum gl_texture_wrap[] = {
241 GL_REPEAT,
242 GL_CLAMP,
243 GL_CLAMP_TO_EDGE,
249 };
251}
252
254{
255 static const GLenum gl_texture_filter[] = {
257 GL_LINEAR,
263 };
265}
266
267GLboolean map_to_gl(bool flag) {
268 return flag ? GL_TRUE : GL_FALSE;
269}
270
271GLuint get_gl_id(const void* handle)
272{
273 return (const GLuint&)handle - 1;
274}
275
276void* get_handle(GLuint id)
277{
278 void* handle = 0;
279 (GLuint&)handle = id + 1;
280 return handle;
281}
282
283void gl_context::put_id(void* handle, void* ptr) const
284{
285 *static_cast<GLuint*>(ptr) = get_gl_id(handle);
286}
287
290{
292 (GLuint&)tex.internal_format = gl_format;
293}
294
297{
298 if (tex.internal_format)
299 return (const GLuint&)tex.internal_format;
302 return gl_format;
303}
304
305
306void gl_set_material_color(GLenum side, const cgv::media::illum::phong_material::color_type& c, float alpha, GLenum type)
307{
308 GLfloat v[4] = { c[0],c[1],c[2],c[3] * alpha };
309 glMaterialfv(side, type, v);
310}
311
314{
315 if (ms == MS_NONE)
316 return;
317 unsigned side = map_to_gl(ms);
318 gl_set_material_color(side, mat.get_ambient(), alpha, GL_AMBIENT);
319 gl_set_material_color(side, mat.get_diffuse(), alpha, GL_DIFFUSE);
320 gl_set_material_color(side, mat.get_specular(), alpha, GL_SPECULAR);
321 gl_set_material_color(side, mat.get_emission(), alpha, GL_EMISSION);
322 glMaterialf(side, GL_SHININESS, mat.get_shininess());
323}
324
327{
328 return info_font_size;
329}
332{
333 if (info_font_face.empty()) {
335 if (!info_font.empty())
336 info_font_face = info_font->get_font_face(FFA_REGULAR);
337 }
338 return info_font_face;
339}
340
343{
344 frame_buffer_stack.top()->handle = get_handle(0);
345 max_nr_indices = 0;
346 max_nr_vertices = 0;
347 info_font_size = 14;
348 show_help = false;
349 show_stats = false;
350
351 // set initial GL state from stack contents
356
361}
362
365{
366 return RA_OPENGL;
367}
368
369//GL_STACK_OVERFLOW, "stack overflow"
370//GL_STACK_UNDERFLOW, "stack underflow",
371std::string get_source_tag_name(GLenum tag)
372{
373 static std::map<GLenum, const char*> source_tags = {
374 { GL_DEBUG_SOURCE_API, "api" },
375 { GL_DEBUG_SOURCE_WINDOW_SYSTEM, "window system" },
376 { GL_DEBUG_SOURCE_SHADER_COMPILER, "shader compiler" },
377 { GL_DEBUG_SOURCE_THIRD_PARTY, "3rd party" },
378 { GL_DEBUG_SOURCE_APPLICATION, "application" },
379 { GL_DEBUG_SOURCE_OTHER, "other" }
380 };
381 return source_tags[tag];
382}
383
384std::string get_type_tag_name(GLenum tag)
385{
386 static std::map<GLenum, const char*> type_tags = {
387 { GL_DEBUG_TYPE_ERROR, "error" },
388 { GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, "deprecated behavior" },
389 { GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, "undefinded behavior" },
390 { GL_DEBUG_TYPE_PORTABILITY, "portability" },
391 { GL_DEBUG_TYPE_PERFORMANCE, "performance" },
392 { GL_DEBUG_TYPE_OTHER, "other" },
393 { GL_DEBUG_TYPE_MARKER, "marker" },
394 { GL_DEBUG_TYPE_PUSH_GROUP, "push group" },
395 { GL_DEBUG_TYPE_POP_GROUP, "pop group" }
396 };
397 return type_tags[tag];
398}
399
400std::string get_severity_tag_name(GLenum tag)
401{
402 static std::map<GLenum, const char*> severity_tags = {
403 { GL_DEBUG_SEVERITY_NOTIFICATION, "notification" },
404 { GL_DEBUG_SEVERITY_HIGH, "high" },
405 { GL_DEBUG_SEVERITY_MEDIUM, "medium" },
406 { GL_DEBUG_SEVERITY_LOW, "low" }
407 };
408 return severity_tags[tag];
409};
410
411void GLAPIENTRY debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
412{
414 return;
415 const gl_context* ctx = reinterpret_cast<const gl_context*>(userParam);
416 std::string msg(message, length);
417 msg = std::string("GLDebug Message[") + cgv::utils::to_string(id) + "] from " + get_source_tag_name(source) + " of type " + get_type_tag_name(type) + " of severity " + get_severity_tag_name(severity) + "\n" + msg;
418 ctx->error(msg);
419}
420
423{
425 error("gl_context::configure_gl could not initialize glew");
426 return false;
427 }
429 version_major = version_string[0] - '0';
430 version_minor = version_string[2] - '0';
431 if (version_major >= 3) {
434 // weird behavior under windows or just nvidia or just my laptop (Stefan)??
437 }
438 else {
439 debug = false;
440 forward_compatible = false;
441 }
442 int version = 10 * version_major + version_minor;
443 if (version >= 32) {
446#ifdef _DEBUG
447 if (context_profile != 0) {
449 if (core_profile)
450 std::cerr << "WARNING: Ignoring that GL_CONTEXT_PROFILE_MASK yields compatibility profile for context created as core." << std::endl;
451 else
452 std::cerr << "WARNING: Ignoring that GL_CONTEXT_PROFILE_MASK does not yield compatibility profile for context created as such." << std::endl;
453 }
454 }
455 else {
456 std::cerr << "WARNING: Ignoring that GL_CONTEXT_PROFILE_MASK yields zero." << std::endl;
457 }
458#endif
459 }
460 else
461 core_profile = false;
463 std::string vendor_string(reinterpret_cast<const char*>(vendor_c_string));
465
466 if (vendor_string.find("NVIDIA") != std::string::npos)
467 gpu_vendor = GPU_VENDOR_NVIDIA;
468 else if (vendor_string.find("INTEL") != std::string::npos)
469 gpu_vendor = GPU_VENDOR_INTEL;
470 else if (vendor_string.find("AMD") != std::string::npos || vendor_string.find("ATI") != std::string::npos)
471 gpu_vendor = GPU_VENDOR_AMD;
472
473#ifdef _DEBUG
474 std::cout << "OpenGL version " << version_major << "." << version_minor << (core_profile?" (core)":" (compatibility)") << (debug?" (debug)":"") << (forward_compatible?" (forward_compatible)":"") << std::endl;
477 if (vendor_c_string)
478 std::cout << " vendor : " << vendor_c_string << std::endl;
480 std::cout << " renderer : " << renderer_c_string << std::endl;
482 std::cout << " glslversion: " << glslversion_c_string << std::endl;
483#endif
484 if (debug) {
486 if (version >= 43) {
488 if (!check_gl_error("gl_context::configure() debug output"))
489 glDebugMessageCallback(debug_callback, this);
490 }
491 }
492 // use the eye location to compute the specular lighting
493 if (!core_profile) {
495 // this makes opengl normalize all surface normals before lighting calculations,
496 // which is essential when using scaling to deform tesselated primities
498
499 // should be initialized by the driver, but better be safe than risk errors later
501 }
503// if (check_gl_error("gl_context::configure_gl before init of children"))
504// return false;
505
506 group_ptr grp(dynamic_cast<group*>(this));
508 for (unsigned i = 0; i<grp->get_nr_children(); ++i)
509 traverser(sma, "nc").traverse(grp->get_child(i));
510
511// if (check_gl_error("gl_context::configure_gl after init of children."))
512// return false;
513
514 return true;
515}
516
517void gl_context::resize_gl()
518{
519 group_ptr grp(dynamic_cast<group*>(this));
521 if (grp) {
524 }
525}
526
531
536
541
547
548void gl_context::clear_background(bool color_flag, bool depth_flag, bool stencil_flag, bool accum_flag) {
549 GLenum bits = 0;
550 if(color_flag)
552 if(depth_flag)
554 if(stencil_flag)
558 if(bits)
559 glClear(bits);
560}
561
564{
565 if (current_font_size == 0)
566 return get_info_font_size();
567 return current_font_size;
568}
576
577void gl_context::init_render_pass()
578{
579#ifdef WIN32
581#else
583#endif
586 else
588
592 for (unsigned i = 0; i < nr_default_light_sources; ++i)
594
595 for (unsigned i = 0; i < nr_default_light_sources; ++i)
598 else
600 }
601 else if ((last_render_pass_flags & RPF_SET_LIGHTS) == 0) {
602 for (unsigned i = 0; i < nr_default_light_sources; ++i)
605 }
607
610 }
612 // this mode allows to define the ambient and diffuse color of the surface material
613 // via the glColor commands
615 }
617 // set some default settings
619 set_cull_state(CM_BACKFACE);
620 if (!core_profile)
622 }
624 set_projection_matrix(cgv::math::perspective4<double>(45.0, (double)get_width()/get_height(),0.001,1000.0));
625
627 set_modelview_matrix(cgv::math::look_at4<double>(vec3(0,0,10), vec3(0,0,0), vec3(0,1,0)));
628
629 if (check_gl_error("gl_context::init_render_pass before init_frame"))
630 return;
631
632 group* grp = dynamic_cast<group*>(this);
636 }
637
638 if (check_gl_error("gl_context::init_render_pass after init_frame"))
639 return;
640 // this defines the background color to which the frame buffer is set by glClear
643 // this defines the background depth buffer value set by glClear
646 // this defines the background depth buffer value set by glClear
649 // this defines the background color to which the accum buffer is set by glClear
657 );
658}
659
661void gl_context::finish_render_pass()
662{
663}
664
666{
667 std::ostream& os;
668 format_callback_handler(std::ostream& _os) : os(_os)
669 {
670 }
673 {
674 os << "\a";
675 return false;
676 }
679 {
680 os << "\b";
681 return false;
682 }
683
684};
685
686void gl_context::draw_textual_info()
687{
688 if (show_help || show_stats) {
692
695
696 set_cursor(20, get_height()-1-20);
697
698 vec4 bg = get_bg_color();
699 //if (bg_r + bg_g + bg_b < 1.5f)
700 if (bg[0] + bg[1] + bg[2] < 1.5f)
701 set_color(rgba(1, 1, 1, 1));
702 else
703 set_color(rgba(0, 0, 0, 1));
704
705 // traverse objects for show_stats callback
706 format_callback_handler fch(output_stream());
707 group_ptr grp(dynamic_cast<group*>(this));
708 if (grp && show_stats) {
710 traverser(sma, "nc").traverse(grp, &fch);
711 output_stream() << std::endl;
712 }
713 //if (bg_r + bg_g + bg_b < 1.5f)
714 if(bg[0] + bg[1] + bg[2] < 1.5f)
715 set_color(rgba(1, 1, 0, 1));
716 else
717 set_color(rgba(0.4f, 0.3f, 0, 1));
718
719 if (grp && show_help) {
720 // collect help from myself and all children
722 traverser(sma, "nc").traverse(grp, &fch);
723 output_stream().flush();
724 }
727 }
728}
729
730void gl_context::perform_screen_shot()
731{
732 glFlush();
734 if (!read_frame_buffer(dv))
735 return;
736 std::string ext("bmp");
738 if (cgv::utils::is_element("png",exts))
739 ext = "png";
740 else if (cgv::utils::is_element("tif",exts))
741 ext = "tif";
742 cgv::media::image::image_writer wr(std::string("screen_shot.")+ext);
743 if (wr.is_format_supported(*dv.get_format()))
744 wr.write_image(dv);
745}
746
748void gl_context::enumerate_program_uniforms(shader_program& prog, std::vector<std::string>& names, std::vector<int>* locations_ptr, std::vector<int>* sizes_ptr, std::vector<int>* types_ptr, bool show) const
749{
750 GLint count;
751 glGetProgramiv(get_gl_id(prog.handle), GL_ACTIVE_UNIFORMS, &count);
752 for (int i = 0; i < count; ++i) {
753 GLchar name[1000];
754 GLsizei length;
755 GLint size;
756 GLenum type;
757 glGetActiveUniform(get_gl_id(prog.handle), i, 1000, &length, &size, &type, name);
758 std::string name_str(name, length);
759 names.push_back(name_str);
760 if (sizes_ptr)
761 sizes_ptr->push_back(size);
762 if (types_ptr)
763 types_ptr->push_back(type);
764 int loc = glGetUniformLocation(get_gl_id(prog.handle), name_str.c_str());
765 if (locations_ptr)
766 locations_ptr->push_back(loc);
767 if (show)
768 std::cout << i << " at " << loc << " = " << name_str << ":" << type << "[" << size << "]" << std::endl;
769 }
770}
771
773void gl_context::enumerate_program_attributes(shader_program& prog, std::vector<std::string>& names, std::vector<int>* locations_ptr, std::vector<int>* sizes_ptr, std::vector<int>* types_ptr, bool show) const
774{
775 GLint count;
776 glGetProgramiv(get_gl_id(prog.handle), GL_ACTIVE_ATTRIBUTES, &count);
777 for (int i = 0; i < count; ++i) {
778 GLchar name[1000];
779 GLsizei length;
780 GLint size;
781 GLenum type;
782 glGetActiveAttrib(get_gl_id(prog.handle), i, 1000, &length, &size, &type, name);
783 std::string name_str(name, length);
784 names.push_back(name_str);
785 if (sizes_ptr)
786 sizes_ptr->push_back(size);
787 if (types_ptr)
788 types_ptr->push_back(type);
789 int loc = glGetAttribLocation(get_gl_id(prog.handle), name_str.c_str());
790 if (locations_ptr)
791 locations_ptr->push_back(loc);
792 if (show)
793 std::cout << i << " at " << loc << " = " << name_str << ":" << type << "[" << size << "]" << std::endl;
794 }
795}
796
799{
802 glColor4fv(&clr[0]);
803 }
804 if (shader_program_stack.empty())
805 return;
807 if (!prog.does_context_set_color())
808 return;
809 int clr_loc = prog.get_color_index();
810 if (clr_loc == -1)
811 return;
812 prog.set_attribute(*this, clr_loc, clr);
813}
814
817{
819 unsigned side = map_to_gl(MS_FRONT_AND_BACK);
820 float alpha = 1.0f - material.get_transparency();
821 gl_set_material_color(side, material.get_ambient_occlusion()*material.get_diffuse_reflectance(), alpha, GL_AMBIENT);
822 gl_set_material_color(side, material.get_diffuse_reflectance(), alpha, GL_DIFFUSE);
823 gl_set_material_color(side, material.get_specular_reflectance(), alpha, GL_SPECULAR);
824 gl_set_material_color(side, material.get_emission(), alpha, GL_EMISSION);
825 glMaterialf(side, GL_SHININESS, 1.0f/(material.get_roughness()+1.0f/128.0f));
826 }
827 context::set_material(material);
828}
829
832{
834 mat.enable_textures(*this);
835}
836
839{
840 mat.disable_textures(*this);
843}
844
845void gl_context::destruct_render_objects()
846{
847 for (unsigned i = 0; i < 4; ++i)
848 progs[i].destruct(*this);
849}
850
853{
854 if (!texture_support) {
855 if (!progs[0].is_created()) {
856 if (!progs[0].build_program(*this, "default.glpr")) {
857 error("could not build default shader program from default.glpr");
858 exit(0);
859 }
860 progs[0].specify_standard_uniforms(true, false, false, true);
861 progs[0].specify_standard_vertex_attribute_names(*this, true, false, false);
862 progs[0].allow_context_to_set_color(true);
863 }
864 return progs[0];
865 }
866 if (!progs[1].is_created()) {
867 if (!progs[1].build_program(*this, "textured_default.glpr")) {
868 error("could not build default shader program with texture support from textured_default.glpr");
869 exit(0);
870 }
871 progs[1].set_uniform(*this, "texture", 0);
872 progs[1].specify_standard_uniforms(true, false, false, true);
873 progs[1].specify_standard_vertex_attribute_names(*this, true, false, true);
874 progs[1].allow_context_to_set_color(true);
875 }
876 return progs[1];
877}
878
881{
882 if (!texture_support) {
883 if (!progs[2].is_created()) {
884 if (!progs[2].build_program(*this, "default_surface.glpr")) {
885 error("could not build surface shader program from default_surface.glpr");
886 exit(0);
887 }
888 progs[2].specify_standard_uniforms(true, true, true, true);
889 progs[2].specify_standard_vertex_attribute_names(*this, true, true, false);
890 progs[2].allow_context_to_set_color(true);
891 }
892 return progs[2];
893 }
894 if (!progs[3].is_created()) {
895 if (!progs[3].build_program(*this, "textured_surface.glpr")) {
896 error("could not build surface shader program with texture support from textured_surface.glpr");
897 exit(0);
898 }
899 progs[3].specify_standard_uniforms(true, true, true, true);
900 progs[3].specify_standard_vertex_attribute_names(*this, true, true, true);
901 progs[3].allow_context_to_set_color(true);
902 }
903 return progs[3];
904}
905
907{
914 continue;
915 }
916 GLfloat col[4] = { 1,1,1,1 };
918 *(rgb*)col = light.get_emission()*light.get_ambient_scale();
920 *(rgb*)col = light.get_emission();
922 *(rgb*)col = light.get_emission();
924
925 GLfloat pos[4] = { 0,0,0,light.get_type() == cgv::media::illum::LT_DIRECTIONAL ? 0.0f : 1.0f };
926 *(vec3*)pos = light.get_position();
928 if (light.get_type() != cgv::media::illum::LT_DIRECTIONAL) {
929 glLightf(GL_LIGHT0 + light_idx, GL_CONSTANT_ATTENUATION, light.get_constant_attenuation());
930 glLightf(GL_LIGHT0 + light_idx, GL_LINEAR_ATTENUATION, light.get_linear_attenuation());
931 glLightf(GL_LIGHT0 + light_idx, GL_QUADRATIC_ATTENUATION, light.get_quadratic_attenuation());
932 }
933 else {
937 }
938 if (light.get_type() == cgv::media::illum::LT_SPOT) {
939 glLightf(GL_LIGHT0 + light_idx, GL_SPOT_CUTOFF, light.get_spot_cutoff());
940 glLightf(GL_LIGHT0 + light_idx, GL_SPOT_EXPONENT, light.get_spot_exponent());
941 glLightfv(GL_LIGHT0 + light_idx, GL_SPOT_DIRECTION, light.get_spot_direction().data());
942 }
943 else {
946 static float dir[3] = { 0,0,1 };
948 }
950 }
951 }
953}
954
955void gl_context::tesselate_arrow(double length, double aspect, double rel_tip_radius, double tip_aspect, int res, bool edges)
956{
957 double cyl_radius = length*aspect;
960 double cyl_length = length - cone_length;
964 mul_modelview_matrix(cgv::math::rotate4(180.0,1.0,0.0,0.0));
965 tesselate_unit_disk(res, false, edges);
967
968 mul_modelview_matrix(cgv::math::translate4(0.0,0.0,1.0));
969 tesselate_unit_cylinder(res, false, edges);
970
971 mul_modelview_matrix(cgv::math::translate4(0.0, 0.0, 1.0));
974 mul_modelview_matrix(cgv::math::rotate4(180.0, 1.0, 0.0, 0.0));
975 tesselate_unit_disk(res, false, edges);
977 mul_modelview_matrix(cgv::math::translate4(0.0, 0.0, 1.0));
978 tesselate_unit_cone(res, false, edges);
980}
981
983void gl_context::rotate_vector_to_target(const dvec3& vector, const dvec3& target)
984{
985 double angle;
986 dvec3 axis;
987 compute_rotation_axis_and_angle_from_vector_pair(vector, target, axis, angle);
988 mul_modelview_matrix(cgv::math::rotate4<double>(180.0 / M_PI * angle, axis));
989}
990
992void gl_context::tesselate_arrow(const dvec3& start, const dvec3& end, double aspect, double rel_tip_radius, double tip_aspect, int res, bool edges)
993{
994 if ((start - end).length() < 1e-8) {
995 error("ignored tesselate arrow called with start and end closer then 1e-8");
996 return;
997 }
999 mul_modelview_matrix(cgv::math::translate4<double>(start));
1000 rotate_vector_to_target(dvec3(0, 0, 1), end - start);
1001 tesselate_arrow((end-start).length(), aspect, rel_tip_radius, tip_aspect, res, edges);
1003}
1004
1006{
1007 set_color(i*l.get_emission());
1009 switch (l.get_type()) {
1010 case LT_DIRECTIONAL :
1011 mul_modelview_matrix(cgv::math::scale4<double>(light_scale, light_scale, light_scale));
1012 tesselate_arrow(vec3(0.0f), l.get_position(), 0.1f,2.0f,0.5f);
1013 break;
1014 case LT_POINT :
1016 cgv::math::translate4<double>(l.get_position())*
1017 cgv::math::scale4<double>(vec3(0.3f*light_scale)));
1019 break;
1020 case LT_SPOT :
1022 cgv::math::translate4<double>(l.get_position())*
1023 cgv::math::scale4<double>(vec3(light_scale))
1024 );
1025 rotate_vector_to_target(dvec3(0, 0, -1), l.get_spot_direction());
1026 {
1027 float t = tan(l.get_spot_cutoff()*(float)M_PI/180);
1028 if (l.get_spot_cutoff() > 45.0f)
1029 mul_modelview_matrix(cgv::math::scale4<double>(1, 1, 0.5f / t));
1030 else
1031 mul_modelview_matrix(cgv::math::scale4<double>(t, t, 0.5f));
1032 mul_modelview_matrix(cgv::math::translate4<double>(0, 0, -1));
1034 set_cull_state(CM_OFF);
1037 }
1038 }
1040}
1041
1043{
1044 if (frame_buffer_stack.empty()) {
1045 error("gl_context::announce_external_frame_buffer_change() called with empty frame buffer stack");
1046 return;
1047 }
1048 GLint fbo_id = 0;
1050 fbo_handle = frame_buffer_stack.top()->handle;
1051 frame_buffer_stack.top()->handle = get_handle(fbo_id);
1052}
1053
1055{
1056 glBindFramebuffer(GL_FRAMEBUFFER, get_gl_id(fbo_handle));
1057 if (frame_buffer_stack.empty())
1058 return;
1059 frame_buffer_stack.top()->handle = fbo_handle;
1060}
1061
1063{
1064 if (window_transformation_stack.empty()) {
1065 error("gl_context::announce_external_viewport_change() called with empty window transformation stack");
1066 return;
1067 }
1068 GLint vp[4];
1070 cgv_viewport_storage = window_transformation_stack.top().front().viewport;
1071 window_transformation_stack.top().front().viewport = ivec4(vp[0], vp[1], vp[2], vp[3]);
1072}
1073
1081
1084{
1087
1088 GLint vp[4];
1090
1092 // push projection matrix
1094 // set orthogonal projection
1096 glOrtho(vp[0], vp[0]+vp[2], vp[1], vp[1]+vp[3], -1, 1);
1097 // push modelview matrix
1099 // use identity for modelview
1101 }
1102 set_modelview_matrix(cgv::math::identity4<double>());
1103 set_projection_matrix(cgv::math::ortho4<double>(vp[0], vp[0] + vp[2], vp[1], vp[1]+vp[3], -1, 1));
1104}
1105
1112
1115 unsigned int x, unsigned int y, FrameBufferType buffer_type,
1116 TypeId type, data::ComponentFormat cf, int w, int h)
1117{
1118 const cgv::data::data_format* df = dv.get_format();
1119 if (df) {
1120 w = int(df->get_width());
1121 h = int(df->get_height());
1122 type = df->get_component_type();
1124 if (w < 1 || h < 1) {
1125 error(std::string("read_frame_buffer: received invalid dimensions (") + cgv::utils::to_string(w) + "," + cgv::utils::to_string(h) + ")");
1126 return false;
1127 }
1128 }
1129 else {
1130 if (w < 1 || h < 1) {
1131 GLint vp[4];
1133 w = w < 1 ? vp[2] : w;
1134 h = h < 1 ? vp[3] : h;
1135 }
1136 }
1137 GLuint gl_type = map_to_gl(type);
1138 if (gl_type == 0) {
1139 error(std::string("read_frame_buffer: could not make component type ")+cgv::type::info::get_type_name(df->get_component_type())+" to gl type");
1140 return false;
1141 }
1143 if (cf != cgv::data::CF_D) {
1145 if (cf != cgv::data::CF_S) {
1146 gl_format = map_to_gl(cf);
1147 if (gl_format == GL_RGB && cf != cgv::data::CF_RGB) {
1148 error(std::string("read_frame_buffer: could not match component format ") + cgv::utils::to_string(df->get_component_format()));
1149 return false;
1150 }
1151 }
1152 }
1154 if (buffer_type < FB_BACK)
1156 else {
1157 switch (buffer_type) {
1158 case FB_FRONT : gl_buffer = GL_FRONT; break;
1159 case FB_BACK : gl_buffer = GL_BACK; break;
1160 case FB_FRONT_LEFT : gl_buffer = GL_FRONT_LEFT; break;
1161 case FB_FRONT_RIGHT : gl_buffer = GL_FRONT_RIGHT; break;
1162 case FB_BACK_LEFT : gl_buffer = GL_BACK_LEFT; break;
1163 case FB_BACK_RIGHT : gl_buffer = GL_BACK_RIGHT; break;
1164 default:
1165 error(std::string("invalid buffer type ")+cgv::utils::to_string(buffer_type));
1166 return false;
1167 }
1168 }
1169 // after all necessary information could be extracted, ensure that format
1170 // and data view are created
1171 if (!df) {
1172 df = new cgv::data::data_format(w,h,type,cf);
1173 dv.~data_view();
1174 new(&dv) data::data_view(df);
1175 dv.manage_format(true);
1176 }
1182 glReadPixels(x,y,w,h,gl_format,gl_type,dv.get_ptr<void>());
1186 return true;
1187}
1188
1189
1190void render_vertex(int k, const float* vertices, const float* normals, const float* tex_coords,
1191 const int* vertex_indices, const int* normal_indices, const int* tex_coord_indices, bool flip_normals)
1192{
1193 if (normals && normal_indices) {
1194 if (flip_normals) {
1195 float n[3] = { -normals[3*normal_indices[k]],-normals[3*normal_indices[k]+1],-normals[3*normal_indices[k]+2] };
1196 glNormal3fv(n);
1197 }
1198 else
1199 glNormal3fv(normals+3*normal_indices[k]);
1200 }
1201 if (tex_coords && tex_coord_indices)
1202 glTexCoord2fv(tex_coords+2*tex_coord_indices[k]);
1203 glVertex3fv(vertices+3*vertex_indices[k]);
1204}
1205
1206attribute_array_binding*& get_aab_ptr()
1207{
1208 static attribute_array_binding* aab_ptr = 0;
1209 return aab_ptr;
1210}
1211
1212vertex_buffer*& get_vbo_ptr()
1213{
1214 static vertex_buffer* vbo_ptr = 0;
1215 return vbo_ptr;
1216}
1217
1218bool gl_context::release_attributes(const float* normals, const float* tex_coords, const int* normal_indices, const int* tex_coord_indices) const
1219{
1220 shader_program* prog_ptr = static_cast<shader_program*>(get_current_program());
1221 if (!prog_ptr || prog_ptr->get_position_index() == -1)
1222 return false;
1223
1224 attribute_array_binding*& aab_ptr = get_aab_ptr();
1225 if (!aab_ptr) {
1226 attribute_array_binding::disable_global_array(*this, prog_ptr->get_position_index());
1227 if (prog_ptr->get_normal_index() != -1 && normals && normal_indices)
1228 attribute_array_binding::disable_global_array(*this, prog_ptr->get_normal_index());
1229 if (prog_ptr->get_texcoord_index() != -1 && tex_coords && tex_coord_indices)
1230 attribute_array_binding::disable_global_array(*this, prog_ptr->get_texcoord_index());
1231 }
1232 else {
1233 aab_ptr->disable(const_cast<gl_context&>(*this));
1234 aab_ptr->disable_array(*this, prog_ptr->get_position_index());
1235 if (prog_ptr->get_normal_index() != -1 && normals && normal_indices)
1236 aab_ptr->disable_global_array(*this, prog_ptr->get_normal_index());
1237 if (prog_ptr->get_texcoord_index() != -1 && tex_coords && tex_coord_indices)
1238 aab_ptr->disable_global_array(*this, prog_ptr->get_texcoord_index());
1239 vertex_buffer*& vbo_ptr = get_vbo_ptr();
1240 vbo_ptr->destruct(*this);
1241 delete vbo_ptr;
1242 vbo_ptr = 0;
1243 }
1244 return true;
1245}
1246
1247bool gl_context::prepare_attributes(std::vector<vec3>& P, std::vector<vec3>& N, std::vector<vec2>& T, unsigned nr_vertices,
1248 const float* vertices, const float* normals, const float* tex_coords,
1249 const int* vertex_indices, const int* normal_indices, const int* tex_coord_indices, bool flip_normals) const
1250{
1251 unsigned i;
1252 shader_program* prog_ptr = static_cast<shader_program*>(get_current_program());
1253 if (!prog_ptr || prog_ptr->get_position_index() == -1)
1254 return false;
1255 P.resize(nr_vertices);
1256 for (i = 0; i < nr_vertices; ++i)
1257 P[i] = *reinterpret_cast<const vec3*>(vertices + 3 * vertex_indices[i]);
1258
1259 if (prog_ptr->get_normal_index() != -1 && normals && normal_indices) {
1260 N.resize(nr_vertices);
1261 for (i = 0; i < nr_vertices; ++i) {
1262 N[i] = *reinterpret_cast<const vec3*>(normals + 3 * normal_indices[i]);
1263 if (flip_normals)
1264 N[i] = -N[i];
1265 }
1266 }
1267 if (prog_ptr->get_texcoord_index() != -1 && tex_coords && tex_coord_indices) {
1268 T.resize(nr_vertices);
1269 for (i = 0; i < nr_vertices; ++i)
1270 T[i] = *reinterpret_cast<const vec2*>(tex_coords + 2 * tex_coord_indices[i]);
1271 }
1272
1273 attribute_array_binding*& aab_ptr = get_aab_ptr();
1274 if (core_profile && !aab_ptr) {
1275 aab_ptr = new attribute_array_binding();
1276 aab_ptr->create(*this);
1277 }
1278 if (!aab_ptr) {
1279 attribute_array_binding::set_global_attribute_array<>(*this, prog_ptr->get_position_index(), P);
1280 attribute_array_binding::enable_global_array(*this, prog_ptr->get_position_index());
1281 if (prog_ptr->get_normal_index() != -1) {
1282 if (normals && normal_indices) {
1283 attribute_array_binding::set_global_attribute_array<>(*this, prog_ptr->get_normal_index(), N);
1284 attribute_array_binding::enable_global_array(*this, prog_ptr->get_normal_index());
1285 }
1286 else
1287 attribute_array_binding::disable_global_array(*this, prog_ptr->get_normal_index());
1288 }
1289 if (prog_ptr->get_texcoord_index() != -1) {
1290 if (tex_coords && tex_coord_indices) {
1291 attribute_array_binding::set_global_attribute_array<>(*this, prog_ptr->get_texcoord_index(), T);
1292 attribute_array_binding::enable_global_array(*this, prog_ptr->get_texcoord_index());
1293 }
1294 else
1295 attribute_array_binding::disable_global_array(*this, prog_ptr->get_texcoord_index());
1296 }
1297 }
1298 else {
1299 vertex_buffer*& vbo_ptr = get_vbo_ptr();
1300 if (!vbo_ptr)
1301 vbo_ptr = new vertex_buffer();
1302 else
1303 vbo_ptr->destruct(*this);
1304 vbo_ptr->create(*this, P.size() * sizeof(vec3) + N.size() * sizeof(vec3) + T.size() * sizeof(vec2));
1305 vbo_ptr->replace(const_cast<gl_context&>(*this), 0, &P.front(), P.size());
1306 size_t nml_off = P.size() * sizeof(vec3);
1307 size_t tex_off = nml_off;
1308 if (!N.empty()) {
1309 vbo_ptr->replace(const_cast<gl_context&>(*this), nml_off, &N.front(), N.size());
1310 tex_off += N.size() * sizeof(vec2);
1311 }
1312 if (!T.empty())
1313 vbo_ptr->replace(const_cast<gl_context&>(*this), tex_off, &T.front(), T.size());
1314
1316 aab_ptr->set_attribute_array(*this, prog_ptr->get_position_index(), td3, *vbo_ptr, 0, P.size());
1317 aab_ptr->enable_array(*this, prog_ptr->get_position_index());
1318 if (prog_ptr->get_normal_index() != -1) {
1319 if (normals && normal_indices) {
1320 aab_ptr->set_attribute_array(*this, prog_ptr->get_normal_index(), td3, *vbo_ptr, nml_off, N.size());
1321 aab_ptr->enable_array(*this, prog_ptr->get_normal_index());
1322 }
1323 else
1324 aab_ptr->disable_array(*this, prog_ptr->get_normal_index());
1325 }
1326 if (prog_ptr->get_texcoord_index() != -1) {
1327 if (tex_coords && tex_coord_indices) {
1329 aab_ptr->set_attribute_array(*this, prog_ptr->get_texcoord_index(), td2, *vbo_ptr, tex_off, T.size());
1330 aab_ptr->enable_array(*this, prog_ptr->get_texcoord_index());
1331 }
1332 else
1333 aab_ptr->disable_array(*this, prog_ptr->get_texcoord_index());
1334 }
1335 aab_ptr->enable(const_cast<gl_context&>(*this));
1336 }
1337 return true;
1338}
1339
1342 const float* vertices, const float* normals, const float* tex_coords,
1343 const int* vertex_indices, const int* normal_indices, const int* tex_coord_indices,
1344 int nr_faces, int face_degree, bool flip_normals) const
1345{
1347 int k = 0;
1348 for (int i = 0; i < nr_faces; ++i) {
1350 for (int j = 0; j < face_degree; ++j, ++k)
1351 render_vertex(k, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals);
1352 glEnd();
1353 }
1354 return;
1355 }
1356 unsigned nr_vertices = face_degree * nr_faces;
1357 std::vector<vec3> P, N;
1358 std::vector<vec2> T;
1359 if (!prepare_attributes(P, N, T, nr_vertices, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals))
1360 return;
1361 for (int i = 0; i < nr_faces; ++i)
1362 glDrawArrays(GL_LINE_LOOP, i*face_degree, face_degree);
1363 release_attributes(normals, tex_coords, normal_indices, tex_coord_indices);
1364}
1365
1366
1367void gl_context::draw_elements_void(GLenum mode, size_t total_count, GLenum type, size_t type_size, const void* indices) const
1368{
1369 ensure_configured();
1370 size_t drawn = 0;
1371 const cgv::type::uint8_type* index_ptr = static_cast<const cgv::type::uint8_type*>(indices);
1372 while (drawn < total_count) {
1373 size_t count = total_count - drawn;
1374 if (count > max_nr_indices)
1375 count = size_t(max_nr_indices);
1376 glDrawElements(mode, GLsizei(count), type, index_ptr + drawn * type_size);
1377 drawn += count;
1378 }
1379}
1380
1381size_t max_nr_indices, max_nr_vertices;
1382void gl_context::ensure_configured() const
1383{
1384 if (max_nr_indices != 0)
1385 return;
1386 glGetInteger64v(GL_MAX_ELEMENTS_INDICES, reinterpret_cast<GLint64*>(&max_nr_indices));
1387 glGetInteger64v(GL_MAX_ELEMENTS_VERTICES, reinterpret_cast<GLint64*>(&max_nr_vertices));
1388}
1389
1392 const float* vertices, const float* normals, const float* tex_coords,
1393 const int* vertex_indices, const int* normal_indices, const int* tex_coord_indices,
1394 int nr_faces, int face_degree, bool is_fan, bool flip_normals) const
1395{
1396 int s = face_degree - 2;
1397 int i, k = 2;
1398 std::vector<GLuint> I;
1399 I.push_back(0); I.push_back(1);
1400 for (i = 0; i < nr_faces; ++i) {
1401 if (is_fan) {
1402 I.push_back(k - 1); I.push_back(k);
1403 I.push_back(0); I.push_back(k);
1404 continue;
1405 }
1406 if (s == 1) {
1407 I.push_back(k - 1); I.push_back(k);
1408 I.push_back(k - 2); I.push_back(k);
1409 }
1410 else {
1411 I.push_back(k - 1); I.push_back(k + 1);
1412 I.push_back(k - 2); I.push_back(k);
1413 I.push_back(k); I.push_back(k + 1);
1414 }
1415 k += 2;
1416 }
1417
1420 for (GLuint j:I)
1421 render_vertex(j, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals);
1422 glEnd();
1423 return;
1424 }
1425 unsigned nr_vertices = 2 + (face_degree - 2) * nr_faces;
1426 std::vector<vec3> P, N;
1427 std::vector<vec2> T;
1428 if (!prepare_attributes(P, N, T, nr_vertices, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals))
1429 return;
1430 draw_elements(GL_LINES, I.size(), &I[0]);
1431 release_attributes(normals, tex_coords, normal_indices, tex_coord_indices);
1432}
1433
1435 const float* vertices, const float* normals, const float* tex_coords,
1436 const int* vertex_indices, const int* normal_indices, const int* tex_coord_indices,
1437 int nr_faces, int face_degree, bool flip_normals) const
1438{
1440 int k = 0;
1441 if (face_degree < 5)
1442 glBegin(face_degree == 3 ? GL_TRIANGLES : GL_QUADS);
1443 for (int i = 0; i < nr_faces; ++i) {
1444 if (face_degree >= 5)
1446 for (int j = 0; j < face_degree; ++j, ++k)
1447 render_vertex(k, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals);
1448 if (face_degree >= 5)
1449 glEnd();
1450 }
1451 if (face_degree < 5)
1452 glEnd();
1453 return;
1454 }
1455 unsigned nr_vertices = face_degree * nr_faces;
1456 std::vector<vec3> P, N;
1457 std::vector<vec2> T;
1458 if (!prepare_attributes(P, N, T, nr_vertices, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals))
1459 return;
1460 /*
1461 for (unsigned x = 0; x < nr_vertices; ++x) {
1462 std::cout << x << ": [" << P[x] << "]";
1463 if (N.size() > 0)
1464 std::cout << ", <" << N[x] << ">";
1465 if (T.size() > 0)
1466 std::cout << ", {" << T[x] << "}";
1467 std::cout << std::endl;
1468 }
1469 */
1470 if (face_degree == 3)
1471 glDrawArrays(GL_TRIANGLES, 0, nr_vertices);
1472 else {
1473 for (int i = 0; i < nr_faces; ++i) {
1474 glDrawArrays(GL_TRIANGLE_FAN, i*face_degree, face_degree);
1475 }
1476 }
1477 release_attributes(normals, tex_coords, normal_indices, tex_coord_indices);
1478}
1479
1481 const float* vertices, const float* normals, const float* tex_coords,
1482 const int* vertex_indices, const int* normal_indices, const int* tex_coord_indices,
1483 int nr_faces, int face_degree, bool is_fan, bool flip_normals) const
1484{
1485 int s = face_degree - 2;
1486 int k = 2;
1488 glBegin(face_degree == 3 ? (is_fan ? GL_TRIANGLE_FAN : GL_TRIANGLE_STRIP) : GL_QUAD_STRIP);
1489 render_vertex(0, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals);
1490 render_vertex(1, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals);
1491 for (int i = 0; i < nr_faces; ++i)
1492 for (int j = 0; j < s; ++j, ++k)
1493 render_vertex(k, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals);
1494 glEnd();
1495 return;
1496 }
1497 unsigned nr_vertices = 2 + (face_degree-2) * nr_faces;
1498 std::vector<vec3> P, N;
1499 std::vector<vec2> T;
1500 if (!prepare_attributes(P, N, T, nr_vertices, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals))
1501 return;
1503 release_attributes(normals, tex_coords, normal_indices, tex_coord_indices);
1504}
1505
1507 if(state.enabled)
1509 else
1511 glDepthFunc(map_to_gl(state.test_func));
1513}
1514
1516 glDepthFunc(map_to_gl(func));
1518}
1519
1524
1529
1531 switch(culling_mode) {
1532 case CM_OFF:
1534 break;
1535 case CM_BACKFACE:
1538 break;
1539 case CM_FRONTFACE:
1542 break;
1543 default:
1544 break;
1545 }
1546 context::set_cull_state(culling_mode);
1547}
1548
1550 if(state.enabled)
1552 else
1556 map_to_gl(state.src_color),
1557 map_to_gl(state.dst_color),
1558 map_to_gl(state.src_alpha),
1559 map_to_gl(state.dst_alpha)
1560 );
1561 } else {
1562 glBlendFunc(map_to_gl(state.src_color), map_to_gl(state.dst_color));
1563 }
1565}
1566
1571
1581
1586
1591
1593 glDepthMask(map_to_gl(mask.depth_flag));
1595 map_to_gl(mask.red_flag),
1596 map_to_gl(mask.green_flag),
1597 map_to_gl(mask.blue_flag),
1598 map_to_gl(mask.alpha_flag)
1599 );
1601}
1602
1604 glDepthMask(map_to_gl(flag));
1606}
1607
1610 map_to_gl(flags[0]),
1611 map_to_gl(flags[1]),
1612 map_to_gl(flags[2]),
1613 map_to_gl(flags[3])
1614 );
1616}
1617
1620{
1622 GLdouble V[16];
1624 return dmat4(4,4,V);
1625 }
1626 if (modelview_matrix_stack.empty())
1627 return identity4<double>();
1628 return modelview_matrix_stack.top();
1629}
1630
1633{
1635 GLdouble P[16];
1637 return dmat4(4,4,P);
1638 }
1639 if (projection_matrix_stack.empty())
1640 return identity4<double>();
1641 return projection_matrix_stack.top();
1642}
1645{
1647 update_window_transformation_array();
1648}
1649
1650void gl_context::update_window_transformation_array()
1651{
1652 const std::vector<window_transformation>& wta = window_transformation_stack.top();
1653 if (wta.size() == 1) {
1654 const ivec4& viewport = wta.front().viewport;
1655 const dvec2& depth_range = wta.front().depth_range;
1656 glViewport(viewport[0], viewport[1], (GLsizei)viewport[2], (GLsizei)viewport[3]);
1657 glScissor(viewport[0], viewport[1], (GLsizei)viewport[2], (GLsizei)viewport[3]);
1658 glDepthRange(depth_range[0], depth_range[1]);
1659 }
1660 else {
1661 for (GLuint array_index = 0; array_index < (GLuint)wta.size(); ++array_index) {
1662 const ivec4& viewport = wta[array_index].viewport;
1663 const dvec2& depth_range = wta[array_index].depth_range;
1664 glViewportIndexedf(array_index, (GLfloat)viewport[0], (GLfloat)viewport[1], (GLfloat)viewport[2], (GLfloat)viewport[3]);
1665 glScissorIndexed(array_index, viewport[0], viewport[1], (GLsizei)viewport[2], (GLsizei)viewport[3]);
1666 glDepthRangeIndexed(array_index, (GLclampd)depth_range[0], (GLclampd)depth_range[1]);
1667 }
1668 }
1669}
1670
1672{
1673 GLint max_value = 1;
1674 if (GLEW_VERSION_4_1)
1675 glGetIntegerv(GL_MAX_VIEWPORTS, &max_value);
1676 return max_value;
1677}
1678
1681{
1682 size_t nr = window_transformation_stack.top().size();
1684 if (nr != window_transformation_stack.top().size())
1685 update_window_transformation_array();
1686 else {
1687 if (array_index < 1) {
1688 glViewport(viewport[0], viewport[1], (GLsizei)viewport[2], (GLsizei)viewport[3]);
1689 glScissor(viewport[0], viewport[1], (GLsizei)viewport[2], (GLsizei)viewport[3]);
1690 }
1691 else {
1692 glViewportIndexedf(array_index, (GLfloat)viewport[0], (GLfloat)viewport[1], (GLfloat)viewport[2], (GLfloat)viewport[3]);
1693 glScissorIndexed(array_index, viewport[0], viewport[1], (GLsizei)viewport[2], (GLsizei)viewport[3]);
1694 }
1695 }
1696}
1697
1699void gl_context::set_depth_range(const dvec2& depth_range, int array_index)
1700{
1701 size_t nr = window_transformation_stack.top().size();
1703 if (nr != window_transformation_stack.top().size())
1704 update_window_transformation_array();
1705 else {
1706 if (array_index < 1)
1707 glDepthRange(depth_range[0], depth_range[1]);
1708 else
1709 glDepthRangeIndexed(array_index, (GLclampd)depth_range[0], (GLclampd)depth_range[1]);
1710 }
1711}
1712/*
1714gl_context::dmat4 gl_context::get_device_matrix() const
1715{
1716 GLint vp[4];
1717 glGetIntegerv(GL_VIEWPORT, vp);
1718 dmat4 D; D.zeros();
1719 D(0, 0) = 0.5*vp[2];
1720 D(0, 3) = 0.5*vp[2] + vp[0];
1721 D(1, 1) = -0.5*vp[3]; // flip y-coordinate
1722 D(1, 3) = get_height() - 0.5*vp[3] - vp[1];
1723 D(2, 2) = 0.5;
1724 D(2, 3) = 0.5;
1725 D(3, 3) = 1.0;
1726 return D;
1727}
1728*/
1740
1752
1755{
1757
1758 if (!in_render_process() && !is_current())
1759 make_current();
1760
1762 /*
1763 GLenum err = glGetError();
1764 if (err != GL_NO_ERROR) {
1765 std::cout << "gl error:";
1766 switch (err) {
1767 case GL_INVALID_ENUM : std::cout << "invalid enum"; break;
1768 case GL_INVALID_VALUE : std::cout << "invalid value"; break;
1769 case GL_INVALID_OPERATION : std::cout << "invalid operation"; break;
1770 case GL_STACK_OVERFLOW : std::cout << "stack overflow"; break;
1771 case GL_STACK_UNDERFLOW : std::cout << "stack underflow"; break;
1772 case GL_OUT_OF_MEMORY : std::cout << "out of memory"; break;
1773 default: std::cout << "unknown error"; break;
1774 }
1775 std::cout << std::endl;
1776
1777 }
1778 */
1779 return z_window;
1780}
1781
1782cgv::data::component_format gl_context::texture_find_best_format(
1784 render_component& rc, const std::vector<cgv::data::data_view>* palettes) const
1785{
1786 GLuint& gl_format = (GLuint&)rc.internal_format;
1789 return best_cf;
1790}
1791
1792std::string gl_error_to_string(GLenum eid) {
1793 switch (eid) {
1794 case GL_NO_ERROR: return "";
1795 case GL_INVALID_ENUM: return "invalid enum";
1796 case GL_INVALID_VALUE: return "invalid value";
1797 case GL_INVALID_OPERATION: return "invalid operation";
1798 case GL_INVALID_FRAMEBUFFER_OPERATION: return "invalid framebuffe";
1799 case GL_OUT_OF_MEMORY: return "out of memory";
1800 case GL_STACK_UNDERFLOW: return "stack underflow";
1801 case GL_STACK_OVERFLOW: return "stack overflow";
1802 default:
1803 return "undefined error (id: " + std::to_string(eid) + ")";
1804 }
1805 //return std::string((const char*)gluErrorString(eid));
1806}
1807
1808std::string gl_error() {
1809 GLenum eid = glGetError();
1810 return gl_error_to_string(eid);
1811}
1812
1813bool gl_context::check_gl_error(const std::string& where, const cgv::render::render_component* rc) const
1814{
1815 GLenum eid = glGetError();
1816 if (eid == GL_NO_ERROR)
1817 return false;
1818 std::string error_string = where + ": " + gl_error_to_string(eid);
1820 return true;
1821}
1822
1823bool gl_context::check_texture_support(TextureType tt, const std::string& where, const cgv::render::render_component* rc) const
1824{
1825 switch (tt) {
1826 case TT_3D:
1827 if (!GLEW_VERSION_1_2) {
1828 error(where + ": 3D texture not supported", rc);
1829 return false;
1830 }
1831 break;
1832 case TT_CUBEMAP:
1833 if (!GLEW_VERSION_1_3) {
1834 error(where + ": cubemap texture not supported", rc);
1835 return false;
1836 }
1837 default:
1838 break;
1839 }
1840 return true;
1841}
1842
1843bool gl_context::check_shader_support(ShaderType st, const std::string& where, const cgv::render::render_component* rc) const
1844{
1845 switch (st) {
1846 case ST_COMPUTE:
1847 if (GLEW_VERSION_4_3)
1848 return true;
1849 else {
1850 error(where+": compute shader need not supported OpenGL version 4.3", rc);
1851 return false;
1852 }
1853 case ST_TESS_CONTROL:
1854 case ST_TESS_EVALUATION:
1855 if (GLEW_VERSION_4_0)
1856 return true;
1857 else {
1858 error(where+": tessellation shader need not supported OpenGL version 4.0", rc);
1859 return false;
1860 }
1861 case ST_GEOMETRY:
1862 if (GLEW_VERSION_3_2)
1863 return true;
1864 else {
1865 error(where + ": geometry shader need not supported OpenGL version 3.2", rc);
1866 return false;
1867 }
1868 default:
1869 if (GLEW_VERSION_2_0)
1870 return true;
1871 else {
1872 error(where + ": shaders need not supported OpenGL version 2.0", rc);
1873 return false;
1874 }
1875 }
1876}
1877
1878bool gl_context::check_fbo_support(const std::string& where, const cgv::render::render_component* rc) const
1879{
1880 if (!GLEW_VERSION_3_0) {
1881 error(where + ": framebuffer objects not supported", rc);
1882 return false;
1883 }
1884 return true;
1885}
1886
1887GLuint gl_context::texture_generate(texture_base& tb) const
1888{
1889 if (!check_texture_support(tb.tt, "gl_context::texture_generate", &tb))
1890 return get_gl_id(0);
1891 GLuint tex_id = get_gl_id(0);
1892 glGenTextures(1, &tex_id);
1894 error("gl_context::texture_generate: attempt to create texture inside glBegin-glEnd-block", &tb);
1895 return tex_id;
1896}
1897
1898int gl_context::query_integer_constant(ContextIntegerConstant cic) const
1899{
1901 switch (cic) {
1902 case MAX_NR_GEOMETRY_SHADER_OUTPUT_VERTICES :
1904 break;
1905 }
1906 GLint value;
1907 glGetIntegerv(gl_const, &value);
1908 return value;
1909}
1910
1911GLuint gl_context::texture_bind(TextureType tt, GLuint tex_id) const
1912{
1913 GLint tmp_id;
1914 glGetIntegerv(get_tex_bind(tt), &tmp_id);
1915 glBindTexture(get_tex_dim(tt), tex_id);
1916 return tmp_id;
1917}
1918
1919void gl_context::texture_unbind(TextureType tt, GLuint tmp_id) const
1920{
1921 glBindTexture(get_tex_dim(tt), tmp_id);
1922}
1923
1924bool gl_context::texture_create(texture_base& tb, cgv::data::data_format& df) const
1925{
1926 GLuint gl_format = (const GLuint&) tb.internal_format;
1927
1928 if (tb.tt == TT_UNDEF)
1929 tb.tt = (TextureType)df.get_nr_dimensions();
1930 GLuint tex_id = texture_generate(tb);
1931 if (tex_id == get_gl_id(0))
1932 return false;
1933 GLuint tmp_id = texture_bind(tb.tt, tex_id);
1934
1935 // extract component type
1936 unsigned int transfer_format = map_to_gl(df.get_standard_component_format(), df.get_integer_interpretation());
1937 if (transfer_format == -1) {
1938 error("could not determine transfer format", &tb);
1939 return false;
1940 }
1941 switch (tb.tt) {
1942 case TT_1D :
1944 gl_format, GLsizei(df.get_width()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1945 break;
1946 case TT_1D_ARRAY :
1948 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1949 break;
1950 case TT_2D :
1951 glTexImage2D(GL_TEXTURE_2D, 0, gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1952 break;
1953 case TT_MULTISAMPLE_2D:
1954 glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, tb.nr_multi_samples, gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), map_to_gl(tb.fixed_sample_locations));
1955 break;
1956 case TT_2D_ARRAY :
1957 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), GLsizei(df.get_depth()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1958 break;
1959 case TT_MULTISAMPLE_2D_ARRAY:
1960 glTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, tb.nr_multi_samples, gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), GLsizei(df.get_depth()), map_to_gl(tb.fixed_sample_locations));
1961 break;
1962 case TT_3D :
1964 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), GLsizei(df.get_depth()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1965 break;
1966 case TT_CUBEMAP :
1968 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1970 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1972 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1974 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1976 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1978 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1979 default:
1980 break;
1981 }
1982 if (check_gl_error("gl_context::texture_create", &tb)) {
1983 glDeleteTextures(1, &tex_id);
1984 texture_unbind(tb.tt, tmp_id);
1985 return false;
1986 }
1987
1988 texture_unbind(tb.tt, tmp_id);
1989 tb.have_mipmaps = false;
1990 tb.handle = get_handle(tex_id);
1991 return true;
1992}
1993
1994bool gl_context::texture_create(
1995 texture_base& tb,
1997 const cgv::data::const_data_view& data,
1998 int level, int cube_side, int num_array_layers, const std::vector<cgv::data::data_view>* palettes) const
1999{
2000 // query the format to be used for the texture
2001 GLuint gl_tex_format = (const GLuint&) tb.internal_format;
2002
2003 // define the texture type from the data format and the cube_side parameter
2004 tb.tt = (TextureType)data.get_format()->get_nr_dimensions();
2005 if(cube_side > -1) {
2006 if(tb.tt == TT_2D)
2007 tb.tt = TT_CUBEMAP;
2008 } else if(num_array_layers != 0) {
2009 if(num_array_layers < 0) {
2010 // automatic inference of layers from texture dimensions
2011 unsigned n_dims = data.get_format()->get_nr_dimensions();
2012 if(n_dims == 2)
2013 tb.tt = TT_1D_ARRAY;
2014 if(n_dims == 3)
2015 tb.tt = TT_2D_ARRAY;
2016 } else {
2017 switch(tb.tt) {
2018 case TT_1D: tb.tt = TT_1D_ARRAY; break;
2019 case TT_2D: tb.tt = TT_2D_ARRAY; break;
2020 case TT_3D: tb.tt = TT_2D_ARRAY; break;
2021 default:
2022 break;
2023 }
2024 }
2025 }
2026 // create texture is not yet done
2027 GLuint tex_id;
2028 if (tb.is_created())
2029 tex_id = get_gl_id(tb.handle);
2030 else {
2031 tex_id = texture_generate(tb);
2032 if (tex_id == get_gl_id(0))
2033 return false;
2034 tb.handle = get_handle(tex_id);
2035 }
2036
2037 // bind texture
2038 GLuint tmp_id = texture_bind(tb.tt, tex_id);
2039
2040 // load data to texture
2041 tb.have_mipmaps = load_texture(data, gl_tex_format, level, cube_side, num_array_layers, palettes);
2042 bool result = !check_gl_error("gl_context::texture_create", &tb);
2043 // restore old texture
2044 texture_unbind(tb.tt, tmp_id);
2045 return result;
2046}
2047
2048bool gl_context::texture_create_from_buffer(
2049 texture_base& tb,
2051 int x, int y, int level) const
2052{
2053 GLuint gl_format = (const GLuint&) tb.internal_format;
2054
2055 tb.tt = (TextureType)df.get_nr_dimensions();
2056 if (tb.tt != TT_2D) {
2057 tb.last_error = "texture creation from buffer only possible for 2d textures";
2058 return false;
2059 }
2060 GLuint tex_id;
2061 if (tb.is_created())
2062 tex_id = get_gl_id(tb.handle);
2063 else {
2064 tex_id = texture_generate(tb);
2065 if (tex_id == get_gl_id(0))
2066 return false;
2067 tb.handle = get_handle(tex_id);
2068 }
2069 GLuint tmp_id = texture_bind(tb.tt, tex_id);
2070
2071 // check mipmap type
2072 bool gen_mipmap = level == -1;
2073 if (gen_mipmap)
2074 level = 0;
2075
2076 glCopyTexImage2D(GL_TEXTURE_2D, level, gl_format, x, y, GLsizei(df.get_width()), GLsizei(df.get_height()), 0);
2077 bool result = false;
2078 std::string error_string("gl_context::texture_create_from_buffer: ");
2079 switch (glGetError()) {
2080 case GL_NO_ERROR :
2081 result = true;
2082 break;
2083 case GL_INVALID_ENUM :
2084 error_string += "target was not an accepted value.";
2085 break;
2086 case GL_INVALID_VALUE :
2087 error_string += "level was less than zero or greater than log sub 2(max), where max is the returned value of GL_MAX_TEXTURE_SIZE.\n"
2088 "or border was not zero or 1.\n"
2089 "or width was less than zero, greater than 2 + GL_MAX_TEXTURE_SIZE; or width cannot be represented as 2n + 2 * border for some integer n.";
2090 break;
2091 case GL_INVALID_OPERATION :
2092 error_string += "glCopyTexImage2D was called between a call to glBegin and the corresponding call to glEnd.";
2093 break;
2094 default:
2095 error_string += gl_error_to_string(glGetError());
2096 break;
2097 }
2098 texture_unbind(tb.tt, tmp_id);
2099 if (!result)
2101 else
2102 if (gen_mipmap)
2103 result = texture_generate_mipmaps(tb, tb.tt == TT_CUBEMAP ? 2 : (int)tb.tt);
2104
2105 return result;
2106}
2107
2108bool gl_context::texture_replace(
2109 texture_base& tb,
2110 int x, int y, int z,
2111 const cgv::data::const_data_view& data,
2112 int level, const std::vector<cgv::data::data_view>* palettes) const
2113{
2114 if (!tb.is_created()) {
2115 error("gl_context::texture_replace: attempt to replace in not created texture", &tb);
2116 return false;
2117 }
2118 // determine dimension from location arguments
2119 unsigned int dim = 1;
2120 if (y != -1) {
2121 ++dim;
2122 if (z != -1)
2123 ++dim;
2124 }
2125 // check consistency
2126 if (tb.tt == TT_CUBEMAP) {
2127 if (dim != 3) {
2128 error("gl_context::texture_replace: replace on cubemap without the side defined", &tb);
2129 return false;
2130 }
2131 if (z < 0 || z > 5) {
2132 error("gl_context::texture_replace: replace on cubemap with invalid side specification", &tb);
2133 return false;
2134 }
2135 }
2136 else {
2137 if (tb.tt != dim) {
2138 error("gl_context::texture_replace: replace on texture with invalid position specification", &tb);
2139 return false;
2140 }
2141 }
2142
2143 // bind texture
2144 GLuint tmp_id = texture_bind(tb.tt, get_gl_id(tb.handle));
2145 tb.have_mipmaps = replace_texture(data, level, x, y, z, palettes) || tb.have_mipmaps;
2146 bool result = !check_gl_error("gl_context::texture_replace", &tb);
2147 texture_unbind(tb.tt, tmp_id);
2148 return result;
2149}
2150
2151bool gl_context::texture_replace_from_buffer(
2152 texture_base& tb,
2153 int x, int y, int z,
2154 int x_buffer, int y_buffer,
2155 unsigned int width, unsigned int height,
2156 int level) const
2157{
2158 if (!tb.is_created()) {
2159 error("gl_context::texture_replace_from_buffer: attempt to replace in not created texture", &tb);
2160 return false;
2161 }
2162 // determine dimension from location arguments
2163 unsigned int dim = 2;
2164 if (z != -1)
2165 ++dim;
2166
2167 // consistency checks
2168 if (tb.tt == TT_CUBEMAP) {
2169 if (dim != 3) {
2170 error("gl_context::texture_replace_from_buffer: replace on cubemap without the side defined", &tb);
2171 return false;
2172 }
2173 if (z < 0 || z > 5) {
2174 error("gl_context::texture_replace_from_buffer: replace on cubemap without invalid side specification", &tb);
2175 return false;
2176 }
2177 }
2178 else {
2179 if (tb.tt != dim) {
2180 tb.last_error = "replace on texture with invalid position specification";
2181 return false;
2182 }
2183 }
2184 // check mipmap type
2185 bool gen_mipmap = level == -1;
2186 if (gen_mipmap)
2187 level = 0;
2188
2189 // bind texture
2190 GLuint tmp_id = texture_bind(tb.tt, get_gl_id(tb.handle));
2191 switch (tb.tt) {
2192 case TT_2D : glCopyTexSubImage2D(GL_TEXTURE_2D, level, x, y, x_buffer, y_buffer, width, height); break;
2193 case TT_3D : glCopyTexSubImage3D(GL_TEXTURE_3D, level, x, y, z, x_buffer, y_buffer, width, height); break;
2194 case TT_CUBEMAP : glCopyTexSubImage2D(get_gl_cube_map_target(z), level, x, y, x_buffer, y_buffer, width, height);
2195 default: break;
2196 }
2197 bool result = !check_gl_error("gl_context::texture_replace_from_buffer", &tb);
2198 texture_unbind(tb.tt, tmp_id);
2199
2200 if (result && gen_mipmap)
2201 result = texture_generate_mipmaps(tb, tb.tt == TT_CUBEMAP ? 2 : (int)tb.tt);
2202
2203 return result;
2204}
2205
2206bool gl_context::texture_create_mipmaps(texture_base& tb, cgv::data::data_format& df) const
2207{
2208 GLuint gl_format = (const GLuint&)tb.internal_format;
2209
2210 // extract component type
2211 unsigned int transfer_format = map_to_gl(df.get_standard_component_format(), df.get_integer_interpretation());
2212
2213 if(transfer_format == -1) {
2214 error("could not determine transfer format", &tb);
2215 return false;
2216 }
2217
2218 // extract texture size and compute number of mip-levels
2219 uvec3 size(unsigned(df.get_width()), unsigned(df.get_height()), unsigned(df.get_depth()));
2220
2221 unsigned max_size = cgv::math::max_value(size);
2222 unsigned num_levels = 1 + static_cast<unsigned>(log2(static_cast<float>(max_size)));
2223
2224 // compute mip-level sizes
2225 std::vector<uvec3> level_sizes(num_levels);
2226 level_sizes[0] = size;
2227
2228 for(unsigned level = 1; level < num_levels; ++level) {
2229 uvec3 level_size = level_sizes[level - 1];
2230 level_size = level_size / 2u;
2231 level_size = cgv::math::max(level_size, uvec3(1u));
2232 level_sizes[level] = level_size;
2233 }
2234
2235 GLuint tmp_id = texture_bind(tb.tt, get_gl_id(tb.handle));
2236
2237 bool result = true;
2238
2239 switch(tb.tt) {
2240 case TT_1D:
2241 for(unsigned level = 1; level < num_levels; ++level) {
2242 uvec3 level_size = level_sizes[level];
2244 }
2245 break;
2246 case TT_1D_ARRAY:
2247 //glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, gl_format, df.get_width(), df.get_height(), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
2248 error("create mipmaps not implemented for 1D array textures", &tb);
2249 result = false;
2250 break;
2251 case TT_2D:
2252 for(unsigned level = 1; level < num_levels; ++level) {
2253 uvec3 level_size = level_sizes[level];
2255 }
2256 break;
2257 case TT_MULTISAMPLE_2D:
2258 //glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, tb.nr_multi_samples, gl_format, df.get_width(), df.get_height(), map_to_gl(tb.fixed_sample_locations));
2259 error("create mipmaps not implemented for 2D multisample textures", &tb);
2260 result = false;
2261 break;
2262 case TT_2D_ARRAY:
2263 //glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, gl_format, df.get_width(), df.get_height(), df.get_depth(), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
2264 error("create mipmaps not implemented for 2D array textures", &tb);
2265 result = false;
2266 break;
2267 case TT_MULTISAMPLE_2D_ARRAY:
2268 //glTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, tb.nr_multi_samples, gl_format, df.get_width(), df.get_height(), df.get_depth(), map_to_gl(tb.fixed_sample_locations));
2269 error("create mipmaps not implemented for 2D multisample array textures", &tb);
2270 result = false;
2271 break;
2272 case TT_3D:
2273 for(unsigned level = 1; level < num_levels; ++level) {
2274 uvec3 level_size = level_sizes[level];
2276 }
2277 break;
2278 case TT_CUBEMAP:
2279 /*glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0,
2280 gl_format, df.get_width(), df.get_height(), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
2281 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0,
2282 gl_format, df.get_width(), df.get_height(), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
2283 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0,
2284 gl_format, df.get_width(), df.get_height(), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
2285 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0,
2286 gl_format, df.get_width(), df.get_height(), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
2287 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0,
2288 gl_format, df.get_width(), df.get_height(), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
2289 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0,
2290 gl_format, df.get_width(), df.get_height(), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
2291 */
2292 error("create mipmaps not implemented for cubemap textures", &tb);
2293 result = false;
2294 default:
2295 break;
2296 }
2297
2298 if(check_gl_error("gl_context::texture_create_mipmaps", &tb))
2299 result = false;
2300
2301 if(result)
2302 tb.have_mipmaps = true;
2303
2304 texture_unbind(tb.tt, tmp_id);
2305 return result;
2306}
2307
2308bool gl_context::texture_generate_mipmaps(texture_base& tb, unsigned int dim) const
2309{
2310 GLuint tmp_id = texture_bind(tb.tt,get_gl_id(tb.handle));
2311
2312 bool is_array = tb.tt == TT_1D_ARRAY || tb.tt == TT_2D_ARRAY;
2313 bool is_cubemap = tb.tt == TT_CUBEMAP;
2314 std::string error_string;
2315 bool result = generate_mipmaps(dim, is_cubemap, is_array, &error_string);
2316 if (result)
2317 tb.have_mipmaps = true;
2318 else
2319 error(std::string("gl_context::texture_generate_mipmaps: ") + error_string);
2320
2321 texture_unbind(tb.tt, tmp_id);
2322 return result;
2323}
2324
2325bool gl_context::texture_destruct(texture_base& tb) const
2326{
2327 if (!tb.is_created()) {
2328 error("gl_context::texture_destruct: attempt to destruct not created texture", &tb);
2329 return false;
2330 }
2331 GLuint tex_id = get_gl_id(tb.handle);
2332 glDeleteTextures(1, &tex_id);
2333 bool result = !check_gl_error("gl_context::texture_destruct", &tb);
2334 tb.handle = 0;
2335 return result;
2336}
2337
2338bool gl_context::texture_set_state(const texture_base& tb) const
2339{
2340 if (tb.tt == TT_UNDEF) {
2341 error("gl_context::texture_set_state: attempt to set state on texture without type", &tb);
2342 return false;
2343 }
2344 GLuint tex_id = (GLuint&) tb.handle - 1;
2345 if (tex_id == -1) {
2346 error("gl_context::texture_set_state: attempt of setting texture state of not created texture", &tb);
2347 return false;
2348 }
2349 GLint tmp_id = texture_bind(tb.tt, tex_id);
2350
2351 if (tb.tt != TT_MULTISAMPLE_2D && tb.tt != TT_MULTISAMPLE_2D_ARRAY) {
2352 glTexParameteri(get_tex_dim(tb.tt), GL_TEXTURE_MIN_FILTER, map_to_gl(tb.min_filter));
2353 glTexParameteri(get_tex_dim(tb.tt), GL_TEXTURE_MAG_FILTER, map_to_gl(tb.mag_filter));
2354 if (tb.min_filter == TF_ANISOTROP)
2355 glTexParameterf(get_tex_dim(tb.tt), GL_TEXTURE_MAX_ANISOTROPY_EXT, tb.anisotropy);
2356 else
2357 glTexParameterf(get_tex_dim(tb.tt), GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
2358 glTexParameteri(get_tex_dim(tb.tt), GL_TEXTURE_COMPARE_FUNC, map_to_gl(tb.compare_function));
2359 glTexParameteri(get_tex_dim(tb.tt), GL_TEXTURE_COMPARE_MODE, (tb.use_compare_function ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE));
2360 if (!core_profile)
2361 glTexParameterf(get_tex_dim(tb.tt), GL_TEXTURE_PRIORITY, tb.priority);
2362 glTexParameterfv(get_tex_dim(tb.tt), GL_TEXTURE_BORDER_COLOR, tb.border_color);
2363 // if (tb.border_color[0] >= 0.0f)
2364 glTexParameteri(get_tex_dim(tb.tt), GL_TEXTURE_WRAP_S, map_to_gl(tb.wrap_s));
2365 if (tb.tt > TT_1D)
2366 glTexParameteri(get_tex_dim(tb.tt), GL_TEXTURE_WRAP_T, map_to_gl(tb.wrap_t));
2367 if (tb.tt == TT_3D)
2368 glTexParameteri(get_tex_dim(tb.tt), GL_TEXTURE_WRAP_R, map_to_gl(tb.wrap_r));
2369 }
2370
2371 bool result = !check_gl_error("gl_context::texture_set_state", &tb);
2372 texture_unbind(tb.tt, tmp_id);
2373 return result;
2374}
2375
2376bool gl_context::texture_enable(texture_base& tb, int tex_unit, unsigned int dim) const
2377{
2378 if (dim < 1 || dim > 3) {
2379 error("gl_context::texture_enable: invalid texture dimension", &tb);
2380 return false;
2381 }
2382 GLuint tex_id = (GLuint&) tb.handle - 1;
2383 if (tex_id == -1) {
2384 error("gl_context::texture_enable: texture not created", &tb);
2385 return false;
2386 }
2387 if (tex_unit >= 0) {
2388 if (!GLEW_VERSION_1_3) {
2389 error("gl_context::texture_enable: multi texturing not supported", &tb);
2390 return false;
2391 }
2392 glActiveTexture(GL_TEXTURE0+tex_unit);
2393 }
2394 GLint& old_binding = (GLint&) tb.user_data;
2395 glGetIntegerv(get_tex_bind(tb.tt), &old_binding);
2396 ++old_binding;
2397 glBindTexture(get_tex_dim(tb.tt), tex_id);
2398 // glEnable is not needed for texture arrays and will throw an invalid enum error
2399 //if(!(tb.tt == TT_1D_ARRAY || tb.tt == TT_2D_ARRAY))
2400 // glEnable(get_tex_dim(tb.tt));
2401 bool result = !check_gl_error("gl_context::texture_enable", &tb);
2402 if (tex_unit >= 0)
2404 return result;
2405}
2406
2407bool gl_context::texture_disable(
2408 texture_base& tb,
2409 int tex_unit, unsigned int dim) const
2410{
2411 if (dim < 1 || dim > 3) {
2412 error("gl_context::texture_disable: invalid texture dimension", &tb);
2413 return false;
2414 }
2415 if (tex_unit == -2) {
2416 error("gl_context::texture_disable: invalid texture unit", &tb);
2417 return false;
2418 }
2419 GLuint old_binding = (const GLuint&) tb.user_data;
2420 --old_binding;
2421 if (tex_unit >= 0)
2422 glActiveTexture(GL_TEXTURE0+tex_unit);
2423 // glDisable is not needed for texture arrays and will throw an invalid enum error
2424 //if(!(tb.tt == TT_1D_ARRAY || tb.tt == TT_2D_ARRAY))
2425 // glDisable(get_tex_dim(tb.tt));
2426 bool result = !check_gl_error("gl_context::texture_disable", &tb);
2427 glBindTexture(get_tex_dim(tb.tt), old_binding);
2428 if (tex_unit >= 0)
2430 return result;
2431}
2432
2433bool gl_context::texture_bind_as_image(texture_base& tb, int tex_unit, int level, bool bind_array, int layer, AccessType access) const
2434{
2435 GLuint tex_id = (GLuint&)tb.handle - 1;
2436 if(tex_id == -1) {
2437 error("gl_context::texture_enable: texture not created", &tb);
2438 return false;
2439 }
2440
2441 if(!GLEW_VERSION_4_2) {
2442 error("gl_context::texture_bind_as_image: image textures not supported", &tb);
2443 return false;
2444 }
2445
2446 GLuint gl_format = (const GLuint&)tb.internal_format;
2447 glBindImageTexture(tex_unit, tex_id, level, map_to_gl(bind_array), layer, map_to_gl(access), gl_format);
2448
2449 bool result = !check_gl_error("gl_context::texture_bind_as_image", &tb);
2450 return result;
2451}
2452
2453bool gl_context::render_buffer_create(render_buffer_base& rb, cgv::data::component_format& cf, int& _width, int& _height) const
2454{
2455 if (!GLEW_VERSION_3_0) {
2456 error("gl_context::render_buffer_create: frame buffer objects not supported", &rb);
2457 return false;
2458 }
2459 if (_width == -1)
2460 _width = get_width();
2461 if (_height == -1)
2462 _height = get_height();
2463
2464 GLuint rb_id;
2467
2468 GLuint& gl_format = (GLuint&)rb.internal_format;
2469 unsigned i = find_best_match(cf, color_buffer_formats);
2470 cgv::data::component_format best_cf(color_buffer_formats[i]);
2471 gl_format = gl_color_buffer_format_ids[i];
2472
2473 i = find_best_match(cf, depth_formats, &best_cf);
2474 if (i != -1) {
2475 best_cf = cgv::data::component_format(depth_formats[i]);
2476 gl_format = gl_depth_format_ids[i];
2477 }
2478
2479 cf = best_cf;
2480 if (rb.nr_multi_samples == 0)
2482 else
2484
2485 if (check_gl_error("gl_context::render_buffer_create", &rb))
2486 return false;
2487 rb.handle = get_handle(rb_id);
2488 return true;
2489}
2490
2491bool gl_context::render_buffer_destruct(render_buffer_base& rc) const
2492{
2493 if (!GLEW_VERSION_3_0) {
2494 error("gl_context::render_buffer_destruct: frame buffer objects not supported", &rc);
2495 return false;
2496 }
2497 GLuint rb_id = ((GLuint&) rc.handle)+1;
2499 if (check_gl_error("gl_context::render_buffer_destruct", &rc))
2500 return false;
2501 rc.handle = 0;
2502 return true;
2503}
2504
2505bool gl_context::frame_buffer_create(frame_buffer_base& fbb) const
2506{
2507 if (!check_fbo_support("gl_context::frame_buffer_create", &fbb))
2508 return false;
2509
2510 if (!context::frame_buffer_create(fbb))
2511 return false;
2512
2513 // allocate framebuffer object
2514 GLuint fbo_id = 0;
2515 glGenFramebuffers(1, &fbo_id);
2516 if (fbo_id == 0) {
2517 error("gl_context::frame_buffer_create: could not allocate framebuffer object", &fbb);
2518 return false;
2519 }
2520 fbb.handle = get_handle(fbo_id);
2521 return true;
2522}
2523
2524bool gl_context::frame_buffer_enable(frame_buffer_base& fbb)
2525{
2526 if (!context::frame_buffer_enable(fbb))
2527 return false;
2528 std::vector<int> buffers;
2529 bool depth_buffer = false;
2530 get_buffer_list(fbb, depth_buffer, buffers, GL_COLOR_ATTACHMENT0);
2531 glBindFramebuffer(GL_FRAMEBUFFER, get_gl_id(fbb.handle));
2532
2533 if (buffers.size() == 1)
2534 glDrawBuffer(buffers[0]);
2535 else if (buffers.size() > 1) {
2536 glDrawBuffers(GLsizei(buffers.size()), reinterpret_cast<GLenum*>(&buffers[0]));
2537 }
2538 else if(depth_buffer) {
2540 //glReadBuffer(GL_NONE);
2541 } else {
2542 error("gl_context::frame_buffer_enable: no attached draw buffer selected!!", &fbb);
2543 return false;
2544 }
2545 return true;
2546}
2547
2550{
2551 if (!context::frame_buffer_disable(fbb))
2552 return false;
2553 if (frame_buffer_stack.empty()) {
2554 error("gl_context::frame_buffer_disable called with empty frame buffer stack!!", &fbb);
2555 return false;
2556 }
2557 else
2558 glBindFramebuffer(GL_FRAMEBUFFER, get_gl_id(frame_buffer_stack.top()->handle));
2559 return true;
2560}
2561
2562bool gl_context::frame_buffer_destruct(frame_buffer_base& fbb) const
2563{
2564 if (!context::frame_buffer_destruct(fbb))
2565 return false;
2566 GLuint fbo_id = get_gl_id(fbb.handle);
2567 glDeleteFramebuffers(1, &fbo_id);
2568 fbb.handle = 0;
2569 return true;
2570}
2571
2572void complete_rect_from_vp(ivec4& D, GLint vp[4])
2573{
2574 if (D(0) == -1)
2575 D(0) = vp[0];
2576 if (D(1) == -1)
2577 D(1) = vp[1];
2578 if (D(2) == -1)
2579 D(2) = vp[0] + vp[2];
2580 if (D(3) == -1)
2581 D(3) = vp[1] + vp[3];
2582}
2583
2584void gl_context::frame_buffer_blit(
2585 const frame_buffer_base* src_fbb_ptr, const ivec4& _S,
2586 frame_buffer_base* dst_fbb_ptr, const ivec4& _D, BufferTypeBits btbs, bool interpolate) const
2587{
2588 static const GLenum masks[8]{
2589 0,
2597 };
2598 ivec4 S = _S;
2599 ivec4 D = _D;
2600 if ((src_fbb_ptr == 0 && (S(0) == -1 || S(1) == -1 || S(2) == -1 || S(3) == -1)) ||
2601 (dst_fbb_ptr == 0 && (D(0) == -1 || D(1) == -1 || D(2) == -1 || D(3) == -1))) {
2602 GLint vp[4];
2604 if (src_fbb_ptr == 0)
2605 complete_rect_from_vp(S, vp);
2606 if (dst_fbb_ptr == 0)
2607 complete_rect_from_vp(D, vp);
2608 }
2610 if (src_fbb_ptr) {
2613 }
2614 if (dst_fbb_ptr) {
2617 }
2618 glBlitFramebuffer(S(0), S(1), S(2), S(3), D(0), D(1), D(2), D(3), masks[btbs], interpolate ? GL_LINEAR : GL_NEAREST);
2619 if (src_fbb_ptr)
2621 if (dst_fbb_ptr)
2623}
2624
2625bool gl_context::frame_buffer_attach(frame_buffer_base& fbb, const render_buffer_base& rb, bool is_depth, int i) const
2626{
2627 if (!context::frame_buffer_attach(fbb, rb, is_depth, i))
2628 return false;
2631 glBindFramebuffer(GL_FRAMEBUFFER, get_gl_id(fbb.handle));
2635 get_gl_id(rb.handle));
2637 return true;
2638}
2639
2641bool gl_context::frame_buffer_attach(frame_buffer_base& fbb,
2642 const texture_base& t, bool is_depth,
2643 int level, int i, int z_or_cube_side) const
2644{
2645 if (!context::frame_buffer_attach(fbb, t, is_depth, level, i, z_or_cube_side))
2646 return false;
2649 glBindFramebuffer(GL_FRAMEBUFFER, get_gl_id(fbb.handle));
2650
2651 if (z_or_cube_side == -1) {
2654 t.tt == TT_2D ? GL_TEXTURE_2D : GL_TEXTURE_2D_MULTISAMPLE, get_gl_id(t.handle), level);
2655 }
2656 else {
2657 if (t.tt == TT_CUBEMAP) {
2660 get_gl_cube_map_target(z_or_cube_side), get_gl_id(t.handle), level);
2661 }
2662 else {
2665 t.tt == TT_3D ? GL_TEXTURE_3D : GL_TEXTURE_2D_MULTISAMPLE_ARRAY , get_gl_id(t.handle), level, z_or_cube_side);
2666 }
2667 }
2668 bool result = !check_gl_error("gl_context::frame_buffer_attach", &fbb);
2670 return result;
2671}
2672
2675{
2676 if (fbb.handle == 0) {
2677 error("gl_context::frame_buffer_is_complete: attempt to check completeness on frame buffer that is not created", &fbb);
2678 return false;
2679 }
2682 glBindFramebuffer(GL_FRAMEBUFFER, get_gl_id(fbb.handle));
2685 switch (error) {
2687 return true;
2689 fbb.last_error = "undefined framebuffer";
2690 return false;
2692 fbb.last_error = "incomplete attachment";
2693 return false;
2695 fbb.last_error = "incomplete or missing attachment";
2696 return false;
2698 fbb.last_error = "incomplete multisample";
2699 return false;
2701 fbb.last_error = "incomplete layer targets";
2702 return false;
2704 fbb.last_error = "incomplete draw buffer";
2705 return false;
2707 fbb.last_error = "incomplete read buffer";
2708 return false;
2710 fbb.last_error = "framebuffer objects unsupported";
2711 return false;
2712 }
2713 fbb.last_error = "unknown error";
2714 return false;
2715}
2716
2717int gl_context::frame_buffer_get_max_nr_color_attachments() const
2718{
2719 if (!check_fbo_support("gl_context::frame_buffer_get_max_nr_color_attachments"))
2720 return 0;
2721
2722 GLint nr;
2724 return nr;
2725}
2726
2727int gl_context::frame_buffer_get_max_nr_draw_buffers() const
2728{
2729 if (!check_fbo_support("gl_context::frame_buffer_get_max_nr_draw_buffers"))
2730 return 0;
2731
2732 GLint nr;
2734 return nr;
2735}
2736
2737GLuint gl_shader_type[] =
2738{
2740};
2741
2742void gl_context::shader_code_destruct(render_component& sc) const
2743{
2744 if (sc.handle == 0) {
2745 error("gl_context::shader_code_destruct: shader not created", &sc);
2746 return;
2747 }
2748 glDeleteShader(get_gl_id(sc.handle));
2749 check_gl_error("gl_context::shader_code_destruct", &sc);
2750}
2751
2752bool gl_context::shader_code_create(render_component& sc, ShaderType st, const std::string& source) const
2753{
2754 if (!check_shader_support(st, "gl_context::shader_code_create", &sc))
2755 return false;
2756
2757 GLuint s_id = glCreateShader(gl_shader_type[st]);
2758 if (s_id == -1) {
2759 error(std::string("gl_context::shader_code_create: ")+gl_error(), &sc);
2760 return false;
2761 }
2762 sc.handle = get_handle(s_id);
2763
2764 const char* s = source.c_str();
2765 glShaderSource(s_id, 1, &s,NULL);
2766 if (check_gl_error("gl_context::shader_code_create", &sc))
2767 return false;
2768
2769 return true;
2770}
2771
2772bool gl_context::shader_code_compile(render_component& sc) const
2773{
2774 if (sc.handle == 0) {
2775 error("gl_context::shader_code_compile: shader not created", &sc);
2776 return false;
2777 }
2778 GLuint s_id = get_gl_id(sc.handle);
2780 int result;
2782 if (result == 1)
2783 return true;
2784 sc.last_error = std::string();
2785 GLint infologLength = 0;
2787 if (infologLength > 0) {
2788 int charsWritten = 0;
2789 char *infoLog = (char *)malloc(infologLength);
2791 sc.last_error = infoLog;
2792 free(infoLog);
2793 }
2794 return false;
2795}
2796
2797bool gl_context::shader_program_create(shader_program_base& spb) const
2798{
2799 if (!check_shader_support(ST_VERTEX, "gl_context::shader_program_create", &spb))
2800 return false;
2801 spb.handle = get_handle(glCreateProgram());
2802 return true;
2803}
2804
2805void gl_context::shader_program_attach(shader_program_base& spb, const render_component& sc) const
2806{
2807 if (spb.handle == 0) {
2808 error("gl_context::shader_program_attach: shader program not created", &spb);
2809 return;
2810 }
2811 glAttachShader(get_gl_id(spb.handle), get_gl_id(sc.handle));
2812}
2813
2814void gl_context::shader_program_detach(shader_program_base& spb, const render_component& sc) const
2815{
2816 if (spb.handle == 0) {
2817 error("gl_context::shader_program_detach: shader program not created", &spb);
2818 return;
2819 }
2820 glDetachShader(get_gl_id(spb.handle), get_gl_id(sc.handle));
2821}
2822
2823bool gl_context::shader_program_link(shader_program_base& spb) const
2824{
2825 if (spb.handle == 0) {
2826 error("gl_context::shader_program_link: shader program not created", &spb);
2827 return false;
2828 }
2829 GLuint p_id = get_gl_id(spb.handle);
2831 int result;
2833 if (result == 1)
2834 return context::shader_program_link(spb);
2835 GLint infologLength = 0;
2837 if (infologLength > 0) {
2839 char *infoLog = (char *)malloc(infologLength);
2841 spb.last_error = infoLog;
2842 error(std::string("gl_context::shader_program_link\n")+infoLog, &spb);
2843 free(infoLog);
2844 }
2845 return false;
2846}
2847
2848bool gl_context::shader_program_set_state(shader_program_base& spb) const
2849{
2850 if (spb.handle == 0) {
2851 error("gl_context::shader_program_set_state: shader program not created", &spb);
2852 return false;
2853 }
2854 GLuint p_id = get_gl_id(spb.handle);
2855 glProgramParameteri(p_id, GL_GEOMETRY_VERTICES_OUT_ARB, spb.geometry_shader_output_count);
2856 glProgramParameteri(p_id, GL_GEOMETRY_INPUT_TYPE_ARB, map_to_gl(spb.geometry_shader_input_type));
2857 glProgramParameteri(p_id, GL_GEOMETRY_OUTPUT_TYPE_ARB, map_to_gl(spb.geometry_shader_output_type));
2858 return true;
2859}
2860
2861bool gl_context::shader_program_enable(shader_program_base& spb)
2862{
2863 if (!context::shader_program_enable(spb))
2864 return false;
2865 glUseProgram(get_gl_id(spb.handle));
2866 shader_program& prog = static_cast<shader_program&>(spb);
2867 if (auto_set_lights_in_current_shader_program && spb.does_use_lights())
2868 set_current_lights(prog);
2869 if (auto_set_material_in_current_shader_program && spb.does_use_material())
2871 if (auto_set_view_in_current_shader_program && spb.does_use_view())
2872 set_current_view(prog);
2873 if (auto_set_gamma_in_current_shader_program && spb.does_use_gamma())
2874 set_current_gamma(prog);
2875 if (prog.does_context_set_color() && prog.get_color_index() >= 0)
2876 prog.set_attribute(*this, prog.get_color_index(), current_color);
2877 return true;
2878}
2879
2880bool gl_context::shader_program_disable(shader_program_base& spb)
2881{
2882 if (!context::shader_program_disable(spb))
2883 return false;
2884 if (shader_program_stack.empty())
2885 glUseProgram(0);
2886 else
2887 glUseProgram(get_gl_id(shader_program_stack.top()->handle));
2888 return true;
2889}
2890
2891bool gl_context::shader_program_destruct(shader_program_base& spb) const
2892{
2893 if (!context::shader_program_destruct(spb))
2894 return false;
2895 glDeleteProgram(get_gl_id(spb.handle));
2896 return true;
2897}
2898
2899int gl_context::get_uniform_location(const shader_program_base& spb, const std::string& name) const
2900{
2901 return glGetUniformLocation(get_gl_id(spb.handle), name.c_str());
2902}
2903
2904std::string value_type_index_to_string(type_descriptor td)
2905{
2906 std::string res = cgv::type::info::get_type_name(td.coordinate_type);
2907 switch (td.element_type) {
2908 case ET_VECTOR:
2909 res = std::string("vector<") + res + "," + cgv::utils::to_string(td.nr_rows) + ">";
2910 break;
2911 case ET_MATRIX:
2912 res = std::string("matrix<") + res + "," + cgv::utils::to_string(td.nr_rows) + "," + cgv::utils::to_string(td.nr_columns) + ">";
2913 if (td.is_row_major)
2914 res += "^T";
2915 default:
2916 break;
2917 }
2918 if (td.is_array)
2919 res += "[]";
2920 return res;
2921}
2922
2923bool gl_context::set_uniform_void(shader_program_base& spb, int loc, type_descriptor value_type, const void* value_ptr) const
2924{
2925 if (value_type.is_array) {
2926 error(std::string("gl_context::set_uniform_void(") + value_type_index_to_string(value_type) + ") array type not supported, please use set_uniform_array instead.", &spb);
2927 return false;
2928 }
2929 if (!spb.handle) {
2930 error("gl_context::set_uniform_void() called on not created program", &spb);
2931 return false;
2932 }
2933 bool not_current = shader_program_stack.empty() || shader_program_stack.top() != &spb;
2934 if (not_current)
2935 glUseProgram(get_gl_id(spb.handle));
2936 bool res = true;
2937 switch (value_type.element_type) {
2938 case ET_VALUE:
2939 switch (value_type.coordinate_type) {
2940 case TI_BOOL: glUniform1i(loc, *reinterpret_cast<const bool*>(value_ptr) ? 1 : 0); break;
2941 case TI_UINT8: glUniform1ui(loc, *reinterpret_cast<const uint8_type*>(value_ptr)); break;
2942 case TI_UINT16: glUniform1ui(loc, *reinterpret_cast<const uint16_type*>(value_ptr)); break;
2943 case TI_UINT32: glUniform1ui(loc, *reinterpret_cast<const uint32_type*>(value_ptr)); break;
2944 case TI_INT8: glUniform1i(loc, *reinterpret_cast<const int8_type*>(value_ptr)); break;
2945 case TI_INT16: glUniform1i(loc, *reinterpret_cast<const int16_type*>(value_ptr)); break;
2946 case TI_INT32: glUniform1i(loc, *reinterpret_cast<const int32_type*>(value_ptr)); break;
2947 case TI_FLT32: glUniform1f(loc, *reinterpret_cast<const flt32_type*>(value_ptr)); break;
2948 case TI_FLT64: glUniform1d(loc, *reinterpret_cast<const flt64_type*>(value_ptr)); break;
2949 default:
2950 error(std::string("gl_context::set_uniform_void(") + value_type_index_to_string(value_type) + ") unsupported coordinate type.", &spb);
2951 res = false; break;
2952 }
2953 break;
2954 case ET_VECTOR:
2955 switch (value_type.nr_rows) {
2956 case 2:
2957 switch (value_type.coordinate_type) {
2958 case TI_BOOL: glUniform2i(loc, reinterpret_cast<const bool*>(value_ptr)[0] ? 1 : 0, reinterpret_cast<const bool*>(value_ptr)[1] ? 1 : 0); break;
2959 case TI_UINT8: glUniform2ui(loc, reinterpret_cast<const uint8_type*> (value_ptr)[0], reinterpret_cast<const uint8_type*> (value_ptr)[1]); break;
2960 case TI_UINT16: glUniform2ui(loc, reinterpret_cast<const uint16_type*>(value_ptr)[0], reinterpret_cast<const uint16_type*>(value_ptr)[1]); break;
2961 case TI_UINT32: glUniform2ui(loc, reinterpret_cast<const uint32_type*>(value_ptr)[0], reinterpret_cast<const uint32_type*>(value_ptr)[1]); break;
2962 case TI_INT8: glUniform2i(loc, reinterpret_cast<const int8_type*> (value_ptr)[0], reinterpret_cast<const int8_type*> (value_ptr)[1]); break;
2963 case TI_INT16: glUniform2i(loc, reinterpret_cast<const int16_type*> (value_ptr)[0], reinterpret_cast<const int16_type*> (value_ptr)[1]); break;
2964 case TI_INT32: glUniform2i(loc, reinterpret_cast<const int32_type*> (value_ptr)[0], reinterpret_cast<const int32_type*> (value_ptr)[1]); break;
2965 case TI_FLT32: glUniform2f(loc, reinterpret_cast<const flt32_type*> (value_ptr)[0], reinterpret_cast<const flt32_type*> (value_ptr)[1]); break;
2966 case TI_FLT64: glUniform2d(loc, reinterpret_cast<const flt64_type*> (value_ptr)[0], reinterpret_cast<const flt64_type*> (value_ptr)[1]); break;
2967 default:
2968 error(std::string("gl_context::set_uniform_void(") + value_type_index_to_string(value_type) + ") unsupported coordinate type.", &spb);
2969 res = false; break;
2970 }
2971 break;
2972 case 3:
2973 switch (value_type.coordinate_type) {
2974 case TI_BOOL: glUniform3i(loc, reinterpret_cast<const bool*>(value_ptr)[0] ? 1 : 0, reinterpret_cast<const bool*>(value_ptr)[1] ? 1 : 0, reinterpret_cast<const bool*>(value_ptr)[2] ? 1 : 0); break;
2975 case TI_UINT8: glUniform3ui(loc, reinterpret_cast<const uint8_type*> (value_ptr)[0], reinterpret_cast<const uint8_type*> (value_ptr)[1], reinterpret_cast<const uint8_type*> (value_ptr)[2]); break;
2976 case TI_UINT16: glUniform3ui(loc, reinterpret_cast<const uint16_type*>(value_ptr)[0], reinterpret_cast<const uint16_type*>(value_ptr)[1], reinterpret_cast<const uint16_type*>(value_ptr)[2]); break;
2977 case TI_UINT32: glUniform3ui(loc, reinterpret_cast<const uint32_type*>(value_ptr)[0], reinterpret_cast<const uint32_type*>(value_ptr)[1], reinterpret_cast<const uint32_type*>(value_ptr)[2]); break;
2978 case TI_INT8: glUniform3i(loc, reinterpret_cast<const int8_type*> (value_ptr)[0], reinterpret_cast<const int8_type*> (value_ptr)[1], reinterpret_cast<const int8_type*> (value_ptr)[2]); break;
2979 case TI_INT16: glUniform3i(loc, reinterpret_cast<const int16_type*> (value_ptr)[0], reinterpret_cast<const int16_type*> (value_ptr)[1], reinterpret_cast<const int16_type*> (value_ptr)[2]); break;
2980 case TI_INT32: glUniform3i(loc, reinterpret_cast<const int32_type*> (value_ptr)[0], reinterpret_cast<const int32_type*> (value_ptr)[1], reinterpret_cast<const int32_type*> (value_ptr)[2]); break;
2981 case TI_FLT32: glUniform3f(loc, reinterpret_cast<const flt32_type*> (value_ptr)[0], reinterpret_cast<const flt32_type*> (value_ptr)[1], reinterpret_cast<const flt32_type*> (value_ptr)[2]); break;
2982 case TI_FLT64: glUniform3d(loc, reinterpret_cast<const flt64_type*> (value_ptr)[0], reinterpret_cast<const flt64_type*> (value_ptr)[1], reinterpret_cast<const flt64_type*> (value_ptr)[2]); break;
2983 default:
2984 error(std::string("gl_context::set_uniform_void(") + value_type_index_to_string(value_type) + ") unsupported coordinate type.", &spb);
2985 res = false; break;
2986 }
2987 break;
2988 case 4:
2989 switch (value_type.coordinate_type) {
2990 case TI_BOOL: glUniform4i(loc, reinterpret_cast<const bool*>(value_ptr)[0] ? 1 : 0, reinterpret_cast<const bool*>(value_ptr)[1] ? 1 : 0, reinterpret_cast<const bool*>(value_ptr)[2] ? 1 : 0, reinterpret_cast<const bool*>(value_ptr)[3] ? 1 : 0); break;
2991 case TI_UINT8: glUniform4ui(loc, reinterpret_cast<const uint8_type*> (value_ptr)[0], reinterpret_cast<const uint8_type*> (value_ptr)[1], reinterpret_cast<const uint8_type*> (value_ptr)[2], reinterpret_cast<const uint8_type*> (value_ptr)[3]); break;
2992 case TI_UINT16: glUniform4ui(loc, reinterpret_cast<const uint16_type*>(value_ptr)[0], reinterpret_cast<const uint16_type*>(value_ptr)[1], reinterpret_cast<const uint16_type*>(value_ptr)[2], reinterpret_cast<const uint16_type*>(value_ptr)[3]); break;
2993 case TI_UINT32: glUniform4ui(loc, reinterpret_cast<const uint32_type*>(value_ptr)[0], reinterpret_cast<const uint32_type*>(value_ptr)[1], reinterpret_cast<const uint32_type*>(value_ptr)[2], reinterpret_cast<const uint32_type*>(value_ptr)[3]); break;
2994 case TI_INT8: glUniform4i(loc, reinterpret_cast<const int8_type*> (value_ptr)[0], reinterpret_cast<const int8_type*> (value_ptr)[1], reinterpret_cast<const int8_type*> (value_ptr)[2], reinterpret_cast<const int8_type*> (value_ptr)[3]); break;
2995 case TI_INT16: glUniform4i(loc, reinterpret_cast<const int16_type*> (value_ptr)[0], reinterpret_cast<const int16_type*> (value_ptr)[1], reinterpret_cast<const int16_type*> (value_ptr)[2], reinterpret_cast<const int16_type*> (value_ptr)[3]); break;
2996 case TI_INT32: glUniform4i(loc, reinterpret_cast<const int32_type*> (value_ptr)[0], reinterpret_cast<const int32_type*> (value_ptr)[1], reinterpret_cast<const int32_type*> (value_ptr)[2], reinterpret_cast<const int32_type*> (value_ptr)[3]); break;
2997 case TI_FLT32: glUniform4f(loc, reinterpret_cast<const flt32_type*> (value_ptr)[0], reinterpret_cast<const flt32_type*> (value_ptr)[1], reinterpret_cast<const flt32_type*> (value_ptr)[2], reinterpret_cast<const flt32_type*> (value_ptr)[3]); break;
2998 case TI_FLT64: glUniform4d(loc, reinterpret_cast<const flt64_type*> (value_ptr)[0], reinterpret_cast<const flt64_type*> (value_ptr)[1], reinterpret_cast<const flt64_type*> (value_ptr)[2], reinterpret_cast<const flt64_type*> (value_ptr)[3]); break;
2999 default:
3000 error(std::string("gl_context::set_uniform_void(") + value_type_index_to_string(value_type) + ") unsupported coordinate type.", &spb);
3001 res = false; break;
3002 }
3003 break;
3004 }
3005 break;
3006 case ET_MATRIX:
3007 switch (value_type.coordinate_type) {
3008 case TI_FLT32:
3009 switch (value_type.nr_rows) {
3010 case 2:
3011 switch (value_type.nr_columns) {
3012 case 2: glUniformMatrix2fv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt32_type*> (value_ptr)); break;
3013 case 3: glUniformMatrix2x3fv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt32_type*> (value_ptr)); break;
3014 case 4: glUniformMatrix2x4fv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt32_type*> (value_ptr)); break;
3015 default:
3016 error(std::string("gl_context::set_uniform_void(") + value_type_index_to_string(value_type) + ") matrix number of columns outside [2,..,4].", &spb);
3017 res = false; break;
3018 }
3019 break;
3020 case 3:
3021 switch (value_type.nr_columns) {
3022 case 2: glUniformMatrix3x2fv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt32_type*> (value_ptr)); break;
3023 case 3: glUniformMatrix3fv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt32_type*> (value_ptr)); break;
3024 case 4: glUniformMatrix3x4fv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt32_type*> (value_ptr)); break;
3025 default:
3026 error(std::string("gl_context::set_uniform_void(") + value_type_index_to_string(value_type) + ") matrix number of columns outside [2,..,4].", &spb);
3027 res = false; break;
3028 }
3029 break;
3030 case 4:
3031 switch (value_type.nr_columns) {
3032 case 2: glUniformMatrix4x2fv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt32_type*> (value_ptr)); break;
3033 case 3: glUniformMatrix4x3fv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt32_type*> (value_ptr)); break;
3034 case 4: glUniformMatrix4fv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt32_type*> (value_ptr)); break;
3035 default:
3036 error(std::string("gl_context::set_uniform_void(") + value_type_index_to_string(value_type) + ") matrix number of columns outside [2,..,4].", &spb);
3037 res = false; break;
3038 }
3039 break;
3040 default:
3041 error(std::string("gl_context::set_uniform_void(") + value_type_index_to_string(value_type) + ") matrix number of rows outside [2,..,4].", &spb);
3042 res = false; break;
3043 }
3044 break;
3045 case TI_FLT64:
3046 switch (value_type.nr_rows) {
3047 case 2:
3048 switch (value_type.nr_columns) {
3049 case 2: glUniformMatrix2dv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt64_type*> (value_ptr)); break;
3050 case 3: glUniformMatrix2x3dv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt64_type*> (value_ptr)); break;
3051 case 4: glUniformMatrix2x4dv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt64_type*> (value_ptr)); break;
3052 default:
3053 error(std::string("gl_context::set_uniform_void(") + value_type_index_to_string(value_type) + ") matrix number of columns outside [2,..,4].", &spb);
3054 res = false; break;
3055 }
3056 break;
3057 case 3:
3058 switch (value_type.nr_columns) {
3059 case 2: glUniformMatrix3x2dv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt64_type*> (value_ptr)); break;
3060 case 3: glUniformMatrix3dv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt64_type*> (value_ptr)); break;
3061 case 4: glUniformMatrix3x4dv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt64_type*> (value_ptr)); break;
3062 default:
3063 error(std::string("gl_context::set_uniform_void(") + value_type_index_to_string(value_type) + ") matrix number of columns outside [2,..,4].", &spb);
3064 res = false; break;
3065 }
3066 break;
3067 case 4:
3068 switch (value_type.nr_columns) {
3069 case 2: glUniformMatrix4x2dv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt64_type*> (value_ptr)); break;
3070 case 3: glUniformMatrix4x3dv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt64_type*> (value_ptr)); break;
3071 case 4: glUniformMatrix4dv(loc, 1, !value_type.is_row_major, reinterpret_cast<const flt64_type*> (value_ptr)); break;
3072 default:
3073 error(std::string("gl_context::set_uniform_void(") + value_type_index_to_string(value_type) + ") matrix number of columns outside [2,..,4].", &spb);
3074 res = false; break;
3075 }
3076 break;
3077 default:
3078 error(std::string("gl_context::set_uniform_void(") + value_type_index_to_string(value_type) + ") matrix number of rows outside [2,..,4].", &spb);
3079 res = false; break;
3080 }
3081 break;
3082 default:
3083 error(std::string("gl_context::set_uniform_void(") + value_type_index_to_string(value_type) + ") non float coordinate type not supported.", &spb);
3084 res = false; break;
3085 }
3086 break;
3087 }
3088 if (not_current)
3089 glUseProgram(shader_program_stack.empty() ? 0 : get_gl_id(shader_program_stack.top()->handle));
3090
3091 if (check_gl_error("gl_context::set_uniform_void()", &spb))
3092 res = false;
3093 return res;
3094}
3095
3096bool gl_context::set_uniform_array_void(shader_program_base& spb, int loc, type_descriptor value_type, const void* value_ptr, size_t nr_elements) const
3097{
3098 if (!value_type.is_array) {
3099 error(std::string("gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) + ") non array type not allowed.", &spb);
3100 return false;
3101 }
3102 if (!spb.handle) {
3103 error("gl_context::set_uniform_array_void() called on not created program", &spb);
3104 return false;
3105 }
3106 bool not_current = shader_program_stack.empty() || shader_program_stack.top() != &spb;
3107 if (not_current)
3108 glUseProgram(get_gl_id(spb.handle));
3109 bool res = true;
3110 switch (value_type.coordinate_type) {
3111 case TI_INT32:
3112 switch (value_type.element_type) {
3113 case ET_VALUE:
3114 glUniform1iv(loc, GLsizei(nr_elements), reinterpret_cast<const int32_type*>(value_ptr));
3115 break;
3116 case ET_VECTOR:
3117 switch (value_type.nr_rows) {
3118 case 2: glUniform2iv(loc, GLsizei(nr_elements), reinterpret_cast<const int32_type*>(value_ptr)); break;
3119 case 3: glUniform3iv(loc, GLsizei(nr_elements), reinterpret_cast<const int32_type*>(value_ptr)); break;
3120 case 4: glUniform4iv(loc, GLsizei(nr_elements), reinterpret_cast<const int32_type*>(value_ptr)); break;
3121 default:
3122 error(std::string("gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) + ") vector dimension outside [2,..4].", &spb);
3123 res = false;
3124 break;
3125 }
3126 break;
3127 case ET_MATRIX:
3128 error(std::string("gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) + ") type not supported.", &spb);
3129 res = false;
3130 break;
3131 }
3132 break;
3133 case TI_UINT32:
3134 switch (value_type.element_type) {
3135 case ET_VALUE:
3136 glUniform1uiv(loc, GLsizei(nr_elements), reinterpret_cast<const uint32_type*>(value_ptr));
3137 break;
3138 case ET_VECTOR:
3139 switch (value_type.nr_rows) {
3140 case 2: glUniform2uiv(loc, GLsizei(nr_elements), reinterpret_cast<const uint32_type*>(value_ptr)); break;
3141 case 3: glUniform3uiv(loc, GLsizei(nr_elements), reinterpret_cast<const uint32_type*>(value_ptr)); break;
3142 case 4: glUniform4uiv(loc, GLsizei(nr_elements), reinterpret_cast<const uint32_type*>(value_ptr)); break;
3143 default:
3144 error(std::string("gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) + ") vector dimension outside [2,..4].", &spb);
3145 res = false;
3146 break;
3147 }
3148 break;
3149 case ET_MATRIX:
3150 error(std::string("gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) + ") type not supported.", &spb);
3151 res = false;
3152 break;
3153 }
3154 break;
3155 case TI_FLT32:
3156 switch (value_type.element_type) {
3157 case ET_VALUE:
3158 glUniform1fv(loc, GLsizei(nr_elements), reinterpret_cast<const flt32_type*>(value_ptr));
3159 break;
3160 case ET_VECTOR:
3161 switch (value_type.nr_rows) {
3162 case 2: glUniform2fv(loc, GLsizei(nr_elements), reinterpret_cast<const flt32_type*>(value_ptr)); break;
3163 case 3: glUniform3fv(loc, GLsizei(nr_elements), reinterpret_cast<const flt32_type*>(value_ptr)); break;
3164 case 4: glUniform4fv(loc, GLsizei(nr_elements), reinterpret_cast<const flt32_type*>(value_ptr)); break;
3165 default:
3166 error(std::string("gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) + ") vector dimension outside [2,..4].", &spb);
3167 res = false;
3168 break;
3169 }
3170 break;
3171 case ET_MATRIX:
3172 switch (value_type.nr_rows) {
3173 case 2:
3174 switch (value_type.nr_columns) {
3175 case 2: glUniformMatrix2fv(loc, GLsizei(nr_elements), value_type.is_row_major, reinterpret_cast<const flt32_type*>(value_ptr)); break;
3176 case 3: glUniformMatrix2x3fv(loc, GLsizei(nr_elements), value_type.is_row_major, reinterpret_cast<const flt32_type*>(value_ptr)); break;
3177 case 4: glUniformMatrix2x4fv(loc, GLsizei(nr_elements), value_type.is_row_major, reinterpret_cast<const flt32_type*>(value_ptr)); break;
3178 default:
3179 error(std::string("gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) + ") matrix number of columns outside [2,..4].", &spb);
3180 res = false;
3181 break;
3182 }
3183 break;
3184 case 3:
3185 switch (value_type.nr_columns) {
3186 case 2: glUniformMatrix3x2fv(loc, GLsizei(nr_elements), value_type.is_row_major, reinterpret_cast<const flt32_type*>(value_ptr)); break;
3187 case 3: glUniformMatrix3fv(loc, GLsizei(nr_elements), value_type.is_row_major, reinterpret_cast<const flt32_type*>(value_ptr)); break;
3188 case 4: glUniformMatrix3x4fv(loc, GLsizei(nr_elements), value_type.is_row_major, reinterpret_cast<const flt32_type*>(value_ptr)); break;
3189 default:
3190 error(std::string("gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) + ") matrix number of columns outside [2,..4].", &spb);
3191 res = false;
3192 break;
3193 }
3194 break;
3195 case 4:
3196 switch (value_type.nr_columns) {
3197 case 2: glUniformMatrix4x2fv(loc, GLsizei(nr_elements), value_type.is_row_major, reinterpret_cast<const flt32_type*>(value_ptr)); break;
3198 case 3: glUniformMatrix4x3fv(loc, GLsizei(nr_elements), value_type.is_row_major, reinterpret_cast<const flt32_type*>(value_ptr)); break;
3199 case 4: glUniformMatrix4fv(loc, GLsizei(nr_elements), value_type.is_row_major, reinterpret_cast<const flt32_type*>(value_ptr)); break;
3200 default:
3201 error(std::string("gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) + ") matrix number of columns outside [2,..4].", &spb);
3202 res = false;
3203 break;
3204 }
3205 break;
3206 default:
3207 error(std::string("gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) + ") matrix number of rows outside [2,..4].", &spb);
3208 res = false;
3209 break;
3210 }
3211 break;
3212 }
3213 break;
3214 default:
3215 error(std::string("gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) + ") unsupported coordinate type (only int32, uint32, and flt32 supported).", &spb);
3216 res = false;
3217 break;
3218 }
3219 if (check_gl_error("gl_context::set_uniform_array_void()", &spb))
3220 res = false;
3221
3222 if (not_current)
3223 glUseProgram(shader_program_stack.empty() ? 0 : get_gl_id(shader_program_stack.top()->handle));
3224
3225 return res;
3226}
3227
3228int gl_context::get_attribute_location(const shader_program_base& spb, const std::string& name) const
3229{
3230 GLint loc = glGetAttribLocation(get_gl_id(spb.handle), name.c_str());
3231 return loc;
3232}
3233
3234bool gl_context::set_attribute_void(shader_program_base& spb, int loc, type_descriptor value_type, const void* value_ptr) const
3235{
3236 if (!spb.handle) {
3237 error("gl_context::set_attribute_void() called on not created program", &spb);
3238 return false;
3239 }
3240 bool not_current = shader_program_stack.empty() || shader_program_stack.top() != &spb;
3241 if (not_current)
3242 glUseProgram(get_gl_id(spb.handle));
3243 bool res = true;
3244 switch (value_type.element_type) {
3245 case ET_VALUE:
3246 switch (value_type.coordinate_type) {
3247 case TI_BOOL: glVertexAttrib1s(loc, *reinterpret_cast<const bool*>(value_ptr) ? 1 : 0); break;
3248 case TI_INT8: glVertexAttrib1s(loc, *reinterpret_cast<const int8_type*>(value_ptr)); break;
3249 case TI_INT16: glVertexAttrib1s(loc, *reinterpret_cast<const int16_type*>(value_ptr)); break;
3250 case TI_INT32: glVertexAttribI1i(loc, *reinterpret_cast<const int32_type*>(value_ptr)); break;
3251 case TI_UINT8: glVertexAttrib1s(loc, *reinterpret_cast<const uint8_type*>(value_ptr)); break;
3252 case TI_UINT16: glVertexAttribI1ui(loc, *reinterpret_cast<const uint16_type*>(value_ptr)); break;
3253 case TI_UINT32: glVertexAttribI1ui(loc, *reinterpret_cast<const uint32_type*>(value_ptr)); break;
3254 case TI_FLT32: glVertexAttrib1f(loc, *reinterpret_cast<const flt32_type*>(value_ptr)); break;
3255 case TI_FLT64: glVertexAttrib1d(loc, *reinterpret_cast<const flt64_type*>(value_ptr)); break;
3256 default:
3257 error(std::string("gl_context::set_attribute_void(") + value_type_index_to_string(value_type) + ") type not supported!", &spb);
3258 res = false;
3259 break;
3260 }
3261 break;
3262 case ET_VECTOR:
3263 switch (value_type.nr_rows) {
3264 case 2:
3265 switch (value_type.coordinate_type) {
3266 case TI_BOOL: glVertexAttrib2s(loc, reinterpret_cast<const bool*>(value_ptr)[0] ? 1 : 0, reinterpret_cast<const bool*>(value_ptr)[1] ? 1 : 0); break;
3267 case TI_UINT8: glVertexAttrib2s(loc, reinterpret_cast<const uint8_type*> (value_ptr)[0], reinterpret_cast<const uint8_type*> (value_ptr)[1]); break;
3268 case TI_UINT16: glVertexAttribI2ui(loc, reinterpret_cast<const uint16_type*>(value_ptr)[0], reinterpret_cast<const uint16_type*>(value_ptr)[1]); break;
3269 case TI_UINT32: glVertexAttribI2ui(loc, reinterpret_cast<const uint32_type*>(value_ptr)[0], reinterpret_cast<const uint32_type*>(value_ptr)[1]); break;
3270 case TI_INT8: glVertexAttrib2s(loc, reinterpret_cast<const int8_type*> (value_ptr)[0], reinterpret_cast<const int8_type*> (value_ptr)[1]); break;
3271 case TI_INT16: glVertexAttrib2s(loc, reinterpret_cast<const int16_type*> (value_ptr)[0], reinterpret_cast<const int16_type*> (value_ptr)[1]); break;
3272 case TI_INT32: glVertexAttribI2i(loc, reinterpret_cast<const int32_type*> (value_ptr)[0], reinterpret_cast<const int32_type*> (value_ptr)[1]); break;
3273 case TI_FLT32: glVertexAttrib2f(loc, reinterpret_cast<const flt32_type*> (value_ptr)[0], reinterpret_cast<const flt32_type*> (value_ptr)[1]); break;
3274 case TI_FLT64: glVertexAttrib2d(loc, reinterpret_cast<const flt64_type*> (value_ptr)[0], reinterpret_cast<const flt64_type*> (value_ptr)[1]); break;
3275 default:
3276 error(std::string("gl_context::set_attribute_void(") + value_type_index_to_string(value_type) + ") unsupported coordinate type.", &spb);
3277 res = false;
3278 break;
3279 }
3280 break;
3281 case 3:
3282 switch (value_type.coordinate_type) {
3283 case TI_BOOL: glVertexAttrib3s (loc, reinterpret_cast<const bool*>(value_ptr)[0] ? 1 : 0, reinterpret_cast<const bool*>(value_ptr)[1] ? 1 : 0, reinterpret_cast<const bool*>(value_ptr)[2] ? 1 : 0); break;
3284 case TI_UINT8: glVertexAttrib3s (loc, reinterpret_cast<const uint8_type*> (value_ptr)[0], reinterpret_cast<const uint8_type*> (value_ptr)[1], reinterpret_cast<const uint8_type*> (value_ptr)[2]); break;
3285 case TI_UINT16: glVertexAttribI3ui(loc, reinterpret_cast<const uint16_type*>(value_ptr)[0], reinterpret_cast<const uint16_type*>(value_ptr)[1], reinterpret_cast<const uint16_type*>(value_ptr)[2]); break;
3286 case TI_UINT32: glVertexAttribI3ui(loc, reinterpret_cast<const uint32_type*>(value_ptr)[0], reinterpret_cast<const uint32_type*>(value_ptr)[1], reinterpret_cast<const uint32_type*>(value_ptr)[2]); break;
3287 case TI_INT8: glVertexAttrib3s (loc, reinterpret_cast<const int8_type*> (value_ptr)[0], reinterpret_cast<const int8_type*> (value_ptr)[1], reinterpret_cast<const int8_type*> (value_ptr)[2]); break;
3288 case TI_INT16: glVertexAttrib3s (loc, reinterpret_cast<const int16_type*> (value_ptr)[0], reinterpret_cast<const int16_type*> (value_ptr)[1], reinterpret_cast<const int16_type*> (value_ptr)[2]); break;
3289 case TI_INT32: glVertexAttribI3i (loc, reinterpret_cast<const int32_type*> (value_ptr)[0], reinterpret_cast<const int32_type*> (value_ptr)[1], reinterpret_cast<const int32_type*> (value_ptr)[2]); break;
3290 case TI_FLT32: glVertexAttrib3f (loc, reinterpret_cast<const flt32_type*> (value_ptr)[0], reinterpret_cast<const flt32_type*> (value_ptr)[1], reinterpret_cast<const flt32_type*> (value_ptr)[2]); break;
3291 case TI_FLT64: glVertexAttrib3d (loc, reinterpret_cast<const flt64_type*> (value_ptr)[0], reinterpret_cast<const flt64_type*> (value_ptr)[1], reinterpret_cast<const flt64_type*> (value_ptr)[2]); break;
3292 default:
3293 error(std::string("gl_context::set_attribute_void(") + value_type_index_to_string(value_type) + ") unsupported coordinate type.", &spb);
3294 res = false; break;
3295 }
3296 break;
3297 case 4:
3298 switch (value_type.coordinate_type) {
3299 case TI_BOOL: glVertexAttrib4s (loc, reinterpret_cast<const bool*>(value_ptr)[0] ? 1 : 0, reinterpret_cast<const bool*>(value_ptr)[1] ? 1 : 0, reinterpret_cast<const bool*>(value_ptr)[2] ? 1 : 0, reinterpret_cast<const bool*>(value_ptr)[3] ? 1 : 0); break;
3300 case TI_UINT8: glVertexAttrib4s (loc, reinterpret_cast<const uint8_type*> (value_ptr)[0], reinterpret_cast<const uint8_type*> (value_ptr)[1], reinterpret_cast<const uint8_type*> (value_ptr)[2], reinterpret_cast<const uint8_type*> (value_ptr)[3]); break;
3301 case TI_UINT16: glVertexAttribI4ui(loc, reinterpret_cast<const uint16_type*>(value_ptr)[0], reinterpret_cast<const uint16_type*>(value_ptr)[1], reinterpret_cast<const uint16_type*>(value_ptr)[2], reinterpret_cast<const uint16_type*>(value_ptr)[3]); break;
3302 case TI_UINT32: glVertexAttribI4ui(loc, reinterpret_cast<const uint32_type*>(value_ptr)[0], reinterpret_cast<const uint32_type*>(value_ptr)[1], reinterpret_cast<const uint32_type*>(value_ptr)[2], reinterpret_cast<const uint32_type*>(value_ptr)[3]); break;
3303 case TI_INT8: glVertexAttrib4s (loc, reinterpret_cast<const int8_type*> (value_ptr)[0], reinterpret_cast<const int8_type*> (value_ptr)[1], reinterpret_cast<const int8_type*> (value_ptr)[2], reinterpret_cast<const int8_type*> (value_ptr)[3]); break;
3304 case TI_INT16: glVertexAttrib4s (loc, reinterpret_cast<const int16_type*> (value_ptr)[0], reinterpret_cast<const int16_type*> (value_ptr)[1], reinterpret_cast<const int16_type*> (value_ptr)[2], reinterpret_cast<const int16_type*> (value_ptr)[3]); break;
3305 case TI_INT32: glVertexAttribI4i (loc, reinterpret_cast<const int32_type*> (value_ptr)[0], reinterpret_cast<const int32_type*> (value_ptr)[1], reinterpret_cast<const int32_type*> (value_ptr)[2], reinterpret_cast<const int32_type*> (value_ptr)[3]); break;
3306 case TI_FLT32: glVertexAttrib4f (loc, reinterpret_cast<const flt32_type*> (value_ptr)[0], reinterpret_cast<const flt32_type*> (value_ptr)[1], reinterpret_cast<const flt32_type*> (value_ptr)[2], reinterpret_cast<const flt32_type*> (value_ptr)[3]); break;
3307 case TI_FLT64: glVertexAttrib4d (loc, reinterpret_cast<const flt64_type*> (value_ptr)[0], reinterpret_cast<const flt64_type*> (value_ptr)[1], reinterpret_cast<const flt64_type*> (value_ptr)[2], reinterpret_cast<const flt64_type*> (value_ptr)[3]); break;
3308 default:
3309 error(std::string("gl_context::set_attribute_void(") + value_type_index_to_string(value_type) + ") unsupported coordinate type.", &spb);
3310 res = false;
3311 break;
3312 }
3313 break;
3314 default:
3315 error(std::string("gl_context::set_attribute_void(") + value_type_index_to_string(value_type) + ") vector dimension outside [2..4]", &spb);
3316 res = false;
3317 break;
3318 }
3319 break;
3320 case ET_MATRIX:
3321 error(std::string("gl_context::set_attribute_void(") + value_type_index_to_string(value_type) + ") matrix type not supported!", &spb);
3322 res = false;
3323 break;
3324 }
3325 if (not_current)
3326 glUseProgram(shader_program_stack.empty() ? 0 : get_gl_id(shader_program_stack.top()->handle));
3327
3328 if (check_gl_error("gl_context::set_uniform_array_void()", &spb))
3329 res = false;
3330 return res;
3331}
3332
3333bool gl_context::attribute_array_binding_create(attribute_array_binding_base& aab) const
3334{
3335 if (!GLEW_VERSION_3_0) {
3336 error("gl_context::attribute_array_binding_create() array attribute bindings not supported", &aab);
3337 return false;
3338 }
3339 GLuint a_id;
3341 if (a_id == -1) {
3342 error(std::string("gl_context::attribute_array_binding_create(): ") + gl_error(), &aab);
3343 return false;
3344 }
3345 aab.ctx_ptr = this;
3346 aab.handle = get_handle(a_id);
3347 return true;
3348}
3349
3350bool gl_context::attribute_array_binding_destruct(attribute_array_binding_base& aab)
3351{
3352 if (&aab == attribute_array_binding_stack.top())
3354 if (!context::attribute_array_binding_destruct(aab))
3355 return false;
3356 if (!aab.handle) {
3357 error("gl_context::attribute_array_binding_destruct(): called on not created attribute array binding", &aab);
3358 return false;
3359 }
3360 GLuint a_id = get_gl_id(aab.handle);
3362 return !check_gl_error("gl_context::attribute_array_binding_destruct");
3363}
3364
3365bool gl_context::attribute_array_binding_enable(attribute_array_binding_base& aab)
3366{
3367 if (!context::attribute_array_binding_enable(aab))
3368 return false;
3369 glBindVertexArray(get_gl_id(aab.handle));
3370 return !check_gl_error("gl_context::attribute_array_binding_enable");
3371}
3372
3373bool gl_context::attribute_array_binding_disable(attribute_array_binding_base& aab)
3374{
3375 if (!context::attribute_array_binding_disable(aab))
3376 return false;
3379 else
3380 glBindVertexArray(get_gl_id(attribute_array_binding_stack.top()->handle));
3381 return true;
3382}
3383
3384bool gl_context::set_element_array(attribute_array_binding_base* aab, const vertex_buffer_base* vbb) const
3385{
3386 if (!vbb) {
3387 error("gl_context::set_element_array(): called without a vertex buffer object", aab);
3388 return false;
3389 }
3390 if (!vbb->handle) {
3391 error("gl_context::set_element_array(): called with not created vertex buffer object", vbb);
3392 return false;
3393 }
3394 if (vbb->type != VBT_INDICES) {
3395 std::cout << "gl_context::set_element_array() : called on vertex buffer object that is not of type VBT_INDICES" << std::endl;
3396// error("gl_context::set_element_array(): called on vertex buffer object that is not of type VBT_INDICES", vbb);
3397// return false;
3398 }
3399 if (aab) {
3400 if (!aab->handle) {
3401 error("gl_context::set_element_array(): called on not created attribute array binding", aab);
3402 return false;
3403 }
3404 }
3405 // enable vertex array
3407 if (aab && not_current)
3408 glBindVertexArray(get_gl_id(aab->handle));
3409
3410 // bind buffer to element array
3411 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, get_gl_id(vbb->handle));
3412
3413 if (aab && not_current)
3415
3416 return !check_gl_error("gl_context::set_element_array_void()", aab);
3417}
3418
3419
3420bool gl_context::set_attribute_array_void(attribute_array_binding_base* aab, int loc, type_descriptor value_type, const vertex_buffer_base* vbb, const void* ptr, size_t nr_elements, unsigned stride) const
3421{
3422 if (value_type == ET_MATRIX) {
3423 error("gl_context::set_attribute_array_void(): called with matrix elements not supported", aab);
3424 return false;
3425 }
3426 if (vbb) {
3427 if (!vbb->handle) {
3428 error("gl_context::set_attribute_array_void(): called with not created vertex buffer object", vbb);
3429 return false;
3430 }
3431 }
3432 if (aab) {
3433 if (!aab->handle) {
3434 error("gl_context::set_attribute_array_void(): called on not created attribute array binding", aab);
3435 return false;
3436 }
3437 }
3438
3440 if (aab && not_current)
3441 glBindVertexArray(get_gl_id(aab->handle));
3442
3443 if (vbb)
3444 glBindBuffer(GL_ARRAY_BUFFER, get_gl_id(vbb->handle));
3445
3446 bool res = true;
3447 unsigned n = value_type.element_type == ET_VALUE ? 1 : value_type.nr_rows;
3448 switch (value_type.coordinate_type) {
3449 case TI_INT8: value_type.normalize ? glVertexAttribPointer(loc, n, GL_BYTE, value_type.normalize, stride, ptr) : glVertexAttribIPointer(loc, n, GL_BYTE, stride, ptr); break;
3450 case TI_INT16: value_type.normalize ? glVertexAttribPointer(loc, n, GL_SHORT, value_type.normalize, stride, ptr) : glVertexAttribIPointer(loc, n, GL_SHORT, stride, ptr); break;
3451 case TI_INT32: value_type.normalize ? glVertexAttribPointer(loc, n, GL_INT, value_type.normalize, stride, ptr) : glVertexAttribIPointer(loc, n, GL_INT, stride, ptr); break;
3452 case TI_UINT8: value_type.normalize ? glVertexAttribPointer(loc, n, GL_UNSIGNED_BYTE, value_type.normalize, stride, ptr) : glVertexAttribIPointer(loc, n, GL_UNSIGNED_BYTE, stride, ptr); break;
3453 case TI_UINT16: value_type.normalize ? glVertexAttribPointer(loc, n, GL_UNSIGNED_SHORT, value_type.normalize, stride, ptr) : glVertexAttribIPointer(loc, n, GL_UNSIGNED_SHORT, stride, ptr); break;
3454 case TI_UINT32: value_type.normalize ? glVertexAttribPointer(loc, n, GL_UNSIGNED_INT, value_type.normalize, stride, ptr) : glVertexAttribIPointer(loc, n, GL_UNSIGNED_INT, stride, ptr); break;
3455 case TI_FLT32: glVertexAttribPointer(loc, n, GL_FLOAT, value_type.normalize, stride, ptr); break;
3456 case TI_FLT64:
3457 if (GLEW_VERSION_4_1)
3458 glVertexAttribLPointer(loc, n, GL_DOUBLE, stride, ptr);
3459 else {
3460 error("gl_context::set_attribute_array_void(): called with coordinates of type double only supported starting with OpenGL 4.1", aab);
3461 res = false;
3462 }
3463 break;
3464 default:
3465 error("gl_context::set_attribute_array_void(): called with unsupported coordinate type", aab);
3466 res = false;
3467 }
3468
3469 if (res)
3471
3472 if (vbb)
3474
3475 if (aab && not_current)
3477
3478
3479 return res && !check_gl_error("gl_context::set_attribute_array_void()", aab);
3480}
3481
3482bool gl_context::enable_attribute_array(attribute_array_binding_base* aab, int loc, bool do_enable) const
3483{
3485 if (aab) {
3486 if (!aab->handle) {
3487 error("gl_context::enable_attribute_array(): called on not created attribute array binding", aab);
3488 return false;
3489 }
3490 if (not_current)
3491 glBindVertexArray(get_gl_id(aab->handle));
3492 }
3493
3494 if (do_enable)
3496 else
3498
3499 if (aab && not_current)
3501
3502 return !check_gl_error("gl_context::enable_attribute_array()");
3503}
3504
3505bool gl_context::is_attribute_array_enabled(const attribute_array_binding_base* aab, int loc) const
3506{
3508 if (aab) {
3509 if (!aab->handle) {
3510 error("gl_context::is_attribute_array_enabled(): called on not created attribute array binding", aab);
3511 return false;
3512 }
3513 if (not_current)
3514 glBindVertexArray(get_gl_id(aab->handle));
3515 }
3516
3517 GLint res;
3519
3520 if (aab && not_current)
3522
3523 return res == GL_TRUE;
3524}
3525
3526GLenum buffer_target(VertexBufferType vbt)
3527{
3528 static GLenum buffer_targets[] = {
3537 };
3538 return buffer_targets[vbt];
3539}
3540
3541GLenum buffer_usage(VertexBufferUsage vbu)
3542{
3543 static GLenum buffer_usages[] = {
3553 };
3554 return buffer_usages[vbu];
3555}
3556
3557bool gl_context::vertex_buffer_bind(const vertex_buffer_base& vbb, VertexBufferType _type, unsigned _idx) const
3558{
3559 if (_idx == unsigned(-1))
3560 glBindBuffer(buffer_target(_type), get_gl_id(vbb.handle));
3561 else
3562 glBindBufferBase(buffer_target(_type), _idx, get_gl_id(vbb.handle));
3563 return !check_gl_error("gl_context::vertex_buffer_bind", &vbb);
3564}
3565
3566bool gl_context::vertex_buffer_unbind(const vertex_buffer_base& vbb, VertexBufferType _type, unsigned _idx) const {
3567 if(_idx == unsigned(-1))
3568 glBindBuffer(buffer_target(_type), 0);
3569 else
3570 glBindBufferBase(buffer_target(_type), _idx, 0);
3571 return !check_gl_error("gl_context::vertex_buffer_unbind", &vbb);
3572}
3573
3574bool gl_context::vertex_buffer_create(vertex_buffer_base& vbb, const void* array_ptr, size_t size_in_bytes) const
3575{
3576 if (!GLEW_VERSION_2_0) {
3577 error("gl_context::vertex_buffer_create() vertex buffer objects not supported", &vbb);
3578 return false;
3579 }
3580 GLuint b_id;
3581 glGenBuffers(1, &b_id);
3582 if (b_id == -1) {
3583 error(std::string("gl_context::vertex_buffer_create(): ") + gl_error(), &vbb);
3584 return false;
3585 }
3586 vbb.handle = get_handle(b_id);
3587 glBindBuffer(buffer_target(vbb.type), b_id);
3588 glBufferData(buffer_target(vbb.type), size_in_bytes, array_ptr, buffer_usage(vbb.usage));
3589 glBindBuffer(buffer_target(vbb.type), 0);
3590 return !check_gl_error("gl_context::vertex_buffer_create", &vbb);
3591}
3592
3593bool gl_context::vertex_buffer_resize(vertex_buffer_base& vbb, const void* array_ptr, size_t size_in_bytes) const {
3594 if(!vbb.handle) {
3595 error("gl_context::vertex_buffer_resize() vertex buffer object must be created before", &vbb);
3596 return false;
3597 }
3598 GLuint b_id = get_gl_id(vbb.handle);
3599 glBindBuffer(buffer_target(vbb.type), b_id);
3600 glBufferData(buffer_target(vbb.type), size_in_bytes, array_ptr, buffer_usage(vbb.usage));
3601 glBindBuffer(buffer_target(vbb.type), 0);
3602 return !check_gl_error("gl_context::vertex_buffer_resize", &vbb);
3603}
3604
3605bool gl_context::vertex_buffer_replace(vertex_buffer_base& vbb, size_t offset, size_t size_in_bytes, const void* array_ptr) const
3606{
3607 if (!vbb.handle) {
3608 error("gl_context::vertex_buffer_replace() vertex buffer object must be created before", &vbb);
3609 return false;
3610 }
3611 GLuint b_id = get_gl_id(vbb.handle);
3612 glBindBuffer(buffer_target(vbb.type), b_id);
3613 glBufferSubData(buffer_target(vbb.type), offset, size_in_bytes, array_ptr);
3614 glBindBuffer(buffer_target(vbb.type), 0);
3615 return !check_gl_error("gl_context::vertex_buffer_replace", &vbb);
3616}
3617
3618bool gl_context::vertex_buffer_copy(const vertex_buffer_base& src, size_t src_offset, vertex_buffer_base& target, size_t target_offset, size_t size_in_bytes) const
3619{
3620 if (!src.handle || !target.handle) {
3621 error("gl_context::vertex_buffer_copy() source and destination vertex buffer objects must have been created before", &src);
3622 return false;
3623 }
3624 GLuint b_id = get_gl_id(src.handle);
3625 glBindBuffer(GL_COPY_READ_BUFFER, get_gl_id(src.handle));
3626 glBindBuffer(GL_COPY_WRITE_BUFFER, get_gl_id(target.handle));
3630 return !check_gl_error("gl_context::vertex_buffer_copy", &src);
3631
3632}
3633
3634bool gl_context::vertex_buffer_copy_back(vertex_buffer_base& vbb, size_t offset, size_t size_in_bytes, void* array_ptr) const
3635{
3636 if (!vbb.handle) {
3637 error("gl_context::vertex_buffer_copy_back() vertex buffer object must be created", &vbb);
3638 return false;
3639 }
3640 GLuint b_id = get_gl_id(vbb.handle);
3642 glGetBufferSubData(GL_COPY_READ_BUFFER, offset, size_in_bytes, array_ptr);
3644 return !check_gl_error("gl_context::vertex_buffer_copy_back", &vbb);
3645}
3646
3647bool gl_context::vertex_buffer_destruct(vertex_buffer_base& vbb) const
3648{
3649 if (vbb.handle) {
3650 GLuint b_id = get_gl_id(vbb.handle);
3651 glDeleteBuffers(1, &b_id);
3652 return !check_gl_error("gl_context::vertex_buffer_destruct");
3653 }
3654 else {
3655 error("gl_context::vertex_buffer_destruct(): called on not created vertex buffer", &vbb);
3656 return false;
3657 }
3658}
3659
3660
3661 }
3662 }
3663}
virtual void stream_stats(std::ostream &)
overload to show the content of this object
Definition base.cxx:24
The group class is a node with children.
Definition group.h:20
complete implementation of method actions that only call one method when entering a node
Definition action.h:113
interface of a handler for traverse callbacks
Definition traverser.h:77
class used to traverse a tree structure
Definition traverser.h:102
bool traverse(base_ptr start, traverse_callback_handler *tch=0)
traverse a tree starting at given node according to set strategy, order and dest and previously comin...
the component format inherits the information of a packing_info and adds information on the component...
cgv::type::info::TypeId get_component_type() const
return the component type
ComponentFormat get_standard_component_format() const
return whether the component format is one of the standard formats
The const_data_view has the functionality of the data_view but uses a const pointer and therefore doe...
Definition data_view.h:221
A data_format describes a multidimensional data block of data entries.
Definition data_format.h:17
size_t get_width() const
return the resolution in the first dimension, or 1 if not defined
size_t get_height() const
return the resolution in the second dimension, or 1 if not defined
const component_format & get_component_format() const
return the component_format info by simple conversion of the this pointer
void manage_format(bool enable=true)
whether to manage the data format pointer
Definition data_view.cxx:59
const data_format * get_format() const
return the component format
Definition data_view.cxx:73
cgv::type::func::transfer_const< P, S * >::type get_ptr() const
return a data pointer to type S
Definition data_view.h:61
the data view gives access to a data array of one, two, three or four dimensions.
Definition data_view.h:153
~data_view()
destruct view and delete data pointer if it is owned by the view
void reflect_horizontally()
reflect 2D data view at horizontal axis
unsigned int get_component_alignment() const
return the component alignment in bits in the packed case and in bytes in the unpacked case
bool empty() const
check if pointer is not yet set
Definition ref_ptr.h:230
virtual void stream_help(std::ostream &os)=0
overload to stream help information to the given output stream
matrix of fixed size dimensions
Definition fmat.h:23
A matrix type (full column major storage) The matrix can be loaded directly into OpenGL without need ...
Definition mat.h:208
>simple class to hold the properties of a light source
>simple class to hold the material properties of a phong material
simple class to hold the material properties of a phong material
the image writer chooses a specific writer automatically based on the extension of the given file nam...
static const std::string & get_supported_extensions(char sep=';')
return a string with a list of supported extensions, where the list entries are separated with the pa...
the attribute_array_binding allows to define vertex attributes (i.e.
bool enable(context &ctx)
enable whole the attribute array binding object
static bool enable_global_array(const context &ctx, int loc)
enable attribute array of given location
bool create(const context &ctx)
create the attribute array binding object
bool disable(context &ctx)
disable whole attribute array binding object
static bool disable_global_array(const context &ctx, int loc)
disable attribute array of given location
bool enable_array(const context &ctx, int loc)
enable array for vertex attribute at location loc
bool disable_array(const context &ctx, int loc)
disable array for attribute at location loc
bool set_attribute_array(const context &ctx, int loc, const T &array)
set vertex attribute location to given array and enable array
virtual void set_blend_func(BlendFunction src_factor, BlendFunction dst_factor)
set the blend function
Definition context.cxx:1733
virtual std::ostream & output_stream()
returns an output stream whose output is printed at the current cursor location, which is managed by ...
Definition context.cxx:901
virtual void mul_modelview_matrix(const dmat4 &MV)
multiply given matrix from right to current modelview matrix
Definition context.cxx:1808
virtual void set_depth_range(const dvec2 &depth_range=dvec2(0, 1), int array_index=-1)
set the current depth range or one of the depth ranges in the window transformation array
Definition context.cxx:1908
virtual bool in_render_process() const =0
return whether the context is currently in process of rendering
virtual bool is_created() const =0
return whether the context is created
shader_program_base * get_current_program() const
check for current program, prepare it for rendering and return pointer to it
Definition context.cxx:440
virtual void error(const std::string &message, const render_component *rc=0) const
error handling
Definition context.cxx:219
void set_current_view(shader_program &prog, bool modelview_deps=true, bool projection_deps=true) const
set the shader program view matrices to the currently enabled view matrices
Definition context.cxx:576
float current_font_size
store current font size
Definition context.h:786
bool enable_vsync
whether vsync should be enabled
Definition context.h:692
virtual void set_buffer_mask(BufferMask mask)
set the buffer mask for depth and color buffers
Definition context.cxx:1777
virtual bool is_current() const =0
return whether the context is current
bool auto_set_lights_in_current_shader_program
whether to automatically set lights in current shader program, defaults to true
Definition context.h:680
virtual void set_blend_func_separate(BlendFunction src_color_factor, BlendFunction dst_color_factor, BlendFunction src_alpha_factor, BlendFunction dst_alpha_factor)
set the blend function separately for color and alpha
Definition context.cxx:1741
virtual void on_lights_changed()
helper function to send light update events
Definition context.cxx:632
void push_depth_test_state()
push a copy of the current depth test state onto the stack saved attributes: depth test enablement,...
Definition context.cxx:1669
std::stack< shader_program_base * > shader_program_stack
stack of currently enabled shader programs
Definition context.h:725
bool is_light_source_enabled(void *handle)
check whether light source is enabled
Definition context.cxx:676
virtual void disable_depth_test()
disable the depth test
Definition context.cxx:1695
int get_bg_stencil() const
return the current stencil value for clearing the background
Definition context.cxx:366
virtual unsigned int get_width() const =0
return the width of the window
bool disable_light_source(void *handle)
disable a given light source and return whether there existed a light source with given handle
Definition context.cxx:700
void pop_depth_test_state()
pop the top of the current depth test state from the stack
Definition context.cxx:1673
void tesselate_unit_sphere(int resolution=25, bool flip_normals=false, bool edges=false)
tesselate a sphere of radius 1
Definition context.cxx:1344
virtual RenderPassFlags get_render_pass_flags() const
return the current render pass flags
Definition context.cxx:758
void tesselate_unit_cylinder(int resolution=25, bool flip_normals=false, bool edges=false)
tesselate a cylinder of radius 1
Definition context.cxx:1252
virtual void set_bg_color(vec4 rgba)
set a user defined background color
Definition context.cxx:293
virtual void set_depth_test_state(DepthTestState state)
set the depth test state
Definition context.cxx:1682
size_t get_nr_enabled_light_sources() const
return the number of light sources
Definition context.cxx:665
virtual unsigned int get_height() const =0
return the height of the window
virtual void disable_blending()
disable blending
Definition context.cxx:1760
BufferMask get_buffer_mask() const
return the current buffer mask
Definition context.cxx:1773
void push_cull_state()
push a copy of the current culling state onto the stack saved attributes: cull face enablement,...
Definition context.cxx:1699
virtual void enable_font_face(media::font::font_face_ptr font_face, float font_size)
enable the given font face with the given size in pixels
Definition context.cxx:906
std::stack< dmat4 > modelview_matrix_stack
keep two matrix stacks for model view and projection matrices
Definition context.h:719
virtual void pop_window_transformation_array()
restore previous viewport and depth range arrays defining the window transformations
Definition context.cxx:1875
virtual void set_color_mask(bvec4 flags)
set the color buffer mask
Definition context.cxx:1794
virtual void set_material(const cgv::media::illum::surface_material &mat)
set the current material
Definition context.cxx:1632
DepthTestState get_depth_test_state() const
return the current depth test state
Definition context.cxx:1678
bool auto_set_material_in_current_shader_program
whether to automatically set material in current shader program, defaults to true
Definition context.h:682
void set_current_lights(shader_program &prog) const
set the shader program lights to the currently enabled lights
Definition context.cxx:617
bool enable_light_source(void *handle)
enable a given light source and return whether there existed a light source with given handle
Definition context.cxx:685
void tesselate_unit_disk(int resolution=25, bool flip_normals=false, bool edges=false)
tesselate a circular disk of radius 1
Definition context.cxx:1176
virtual void enable_depth_test()
enable the depth test
Definition context.cxx:1691
bool support_compatibility_mode
whether to support view and lighting management of compatibility mode, defaults to true
Definition context.h:686
void set_current_gamma(shader_program &prog) const
set the shader program gamma values
Definition context.cxx:1580
vec4 get_bg_color() const
return the current color value for clearing the background
Definition context.cxx:302
void pop_projection_matrix()
see push_P for an explanation
Definition context.cxx:1825
std::stack< attribute_array_binding_base * > attribute_array_binding_stack
stack of currently enabled attribute array binding
Definition context.h:737
BlendState get_blend_state() const
return the current blend state
Definition context.cxx:1725
virtual void set_cull_state(CullingMode culling_mode)
set the culling state
Definition context.cxx:1712
virtual void set_depth_func(CompareFunction func)
set the depth test function
Definition context.cxx:1686
void set_light_source(void *handle, const cgv::media::illum::light_source &light, bool place_now=true)
set light source newly
Definition context.cxx:563
void push_projection_matrix()
same as push_V but for the projection matrix - a different matrix stack is used.
Definition context.cxx:1820
bool current_material_is_textured
store flag to tell whether current material is textured
Definition context.h:765
virtual void set_projection_matrix(const dmat4 &P)
set the current projection matrix, which transforms from eye to clip space
Definition context.cxx:1853
rgba current_color
current color value
Definition context.h:694
static const unsigned nr_default_light_sources
number of default light sources
Definition context.h:755
cgv::media::illum::light_source default_light_source[nr_default_light_sources]
default light sources
Definition context.h:757
virtual void set_cursor(int x, int y)
flush the output_stream and set a new cursor position given in opengl coordinates with (0,...
Definition context.cxx:1959
virtual void set_bg_stencil(int s)
set a user defined background stencil value
Definition context.cxx:362
virtual void set_bg_accum_color(vec4 rgba)
set a user defined background color for the accumulation buffer
Definition context.cxx:379
cgv::media::illum::surface_material default_material
store a default material
Definition context.h:761
float get_bg_depth() const
return the current depth value for clearing the background
Definition context.cxx:349
virtual void set_textured_material(const textured_material &mat)
set the current material
Definition context.cxx:1651
std::stack< std::vector< window_transformation > > window_transformation_stack
keep stack of window transformations
Definition context.h:721
vec4 get_bg_accum_color() const
return the current color value for clearing the accumulation buffer
Definition context.cxx:387
const cgv::media::illum::light_source & get_light_source(void *handle) const
read access to light source
Definition context.cxx:548
virtual bool make_current() const =0
make the current context current if possible
bool draw_in_compatibility_mode
whether to do all drawing in compatibility mode, only possible if support_compatibility_mode is true,...
Definition context.h:688
virtual void set_blend_state(BlendState state)
set the complete blend state
Definition context.cxx:1729
bool sRGB_framebuffer
whether to use opengl option to support sRGB framebuffer
Definition context.h:696
virtual RenderPassFlags get_default_render_pass_flags() const
return the default render pass flags
Definition context.cxx:766
virtual void set_bg_depth(float d)
set a user defined background depth value
Definition context.cxx:345
virtual void enable_blending()
enable blending
Definition context.cxx:1756
void set_current_material(shader_program &prog) const
set the shader program material to the currently enabled material
Definition context.cxx:605
void pop_cull_state()
pop the top of the current culling state from the stack
Definition context.cxx:1703
void pop_modelview_matrix()
see push_V for an explanation
Definition context.cxx:1814
void * default_light_source_handles[nr_default_light_sources]
handles of default light sources
Definition context.h:759
void push_modelview_matrix()
push the current viewing matrix onto a matrix stack for viewing matrices.
Definition context.cxx:1802
std::stack< frame_buffer_base * > frame_buffer_stack
stack of currently enabled frame buffers
Definition context.h:723
bool auto_set_view_in_current_shader_program
whether to automatically set viewing matrixes in current shader program, defaults to true
Definition context.h:678
void tesselate_unit_cone(int resolution=25, bool flip_normals=false, bool edges=false)
tesselate a cone of radius 1
Definition context.cxx:1208
CullingMode get_cull_state() const
return the current culling state
Definition context.cxx:1708
virtual void set_viewport(const ivec4 &viewport, int array_index=-1)
set the current viewport or one of the viewports in the window transformation array
Definition context.cxx:1901
const cgv::media::illum::surface_material * current_material_ptr
store pointer to current material
Definition context.h:763
virtual void set_modelview_matrix(const dmat4 &MV)
set the current modelview matrix, which transforms from world to eye space
Definition context.cxx:1836
void * get_enabled_light_source_handle(size_t i) const
access to handle of i-th light source
Definition context.cxx:671
cgv::media::font::font_face_ptr current_font_face
store current font
Definition context.h:788
virtual void set_depth_mask(bool flag)
set the depth buffer mask
Definition context.cxx:1785
bool auto_set_gamma_in_current_shader_program
whether to automatically set gamma in current shader program, defaults to true
Definition context.h:684
virtual void init_frame(context &)
this method is called in one pass over all drawables before the draw method
Definition drawable.cxx:108
virtual void resize(unsigned int w, unsigned int h)
callback to announce resizing of the output window
Definition drawable.cxx:104
virtual bool init(context &)
this method is called after creation or recreation of the context, return whether all necessary funct...
Definition drawable.cxx:99
base interface for framebuffer
Definition context.h:471
implementation of the context API for the OpenGL API excluding methods for font selection,...
Definition gl_context.h:44
media::font::font_face_ptr get_current_font_face() const override
overwrite function to return info font face in case no font is currently selected
void set_depth_func(CompareFunction func) override
set the depth test function
void push_pixel_coords() override
use this to push transformation matrices on the stack such that x and y coordinates correspond to win...
void set_depth_mask(bool flag) override
set the depth buffer mask
RenderAPI get_render_api() const override
return the used rendering API
bool frame_buffer_disable(frame_buffer_base &fbb) override
disable the framebuffer object
void tesselate_arrow(double length=1, double aspect=0.1, double rel_tip_radius=2.0, double tip_aspect=0.3, int res=25, bool edges=false) override
tesselate an arrow from the origin in z-direction
void set_color(const rgba &clr) override
set the current color
void set_buffer_mask(BufferMask mask) override
set the buffer mask for depth and color buffers
float info_font_size
font size to draw textual info
Definition gl_context.h:143
bool frame_buffer_is_complete(const frame_buffer_base &fbb) const override
check for completeness, if not complete, get the reason in last_error
void set_bg_color(vec4 rgba) override
set a user defined background color
void draw_light_source(const cgv::media::illum::light_source &l, float intensity_scale, float light_scale) override
draw a light source with an emissive material
void announce_external_viewport_change(ivec4 &cgv_viewport_storage) override
announce an external viewport change performed with rendering API to the cgv framework providing spac...
void enumerate_program_attributes(shader_program &prog, std::vector< std::string > &names, std::vector< int > *locations_ptr=0, std::vector< int > *sizes_ptr=0, std::vector< int > *types_ptr=0, bool show=false) const override
get list of program attributes
void enable_depth_test() override
enable the depth test
void pop_window_transformation_array() override
restore previous viewport and depth range arrays defining the window transformations
shader_program & ref_default_shader_program(bool texture_support=false) override
return a reference to a shader program used to render without illumination
bool prepare_attributes(std::vector< vec3 > &P, std::vector< vec3 > &N, std::vector< vec2 > &T, unsigned nr_vertices, const float *vertices, const float *normals, const float *tex_coords, const int *vertex_indices, const int *normal_indices, const int *tex_coord_indices, bool flip_normals) const
helper function to prepare attribute arrays
gl_context()
construct context and attach signals
cgv::media::font::font_face_ptr get_info_font_face() const
return info font face and ensure that it is created
void set_color_mask(bvec4 flags) override
set the color buffer mask
void recover_from_external_frame_buffer_change(void *cgv_fbo_storage) override
restore cgv frame buffer to the state before the external change
dmat4 get_modelview_matrix() const override
return homogeneous 4x4 viewing matrix, which transforms from world to eye space
void set_material(const cgv::media::illum::surface_material &mat) override
set the current material
void enable_blending() override
enable blending
void set_bg_stencil(int s) override
set a user defined background stencil value
void recover_from_external_viewport_change(const ivec4 &cgv_viewport_storage) override
restore cgv viewport to the state before the external change
void set_modelview_matrix(const dmat4 &V) override
set the current modelview matrix, which transforms from world to eye space
double get_window_z(int x_window, int y_window) const override
read the device z-coordinate from the z-buffer for the given device x- and y-coordinates
dmat4 get_projection_matrix() const override
return homogeneous 4x4 projection matrix, which transforms from eye to clip space
void enumerate_program_uniforms(shader_program &prog, std::vector< std::string > &names, std::vector< int > *locations_ptr=0, std::vector< int > *sizes_ptr=0, std::vector< int > *types_ptr=0, bool show=false) const override
get list of program uniforms
virtual bool read_frame_buffer(data::data_view &dv, unsigned int x=0, unsigned int y=0, FrameBufferType buffer_type=FB_BACK, cgv::type::info::TypeId type=type::info::TI_UINT8, data::ComponentFormat cf=data::CF_RGB, int w=-1, int h=-1) override
implement according to specification in context class
void enable_material(textured_material &mat) override
enable a material with textures
float get_info_font_size() const
return info font size
void set_bg_depth(float d) override
set a user defined background depth value
cgv::media::font::font_face_ptr info_font_face
font used to draw textual info
Definition gl_context.h:141
void clear_background(bool color_flag, bool depth_flag, bool stencil_flag=false, bool accum_flag=false) override
clear the buffer contents of the flagged buffers to the set background colors
shader_program & ref_surface_shader_program(bool texture_support=false) override
return a reference to the default shader program used to render surfaces
void set_depth_range(const dvec2 &depth_range=dvec2(0, 1), int array_index=-1) override
set the current depth range or one of the depth ranges in the window transformation array
void draw_strip_or_fan(const float *vertices, const float *normals, const float *tex_coords, const int *vertex_indices, const int *normal_indices, const int *tex_coord_indices, int nr_faces, int face_degree, bool is_fan, bool flip_normals) const override
tesselate with one face strip
void set_blend_state(BlendState state) override
set the complete blend state
bool configure_gl()
ensure that glew is initialized, define lighting mode, viewing pyramid and the rendering mode and ret...
bool release_attributes(const float *normals, const float *tex_coords, const int *normal_indices, const int *tex_coord_indices) const
helper function to disable attribute arrays
float get_current_font_size() const override
overwrite function to return info font size in case no font is currently selected
void set_cull_state(CullingMode culling_mode) override
set the culling state
void draw_edges_of_faces(const float *vertices, const float *normals, const float *tex_coords, const int *vertex_indices, const int *normal_indices, const int *tex_coord_indices, int nr_faces, int face_degree, bool flip_normals=false) const override
pass geometry of given faces to current shader program and generate draw calls to render lines for th...
void set_projection_matrix(const dmat4 &P) override
set the current projection matrix, which transforms from eye to clip space
unsigned get_max_window_transformation_array_size() const override
query the maximum number of supported window transformations, which is at least 1
void set_bg_accum_color(vec4 rgba) override
set a user defined background color for the accumulation buffer
void disable_blending() override
disable blending
void rotate_vector_to_target(const dvec3 &vector, const dvec3 &target)
helper function that multiplies a rotation to modelview matrix such that vector is rotated onto targe...
void set_blend_func(BlendFunction src_factor, BlendFunction dst_factor) override
set the blend function
void set_viewport(const ivec4 &viewport, int array_index=-1) override
set the current viewport or one of the viewports in the window transformation array
void pop_pixel_coords() override
pop previously changed transformation matrices
void disable_material(textured_material &mat) override
disable a material with textures
void on_lights_changed() override
helper function to send light update events
void disable_depth_test() override
disable the depth test
void set_blend_func_separate(BlendFunction src_color_factor, BlendFunction dst_color_factor, BlendFunction src_alpha_factor, BlendFunction dst_alpha_factor) override
set the blend function separately for color and alpha
void draw_faces(const float *vertices, const float *normals, const float *tex_coords, const int *vertex_indices, const int *normal_indices, const int *tex_coord_indices, int nr_faces, int face_degree, bool flip_normals) const override
tesselate with independent faces
void set_depth_test_state(DepthTestState state) override
set the depth test state
void draw_edges_of_strip_or_fan(const float *vertices, const float *normals, const float *tex_coords, const int *vertex_indices, const int *normal_indices, const int *tex_coord_indices, int nr_faces, int face_degree, bool is_fan, bool flip_normals=false) const override
pass geometry of given strip or fan to current shader program and generate draw calls to render lines...
void announce_external_frame_buffer_change(void *&cgv_fbo_storage) override
announce an external frame buffer change performed with rendering API to the cgv framework providing ...
base interface for all render components
Definition context.h:301
a shader program combines several shader code fragments to a complete definition of the shading pipel...
bool set_uniform(const context &ctx, const std::string &name, const T &value, bool generate_error=false)
Set the value of a uniform by name, where the type can be any of int, unsigned, float,...
bool set_attribute(const context &ctx, const std::string &name, const T &value)
set constant default value of a vertex attribute by attribute name, if name does not specify an attri...
base interface for a texture
Definition context.h:332
the texture class encapsulates all functionality independent of the rendering api.
Definition texture.h:15
void set_component_format(const component_format &cf)
change component format and clear internal format
Definition texture.cxx:61
class that extends obj_material with the management of textures
a vertex buffer is an unstructured memory block on the GPU.
bool create(const context &ctx, size_t size_in_bytes)
create empty vertex buffer of size size given in bytes
void destruct(const context &ctx)
destruct the render buffer
bool replace(const context &ctx, size_t buffer_offset_in_bytes, const T *array_ptr, size_t nr_elements)
replace part (starting at byte offset buffer_offset_in_bytes) or whole vertex buffer content from nr_...
the base namespace holds the base hierarchy, support for plugin registration and signals
Definition action.cxx:4
data::ref_ptr< group, true > group_ptr
ref counted pointer to a node
Definition group.h:14
ComponentFormat
define standard formats, which should be used to avoid wrong assignment of component names
@ CF_S
depth component
@ CF_RGB
color format with two components R and G
@ CF_D
color format with components B, G, R and A
unsigned find_best_match(const component_format &fmt, const char **format_descriptions, const component_format *fmt0, bool(*fmt1_better_match)(const component_format &fmt, const component_format &fmt1, const component_format &fmt2))
find the best matching format in a list of formats described by strings and return index of best matc...
namespace that holds the abstract gui interface
Definition vr_calib.cxx:10
void message(const std::string &_message)
tell the user something with a message box
Definition dialog.cxx:14
namespace for font support
Definition font.cxx:6
font_ptr default_font(bool mono_space)
return platform dependend default font
Definition font.cxx:57
bool load_texture(const cgv::data::const_data_view &data, unsigned gl_tex_format, unsigned level, unsigned cube_side, int num_array_layers, const std::vector< data_view > *palettes)
load data to a texture with the glTexImage commands and generate mipmaps if the level parameter is -1...
void gl_set_material(const cgv::media::illum::phong_material &mat, MaterialSide ms, float alpha)
enable a material without textures
bool replace_texture(const cgv::data::const_data_view &data, int level, int x, int y, int z, const std::vector< cgv::data::data_view > *palettes)
replace part or complete data of currently bound texture with the data in the given data view
bool ensure_glew_initialized()
initialize glew in the first call to this function and always return whether this was successful
Definition gl.cxx:19
void set_gl_format(texture &tex, GLuint gl_format, const std::string &component_format_description)
set a very specific texture format. This should be called after the texture is constructed and before...
bool generate_mipmaps(unsigned int dim, bool is_cubemap, bool is_array, std::string *last_error)
generate mipmaps for the currently bound texture, which has the given texture dimension; optionally p...
unsigned find_best_texture_format(const cgv::data::component_format &_cf, cgv::data::component_format *best_cf, const std::vector< data_view > *palettes)
map the given component format to the best matching available gl component format
unsigned get_gl_cube_map_target(unsigned side)
return one of the six cube map sides gl enums
std::vector< int > get_context_creation_attrib_list(cgv::render::context_config &cc)
construct a 0 terminated list of context creation attribute definitions
GLuint get_gl_format(const texture &tex)
return the texture format used for a given texture. If called before texture has been created,...
RenderAPI
enumeration of rendering APIs which can be queried from the context
Definition context.h:70
CullingMode
different culling modes
Definition context.h:143
BlendFunction
different blend functions
Definition context.h:150
AccessType
different access types
Definition context.h:266
TextureFilter
different texture filter
Definition context.h:189
TextureWrap
different texture wrap modes
Definition context.h:173
FrameBufferType
different frame buffer types which can be combined together with or
Definition context.h:488
MaterialSide
different sides of a material
Definition context.h:128
VertexBufferUsage
Provides vertex buffer usage hints as defined in OpenGL.
Definition context.h:427
ContextIntegerConstant
integer constants that can be queried from context
Definition context.h:508
ShaderType
different shader types
Definition context.h:485
PrimitiveType
different primitive types
Definition context.h:225
VertexBufferType
Provides vertex buffer types to allow implicit binding.
Definition context.h:414
@ VBT_INDICES
The buffer contains indices and will be bound to GL_ELEMENT_ARRAY_BUFFER.
Definition context.h:417
BufferTypeBits
Bits for the selection of different buffer types.
Definition context.h:461
TextureType
different texture types
Definition context.h:201
RenderPassFlags
available flags that can be queried from the context and set for a new render pass
Definition context.h:93
@ RPF_CLEAR_ACCUM
whether to clear the accumulation buffer
Definition context.h:108
@ RPF_SET_MODELVIEW
whether to set default modelview matrix
Definition context.h:96
@ RPF_SET_MATERIAL
whether to define default material
Definition context.h:100
@ RPF_SET_CLEAR_DEPTH
whether to set the clear color
Definition context.h:114
@ RPF_SET_LIGHTS
whether to define default lights
Definition context.h:99
@ RPF_CLEAR_COLOR
whether to clear the color buffer
Definition context.h:105
@ RPF_CLEAR_STENCIL
whether to clear the depth buffer
Definition context.h:107
@ RPF_SET_CLEAR_STENCIL
whether to set the clear color
Definition context.h:115
@ RPF_ENABLE_MATERIAL
whether to enable material
Definition context.h:102
@ RPF_DRAWABLES_INIT_FRAME
whether to call the init_frame method of the drawables
Definition context.h:111
@ RPF_CLEAR_DEPTH
whether to clear the depth buffer
Definition context.h:106
@ RPF_SET_STATE_FLAGS
whether to set depth buffer and culling flags
Definition context.h:112
@ RPF_SET_PROJECTION
whether to set default projection matrix
Definition context.h:95
@ RPF_SET_CLEAR_ACCUM
whether to set the accumulation buffer clear color
Definition context.h:116
@ RPF_SET_CLEAR_COLOR
whether to set the clear color
Definition context.h:113
@ RPF_SET_LIGHTS_ON
whether to turn on default lights
Definition context.h:101
CompareFunction
different comparison functions used for depth testing or texture comparisons
Definition context.h:254
namespace for templates that provide type information
Definition type_access.h:9
const char * get_type_name(TypeId tid)
function that returns the name of a type specified through TypeId
Definition type_id.cxx:117
TypeId
ids for the different types and type constructs
Definition type_id.h:12
@ TI_INT16
signed integer stored in 8 bits
Definition type_id.h:20
@ TI_INT8
boolean
Definition type_id.h:19
@ TI_INT32
signed integer stored in 16 bits
Definition type_id.h:21
@ TI_FLT32
floating point type stored in 16 bits
Definition type_id.h:28
@ TI_UINT32
unsigned integer stored in 16 bits
Definition type_id.h:25
@ TI_UINT8
signed integer stored in 64 bits
Definition type_id.h:23
@ TI_BOOL
void
Definition type_id.h:18
@ TI_UINT16
unsigned integer stored in 8 bits
Definition type_id.h:24
@ TI_FLT64
floating point type stored in 32 bits
Definition type_id.h:29
namespace for compile time type information
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
char to_upper(char c)
convert char to upper case
Definition scan.cxx:106
bool is_element(char c, const std::string &s)
check if char c arises in string s
Definition scan.cxx:291
the cgv namespace
Definition print.h:11
cgv::media::color< float, cgv::media::RGB, cgv::media::OPACITY > rgba
declare rgba color type with 32 bit components
Definition color.h:855
cgv::math::fvec< double, 3 > dvec3
declare type of 3d double precision floating point vectors
Definition fvec.h:676
cgv::math::fvec< uint32_t, 3 > uvec3
declare type of 3d 32 bit unsigned integer vectors
Definition fvec.h:702
cgv::math::fvec< int32_t, 4 > ivec4
declare type of 4d 32 bit integer vectors
Definition fvec.h:698
cgv::math::fmat< double, 4, 4 > dmat4
declare type of 4x4 matrices
Definition fmat.h:369
cgv::math::fvec< float, 2 > vec2
declare type of 2d single precision floating point vectors
Definition fvec.h:667
cgv::math::fvec< float, 3 > vec3
declare type of 3d single precision floating point vectors
Definition fvec.h:669
Helper functions to process strings.
Represents a blend state used to configure fragment blending.
Definition context.h:645
bool enabled
whether blending is enabled
Definition context.h:647
BlendFunction dst_color
the destination color (rgb) factor
Definition context.h:651
BlendFunction dst_alpha
the destination alpha factor
Definition context.h:655
BlendFunction src_alpha
the source alpha factor
Definition context.h:653
BlendFunction src_color
the source color (rgb) factor
Definition context.h:649
Represents a buffer mask used to mask depth and color buffer outputs.
Definition context.h:660
Represents a depth test state used to configure depth testing.
Definition context.h:637
bool enabled
whether the depth test is enabled
Definition context.h:639
CompareFunction test_func
the function used to compare depth values
Definition context.h:641
configuration object used to define context parameters that need to be set already at creation time
Definition context.h:525
int version_minor
default: -1 ... minor version of maximum supported OpenGL version
Definition context.h:554
int version_major
default: -1 ... major version of maximum supported OpenGL version
Definition context.h:552
bool debug
default: false in release and true in debug version
Definition context.h:558
bool forward_compatible
default: false
Definition context.h:556
bool core_profile
default: true
Definition context.h:560
bool depth_buffer
default: true
Definition context.h:529
bool on_enter_children(group *)
called before the children of a group node g are processed, return whether these should be skipped....
bool on_leave_children(group *)
called when the children of a group node g have been left, return whether to terminate traversal
compact type description of data that can be sent to the context; convertible to int
Definition context.h:47