1#include <cgv/base/group.h>
4#include <cgv_gl/gl/wgl.h>
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>
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>
31using namespace cgv::os;
32using namespace cgv::math;
34using namespace cgv::media::illum;
43 const int CONTEXT_FLAGS = WGL_CONTEXT_FLAGS_ARB;
44 const int CONTEXT_FORWARD_COMPATIBLE_BIT = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
45 const int CONTEXT_DEBUG_BIT = WGL_CONTEXT_DEBUG_BIT_ARB;
46 const int CONTEXT_MAJOR_VERSION = WGL_CONTEXT_MAJOR_VERSION_ARB;
47 const int CONTEXT_MINOR_VERSION = WGL_CONTEXT_MINOR_VERSION_ARB;
48 const int CONTEXT_PROFILE_MASK = WGL_CONTEXT_PROFILE_MASK_ARB;
49 const int CONTEXT_CORE_PROFILE_BIT = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
50 const int CONTEXT_COMPATIBILITY_PROFILE_BIT = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
52 const int CONTEXT_FLAGS = GLX_CONTEXT_FLAGS_ARB;
53 const int CONTEXT_FORWARD_COMPATIBLE_BIT = GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
54 const int CONTEXT_DEBUG_BIT = GLX_CONTEXT_DEBUG_BIT_ARB;
55 const int CONTEXT_MAJOR_VERSION = GLX_CONTEXT_MAJOR_VERSION_ARB;
56 const int CONTEXT_MINOR_VERSION = GLX_CONTEXT_MINOR_VERSION_ARB;
57 const int CONTEXT_PROFILE_MASK = GLX_CONTEXT_PROFILE_MASK_ARB;
58 const int CONTEXT_CORE_PROFILE_BIT = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
59 const int CONTEXT_COMPATIBILITY_PROFILE_BIT = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
61 std::vector<int> attrib_list;
68 attrib_list.push_back(CONTEXT_FLAGS);
69 attrib_list.push_back(
71 (cc.
debug ? CONTEXT_DEBUG_BIT : 0));
74 attrib_list.push_back(CONTEXT_MAJOR_VERSION);
78 attrib_list.push_back(CONTEXT_MINOR_VERSION);
82 attrib_list.push_back(CONTEXT_PROFILE_MASK);
83 attrib_list.push_back(
84 cc.
core_profile ? CONTEXT_CORE_PROFILE_BIT : CONTEXT_COMPATIBILITY_PROFILE_BIT);
86 attrib_list.push_back(0);
92 static const GLenum gl_primitive_type[] = {
98 GL_LINE_STRIP_ADJACENCY,
101 GL_TRIANGLES_ADJACENCY,
103 GL_TRIANGLE_STRIP_ADJACENCY,
110 return gl_primitive_type[primitive_type];
115 static const GLenum gl_material_side[] = {
121 return gl_material_side[material_side];
126 static const GLenum gl_access_type[] = {
131 return gl_access_type[access_type];
136 static const GLenum gl_blend_func[] = {
140 GL_ONE_MINUS_SRC_COLOR,
142 GL_ONE_MINUS_DST_COLOR,
144 GL_ONE_MINUS_SRC_ALPHA,
146 GL_ONE_MINUS_DST_ALPHA,
148 GL_ONE_MINUS_CONSTANT_COLOR,
150 GL_ONE_MINUS_CONSTANT_ALPHA,
151 GL_SRC_ALPHA_SATURATE,
153 GL_ONE_MINUS_SRC1_COLOR,
155 GL_ONE_MINUS_SRC1_ALPHA
157 return gl_blend_func[blend_function];
162 static const GLenum gl_compare_func[] = {
172 return gl_compare_func[compare_func];
175static const GLenum gl_depth_format_ids[] =
178 GL_DEPTH_COMPONENT16,
179 GL_DEPTH_COMPONENT24,
183static const GLenum gl_color_buffer_format_ids[] =
189static const char* depth_formats[] =
198static const char* color_buffer_formats[] =
207 static const GLenum gl_texture_type[] = {
215 GL_TEXTURE_2D_MULTISAMPLE,
216 GL_TEXTURE_2D_MULTISAMPLE_ARRAY
218 return gl_texture_type[texture_type];
223 static const GLenum gl_tex_binding[] = {
225 GL_TEXTURE_BINDING_1D,
226 GL_TEXTURE_BINDING_2D,
227 GL_TEXTURE_BINDING_3D,
228 GL_TEXTURE_BINDING_1D_ARRAY,
229 GL_TEXTURE_BINDING_2D_ARRAY,
230 GL_TEXTURE_BINDING_CUBE_MAP,
232 GL_TEXTURE_BINDING_2D_MULTISAMPLE,
233 GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY
235 return gl_tex_binding[texture_type];
240 static const GLenum gl_texture_wrap[] = {
246 GL_MIRROR_CLAMP_TO_EDGE_EXT,
247 GL_MIRROR_CLAMP_TO_BORDER_EXT,
250 return gl_texture_wrap[texture_wrap];
255 static const GLenum gl_texture_filter[] = {
258 GL_NEAREST_MIPMAP_NEAREST,
259 GL_LINEAR_MIPMAP_NEAREST,
260 GL_NEAREST_MIPMAP_LINEAR,
261 GL_LINEAR_MIPMAP_LINEAR,
262 GL_LINEAR_MIPMAP_LINEAR
264 return gl_texture_filter[filter_type];
267GLboolean map_to_gl(
bool flag) {
268 return flag ? GL_TRUE : GL_FALSE;
271GLuint get_gl_id(
const void* handle)
273 return (
const GLuint&)handle - 1;
276void* get_handle(GLuint
id)
279 (GLuint&)handle =
id + 1;
283void gl_context::put_id(
void* handle,
void* ptr)
const
285 *
static_cast<GLuint*
>(ptr) = get_gl_id(handle);
292 (GLuint&)tex.internal_format = gl_format;
298 if (tex.internal_format)
299 return (
const GLuint&)tex.internal_format;
306void gl_set_material_color(GLenum side,
const cgv::media::illum::phong_material::color_type& c,
float alpha, GLenum
type)
308 GLfloat v[4] = { c[0],c[1],c[2],c[3] * alpha };
309 glMaterialfv(side,
type, v);
317 unsigned side = map_to_gl(ms);
318 gl_set_material_color(side,
mat.ambient, alpha, GL_AMBIENT);
319 gl_set_material_color(side,
mat.diffuse, alpha, GL_DIFFUSE);
320 gl_set_material_color(side,
mat.specular, alpha, GL_SPECULAR);
321 gl_set_material_color(side,
mat.emission, alpha, GL_EMISSION);
322 glMaterialf(side, GL_SHININESS,
mat.shininess);
335 if (!info_font.
empty())
371std::string get_source_tag_name(GLenum tag)
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" }
381 return source_tags[tag];
384std::string get_type_tag_name(GLenum tag)
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" }
397 return type_tags[tag];
400std::string get_severity_tag_name(GLenum tag)
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" }
408 return severity_tags[tag];
411void GLAPIENTRY debug_callback(GLenum source, GLenum type, GLuint
id, GLenum severity, GLsizei length,
const GLchar*
message,
const void* userParam)
413 if (severity == GL_DEBUG_SEVERITY_NOTIFICATION)
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;
425 error(
"gl_context::configure_gl could not initialize glew");
428 const GLubyte* version_string = glGetString(GL_VERSION);
433 glGetIntegerv(GL_CONTEXT_FLAGS, &context_flags);
435 debug = (context_flags & GL_CONTEXT_FLAG_DEBUG_BIT) != 0;
444 GLint context_profile;
445 glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &context_profile);
447 if (context_profile != 0) {
448 if (
core_profile != ((context_profile & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) == 0)) {
450 std::cerr <<
"WARNING: Ignoring that GL_CONTEXT_PROFILE_MASK yields compatibility profile for context created as core." << std::endl;
452 std::cerr <<
"WARNING: Ignoring that GL_CONTEXT_PROFILE_MASK does not yield compatibility profile for context created as such." << std::endl;
456 std::cerr <<
"WARNING: Ignoring that GL_CONTEXT_PROFILE_MASK yields zero." << std::endl;
462 const GLubyte* vendor_c_string = glGetString(GL_VENDOR);
463 std::string vendor_string(
reinterpret_cast<const char*
>(vendor_c_string));
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;
474 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &gpu_capabilities.max_render_buffer_size);
475 glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &gpu_capabilities.max_geometry_shader_output_vertex_count);
476 glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &gpu_capabilities.max_geometry_shader_output_component_count);
477 glGetIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &gpu_capabilities.max_geometry_shader_total_output_component_count);
478 glGetIntegerv(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE, &gpu_capabilities.max_compute_shared_memory_size);
479 glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &gpu_capabilities.max_compute_work_group_invocations);
480 for(
unsigned i = 0; i < 3; ++i)
481 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT,
static_cast<GLuint
>(i), &gpu_capabilities.max_compute_work_group_count[i]);
482 for(
unsigned i = 0; i < 3; ++i)
483 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE,
static_cast<GLuint
>(i), &gpu_capabilities.max_compute_work_group_size[i]);
487 const GLubyte* renderer_c_string = glGetString(GL_RENDERER);
488 const GLubyte* glslversion_c_string = glGetString(GL_SHADING_LANGUAGE_VERSION);
490 std::cout <<
" vendor : " << vendor_c_string << std::endl;
491 if (renderer_c_string)
492 std::cout <<
" renderer : " << renderer_c_string << std::endl;
493 if (glslversion_c_string)
494 std::cout <<
" glslversion: " << glslversion_c_string << std::endl;
497 glEnable(GL_DEBUG_OUTPUT);
499 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
500 if (!check_gl_error(
"gl_context::configure() debug output"))
501 glDebugMessageCallback(debug_callback,
this);
506 glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
509 glEnable(GL_NORMALIZE);
512 glMatrixMode(GL_MODELVIEW);
529void gl_context::resize_gl()
563 bits |= GL_COLOR_BUFFER_BIT;
565 bits |= GL_DEPTH_BUFFER_BIT;
567 bits |= GL_STENCIL_BUFFER_BIT;
569 bits |= GL_ACCUM_BUFFER_BIT;
589void gl_context::init_render_pass()
594 glXSwapIntervalEXT(glXGetCurrentDisplay(), glXGetCurrentDrawable(),
enable_vsync ? 1 : 0);
597 glEnable(GL_FRAMEBUFFER_SRGB);
599 glDisable(GL_FRAMEBUFFER_SRGB);
618 last_render_pass_flags = current_render_pass_flags;
626 glEnable(GL_COLOR_MATERIAL);
633 glEnable(GL_NORMALIZE);
641 if (check_gl_error(
"gl_context::init_render_pass before init_frame"))
644 group* grp =
dynamic_cast<group*
>(
this);
646 single_method_action<drawable,void,cgv::render::context&> sma(*
this, &
drawable::init_frame,
true,
true);
650 if (check_gl_error(
"gl_context::init_render_pass after init_frame"))
673void gl_context::finish_render_pass()
680 format_callback_handler(std::ostream& _os) : os(_os)
698void gl_context::draw_textual_info()
700 if (show_help || show_stats) {
712 if (bg[0] + bg[1] + bg[2] < 1.5f)
720 if (grp && show_stats) {
726 if(bg[0] + bg[1] + bg[2] < 1.5f)
731 if (grp && show_help) {
742void gl_context::perform_screen_shot()
748 std::string ext(
"bmp");
754 cgv::media::image::image_writer wr(std::string(
"screen_shot.")+ext);
760void 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
763 glGetProgramiv(get_gl_id(prog.handle), GL_ACTIVE_UNIFORMS, &count);
764 for (
int i = 0; i < count; ++i) {
769 glGetActiveUniform(get_gl_id(prog.handle), i, 1000, &length, &size, &
type, name);
770 std::string name_str(name, length);
771 names.push_back(name_str);
773 sizes_ptr->push_back(size);
775 types_ptr->push_back(
type);
776 int loc = glGetUniformLocation(get_gl_id(prog.handle), name_str.c_str());
778 locations_ptr->push_back(loc);
780 std::cout << i <<
" at " << loc <<
" = " << name_str <<
":" <<
type <<
"[" << size <<
"]" << std::endl;
788 glGetProgramiv(get_gl_id(prog.handle), GL_ACTIVE_ATTRIBUTES, &count);
789 for (
int i = 0; i < count; ++i) {
794 glGetActiveAttrib(get_gl_id(prog.handle), i, 1000, &length, &size, &
type, name);
795 std::string name_str(name, length);
796 names.push_back(name_str);
798 sizes_ptr->push_back(size);
800 types_ptr->push_back(
type);
801 int loc = glGetAttribLocation(get_gl_id(prog.handle), name_str.c_str());
803 locations_ptr->push_back(loc);
805 std::cout << i <<
" at " << loc <<
" = " << name_str <<
":" <<
type <<
"[" << size <<
"]" << std::endl;
819 if (!prog.does_context_set_color())
821 int clr_loc = prog.get_color_index();
831 unsigned side = map_to_gl(MS_FRONT_AND_BACK);
836 gl_set_material_color(side, material.
emission, alpha, GL_EMISSION);
837 glMaterialf(side, GL_SHININESS, 1.0f / (material.
roughness + 1.0f / 128.0f));
846 mat.enable_textures(*
this);
852 mat.disable_textures(*
this);
857void gl_context::destruct_render_objects()
859 for (
unsigned i = 0; i < 4; ++i)
860 progs[i].destruct(*
this);
866 if (!texture_support) {
868 if (!progs[0].build_program(*
this,
"default.glpr")) {
869 error(
"could not build default shader program from default.glpr");
872 progs[0].specify_standard_uniforms(
true,
false,
false,
true);
873 progs[0].specify_standard_vertex_attribute_names(*
this,
true,
false,
false);
874 progs[0].allow_context_to_set_color(
true);
879 if (!progs[1].build_program(*
this,
"textured_default.glpr")) {
880 error(
"could not build default shader program with texture support from textured_default.glpr");
883 progs[1].set_uniform(*
this,
"texture", 0);
884 progs[1].specify_standard_uniforms(
true,
false,
false,
true);
885 progs[1].specify_standard_vertex_attribute_names(*
this,
true,
false,
true);
886 progs[1].allow_context_to_set_color(
true);
894 if (!texture_support) {
896 if (!progs[2].build_program(*
this,
"default_surface.glpr")) {
897 error(
"could not build surface shader program from default_surface.glpr");
900 progs[2].specify_standard_uniforms(
true,
true,
true,
true);
901 progs[2].specify_standard_vertex_attribute_names(*
this,
true,
true,
false);
902 progs[2].allow_context_to_set_color(
true);
907 if (!progs[3].build_program(*
this,
"textured_surface.glpr")) {
908 error(
"could not build surface shader program with texture support from textured_surface.glpr");
911 progs[3].specify_standard_uniforms(
true,
true,
true,
true);
912 progs[3].specify_standard_vertex_attribute_names(*
this,
true,
true,
true);
913 progs[3].allow_context_to_set_color(
true);
922 glGetIntegerv(GL_MAX_LIGHTS, &max_nr_lights);
923 for (GLint light_idx = 0; light_idx < max_nr_lights; ++light_idx) {
925 glDisable(GL_LIGHT0 + light_idx);
928 GLfloat col[4] = { 1,1,1,1 };
930 *(
rgb*)col = light.get_emission()*light.get_ambient_scale();
931 glLightfv(GL_LIGHT0 + light_idx, GL_AMBIENT, col);
932 *(
rgb*)col = light.get_emission();
933 glLightfv(GL_LIGHT0 + light_idx, GL_DIFFUSE, col);
934 *(
rgb*)col = light.get_emission();
935 glLightfv(GL_LIGHT0 + light_idx, GL_SPECULAR, col);
937 GLfloat pos[4] = { 0,0,0,light.get_type() == cgv::media::illum::LT_DIRECTIONAL ? 0.0f : 1.0f };
938 *(
vec3*)pos = light.get_position();
939 glLightfv(GL_LIGHT0 + light_idx, GL_POSITION, pos);
940 if (light.get_type() != cgv::media::illum::LT_DIRECTIONAL) {
941 glLightf(GL_LIGHT0 + light_idx, GL_CONSTANT_ATTENUATION, light.get_constant_attenuation());
942 glLightf(GL_LIGHT0 + light_idx, GL_LINEAR_ATTENUATION, light.get_linear_attenuation());
943 glLightf(GL_LIGHT0 + light_idx, GL_QUADRATIC_ATTENUATION, light.get_quadratic_attenuation());
946 glLightf(GL_LIGHT0 + light_idx, GL_CONSTANT_ATTENUATION, 1);
947 glLightf(GL_LIGHT0 + light_idx, GL_LINEAR_ATTENUATION, 0);
948 glLightf(GL_LIGHT0 + light_idx, GL_QUADRATIC_ATTENUATION, 0);
950 if (light.get_type() == cgv::media::illum::LT_SPOT) {
951 glLightf(GL_LIGHT0 + light_idx, GL_SPOT_CUTOFF, light.get_spot_cutoff());
952 glLightf(GL_LIGHT0 + light_idx, GL_SPOT_EXPONENT, light.get_spot_exponent());
953 glLightfv(GL_LIGHT0 + light_idx, GL_SPOT_DIRECTION, light.get_spot_direction().
data());
956 glLightf(GL_LIGHT0 + light_idx, GL_SPOT_CUTOFF, 180.0f);
957 glLightf(GL_LIGHT0 + light_idx, GL_SPOT_EXPONENT, 0.0f);
958 static float dir[3] = { 0,0,1 };
959 glLightfv(GL_LIGHT0 + light_idx, GL_SPOT_DIRECTION, dir);
961 glEnable(GL_LIGHT0 + light_idx);
969 double cyl_radius = length*aspect;
970 double cone_radius = rel_tip_radius*cyl_radius;
971 double cone_length = cone_radius/tip_aspect;
972 double cyl_length = length - cone_length;
984 mul_modelview_matrix(cgv::math::scale4(rel_tip_radius, rel_tip_radius, cone_length / cyl_length));
999 compute_rotation_axis_and_angle_from_vector_pair(vector, target, axis, angle);
1006 if ((start - end).length() < 1e-8) {
1007 error(
"ignored tesselate arrow called with start and end closer then 1e-8");
1013 tesselate_arrow((end-start).length(), aspect, rel_tip_radius, tip_aspect, res, edges);
1021 switch (l.get_type()) {
1022 case LT_DIRECTIONAL :
1028 cgv::math::translate4<double>(l.get_position())*
1029 cgv::math::scale4<double>(
vec3(0.3f*light_scale)));
1034 cgv::math::translate4<double>(l.get_position())*
1035 cgv::math::scale4<double>(
vec3(light_scale))
1039 float t = tan(l.get_spot_cutoff()*(
float)M_PI/180);
1040 if (l.get_spot_cutoff() > 45.0f)
1057 error(
"gl_context::announce_external_frame_buffer_change() called with empty frame buffer stack");
1061 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &fbo_id);
1068 glBindFramebuffer(GL_FRAMEBUFFER, get_gl_id(fbo_handle));
1077 error(
"gl_context::announce_external_viewport_change() called with empty window transformation stack");
1081 glGetIntegerv(GL_VIEWPORT, vp);
1088 glViewport(cgv_viewport_storage[0], cgv_viewport_storage[1], cgv_viewport_storage[2], cgv_viewport_storage[3]);
1101 glGetIntegerv(GL_VIEWPORT, vp);
1105 glMatrixMode(GL_PROJECTION);
1108 glOrtho(vp[0], vp[0]+vp[2], vp[1], vp[1]+vp[3], -1, 1);
1110 glMatrixMode(GL_MODELVIEW);
1136 if (w < 1 || h < 1) {
1142 if (w < 1 || h < 1) {
1144 glGetIntegerv(GL_VIEWPORT,vp);
1145 w = w < 1 ? vp[2] : w;
1146 h = h < 1 ? vp[3] : h;
1149 GLuint gl_type = map_to_gl(
type);
1154 GLuint gl_format = GL_DEPTH_COMPONENT;
1156 gl_format = GL_STENCIL_INDEX;
1158 gl_format = map_to_gl(cf);
1165 GLenum gl_buffer = GL_BACK;
1166 if (buffer_type < FB_BACK)
1167 gl_buffer = GL_COLOR_ATTACHMENT0+buffer_type;
1169 switch (buffer_type) {
1170 case FB_FRONT : gl_buffer = GL_FRONT;
break;
1171 case FB_BACK : gl_buffer = GL_BACK;
break;
1172 case FB_FRONT_LEFT : gl_buffer = GL_FRONT_LEFT;
break;
1173 case FB_FRONT_RIGHT : gl_buffer = GL_FRONT_RIGHT;
break;
1174 case FB_BACK_LEFT : gl_buffer = GL_BACK_LEFT;
break;
1175 case FB_BACK_RIGHT : gl_buffer = GL_BACK_RIGHT;
break;
1189 GLint old_buffer, old_pack;
1190 glGetIntegerv(GL_READ_BUFFER, &old_buffer);
1191 glGetIntegerv(GL_PACK_ALIGNMENT, &old_pack);
1192 glReadBuffer(gl_buffer);
1194 glReadPixels(x,y,w,h,gl_format,gl_type,dv.
get_ptr<
void>());
1195 glReadBuffer(old_buffer);
1196 glPixelStorei(GL_PACK_ALIGNMENT, old_pack);
1202void render_vertex(
int k,
const float* vertices,
const float* normals,
const float* tex_coords,
1203 const int* vertex_indices,
const int* normal_indices,
const int* tex_coord_indices,
bool flip_normals)
1205 if (normals && normal_indices) {
1207 float n[3] = { -normals[3*normal_indices[k]],-normals[3*normal_indices[k]+1],-normals[3*normal_indices[k]+2] };
1211 glNormal3fv(normals+3*normal_indices[k]);
1213 if (tex_coords && tex_coord_indices)
1214 glTexCoord2fv(tex_coords+2*tex_coord_indices[k]);
1215 glVertex3fv(vertices+3*vertex_indices[k]);
1218attribute_array_binding*& get_aab_ptr()
1220 static attribute_array_binding* aab_ptr = 0;
1224vertex_buffer*& get_vbo_ptr()
1226 static vertex_buffer* vbo_ptr = 0;
1233 if (!prog_ptr || prog_ptr->get_position_index() == -1)
1236 attribute_array_binding*& aab_ptr = get_aab_ptr();
1239 if (prog_ptr->get_normal_index() != -1 && normals && normal_indices)
1241 if (prog_ptr->get_texcoord_index() != -1 && tex_coords && tex_coord_indices)
1246 aab_ptr->
disable_array(*
this, prog_ptr->get_position_index());
1247 if (prog_ptr->get_normal_index() != -1 && normals && normal_indices)
1249 if (prog_ptr->get_texcoord_index() != -1 && tex_coords && tex_coord_indices)
1251 vertex_buffer*& vbo_ptr = get_vbo_ptr();
1260 const float* vertices,
const float* normals,
const float* tex_coords,
1261 const int* vertex_indices,
const int* normal_indices,
const int* tex_coord_indices,
bool flip_normals)
const
1265 if (!prog_ptr || prog_ptr->get_position_index() == -1)
1267 P.resize(nr_vertices);
1268 for (i = 0; i < nr_vertices; ++i)
1269 P[i] = *
reinterpret_cast<const vec3*
>(vertices + 3 * vertex_indices[i]);
1271 if (prog_ptr->get_normal_index() != -1 && normals && normal_indices) {
1272 N.resize(nr_vertices);
1273 for (i = 0; i < nr_vertices; ++i) {
1274 N[i] = *
reinterpret_cast<const vec3*
>(normals + 3 * normal_indices[i]);
1279 if (prog_ptr->get_texcoord_index() != -1 && tex_coords && tex_coord_indices) {
1280 T.resize(nr_vertices);
1281 for (i = 0; i < nr_vertices; ++i)
1282 T[i] = *
reinterpret_cast<const vec2*
>(tex_coords + 2 * tex_coord_indices[i]);
1285 attribute_array_binding*& aab_ptr = get_aab_ptr();
1287 aab_ptr =
new attribute_array_binding();
1293 if (prog_ptr->get_normal_index() != -1) {
1294 if (normals && normal_indices) {
1301 if (prog_ptr->get_texcoord_index() != -1) {
1302 if (tex_coords && tex_coord_indices) {
1311 vertex_buffer*& vbo_ptr = get_vbo_ptr();
1313 vbo_ptr =
new vertex_buffer();
1316 vbo_ptr->
create(*
this, P.size() *
sizeof(
vec3) + N.size() *
sizeof(
vec3) + T.size() *
sizeof(
vec2));
1318 size_t nml_off = P.size() *
sizeof(
vec3);
1319 size_t tex_off = nml_off;
1322 tex_off += N.size() *
sizeof(
vec3);
1327 type_descriptor td3 = element_descriptor_traits<vec3>::get_type_descriptor(P.front());
1328 aab_ptr->
set_attribute_array(*
this, prog_ptr->get_position_index(), td3, *vbo_ptr, 0, P.size());
1329 aab_ptr->
enable_array(*
this, prog_ptr->get_position_index());
1330 if (prog_ptr->get_normal_index() != -1) {
1331 if (normals && normal_indices) {
1332 aab_ptr->
set_attribute_array(*
this, prog_ptr->get_normal_index(), td3, *vbo_ptr, nml_off, N.size());
1333 aab_ptr->
enable_array(*
this, prog_ptr->get_normal_index());
1336 aab_ptr->
disable_array(*
this, prog_ptr->get_normal_index());
1338 if (prog_ptr->get_texcoord_index() != -1) {
1339 if (tex_coords && tex_coord_indices) {
1340 type_descriptor td2 = element_descriptor_traits<vec2>::get_type_descriptor(T.front());
1341 aab_ptr->
set_attribute_array(*
this, prog_ptr->get_texcoord_index(), td2, *vbo_ptr, tex_off, T.size());
1342 aab_ptr->
enable_array(*
this, prog_ptr->get_texcoord_index());
1345 aab_ptr->
disable_array(*
this, prog_ptr->get_texcoord_index());
1354 const float* vertices,
const float* normals,
const float* tex_coords,
1355 const int* vertex_indices,
const int* normal_indices,
const int* tex_coord_indices,
1356 int nr_faces,
int face_degree,
bool flip_normals)
const
1360 for (
int i = 0; i < nr_faces; ++i) {
1361 glBegin(GL_LINE_LOOP);
1362 for (
int j = 0; j < face_degree; ++j, ++k)
1363 render_vertex(k, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals);
1368 unsigned nr_vertices = face_degree * nr_faces;
1369 std::vector<vec3> P, N;
1370 std::vector<vec2> T;
1371 if (!
prepare_attributes(P, N, T, nr_vertices, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals))
1373 for (
int i = 0; i < nr_faces; ++i)
1374 glDrawArrays(GL_LINE_LOOP, i*face_degree, face_degree);
1379void gl_context::draw_elements_void(GLenum mode,
size_t total_count, GLenum
type,
size_t type_size,
const void* indices)
const
1381 ensure_configured();
1384 while (drawn < total_count) {
1385 size_t count = total_count - drawn;
1386 if (count > max_nr_indices)
1387 count = size_t(max_nr_indices);
1388 glDrawElements(mode, GLsizei(count),
type, index_ptr + drawn * type_size);
1393size_t max_nr_indices, max_nr_vertices;
1394void gl_context::ensure_configured()
const
1396 if (max_nr_indices != 0)
1398 glGetInteger64v(GL_MAX_ELEMENTS_INDICES,
reinterpret_cast<GLint64*
>(&max_nr_indices));
1399 glGetInteger64v(GL_MAX_ELEMENTS_VERTICES,
reinterpret_cast<GLint64*
>(&max_nr_vertices));
1404 const float* vertices,
const float* normals,
const float* tex_coords,
1405 const int* vertex_indices,
const int* normal_indices,
const int* tex_coord_indices,
1406 int nr_faces,
int face_degree,
bool is_fan,
bool flip_normals)
const
1408 int s = face_degree - 2;
1410 std::vector<GLuint> I;
1411 I.push_back(0); I.push_back(1);
1412 for (i = 0; i < nr_faces; ++i) {
1414 I.push_back(k - 1); I.push_back(k);
1415 I.push_back(0); I.push_back(k);
1419 I.push_back(k - 1); I.push_back(k);
1420 I.push_back(k - 2); I.push_back(k);
1423 I.push_back(k - 1); I.push_back(k + 1);
1424 I.push_back(k - 2); I.push_back(k);
1425 I.push_back(k); I.push_back(k + 1);
1433 render_vertex(j, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals);
1437 unsigned nr_vertices = 2 + (face_degree - 2) * nr_faces;
1438 std::vector<vec3> P, N;
1439 std::vector<vec2> T;
1440 if (!
prepare_attributes(P, N, T, nr_vertices, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals))
1442 draw_elements(GL_LINES, I.size(), &I[0]);
1447 const float* vertices,
const float* normals,
const float* tex_coords,
1448 const int* vertex_indices,
const int* normal_indices,
const int* tex_coord_indices,
1449 int nr_faces,
int face_degree,
bool flip_normals)
const
1453 if (face_degree < 5)
1454 glBegin(face_degree == 3 ? GL_TRIANGLES : GL_QUADS);
1455 for (
int i = 0; i < nr_faces; ++i) {
1456 if (face_degree >= 5)
1457 glBegin(GL_POLYGON);
1458 for (
int j = 0; j < face_degree; ++j, ++k)
1459 render_vertex(k, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals);
1460 if (face_degree >= 5)
1463 if (face_degree < 5)
1467 unsigned nr_vertices = face_degree * nr_faces;
1468 std::vector<vec3> P, N;
1469 std::vector<vec2> T;
1470 if (!
prepare_attributes(P, N, T, nr_vertices, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals))
1482 if (face_degree == 3)
1483 glDrawArrays(GL_TRIANGLES, 0, nr_vertices);
1485 for (
int i = 0; i < nr_faces; ++i) {
1486 glDrawArrays(GL_TRIANGLE_FAN, i*face_degree, face_degree);
1493 const float* vertices,
const float* normals,
const float* tex_coords,
1494 const int* vertex_indices,
const int* normal_indices,
const int* tex_coord_indices,
1495 int nr_faces,
int face_degree,
bool is_fan,
bool flip_normals)
const
1497 int s = face_degree - 2;
1500 glBegin(face_degree == 3 ? (is_fan ? GL_TRIANGLE_FAN : GL_TRIANGLE_STRIP) : GL_QUAD_STRIP);
1501 render_vertex(0, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals);
1502 render_vertex(1, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals);
1503 for (
int i = 0; i < nr_faces; ++i)
1504 for (
int j = 0; j < s; ++j, ++k)
1505 render_vertex(k, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals);
1509 unsigned nr_vertices = 2 + (face_degree-2) * nr_faces;
1510 std::vector<vec3> P, N;
1511 std::vector<vec2> T;
1512 if (!
prepare_attributes(P, N, T, nr_vertices, vertices, normals, tex_coords, vertex_indices, normal_indices, tex_coord_indices, flip_normals))
1514 glDrawArrays(is_fan ? GL_TRIANGLE_FAN : GL_TRIANGLE_STRIP, 0, nr_vertices);
1520 glEnable(GL_DEPTH_TEST);
1522 glDisable(GL_DEPTH_TEST);
1523 glDepthFunc(map_to_gl(state.
test_func));
1528 glDepthFunc(map_to_gl(
func));
1533 glEnable(GL_DEPTH_TEST);
1538 glDisable(GL_DEPTH_TEST);
1543 switch(culling_mode) {
1545 glDisable(GL_CULL_FACE);
1548 glEnable(GL_CULL_FACE);
1549 glCullFace(GL_BACK);
1552 glEnable(GL_CULL_FACE);
1553 glCullFace(GL_FRONT);
1565 glDisable(GL_BLEND);
1566 if(GLEW_EXT_blend_func_separate) {
1567 glBlendFuncSeparate(
1580 glBlendFunc(map_to_gl(src_factor), map_to_gl(dst_factor));
1585 glBlendFuncSeparate(
1586 map_to_gl(src_color_factor),
1587 map_to_gl(dst_color_factor),
1588 map_to_gl(src_alpha_factor),
1589 map_to_gl(dst_alpha_factor)
1600 glDisable(GL_BLEND);
1616 glDepthMask(map_to_gl(flag));
1622 map_to_gl(flags[0]),
1623 map_to_gl(flags[1]),
1624 map_to_gl(flags[2]),
1635 glGetDoublev(GL_MODELVIEW_MATRIX, V);
1636 return dmat4(4,4,V);
1639 return identity4<double>();
1648 glGetDoublev(GL_PROJECTION_MATRIX, P);
1649 return dmat4(4,4,P);
1651 if (projection_matrix_stack.empty())
1652 return identity4<double>();
1653 return projection_matrix_stack.top();
1659 update_window_transformation_array();
1662void gl_context::update_window_transformation_array()
1665 if (wta.size() == 1) {
1666 const ivec4& viewport = wta.front().viewport;
1667 const dvec2& depth_range = wta.front().depth_range;
1668 glViewport(viewport[0], viewport[1], (GLsizei)viewport[2], (GLsizei)viewport[3]);
1669 glScissor(viewport[0], viewport[1], (GLsizei)viewport[2], (GLsizei)viewport[3]);
1670 glDepthRange(depth_range[0], depth_range[1]);
1673 for (GLuint array_index = 0; array_index < (GLuint)wta.size(); ++array_index) {
1674 const ivec4& viewport = wta[array_index].viewport;
1675 const dvec2& depth_range = wta[array_index].depth_range;
1676 glViewportIndexedf(array_index, (GLfloat)viewport[0], (GLfloat)viewport[1], (GLfloat)viewport[2], (GLfloat)viewport[3]);
1677 glScissorIndexed(array_index, viewport[0], viewport[1], (GLsizei)viewport[2], (GLsizei)viewport[3]);
1678 glDepthRangeIndexed(array_index, (GLclampd)depth_range[0], (GLclampd)depth_range[1]);
1685 GLint max_value = 1;
1686 if (GLEW_VERSION_4_1)
1687 glGetIntegerv(GL_MAX_VIEWPORTS, &max_value);
1697 update_window_transformation_array();
1699 if (array_index < 1) {
1700 glViewport(viewport[0], viewport[1], (GLsizei)viewport[2], (GLsizei)viewport[3]);
1701 glScissor(viewport[0], viewport[1], (GLsizei)viewport[2], (GLsizei)viewport[3]);
1704 glViewportIndexedf(array_index, (GLfloat)viewport[0], (GLfloat)viewport[1], (GLfloat)viewport[2], (GLfloat)viewport[3]);
1705 glScissorIndexed(array_index, viewport[0], viewport[1], (GLsizei)viewport[2], (GLsizei)viewport[3]);
1716 update_window_transformation_array();
1718 if (array_index < 1)
1719 glDepthRange(depth_range[0], depth_range[1]);
1721 glDepthRangeIndexed(array_index, (GLclampd)depth_range[0], (GLclampd)depth_range[1]);
1726gl_context::dmat4 gl_context::get_device_matrix() const
1729 glGetIntegerv(GL_VIEWPORT, vp);
1731 D(0, 0) = 0.5*vp[2];
1732 D(0, 3) = 0.5*vp[2] + vp[0];
1733 D(1, 1) = -0.5*vp[3]; // flip y-coordinate
1734 D(1, 3) = get_height() - 0.5*vp[3] - vp[1];
1745 glGetIntegerv(GL_MATRIX_MODE, &mm);
1746 glMatrixMode(GL_MODELVIEW);
1747 glLoadMatrixd(V.
data());
1757 glGetIntegerv(GL_MATRIX_MODE, &mm);
1758 glMatrixMode(GL_PROJECTION);
1759 glLoadMatrixd(P.
data());
1773 glReadPixels(x_window, y_window, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z_window);
1797 render_component& rc,
const std::vector<cgv::data::data_view>* palettes)
const
1799 GLuint& gl_format = (GLuint&)rc.internal_format;
1801 if (debug_texture_format_matching)
1802 std::cout <<
"Texture Format Search for '" << cf <<
"':" << std::endl;
1804 if (debug_texture_format_matching)
1805 std::cout <<
"found: '" << best_cf <<
"' = " << std::hex << gl_format << std::endl;
1809std::string gl_error_to_string(GLenum eid) {
1811 case GL_NO_ERROR:
return "";
1812 case GL_INVALID_ENUM:
return "invalid enum";
1813 case GL_INVALID_VALUE:
return "invalid value";
1814 case GL_INVALID_OPERATION:
return "invalid operation";
1815 case GL_INVALID_FRAMEBUFFER_OPERATION:
return "invalid framebuffe";
1816 case GL_OUT_OF_MEMORY:
return "out of memory";
1817 case GL_STACK_UNDERFLOW:
return "stack underflow";
1818 case GL_STACK_OVERFLOW:
return "stack overflow";
1820 return "undefined error (id: " + std::to_string(eid) +
")";
1825std::string gl_error() {
1826 GLenum eid = glGetError();
1829 while (glGetError());
1830 return gl_error_to_string(eid);
1833bool gl_context::check_gl_error(
const std::string& where,
const cgv::render::render_component* rc)
const
1835 GLenum eid = glGetError();
1836 if (eid == GL_NO_ERROR)
1838 std::string error_string = where +
": " + gl_error_to_string(eid);
1839 error(error_string, rc);
1840 while (glGetError());
1844bool gl_context::check_texture_support(
TextureType tt,
const std::string& where,
const cgv::render::render_component* rc)
const
1848 if (!GLEW_VERSION_1_2) {
1849 error(where +
": 3D texture not supported", rc);
1854 if (!GLEW_VERSION_1_3) {
1855 error(where +
": cubemap texture not supported", rc);
1864bool gl_context::check_shader_support(
ShaderType st,
const std::string& where,
const cgv::render::render_component* rc)
const
1869 if(GLEW_VERSION_4_5) {
1870 if(GLEW_NV_mesh_shader || GLEW_EXT_mesh_shader)
1873 error(where +
": task and mesh shaders require support of the GL_NV_mesh_shader or GLSL_EXT_mesh_shader extensions", rc);
1877 error(where +
": task and mesh shaders are only supported starting from OpenGL version 4.5", rc);
1881 if (GLEW_VERSION_4_3)
1884 error(where+
": compute shaders are only supported starting from OpenGL version 4.3", rc);
1887 case ST_TESS_CONTROL:
1888 case ST_TESS_EVALUATION:
1889 if (GLEW_VERSION_4_0)
1892 error(where+
": tessellation shaders are only supported starting from OpenGL version 4.0", rc);
1896 if (GLEW_VERSION_3_2)
1899 error(where +
": geometry shaders are only supported starting from OpenGL version 3.2", rc);
1903 if (GLEW_VERSION_2_0)
1906 error(where +
": shaders are only supported starting from OpenGL version 2.0", rc);
1912bool gl_context::check_fbo_support(
const std::string& where,
const cgv::render::render_component* rc)
const
1914 if (!GLEW_VERSION_3_0) {
1915 error(where +
": framebuffer objects not supported", rc);
1921GLuint gl_context::texture_generate(texture_base& tb)
const
1923 if (!check_texture_support(tb.tt,
"gl_context::texture_generate", &tb))
1924 return get_gl_id(0);
1925 GLuint tex_id = get_gl_id(0);
1926 glGenTextures(1, &tex_id);
1927 if (glGetError() == GL_INVALID_OPERATION)
1928 error(
"gl_context::texture_generate: attempt to create texture inside glBegin-glEnd-block", &tb);
1932GLuint gl_context::texture_bind(
TextureType tt, GLuint tex_id)
const
1935 glGetIntegerv(get_tex_bind(tt), &tmp_id);
1936 glBindTexture(get_tex_dim(tt), tex_id);
1940void gl_context::texture_unbind(
TextureType tt, GLuint tmp_id)
const
1942 glBindTexture(get_tex_dim(tt), tmp_id);
1945bool gl_context::texture_create(texture_base& tb, cgv::data::data_format& df)
const
1947 GLuint gl_format = (
const GLuint&) tb.internal_format;
1949 if (tb.tt == TT_UNDEF)
1951 GLuint tex_id = texture_generate(tb);
1952 if (tex_id == get_gl_id(0))
1954 GLuint tmp_id = texture_bind(tb.tt, tex_id);
1957 unsigned int transfer_format = map_to_gl(df.get_standard_component_format(), df.get_integer_interpretation());
1958 if (transfer_format == -1) {
1959 error(
"could not determine transfer format", &tb);
1964 glTexImage1D(GL_TEXTURE_1D, 0,
1965 gl_format, GLsizei(df.get_width()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1968 glTexImage2D(GL_TEXTURE_1D_ARRAY, 0,
1969 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1972 glTexImage2D(GL_TEXTURE_2D, 0, gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1974 case TT_MULTISAMPLE_2D:
1975 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));
1978 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);
1980 case TT_MULTISAMPLE_2D_ARRAY:
1981 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));
1984 glTexImage3D(GL_TEXTURE_3D, 0,
1985 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), GLsizei(df.get_depth()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1988 glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0,
1989 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1990 glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0,
1991 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1992 glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0,
1993 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1994 glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0,
1995 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1996 glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0,
1997 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
1998 glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0,
1999 gl_format, GLsizei(df.get_width()), GLsizei(df.get_height()), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
2003 if (check_gl_error(
"gl_context::texture_create", &tb)) {
2004 glDeleteTextures(1, &tex_id);
2005 texture_unbind(tb.tt, tmp_id);
2009 texture_unbind(tb.tt, tmp_id);
2010 tb.have_mipmaps =
false;
2011 tb.handle = get_handle(tex_id);
2015bool gl_context::texture_create(
2017 cgv::data::data_format& target_format,
2018 const cgv::data::const_data_view& data,
2019 int level,
int cube_side,
int num_array_layers,
const std::vector<cgv::data::data_view>* palettes)
const
2022 GLuint gl_tex_format = (
const GLuint&) tb.internal_format;
2025 tb.tt = (
TextureType)data.get_format()->get_nr_dimensions();
2026 if(cube_side > -1) {
2029 }
else if(num_array_layers != 0) {
2030 if(num_array_layers < 0) {
2032 unsigned n_dims = data.get_format()->get_nr_dimensions();
2034 tb.tt = TT_1D_ARRAY;
2036 tb.tt = TT_2D_ARRAY;
2039 case TT_1D: tb.tt = TT_1D_ARRAY;
break;
2040 case TT_2D: tb.tt = TT_2D_ARRAY;
break;
2041 case TT_3D: tb.tt = TT_2D_ARRAY;
break;
2049 if (tb.is_created())
2050 tex_id = get_gl_id(tb.handle);
2052 tex_id = texture_generate(tb);
2053 if (tex_id == get_gl_id(0))
2055 tb.handle = get_handle(tex_id);
2059 GLuint tmp_id = texture_bind(tb.tt, tex_id);
2062 tb.have_mipmaps =
load_texture(data, gl_tex_format, level, cube_side, num_array_layers, palettes);
2063 bool result = !check_gl_error(
"gl_context::texture_create", &tb);
2065 texture_unbind(tb.tt, tmp_id);
2069bool gl_context::texture_create_from_buffer(
2071 cgv::data::data_format& df,
2072 int x,
int y,
int level)
const
2074 GLuint gl_format = (
const GLuint&) tb.internal_format;
2077 if (tb.tt != TT_2D) {
2078 tb.last_error =
"texture creation from buffer only possible for 2d textures";
2082 if (tb.is_created())
2083 tex_id = get_gl_id(tb.handle);
2085 tex_id = texture_generate(tb);
2086 if (tex_id == get_gl_id(0))
2088 tb.handle = get_handle(tex_id);
2090 GLuint tmp_id = texture_bind(tb.tt, tex_id);
2093 bool gen_mipmap = level == -1;
2097 glCopyTexImage2D(GL_TEXTURE_2D, level, gl_format, x, y, GLsizei(df.get_width()), GLsizei(df.get_height()), 0);
2098 bool result =
false;
2099 std::string error_string(
"gl_context::texture_create_from_buffer: ");
2100 switch (glGetError()) {
2104 case GL_INVALID_ENUM :
2105 error_string +=
"target was not an accepted value.";
2107 case GL_INVALID_VALUE :
2108 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"
2109 "or border was not zero or 1.\n"
2110 "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.";
2112 case GL_INVALID_OPERATION :
2113 error_string +=
"glCopyTexImage2D was called between a call to glBegin and the corresponding call to glEnd.";
2116 error_string += gl_error_to_string(glGetError());
2119 texture_unbind(tb.tt, tmp_id);
2121 error(error_string, &tb);
2124 result = texture_generate_mipmaps(tb, tb.tt == TT_CUBEMAP ? 2 : (
int)tb.tt);
2129bool gl_context::texture_replace(
2131 int x,
int y,
int z,
2132 const cgv::data::const_data_view& data,
2133 int level,
const std::vector<cgv::data::data_view>* palettes)
const
2135 if (!tb.is_created()) {
2136 error(
"gl_context::texture_replace: attempt to replace in not created texture", &tb);
2140 unsigned int dim = 1;
2147 if (tb.tt == TT_CUBEMAP) {
2149 error(
"gl_context::texture_replace: replace on cubemap without the side defined", &tb);
2152 if (z < 0 || z > 5) {
2153 error(
"gl_context::texture_replace: replace on cubemap with invalid side specification", &tb);
2159 error(
"gl_context::texture_replace: replace on texture with invalid position specification", &tb);
2165 GLuint tmp_id = texture_bind(tb.tt, get_gl_id(tb.handle));
2166 tb.have_mipmaps =
replace_texture(data, level, x, y, z, palettes) || tb.have_mipmaps;
2167 bool result = !check_gl_error(
"gl_context::texture_replace", &tb);
2168 texture_unbind(tb.tt, tmp_id);
2172bool gl_context::texture_replace_from_buffer(
2174 int x,
int y,
int z,
2175 int x_buffer,
int y_buffer,
2176 unsigned int width,
unsigned int height,
2179 if (!tb.is_created()) {
2180 error(
"gl_context::texture_replace_from_buffer: attempt to replace in not created texture", &tb);
2184 unsigned int dim = 2;
2189 if (tb.tt == TT_CUBEMAP) {
2191 error(
"gl_context::texture_replace_from_buffer: replace on cubemap without the side defined", &tb);
2194 if (z < 0 || z > 5) {
2195 error(
"gl_context::texture_replace_from_buffer: replace on cubemap without invalid side specification", &tb);
2201 tb.last_error =
"replace on texture with invalid position specification";
2206 bool gen_mipmap = level == -1;
2211 GLuint tmp_id = texture_bind(tb.tt, get_gl_id(tb.handle));
2213 case TT_2D : glCopyTexSubImage2D(GL_TEXTURE_2D, level, x, y, x_buffer, y_buffer, width, height);
break;
2214 case TT_3D : glCopyTexSubImage3D(GL_TEXTURE_3D, level, x, y, z, x_buffer, y_buffer, width, height);
break;
2215 case TT_CUBEMAP : glCopyTexSubImage2D(
get_gl_cube_map_target(z), level, x, y, x_buffer, y_buffer, width, height);
2218 bool result = !check_gl_error(
"gl_context::texture_replace_from_buffer", &tb);
2219 texture_unbind(tb.tt, tmp_id);
2221 if (result && gen_mipmap)
2222 result = texture_generate_mipmaps(tb, tb.tt == TT_CUBEMAP ? 2 : (
int)tb.tt);
2227bool gl_context::texture_copy_back(
const texture_base& tb,
int level, cgv::data::data_view& dv)
const
2229 if(!tb.is_created()) {
2230 error(
"gl_context::texture_copy_back: attempt to copy from not created texture", &tb);
2234 GLuint tmp_id = texture_bind(tb.tt, get_gl_id(tb.handle));
2237 bool result = !check_gl_error(
"gl_context::texture_copy_back", &tb);
2238 texture_unbind(tb.tt, tmp_id);
2243bool gl_context::texture_create_mipmaps(texture_base& tb, cgv::data::data_format& df)
const
2245 GLuint gl_format = (
const GLuint&)tb.internal_format;
2248 unsigned int transfer_format = map_to_gl(df.get_standard_component_format(), df.get_integer_interpretation());
2250 if(transfer_format == -1) {
2251 error(
"could not determine transfer format", &tb);
2256 uvec3 size(
unsigned(df.get_width()),
unsigned(df.get_height()),
unsigned(df.get_depth()));
2258 unsigned max_size = cgv::math::max_value(size);
2259 unsigned num_levels = 1 +
static_cast<unsigned>(log2(
static_cast<float>(max_size)));
2262 std::vector<uvec3> level_sizes(num_levels);
2263 level_sizes[0] = size;
2265 for(
unsigned level = 1; level < num_levels; ++level) {
2266 uvec3 level_size = level_sizes[level - 1];
2267 level_size = level_size / 2u;
2268 level_size = cgv::math::max(level_size,
uvec3(1u));
2269 level_sizes[level] = level_size;
2272 GLuint tmp_id = texture_bind(tb.tt, get_gl_id(tb.handle));
2278 for(
unsigned level = 1; level < num_levels; ++level) {
2279 uvec3 level_size = level_sizes[level];
2280 glTexImage1D(GL_TEXTURE_1D, level, gl_format, level_size.
x(), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
2285 error(
"create mipmaps not implemented for 1D array textures", &tb);
2289 for(
unsigned level = 1; level < num_levels; ++level) {
2290 uvec3 level_size = level_sizes[level];
2291 glTexImage2D(GL_TEXTURE_2D, level, gl_format, level_size.
x(), level_size.
y(), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
2294 case TT_MULTISAMPLE_2D:
2296 error(
"create mipmaps not implemented for 2D multisample textures", &tb);
2301 error(
"create mipmaps not implemented for 2D array textures", &tb);
2304 case TT_MULTISAMPLE_2D_ARRAY:
2306 error(
"create mipmaps not implemented for 2D multisample array textures", &tb);
2310 for(
unsigned level = 1; level < num_levels; ++level) {
2311 uvec3 level_size = level_sizes[level];
2312 glTexImage3D(GL_TEXTURE_3D, level, gl_format, level_size.
x(), level_size.
y(), level_size.
z(), 0, transfer_format, GL_UNSIGNED_BYTE, 0);
2329 error(
"create mipmaps not implemented for cubemap textures", &tb);
2335 if(check_gl_error(
"gl_context::texture_create_mipmaps", &tb))
2339 tb.have_mipmaps =
true;
2341 texture_unbind(tb.tt, tmp_id);
2345bool gl_context::texture_generate_mipmaps(texture_base& tb,
unsigned int dim)
const
2347 GLuint tmp_id = texture_bind(tb.tt,get_gl_id(tb.handle));
2349 bool is_array = tb.tt == TT_1D_ARRAY || tb.tt == TT_2D_ARRAY;
2350 bool is_cubemap = tb.tt == TT_CUBEMAP;
2351 std::string error_string;
2354 tb.have_mipmaps =
true;
2356 error(std::string(
"gl_context::texture_generate_mipmaps: ") + error_string);
2358 texture_unbind(tb.tt, tmp_id);
2362bool gl_context::texture_destruct(texture_base& tb)
const
2364 if (!tb.is_created()) {
2365 error(
"gl_context::texture_destruct: attempt to destruct not created texture", &tb);
2368 GLuint tex_id = get_gl_id(tb.handle);
2369 glDeleteTextures(1, &tex_id);
2370 bool result = !check_gl_error(
"gl_context::texture_destruct", &tb);
2376bool gl_context::texture_set_state(
const texture_base& tb)
const
2378 if (tb.tt == TT_UNDEF) {
2379 error(
"gl_context::texture_set_state: attempt to set state on texture without type", &tb);
2382 GLuint tex_id = (GLuint&) tb.handle - 1;
2384 error(
"gl_context::texture_set_state: attempt of setting texture state of not created texture", &tb);
2387 GLint tmp_id = texture_bind(tb.tt, tex_id);
2389 if (tb.tt != TT_MULTISAMPLE_2D && tb.tt != TT_MULTISAMPLE_2D_ARRAY) {
2390 glTexParameteri(get_tex_dim(tb.tt), GL_TEXTURE_MIN_FILTER, map_to_gl(tb.min_filter));
2391 glTexParameteri(get_tex_dim(tb.tt), GL_TEXTURE_MAG_FILTER, map_to_gl(tb.mag_filter));
2392 if (tb.min_filter == TF_ANISOTROP)
2393 glTexParameterf(get_tex_dim(tb.tt), GL_TEXTURE_MAX_ANISOTROPY_EXT, tb.anisotropy);
2395 glTexParameterf(get_tex_dim(tb.tt), GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
2396 glTexParameteri(get_tex_dim(tb.tt), GL_TEXTURE_COMPARE_FUNC, map_to_gl(tb.compare_function));
2397 glTexParameteri(get_tex_dim(tb.tt), GL_TEXTURE_COMPARE_MODE, (tb.use_compare_function ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE));
2399 glTexParameterf(get_tex_dim(tb.tt), GL_TEXTURE_PRIORITY, tb.priority);
2400 glTexParameterfv(get_tex_dim(tb.tt), GL_TEXTURE_BORDER_COLOR, tb.border_color);
2402 glTexParameteri(get_tex_dim(tb.tt), GL_TEXTURE_WRAP_S, map_to_gl(tb.wrap_s));
2404 glTexParameteri(get_tex_dim(tb.tt), GL_TEXTURE_WRAP_T, map_to_gl(tb.wrap_t));
2406 glTexParameteri(get_tex_dim(tb.tt), GL_TEXTURE_WRAP_R, map_to_gl(tb.wrap_r));
2409 bool result = !check_gl_error(
"gl_context::texture_set_state", &tb);
2410 texture_unbind(tb.tt, tmp_id);
2414bool gl_context::texture_enable(texture_base& tb,
int tex_unit,
unsigned int dim)
const
2416 if (dim < 1 || dim > 3) {
2417 error(
"gl_context::texture_enable: invalid texture dimension", &tb);
2420 GLuint tex_id = (GLuint&) tb.handle - 1;
2422 error(
"gl_context::texture_enable: texture not created", &tb);
2425 if (tex_unit >= 0) {
2426 if (!GLEW_VERSION_1_3) {
2427 error(
"gl_context::texture_enable: multi texturing not supported", &tb);
2430 glActiveTexture(GL_TEXTURE0+tex_unit);
2432 GLint& old_binding = (GLint&) tb.user_data;
2433 glGetIntegerv(get_tex_bind(tb.tt), &old_binding);
2435 glBindTexture(get_tex_dim(tb.tt), tex_id);
2439 bool result = !check_gl_error(
"gl_context::texture_enable", &tb);
2441 glActiveTexture(GL_TEXTURE0);
2445bool gl_context::texture_disable(
2447 int tex_unit,
unsigned int dim)
const
2449 if (dim < 1 || dim > 3) {
2450 error(
"gl_context::texture_disable: invalid texture dimension", &tb);
2453 if (tex_unit == -2) {
2454 error(
"gl_context::texture_disable: invalid texture unit", &tb);
2457 GLuint old_binding = (
const GLuint&) tb.user_data;
2460 glActiveTexture(GL_TEXTURE0+tex_unit);
2464 bool result = !check_gl_error(
"gl_context::texture_disable", &tb);
2465 glBindTexture(get_tex_dim(tb.tt), old_binding);
2467 glActiveTexture(GL_TEXTURE0);
2471bool gl_context::texture_bind_as_image(texture_base& tb,
int tex_unit,
int level,
bool bind_array,
int layer,
AccessType access)
const
2473 GLuint tex_id = (GLuint&)tb.handle - 1;
2475 error(
"gl_context::texture_enable: texture not created", &tb);
2479 if(!GLEW_VERSION_4_2) {
2480 error(
"gl_context::texture_bind_as_image: image textures not supported", &tb);
2484 GLuint gl_format = (
const GLuint&)tb.internal_format;
2485 glBindImageTexture(tex_unit, tex_id, level, map_to_gl(bind_array), layer, map_to_gl(access), gl_format);
2487 bool result = !check_gl_error(
"gl_context::texture_bind_as_image", &tb);
2491bool gl_context::render_buffer_create(render_buffer_base& rb, cgv::data::component_format& cf,
int& _width,
int& _height)
const
2493 if (!GLEW_VERSION_3_0) {
2494 error(
"gl_context::render_buffer_create: frame buffer objects not supported", &rb);
2503 glGenRenderbuffers(1, &rb_id);
2504 glBindRenderbuffer(GL_RENDERBUFFER, rb_id);
2506 GLuint& gl_format = (GLuint&)rb.internal_format;
2508 cgv::data::component_format best_cf(color_buffer_formats[i]);
2509 gl_format = gl_color_buffer_format_ids[i];
2513 best_cf = cgv::data::component_format(depth_formats[i]);
2514 gl_format = gl_depth_format_ids[i];
2518 if (rb.nr_multi_samples == 0)
2519 glRenderbufferStorage(GL_RENDERBUFFER, gl_format, _width, _height);
2521 glRenderbufferStorageMultisample(GL_RENDERBUFFER, rb.nr_multi_samples, gl_format, _width, _height);
2523 if (check_gl_error(
"gl_context::render_buffer_create", &rb))
2525 rb.handle = get_handle(rb_id);
2529bool gl_context::render_buffer_destruct(render_buffer_base& rc)
const
2531 if (!GLEW_VERSION_3_0) {
2532 error(
"gl_context::render_buffer_destruct: frame buffer objects not supported", &rc);
2535 GLuint rb_id = ((GLuint&) rc.handle)+1;
2536 glDeleteRenderbuffers(1, &rb_id);
2537 if (check_gl_error(
"gl_context::render_buffer_destruct", &rc))
2544bool gl_context::frame_buffer_create(frame_buffer_base& fbb)
const
2546 if (!check_fbo_support(
"gl_context::frame_buffer_create", &fbb))
2549 if (!context::frame_buffer_create(fbb))
2554 glGenFramebuffers(1, &fbo_id);
2556 error(
"gl_context::frame_buffer_create: could not allocate framebuffer object", &fbb);
2559 fbb.handle = get_handle(fbo_id);
2563bool gl_context::frame_buffer_enable(frame_buffer_base& fbb)
2565 if (!context::frame_buffer_enable(fbb))
2567 std::vector<int> buffers;
2569 get_buffer_list(fbb,
depth_buffer, buffers, GL_COLOR_ATTACHMENT0);
2570 glBindFramebuffer(GL_FRAMEBUFFER, get_gl_id(fbb.handle));
2572 if (buffers.size() == 1)
2573 glDrawBuffer(buffers[0]);
2574 else if (buffers.size() > 1) {
2575 glDrawBuffers(GLsizei(buffers.size()),
reinterpret_cast<GLenum*
>(&buffers[0]));
2578 glDrawBuffer(GL_NONE);
2581 error(
"gl_context::frame_buffer_enable: no attached draw buffer selected!!", &fbb);
2590 if (!context::frame_buffer_disable(fbb))
2593 error(
"gl_context::frame_buffer_disable called with empty frame buffer stack!!", &fbb);
2603 if (!context::frame_buffer_destruct(fbb))
2605 GLuint fbo_id = get_gl_id(fbb.handle);
2606 glDeleteFramebuffers(1, &fbo_id);
2612void complete_rect_from_vp(
ivec4& D, GLint vp[4])
2619 D(2) = vp[0] + vp[2];
2621 D(3) = vp[1] + vp[3];
2624void gl_context::frame_buffer_blit(
2625 const frame_buffer_base* src_fbb_ptr,
const ivec4& _S,
2626 frame_buffer_base* dst_fbb_ptr,
const ivec4& _D,
BufferTypeBits btbs,
bool interpolate)
const
2628 static const GLenum masks[8]{
2630 GL_COLOR_BUFFER_BIT,
2631 GL_DEPTH_BUFFER_BIT,
2632 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
2633 GL_STENCIL_BUFFER_BIT,
2634 GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT,
2635 GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
2636 GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT
2640 if ((src_fbb_ptr == 0 && (S(0) == -1 || S(1) == -1 || S(2) == -1 || S(3) == -1)) ||
2641 (dst_fbb_ptr == 0 && (D(0) == -1 || D(1) == -1 || D(2) == -1 || D(3) == -1))) {
2643 glGetIntegerv(GL_VIEWPORT, vp);
2644 if (src_fbb_ptr == 0)
2645 complete_rect_from_vp(S, vp);
2646 if (dst_fbb_ptr == 0)
2647 complete_rect_from_vp(D, vp);
2649 GLint old_draw_fbo, old_read_fbo;
2651 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &old_read_fbo);
2652 glBindFramebuffer(GL_READ_FRAMEBUFFER, get_gl_id(src_fbb_ptr->handle));
2655 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_draw_fbo);
2656 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, get_gl_id(dst_fbb_ptr->handle));
2658 glBlitFramebuffer(S(0), S(1), S(2), S(3), D(0), D(1), D(2), D(3), masks[btbs], interpolate ? GL_LINEAR : GL_NEAREST);
2660 glBindFramebuffer(GL_READ_FRAMEBUFFER, old_read_fbo);
2662 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old_draw_fbo);
2665bool gl_context::frame_buffer_attach(frame_buffer_base& fbb,
const render_buffer_base& rb,
bool is_depth,
int i)
const
2667 if (!context::frame_buffer_attach(fbb, rb, is_depth, i))
2670 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_binding);
2671 glBindFramebuffer(GL_FRAMEBUFFER, get_gl_id(fbb.handle));
2672 glFramebufferRenderbuffer(GL_FRAMEBUFFER,
2673 is_depth ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0 + i,
2675 get_gl_id(rb.handle));
2676 glBindFramebuffer(GL_FRAMEBUFFER, old_binding);
2683 int level,
int i,
int z_or_cube_side)
const
2685 if (!context::frame_buffer_attach(fbb, t, is_depth, level, i, z_or_cube_side))
2688 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_binding);
2689 glBindFramebuffer(GL_FRAMEBUFFER, get_gl_id(fbb.handle));
2691 if (z_or_cube_side == -1) {
2692 glFramebufferTexture2D(GL_FRAMEBUFFER,
2693 is_depth ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0+i,
2694 t.tt == TT_2D ? GL_TEXTURE_2D : GL_TEXTURE_2D_MULTISAMPLE, get_gl_id(t.handle), level);
2697 if (t.tt == TT_CUBEMAP) {
2698 glFramebufferTexture2D(GL_FRAMEBUFFER,
2699 GL_COLOR_ATTACHMENT0+i,
2703 glFramebufferTexture3D(GL_FRAMEBUFFER,
2704 GL_COLOR_ATTACHMENT0+i,
2705 t.tt == TT_3D ? GL_TEXTURE_3D : GL_TEXTURE_2D_MULTISAMPLE_ARRAY , get_gl_id(t.handle), level, z_or_cube_side);
2708 bool result = !check_gl_error(
"gl_context::frame_buffer_attach", &fbb);
2709 glBindFramebuffer(GL_FRAMEBUFFER, old_binding);
2716 if (fbb.handle == 0) {
2717 error(
"gl_context::frame_buffer_is_complete: attempt to check completeness on frame buffer that is not created", &fbb);
2721 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_binding);
2722 glBindFramebuffer(GL_FRAMEBUFFER, get_gl_id(fbb.handle));
2723 GLenum
error = glCheckFramebufferStatus(GL_FRAMEBUFFER);
2724 glBindFramebuffer(GL_FRAMEBUFFER, old_binding);
2726 case GL_FRAMEBUFFER_COMPLETE:
2728 case GL_FRAMEBUFFER_UNDEFINED:
2731 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
2734 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
2735 fbb.
last_error =
"incomplete or missing attachment";
2737 case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
2740 case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
2743 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
2746 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
2749 case GL_FRAMEBUFFER_UNSUPPORTED:
2750 fbb.
last_error =
"framebuffer objects unsupported";
2757int gl_context::frame_buffer_get_max_nr_color_attachments()
const
2759 if (!check_fbo_support(
"gl_context::frame_buffer_get_max_nr_color_attachments"))
2763 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &nr);
2767int gl_context::frame_buffer_get_max_nr_draw_buffers()
const
2769 if (!check_fbo_support(
"gl_context::frame_buffer_get_max_nr_draw_buffers"))
2773 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &nr);
2777GLuint gl_shader_type[] =
2779 0, GL_COMPUTE_SHADER, GL_VERTEX_SHADER, GL_TESS_CONTROL_SHADER, GL_TESS_EVALUATION_SHADER, GL_GEOMETRY_SHADER, GL_FRAGMENT_SHADER, GL_TASK_SHADER_EXT, GL_MESH_SHADER_EXT
2782void gl_context::shader_code_destruct(render_component& sc)
const
2784 if (sc.handle == 0) {
2785 error(
"gl_context::shader_code_destruct: shader not created", &sc);
2788 glDeleteShader(get_gl_id(sc.handle));
2791 check_gl_error(
"gl_context::shader_code_destruct", &sc);
2794bool gl_context::shader_code_create(render_component& sc,
ShaderType st,
const std::string& source)
const
2796 if (!check_shader_support(st,
"gl_context::shader_code_create", &sc))
2799 while (glGetError());
2801 GLuint s_id = glCreateShader(gl_shader_type[st]);
2803 error(std::string(
"gl_context::shader_code_create: ")+gl_error(), &sc);
2806 sc.handle = get_handle(s_id);
2808 const char* s = source.c_str();
2809 glShaderSource(s_id, 1, &s,NULL);
2810 if (check_gl_error(
"gl_context::shader_code_create", &sc))
2816bool gl_context::shader_code_compile(render_component& sc)
const
2818 if (sc.handle == 0) {
2819 error(
"gl_context::shader_code_compile: shader not created", &sc);
2822 GLuint s_id = get_gl_id(sc.handle);
2823 glCompileShader(s_id);
2824 GLint result = GL_FALSE;
2825 glGetShaderiv(s_id, GL_COMPILE_STATUS, &result);
2826 if (result == GL_TRUE)
2828 sc.last_error = std::string();
2829 GLint infologLength = 0;
2830 glGetShaderiv(s_id, GL_INFO_LOG_LENGTH, &infologLength);
2831 if (infologLength > 0) {
2832 GLsizei charsWritten = 0;
2833 sc.last_error = std::string(infologLength, 0);
2834 glGetShaderInfoLog(s_id, infologLength, &charsWritten, &sc.last_error.front());
2835 sc.last_error.resize(
static_cast<size_t>(charsWritten));
2840bool gl_context::shader_program_create(shader_program_base& spb)
const
2842 if (!check_shader_support(ST_VERTEX,
"gl_context::shader_program_create", &spb))
2844 spb.handle = get_handle(glCreateProgram());
2848void gl_context::shader_program_attach(shader_program_base& spb,
const render_component& sc)
const
2850 if (spb.handle == 0) {
2851 error(
"gl_context::shader_program_attach: shader program not created", &spb);
2854 glAttachShader(get_gl_id(spb.handle), get_gl_id(sc.handle));
2857void gl_context::shader_program_detach(shader_program_base& spb,
const render_component& sc)
const
2859 if (spb.handle == 0) {
2860 error(
"gl_context::shader_program_detach: shader program not created", &spb);
2863 glDetachShader(get_gl_id(spb.handle), get_gl_id(sc.handle));
2866bool gl_context::shader_program_link(shader_program_base& spb)
const
2868 if (spb.handle == 0) {
2869 error(
"gl_context::shader_program_link: shader program not created", &spb);
2872 GLuint p_id = get_gl_id(spb.handle);
2873 glLinkProgram(p_id);
2874 GLint result = GL_FALSE;
2875 glGetProgramiv(p_id, GL_LINK_STATUS, &result);
2876 if (result == GL_TRUE)
2877 return context::shader_program_link(spb);
2878 GLint infologLength = 0;
2879 glGetProgramiv(p_id, GL_INFO_LOG_LENGTH, &infologLength);
2880 if (infologLength > 0) {
2881 GLsizei charsWritten = 0;
2882 spb.last_error = std::string(infologLength, 0);
2883 glGetProgramInfoLog(p_id, infologLength, &charsWritten, &spb.last_error.front());
2884 spb.last_error.resize(
static_cast<size_t>(charsWritten));
2885 error(
"gl_context::shader_program_link\n" + spb.last_error, &spb);
2891bool gl_context::shader_program_set_state(shader_program_base& spb)
const
2893 if (spb.handle == 0) {
2894 error(
"gl_context::shader_program_set_state: shader program not created", &spb);
2897 GLuint p_id = get_gl_id(spb.handle);
2898 glProgramParameteri(p_id, GL_GEOMETRY_VERTICES_OUT_ARB, spb.geometry_shader_output_count);
2899 glProgramParameteri(p_id, GL_GEOMETRY_INPUT_TYPE_ARB, map_to_gl(spb.geometry_shader_input_type));
2900 glProgramParameteri(p_id, GL_GEOMETRY_OUTPUT_TYPE_ARB, map_to_gl(spb.geometry_shader_output_type));
2904bool gl_context::shader_program_enable(shader_program_base& spb)
2906 if (!context::shader_program_enable(spb))
2908 glUseProgram(get_gl_id(spb.handle));
2909 shader_program& prog =
static_cast<shader_program&
>(spb);
2918 if (prog.does_context_set_color() && prog.get_color_index() >= 0)
2919 prog.set_attribute(*
this, prog.get_color_index(),
current_color);
2923bool gl_context::shader_program_disable(shader_program_base& spb)
2925 if (!context::shader_program_disable(spb))
2934bool gl_context::shader_program_destruct(shader_program_base& spb)
const
2936 if (!context::shader_program_destruct(spb))
2938 glDeleteProgram(get_gl_id(spb.handle));
2944bool gl_context::shader_program_get_active_uniforms(shader_program_base& spb, std::vector<std::string>& names)
const
2946 if (spb.handle == 0)
2949 GLuint p_id = get_gl_id(spb.handle);
2951 GLint num_active_uniforms = 0;
2952 glGetProgramiv(p_id, GL_ACTIVE_UNIFORMS, &num_active_uniforms);
2954 names.reserve(num_active_uniforms);
2956 std::vector<GLchar> buffer(256);
2957 for (
int i = 0; i < num_active_uniforms; ++i) {
2958 GLint array_size = 0;
2960 GLsizei actual_length = 0;
2962 glGetActiveUniform(p_id, i, GLsizei(buffer.size()), &actual_length, &array_size, &type, buffer.data());
2963 std::string name(
static_cast<char*
>(buffer.data()), actual_length);
2966 if(array_size > 1) {
2968 size_t bracket_pos = name.find(
'[');
2969 if(bracket_pos != std::string::npos)
2970 name.resize(bracket_pos);
2974 names.push_back(name);
2976 for(GLint i = 0; i < array_size; ++i)
2977 names.push_back(name +
"[" + std::to_string(i) +
"]");
2981 names.push_back(name);
2987program_variable_info construct_program_variable(
const std::vector<GLchar>& buffer, GLsizei actual_length, GLint array_size, GLenum type)
2989 program_variable_info V;
2990 V.name = std::string(
static_cast<const char*
>(buffer.data()), actual_length);
2992 if (array_size > 1) {
2994 size_t bracket_pos = V.name.find(
'[');
2995 if (bracket_pos != std::string::npos)
2996 V.name.resize(bracket_pos);
2997 if (!V.name.empty())
2998 V.array_size = array_size;
3046void gl_context::shader_program_inspect_variables(shader_program_base& spb,
ProgramVariableKind kind, std::vector<program_variable_info>& Vs,
bool get_location,
bool get_value)
const
3049 spb.put_id(prog_id);
3051 std::vector<GLchar> buffer(256);
3052 GLint array_size = 0;
3054 GLsizei actual_length = 0;
3056 GLint num_active_variables = 0;
3057 glGetProgramiv(prog_id, kind == cgv::render::PVK_UNIFORM ? GL_ACTIVE_UNIFORMS : GL_ACTIVE_ATTRIBUTES, &num_active_variables);
3059 GLint old_prog_id = prog_id;
3060 if (kind == cgv::render::PVK_ATTRIBUTE) {
3061 glGetIntegerv(GL_CURRENT_PROGRAM, &old_prog_id);
3062 if (old_prog_id != prog_id)
3063 glUseProgram(prog_id);
3066 for (
int i = 0; i < num_active_variables; ++i) {
3068 (kind == cgv::render::PVK_UNIFORM ? glGetActiveUniform : glGetActiveAttrib)(prog_id, i,
3069 GLsizei(buffer.size()), &actual_length, &array_size, &type, buffer.data());
3070 cgv::render::program_variable_info V = construct_program_variable(buffer, actual_length, array_size, type);
3072 size_t cnt = 1, s, S;
3079 std::vector<char> read_buffer;
3080 if (kind == cgv::render::PVK_ATTRIBUTE && cnt != 4)
3081 read_buffer.resize(4 * s / cnt);
3082 for (
unsigned j = 0; j < V.
array_size; ++j) {
3084 std::string postfix;
3088 if (get_location || get_value)
3089 V.
program_location = (kind == cgv::render::PVK_UNIFORM ? glGetUniformLocation : glGetAttribLocation)(
3090 prog_id, (V.
name + postfix).c_str());
3100 void* read_ptr = read_buffer.empty() ? value_ptr : read_buffer.data();
3105 if (kind == cgv::render::PVK_UNIFORM)
3108 glGetVertexAttribIiv(V.
program_location, GL_CURRENT_VERTEX_ATTRIB, (GLint*)(read_ptr));
3111 if (kind == cgv::render::PVK_UNIFORM)
3114 glGetVertexAttribIuiv(V.
program_location, GL_CURRENT_VERTEX_ATTRIB, (GLuint*)(read_ptr));
3117 if (kind == cgv::render::PVK_UNIFORM)
3120 glGetVertexAttribfv(V.
program_location, GL_CURRENT_VERTEX_ATTRIB, (GLfloat*)(read_ptr));
3123 if (kind == cgv::render::PVK_UNIFORM)
3126 glGetVertexAttribdv(V.
program_location, GL_CURRENT_VERTEX_ATTRIB, (GLdouble*)(read_ptr));
3130 if (read_ptr != value_ptr)
3131 std::copy((
const char*)read_ptr, (
const char*)read_ptr + s, (
char*)value_ptr);
3137 if (old_prog_id != prog_id)
3138 glUseProgram(old_prog_id);
3142int gl_context::get_uniform_location(
const shader_program_base& spb,
const std::string& name)
const
3144 return glGetUniformLocation(get_gl_id(spb.handle), name.c_str());
3147std::string value_type_index_to_string(type_descriptor td)
3150 switch (td.element_type) {
3156 if (td.is_row_major)
3166bool gl_context::set_uniform_void(shader_program_base& spb,
int loc, type_descriptor value_type,
const void* value_ptr)
const
3168 if (value_type.is_array) {
3169 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);
3173 error(
"gl_context::set_uniform_void() called on not created program", &spb);
3178 glUseProgram(get_gl_id(spb.handle));
3180 switch (value_type.element_type) {
3182 switch (value_type.coordinate_type) {
3183 case TI_BOOL: glUniform1i(loc, *
reinterpret_cast<const bool*
>(value_ptr) ? 1 : 0);
break;
3184 case TI_UINT8: glUniform1ui(loc, *
reinterpret_cast<const uint8_type*
>(value_ptr));
break;
3187 case TI_INT8: glUniform1i(loc, *
reinterpret_cast<const int8_type*
>(value_ptr));
break;
3188 case TI_INT16: glUniform1i(loc, *
reinterpret_cast<const int16_type*
>(value_ptr));
break;
3189 case TI_INT32: glUniform1i(loc, *
reinterpret_cast<const int32_type*
>(value_ptr));
break;
3190 case TI_FLT32: glUniform1f(loc, *
reinterpret_cast<const flt32_type*
>(value_ptr));
break;
3191 case TI_FLT64: glUniform1d(loc, *
reinterpret_cast<const flt64_type*
>(value_ptr));
break;
3193 error(std::string(
"gl_context::set_uniform_void(") + value_type_index_to_string(value_type) +
") unsupported coordinate type.", &spb);
3198 switch (value_type.nr_rows) {
3200 switch (value_type.coordinate_type) {
3201 case TI_BOOL: glUniform2i(loc,
reinterpret_cast<const bool*
>(value_ptr)[0] ? 1 : 0,
reinterpret_cast<const bool*
>(value_ptr)[1] ? 1 : 0);
break;
3202 case TI_UINT8: glUniform2ui(loc,
reinterpret_cast<const uint8_type*
> (value_ptr)[0],
reinterpret_cast<const uint8_type*
> (value_ptr)[1]);
break;
3205 case TI_INT8: glUniform2i(loc,
reinterpret_cast<const int8_type*
> (value_ptr)[0],
reinterpret_cast<const int8_type*
> (value_ptr)[1]);
break;
3206 case TI_INT16: glUniform2i(loc,
reinterpret_cast<const int16_type*
> (value_ptr)[0],
reinterpret_cast<const int16_type*
> (value_ptr)[1]);
break;
3207 case TI_INT32: glUniform2i(loc,
reinterpret_cast<const int32_type*
> (value_ptr)[0],
reinterpret_cast<const int32_type*
> (value_ptr)[1]);
break;
3208 case TI_FLT32: glUniform2f(loc,
reinterpret_cast<const flt32_type*
> (value_ptr)[0],
reinterpret_cast<const flt32_type*
> (value_ptr)[1]);
break;
3209 case TI_FLT64: glUniform2d(loc,
reinterpret_cast<const flt64_type*
> (value_ptr)[0],
reinterpret_cast<const flt64_type*
> (value_ptr)[1]);
break;
3211 error(std::string(
"gl_context::set_uniform_void(") + value_type_index_to_string(value_type) +
") unsupported coordinate type.", &spb);
3216 switch (value_type.coordinate_type) {
3217 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;
3218 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;
3221 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;
3222 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;
3223 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;
3224 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;
3225 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;
3227 error(std::string(
"gl_context::set_uniform_void(") + value_type_index_to_string(value_type) +
") unsupported coordinate type.", &spb);
3232 switch (value_type.coordinate_type) {
3233 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;
3234 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;
3237 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;
3238 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;
3239 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;
3240 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;
3241 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;
3243 error(std::string(
"gl_context::set_uniform_void(") + value_type_index_to_string(value_type) +
") unsupported coordinate type.", &spb);
3250 switch (value_type.coordinate_type) {
3252 switch (value_type.nr_rows) {
3254 switch (value_type.nr_columns) {
3255 case 2: glUniformMatrix2fv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt32_type*
> (value_ptr));
break;
3256 case 3: glUniformMatrix2x3fv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt32_type*
> (value_ptr));
break;
3257 case 4: glUniformMatrix2x4fv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt32_type*
> (value_ptr));
break;
3259 error(std::string(
"gl_context::set_uniform_void(") + value_type_index_to_string(value_type) +
") matrix number of columns outside [2,..,4].", &spb);
3264 switch (value_type.nr_columns) {
3265 case 2: glUniformMatrix3x2fv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt32_type*
> (value_ptr));
break;
3266 case 3: glUniformMatrix3fv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt32_type*
> (value_ptr));
break;
3267 case 4: glUniformMatrix3x4fv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt32_type*
> (value_ptr));
break;
3269 error(std::string(
"gl_context::set_uniform_void(") + value_type_index_to_string(value_type) +
") matrix number of columns outside [2,..,4].", &spb);
3274 switch (value_type.nr_columns) {
3275 case 2: glUniformMatrix4x2fv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt32_type*
> (value_ptr));
break;
3276 case 3: glUniformMatrix4x3fv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt32_type*
> (value_ptr));
break;
3277 case 4: glUniformMatrix4fv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt32_type*
> (value_ptr));
break;
3279 error(std::string(
"gl_context::set_uniform_void(") + value_type_index_to_string(value_type) +
") matrix number of columns outside [2,..,4].", &spb);
3284 error(std::string(
"gl_context::set_uniform_void(") + value_type_index_to_string(value_type) +
") matrix number of rows outside [2,..,4].", &spb);
3289 switch (value_type.nr_rows) {
3291 switch (value_type.nr_columns) {
3292 case 2: glUniformMatrix2dv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt64_type*
> (value_ptr));
break;
3293 case 3: glUniformMatrix2x3dv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt64_type*
> (value_ptr));
break;
3294 case 4: glUniformMatrix2x4dv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt64_type*
> (value_ptr));
break;
3296 error(std::string(
"gl_context::set_uniform_void(") + value_type_index_to_string(value_type) +
") matrix number of columns outside [2,..,4].", &spb);
3301 switch (value_type.nr_columns) {
3302 case 2: glUniformMatrix3x2dv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt64_type*
> (value_ptr));
break;
3303 case 3: glUniformMatrix3dv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt64_type*
> (value_ptr));
break;
3304 case 4: glUniformMatrix3x4dv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt64_type*
> (value_ptr));
break;
3306 error(std::string(
"gl_context::set_uniform_void(") + value_type_index_to_string(value_type) +
") matrix number of columns outside [2,..,4].", &spb);
3311 switch (value_type.nr_columns) {
3312 case 2: glUniformMatrix4x2dv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt64_type*
> (value_ptr));
break;
3313 case 3: glUniformMatrix4x3dv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt64_type*
> (value_ptr));
break;
3314 case 4: glUniformMatrix4dv(loc, 1, !value_type.is_row_major,
reinterpret_cast<const flt64_type*
> (value_ptr));
break;
3316 error(std::string(
"gl_context::set_uniform_void(") + value_type_index_to_string(value_type) +
") matrix number of columns outside [2,..,4].", &spb);
3321 error(std::string(
"gl_context::set_uniform_void(") + value_type_index_to_string(value_type) +
") matrix number of rows outside [2,..,4].", &spb);
3326 error(std::string(
"gl_context::set_uniform_void(") + value_type_index_to_string(value_type) +
") non float coordinate type not supported.", &spb);
3334 if (check_gl_error(
"gl_context::set_uniform_void()", &spb))
3339bool 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
3341 if (!value_type.is_array) {
3342 error(std::string(
"gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) +
") non array type not allowed.", &spb);
3346 error(
"gl_context::set_uniform_array_void() called on not created program", &spb);
3351 glUseProgram(get_gl_id(spb.handle));
3353 switch (value_type.coordinate_type) {
3355 switch (value_type.element_type) {
3357 glUniform1iv(loc, GLsizei(nr_elements),
reinterpret_cast<const int32_type*
>(value_ptr));
3360 switch (value_type.nr_rows) {
3361 case 2: glUniform2iv(loc, GLsizei(nr_elements),
reinterpret_cast<const int32_type*
>(value_ptr));
break;
3362 case 3: glUniform3iv(loc, GLsizei(nr_elements),
reinterpret_cast<const int32_type*
>(value_ptr));
break;
3363 case 4: glUniform4iv(loc, GLsizei(nr_elements),
reinterpret_cast<const int32_type*
>(value_ptr));
break;
3365 error(std::string(
"gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) +
") vector dimension outside [2,..4].", &spb);
3371 error(std::string(
"gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) +
") type not supported.", &spb);
3377 switch (value_type.element_type) {
3379 glUniform1uiv(loc, GLsizei(nr_elements),
reinterpret_cast<const uint32_type*
>(value_ptr));
3382 switch (value_type.nr_rows) {
3383 case 2: glUniform2uiv(loc, GLsizei(nr_elements),
reinterpret_cast<const uint32_type*
>(value_ptr));
break;
3384 case 3: glUniform3uiv(loc, GLsizei(nr_elements),
reinterpret_cast<const uint32_type*
>(value_ptr));
break;
3385 case 4: glUniform4uiv(loc, GLsizei(nr_elements),
reinterpret_cast<const uint32_type*
>(value_ptr));
break;
3387 error(std::string(
"gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) +
") vector dimension outside [2,..4].", &spb);
3393 error(std::string(
"gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) +
") type not supported.", &spb);
3399 switch (value_type.element_type) {
3401 glUniform1fv(loc, GLsizei(nr_elements),
reinterpret_cast<const flt32_type*
>(value_ptr));
3404 switch (value_type.nr_rows) {
3405 case 2: glUniform2fv(loc, GLsizei(nr_elements),
reinterpret_cast<const flt32_type*
>(value_ptr));
break;
3406 case 3: glUniform3fv(loc, GLsizei(nr_elements),
reinterpret_cast<const flt32_type*
>(value_ptr));
break;
3407 case 4: glUniform4fv(loc, GLsizei(nr_elements),
reinterpret_cast<const flt32_type*
>(value_ptr));
break;
3409 error(std::string(
"gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) +
") vector dimension outside [2,..4].", &spb);
3415 switch (value_type.nr_rows) {
3417 switch (value_type.nr_columns) {
3418 case 2: glUniformMatrix2fv(loc, GLsizei(nr_elements), value_type.is_row_major,
reinterpret_cast<const flt32_type*
>(value_ptr));
break;
3419 case 3: glUniformMatrix2x3fv(loc, GLsizei(nr_elements), value_type.is_row_major,
reinterpret_cast<const flt32_type*
>(value_ptr));
break;
3420 case 4: glUniformMatrix2x4fv(loc, GLsizei(nr_elements), value_type.is_row_major,
reinterpret_cast<const flt32_type*
>(value_ptr));
break;
3422 error(std::string(
"gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) +
") matrix number of columns outside [2,..4].", &spb);
3428 switch (value_type.nr_columns) {
3429 case 2: glUniformMatrix3x2fv(loc, GLsizei(nr_elements), value_type.is_row_major,
reinterpret_cast<const flt32_type*
>(value_ptr));
break;
3430 case 3: glUniformMatrix3fv(loc, GLsizei(nr_elements), value_type.is_row_major,
reinterpret_cast<const flt32_type*
>(value_ptr));
break;
3431 case 4: glUniformMatrix3x4fv(loc, GLsizei(nr_elements), value_type.is_row_major,
reinterpret_cast<const flt32_type*
>(value_ptr));
break;
3433 error(std::string(
"gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) +
") matrix number of columns outside [2,..4].", &spb);
3439 switch (value_type.nr_columns) {
3440 case 2: glUniformMatrix4x2fv(loc, GLsizei(nr_elements), value_type.is_row_major,
reinterpret_cast<const flt32_type*
>(value_ptr));
break;
3441 case 3: glUniformMatrix4x3fv(loc, GLsizei(nr_elements), value_type.is_row_major,
reinterpret_cast<const flt32_type*
>(value_ptr));
break;
3442 case 4: glUniformMatrix4fv(loc, GLsizei(nr_elements), value_type.is_row_major,
reinterpret_cast<const flt32_type*
>(value_ptr));
break;
3444 error(std::string(
"gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) +
") matrix number of columns outside [2,..4].", &spb);
3450 error(std::string(
"gl_context::set_uniform_array_void(") + value_type_index_to_string(value_type) +
") matrix number of rows outside [2,..4].", &spb);
3458 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);
3462 if (check_gl_error(
"gl_context::set_uniform_array_void()", &spb))
3471int gl_context::get_uniform_block_index(
const shader_program_base& spb,
const std::string& name)
const
3473 return glGetUniformBlockIndex(get_gl_id(spb.handle), name.c_str());
3476bool gl_context::set_uniform_block_binding(shader_program_base& spb,
int index,
int binding)
const
3479 error(
"gl_context::set_uniform_block_binding() called on not created program", &spb);
3482 glUniformBlockBinding(get_gl_id(spb.handle), index, binding);
3483 return check_gl_error(
"gl_context::set_uniform_block_binding()", &spb);
3486int gl_context::get_attribute_location(
const shader_program_base& spb,
const std::string& name)
const
3488 return glGetAttribLocation(get_gl_id(spb.handle), name.c_str());
3491bool gl_context::set_attribute_void(shader_program_base& spb,
int loc, type_descriptor value_type,
const void* value_ptr)
const
3494 error(
"gl_context::set_attribute_void() called on not created program", &spb);
3499 glUseProgram(get_gl_id(spb.handle));
3501 switch (value_type.element_type) {
3503 switch (value_type.coordinate_type) {
3504 case TI_BOOL: glVertexAttrib1s(loc, *
reinterpret_cast<const bool*
>(value_ptr) ? 1 : 0);
break;
3505 case TI_INT8: glVertexAttrib1s(loc, *
reinterpret_cast<const int8_type*
>(value_ptr));
break;
3506 case TI_INT16: glVertexAttrib1s(loc, *
reinterpret_cast<const int16_type*
>(value_ptr));
break;
3507 case TI_INT32: glVertexAttribI1i(loc, *
reinterpret_cast<const int32_type*
>(value_ptr));
break;
3508 case TI_UINT8: glVertexAttrib1s(loc, *
reinterpret_cast<const uint8_type*
>(value_ptr));
break;
3509 case TI_UINT16: glVertexAttribI1ui(loc, *
reinterpret_cast<const uint16_type*
>(value_ptr));
break;
3510 case TI_UINT32: glVertexAttribI1ui(loc, *
reinterpret_cast<const uint32_type*
>(value_ptr));
break;
3511 case TI_FLT32: glVertexAttrib1f(loc, *
reinterpret_cast<const flt32_type*
>(value_ptr));
break;
3512 case TI_FLT64: glVertexAttrib1d(loc, *
reinterpret_cast<const flt64_type*
>(value_ptr));
break;
3514 error(std::string(
"gl_context::set_attribute_void(") + value_type_index_to_string(value_type) +
") type not supported!", &spb);
3520 switch (value_type.nr_rows) {
3522 switch (value_type.coordinate_type) {
3523 case TI_BOOL: glVertexAttrib2s(loc,
reinterpret_cast<const bool*
>(value_ptr)[0] ? 1 : 0,
reinterpret_cast<const bool*
>(value_ptr)[1] ? 1 : 0);
break;
3524 case TI_UINT8: glVertexAttrib2s(loc,
reinterpret_cast<const uint8_type*
> (value_ptr)[0],
reinterpret_cast<const uint8_type*
> (value_ptr)[1]);
break;
3525 case TI_UINT16: glVertexAttribI2ui(loc,
reinterpret_cast<const uint16_type*
>(value_ptr)[0],
reinterpret_cast<const uint16_type*
>(value_ptr)[1]);
break;
3526 case TI_UINT32: glVertexAttribI2ui(loc,
reinterpret_cast<const uint32_type*
>(value_ptr)[0],
reinterpret_cast<const uint32_type*
>(value_ptr)[1]);
break;
3527 case TI_INT8: glVertexAttrib2s(loc,
reinterpret_cast<const int8_type*
> (value_ptr)[0],
reinterpret_cast<const int8_type*
> (value_ptr)[1]);
break;
3528 case TI_INT16: glVertexAttrib2s(loc,
reinterpret_cast<const int16_type*
> (value_ptr)[0],
reinterpret_cast<const int16_type*
> (value_ptr)[1]);
break;
3529 case TI_INT32: glVertexAttribI2i(loc,
reinterpret_cast<const int32_type*
> (value_ptr)[0],
reinterpret_cast<const int32_type*
> (value_ptr)[1]);
break;
3530 case TI_FLT32: glVertexAttrib2f(loc,
reinterpret_cast<const flt32_type*
> (value_ptr)[0],
reinterpret_cast<const flt32_type*
> (value_ptr)[1]);
break;
3531 case TI_FLT64: glVertexAttrib2d(loc,
reinterpret_cast<const flt64_type*
> (value_ptr)[0],
reinterpret_cast<const flt64_type*
> (value_ptr)[1]);
break;
3533 error(std::string(
"gl_context::set_attribute_void(") + value_type_index_to_string(value_type) +
") unsupported coordinate type.", &spb);
3539 switch (value_type.coordinate_type) {
3540 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;
3541 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;
3544 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;
3545 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;
3546 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;
3547 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;
3548 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;
3550 error(std::string(
"gl_context::set_attribute_void(") + value_type_index_to_string(value_type) +
") unsupported coordinate type.", &spb);
3555 switch (value_type.coordinate_type) {
3556 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;
3557 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;
3560 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;
3561 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;
3562 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;
3563 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;
3564 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;
3566 error(std::string(
"gl_context::set_attribute_void(") + value_type_index_to_string(value_type) +
") unsupported coordinate type.", &spb);
3572 error(std::string(
"gl_context::set_attribute_void(") + value_type_index_to_string(value_type) +
") vector dimension outside [2..4]", &spb);
3578 error(std::string(
"gl_context::set_attribute_void(") + value_type_index_to_string(value_type) +
") matrix type not supported!", &spb);
3585 if (check_gl_error(
"gl_context::set_uniform_array_void()", &spb))
3590bool gl_context::attribute_array_binding_create(attribute_array_binding_base& aab)
const
3592 if (!GLEW_VERSION_3_0) {
3593 error(
"gl_context::attribute_array_binding_create() array attribute bindings not supported", &aab);
3597 glGenVertexArrays(1, &a_id);
3599 error(std::string(
"gl_context::attribute_array_binding_create(): ") + gl_error(), &aab);
3603 aab.handle = get_handle(a_id);
3607bool gl_context::attribute_array_binding_destruct(attribute_array_binding_base& aab)
const
3610 glBindVertexArray(0);
3611 if (!context::attribute_array_binding_destruct(aab))
3614 error(
"gl_context::attribute_array_binding_destruct(): called on not created attribute array binding", &aab);
3617 GLuint a_id = get_gl_id(aab.handle);
3618 glDeleteVertexArrays(1, &a_id);
3621 return !check_gl_error(
"gl_context::attribute_array_binding_destruct");
3624bool gl_context::attribute_array_binding_enable(attribute_array_binding_base& aab)
3626 if (!context::attribute_array_binding_enable(aab))
3628 glBindVertexArray(get_gl_id(aab.handle));
3629 return !check_gl_error(
"gl_context::attribute_array_binding_enable");
3632bool gl_context::attribute_array_binding_disable(attribute_array_binding_base& aab)
3634 if (!context::attribute_array_binding_disable(aab))
3637 glBindVertexArray(0);
3643bool gl_context::set_element_array(attribute_array_binding_base* aab,
const vertex_buffer_base* vbb)
const
3646 error(
"gl_context::set_element_array(): called without a vertex buffer object", aab);
3650 error(
"gl_context::set_element_array(): called with not created vertex buffer object", vbb);
3654 std::cout <<
"gl_context::set_element_array() : called on vertex buffer object that is not of type VBT_INDICES" << std::endl;
3660 error(
"gl_context::set_element_array(): called on not created attribute array binding", aab);
3666 if (aab && not_current)
3667 glBindVertexArray(get_gl_id(aab->handle));
3670 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, get_gl_id(vbb->handle));
3672 if (aab && not_current)
3675 return !check_gl_error(
"gl_context::set_element_array_void()", aab);
3679bool 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
3681 if (value_type == ET_MATRIX) {
3682 error(
"gl_context::set_attribute_array_void(): called with matrix elements not supported", aab);
3687 error(
"gl_context::set_attribute_array_void(): called with not created vertex buffer object", vbb);
3693 error(
"gl_context::set_attribute_array_void(): called on not created attribute array binding", aab);
3699 if (aab && not_current)
3700 glBindVertexArray(get_gl_id(aab->handle));
3703 glBindBuffer(GL_ARRAY_BUFFER, get_gl_id(vbb->handle));
3706 unsigned n = value_type.element_type == ET_VALUE ? 1 : value_type.nr_rows;
3707 switch (value_type.coordinate_type) {
3708 case TI_INT8: value_type.normalize ? glVertexAttribPointer(loc, n, GL_BYTE, value_type.normalize, stride, ptr) : glVertexAttribIPointer(loc, n, GL_BYTE, stride, ptr);
break;
3709 case TI_INT16: value_type.normalize ? glVertexAttribPointer(loc, n, GL_SHORT, value_type.normalize, stride, ptr) : glVertexAttribIPointer(loc, n, GL_SHORT, stride, ptr);
break;
3710 case TI_INT32: value_type.normalize ? glVertexAttribPointer(loc, n, GL_INT, value_type.normalize, stride, ptr) : glVertexAttribIPointer(loc, n, GL_INT, stride, ptr);
break;
3711 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;
3712 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;
3713 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;
3714 case TI_FLT32: glVertexAttribPointer(loc, n, GL_FLOAT, value_type.normalize, stride, ptr);
break;
3716 if (GLEW_VERSION_4_1)
3717 glVertexAttribLPointer(loc, n, GL_DOUBLE, stride, ptr);
3719 error(
"gl_context::set_attribute_array_void(): called with coordinates of type double only supported starting with OpenGL 4.1", aab);
3724 error(
"gl_context::set_attribute_array_void(): called with unsupported coordinate type", aab);
3729 glEnableVertexAttribArray(loc);
3732 glBindBuffer(GL_ARRAY_BUFFER, 0);
3734 if (aab && not_current)
3738 return res && !check_gl_error(
"gl_context::set_attribute_array_void()", aab);
3741bool gl_context::enable_attribute_array(attribute_array_binding_base* aab,
int loc,
bool do_enable)
const
3746 error(
"gl_context::enable_attribute_array(): called on not created attribute array binding", aab);
3750 glBindVertexArray(get_gl_id(aab->handle));
3754 glEnableVertexAttribArray(loc);
3756 glDisableVertexAttribArray(loc);
3758 if (aab && not_current)
3761 return !check_gl_error(
"gl_context::enable_attribute_array()");
3764bool gl_context::is_attribute_array_enabled(
const attribute_array_binding_base* aab,
int loc)
const
3769 error(
"gl_context::is_attribute_array_enabled(): called on not created attribute array binding", aab);
3773 glBindVertexArray(get_gl_id(aab->handle));
3777 glGetVertexAttribiv(loc, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &res);
3779 if (aab && not_current)
3782 return res == GL_TRUE;
3787 static GLenum buffer_targets[] = {
3789 GL_ELEMENT_ARRAY_BUFFER,
3792 GL_TRANSFORM_FEEDBACK_BUFFER,
3793 GL_SHADER_STORAGE_BUFFER,
3794 GL_ATOMIC_COUNTER_BUFFER,
3795 GL_DRAW_INDIRECT_BUFFER
3797 return buffer_targets[vbt];
3802 static GLenum buffer_usages[] = {
3813 return buffer_usages[vbu];
3816bool gl_context::vertex_buffer_bind(
const vertex_buffer_base& vbb,
VertexBufferType _type,
unsigned _idx)
const
3818 if (_idx ==
unsigned(-1))
3819 glBindBuffer(buffer_target(_type), get_gl_id(vbb.handle));
3821 glBindBufferBase(buffer_target(_type), _idx, get_gl_id(vbb.handle));
3822 return !check_gl_error(
"gl_context::vertex_buffer_bind", &vbb);
3825bool gl_context::vertex_buffer_unbind(
const vertex_buffer_base& vbb,
VertexBufferType _type,
unsigned _idx)
const {
3826 if(_idx ==
unsigned(-1))
3827 glBindBuffer(buffer_target(_type), 0);
3829 glBindBufferBase(buffer_target(_type), _idx, 0);
3830 return !check_gl_error(
"gl_context::vertex_buffer_unbind", &vbb);
3833bool gl_context::vertex_buffer_create(vertex_buffer_base& vbb,
const void* array_ptr,
size_t size_in_bytes)
const
3835 if (!GLEW_VERSION_2_0) {
3836 error(
"gl_context::vertex_buffer_create() vertex buffer objects not supported", &vbb);
3840 glGenBuffers(1, &b_id);
3842 error(std::string(
"gl_context::vertex_buffer_create(): ") + gl_error(), &vbb);
3845 vbb.handle = get_handle(b_id);
3846 glBindBuffer(buffer_target(vbb.type), b_id);
3847 glBufferData(buffer_target(vbb.type), size_in_bytes, array_ptr, buffer_usage(vbb.usage));
3848 glBindBuffer(buffer_target(vbb.type), 0);
3849 return !check_gl_error(
"gl_context::vertex_buffer_create", &vbb);
3852bool gl_context::vertex_buffer_resize(vertex_buffer_base& vbb,
const void* array_ptr,
size_t size_in_bytes)
const {
3854 error(
"gl_context::vertex_buffer_resize() vertex buffer object must be created before", &vbb);
3857 GLuint b_id = get_gl_id(vbb.handle);
3858 glBindBuffer(buffer_target(vbb.type), b_id);
3859 glBufferData(buffer_target(vbb.type), size_in_bytes, array_ptr, buffer_usage(vbb.usage));
3860 glBindBuffer(buffer_target(vbb.type), 0);
3861 return !check_gl_error(
"gl_context::vertex_buffer_resize", &vbb);
3864bool gl_context::vertex_buffer_clear(vertex_buffer_base& vbb,
size_t offset,
size_t size_in_bytes)
const
3867 error(
"gl_context::vertex_buffer_clear() vertex buffer object must be created before", &vbb);
3870 GLuint b_id = get_gl_id(vbb.handle);
3871 glBindBuffer(buffer_target(vbb.type), b_id);
3872 glClearBufferSubData(buffer_target(vbb.type), GL_R8, offset, size_in_bytes, GL_RED, GL_UNSIGNED_BYTE, NULL);
3873 glBindBuffer(buffer_target(vbb.type), 0);
3874 return !check_gl_error(
"gl_context::vertex_buffer_clear", &vbb);
3877bool gl_context::vertex_buffer_replace(vertex_buffer_base& vbb,
size_t offset,
size_t size_in_bytes,
const void* array_ptr)
const
3880 error(
"gl_context::vertex_buffer_replace() vertex buffer object must be created before", &vbb);
3883 GLuint b_id = get_gl_id(vbb.handle);
3884 glBindBuffer(buffer_target(vbb.type), b_id);
3885 glBufferSubData(buffer_target(vbb.type), offset, size_in_bytes, array_ptr);
3886 glBindBuffer(buffer_target(vbb.type), 0);
3887 return !check_gl_error(
"gl_context::vertex_buffer_replace", &vbb);
3890bool 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
3892 if (!src.handle || !target.handle) {
3893 error(
"gl_context::vertex_buffer_copy() source and destination vertex buffer objects must have been created before", &src);
3896 GLuint b_id = get_gl_id(src.handle);
3897 glBindBuffer(GL_COPY_READ_BUFFER, get_gl_id(src.handle));
3898 glBindBuffer(GL_COPY_WRITE_BUFFER, get_gl_id(target.handle));
3899 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, src_offset, target_offset, size_in_bytes);
3900 glBindBuffer(GL_COPY_READ_BUFFER, 0);
3901 glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
3902 return !check_gl_error(
"gl_context::vertex_buffer_copy", &src);
3906bool gl_context::vertex_buffer_copy_back(
const vertex_buffer_base& vbb,
size_t offset,
size_t size_in_bytes,
void* array_ptr)
const
3909 error(
"gl_context::vertex_buffer_copy_back() vertex buffer object must be created", &vbb);
3912 GLuint b_id = get_gl_id(vbb.handle);
3913 GLuint bind_point = GL_COPY_READ_BUFFER;
3924 glBindBuffer(bind_point, b_id);
3925 glGetBufferSubData(bind_point, offset, size_in_bytes, array_ptr);
3926 glBindBuffer(bind_point, 0);
3927 return !check_gl_error(
"gl_context::vertex_buffer_copy_back", &vbb);
3930bool gl_context::vertex_buffer_destruct(vertex_buffer_base& vbb)
const
3933 GLuint b_id = get_gl_id(vbb.handle);
3934 glDeleteBuffers(1, &b_id);
3937 return !check_gl_error(
"gl_context::vertex_buffer_destruct");
3940 error(
"gl_context::vertex_buffer_destruct(): called on not created vertex buffer", &vbb);
virtual void stream_stats(std::ostream &)
overload to show the content of this object
The group class is a node with children.
unsigned int get_nr_children() const
return the number of children
base_ptr get_child(unsigned int i) const
return the i-th child
complete implementation of method actions that only call one method when entering a node
complete implementation of method actions that only call one method when entering a node
interface of a handler for traverse callbacks
class used to traverse a tree structure
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...
void manage_format(bool enable=true)
whether to manage the data format pointer
const data_format * get_format() const
return the component format
cgv::type::func::transfer_const< P, S * >::type get_ptr() const
return a data pointer to type S
the data view gives access to a data array of one, two, three or four dimensions.
~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
virtual void stream_help(std::ostream &os)=0
overload to stream help information to the given output stream
T & z()
return third component
T & y()
return second component
T * data()
return a pointer to the underlying array serving as component storage
T & x()
return first component
A matrix type (full column major storage) The matrix can be loaded directly into OpenGL without need ...
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
static bool set_global_attribute_array(const context &ctx, int loc, const vertex_buffer &vbo, type_descriptor td, size_t size, size_t offset, unsigned stride=0)
point array of vertex attribute at location loc to vertex buffer array array stored in CPU memory; in...
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
virtual std::ostream & output_stream()
returns an output stream whose output is printed at the current cursor location, which is managed by ...
virtual void mul_modelview_matrix(const dmat4 &MV)
multiply given matrix from right to current modelview matrix
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
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
virtual void error(const std::string &message, const render_component *rc=0) const
error handling
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
float current_font_size
store current font size
bool enable_vsync
whether vsync should be enabled
virtual void set_buffer_mask(BufferMask mask)
set the buffer mask for depth and color buffers
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
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
virtual void on_lights_changed()
helper function to send light update events
void push_depth_test_state()
push a copy of the current depth test state onto the stack saved attributes: depth test enablement,...
std::stack< shader_program_base * > shader_program_stack
stack of currently enabled shader programs
bool is_light_source_enabled(void *handle)
check whether light source is enabled
virtual void disable_depth_test()
disable the depth test
int get_bg_stencil() const
return the current stencil value for clearing the background
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
void pop_depth_test_state()
pop the top of the current depth test state from the stack
void tesselate_unit_sphere(int resolution=25, bool flip_normals=false, bool edges=false)
tesselate a sphere of radius 1
virtual RenderPassFlags get_render_pass_flags() const
return the current render pass flags
void tesselate_unit_cylinder(int resolution=25, bool flip_normals=false, bool edges=false)
tesselate a cylinder of radius 1
virtual void set_bg_color(vec4 rgba)
set a user defined background color
virtual void set_depth_test_state(DepthTestState state)
set the depth test state
size_t get_nr_enabled_light_sources() const
return the number of light sources
virtual unsigned int get_height() const =0
return the height of the window
virtual void disable_blending()
disable blending
BufferMask get_buffer_mask() const
return the current buffer mask
void push_cull_state()
push a copy of the current culling state onto the stack saved attributes: cull face enablement,...
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
std::stack< dmat4 > modelview_matrix_stack
keep two matrix stacks for model view and projection matrices
virtual void pop_window_transformation_array()
restore previous viewport and depth range arrays defining the window transformations
virtual void set_color_mask(bvec4 flags)
set the color buffer mask
virtual void set_material(const cgv::media::illum::surface_material &mat)
set the current material
DepthTestState get_depth_test_state() const
return the current depth test state
bool auto_set_material_in_current_shader_program
whether to automatically set material in current shader program, defaults to true
void set_current_lights(shader_program &prog) const
set the shader program lights to the currently enabled lights
bool enable_light_source(void *handle)
enable a given light source and return whether there existed a light source with given handle
void tesselate_unit_disk(int resolution=25, bool flip_normals=false, bool edges=false)
tesselate a circular disk of radius 1
virtual void enable_depth_test()
enable the depth test
bool support_compatibility_mode
whether to support view and lighting management of compatibility mode, defaults to true
void set_current_gamma(shader_program &prog) const
set the shader program gamma values
vec4 get_bg_color() const
return the current color value for clearing the background
void pop_projection_matrix()
see push_P for an explanation
std::stack< attribute_array_binding_base * > attribute_array_binding_stack
stack of currently enabled attribute array binding
BlendState get_blend_state() const
return the current blend state
virtual void set_cull_state(CullingMode culling_mode)
set the culling state
virtual void set_depth_func(CompareFunction func)
set the depth test function
void set_light_source(void *handle, const cgv::media::illum::light_source &light, bool place_now=true)
set light source newly
void push_projection_matrix()
same as push_V but for the projection matrix - a different matrix stack is used.
bool current_material_is_textured
store flag to tell whether current material is textured
virtual void set_projection_matrix(const dmat4 &P)
set the current projection matrix, which transforms from eye to clip space
rgba current_color
current color value
static const unsigned nr_default_light_sources
number of default light sources
cgv::media::illum::light_source default_light_source[nr_default_light_sources]
default light sources
virtual void set_cursor(int x, int y)
flush the output_stream and set a new cursor position given in opengl coordinates with (0,...
virtual void set_bg_stencil(int s)
set a user defined background stencil value
virtual void set_bg_accum_color(vec4 rgba)
set a user defined background color for the accumulation buffer
cgv::media::illum::surface_material default_material
store a default material
float get_bg_depth() const
return the current depth value for clearing the background
virtual void set_textured_material(const textured_material &mat)
set the current material
std::stack< std::vector< window_transformation > > window_transformation_stack
keep stack of window transformations
vec4 get_bg_accum_color() const
return the current color value for clearing the accumulation buffer
const cgv::media::illum::light_source & get_light_source(void *handle) const
read access to light source
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,...
virtual void set_blend_state(BlendState state)
set the complete blend state
bool sRGB_framebuffer
whether to use opengl option to support sRGB framebuffer
virtual RenderPassFlags get_default_render_pass_flags() const
return the default render pass flags
virtual void set_bg_depth(float d)
set a user defined background depth value
virtual void enable_blending()
enable blending
void set_current_material(shader_program &prog) const
set the shader program material to the currently enabled material
void pop_cull_state()
pop the top of the current culling state from the stack
void pop_modelview_matrix()
see push_V for an explanation
void * default_light_source_handles[nr_default_light_sources]
handles of default light sources
void push_modelview_matrix()
push the current viewing matrix onto a matrix stack for viewing matrices.
std::stack< frame_buffer_base * > frame_buffer_stack
stack of currently enabled frame buffers
bool auto_set_view_in_current_shader_program
whether to automatically set viewing matrixes in current shader program, defaults to true
void tesselate_unit_cone(int resolution=25, bool flip_normals=false, bool edges=false)
tesselate a cone of radius 1
CullingMode get_cull_state() const
return the current culling state
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
const cgv::media::illum::surface_material * current_material_ptr
store pointer to current material
virtual void set_modelview_matrix(const dmat4 &MV)
set the current modelview matrix, which transforms from world to eye space
void * get_enabled_light_source_handle(size_t i) const
access to handle of i-th light source
cgv::media::font::font_face_ptr current_font_face
store current font
virtual void set_depth_mask(bool flag)
set the depth buffer mask
bool auto_set_gamma_in_current_shader_program
whether to automatically set gamma in current shader program, defaults to true
virtual void init_frame(context &)
this method is called in one pass over all drawables before the draw method
virtual void resize(unsigned int w, unsigned int h)
callback to announce resizing of the output window
virtual bool init(context &)
this method is called after creation or recreation of the context, return whether all necessary funct...
base interface for framebuffer
implementation of the context API for the OpenGL API excluding methods for font selection,...
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
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
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
const context * ctx_ptr
keep pointer to my context
std::string last_error
a string that contains the last error
a shader program combines several shader code fragments to a complete definition of the shading pipel...
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
the texture class encapsulates all functionality independent of the rendering api.
void set_component_format(const component_format &cf)
change component format and clear internal format
class that extends obj_material with the management of textures
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
data::ref_ptr< group, true > group_ptr
ref counted pointer to a node
ComponentFormat
define standard formats, which should be used to avoid wrong assignment of component names
@ 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), bool show_debug_info)
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
void message(const std::string &_message)
tell the user something with a message box
namespace for opengl specific GPU programming
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 read_texture(cgv::data::data_view &data, unsigned level)
read back a texture into a data view with the glGetTexImage command
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
unsigned find_best_texture_format(const cgv::data::component_format &_cf, cgv::data::component_format *best_cf, const std::vector< data_view > *palettes, bool show_debug_info)
map the given component format to the best matching available gl component format
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 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,...
namespace for api independent GPU programming
RenderAPI
enumeration of rendering APIs which can be queried from the context
CullingMode
different culling modes
BlendFunction
different blend functions
AccessType
different access types
TextureFilter
different texture filter
TextureWrap
different texture wrap modes
FrameBufferType
different frame buffer types which can be combined together with or
MaterialSide
different sides of a material
ProgramVariableKind
enumerates different kinds of shader program variables
VertexBufferUsage
Provides vertex buffer usage hints as defined in OpenGL.
ShaderType
different shader types
PrimitiveType
different primitive types
VertexBufferType
Provides vertex buffer types to allow implicit binding.
@ VBT_VERTICES
The buffer contains vertices and will be bound to GL_ARRAY_BUFFER.
@ VBT_TEXTURE
The buffer contains texture data and will be bound to GL_TEXTURE_BUFFER.
@ VBT_INDICES
The buffer contains indices and will be bound to GL_ELEMENT_ARRAY_BUFFER.
@ VBT_ATOMIC_COUNTER
The buffer contains atomic counter and will be bound to GL_ATOMIC_COUNTER_BUFFER.
@ VBT_STORAGE
The buffer contains arbitrary data and will be bound to GL_SHADER_STORAGE_BUFFER.
@ VBT_UNIFORM
The buffer contains uniforms and will be bound to GL_UNIFORM_BUFFER.
@ VBT_INDIRECT
The buffer contains indirect draw commands and will be bound to GL_DRAW_INDIRECT_BUFFER.
@ VBT_FEEDBACK
The buffer is used for transform&feedback and will be bound to GL_TRANSFORM_FEEDBACK_BUFFER.
BufferTypeBits
Bits for the selection of different buffer types.
TextureType
different texture types
RenderPassFlags
available flags that can be queried from the context and set for a new render pass
@ RPF_CLEAR_ACCUM
whether to clear the accumulation buffer
@ RPF_SET_MODELVIEW
whether to set default modelview matrix
@ RPF_SET_MATERIAL
whether to define default material
@ RPF_SET_CLEAR_DEPTH
whether to set the clear color
@ RPF_SET_LIGHTS
whether to define default lights
@ RPF_CLEAR_COLOR
whether to clear the color buffer
@ RPF_CLEAR_STENCIL
whether to clear the depth buffer
@ RPF_SET_CLEAR_STENCIL
whether to set the clear color
@ RPF_ENABLE_MATERIAL
whether to enable material
@ RPF_DRAWABLES_INIT_FRAME
whether to call the init_frame method of the drawables
@ RPF_CLEAR_DEPTH
whether to clear the depth buffer
@ RPF_SET_STATE_FLAGS
whether to set depth buffer and culling flags
@ RPF_SET_PROJECTION
whether to set default projection matrix
@ RPF_SET_CLEAR_ACCUM
whether to set the accumulation buffer clear color
@ RPF_SET_CLEAR_COLOR
whether to set the clear color
@ RPF_SET_LIGHTS_ON
whether to turn on default lights
CompareFunction
different comparison functions used for depth testing or texture comparisons
namespace for functions that act on types
namespace for templates that provide type information
const char * get_type_name(TypeId tid)
function that returns the name of a type specified through TypeId
TypeId
ids for the different types and type constructs
@ TI_INT16
signed integer stored in 8 bits
@ TI_INT32
signed integer stored in 16 bits
@ TI_FLT32
floating point type stored in 16 bits
@ TI_UINT32
unsigned integer stored in 16 bits
@ TI_UINT8
signed integer stored in 64 bits
@ TI_UINT16
unsigned integer stored in 8 bits
@ TI_FLT64
floating point type stored in 32 bits
namespace for compile time type information
double flt64_type
this type provides a 64 bit floating point type
signed char int8_type
this type provides an 8 bit signed integer type
int int32_type
this type provides an 32 bit signed integer type
short int16_type
this type provides an 16 bit signed integer type
unsigned short uint16_type
this type provides an 16 bit unsigned integer type
unsigned int uint32_type
this type provides an 32 bit unsigned integer type
float flt32_type
this type provides a 32 bit floating point type
unsigned char uint8_type
this type provides an 8 bit unsigned integer type
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
bool is_element(char c, const std::string &s)
check if char c arises in string s
this header is dependency free
cgv::math::fvec< float, 4 > vec4
declare type of 4d single precision floating point vectors (used for homogeneous coordinates)
cgv::media::color< float, cgv::media::RGB, cgv::media::OPACITY > rgba
declare rgba color type with 32 bit components
cgv::math::fvec< double, 3 > dvec3
declare type of 3d double precision floating point vectors
cgv::math::fvec< uint32_t, 3 > uvec3
declare type of 3d 32 bit unsigned integer vectors
cgv::math::fvec< int32_t, 4 > ivec4
declare type of 4d 32 bit integer vectors
cgv::media::color< float, cgv::media::RGB > rgb
declare rgb color type with 32 bit components
cgv::math::fmat< double, 4, 4 > dmat4
declare type of 4x4 matrices
cgv::math::fvec< float, 2 > vec2
declare type of 2d single precision floating point vectors
cgv::math::fvec< bool, 4 > bvec4
declare type of 4d boolean vectors
cgv::math::fvec< float, 3 > vec3
declare type of 3d single precision floating point vectors
cgv::math::fvec< double, 2 > dvec2
declare type of 2d double precision floating point vectors
Helper functions to process strings.
Represents a blend state used to configure fragment blending.
bool enabled
whether blending is enabled
BlendFunction dst_color
the destination color (rgb) factor
BlendFunction dst_alpha
the destination alpha factor
BlendFunction src_alpha
the source alpha factor
BlendFunction src_color
the source color (rgb) factor
Represents a buffer mask used to mask depth and color buffer outputs.
bool red_flag
whether to write to the red channel of the color buffer
bool depth_flag
whether to write to the depth buffer if the depth test is enabled
bool alpha_flag
whether to write to the alpha channel of the color buffer
bool green_flag
whether to write to the green channel of the color buffer
bool blue_flag
whether to write to the blue channel of the color buffer
Represents a depth test state used to configure depth testing.
bool enabled
whether the depth test is enabled
CompareFunction test_func
the function used to compare depth values
configuration object used to define context parameters that need to be set already at creation time
int version_minor
default: -1 ... minor version of maximum supported OpenGL version
int version_major
default: -1 ... major version of maximum supported OpenGL version
bool debug
default: false in release and true in debug version
bool forward_compatible
default: false
bool core_profile
default: true
bool depth_buffer
default: true
std::string name
name as it appears in shaders
std::vector< char > current_value
data storage for the value of the program variable
unsigned array_size
dimension of arrays
void compute_sizes(size_t &cnt, size_t &s, size_t &S) const
helper member function to compute counts and sizes
int program_location
location in program, but not for array variables which span multiple locations
cgv::render::type_descriptor type_descr
type descriptor providing information on component and compositions (scalar, vector or matrix)
compact type description of data that can be sent to the context; convertible to int