diff --git a/deps_src/imgui/imconfig.h b/deps_src/imgui/imconfig.h index 9f38c09797..d03906cb77 100644 --- a/deps_src/imgui/imconfig.h +++ b/deps_src/imgui/imconfig.h @@ -153,6 +153,8 @@ namespace ImGui // const wchar_t CustomSupportsMarker = 0x1D; // const wchar_t CustomSeamMarker = 0x1E; // const wchar_t MmuSegmentationMarker = 0x1F; + const wchar_t HorizontalHide = 0xB1; + const wchar_t HorizontalShow = 0xB2; // Do not forget use following letters only in wstring //BBS use 08xx to avoid unicode character which may be used diff --git a/resources/images/horizontal_hide.svg b/resources/images/horizontal_hide.svg new file mode 100644 index 0000000000..28f3e27f3e --- /dev/null +++ b/resources/images/horizontal_hide.svg @@ -0,0 +1,46 @@ + + + + + + + + + + diff --git a/resources/images/horizontal_show.svg b/resources/images/horizontal_show.svg new file mode 100644 index 0000000000..dab8523875 --- /dev/null +++ b/resources/images/horizontal_show.svg @@ -0,0 +1,46 @@ + + + + + + + + + + diff --git a/resources/profiles_template/Template/filament/filament_sbs_template.json b/resources/profiles_template/Template/filament/filament_sbs_template.json index 2cc7bd22c6..644423508c 100644 --- a/resources/profiles_template/Template/filament/filament_sbs_template.json +++ b/resources/profiles_template/Template/filament/filament_sbs_template.json @@ -111,7 +111,7 @@ "0" ], "hot_plate_temp": [ - "5705" + "70" ], "hot_plate_temp_initial_layer": [ "70" @@ -165,4 +165,4 @@ "filament_end_gcode": [ "; filament end gcode \nM106 P3 S0\n" ] -} \ No newline at end of file +} diff --git a/resources/shaders/140/background.fs b/resources/shaders/140/background.fs index c21f3a70cd..4e595312ee 100644 --- a/resources/shaders/140/background.fs +++ b/resources/shaders/140/background.fs @@ -5,7 +5,9 @@ uniform vec4 bottom_color; in vec2 tex_coord; +out vec4 out_color; + void main() { - gl_FragColor = mix(bottom_color, top_color, tex_coord.y); + out_color = mix(bottom_color, top_color, tex_coord.y); } diff --git a/resources/shaders/140/dashed_thick_lines.fs b/resources/shaders/140/dashed_thick_lines.fs new file mode 100644 index 0000000000..7ea3c6d610 --- /dev/null +++ b/resources/shaders/140/dashed_thick_lines.fs @@ -0,0 +1,34 @@ +#version 150 + +// see as reference: https://github.com/mhalber/Lines/blob/master/geometry_shader_lines.h +// https://stackoverflow.com/questions/52928678/dashed-line-in-opengl3 + +const float aa_radius = 0.5; + +uniform float dash_size; +uniform float gap_size; +uniform vec4 uniform_color; + +in float line_width; +// x = v tex coord, y = s coord +in vec2 seg_params; + +out vec4 out_color; + +void main() +{ + float inv_stride = 1.0 / (dash_size + gap_size); + if (gap_size > 0.0 && fract(seg_params.y * inv_stride) > dash_size * inv_stride) + discard; + + // We render a quad that is fattened by r, giving total width of the line to be w+r. We want smoothing to happen + // around w, so that the edge is properly smoothed out. As such, in the smoothstep function we have: + // Far edge : 1.0 = (w+r) / (w+r) + // Close edge : 1.0 - (2r / (w+r)) = (w+r)/(w+r) - 2r/(w+r)) = (w-r) / (w+r) + // This way the smoothing is centered around 'w'. + + out_color = uniform_color; + float inv_line_width = 1.0 / line_width; + float aa = 1.0 - smoothstep(1.0 - (2.0 * aa_radius * inv_line_width), 1.0, abs(seg_params.x * inv_line_width)); + out_color.a *= aa; +} diff --git a/resources/shaders/140/dashed_thick_lines.gs b/resources/shaders/140/dashed_thick_lines.gs new file mode 100644 index 0000000000..c4897e9491 --- /dev/null +++ b/resources/shaders/140/dashed_thick_lines.gs @@ -0,0 +1,50 @@ +#version 150 + +// see as reference: https://github.com/mhalber/Lines/blob/master/geometry_shader_lines.h +// https://stackoverflow.com/questions/52928678/dashed-line-in-opengl3 + +layout(lines) in; +layout(triangle_strip, max_vertices = 4) out; + +const float aa_radius = 0.5; + +uniform vec2 viewport_size; +uniform float width; + +in float coord_s[]; + +out float line_width; +// x = v tex coord, y = s coord +out vec2 seg_params; + +void main() +{ + vec2 ndc_0 = gl_in[0].gl_Position.xy / gl_in[0].gl_Position.w; + vec2 ndc_1 = gl_in[1].gl_Position.xy / gl_in[1].gl_Position.w; + + vec2 dir = normalize((ndc_1 - ndc_0) * viewport_size); + vec2 normal_dir = vec2(-dir.y, dir.x); + + line_width = max(1.0, width) + 2.0 * aa_radius; + float half_line_width = 0.5 * line_width; + + vec2 normal = vec2(line_width / viewport_size[0], line_width / viewport_size[1]) * normal_dir; + + seg_params = vec2(-half_line_width, coord_s[0]); + gl_Position = vec4((ndc_0 + normal) * gl_in[0].gl_Position.w, gl_in[0].gl_Position.zw); + EmitVertex(); + + seg_params = vec2(-half_line_width, coord_s[0]); + gl_Position = vec4((ndc_0 - normal) * gl_in[0].gl_Position.w, gl_in[0].gl_Position.zw); + EmitVertex(); + + seg_params = vec2(half_line_width, coord_s[1]); + gl_Position = vec4((ndc_1 + normal) * gl_in[1].gl_Position.w, gl_in[1].gl_Position.zw); + EmitVertex(); + + seg_params = vec2(half_line_width, coord_s[1]); + gl_Position = vec4((ndc_1 - normal) * gl_in[1].gl_Position.w, gl_in[1].gl_Position.zw); + EmitVertex(); + + EndPrimitive(); +} diff --git a/resources/shaders/140/dashed_thick_lines.vs b/resources/shaders/140/dashed_thick_lines.vs new file mode 100644 index 0000000000..79a9fe38cd --- /dev/null +++ b/resources/shaders/140/dashed_thick_lines.vs @@ -0,0 +1,18 @@ +#version 150 + +// see as reference: https://github.com/mhalber/Lines/blob/master/geometry_shader_lines.h +// https://stackoverflow.com/questions/52928678/dashed-line-in-opengl3 + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; + +// v_position.w = coordinate along the line +in vec4 v_position; + +out float coord_s; + +void main() +{ + coord_s = v_position.w; + gl_Position = projection_matrix * view_model_matrix * vec4(v_position.xyz, 1.0); +} \ No newline at end of file diff --git a/resources/shaders/140/flat.fs b/resources/shaders/140/flat.fs index e74124dcae..28642d53fe 100644 --- a/resources/shaders/140/flat.fs +++ b/resources/shaders/140/flat.fs @@ -2,7 +2,9 @@ uniform vec4 uniform_color; +out vec4 out_color; + void main() { - gl_FragColor = uniform_color; + out_color = uniform_color; } diff --git a/resources/shaders/140/flat_texture.fs b/resources/shaders/140/flat_texture.fs index dec946721e..bb6682367f 100644 --- a/resources/shaders/140/flat_texture.fs +++ b/resources/shaders/140/flat_texture.fs @@ -4,7 +4,9 @@ uniform sampler2D uniform_texture; in vec2 tex_coord; +out vec4 out_color; + void main() { - gl_FragColor = texture(uniform_texture, tex_coord); + out_color = texture(uniform_texture, tex_coord); } diff --git a/resources/shaders/140/gouraud_light.fs b/resources/shaders/140/gouraud_light.fs index de616e066a..0f918f4f69 100644 --- a/resources/shaders/140/gouraud_light.fs +++ b/resources/shaders/140/gouraud_light.fs @@ -6,7 +6,9 @@ uniform float emission_factor; // x = tainted, y = specular; in vec2 intensity; +out vec4 out_color; + void main() { - gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); + out_color = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); } diff --git a/resources/shaders/140/gouraud_light_instanced.fs b/resources/shaders/140/gouraud_light_instanced.fs index de616e066a..0f918f4f69 100644 --- a/resources/shaders/140/gouraud_light_instanced.fs +++ b/resources/shaders/140/gouraud_light_instanced.fs @@ -6,7 +6,9 @@ uniform float emission_factor; // x = tainted, y = specular; in vec2 intensity; +out vec4 out_color; + void main() { - gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); + out_color = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); } diff --git a/resources/shaders/140/hotbed.fs b/resources/shaders/140/hotbed.fs new file mode 100644 index 0000000000..9bb1a7caf6 --- /dev/null +++ b/resources/shaders/140/hotbed.fs @@ -0,0 +1,46 @@ +#version 140 + +const vec3 ZERO = vec3(0.0, 0.0, 0.0); +const vec3 WHITE = vec3(1.0, 1.0, 1.0); +struct PrintVolumeDetection +{ + // 0 = rectangle, 1 = circle, 2 = custom, 3 = invalid + int type; + // type = 0 (rectangle): + // x = min.x, y = min.y, z = max.x, w = max.y + // type = 1 (circle): + // x = center.x, y = center.y, z = radius + vec4 xy_data; + // x = min z, y = max z + vec2 z_data; +}; + +uniform vec4 uniform_color; +uniform float emission_factor; +uniform PrintVolumeDetection print_volume; +// x = diffuse, y = specular; +in vec2 intensity; +in vec4 world_pos; + +out vec4 out_color; + +void main() +{ + vec3 color = uniform_color.rgb; + float alpha = uniform_color.a; + // if the fragment is outside the print volume -> use darker color + vec3 pv_check_min = ZERO; + vec3 pv_check_max = ZERO; + if (print_volume.type == 0) {// rectangle + pv_check_min = world_pos.xyz - vec3(print_volume.xy_data.x, print_volume.xy_data.y, print_volume.z_data.x); + pv_check_max = world_pos.xyz - vec3(print_volume.xy_data.z, print_volume.xy_data.w, print_volume.z_data.y); + } + else if (print_volume.type == 1) {// circle + float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy); + pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x); + pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y); + } + color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, WHITE, 0.3333) : color; + //out_color = vec4(vec3(intensity.y) + color * intensity.x, alpha); + out_color = vec4(vec3(intensity.y) + color * (intensity.x + emission_factor), alpha); +} \ No newline at end of file diff --git a/resources/shaders/140/hotbed.vs b/resources/shaders/140/hotbed.vs new file mode 100644 index 0000000000..fa2c438d67 --- /dev/null +++ b/resources/shaders/140/hotbed.vs @@ -0,0 +1,47 @@ +#version 140 + +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +#define INTENSITY_AMBIENT 0.3 + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat3 view_normal_matrix; +uniform mat4 volume_world_matrix; + +in vec3 v_position; +in vec3 v_normal; + +// x = tainted, y = specular; +out vec2 intensity; +out vec4 world_pos; +void main() +{ + // First transform the normal into camera space and normalize the result. + vec3 normal = normalize(view_normal_matrix * v_normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + world_pos = volume_world_matrix * vec4(v_position, 1.0); + vec4 position = view_model_matrix * vec4(v_position, 1.0); + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + gl_Position = projection_matrix * position; +} diff --git a/resources/shaders/140/imgui.fs b/resources/shaders/140/imgui.fs index 4b2571749f..1666c814eb 100644 --- a/resources/shaders/140/imgui.fs +++ b/resources/shaders/140/imgui.fs @@ -5,7 +5,9 @@ uniform sampler2D Texture; in vec2 Frag_UV; in vec4 Frag_Color; +out vec4 out_color; + void main() { - gl_FragColor = Frag_Color * texture(Texture, Frag_UV.st); + out_color = Frag_Color * texture(Texture, Frag_UV.st); } \ No newline at end of file diff --git a/resources/shaders/140/mm_contour.fs b/resources/shaders/140/mm_contour.fs index e74124dcae..28642d53fe 100644 --- a/resources/shaders/140/mm_contour.fs +++ b/resources/shaders/140/mm_contour.fs @@ -2,7 +2,9 @@ uniform vec4 uniform_color; +out vec4 out_color; + void main() { - gl_FragColor = uniform_color; + out_color = uniform_color; } diff --git a/resources/shaders/140/thumbnail.fs b/resources/shaders/140/thumbnail.fs index e7963328f9..366a0731f5 100644 --- a/resources/shaders/140/thumbnail.fs +++ b/resources/shaders/140/thumbnail.fs @@ -9,13 +9,15 @@ in vec2 intensity; //varying float drop; in vec4 world_pos; +out vec4 out_color; + void main() { if (world_pos.z < 0.0) discard; if(ban_light){ - gl_FragColor = uniform_color; + out_color = uniform_color; } else{ - gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); + out_color = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); } } diff --git a/resources/shaders/140/variable_layer_height.fs b/resources/shaders/140/variable_layer_height.fs index cf1fc309cc..658f812286 100644 --- a/resources/shaders/140/variable_layer_height.fs +++ b/resources/shaders/140/variable_layer_height.fs @@ -15,6 +15,8 @@ in vec2 intensity; in float object_z; +out vec4 out_color; + void main() { float object_z_row = z_to_texture_row * object_z; @@ -37,5 +39,5 @@ void main() color = mix(texture(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row + 0.5 )), -10000.), texture(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row * 2. + 1.)), 10000.), lod); // Mix the final color. - gl_FragColor = vec4(vec3(intensity.y), 1.0) + intensity.x * mix(color, vec4(1.0, 1.0, 0.0, 1.0), z_blend); + out_color = vec4(vec3(intensity.y), 1.0) + intensity.x * mix(color, vec4(1.0, 1.0, 0.0, 1.0), z_blend); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8e9a31f705..a123be1fab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,6 +15,7 @@ add_subdirectory(libslic3r) if (SLIC3R_GUI) # imgui, imguizmo, and hidapi are now included from deps_src + add_subdirectory(libvgcode) if(WIN32) message(STATUS "WXWIN environment set to: $ENV{WXWIN}") diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index 4fd9b565b3..c9ce68e3e0 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -190,6 +190,9 @@ void AppConfig::set_defaults() #endif // _WIN32 } + if (get("seq_top_layer_only").empty()) + set("seq_top_layer_only", "1"); + if (get("use_perspective_camera").empty()) set_bool("use_perspective_camera", true); diff --git a/src/libslic3r/BuildVolume.cpp b/src/libslic3r/BuildVolume.cpp index 9ce30f285c..3802fbc014 100644 --- a/src/libslic3r/BuildVolume.cpp +++ b/src/libslic3r/BuildVolume.cpp @@ -565,40 +565,6 @@ inline bool all_inside_vertices_normals_interleaved(const std::vector &pa return true; } -bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::vector& paths, const Eigen::AlignedBox& paths_bbox, bool ignore_bottom) const -{ - assert(paths.size() % 6 == 0); - static constexpr const double epsilon = BedEpsilon; - switch (m_type) { - case BuildVolume_Type::Rectangle: - { - BoundingBox3Base build_volume = this->bounding_volume().inflated(epsilon); - if (m_max_print_height == 0.0) - build_volume.max.z() = std::numeric_limits::max(); - if (ignore_bottom) - build_volume.min.z() = -std::numeric_limits::max(); - return build_volume.contains(paths_bbox.min().cast()) && build_volume.contains(paths_bbox.max().cast()); - } - case BuildVolume_Type::Circle: - { - const Vec2f c = unscaled(m_circle.center); - const float r = unscaled(m_circle.radius) + float(epsilon); - const float r2 = sqr(r); - return m_max_print_height == 0.0 ? - all_inside_vertices_normals_interleaved(paths, [c, r2](Vec3f p) { return (to_2d(p) - c).squaredNorm() <= r2; }) : - all_inside_vertices_normals_interleaved(paths, [c, r2, z = m_max_print_height + epsilon](Vec3f p) { return (to_2d(p) - c).squaredNorm() <= r2 && p.z() <= z; }); - } - case BuildVolume_Type::Convex: - //FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently. - case BuildVolume_Type::Custom: - return m_max_print_height == 0.0 ? - all_inside_vertices_normals_interleaved(paths, [this](Vec3f p) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(p).cast()); }) : - all_inside_vertices_normals_interleaved(paths, [this, z = m_max_print_height + epsilon](Vec3f p) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(p).cast()) && p.z() <= z; }); - default: - return true; - } -} - std::string_view BuildVolume::type_name(BuildVolume_Type type) { using namespace std::literals; diff --git a/src/libslic3r/BuildVolume.hpp b/src/libslic3r/BuildVolume.hpp index 6e32f46d52..6f53fdd704 100644 --- a/src/libslic3r/BuildVolume.hpp +++ b/src/libslic3r/BuildVolume.hpp @@ -118,8 +118,6 @@ public: // Called on final G-code paths. //FIXME The test does not take the thickness of the extrudates into account! bool all_paths_inside(const GCodeProcessorResult& paths, const BoundingBoxf3& paths_bbox, bool ignore_bottom = true) const; - // Called on initial G-code preview on OpenGL vertex buffer interleaved normals and vertices. - bool all_paths_inside_vertices_and_normals_interleaved(const std::vector& paths, const Eigen::AlignedBox& bbox, bool ignore_bottom = true) const; int get_extruder_area_count() const { return m_extruder_volumes.size(); } const BuildExtruderVolume& get_extruder_area_volume(int index) const; diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 657c8dc15f..1817ae326c 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -251,6 +251,8 @@ set(lisbslic3r_sources GCode/WipeTower.hpp GCodeWriter.cpp GCodeWriter.hpp + Geometry/ArcWelder.hpp + Geometry/ArcWelder.cpp Geometry/Bicubic.hpp Geometry/Circle.cpp Geometry/Circle.hpp diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 0e07e3fdb8..2d1940e448 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2006,6 +2006,7 @@ namespace DoExport { silent_time_estimator_enabled = (config.gcode_flavor == gcfMarlinLegacy || config.gcode_flavor == gcfMarlinFirmware) && config.silent_mode; processor.reset(); + processor.initialize_result_moves(); processor.apply_config(config); processor.enable_stealth_time_estimator(silent_time_estimator_enabled); } @@ -2241,9 +2242,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_max_layer_z = 0.f; m_last_width = 0.f; m_is_role_based_fan_on.fill(false); -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_last_mm3_per_mm = 0.; -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING m_fan_mover.release(); @@ -6335,14 +6333,6 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, gcode += buf; } -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - if (last_was_wipe_tower || (m_last_mm3_per_mm != path.mm3_per_mm)) { - m_last_mm3_per_mm = path.mm3_per_mm; - sprintf(buf, ";%s%f\n", GCodeProcessor::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); - gcode += buf; - } -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - if (last_was_wipe_tower || std::abs(m_last_height - path.height) > EPSILON) { m_last_height = path.height; sprintf(buf, ";%s%g\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height).c_str(), m_last_height); diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 30c48df054..b2047bd3aa 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -572,9 +572,6 @@ private: float m_last_layer_z{ 0.0f }; float m_max_layer_z{ 0.0f }; float m_last_width{ 0.0f }; -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - double m_last_mm3_per_mm; -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING // Always check gcode placeholders when building in debug mode. #if !defined(NDEBUG) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index bd413d3782..d772d1d341 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -32,6 +32,8 @@ #include +#include "Geometry/ArcWelder.hpp" + static const float DEFAULT_TOOLPATH_WIDTH = 0.4f; static const float DEFAULT_TOOLPATH_HEIGHT = 0.2f; @@ -109,10 +111,6 @@ const float GCodeProcessor::Wipe_Height = 0.05f; bool GCodeProcessor::s_IsBBLPrinter = true; -#if ENABLE_GCODE_VIEWER_DATA_CHECKING -const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "MM3_PER_MM:"; -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - static void set_option_value(ConfigOptionFloats& option, size_t id, float value) { if (id < option.values.size()) @@ -138,7 +136,7 @@ static float intersection_distance(float initial_rate, float final_rate, float a static float speed_from_distance(float initial_feedrate, float distance, float acceleration) { // to avoid invalid negative numbers due to numerical errors - float value = std::max(0.0f, sqr(initial_feedrate) + 2.0f * acceleration * distance); + const float value = std::max(0.0f, sqr(initial_feedrate) + 2.0f * acceleration * distance); return ::sqrt(value); } @@ -147,7 +145,7 @@ static float speed_from_distance(float initial_feedrate, float distance, float a static float max_allowable_speed(float acceleration, float target_velocity, float distance) { // to avoid invalid negative numbers due to numerical errors - float value = std::max(0.0f, sqr(target_velocity) - 2.0f * acceleration * distance); + const float value = std::max(0.0f, sqr(target_velocity) - 2.0f * acceleration * distance); return std::sqrt(value); } @@ -242,30 +240,18 @@ void GCodeProcessor::CpColor::reset() float GCodeProcessor::Trapezoid::acceleration_time(float entry_feedrate, float acceleration) const { - return acceleration_time_from_distance(entry_feedrate, accelerate_until, acceleration); -} - -float GCodeProcessor::Trapezoid::cruise_time() const -{ - return (cruise_feedrate != 0.0f) ? cruise_distance() / cruise_feedrate : 0.0f; + return acceleration_time_from_distance(entry_feedrate, acceleration_distance(), acceleration); } float GCodeProcessor::Trapezoid::deceleration_time(float distance, float acceleration) const { - return acceleration_time_from_distance(cruise_feedrate, (distance - decelerate_after), -acceleration); -} - -float GCodeProcessor::Trapezoid::cruise_distance() const -{ - return decelerate_after - accelerate_until; + return acceleration_time_from_distance(cruise_feedrate, deceleration_distance(distance), -acceleration); } void GCodeProcessor::TimeBlock::calculate_trapezoid() { - trapezoid.cruise_feedrate = feedrate_profile.cruise; - float accelerate_distance = std::max(0.0f, estimated_acceleration_distance(feedrate_profile.entry, feedrate_profile.cruise, acceleration)); - float decelerate_distance = std::max(0.0f, estimated_acceleration_distance(feedrate_profile.cruise, feedrate_profile.exit, -acceleration)); + const float decelerate_distance = std::max(0.0f, estimated_acceleration_distance(feedrate_profile.cruise, feedrate_profile.exit, -acceleration)); float cruise_distance = distance - accelerate_distance - decelerate_distance; // Not enough space to reach the nominal feedrate. @@ -276,18 +262,13 @@ void GCodeProcessor::TimeBlock::calculate_trapezoid() cruise_distance = 0.0f; trapezoid.cruise_feedrate = speed_from_distance(feedrate_profile.entry, accelerate_distance, acceleration); } + else + trapezoid.cruise_feedrate = feedrate_profile.cruise; trapezoid.accelerate_until = accelerate_distance; trapezoid.decelerate_after = accelerate_distance + cruise_distance; } -float GCodeProcessor::TimeBlock::time() const -{ - return trapezoid.acceleration_time(feedrate_profile.entry, acceleration) - + trapezoid.cruise_time() - + trapezoid.deceleration_time(distance, acceleration); -} - void GCodeProcessor::TimeMachine::State::reset() { feedrate = 0.0f; @@ -323,53 +304,60 @@ void GCodeProcessor::TimeMachine::reset() gcode_time.reset(); blocks = std::vector(); g1_times_cache = std::vector(); - std::fill(moves_time.begin(), moves_time.end(), 0.0f); - std::fill(roles_time.begin(), roles_time.end(), 0.0f); - layers_time = std::vector(); + first_layer_time = 0.0f; prepare_time = 0.0f; } -void GCodeProcessor::TimeMachine::simulate_st_synchronize(float additional_time) +static void planner_forward_pass_kernel(const GCodeProcessor::TimeBlock& prev, GCodeProcessor::TimeBlock& curr) { - if (!enabled) - return; - - calculate_time(0, additional_time); -} - -static void planner_forward_pass_kernel(GCodeProcessor::TimeBlock& prev, GCodeProcessor::TimeBlock& curr) -{ - // If the previous block is an acceleration block, but it is not long enough to complete the - // full speed change within the block, we need to adjust the entry speed accordingly. Entry - // speeds have already been reset, maximized, and reverse planned by reverse planner. - // If nominal length is true, max junction speed is guaranteed to be reached. No need to recheck. - if (!prev.flags.nominal_length) { - if (prev.feedrate_profile.entry < curr.feedrate_profile.entry) { - float entry_speed = std::min(curr.feedrate_profile.entry, max_allowable_speed(-prev.acceleration, prev.feedrate_profile.entry, prev.distance)); - - // Check for junction speed change - if (curr.feedrate_profile.entry != entry_speed) { - curr.feedrate_profile.entry = entry_speed; - curr.flags.recalculate = true; - } + // + // C:\prusa\firmware\Prusa-Firmware-Buddy\lib\Marlin\Marlin\src\module\planner.cpp + // Line 954 + // + // If the previous block is an acceleration block, too short to complete the full speed + // change, adjust the entry speed accordingly. Entry speeds have already been reset, + // maximized, and reverse-planned. If nominal length is set, max junction speed is + // guaranteed to be reached. No need to recheck. + if (!prev.flags.nominal_length && prev.feedrate_profile.entry < curr.feedrate_profile.entry) { + // Compute the maximum allowable speed + const float new_entry_speed = max_allowable_speed(-prev.acceleration, prev.feedrate_profile.entry, prev.distance); + // If true, current block is full-acceleration and we can move the planned pointer forward. + if (new_entry_speed < curr.feedrate_profile.entry) { + // Always <= max_entry_speed_sqr. Backward pass sets this. + curr.feedrate_profile.entry = new_entry_speed; + curr.flags.recalculate = true; } } } -void planner_reverse_pass_kernel(GCodeProcessor::TimeBlock& curr, GCodeProcessor::TimeBlock& next) +static void planner_reverse_pass_kernel(GCodeProcessor::TimeBlock& curr, const GCodeProcessor::TimeBlock& next) { - // If entry speed is already at the maximum entry speed, no need to recheck. Block is cruising. - // If not, block in state of acceleration or deceleration. Reset entry speed to maximum and - // check for maximum allowable speed reductions to ensure maximum possible planned speed. - if (curr.feedrate_profile.entry != curr.max_entry_speed) { - // If nominal length true, max junction speed is guaranteed to be reached. Only compute - // for max allowable speed if block is decelerating and nominal length is false. - if (!curr.flags.nominal_length && curr.max_entry_speed > next.feedrate_profile.entry) - curr.feedrate_profile.entry = std::min(curr.max_entry_speed, max_allowable_speed(-curr.acceleration, next.feedrate_profile.entry, curr.distance)); - else - curr.feedrate_profile.entry = curr.max_entry_speed; - - curr.flags.recalculate = true; + // + // C:\prusa\firmware\Prusa-Firmware-Buddy\lib\Marlin\Marlin\src\module\planner.cpp + // Line 857 + // + // If entry speed is already at the maximum entry speed, and there was no change of speed + // in the next block, there is no need to recheck. Block is cruising and there is no need to + // compute anything for this block, + // If not, block entry speed needs to be recalculated to ensure maximum possible planned speed. + const float max_entry_speed = curr.max_entry_speed; + // Compute maximum entry speed decelerating over the current block from its exit speed. + // If not at the maximum entry speed, or the previous block entry speed changed + if (curr.feedrate_profile.entry != max_entry_speed || next.flags.recalculate) { + // If nominal length true, max junction speed is guaranteed to be reached. + // If a block can de/ac-celerate from nominal speed to zero within the length of the block, then + // the current block and next block junction speeds are guaranteed to always be at their maximum + // junction speeds in deceleration and acceleration, respectively. This is due to how the current + // block nominal speed limits both the current and next maximum junction speeds. Hence, in both + // the reverse and forward planners, the corresponding block junction speed will always be at the + // the maximum junction speed and may always be ignored for any speed reduction checks. + const float new_entry_speed = curr.flags.nominal_length ? max_entry_speed : + std::min(max_entry_speed, max_allowable_speed(-curr.acceleration, next.feedrate_profile.entry, curr.distance)); + if (curr.feedrate_profile.entry != new_entry_speed) { + // Just Set the new entry speed. + curr.feedrate_profile.entry = new_entry_speed; + curr.flags.recalculate = true; + } } } @@ -379,7 +367,7 @@ static void recalculate_trapezoids(std::vector& block GCodeProcessor::TimeBlock* next = nullptr; for (size_t i = 0; i < blocks.size(); ++i) { - GCodeProcessor::TimeBlock& b = blocks[i]; + GCodeProcessor::TimeBlock& b = blocks[i]; curr = next; next = &b; @@ -388,10 +376,8 @@ static void recalculate_trapezoids(std::vector& block // Recalculate if current block entry or exit junction speed has changed. if (curr->flags.recalculate || next->flags.recalculate) { // NOTE: Entry and exit factors always > 0 by all previous logic operations. - GCodeProcessor::TimeBlock block = *curr; - block.feedrate_profile.exit = next->feedrate_profile.entry; - block.calculate_trapezoid(); - curr->trapezoid = block.trapezoid; + curr->feedrate_profile.exit = next->feedrate_profile.entry; + curr->calculate_trapezoid(); curr->flags.recalculate = false; // Reset current only to ensure next trapezoid is computed } } @@ -399,68 +385,159 @@ static void recalculate_trapezoids(std::vector& block // Last/newest block in buffer. Always recalculated. if (next != nullptr) { - GCodeProcessor::TimeBlock block = *next; - block.feedrate_profile.exit = next->safe_feedrate; - block.calculate_trapezoid(); - next->trapezoid = block.trapezoid; + next->feedrate_profile.exit = next->safe_feedrate; + next->calculate_trapezoid(); next->flags.recalculate = false; } } -void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks, float additional_time) +void GCodeProcessor::TimeMachine::calculate_time(GCodeProcessorResult& result, PrintEstimatedStatistics::ETimeMode mode, size_t keep_last_n_blocks, float additional_time) { if (!enabled || blocks.size() < 2) return; assert(keep_last_n_blocks <= blocks.size()); + // reverse_pass + for (int i = static_cast(blocks.size()) - 1; i > 0; --i) { + planner_reverse_pass_kernel(blocks[i - 1], blocks[i]); + } + // forward_pass for (size_t i = 0; i + 1 < blocks.size(); ++i) { planner_forward_pass_kernel(blocks[i], blocks[i + 1]); } - // reverse_pass - for (int i = static_cast(blocks.size()) - 1; i > 0; --i) - planner_reverse_pass_kernel(blocks[i - 1], blocks[i]); - recalculate_trapezoids(blocks); - size_t n_blocks_process = blocks.size() - keep_last_n_blocks; + const size_t n_blocks_process = blocks.size() - keep_last_n_blocks; for (size_t i = 0; i < n_blocks_process; ++i) { const TimeBlock& block = blocks[i]; float block_time = block.time(); if (i == 0) block_time += additional_time; - time += block_time; + time += double(block_time); + result.moves[block.move_id].time[static_cast(mode)] = block_time; gcode_time.cache += block_time; - //BBS: don't calculate travel of start gcode into travel time - if (!block.flags.prepare_stage || block.move_type != EMoveType::Travel) - moves_time[static_cast(block.move_type)] += block_time; - roles_time[static_cast(block.role)] += block_time; - if (block.layer_id >= layers_time.size()) { - const size_t curr_size = layers_time.size(); - layers_time.resize(block.layer_id); - for (size_t i = curr_size; i < layers_time.size(); ++i) { - layers_time[i] = 0.0f; - } - } - layers_time[block.layer_id - 1] += block_time; //BBS if (block.flags.prepare_stage) prepare_time += block_time; - g1_times_cache.push_back({ block.g1_line_id, block.remaining_internal_g1_lines, time }); + + if (block.layer_id == 1) + first_layer_time += block_time; + + // detect actual speed moves required to render toolpaths using actual speed + if (mode == PrintEstimatedStatistics::ETimeMode::Normal) { + GCodeProcessorResult::MoveVertex& curr_move = result.moves[block.move_id]; + if (curr_move.type != EMoveType::Extrude && + curr_move.type != EMoveType::Travel && + curr_move.type != EMoveType::Wipe) + continue; + + assert(curr_move.actual_feedrate == 0.0f); + + GCodeProcessorResult::MoveVertex& prev_move = result.moves[block.move_id - 1]; + const bool interpolate = (prev_move.type == curr_move.type); + if (!interpolate && + prev_move.type != EMoveType::Extrude && + prev_move.type != EMoveType::Travel && + prev_move.type != EMoveType::Wipe) + prev_move.actual_feedrate = block.feedrate_profile.entry; + + if (EPSILON < block.trapezoid.accelerate_until && block.trapezoid.accelerate_until < block.distance - EPSILON) { + const float t = block.trapezoid.accelerate_until / block.distance; + const Vec3f position = lerp(prev_move.position, curr_move.position, t); + if ((position - prev_move.position).norm() > EPSILON && + (position - curr_move.position).norm() > EPSILON) { + const float delta_extruder = interpolate ? lerp(prev_move.delta_extruder, curr_move.delta_extruder, t) : curr_move.delta_extruder; + const float feedrate = interpolate ? lerp(prev_move.feedrate, curr_move.feedrate, t) : curr_move.feedrate; + const float width = interpolate ? lerp(prev_move.width, curr_move.width, t) : curr_move.width; + const float height = interpolate ? lerp(prev_move.height, curr_move.height, t) : curr_move.height; + // ORCA: Fix issue with flow rate changes being visualized incorrectly + const float mm3_per_mm = curr_move.mm3_per_mm; + const float fan_speed = interpolate ? lerp(prev_move.fan_speed, curr_move.fan_speed, t) : curr_move.fan_speed; + const float temperature = interpolate ? lerp(prev_move.temperature, curr_move.temperature, t) : curr_move.temperature; + actual_speed_moves.push_back({ + block.move_id, + position, + block.trapezoid.cruise_feedrate, + delta_extruder, + feedrate, + width, + height, + mm3_per_mm, + fan_speed, + temperature + }); + } + } + + const bool has_deceleration = block.trapezoid.deceleration_distance(block.distance) > EPSILON; + if (has_deceleration && block.trapezoid.decelerate_after > block.trapezoid.accelerate_until + EPSILON) { + const float t = block.trapezoid.decelerate_after / block.distance; + const Vec3f position = lerp(prev_move.position, curr_move.position, t); + if ((position - prev_move.position).norm() > EPSILON && + (position - curr_move.position).norm() > EPSILON) { + const float delta_extruder = interpolate ? lerp(prev_move.delta_extruder, curr_move.delta_extruder, t) : curr_move.delta_extruder; + const float feedrate = interpolate ? lerp(prev_move.feedrate, curr_move.feedrate, t) : curr_move.feedrate; + const float width = interpolate ? lerp(prev_move.width, curr_move.width, t) : curr_move.width; + const float height = interpolate ? lerp(prev_move.height, curr_move.height, t) : curr_move.height; + // ORCA: Fix issue with flow rate changes being visualized incorrectly + const float mm3_per_mm = curr_move.mm3_per_mm; + const float fan_speed = interpolate ? lerp(prev_move.fan_speed, curr_move.fan_speed, t) : curr_move.fan_speed; + const float temperature = interpolate ? lerp(prev_move.temperature, curr_move.temperature, t) : curr_move.temperature; + actual_speed_moves.push_back({ + block.move_id, + position, + block.trapezoid.cruise_feedrate, + delta_extruder, + feedrate, + width, + height, + mm3_per_mm, + fan_speed, + temperature + }); + } + } + + const bool is_cruise_only = block.trapezoid.is_cruise_only(block.distance); + actual_speed_moves.push_back({ + block.move_id, + std::nullopt, + (is_cruise_only || !has_deceleration) ? block.trapezoid.cruise_feedrate : block.feedrate_profile.exit, + std::nullopt, + std::nullopt, + std::nullopt, + std::nullopt, + std::nullopt, + std::nullopt, + std::nullopt + }); + } + g1_times_cache.push_back({ block.g1_line_id, block.remaining_internal_g1_lines, float(time) }); // update times for remaining time to printer stop placeholders auto it_stop_time = std::lower_bound(stop_times.begin(), stop_times.end(), block.g1_line_id, [](const StopTime& t, unsigned int value) { return t.g1_line_id < value; }); if (it_stop_time != stop_times.end() && it_stop_time->g1_line_id == block.g1_line_id) - it_stop_time->elapsed_time = time; + it_stop_time->elapsed_time = float(time); } - if (keep_last_n_blocks) + if (keep_last_n_blocks) { blocks.erase(blocks.begin(), blocks.begin() + n_blocks_process); - else + + // Ensure that the new first block's entry speed will be preserved to prevent discontinuity + // between the erased blocks' exit speed and the new first block's entry speed. + // Otherwise, the first block's entry speed could be recalculated on the next pass without + // considering that there are no more blocks before this first block. This could lead + // to discontinuity between the exit speed (of already processed blocks) and the entry + // speed of the first block. + TimeBlock &first_block = blocks.front(); + first_block.max_entry_speed = first_block.feedrate_profile.entry; + } else { blocks.clear(); + } } void GCodeProcessor::TimeProcessor::reset() @@ -1431,35 +1508,6 @@ void GCodeProcessor::UsedFilaments::process_caches(GCodeProcessor* processor) process_total_volume_cache(processor); } -#if ENABLE_GCODE_VIEWER_STATISTICS -void GCodeProcessorResult::reset() { - //BBS: add mutex for protection of gcode result - lock(); - - moves = std::vector(); - printable_area = Pointfs(); - //BBS: add bed exclude area - bed_exclude_area = Pointfs(); - wrapping_exclude_area = Pointfs(); - //BBS: add toolpath_outside - toolpath_outside = false; - //BBS: add label_object_enabled - label_object_enabled = false; - timelapse_warning_code = 0; - printable_height = 0.0f; - settings_ids.reset(); - extruders_count = 0; - extruder_colors = std::vector(); - filament_diameters = std::vector(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DIAMETER); - filament_densities = std::vector(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DENSITY); - custom_gcode_per_print_z = std::vector(); - spiral_vase_layers = std::vector>>(); - time = 0; - - //BBS: add mutex for protection of gcode result - unlock(); -} -#else void GCodeProcessorResult::reset() { //BBS: add mutex for protection of gcode result lock(); @@ -1486,7 +1534,7 @@ void GCodeProcessorResult::reset() { filament_densities = std::vector(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DENSITY); filament_costs = std::vector(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_COST); custom_gcode_per_print_z = std::vector(); - spiral_vase_layers = std::vector>>(); + spiral_vase_mode = false; layer_filaments.clear(); filament_change_count_map.clear(); warnings.clear(); @@ -1496,7 +1544,6 @@ void GCodeProcessorResult::reset() { //BBS: add logs BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: this=%2% reset finished")%__LINE__%this; } -#endif // ENABLE_GCODE_VIEWER_STATISTICS const std::vector> GCodeProcessor::Producers = { //BBS: OrcaSlicer is also "bambu". Otherwise the time estimation didn't work. @@ -1589,8 +1636,8 @@ void GCodeProcessor::register_commands() std::unordered_map command_handler_list = { {"G0", [this](const GCodeReader::GCodeLine& line) { process_G0(line); }}, // Move {"G1", [this](const GCodeReader::GCodeLine& line) { process_G1(line); }}, // Move - {"G2", [this](const GCodeReader::GCodeLine& line) { process_G2_G3(line); }}, // Move - {"G3", [this](const GCodeReader::GCodeLine& line) { process_G2_G3(line); }}, // Move + {"G2", [this](const GCodeReader::GCodeLine& line) { process_G2_G3(line, true); }}, // Move + {"G3", [this](const GCodeReader::GCodeLine& line) { process_G2_G3(line, false); }}, // Move {"G4", [this](const GCodeReader::GCodeLine& line) { process_G4(line); }}, // Delay {"G10", [this](const GCodeReader::GCodeLine& line) { process_G10(line); }}, // Retract @@ -1702,23 +1749,23 @@ bool GCodeProcessor::check_multi_extruder_gcode_valid(const int // sometimes, the start line extrude was outside the edge of plate a little, this is allowed, so do not include into the gcode_path_pos if (move.type == EMoveType::Extrude /* && move.extrusion_role != ExtrusionRole::erFlush || move.type == EMoveType::Travel*/) if (move.extrusion_role == ExtrusionRole::erCustom) { - if (move.is_arc_move_with_interpolation_points()) { + /*if (move.is_arc_move_with_interpolation_points()) { for (int i = 0; i < move.interpolation_points.size(); i++) { gcode_path_pos[move.object_label_id][int(move.extruder_id)].pos_custom.emplace_back(to_2d(move.interpolation_points[i].cast())); } - } else { + } else {*/ gcode_path_pos[move.object_label_id][int(move.extruder_id)].pos_custom.emplace_back(to_2d(move.position.cast())); - } + //} gcode_path_pos[move.object_label_id][int(move.extruder_id)].max_print_z_custom = std::max(gcode_path_pos[move.object_label_id][int(move.extruder_id)].max_print_z_custom, move.print_z); } else { - if (move.is_arc_move_with_interpolation_points()) { + /*if (move.is_arc_move_with_interpolation_points()) { for (int i = 0; i < move.interpolation_points.size(); i++) { gcode_path_pos[move.object_label_id][int(move.extruder_id)].pos.emplace_back(to_2d(move.interpolation_points[i].cast())); } - } else { + } else {*/ gcode_path_pos[move.object_label_id][int(move.extruder_id)].pos.emplace_back(to_2d(move.position.cast())); - } + //} gcode_path_pos[move.object_label_id][int(move.extruder_id)].max_print_z = std::max(gcode_path_pos[move.object_label_id][int(move.extruder_id)].max_print_z, move.print_z); } @@ -1839,7 +1886,7 @@ void GCodeProcessor::apply_config(const PrintConfig& config) size_t filament_count = config.filament_diameter.values.size(); m_result.filaments_count = filament_count; - // Orca: + // Orca: m_is_XL_printer = is_XL_printer(config); m_preheat_time = config.preheat_time; m_preheat_steps = config.preheat_steps; @@ -1943,8 +1990,10 @@ void GCodeProcessor::apply_config(const PrintConfig& config) } const ConfigOptionBool* spiral_vase = config.option("spiral_mode"); - if (spiral_vase != nullptr) + if (spiral_vase != nullptr) { m_detect_layer_based_on_tag = spiral_vase->value; + m_result.spiral_vase_mode = spiral_vase->value; + } const ConfigOptionBool* has_scarf_joint_seam = config.option("has_scarf_joint_seam"); if (has_scarf_joint_seam != nullptr) @@ -2271,8 +2320,10 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) m_result.printable_height = printable_height->value; const ConfigOptionBool* spiral_vase = config.option("spiral_mode"); - if (spiral_vase != nullptr) + if (spiral_vase != nullptr) { m_detect_layer_based_on_tag = spiral_vase->value; + m_result.spiral_vase_mode = spiral_vase->value; + } const ConfigOptionBool* has_scarf_joint_seam = config.option("has_scarf_joint_seam"); if (has_scarf_joint_seam != nullptr) @@ -2311,9 +2362,6 @@ void GCodeProcessor::reset() m_virtual_flushing = false; m_wipe_tower = false; m_remaining_volume = std::vector(MAXIMUM_EXTRUDER_NUMBER, 0.f); - // BBS: arc move related data - m_move_path_type = EMovePathType::Noop_move; - m_arc_center = Vec3f::Zero(); m_line_id = 0; m_last_line_id = 0; @@ -2370,12 +2418,6 @@ void GCodeProcessor::reset() m_seams_count = 0; m_preheat_time = 0.f; m_preheat_steps = 1; - -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_mm3_per_mm_compare.reset(); - m_height_compare.reset(); - m_width_compare.reset(); -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING } static inline const char* skip_whitespaces(const char *begin, const char *end) { @@ -2404,10 +2446,6 @@ void GCodeProcessor::process_file(const std::string& filename, std::function(PrintEstimatedStatistics::ETimeMode::Count); ++i) { TimeMachine& machine = m_time_processor.machines[i]; TimeMachine::CustomGCodeTime& gcode_time = machine.gcode_time; - machine.calculate_time(); if (gcode_time.needed && gcode_time.cache != 0.0f) gcode_time.times.push_back({ CustomGCode::ColorChange, gcode_time.cache }); } @@ -2526,43 +2560,19 @@ void GCodeProcessor::finalize(bool post_process) m_used_filaments.process_caches(this); update_estimated_times_stats(); - auto time_mode = m_result.print_statistics.modes[static_cast(PrintEstimatedStatistics::ETimeMode::Normal)]; - auto it = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [](const std::pair& item) { return erCustom == item.first; }); - auto prepare_time = (it != time_mode.roles_times.end()) ? it->second : 0.0f; + m_result.initial_layer_time = get_first_layer_time(PrintEstimatedStatistics::ETimeMode::Normal); - std::vector& layer_times = m_result.print_statistics.modes[static_cast(PrintEstimatedStatistics::ETimeMode::Normal)].layers_times; - m_result.initial_layer_time = layer_times.size() > 0 ? std::max(float(0.0), layer_times[0] - prepare_time) : 0; - - //update times for results - for (size_t i = 0; i < m_result.moves.size(); i++) { - //field layer_duration contains the layer id for the move in which the layer_duration has to be set. - size_t layer_id = size_t(m_result.moves[i].layer_duration); - if (layer_times.size() > layer_id - 1 && layer_id > 0) - m_result.moves[i].layer_duration = layer_id == 1 ? std::max(0.f,layer_times[layer_id - 1] - prepare_time) : layer_times[layer_id - 1]; - else - m_result.moves[i].layer_duration = 0; - } - -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - std::cout << "\n"; - m_mm3_per_mm_compare.output(); - m_height_compare.output(); - m_width_compare.output(); -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING if (post_process){ run_post_process(); } -#if ENABLE_GCODE_VIEWER_STATISTICS - m_result.time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - m_start_time).count(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS //BBS: update slice warning update_slice_warnings(); } float GCodeProcessor::get_time(PrintEstimatedStatistics::ETimeMode mode) const { - return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? m_time_processor.machines[static_cast(mode)].time : 0.0f; + return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? float(m_time_processor.machines[static_cast(mode)].time) : 0.0f; } float GCodeProcessor::get_prepare_time(PrintEstimatedStatistics::ETimeMode mode) const @@ -2572,7 +2582,7 @@ float GCodeProcessor::get_prepare_time(PrintEstimatedStatistics::ETimeMode mode) std::string GCodeProcessor::get_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const { - return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? short_time(get_time_dhms(m_time_processor.machines[static_cast(mode)].time)) : std::string("N/A"); + return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? short_time(get_time_dhms(float(m_time_processor.machines[static_cast(mode)].time))) : std::string("N/A"); } std::vector>> GCodeProcessor::get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const @@ -2590,32 +2600,6 @@ std::vector>> GCodeProcesso return ret; } -std::vector> GCodeProcessor::get_moves_time(PrintEstimatedStatistics::ETimeMode mode) const -{ - std::vector> ret; - if (mode < PrintEstimatedStatistics::ETimeMode::Count) { - for (size_t i = 0; i < m_time_processor.machines[static_cast(mode)].moves_time.size(); ++i) { - float time = m_time_processor.machines[static_cast(mode)].moves_time[i]; - if (time > 0.0f) - ret.push_back({ static_cast(i), time }); - } - } - return ret; -} - -std::vector> GCodeProcessor::get_roles_time(PrintEstimatedStatistics::ETimeMode mode) const -{ - std::vector> ret; - if (mode < PrintEstimatedStatistics::ETimeMode::Count) { - for (size_t i = 0; i < m_time_processor.machines[static_cast(mode)].roles_time.size(); ++i) { - float time = m_time_processor.machines[static_cast(mode)].roles_time[i]; - if (time > 0.0f) - ret.push_back({ static_cast(i), time }); - } - } - return ret; -} - ConfigSubstitutions load_from_superslicer_gcode_file(const std::string& filename, DynamicPrintConfig& config, ForwardCompatibilitySubstitutionRule compatibility_rule) { // for reference, see: ConfigBase::load_from_gcode_file() @@ -2649,11 +2633,9 @@ void GCodeProcessor::apply_config_superslicer(const std::string& filename) apply_config(config); } -std::vector GCodeProcessor::get_layers_time(PrintEstimatedStatistics::ETimeMode mode) const +float GCodeProcessor::get_first_layer_time(PrintEstimatedStatistics::ETimeMode mode) const { - return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? - m_time_processor.machines[static_cast(mode)].layers_time : - std::vector(); + return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? m_time_processor.machines[static_cast(mode)].first_layer_time : 0.0f; } void GCodeProcessor::apply_config_simplify3d(const std::string& filename) @@ -3050,7 +3032,7 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers m_virtual_flushing = false; return; } - + // Orca: Integrate filament consumption for purging performed to an external device and controlled via macros // (eg. Happy Hare) in the filament consumption stats. if (boost::starts_with(comment, GCodeProcessor::External_Purge_Tag)) { @@ -3062,7 +3044,7 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers float filament_diameter = (static_cast(filament_id) < m_result.filament_diameters.size()) ? m_result.filament_diameters[filament_id] : m_result.filament_diameters.back(); float filament_radius = 0.5f * filament_diameter; float area_filament_cross_section = static_cast(M_PI) * sqr(filament_radius); - + float dE = std::stof(match.str()); float volume_extruded_filament = area_filament_cross_section * dE; m_used_filaments.update_flush_per_filament(filament_id, volume_extruded_filament); @@ -3185,29 +3167,8 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers // layer change tag if (comment == reserved_tag(ETags::Layer_Change)) { ++m_layer_id; - if (m_detect_layer_based_on_tag) { - if (m_result.moves.empty() || m_result.spiral_vase_layers.empty()) - // add a placeholder for layer height. the actual value will be set inside process_G1() method - m_result.spiral_vase_layers.push_back({ FLT_MAX, { 0, 0 } }); - else { - const size_t move_id = m_result.moves.size() - 1 - m_seams_count; - if (!m_result.spiral_vase_layers.empty()) - m_result.spiral_vase_layers.back().second.second = move_id; - // add a placeholder for layer height. the actual value will be set inside process_G1() method - m_result.spiral_vase_layers.push_back({ FLT_MAX, { move_id, move_id } }); - } - } return; } - -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - // mm3_per_mm print tag - if (boost::starts_with(comment, Mm3_Per_Mm_Tag)) { - if (! parse_number(comment.substr(Mm3_Per_Mm_Tag.size()), m_mm3_per_mm_compare.last_tag_value)) - BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Mm3_Per_Mm (" << comment << ")."; - return; - } -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING } bool GCodeProcessor::process_producers_tags(const std::string_view comment) @@ -3695,45 +3656,60 @@ void GCodeProcessor::process_G0(const GCodeReader::GCodeLine& line) } void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line, const std::optional& remaining_internal_g1_lines) +{ + std::array, 4> g1_axes = { std::nullopt, std::nullopt, std::nullopt, std::nullopt }; + if (line.has_x()) g1_axes[X] = (double)line.x(); + if (line.has_y()) g1_axes[Y] = (double)line.y(); + if (line.has_z()) g1_axes[Z] = (double)line.z(); + if (line.has_e()) g1_axes[E] = (double)line.e(); + std::optional g1_feedrate = std::nullopt; + if (line.has_f()) g1_feedrate = (double)line.f(); + process_G1(g1_axes, g1_feedrate); +} + +void GCodeProcessor::process_G1(const std::array, 4>& axes, const std::optional& feedrate, + G1DiscretizationOrigin origin, const std::optional& remaining_internal_g1_lines) { int filament_id = get_filament_id(); int last_filament_id = get_last_filament_id(); float filament_diameter = (static_cast(filament_id) < m_result.filament_diameters.size()) ? m_result.filament_diameters[filament_id] : m_result.filament_diameters.back(); float filament_radius = 0.5f * filament_diameter; float area_filament_cross_section = static_cast(M_PI) * sqr(filament_radius); - auto absolute_position = [this, area_filament_cross_section](Axis axis, const GCodeReader::GCodeLine& lineG1) { - bool is_relative = (m_global_positioning_type == EPositioningType::Relative); - if (axis == E) - is_relative |= (m_e_local_positioning_type == EPositioningType::Relative); - if (lineG1.has(Slic3r::Axis(axis))) { - float lengthsScaleFactor = (m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f; - float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor; + auto move_type = [this](const AxisCoords& delta_pos) { + if (m_wiping) + return EMoveType::Wipe; + else if (delta_pos[E] < 0.0f) + return (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) ? EMoveType::Travel : EMoveType::Retract; + else if (delta_pos[E] > 0.0f) { + if (delta_pos[X] == 0.0f && delta_pos[Y] == 0.0f) + return (delta_pos[Z] == 0.0f) ? EMoveType::Unretract : EMoveType::Travel; + else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f) + return EMoveType::Extrude; + } + else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) + return EMoveType::Travel; + + return EMoveType::Noop; + }; + + auto extract_absolute_position_on_axis = [&](Axis axis, std::optional value, double area_filament_cross_section) + { + if (value.has_value()) { + bool is_relative = (m_global_positioning_type == EPositioningType::Relative); + if (axis == E) + is_relative |= (m_e_local_positioning_type == EPositioningType::Relative); + + const double lengthsScaleFactor = (m_units == EUnits::Inches) ? double(INCHES_TO_MM) : 1.0; + double ret = *value * lengthsScaleFactor; + // if (axis == E && m_use_volumetric_e) + // ret /= area_filament_cross_section; return is_relative ? m_start_position[axis] + ret : m_origin[axis] + ret; } else return m_start_position[axis]; }; - auto move_type = [this](const AxisCoords& delta_pos) { - EMoveType type = EMoveType::Noop; - - if (m_wiping) - type = EMoveType::Wipe; - else if (delta_pos[E] < 0.0f) - type = (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) ? EMoveType::Travel : EMoveType::Retract; - else if (delta_pos[E] > 0.0f) { - if (delta_pos[X] == 0.0f && delta_pos[Y] == 0.0f) - type = (delta_pos[Z] == 0.0f) ? EMoveType::Unretract : EMoveType::Travel; - else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f) - type = EMoveType::Extrude; - } - else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) - type = EMoveType::Travel; - - return type; - }; - ++m_g1_line_id; // enable processing of lines M201/M203/M204/M205 @@ -3741,12 +3717,12 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line, const std::o // updates axes positions from line for (unsigned char a = X; a <= E; ++a) { - m_end_position[a] = absolute_position((Axis)a, line); + m_end_position[a] = extract_absolute_position_on_axis((Axis)a, axes[a], double(area_filament_cross_section)); } // updates feedrate from line, if present - if (line.has_f()) - m_feedrate = line.f() * MMMIN_TO_MMSEC; + if (feedrate.has_value()) + m_feedrate = (*feedrate) * MMMIN_TO_MMSEC; // calculates movement deltas float max_abs_delta = 0.0f; @@ -3778,13 +3754,10 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line, const std::o } // volume extruded filament / tool displacement = area toolpath cross section m_mm3_per_mm = area_toolpath_cross_section; -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_mm3_per_mm_compare.update(area_toolpath_cross_section, m_extrusion_role); -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING if (m_forced_height > 0.0f) m_height = m_forced_height; - else { + else if (origin == G1DiscretizationOrigin::G1) { if (m_end_position[Z] > m_extruded_last_z + EPSILON) m_height = m_end_position[Z] - m_extruded_last_z; } @@ -3795,13 +3768,10 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line, const std::o if (m_end_position[Z] == 0.0f) m_end_position[Z] = m_height; - m_extruded_last_z = m_end_position[Z]; + if (origin == G1DiscretizationOrigin::G1) + m_extruded_last_z = m_end_position[Z]; m_options_z_corrector.update(m_height); -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_height_compare.update(m_height, m_extrusion_role); -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - if (m_forced_width > 0.0f) m_width = m_forced_width; else if (m_extrusion_role == erExternalPerimeter) @@ -3819,10 +3789,6 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line, const std::o // clamp width to avoid artifacts which may arise from wrong values of m_height m_width = std::min(m_width, std::max(2.0f, 4.0f * m_height)); - -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_width_compare.update(m_width, m_extrusion_role); -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING } else if (type == EMoveType::Unretract && m_flushing) { int extruder_id = get_extruder_id(); @@ -3879,6 +3845,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line, const std::o block.role = (type != EMoveType::Travel || m_extrusion_role == erCustom) ? m_extrusion_role : erNone; block.distance = distance; block.g1_line_id = m_g1_line_id; + block.move_id = static_cast(m_result.moves.size()); block.remaining_internal_g1_lines = remaining_internal_g1_lines.has_value() ? *remaining_internal_g1_lines : 0; block.layer_id = std::max(1, m_layer_id); block.flags.prepare_stage = m_processing_start_custom_gcode; @@ -4059,11 +4026,11 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line, const std::o prev = curr; blocks.push_back(block); - - if (blocks.size() > TimeProcessor::Planner::refresh_threshold) - machine.calculate_time(TimeProcessor::Planner::queue_size); } + if (m_time_processor.machines[0].blocks.size() > TimeProcessor::Planner::refresh_threshold) + calculate_time(m_result, TimeProcessor::Planner::queue_size); + const Vec3f plate_offset = {(float) m_x_offset, (float) m_y_offset, 0.0f}; if (m_seams_detector.is_active()) { @@ -4107,20 +4074,6 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line, const std::o m_seams_detector.set_first_vertex(m_result.moves.back().position - m_extruder_offsets[filament_id] - plate_offset); } - if (m_detect_layer_based_on_tag && !m_result.spiral_vase_layers.empty()) { - if (delta_pos[Z] >= 0.0 && type == EMoveType::Extrude) { - const float current_z = static_cast(m_end_position[Z]); - // replace layer height placeholder with correct value - if (m_result.spiral_vase_layers.back().first == FLT_MAX) { - m_result.spiral_vase_layers.back().first = current_z; - } else { - m_result.spiral_vase_layers.back().first = std::max(m_result.spiral_vase_layers.back().first, current_z); - } - } - if (!m_result.moves.empty()) - m_result.spiral_vase_layers.back().second.second = m_result.moves.size() - 1 - m_seams_count; - } - // store move store_move_vertex(type); } @@ -4193,69 +4146,8 @@ void GCodeProcessor::process_VG1(const GCodeReader::GCodeLine& line) return; EMoveType type = move_type(delta_pos); - if (type == EMoveType::Extrude) { - float delta_xyz = std::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z])); - float volume_extruded_filament = area_filament_cross_section * delta_pos[E]; - float area_toolpath_cross_section = volume_extruded_filament / delta_xyz; - - if(m_extrusion_role == ExtrusionRole::erSupportMaterial || m_extrusion_role == ExtrusionRole::erSupportMaterialInterface || m_extrusion_role ==ExtrusionRole::erSupportTransition) - m_used_filaments.increase_support_caches(volume_extruded_filament); - else if (m_extrusion_role==ExtrusionRole::erWipeTower) { - m_used_filaments.increase_wipe_tower_caches(volume_extruded_filament); - } - else { - // save extruded volume to the cache - m_used_filaments.increase_model_caches(volume_extruded_filament); - } - // volume extruded filament / tool displacement = area toolpath cross section - m_mm3_per_mm = area_toolpath_cross_section; -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_mm3_per_mm_compare.update(area_toolpath_cross_section, m_extrusion_role); -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - - if (m_forced_height > 0.0f) - m_height = m_forced_height; - else { - if (m_end_position[Z] > m_extruded_last_z + EPSILON) - m_height = m_end_position[Z] - m_extruded_last_z; - } - - if (m_height == 0.0f) - m_height = DEFAULT_TOOLPATH_HEIGHT; - - if (m_end_position[Z] == 0.0f) - m_end_position[Z] = m_height; - - m_extruded_last_z = m_end_position[Z]; - m_options_z_corrector.update(m_height); - -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_height_compare.update(m_height, m_extrusion_role); -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - - if (m_forced_width > 0.0f) - m_width = m_forced_width; - else if (m_extrusion_role == erExternalPerimeter) - // cross section: rectangle - m_width = delta_pos[E] * static_cast(M_PI * sqr(1.05f * filament_radius)) / (delta_xyz * m_height); - else if (m_extrusion_role == erBridgeInfill || m_extrusion_role == erNone) - // cross section: circle - m_width = static_cast(m_result.filament_diameters[filament_id]) * std::sqrt(delta_pos[E] / delta_xyz); - else - // cross section: rectangle + 2 semicircles - m_width = delta_pos[E] * static_cast(M_PI * sqr(filament_radius)) / (delta_xyz * m_height) + static_cast(1.0 - 0.25 * M_PI) * m_height; - - if (m_width == 0.0f) - m_width = DEFAULT_TOOLPATH_WIDTH; - - // clamp width to avoid artifacts which may arise from wrong values of m_height - m_width = std::min(m_width, std::max(2.0f, 4.0f * m_height)); - -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_width_compare.update(m_width, m_extrusion_role); -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - } - else if (EMoveType::Unretract == type && m_virtual_flushing) { + // BBS: now we only support virtual flush + if (EMoveType::Unretract == type && m_virtual_flushing) { int extruder_id = get_extruder_id(); float volume_flushed_filament = area_filament_cross_section * delta_pos[E]; if (m_remaining_volume[extruder_id] > volume_flushed_filament) @@ -4492,448 +4384,308 @@ void GCodeProcessor::process_VG1(const GCodeReader::GCodeLine& line) prev = curr; blocks.push_back(block); - - if (blocks.size() > TimeProcessor::Planner::refresh_threshold) - machine.calculate_time(TimeProcessor::Planner::queue_size); } // do not save the move } -// BBS: this function is absolutely new for G2 and G3 gcode -void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line) +void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise) { + enum class EFitting { None, IJ, R }; + std::string_view axis_pos_I; + std::string_view axis_pos_J; + EFitting fitting = EFitting::None; + if (line.has('R')) { + fitting = EFitting::R; + } else { + axis_pos_I = line.axis_pos('I'); + axis_pos_J = line.axis_pos('J'); + if (! axis_pos_I.empty() || ! axis_pos_J.empty()) + fitting = EFitting::IJ; + } + + if (fitting == EFitting::None) + return; + int filament_id = get_filament_id(); - float filament_diameter = (static_cast(filament_id) < m_result.filament_diameters.size()) ? m_result.filament_diameters[filament_id] : m_result.filament_diameters.back(); - float filament_radius = 0.5f * filament_diameter; - float area_filament_cross_section = static_cast(M_PI) * sqr(filament_radius); - auto absolute_position = [this, area_filament_cross_section](Axis axis, const GCodeReader::GCodeLine& lineG2_3) { - bool is_relative = (m_global_positioning_type == EPositioningType::Relative); - if (axis == E) - is_relative |= (m_e_local_positioning_type == EPositioningType::Relative); + const float filament_diameter = (static_cast(filament_id) < m_result.filament_diameters.size()) ? m_result.filament_diameters[filament_id] : m_result.filament_diameters.back(); + const float filament_radius = 0.5f * filament_diameter; + const float area_filament_cross_section = static_cast(M_PI) * sqr(filament_radius); - if (lineG2_3.has(Slic3r::Axis(axis))) { - float lengthsScaleFactor = (m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f; - float ret = lineG2_3.value(Slic3r::Axis(axis)) * lengthsScaleFactor; - if (axis == I) - return m_start_position[X] + ret; - else if (axis == J) - return m_start_position[Y] + ret; - else - return is_relative ? m_start_position[axis] + ret : m_origin[axis] + ret; - } - else { - if (axis == I) - return m_start_position[X]; - else if (axis == J) - return m_start_position[Y]; - else - return m_start_position[axis]; - } + AxisCoords end_position = m_start_position; + for (unsigned char a = X; a <= E; ++a) { + end_position[a] = extract_absolute_position_on_axis((Axis)a, line, double(area_filament_cross_section)); + } + + // relative center + Vec3f rel_center = Vec3f::Zero(); +#ifndef NDEBUG + double radius = 0.0; +#endif // NDEBUG + if (fitting == EFitting::R) { + float r; + if (!line.has_value('R', r) || r == 0.0f) + return; +#ifndef NDEBUG + radius = (double)std::abs(r); +#endif // NDEBUG + const Vec2f start_pos((float)m_start_position[X], (float)m_start_position[Y]); + const Vec2f end_pos((float)end_position[X], (float)end_position[Y]); + const Vec2f c = Geometry::ArcWelder::arc_center(start_pos, end_pos, r, !clockwise); + rel_center.x() = c.x() - m_start_position[X]; + rel_center.y() = c.y() - m_start_position[Y]; + } + else { + assert(fitting == EFitting::IJ); + if (! axis_pos_I.empty() && ! line.has_value(axis_pos_I, rel_center.x())) + return; + if (! axis_pos_J.empty() && ! line.has_value(axis_pos_J, rel_center.y())) + return; + } + + // scale center, if needed + if (m_units == EUnits::Inches) + rel_center *= INCHES_TO_MM; + + struct Arc + { + Vec3d start{ Vec3d::Zero() }; + Vec3d end{ Vec3d::Zero() }; + Vec3d center{ Vec3d::Zero() }; + + double angle{ 0.0 }; + double delta_x() const { return end.x() - start.x(); } + double delta_y() const { return end.y() - start.y(); } + double delta_z() const { return end.z() - start.z(); } + + double length() const { return angle * start_radius(); } + double travel_length() const { return std::sqrt(sqr(length()) + sqr(delta_z())); } + double start_radius() const { return (start - center).norm(); } + double end_radius() const { return (end - center).norm(); } + + Vec3d relative_start() const { return start - center; } + Vec3d relative_end() const { return end - center; } + + bool is_full_circle() const { return std::abs(delta_x()) < EPSILON && std::abs(delta_y()) < EPSILON; } }; - auto move_type = [this](const float& delta_E) { - if (delta_E == 0.0f) - return EMoveType::Travel; - else - return EMoveType::Extrude; + Arc arc; + + // arc start endpoint + arc.start = Vec3d(m_start_position[X], m_start_position[Y], m_start_position[Z]); + + // arc center + arc.center = arc.start + rel_center.cast(); + + // arc end endpoint + arc.end = Vec3d(end_position[X], end_position[Y], end_position[Z]); + + // radii + if (std::abs(arc.end_radius() - arc.start_radius()) > 0.001) { + // what to do ??? + } + + assert(fitting != EFitting::R || std::abs(radius - arc.start_radius()) < EPSILON); + + // updates feedrate from line + std::optional feedrate; + if (line.has_f()) { + // feedrate = m_feed_multiply.current * line.f() * MMMIN_TO_MMSEC; + feedrate = 1.0f * line.f() * MMMIN_TO_MMSEC; + } + + // updates extrusion from line + std::optional extrusion; + if (line.has_e()) + extrusion = end_position[E] - m_start_position[E]; + + // relative arc endpoints + const Vec3d rel_arc_start = arc.relative_start(); + const Vec3d rel_arc_end = arc.relative_end(); + + // arc angle + if (arc.is_full_circle()) + arc.angle = 2.0 * PI; + else { + arc.angle = std::atan2(rel_arc_start.x() * rel_arc_end.y() - rel_arc_start.y() * rel_arc_end.x(), + rel_arc_start.x() * rel_arc_end.x() + rel_arc_start.y() * rel_arc_end.y()); + if (arc.angle < 0.0) + arc.angle += 2.0 * PI; + if (clockwise) + arc.angle -= 2.0 * PI; + } + + const double travel_length = arc.travel_length(); + if (travel_length < 0.001) + return; + + auto adjust_target = [this, area_filament_cross_section](const AxisCoords& target, const AxisCoords& prev_position) { + AxisCoords ret = target; + if (m_global_positioning_type == EPositioningType::Relative) { + for (unsigned char a = X; a <= E; ++a) { + ret[a] -= prev_position[a]; + } + } + else if (m_e_local_positioning_type == EPositioningType::Relative) + ret[E] -= prev_position[E]; + + // if (m_use_volumetric_e) + // ret[E] *= area_filament_cross_section; + + const double lengthsScaleFactor = (m_units == EUnits::Inches) ? double(INCHES_TO_MM) : 1.0; + for (unsigned char a = X; a <= E; ++a) { + ret[a] /= lengthsScaleFactor; + } + return ret; }; - auto arc_interpolation = [this](const Vec3f& start_pos, const Vec3f& end_pos, const Vec3f& center_pos, const bool is_ccw) { - float radius = ArcSegment::calc_arc_radius(start_pos, center_pos); - //BBS: radius is too small to draw - if (radius <= DRAW_ARC_TOLERANCE) { - m_interpolation_points.resize(0); - return; - } - float radian_step = 2 * acos((radius - DRAW_ARC_TOLERANCE) / radius); - float num = ArcSegment::calc_arc_radian(start_pos, end_pos, center_pos, is_ccw) / radian_step; - float z_step = (num < 1)? end_pos.z() - start_pos.z() : (end_pos.z() - start_pos.z()) / num; - radian_step = is_ccw ? radian_step : -radian_step; - int interpolation_num = floor(num); + auto internal_only_g1_line = [this](const AxisCoords& target, bool has_z, const std::optional& feedrate, + const std::optional& extrusion, const std::optional& remaining_internal_g1_lines = std::nullopt) { + std::array, 4> g1_axes = { target[X], target[Y], std::nullopt, std::nullopt }; + std::optional g1_feedrate = std::nullopt; + if (has_z) + g1_axes[Z] = target[Z]; + if (extrusion.has_value()) + g1_axes[E] = target[E]; + if (feedrate.has_value()) + g1_feedrate = (double)*feedrate / MMMIN_TO_MMSEC; + process_G1(g1_axes, g1_feedrate, G1DiscretizationOrigin::G2G3, remaining_internal_g1_lines); + }; - m_interpolation_points.resize(interpolation_num, Vec3f::Zero()); - Vec3f delta = start_pos - center_pos; - for (auto i = 0; i < interpolation_num; i++) { - float cos_val = cos((i+1) * radian_step); - float sin_val = sin((i+1) * radian_step); - m_interpolation_points[i] = Vec3f(center_pos.x() + delta.x() * cos_val - delta.y() * sin_val, - center_pos.y() + delta.x() * sin_val + delta.y() * cos_val, - start_pos.z() + (i + 1) * z_step); - } - }; + if (m_flavor == gcfMarlinFirmware) { + // calculate arc segments + // reference: + // Prusa-Firmware-Buddy\lib\Marlin\Marlin\src\gcode\motion\G2_G3.cpp - plan_arc() + // https://github.com/prusa3d/Prusa-Firmware-Buddy-Private/blob/private/lib/Marlin/Marlin/src/gcode/motion/G2_G3.cpp - ++m_g1_line_id; + static const float MAX_ARC_DEVIATION = 0.02f; + static const float MIN_ARC_SEGMENTS_PER_SEC = 50; + static const float MIN_ARC_SEGMENT_MM = 0.1f; + static const float MAX_ARC_SEGMENT_MM = 2.0f; + const float feedrate_mm_s = feedrate.has_value() ? *feedrate : m_feedrate; + const float radius_mm = rel_center.norm(); + const float segment_mm = std::clamp(std::min(std::sqrt(8.0f * radius_mm * MAX_ARC_DEVIATION), feedrate_mm_s * (1.0f / MIN_ARC_SEGMENTS_PER_SEC)), MIN_ARC_SEGMENT_MM, MAX_ARC_SEGMENT_MM); + const float flat_mm = radius_mm * std::abs(arc.angle); + const size_t segments = std::max(flat_mm / segment_mm + 0.8f, 1); - //BBS: enable processing of lines M201/M203/M204/M205 - m_time_processor.machine_envelope_processing_enabled = true; + AxisCoords prev_target = m_start_position; - //BBS: get axes positions from line - for (unsigned char a = X; a <= E; ++a) { - m_end_position[a] = absolute_position((Axis)a, line); - } - //BBS: G2 G3 line but has no I and J axis, invalid G code format - if (!line.has(I) && !line.has(J)) - return; - //BBS: P mode, but xy position is not same, or P is not 1, invalid G code format - if (line.has(P) && - (m_start_position[X] != m_end_position[X] || - m_start_position[Y] != m_end_position[Y] || - ((int)line.p()) != 1)) - return; + if (segments > 1) { + const float inv_segments = 1.0f / static_cast(segments); + const float theta_per_segment = static_cast(arc.angle) * inv_segments; + const float cos_T = cos(theta_per_segment); + const float sin_T = sin(theta_per_segment); + const float z_per_segment = arc.delta_z() * inv_segments; + const float extruder_per_segment = (extrusion.has_value()) ? *extrusion * inv_segments : 0.0f; - m_arc_center = Vec3f(absolute_position(I, line),absolute_position(J, line),m_start_position[Z]); - //BBS: G2 is CW direction, G3 is CCW direction - const std::string_view cmd = line.cmd(); - m_move_path_type = (::atoi(&cmd[1]) == 2) ? EMovePathType::Arc_move_cw : EMovePathType::Arc_move_ccw; - //BBS: get arc length,interpolation points and radian in X-Y plane - Vec3f start_point = Vec3f(m_start_position[X], m_start_position[Y], m_start_position[Z]); - Vec3f end_point = Vec3f(m_end_position[X], m_end_position[Y], m_end_position[Z]); - float arc_length; - if (!line.has(P)) - arc_length = ArcSegment::calc_arc_length(start_point, end_point, m_arc_center, (m_move_path_type == EMovePathType::Arc_move_ccw)); - else - arc_length = ((int)line.p()) * 2 * PI * (start_point - m_arc_center).norm(); - //BBS: Attention! arc_onterpolation does not support P mode while P is not 1. - arc_interpolation(start_point, end_point, m_arc_center, (m_move_path_type == EMovePathType::Arc_move_ccw)); - float radian = ArcSegment::calc_arc_radian(start_point, end_point, m_arc_center, (m_move_path_type == EMovePathType::Arc_move_ccw)); - Vec3f start_dir = Circle::calc_tangential_vector(start_point, m_arc_center, (m_move_path_type == EMovePathType::Arc_move_ccw)); - Vec3f end_dir = Circle::calc_tangential_vector(end_point, m_arc_center, (m_move_path_type == EMovePathType::Arc_move_ccw)); + static const size_t N_ARC_CORRECTION = 25; + size_t arc_recalc_count = N_ARC_CORRECTION; - //BBS: updates feedrate from line, if present - if (line.has_f()) - m_feedrate = line.f() * MMMIN_TO_MMSEC; - - //BBS: calculates movement deltas - AxisCoords delta_pos; - for (unsigned char a = X; a <= E; ++a) { - delta_pos[a] = m_end_position[a] - m_start_position[a]; - } - - //BBS: no displacement, return - if (arc_length == 0.0f && delta_pos[Z] == 0.0f) - return; - - EMoveType type = move_type(delta_pos[E]); - - - const float delta_xyz = std::sqrt(sqr(arc_length) + sqr(delta_pos[Z])); - m_travel_dist = delta_xyz; - if (type == EMoveType::Extrude) { - float volume_extruded_filament = area_filament_cross_section * delta_pos[E]; - float area_toolpath_cross_section = volume_extruded_filament / delta_xyz; - - if(m_extrusion_role == ExtrusionRole::erSupportMaterial || m_extrusion_role == ExtrusionRole::erSupportMaterialInterface || m_extrusion_role ==ExtrusionRole::erSupportTransition) - m_used_filaments.increase_support_caches(volume_extruded_filament); - else if (m_extrusion_role == ExtrusionRole::erWipeTower) { - //BBS: save wipe tower volume to the cache - m_used_filaments.increase_wipe_tower_caches(volume_extruded_filament); - } - else { - //BBS: save extruded volume to the cache - m_used_filaments.increase_model_caches(volume_extruded_filament); - } - //BBS: volume extruded filament / tool displacement = area toolpath cross section - m_mm3_per_mm = area_toolpath_cross_section; -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_mm3_per_mm_compare.update(area_toolpath_cross_section, m_extrusion_role); -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - - if (m_forced_height > 0.0f) - m_height = m_forced_height; - else { - if (m_end_position[Z] > m_extruded_last_z + EPSILON) - m_height = m_end_position[Z] - m_extruded_last_z; - } - - if (m_height == 0.0f) - m_height = DEFAULT_TOOLPATH_HEIGHT; - - if (m_end_position[Z] == 0.0f) - m_end_position[Z] = m_height; - - m_extruded_last_z = m_end_position[Z]; - m_options_z_corrector.update(m_height); - -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_height_compare.update(m_height, m_extrusion_role); -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - - if (m_forced_width > 0.0f) - m_width = m_forced_width; - else if (m_extrusion_role == erExternalPerimeter) - //BBS: cross section: rectangle - m_width = delta_pos[E] * static_cast(M_PI * sqr(1.05f * filament_radius)) / (delta_xyz * m_height); - else if (m_extrusion_role == erBridgeInfill || m_extrusion_role == erInternalBridgeInfill || m_extrusion_role == erNone) - //BBS: cross section: circle - m_width = static_cast(m_result.filament_diameters[filament_id]) * std::sqrt(delta_pos[E] / delta_xyz); - else - //BBS: cross section: rectangle + 2 semicircles - m_width = delta_pos[E] * static_cast(M_PI * sqr(filament_radius)) / (delta_xyz * m_height) + static_cast(1.0 - 0.25 * M_PI) * m_height; - - if (m_width == 0.0f) - m_width = DEFAULT_TOOLPATH_WIDTH; - - //BBS: clamp width to avoid artifacts which may arise from wrong values of m_height - m_width = std::min(m_width, std::max(2.0f, 4.0f * m_height)); - -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_width_compare.update(m_width, m_extrusion_role); -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - } - - //BBS: time estimate section - assert(delta_xyz != 0.0f); - float inv_distance = 1.0f / delta_xyz; - float radius = ArcSegment::calc_arc_radius(start_point, m_arc_center); - - for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { - TimeMachine& machine = m_time_processor.machines[i]; - if (!machine.enabled) - continue; - - TimeMachine::State& curr = machine.curr; - TimeMachine::State& prev = machine.prev; - std::vector& blocks = machine.blocks; - - curr.feedrate = (type == EMoveType::Travel) ? - minimum_travel_feedrate(static_cast(i), m_feedrate) : - minimum_feedrate(static_cast(i), m_feedrate); - - //BBS: calculeta enter and exit direction - curr.enter_direction = start_dir; - curr.exit_direction = end_dir; - - TimeBlock block; - block.move_type = type; - //BBS: don't calculate travel time into extrusion path, except travel inside start and end gcode. - block.role = (type != EMoveType::Travel || m_extrusion_role == erCustom) ? m_extrusion_role : erNone; - block.distance = delta_xyz; - block.g1_line_id = m_g1_line_id; - block.layer_id = std::max(1, m_layer_id); - block.flags.prepare_stage = m_processing_start_custom_gcode; - - // BBS: calculates block cruise feedrate - // For arc move, we need to limite the cruise according to centripetal acceleration which is - // same with acceleration in x-y plane. Because arc move part is only on x-y plane, we use x-y acceleration directly - float centripetal_acceleration = get_acceleration(static_cast(i)); - float max_feedrate_by_centri_acc = sqrtf(centripetal_acceleration * radius) / (arc_length * inv_distance); - curr.feedrate = std::min(curr.feedrate, max_feedrate_by_centri_acc); - - float min_feedrate_factor = 1.0f; - for (unsigned char a = X; a <= E; ++a) { - if (a == X || a == Y) - //BBS: use resultant feedrate in x-y plane - curr.axis_feedrate[a] = curr.feedrate * arc_length * inv_distance; - else if (a == Z) - curr.axis_feedrate[a] = curr.feedrate * delta_pos[a] * inv_distance; - else - curr.axis_feedrate[a] *= machine.extrude_factor_override_percentage; - - curr.abs_axis_feedrate[a] = std::abs(curr.axis_feedrate[a]); - if (curr.abs_axis_feedrate[a] != 0.0f) { - float axis_max_feedrate = get_axis_max_feedrate(static_cast(i), static_cast(a), m_extruder_id); - if (axis_max_feedrate != 0.0f) min_feedrate_factor = std::min(min_feedrate_factor, axis_max_feedrate / curr.abs_axis_feedrate[a]); - } - } - curr.feedrate *= min_feedrate_factor; - block.feedrate_profile.cruise = curr.feedrate; - if (min_feedrate_factor < 1.0f) { - for (unsigned char a = X; a <= E; ++a) { - curr.axis_feedrate[a] *= min_feedrate_factor; - curr.abs_axis_feedrate[a] *= min_feedrate_factor; - } - } - - //BBS: calculates block acceleration - float acceleration = (type == EMoveType::Travel) ? - get_travel_acceleration(static_cast(i)) : - get_acceleration(static_cast(i)); - float min_acc_factor = 1.0f; - AxisCoords axis_acc; - for (unsigned char a = X; a <= Z; ++a) { - if (a == X || a == Y) - //BBS: use resultant feedrate in x-y plane - axis_acc[a] = acceleration * arc_length * inv_distance; - else - axis_acc[a] = acceleration * std::abs(delta_pos[a]) * inv_distance; - - if (axis_acc[a] != 0.0f) { - float axis_max_acceleration = get_axis_max_acceleration(static_cast(i), static_cast(a), m_extruder_id); - if (axis_max_acceleration != 0.0f && axis_acc[a] > axis_max_acceleration) min_acc_factor = std::min(min_acc_factor, axis_max_acceleration / axis_acc[a]); - } - } - block.acceleration = acceleration * min_acc_factor; - - //BBS: calculates block exit feedrate - for (unsigned char a = X; a <= E; ++a) { - float axis_max_jerk = get_axis_max_jerk(static_cast(i), static_cast(a)); - if (curr.abs_axis_feedrate[a] > axis_max_jerk) - curr.safe_feedrate = std::min(curr.safe_feedrate, axis_max_jerk); - } - block.feedrate_profile.exit = curr.safe_feedrate; - - //BBS: calculates block entry feedrate - static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f; - float vmax_junction = curr.safe_feedrate; - if (!blocks.empty() && prev.feedrate > PREVIOUS_FEEDRATE_THRESHOLD) { - bool prev_speed_larger = prev.feedrate > block.feedrate_profile.cruise; - float smaller_speed_factor = prev_speed_larger ? (block.feedrate_profile.cruise / prev.feedrate) : (prev.feedrate / block.feedrate_profile.cruise); - //BBS: Pick the smaller of the nominal speeds. Higher speed shall not be achieved at the junction during coasting. - vmax_junction = prev_speed_larger ? block.feedrate_profile.cruise : prev.feedrate; - - float v_factor = 1.0f; - bool limited = false; - - for (unsigned char a = X; a <= E; ++a) { - //BBS: Limit an axis. We have to differentiate coasting from the reversal of an axis movement, or a full stop. - if (a == X) { - Vec3f exit_v = prev.feedrate * (prev.exit_direction); - if (prev_speed_larger) - exit_v *= smaller_speed_factor; - Vec3f entry_v = block.feedrate_profile.cruise * (curr.enter_direction); - Vec3f jerk_v = entry_v - exit_v; - jerk_v = Vec3f(abs(jerk_v.x()), abs(jerk_v.y()), abs(jerk_v.z())); - Vec3f max_xyz_jerk_v = get_xyz_max_jerk(static_cast(i)); - - for (size_t i = 0; i < 3; i++) - { - if (jerk_v[i] > max_xyz_jerk_v[i]) { - v_factor *= max_xyz_jerk_v[i] / jerk_v[i]; - jerk_v *= v_factor; - limited = true; - } - } - } - else if (a == Y || a == Z) { - continue; + Vec2f rvec(-rel_center.x(), -rel_center.y()); + AxisCoords arc_target = { 0.0f, 0.0f, m_start_position[Z], m_start_position[E] }; + for (size_t i = 1; i < segments; ++i) { + if (--arc_recalc_count) { + // Apply vector rotation matrix to previous rvec.a / 1 + const float r_new_Y = rvec.x() * sin_T + rvec.y() * cos_T; + rvec.x() = rvec.x() * cos_T - rvec.y() * sin_T; + rvec.y() = r_new_Y; } else { - float v_exit = prev.axis_feedrate[a]; - float v_entry = curr.axis_feedrate[a]; - - if (prev_speed_larger) - v_exit *= smaller_speed_factor; - - if (limited) { - v_exit *= v_factor; - v_entry *= v_factor; - } - - //BBS: Calculate the jerk depending on whether the axis is coasting in the same direction or reversing a direction. - float jerk = - (v_exit > v_entry) ? - (((v_entry > 0.0f) || (v_exit < 0.0f)) ? - //BBS: coasting - (v_exit - v_entry) : - //BBS: axis reversal - std::max(v_exit, -v_entry)) : - (((v_entry < 0.0f) || (v_exit > 0.0f)) ? - //BBS: coasting - (v_entry - v_exit) : - //BBS: axis reversal - std::max(-v_exit, v_entry)); - - - float axis_max_jerk = get_axis_max_jerk(static_cast(i), static_cast(a)); - if (jerk > axis_max_jerk) { - v_factor *= axis_max_jerk / jerk; - limited = true; - } + arc_recalc_count = N_ARC_CORRECTION; + // Arc correction to radius vector. Computed only every N_ARC_CORRECTION increments. + // Compute exact location by applying transformation matrix from initial radius vector(=-offset). + // To reduce stuttering, the sin and cos could be computed at different times. + // For now, compute both at the same time. + const float Ti = i * theta_per_segment; + const float cos_Ti = cos(Ti); + const float sin_Ti = sin(Ti); + rvec.x() = -rel_center.x() * cos_Ti + rel_center.y() * sin_Ti; + rvec.y() = -rel_center.x() * sin_Ti - rel_center.y() * cos_Ti; } - } - if (limited) - vmax_junction *= v_factor; + // Update arc_target location + arc_target[X] = arc.center.x() + rvec.x(); + arc_target[Y] = arc.center.y() + rvec.y(); + arc_target[Z] += z_per_segment; + arc_target[E] += extruder_per_segment; - //BBS: Now the transition velocity is known, which maximizes the shared exit / entry velocity while - // respecting the jerk factors, it may be possible, that applying separate safe exit / entry velocities will achieve faster prints. - float vmax_junction_threshold = vmax_junction * 0.99f; - - //BBS: Not coasting. The machine will stop and start the movements anyway, better to start the segment from start. - if ((prev.safe_feedrate > vmax_junction_threshold) && (curr.safe_feedrate > vmax_junction_threshold)) - vmax_junction = curr.safe_feedrate; - } - - float v_allowable = max_allowable_speed(-acceleration, curr.safe_feedrate, block.distance); - block.feedrate_profile.entry = std::min(vmax_junction, v_allowable); - - block.max_entry_speed = vmax_junction; - block.flags.nominal_length = (block.feedrate_profile.cruise <= v_allowable); - block.flags.recalculate = true; - block.safe_feedrate = curr.safe_feedrate; - - //BBS: calculates block trapezoid - block.calculate_trapezoid(); - - //BBS: updates previous - prev = curr; - - blocks.push_back(block); - - if (blocks.size() > TimeProcessor::Planner::refresh_threshold) - machine.calculate_time(TimeProcessor::Planner::queue_size); - } - - //BBS: seam detector - Vec3f plate_offset = {(float) m_x_offset, (float) m_y_offset, 0.0f}; - - if (m_seams_detector.is_active()) { - //BBS: check for seam starting vertex - if (type == EMoveType::Extrude && m_extrusion_role == erExternalPerimeter) { - const Vec3f new_pos = m_result.moves.back().position - m_extruder_offsets[filament_id] - plate_offset; - if (!m_seams_detector.has_first_vertex()) { - m_seams_detector.set_first_vertex(new_pos); - } else if (m_detect_layer_based_on_tag) { - // We may have sloped loop, drop any previous start pos if we have z increment - const std::optional first_vertex = m_seams_detector.get_first_vertex(); - if (new_pos.z() > first_vertex->z()) { - m_seams_detector.set_first_vertex(new_pos); - } + m_start_position = m_end_position; // this is required because we are skipping the call to process_gcode_line() + internal_only_g1_line(adjust_target(arc_target, prev_target), z_per_segment != 0.0, (i == 1) ? feedrate : std::nullopt, + extrusion, segments - i); + prev_target = arc_target; } } - //BBS: check for seam ending vertex and store the resulting move - else if ((type != EMoveType::Extrude || (m_extrusion_role != erExternalPerimeter && m_extrusion_role != erOverhangPerimeter)) && m_seams_detector.has_first_vertex()) { - auto set_end_position = [this](const Vec3f& pos) { - m_end_position[X] = pos.x(); m_end_position[Y] = pos.y(); m_end_position[Z] = pos.z(); - }; - const Vec3f curr_pos(m_end_position[X], m_end_position[Y], m_end_position[Z]); - const Vec3f new_pos = m_result.moves.back().position - m_extruder_offsets[filament_id] - plate_offset; - const std::optional first_vertex = m_seams_detector.get_first_vertex(); - //BBS: the threshold value = 0.0625f == 0.25 * 0.25 is arbitrary, we may find some smarter condition later - if ((new_pos - *first_vertex).squaredNorm() < 0.0625f) { - set_end_position(0.5f * (new_pos + *first_vertex)); - store_move_vertex(EMoveType::Seam); - set_end_position(curr_pos); + // Ensure last segment arrives at target location. + m_start_position = m_end_position; // this is required because we are skipping the call to process_gcode_line() + internal_only_g1_line(adjust_target(end_position, prev_target), arc.delta_z() != 0.0, (segments == 1) ? feedrate : std::nullopt, extrusion); + } + else { + // calculate arc segments + // reference: + // Prusa-Firmware\Firmware\motion_control.cpp - mc_arc() + // https://github.com/prusa3d/Prusa-Firmware/blob/MK3/Firmware/motion_control.cpp + + // segments count +#if 0 + static const double MM_PER_ARC_SEGMENT = 1.0; + const size_t segments = std::max(std::floor(travel_length / MM_PER_ARC_SEGMENT), 1); +#else + static const double gcode_arc_tolerance = 0.0125; + const size_t segments = Geometry::ArcWelder::arc_discretization_steps(arc.start_radius(), std::abs(arc.angle), gcode_arc_tolerance); +#endif + + const double inv_segment = 1.0 / double(segments); + const double theta_per_segment = arc.angle * inv_segment; + const double z_per_segment = arc.delta_z() * inv_segment; + const double extruder_per_segment = (extrusion.has_value()) ? *extrusion * inv_segment : 0.0; + const double sq_theta_per_segment = sqr(theta_per_segment); + const double cos_T = 1.0 - 0.5 * sq_theta_per_segment; + const double sin_T = theta_per_segment - sq_theta_per_segment * theta_per_segment / 6.0f; + + AxisCoords prev_target = m_start_position; + AxisCoords arc_target; + + // Initialize the linear axis + arc_target[Z] = m_start_position[Z]; + + // Initialize the extruder axis + arc_target[E] = m_start_position[E]; + + static const size_t N_ARC_CORRECTION = 25; + Vec3d curr_rel_arc_start = arc.relative_start(); + size_t count = N_ARC_CORRECTION; + + for (size_t i = 1; i < segments; ++i) { + if (count-- == 0) { + const double cos_Ti = ::cos(i * theta_per_segment); + const double sin_Ti = ::sin(i * theta_per_segment); + curr_rel_arc_start.x() = -double(rel_center.x()) * cos_Ti + double(rel_center.y()) * sin_Ti; + curr_rel_arc_start.y() = -double(rel_center.x()) * sin_Ti - double(rel_center.y()) * cos_Ti; + count = N_ARC_CORRECTION; + } + else { + const float r_axisi = curr_rel_arc_start.x() * sin_T + curr_rel_arc_start.y() * cos_T; + curr_rel_arc_start.x() = curr_rel_arc_start.x() * cos_T - curr_rel_arc_start.y() * sin_T; + curr_rel_arc_start.y() = r_axisi; } - m_seams_detector.activate(false); - } - } - else if (type == EMoveType::Extrude && m_extrusion_role == erExternalPerimeter) { - m_seams_detector.activate(true); - m_seams_detector.set_first_vertex(m_result.moves.back().position - m_extruder_offsets[filament_id] - plate_offset); - } + // Update arc_target location + arc_target[X] = arc.center.x() + curr_rel_arc_start.x(); + arc_target[Y] = arc.center.y() + curr_rel_arc_start.y(); + arc_target[Z] += z_per_segment; + arc_target[E] += extruder_per_segment; - // Orca: we now use spiral_vase_layers for proper layer detect when scarf joint is enabled, - // and this is needed if the layer has only arc moves - if (m_detect_layer_based_on_tag && !m_result.spiral_vase_layers.empty()) { - if (delta_pos[Z] >= 0.0 && type == EMoveType::Extrude) { - const float current_z = static_cast(m_end_position[Z]); - // replace layer height placeholder with correct value - if (m_result.spiral_vase_layers.back().first == FLT_MAX) { - m_result.spiral_vase_layers.back().first = current_z; - } else { - m_result.spiral_vase_layers.back().first = std::max(m_result.spiral_vase_layers.back().first, current_z); - } + m_start_position = m_end_position; // this is required because we are skipping the call to process_gcode_line() + internal_only_g1_line(adjust_target(arc_target, prev_target), z_per_segment != 0.0, (i == 1) ? feedrate : std::nullopt, + extrusion, segments - i); + prev_target = arc_target; } - if (!m_result.moves.empty()) - m_result.spiral_vase_layers.back().second.second = m_result.moves.size() - 1 - m_seams_count; - } - //BBS: store move - store_move_vertex(type, m_move_path_type); + // Ensure last segment arrives at target location. + m_start_position = m_end_position; // this is required because we are skipping the call to process_gcode_line() + internal_only_g1_line(adjust_target(end_position, prev_target), arc.delta_z() != 0.0, (segments == 1) ? feedrate : std::nullopt, extrusion); + } } //BBS @@ -5631,24 +5383,13 @@ void GCodeProcessor::process_filament_change(int id) store_move_vertex(EMoveType::Tool_change); } -void GCodeProcessor::store_move_vertex(EMoveType type, EMovePathType path_type) +void GCodeProcessor::store_move_vertex(EMoveType type, EMovePathType path_type, bool internal_only) { int filament_id = get_filament_id(); m_last_line_id = (type == EMoveType::Color_change || type == EMoveType::Pause_Print || type == EMoveType::Custom_GCode) ? m_line_id + 1 : ((type == EMoveType::Seam) ? m_last_line_id : m_line_id); - //BBS: apply plate's and extruder's offset to arc interpolation points - if (path_type == EMovePathType::Arc_move_cw || - path_type == EMovePathType::Arc_move_ccw) { - for (size_t i = 0; i < m_interpolation_points.size(); i++) - m_interpolation_points[i] = - Vec3f(m_interpolation_points[i].x() + m_x_offset, - m_interpolation_points[i].y() + m_y_offset, - m_processing_start_custom_gcode ? m_first_layer_height : m_interpolation_points[i].z()) + - m_extruder_offsets[filament_id]; - } - m_result.moves.push_back({ m_last_line_id, type, @@ -5659,18 +5400,16 @@ void GCodeProcessor::store_move_vertex(EMoveType type, EMovePathType path_type) Vec3f(m_end_position[X] + m_x_offset, m_end_position[Y] + m_y_offset, m_processing_start_custom_gcode ? m_first_layer_height : m_end_position[Z]- m_z_offset) + m_extruder_offsets[filament_id], static_cast(m_end_position[E] - m_start_position[E]), m_feedrate, + 0.0f, // actual feedrate m_width, m_height, m_mm3_per_mm, m_travel_dist, m_fan_speed, m_extruder_temps[filament_id], - static_cast(m_result.moves.size()), - static_cast(m_layer_id), //layer_duration: set later - //BBS: add arc move related data - path_type, - Vec3f(m_arc_center(0, 0) + m_x_offset, m_arc_center(1, 0) + m_y_offset, m_arc_center(2, 0)) + m_extruder_offsets[filament_id], - m_interpolation_points, + { 0.0f, 0.0f }, // time + std::max(1, m_layer_id) - 1, + internal_only, m_object_label_id, m_print_z }); @@ -5835,6 +5574,9 @@ int GCodeProcessor::get_filament_vitrification_temperature(size_t extrude_id) void GCodeProcessor::process_custom_gcode_time(CustomGCode::Type code) { + //FIXME this simulates st_synchronize! is it correct? + // The estimated time may be longer than the real print time. + simulate_st_synchronize(); for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { TimeMachine& machine = m_time_processor.machines[i]; if (!machine.enabled) @@ -5842,9 +5584,6 @@ void GCodeProcessor::process_custom_gcode_time(CustomGCode::Type code) TimeMachine::CustomGCodeTime& gcode_time = machine.gcode_time; gcode_time.needed = true; - //FIXME this simulates st_synchronize! is it correct? - // The estimated time may be longer than the real print time. - machine.simulate_st_synchronize(); if (gcode_time.cache != 0.0f) { gcode_time.times.push_back({ code, gcode_time.cache }); gcode_time.cache = 0.0f; @@ -5867,11 +5606,69 @@ void GCodeProcessor::process_filaments(CustomGCode::Type code) } } +void GCodeProcessor::calculate_time(GCodeProcessorResult& result, size_t keep_last_n_blocks, float additional_time) +{ + // calculate times + std::vector actual_speed_moves; + for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { + TimeMachine& machine = m_time_processor.machines[i]; + machine.calculate_time(m_result, static_cast(i), keep_last_n_blocks, additional_time); + if (static_cast(i) == PrintEstimatedStatistics::ETimeMode::Normal) + actual_speed_moves = std::move(machine.actual_speed_moves); + } + + // insert actual speed moves into the move list + unsigned int inserted_actual_speed_moves_count = 0; + std::vector new_moves; + std::map id_map; + for (auto it = actual_speed_moves.begin(); it != actual_speed_moves.end(); ++it) { + const unsigned int base_id = it->move_id + inserted_actual_speed_moves_count; + if (it->position.has_value()) { + // insert actual speed move into the move list + // clone from existing move + GCodeProcessorResult::MoveVertex new_move = result.moves[base_id]; + // override modified parameters + new_move.time = { 0.0f, 0.0f }; + new_move.position = *it->position; + new_move.actual_feedrate = it->actual_feedrate; + new_move.delta_extruder = *it->delta_extruder; + new_move.feedrate = *it->feedrate; + new_move.width = *it->width; + new_move.height = *it->height; + new_move.mm3_per_mm = *it->mm3_per_mm; + new_move.fan_speed = *it->fan_speed; + new_move.temperature = *it->temperature; + new_move.internal_only = true; + new_moves.push_back(new_move); + } + else { + result.moves.insert(result.moves.begin() + base_id, new_moves.begin(), new_moves.end()); + id_map[it->move_id] = base_id + new_moves.size(); + // update move actual speed + result.moves[base_id + new_moves.size()].actual_feedrate = it->actual_feedrate; + inserted_actual_speed_moves_count += new_moves.size(); + // synchronize seams actual speed + if (base_id + new_moves.size() + 1 < result.moves.size()) { + GCodeProcessorResult::MoveVertex& move = result.moves[base_id + new_moves.size() + 1]; + if (move.type == EMoveType::Seam) + move.actual_feedrate = it->actual_feedrate; + } + new_moves.clear(); + } + } + + // synchronize blocks' move_ids with after moves for actual speed insertion + for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { + for (GCodeProcessor::TimeBlock& block : m_time_processor.machines[i].blocks) { + auto it = id_map.find(block.move_id); + block.move_id = (it != id_map.end()) ? it->second : block.move_id + inserted_actual_speed_moves_count; + } + } +} + void GCodeProcessor::simulate_st_synchronize(float additional_time) { - for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { - m_time_processor.machines[i].simulate_st_synchronize(additional_time); - } + calculate_time(m_result, 0, additional_time); } void GCodeProcessor::update_estimated_times_stats() @@ -5881,9 +5678,6 @@ void GCodeProcessor::update_estimated_times_stats() data.time = get_time(mode); data.prepare_time = get_prepare_time(mode); data.custom_gcode_times = get_custom_gcode_times(mode, true); - data.moves_times = get_moves_time(mode); - data.roles_times = get_roles_time(mode); - data.layers_times = get_layers_time(mode); }; update_mode(PrintEstimatedStatistics::ETimeMode::Normal); @@ -5901,6 +5695,23 @@ void GCodeProcessor::update_estimated_times_stats() m_result.print_statistics.total_volumes_per_extruder = m_used_filaments.total_volumes_per_filament; } +double GCodeProcessor::extract_absolute_position_on_axis(Axis axis, const GCodeReader::GCodeLine& line, double area_filament_cross_section) +{ + if (line.has(Slic3r::Axis(axis))) { + bool is_relative = (m_global_positioning_type == EPositioningType::Relative); + if (axis == E) + is_relative |= (m_e_local_positioning_type == EPositioningType::Relative); + + const double lengthsScaleFactor = (m_units == EUnits::Inches) ? double(INCHES_TO_MM) : 1.0; + double ret = line.value(Slic3r::Axis(axis)) * lengthsScaleFactor; + // if (axis == E && m_use_volumetric_e) + // ret /= area_filament_cross_section; + return is_relative ? m_start_position[axis] + ret : m_origin[axis] + ret; + } + else + return m_start_position[axis]; +} + //BBS: ugly code... void GCodeProcessor::update_slice_warnings() { diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 080906da42..b17f7d0933 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -57,21 +57,12 @@ class Print; float time; float prepare_time; std::vector>> custom_gcode_times; - std::vector> moves_times; - std::vector> roles_times; - std::vector layers_times; void reset() { time = 0.0f; prepare_time = 0.0f; custom_gcode_times.clear(); custom_gcode_times.shrink_to_fit(); - moves_times.clear(); - moves_times.shrink_to_fit(); - roles_times.clear(); - roles_times.shrink_to_fit(); - layers_times.clear(); - layers_times.shrink_to_fit(); } }; @@ -125,7 +116,7 @@ class Print; struct GCodeCheckResult { - int error_code = 0; // 0 means succeed, 0b 0001 multi extruder printable area error, 0b 0010 multi extruder printable height error, + int error_code = 0; // 0 means succeed, 0b 0001 multi extruder printable area error, 0b 0010 multi extruder printable height error, // 0b 0100 plate printable area error, 0b 1000 plate printable height error, 0b 10000 wrapping detection area error std::map>> print_area_error_infos; // printable_area extruder_id to which cannot printed in this extruder std::map>> print_height_error_infos; // printable_height extruder_id to which cannot printed in this extruder @@ -186,31 +177,23 @@ class Print; Vec3f position{ Vec3f::Zero() }; // mm float delta_extruder{ 0.0f }; // mm float feedrate{ 0.0f }; // mm/s + float actual_feedrate{ 0.0f }; // mm/s float width{ 0.0f }; // mm float height{ 0.0f }; // mm float mm3_per_mm{ 0.0f }; float travel_dist{ 0.0f }; // mm float fan_speed{ 0.0f }; // percentage float temperature{ 0.0f }; // Celsius degrees - float time{ 0.0f }; // s - float layer_duration{ 0.0f }; // s (layer id before finalize) + std::array(PrintEstimatedStatistics::ETimeMode::Count)> time{ 0.0f, 0.0f }; // s + unsigned int layer_id{ 0 }; + bool internal_only{ false }; - - //BBS: arc move related data - EMovePathType move_path_type{ EMovePathType::Noop_move }; - Vec3f arc_center_position{ Vec3f::Zero() }; // mm - std::vector interpolation_points; // interpolation points of arc for drawing + //BBS int object_label_id{-1}; float print_z{0.0f}; float volumetric_rate() const { return feedrate * mm3_per_mm; } - //BBS: new function to support arc move - bool is_arc_move_with_interpolation_points() const { - return (move_path_type == EMovePathType::Arc_move_ccw || move_path_type == EMovePathType::Arc_move_cw) && interpolation_points.size(); - } - bool is_arc_move() const { - return move_path_type == EMovePathType::Arc_move_ccw || move_path_type == EMovePathType::Arc_move_cw; - } + float actual_volumetric_rate() const { return actual_feedrate * mm3_per_mm; } }; struct SliceWarning { @@ -240,6 +223,7 @@ class Print; int timelapse_warning_code {0}; bool support_traditional_timelapse{true}; float printable_height; + float z_offset; SettingsIds settings_ids; size_t filaments_count; bool backtrace_enabled; @@ -253,7 +237,7 @@ class Print; std::vector limit_filament_maps; PrintEstimatedStatistics print_statistics; std::vector custom_gcode_per_print_z; - std::vector>> spiral_vase_layers; + bool spiral_vase_mode; //BBS std::vector warnings; int nozzle_hrc; @@ -264,9 +248,6 @@ class Print; std::map, int > filament_change_count_map; BedType bed_type = BedType::btCount; -#if ENABLE_GCODE_VIEWER_STATISTICS - int64_t time{ 0 }; -#endif // ENABLE_GCODE_VIEWER_STATISTICS void reset(); //BBS: add mutex for protection of gcode result @@ -293,7 +274,7 @@ class Print; filament_costs = other.filament_costs; print_statistics = other.print_statistics; custom_gcode_per_print_z = other.custom_gcode_per_print_z; - spiral_vase_layers = other.spiral_vase_layers; + spiral_vase_mode = other.spiral_vase_mode; warnings = other.warnings; bed_type = other.bed_type; gcode_check_result = other.gcode_check_result; @@ -378,10 +359,6 @@ class Print; static bool s_IsBBLPrinter; -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - static const std::string Mm3_Per_Mm_Tag; -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - private: using AxisCoords = std::array; using ExtruderColors = std::vector; @@ -430,9 +407,12 @@ class Print; float cruise_feedrate{ 0.0f }; // mm/sec float acceleration_time(float entry_feedrate, float acceleration) const; - float cruise_time() const; + float cruise_time() const { return (cruise_feedrate != 0.0f) ? cruise_distance() / cruise_feedrate : 0.0f; } float deceleration_time(float distance, float acceleration) const; - float cruise_distance() const; + float acceleration_distance() const { return accelerate_until; } + float cruise_distance() const { return decelerate_after - accelerate_until; } + float deceleration_distance(float distance) const { return distance - decelerate_after; } + bool is_cruise_only(float distance) const { return std::abs(cruise_distance() - distance) < EPSILON; } }; struct TimeBlock @@ -446,6 +426,7 @@ class Print; EMoveType move_type{ EMoveType::Noop }; ExtrusionRole role{ erNone }; + unsigned int move_id{ 0 }; unsigned int g1_line_id{ 0 }; unsigned int remaining_internal_g1_lines{ 0 }; unsigned int layer_id{ 0 }; @@ -460,7 +441,10 @@ class Print; // Calculates this block's trapezoid void calculate_trapezoid(); - float time() const; + float time() const { + return trapezoid.acceleration_time(feedrate_profile.entry, acceleration) + + trapezoid.cruise_time() + trapezoid.deceleration_time(distance, acceleration); + } }; @@ -477,7 +461,7 @@ class Print; AxisCoords axis_feedrate; // mm/s AxisCoords abs_axis_feedrate; // mm/s - //BBS: unit vector of enter speed and exit speed in x-y-z space. + //BBS: unit vector of enter speed and exit speed in x-y-z space. //For line move, there are same. For arc move, there are different. Vec3f enter_direction; Vec3f exit_direction; @@ -501,6 +485,20 @@ class Print; float elapsed_time; }; + struct ActualSpeedMove + { + unsigned int move_id{ 0 }; + std::optional position; + float actual_feedrate{ 0.0f }; + std::optional delta_extruder; + std::optional feedrate; + std::optional width; + std::optional height; + std::optional mm3_per_mm; + std::optional fan_speed; + std::optional temperature; + }; + bool enabled; float acceleration; // mm/s^2 // hard limit for the acceleration, to which the firmware will clamp. @@ -512,7 +510,9 @@ class Print; // hard limit for the travel acceleration, to which the firmware will clamp. float max_travel_acceleration; // mm/s^2 float extrude_factor_override_percentage; - float time; // s + // We accumulate total print time in doubles to reduce the loss of precision + // while adding big floating numbers with small float numbers. + double time; // s struct StopTime { unsigned int g1_line_id; @@ -526,17 +526,14 @@ class Print; CustomGCodeTime gcode_time; std::vector blocks; std::vector g1_times_cache; - std::array(EMoveType::Count)> moves_time; - std::array(ExtrusionRole::erCount)> roles_time; - std::vector layers_time; + float first_layer_time; + std::vector actual_speed_moves; //BBS: prepare stage time before print model, including start gcode time and mostly same with start gcode time float prepare_time; void reset(); - // Simulates firmware st_synchronize() call - void simulate_st_synchronize(float additional_time = 0.0f); - void calculate_time(size_t keep_last_n_blocks = 0, float additional_time = 0.0f); + void calculate_time(GCodeProcessorResult& result, PrintEstimatedStatistics::ETimeMode mode, size_t keep_last_n_blocks = 0, float additional_time = 0.0f); }; struct UsedFilaments // filaments per ColorChange @@ -765,10 +762,6 @@ class Print; //BBS: x, y offset for gcode generated double m_x_offset{ 0 }; double m_y_offset{ 0 }; - //BBS: arc move related data - EMovePathType m_move_path_type{ EMovePathType::Noop_move }; - Vec3f m_arc_center{ Vec3f::Zero() }; // mm - std::vector m_interpolation_points; unsigned int m_line_id; unsigned int m_last_line_id; @@ -807,9 +800,6 @@ class Print; float m_preheat_time; int m_preheat_steps; bool m_disable_m73; -#if ENABLE_GCODE_VIEWER_STATISTICS - std::chrono::time_point m_start_time; -#endif // ENABLE_GCODE_VIEWER_STATISTICS enum class EProducer { @@ -836,12 +826,6 @@ class Print; GCodeProcessorResult m_result; static unsigned int s_result_id; -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - DataChecker m_mm3_per_mm_compare{ "mm3_per_mm", 0.01f }; - DataChecker m_height_compare{ "height", 0.01f }; - DataChecker m_width_compare{ "width", 0.01f }; -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - public: GCodeProcessor(); void init_filament_maps_and_nozzle_type_when_import_only_gcode(); @@ -876,6 +860,11 @@ class Print; // Streaming interface, for processing G-codes just generated by PrusaSlicer in a pipelined fashion. void initialize(const std::string& filename); + void initialize_result_moves() { + // 1st move must be a dummy move + assert(m_result.moves.empty()); + m_result.moves.emplace_back(GCodeProcessorResult::MoveVertex()); + } void process_buffer(const std::string& buffer); void finalize(bool post_process); @@ -884,9 +873,7 @@ class Print; std::string get_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const; std::vector>> get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const; - std::vector> get_moves_time(PrintEstimatedStatistics::ETimeMode mode) const; - std::vector> get_roles_time(PrintEstimatedStatistics::ETimeMode mode) const; - std::vector get_layers_time(PrintEstimatedStatistics::ETimeMode mode) const; + float get_first_layer_time(PrintEstimatedStatistics::ETimeMode mode) const; //BBS: set offset for gcode writer void set_xy_offset(double x, double y) { m_x_offset = x; m_y_offset = y; } @@ -917,7 +904,16 @@ class Print; // Move void process_G0(const GCodeReader::GCodeLine& line); void process_G1(const GCodeReader::GCodeLine& line, const std::optional& remaining_internal_g1_lines = std::nullopt); - void process_G2_G3(const GCodeReader::GCodeLine& line); + enum class G1DiscretizationOrigin { + G1, + G2G3, + }; + void process_G1(const std::array, 4>& axes = { std::nullopt, std::nullopt, std::nullopt, std::nullopt }, + const std::optional& feedrate = std::nullopt, G1DiscretizationOrigin origin = G1DiscretizationOrigin::G1, + const std::optional& remaining_internal_g1_lines = std::nullopt); + + // Arc Move + void process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise); void process_VG1(const GCodeReader::GCodeLine& line); @@ -1054,7 +1050,7 @@ class Print; void run_post_process(); //BBS: different path_type is only used for arc move - void store_move_vertex(EMoveType type, EMovePathType path_type = EMovePathType::Noop_move); + void store_move_vertex(EMoveType type, EMovePathType path_type = EMovePathType::Noop_move, bool internal_only = false); void set_extrusion_role(ExtrusionRole role); @@ -1077,10 +1073,15 @@ class Print; void process_custom_gcode_time(CustomGCode::Type code); void process_filaments(CustomGCode::Type code); + void calculate_time(GCodeProcessorResult& result, size_t keep_last_n_blocks = 0, float additional_time = 0.0f); + // Simulates firmware st_synchronize() call void simulate_st_synchronize(float additional_time = 0.0f); void update_estimated_times_stats(); + + double extract_absolute_position_on_axis(Axis axis, const GCodeReader::GCodeLine& line, double area_filament_cross_section); + //BBS: void update_slice_warnings(); diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index a334159e9f..0be6748594 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -528,12 +528,9 @@ public: m_extrusion_flow(0.f), m_preview_suppressed(false), m_elapsed_time(0.f), -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_default_analyzer_line_width(line_width), -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - m_gcode_flavor(flavor), - m_filpar(filament_parameters) - { + m_gcode_flavor(flavor), + m_filpar(filament_parameters) + { // ORCA: This class is only used by BBL printers, so set the parameter appropriately. // This fixes an issue where the wipe tower was using BBL tags resulting in statistics for purging in the purge tower not being displayed. GCodeProcessor::s_IsBBLPrinter = true; @@ -553,18 +550,6 @@ public: return *this; } -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - WipeTowerWriter& change_analyzer_mm3_per_mm(float len, float e) { - static const float area = float(M_PI) * 1.75f * 1.75f / 4.f; - float mm3_per_mm = (len == 0.f ? 0.f : area * e / len); - // adds tag for processor: - std::stringstream str; - str << ";" << GCodeProcessor::Mm3_Per_Mm_Tag << mm3_per_mm << "\n"; - m_gcode += str.str(); - return *this; - } -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - WipeTowerWriter& set_initial_position(const Vec2f &pos, float width = 0.f, float depth = 0.f, float internal_angle = 0.f) { m_wipe_tower_width = width; m_wipe_tower_depth = depth; @@ -602,13 +587,8 @@ public: // Suppress / resume G-code preview in Slic3r. Slic3r will have difficulty to differentiate the various // filament loading and cooling moves from normal extrusion moves. Therefore the writer // is asked to suppres output of some lines, which look like extrusions. -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - WipeTowerWriter& suppress_preview() { change_analyzer_line_width(0.f); m_preview_suppressed = true; return *this; } - WipeTowerWriter& resume_preview() { change_analyzer_line_width(m_default_analyzer_line_width); m_preview_suppressed = false; return *this; } -#else WipeTowerWriter& suppress_preview() { m_preview_suppressed = true; return *this; } - WipeTowerWriter& resume_preview() { m_preview_suppressed = false; return *this; } -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING + WipeTowerWriter& resume_preview() { m_preview_suppressed = false; return *this; } WipeTowerWriter& feedrate(float f) { @@ -647,12 +627,9 @@ public: Vec2f rot(this->rotate(Vec2f(x,y))); // this is where we want to go if (! m_preview_suppressed && e > 0.f && len > 0.f) { -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - change_analyzer_mm3_per_mm(len, e); -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - // Width of a squished extrusion, corrected for the roundings of the squished extrusions. + // Width of a squished extrusion, corrected for the roundings of the squished extrusions. // This is left zero if it is a travel move. - float width = e * m_filpar[0].filament_area / (len * m_layer_height); + float width = e * m_filpar[0].filament_area / (len * m_layer_height); // Correct for the roundings of a squished extrusion. width += m_layer_height * float(1. - M_PI / 4.); if (m_extrusions.empty() || m_extrusions.back().pos != rotated_current_pos) @@ -1212,9 +1189,6 @@ private: float m_wipe_tower_depth = 0.f; unsigned m_last_fan_speed = 0; int current_temp = -1; -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - const float m_default_analyzer_line_width; -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING float m_used_filament_length = 0.f; GCodeFlavor m_gcode_flavor; const std::vector& m_filpar; diff --git a/src/libslic3r/GCodeReader.cpp b/src/libslic3r/GCodeReader.cpp index 9889fe90cb..17510800c5 100644 --- a/src/libslic3r/GCodeReader.cpp +++ b/src/libslic3r/GCodeReader.cpp @@ -222,6 +222,28 @@ bool GCodeReader::parse_file_raw(const std::string &filename, raw_line_callback_ [](size_t){}); } +const char* GCodeReader::axis_pos(const char *raw_str, char axis) +{ + const char *c = raw_str; + // Skip the whitespaces. + c = skip_whitespaces(c); + // Skip the command. + c = skip_word(c); + // Up to the end of line or comment. + while (! is_end_of_gcode_line(*c)) { + // Skip whitespaces. + c = skip_whitespaces(c); + if (is_end_of_gcode_line(*c)) + break; + // Check the name of the axis. + if (*c == axis) + return c; + // Skip the rest of the word. + c = skip_word(c); + } + return nullptr; +} + bool GCodeReader::GCodeLine::has(char axis) const { const char *c = m_raw.c_str(); @@ -244,6 +266,29 @@ bool GCodeReader::GCodeLine::has(char axis) const return false; } +std::string_view GCodeReader::GCodeLine::axis_pos(char axis) const +{ + const std::string &s = this->raw(); + const char *c = GCodeReader::axis_pos(this->raw().c_str(), axis); + return c ? std::string_view{ c, s.size() - (c - s.data()) } : std::string_view(); +} + +bool GCodeReader::GCodeLine::has_value(std::string_view axis_pos, float &value) +{ + if (const char *c = axis_pos.data(); c) { + // Try to parse the numeric value. + double v = 0.; + const char *end = axis_pos.data() + axis_pos.size(); + auto [pend, ec] = fast_float::from_chars(++ c, end, v); + if (pend != c && is_end_of_word(*pend)) { + // The axis value has been parsed correctly. + value = float(v); + return true; + } + } + return false; +} + bool GCodeReader::GCodeLine::has_value(char axis, float &value) const { assert(is_decimal_separator_point()); diff --git a/src/libslic3r/GCodeReader.hpp b/src/libslic3r/GCodeReader.hpp index 196a7f7fc6..12b9dc98e2 100644 --- a/src/libslic3r/GCodeReader.hpp +++ b/src/libslic3r/GCodeReader.hpp @@ -26,11 +26,15 @@ public: const std::string_view comment() const { size_t pos = m_raw.find(';'); return (pos == std::string::npos) ? std::string_view() : std::string_view(m_raw).substr(pos + 1); } + // Return position in this->raw() string starting with the "axis" character. + std::string_view axis_pos(char axis) const; void clear() { m_raw.clear(); } bool has(Axis axis) const { return (m_mask & (1 << int(axis))) != 0; } float value(Axis axis) const { return m_axis[axis]; } bool has(char axis) const; bool has_value(char axis, float &value) const; + // Parse value of an axis from raw string starting at axis_pos. + static bool has_value(std::string_view axis_pos, float &value); float new_X(const GCodeReader &reader) const { return this->has(X) ? this->x() : reader.x(); } float new_Y(const GCodeReader &reader) const { return this->has(Y) ? this->y() : reader.y(); } float new_Z(const GCodeReader &reader) const { return this->has(Z) ? this->z() : reader.z(); } @@ -190,6 +194,7 @@ private: ; // silence -Wempty-body return c; } + static const char* axis_pos(const char *raw_str, char axis); GCodeConfig m_config; float m_position[NUM_AXES]; diff --git a/src/libslic3r/Geometry/ArcWelder.cpp b/src/libslic3r/Geometry/ArcWelder.cpp new file mode 100644 index 0000000000..e9218c2625 --- /dev/null +++ b/src/libslic3r/Geometry/ArcWelder.cpp @@ -0,0 +1,32 @@ +// The following code for merging circles into arches originates from https://github.com/FormerLurker/ArcWelderLib + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Arc Welder: Anti-Stutter Library +// +// Compresses many G0/G1 commands into G2/G3(arc) commands where possible, ensuring the tool paths stay within the specified resolution. +// This reduces file size and the number of gcodes per second. +// +// Uses the 'Gcode Processor Library' for gcode parsing, position processing, logging, and other various functionality. +// +// Copyright(C) 2021 - Brad Hochgesang +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// This program is free software : you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU Affero General Public License for more details. +// +// +// You can contact the author at the following email address: +// FormerLurker@pm.me +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "ArcWelder.hpp" + +namespace Slic3r { namespace Geometry { namespace ArcWelder { + +} } } // namespace Slic3r::Geometry::ArcWelder diff --git a/src/libslic3r/Geometry/ArcWelder.hpp b/src/libslic3r/Geometry/ArcWelder.hpp new file mode 100644 index 0000000000..184a2d6c7c --- /dev/null +++ b/src/libslic3r/Geometry/ArcWelder.hpp @@ -0,0 +1,71 @@ +#ifndef slic3r_Geometry_ArcWelder_hpp_ +#define slic3r_Geometry_ArcWelder_hpp_ + +#include +#include +#include +#include +#include +#include + +#include "libslic3r/libslic3r.h" + +namespace Slic3r { namespace Geometry { namespace ArcWelder { + +// Calculate center point (center of a circle) of an arc given two points and a radius. +// positive radius: take shorter arc +// negative radius: take longer arc +// radius must NOT be zero! +template +inline Eigen::Matrix arc_center( + const Eigen::MatrixBase &start_pos, + const Eigen::MatrixBase &end_pos, + const Float radius, + const bool is_ccw) +{ + static_assert(Derived::IsVectorAtCompileTime && int(Derived::SizeAtCompileTime) == 2, "arc_center(): first parameter is not a 2D vector"); + static_assert(Derived2::IsVectorAtCompileTime && int(Derived2::SizeAtCompileTime) == 2, "arc_center(): second parameter is not a 2D vector"); + static_assert(std::is_same::value, "arc_center(): Both vectors must be of the same type."); + static_assert(std::is_same::value, "arc_center(): Radius must be of the same type as the vectors."); + assert(radius != 0); + using Vector = Eigen::Matrix; + auto v = end_pos - start_pos; + Float q2 = v.squaredNorm(); + assert(q2 > 0); + Float t2 = sqr(radius) / q2 - Float(.25f); + // If the start_pos and end_pos are nearly antipodal, t2 may become slightly negative. + // In that case return a centroid of start_point & end_point. + Float t = t2 > 0 ? sqrt(t2) : Float(0); + auto mid = Float(0.5) * (start_pos + end_pos); + Vector vp{ -v.y() * t, v.x() * t }; + return (radius > Float(0)) == is_ccw ? (mid + vp).eval() : (mid - vp).eval(); +} + + +// Return number of linear segments necessary to interpolate arc of a given positive radius and positive angle to satisfy +// maximum deviation of an interpolating polyline from an analytic arc. +template +size_t arc_discretization_steps(const FloatType radius, const FloatType angle, const FloatType deviation) +{ + assert(radius > 0); + assert(angle > 0); + assert(angle <= FloatType(2. * M_PI)); + assert(deviation > 0); + + FloatType d = radius - deviation; + return d < EPSILON ? + // Radius smaller than deviation. + ( // Acute angle: a single segment interpolates the arc with sufficient accuracy. + angle < M_PI || + // Obtuse angle: Test whether the furthest point (center) of an arc is closer than deviation to the center of a line segment. + radius * (FloatType(1.) + cos(M_PI - FloatType(.5) * angle)) < deviation ? + // Single segment is sufficient + 1 : + // Two segments are necessary, the middle point is at the center of the arc. + 2) : + size_t(ceil(angle / (2. * acos(d / radius)))); +} + +} } } // namespace Slic3r::Geometry::ArcWelder + +#endif // slic3r_Geometry_ArcWelder_hpp_ diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index d8dc5a7d42..a1078cdb48 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -18,10 +18,6 @@ #define DISABLE_INSTANCES_SYNCH 0 // Use wxDataViewRender instead of wxDataViewCustomRenderer #define ENABLE_NONCUSTOM_DATA_VIEW_RENDERING 0 -// Enable G-Code viewer statistics imgui dialog -#define ENABLE_GCODE_VIEWER_STATISTICS 0 -// Enable G-Code viewer comparison between toolpaths height and width detected from gcode and calculated at gcode generation -#define ENABLE_GCODE_VIEWER_DATA_CHECKING 0 // Enable project dirty state manager debug window #define ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW 0 @@ -39,28 +35,21 @@ // Enable rework of Reload from disk command #define ENABLE_RELOAD_FROM_DISK_REWORK 1 -//==================== -// 2.4.0.beta1 techs -//==================== -#define ENABLE_2_4_0_BETA1 1 - // Enable rendering modifiers and similar objects always as transparent -#define ENABLE_MODIFIERS_ALWAYS_TRANSPARENT (1 && ENABLE_2_4_0_BETA1) - - -//==================== -// 2.4.0.beta2 techs -//==================== -#define ENABLE_2_4_0_BETA2 1 +#define ENABLE_MODIFIERS_ALWAYS_TRANSPARENT 1 // Enable modified ImGuiWrapper::slider_float() to create a compound widget where // an additional button can be used to set the keyboard focus into the slider // to allow the user to type in the desired value -#define ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT (1 && ENABLE_2_4_0_BETA2) +#define ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT 1 // Enable fit print volume command for circular printbeds -#define ENABLE_ENHANCED_PRINT_VOLUME_FIT (1 && ENABLE_2_4_0_BETA2) +#define ENABLE_ENHANCED_PRINT_VOLUME_FIT 1 // Enable picking using raytracing #define ENABLE_RAYCAST_PICKING_DEBUG 0 +// Enable imgui debug dialog for new gcode viewer (using libvgcode) +#define ENABLE_NEW_GCODE_VIEWER_DEBUG 0 +// Enable extension of tool position imgui dialog to show actual speed profile +#define ENABLE_ACTUAL_SPEED_DEBUG 1 #endif // _prusaslicer_technologies_h_ diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index 78ea99c96b..976374fe81 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -85,6 +85,7 @@ extern unsigned get_logging_level(); extern void trace(unsigned int level, const char *message); // Format memory allocated, separate thousands by comma. extern std::string format_memsize_MB(size_t n); +extern std::string format_memsize(size_t bytes, unsigned int decimals = 1); // Return string to be added to the boost::log output to inform about the current process memory allocation. // The string is non-empty if the loglevel >= info (3) or ignore_loglevel==true. // Latter is used to get the memory info from SysInfoDialog. diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp index 9b90abe74e..3168a15f79 100644 --- a/src/libslic3r/utils.cpp +++ b/src/libslic3r/utils.cpp @@ -1378,6 +1378,42 @@ std::string format_memsize_MB(size_t n) return out + "MB"; } +std::string format_memsize(size_t bytes, unsigned int decimals) +{ + static constexpr const float kb = 1024.0f; + static constexpr const float mb = 1024.0f * kb; + static constexpr const float gb = 1024.0f * mb; + static constexpr const float tb = 1024.0f * gb; + + const float f_bytes = static_cast(bytes); + if (f_bytes < kb) + return std::to_string(bytes) + " bytes"; + else if (f_bytes < mb) { + const float f_kb = f_bytes / kb; + char buf[64]; + sprintf(buf, "%.*f", decimals, f_kb); + return std::to_string(bytes) + " bytes (" + std::string(buf) + "KB)"; + } + else if (f_bytes < gb) { + const float f_mb = f_bytes / mb; + char buf[64]; + sprintf(buf, "%.*f", decimals, f_mb); + return std::to_string(bytes) + " bytes (" + std::string(buf) + "MB)"; + } + else if (f_bytes < tb) { + const float f_gb = f_bytes / gb; + char buf[64]; + sprintf(buf, "%.*f", decimals, f_gb); + return std::to_string(bytes) + " bytes (" + std::string(buf) + "GB)"; + } + else { + const float f_tb = f_bytes / tb; + char buf[64]; + sprintf(buf, "%.*f", decimals, f_tb); + return std::to_string(bytes) + " bytes (" + std::string(buf) + "TB)"; + } +} + // Returns platform-specific string to be used as log output or parsed in SysInfoDialog. // The latter parses the string with (semi)colons as separators, it should look about as // "desc1: value1; desc2: value2" or similar (spaces should not matter). diff --git a/src/libvgcode/CMakeLists.txt b/src/libvgcode/CMakeLists.txt new file mode 100644 index 0000000000..fe3f0da07f --- /dev/null +++ b/src/libvgcode/CMakeLists.txt @@ -0,0 +1,80 @@ +cmake_minimum_required(VERSION 3.13) +project(libvgcode) + +# glad library +if (EMSCRIPTEN OR SLIC3R_OPENGL_ES) + set(GLAD_SOURCES + glad/include/glad/gles2.h + glad/include/KHR/khrplatform.h + glad/src/gles2.c + ) +else () + set(GLAD_SOURCES + glad/include/glad/gl.h + glad/include/KHR/khrplatform.h + glad/src/gl.c + ) +endif () + +set(LIBVGCODE_SOURCES + # API + include/ColorPrint.hpp + include/ColorRange.hpp + include/GCodeInputData.hpp + include/PathVertex.hpp + include/Types.hpp + include/Viewer.hpp + # source + src/Bitset.hpp + src/Bitset.cpp + src/CogMarker.hpp + src/CogMarker.cpp + src/ColorPrint.cpp + src/ColorRange.cpp + src/ExtrusionRoles.hpp + src/ExtrusionRoles.cpp + src/GCodeInputData.cpp + src/Layers.hpp + src/Layers.cpp + src/OpenGLUtils.hpp + src/OpenGLUtils.cpp + src/OptionTemplate.hpp + src/OptionTemplate.cpp + src/PathVertex.cpp + src/Range.hpp + src/Range.cpp + src/SegmentTemplate.hpp + src/SegmentTemplate.cpp + src/Settings.hpp + src/Settings.cpp + src/Shaders.hpp + src/ShadersES.hpp + src/ToolMarker.hpp + src/ToolMarker.cpp + src/Types.cpp + src/Utils.hpp + src/Utils.cpp + src/Viewer.cpp + src/ViewerImpl.hpp + src/ViewerImpl.cpp + src/ViewRange.hpp + src/ViewRange.cpp + ${GLAD_SOURCES} +) + +add_library(libvgcode STATIC ${LIBVGCODE_SOURCES}) + +if (EMSCRIPTEN OR SLIC3R_OPENGL_ES) + add_compile_definitions(ENABLE_OPENGL_ES) +endif() + +if (WIN32) + foreach(_source IN ITEMS ${LIBVGCODE_SOURCES}) + get_filename_component(_source_path "${_source}" PATH) + string(REPLACE "/" "\\" _group_path "${_source_path}") + source_group("${_group_path}" FILES "${_source}") + endforeach() +endif () + +# glad includes +include_directories(glad/include) \ No newline at end of file diff --git a/src/libvgcode/glad/include/KHR/khrplatform.h b/src/libvgcode/glad/include/KHR/khrplatform.h new file mode 100644 index 0000000000..01646449ca --- /dev/null +++ b/src/libvgcode/glad/include/KHR/khrplatform.h @@ -0,0 +1,311 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2018 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * The master copy of khrplatform.h is maintained in the Khronos EGL + * Registry repository at https://github.com/KhronosGroup/EGL-Registry + * The last semantic modification to khrplatform.h was at commit ID: + * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by filing pull requests or issues on + * the EGL Registry repository linked above. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) +# define KHRONOS_STATIC 1 +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(KHRONOS_STATIC) + /* If the preprocessor constant KHRONOS_STATIC is defined, make the + * header compatible with static linking. */ +# define KHRONOS_APICALL +#elif defined(_WIN32) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#elif defined(__ANDROID__) +# define KHRONOS_APICALL __attribute__((visibility("default"))) +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 +/* + * To support platform where unsigned long cannot be used interchangeably with + * inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t. + * Ideally, we could just use (u)intptr_t everywhere, but this could result in + * ABI breakage if khronos_uintptr_t is changed from unsigned long to + * unsigned long long or similar (this results in different C++ name mangling). + * To avoid changes for existing platforms, we restrict usage of intptr_t to + * platforms where the size of a pointer is larger than the size of long. + */ +#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__) +#if __SIZEOF_POINTER__ > __SIZEOF_LONG__ +#define KHRONOS_USE_INTPTR_T +#endif +#endif + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +/* + * Types that differ between LLP64 and LP64 architectures - in LLP64, + * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears + * to be the only LLP64 architecture in current use. + */ +#ifdef KHRONOS_USE_INTPTR_T +typedef intptr_t khronos_intptr_t; +typedef uintptr_t khronos_uintptr_t; +#elif defined(_WIN64) +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +#endif + +#if defined(_WIN64) +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ diff --git a/src/libvgcode/glad/include/glad/gl.h b/src/libvgcode/glad/include/glad/gl.h new file mode 100644 index 0000000000..9a81409086 --- /dev/null +++ b/src/libvgcode/glad/include/glad/gl.h @@ -0,0 +1,3644 @@ +/** + * Loader generated by glad 2.0.4 on Thu Feb 1 07:09:02 2024 + * + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + * + * Generator: C/C++ + * Specification: gl + * Extensions: 0 + * + * APIs: + * - gl:core=4.6 + * + * Options: + * - ALIAS = False + * - DEBUG = False + * - HEADER_ONLY = False + * - LOADER = True + * - MX = False + * - ON_DEMAND = False + * + * Commandline: + * --api='gl:core=4.6' --extensions='' c --loader + * + * Online: + * http://glad.sh/#api=gl%3Acore%3D4.6&extensions=&generator=c&options=LOADER + * + */ + +#ifndef GLAD_GL_H_ +#define GLAD_GL_H_ + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-id-macro" +#endif +#ifdef __gl_h_ + #error OpenGL (gl.h) header already included (API: gl), remove previous include! +#endif +#define __gl_h_ 1 +#ifdef __gl3_h_ + #error OpenGL (gl3.h) header already included (API: gl), remove previous include! +#endif +#define __gl3_h_ 1 +#ifdef __glext_h_ + #error OpenGL (glext.h) header already included (API: gl), remove previous include! +#endif +#define __glext_h_ 1 +#ifdef __gl3ext_h_ + #error OpenGL (gl3ext.h) header already included (API: gl), remove previous include! +#endif +#define __gl3ext_h_ 1 +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#define GLAD_GL +#define GLAD_OPTION_GL_LOADER + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GLAD_PLATFORM_H_ +#define GLAD_PLATFORM_H_ + +#ifndef GLAD_PLATFORM_WIN32 + #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__) + #define GLAD_PLATFORM_WIN32 1 + #else + #define GLAD_PLATFORM_WIN32 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_APPLE + #ifdef __APPLE__ + #define GLAD_PLATFORM_APPLE 1 + #else + #define GLAD_PLATFORM_APPLE 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_EMSCRIPTEN + #ifdef __EMSCRIPTEN__ + #define GLAD_PLATFORM_EMSCRIPTEN 1 + #else + #define GLAD_PLATFORM_EMSCRIPTEN 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_UWP + #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) + #ifdef __has_include + #if __has_include() + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #endif + + #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY + #include + #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) + #define GLAD_PLATFORM_UWP 1 + #endif + #endif + + #ifndef GLAD_PLATFORM_UWP + #define GLAD_PLATFORM_UWP 0 + #endif +#endif + +#ifdef __GNUC__ + #define GLAD_GNUC_EXTENSION __extension__ +#else + #define GLAD_GNUC_EXTENSION +#endif + +#define GLAD_UNUSED(x) (void)(x) + +#ifndef GLAD_API_CALL + #if defined(GLAD_API_CALL_EXPORT) + #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) + #if defined(GLAD_API_CALL_EXPORT_BUILD) + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllexport)) extern + #else + #define GLAD_API_CALL __declspec(dllexport) extern + #endif + #else + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllimport)) extern + #else + #define GLAD_API_CALL __declspec(dllimport) extern + #endif + #endif + #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) + #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern + #else + #define GLAD_API_CALL extern + #endif + #else + #define GLAD_API_CALL extern + #endif +#endif + +#ifdef APIENTRY + #define GLAD_API_PTR APIENTRY +#elif GLAD_PLATFORM_WIN32 + #define GLAD_API_PTR __stdcall +#else + #define GLAD_API_PTR +#endif + +#ifndef GLAPI +#define GLAPI GLAD_API_CALL +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY GLAD_API_PTR +#endif + +#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) +#define GLAD_VERSION_MAJOR(version) (version / 10000) +#define GLAD_VERSION_MINOR(version) (version % 10000) + +#define GLAD_GENERATOR_VERSION "2.0.4" + +typedef void (*GLADapiproc)(void); + +typedef GLADapiproc (*GLADloadfunc)(const char *name); +typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name); + +typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); +typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); + +#endif /* GLAD_PLATFORM_H_ */ + +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_ALL_SHADER_BITS 0xFFFFFFFF +#define GL_ALPHA 0x1906 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_ALWAYS 0x0207 +#define GL_AND 0x1501 +#define GL_AND_INVERTED 0x1504 +#define GL_AND_REVERSE 0x1502 +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ARRAY_SIZE 0x92FB +#define GL_ARRAY_STRIDE 0x92FE +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_AUTO_GENERATE_MIPMAP 0x8295 +#define GL_BACK 0x0405 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_BGRA_INTEGER 0x8D9B +#define GL_BGR_INTEGER 0x8D9A +#define GL_BLEND 0x0BE2 +#define GL_BLEND_COLOR 0x8005 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLOCK_INDEX 0x92FD +#define GL_BLUE 0x1905 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_BUFFER 0x82E0 +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_STORAGE_FLAGS 0x8220 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_BUFFER_USAGE 0x8765 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_BYTE 0x1400 +#define GL_CAVEAT_SUPPORT 0x82B8 +#define GL_CCW 0x0901 +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_CLEAR 0x1500 +#define GL_CLEAR_BUFFER 0x82B4 +#define GL_CLEAR_TEXTURE 0x9365 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 +#define GL_CLIENT_STORAGE_BIT 0x0200 +#define GL_CLIPPING_INPUT_PRIMITIVES 0x82F6 +#define GL_CLIPPING_OUTPUT_PRIMITIVES 0x82F7 +#define GL_CLIP_DEPTH_MODE 0x935D +#define GL_CLIP_DISTANCE0 0x3000 +#define GL_CLIP_DISTANCE1 0x3001 +#define GL_CLIP_DISTANCE2 0x3002 +#define GL_CLIP_DISTANCE3 0x3003 +#define GL_CLIP_DISTANCE4 0x3004 +#define GL_CLIP_DISTANCE5 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_CLIP_ORIGIN 0x935C +#define GL_COLOR 0x1800 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_COLOR_ATTACHMENT16 0x8CF0 +#define GL_COLOR_ATTACHMENT17 0x8CF1 +#define GL_COLOR_ATTACHMENT18 0x8CF2 +#define GL_COLOR_ATTACHMENT19 0x8CF3 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT20 0x8CF4 +#define GL_COLOR_ATTACHMENT21 0x8CF5 +#define GL_COLOR_ATTACHMENT22 0x8CF6 +#define GL_COLOR_ATTACHMENT23 0x8CF7 +#define GL_COLOR_ATTACHMENT24 0x8CF8 +#define GL_COLOR_ATTACHMENT25 0x8CF9 +#define GL_COLOR_ATTACHMENT26 0x8CFA +#define GL_COLOR_ATTACHMENT27 0x8CFB +#define GL_COLOR_ATTACHMENT28 0x8CFC +#define GL_COLOR_ATTACHMENT29 0x8CFD +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT30 0x8CFE +#define GL_COLOR_ATTACHMENT31 0x8CFF +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_COMPONENTS 0x8283 +#define GL_COLOR_ENCODING 0x8296 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_COLOR_RENDERABLE 0x8286 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B +#define GL_COMPILE_STATUS 0x8B81 +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_RG 0x8226 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#define GL_COMPUTE_SHADER_INVOCATIONS 0x82F5 +#define GL_COMPUTE_SUBROUTINE 0x92ED +#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 +#define GL_COMPUTE_TEXTURE 0x82A0 +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_CONDITION_SATISFIED 0x911C +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_FLAGS 0x821E +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 +#define GL_CONTEXT_FLAG_NO_ERROR_BIT 0x00000008 +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 +#define GL_CONTEXT_LOST 0x0507 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC +#define GL_COPY 0x1503 +#define GL_COPY_INVERTED 0x150C +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_CURRENT_QUERY 0x8865 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_CW 0x0900 +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DECR 0x1E03 +#define GL_DECR_WRAP 0x8508 +#define GL_DELETE_STATUS 0x8B80 +#define GL_DEPTH 0x1801 +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_DEPTH_CLAMP 0x864F +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH_COMPONENTS 0x8284 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_RENDERABLE 0x8287 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_DITHER 0x0BD0 +#define GL_DONT_CARE 0x1100 +#define GL_DOUBLE 0x140A +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE +#define GL_DRAW_BUFFER 0x0C01 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#define GL_DST_ALPHA 0x0304 +#define GL_DST_COLOR 0x0306 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_STORAGE_BIT 0x0100 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_EQUAL 0x0202 +#define GL_EQUIV 0x1509 +#define GL_EXTENSIONS 0x1F03 +#define GL_FALSE 0 +#define GL_FASTEST 0x1101 +#define GL_FILL 0x1B02 +#define GL_FILTER 0x829A +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_FIXED 0x140C +#define GL_FIXED_ONLY 0x891D +#define GL_FLOAT 0x1406 +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4 0x8B5C +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_FRACTIONAL_EVEN 0x8E7C +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_FRAGMENT_SHADER_INVOCATIONS 0x82F4 +#define GL_FRAGMENT_SUBROUTINE 0x92EC +#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 +#define GL_FRAGMENT_TEXTURE 0x829F +#define GL_FRAMEBUFFER 0x8D40 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FRAMEBUFFER_BLEND 0x828B +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_RENDERABLE 0x8289 +#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_FRONT 0x0404 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_FRONT_FACE 0x0B46 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_FULL_SUPPORT 0x82B7 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_FUNC_SUBTRACT 0x800A +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED 0x82F3 +#define GL_GEOMETRY_SUBROUTINE 0x92EB +#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 +#define GL_GEOMETRY_TEXTURE 0x829E +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEQUAL 0x0206 +#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 +#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 +#define GL_GREATER 0x0204 +#define GL_GREEN 0x1904 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_GUILTY_CONTEXT_RESET 0x8253 +#define GL_HALF_FLOAT 0x140B +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_HIGH_INT 0x8DF5 +#define GL_IMAGE_1D 0x904C +#define GL_IMAGE_1D_ARRAY 0x9052 +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_IMAGE_2D_MULTISAMPLE 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +#define GL_IMAGE_2D_RECT 0x904F +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BUFFER 0x9051 +#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 +#define GL_IMAGE_CLASS_11_11_10 0x82C2 +#define GL_IMAGE_CLASS_1_X_16 0x82BE +#define GL_IMAGE_CLASS_1_X_32 0x82BB +#define GL_IMAGE_CLASS_1_X_8 0x82C1 +#define GL_IMAGE_CLASS_2_X_16 0x82BD +#define GL_IMAGE_CLASS_2_X_32 0x82BA +#define GL_IMAGE_CLASS_2_X_8 0x82C0 +#define GL_IMAGE_CLASS_4_X_16 0x82BC +#define GL_IMAGE_CLASS_4_X_32 0x82B9 +#define GL_IMAGE_CLASS_4_X_8 0x82BF +#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_IMAGE_PIXEL_FORMAT 0x82A9 +#define GL_IMAGE_PIXEL_TYPE 0x82AA +#define GL_IMAGE_TEXEL_SIZE 0x82A7 +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_INCR 0x1E02 +#define GL_INCR_WRAP 0x8507 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_INNOCENT_CONTEXT_RESET 0x8254 +#define GL_INT 0x1404 +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 +#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B +#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 +#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A +#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 +#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C +#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 +#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 +#define GL_INTERNALFORMAT_PREFERRED 0x8270 +#define GL_INTERNALFORMAT_RED_SIZE 0x8271 +#define GL_INTERNALFORMAT_RED_TYPE 0x8278 +#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 +#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 +#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D +#define GL_INTERNALFORMAT_SUPPORTED 0x826F +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_INT_IMAGE_1D 0x9057 +#define GL_INT_IMAGE_1D_ARRAY 0x905D +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +#define GL_INT_IMAGE_2D_RECT 0x905A +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_BUFFER 0x905C +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_INVALID_INDEX 0xFFFFFFFF +#define GL_INVALID_OPERATION 0x0502 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVERT 0x150A +#define GL_ISOLINES 0x8E7A +#define GL_IS_PER_PATCH 0x92E7 +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_KEEP 0x1E00 +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_LAYER_PROVOKING_VERTEX 0x825E +#define GL_LEFT 0x0406 +#define GL_LEQUAL 0x0203 +#define GL_LESS 0x0201 +#define GL_LINE 0x1B01 +#define GL_LINEAR 0x2601 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_LINES 0x0001 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_LINE_STRIP 0x0003 +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINK_STATUS 0x8B82 +#define GL_LOCATION 0x930E +#define GL_LOCATION_COMPONENT 0x934A +#define GL_LOCATION_INDEX 0x930F +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_LOSE_CONTEXT_ON_RESET 0x8252 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_LOW_INT 0x8DF3 +#define GL_MAJOR_VERSION 0x821B +#define GL_MANUAL_GENERATE_MIPMAP 0x8294 +#define GL_MAP_COHERENT_BIT 0x0080 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_PERSISTENT_BIT 0x0040 +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MATRIX_STRIDE 0x92FF +#define GL_MAX 0x8008 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_CLIP_DISTANCES 0x0D32 +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMBINED_DIMENSIONS 0x8282 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_MAX_CULL_DISTANCES 0x82F9 +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_DEPTH 0x8280 +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_HEIGHT 0x827F +#define GL_MAX_IMAGE_SAMPLES 0x906D +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_MAX_LAYERS 0x8281 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_VERTEX_STREAMS 0x8E71 +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VIEWPORTS 0x825B +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_WIDTH 0x827E +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_MIN 0x8007 +#define GL_MINOR_VERSION 0x821C +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_MIPMAP 0x8293 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 +#define GL_MULTISAMPLE 0x809D +#define GL_NAME_LENGTH 0x92F9 +#define GL_NAND 0x150E +#define GL_NEAREST 0x2600 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_NEGATIVE_ONE_TO_ONE 0x935E +#define GL_NEVER 0x0200 +#define GL_NICEST 0x1102 +#define GL_NONE 0 +#define GL_NOOP 0x1505 +#define GL_NOR 0x1508 +#define GL_NOTEQUAL 0x0205 +#define GL_NO_ERROR 0 +#define GL_NO_RESET_NOTIFICATION 0x8261 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_NUM_EXTENSIONS 0x821D +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_NUM_SPIR_V_EXTENSIONS 0x9554 +#define GL_OBJECT_TYPE 0x9112 +#define GL_OFFSET 0x92FC +#define GL_ONE 1 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_OR 0x1507 +#define GL_OR_INVERTED 0x150D +#define GL_OR_REVERSE 0x150B +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D +#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C +#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E +#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PARAMETER_BUFFER 0x80EE +#define GL_PARAMETER_BUFFER_BINDING 0x80EF +#define GL_PATCHES 0x000E +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_POINT 0x1B00 +#define GL_POINTS 0x0000 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_OFFSET_CLAMP 0x8E1B +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_PRIMITIVES_SUBMITTED 0x82EF +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_PROGRAM 0x82E2 +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_PROVOKING_VERTEX 0x8E4F +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_QUADS 0x0007 +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_QUERY 0x82E3 +#define GL_QUERY_BUFFER 0x9192 +#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +#define GL_QUERY_BUFFER_BINDING 0x9193 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_NO_WAIT_INVERTED 0x8E18 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_QUERY_RESULT_NO_WAIT 0x9194 +#define GL_QUERY_TARGET 0x82EA +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_WAIT_INVERTED 0x8E17 +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_R16 0x822A +#define GL_R16F 0x822D +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R16_SNORM 0x8F98 +#define GL_R32F 0x822E +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_R3_G3_B2 0x2A10 +#define GL_R8 0x8229 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R8_SNORM 0x8F94 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_READ_BUFFER 0x0C02 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_READ_ONLY 0x88B8 +#define GL_READ_PIXELS 0x828C +#define GL_READ_PIXELS_FORMAT 0x828D +#define GL_READ_PIXELS_TYPE 0x828E +#define GL_READ_WRITE 0x88BA +#define GL_RED 0x1903 +#define GL_RED_INTEGER 0x8D94 +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERER 0x1F01 +#define GL_REPEAT 0x2901 +#define GL_REPLACE 0x1E01 +#define GL_RESET_NOTIFICATION_STRATEGY 0x8256 +#define GL_RG 0x8227 +#define GL_RG16 0x822C +#define GL_RG16F 0x822F +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG16_SNORM 0x8F99 +#define GL_RG32F 0x8230 +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_RG8 0x822B +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB 0x1907 +#define GL_RGB10 0x8052 +#define GL_RGB10_A2 0x8059 +#define GL_RGB10_A2UI 0x906F +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGB16F 0x881B +#define GL_RGB16I 0x8D89 +#define GL_RGB16UI 0x8D77 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGB32F 0x8815 +#define GL_RGB32I 0x8D83 +#define GL_RGB32UI 0x8D71 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB565 0x8D62 +#define GL_RGB5_A1 0x8057 +#define GL_RGB8 0x8051 +#define GL_RGB8I 0x8D8F +#define GL_RGB8UI 0x8D7D +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGB9_E5 0x8C3D +#define GL_RGBA 0x1908 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_RGBA16F 0x881A +#define GL_RGBA16I 0x8D88 +#define GL_RGBA16UI 0x8D76 +#define GL_RGBA16_SNORM 0x8F9B +#define GL_RGBA2 0x8055 +#define GL_RGBA32F 0x8814 +#define GL_RGBA32I 0x8D82 +#define GL_RGBA32UI 0x8D70 +#define GL_RGBA4 0x8056 +#define GL_RGBA8 0x8058 +#define GL_RGBA8I 0x8D8E +#define GL_RGBA8UI 0x8D7C +#define GL_RGBA8_SNORM 0x8F97 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RG_INTEGER 0x8228 +#define GL_RIGHT 0x0407 +#define GL_SAMPLER 0x82E6 +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_BINDING 0x8919 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLES_PASSED 0x8914 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_SET 0x150F +#define GL_SHADER 0x82E1 +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_SHADER_BINARY_FORMAT_SPIR_V 0x9551 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_SHADER_IMAGE_ATOMIC 0x82A6 +#define GL_SHADER_IMAGE_LOAD 0x82A4 +#define GL_SHADER_IMAGE_STORE 0x82A5 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_TYPE 0x8B4F +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_SHORT 0x1402 +#define GL_SIGNALED 0x9119 +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SPIR_V_BINARY 0x9552 +#define GL_SPIR_V_EXTENSIONS 0x9553 +#define GL_SRC1_ALPHA 0x8589 +#define GL_SRC1_COLOR 0x88F9 +#define GL_SRC_ALPHA 0x0302 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_SRC_COLOR 0x0300 +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB_READ 0x8297 +#define GL_SRGB_WRITE 0x8298 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_STATIC_COPY 0x88E6 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STENCIL 0x1802 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_COMPONENTS 0x8285 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_INDEX 0x1901 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_RENDERABLE 0x8288 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STEREO 0x0C33 +#define GL_STREAM_COPY 0x88E2 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_SYNC_STATUS 0x9114 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#define GL_TESS_CONTROL_SHADER_PATCHES 0x82F1 +#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 +#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF +#define GL_TESS_CONTROL_TEXTURE 0x829C +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#define GL_TESS_EVALUATION_SHADER_INVOCATIONS 0x82F2 +#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA +#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 +#define GL_TESS_EVALUATION_TEXTURE 0x829D +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_TEXTURE_BUFFER_BINDING 0x8C2A +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 +#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 +#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_TEXTURE_GATHER 0x82A2 +#define GL_TEXTURE_GATHER_SHADOW 0x82A3 +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_IMAGE_FORMAT 0x828F +#define GL_TEXTURE_IMAGE_TYPE 0x8290 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_SHADOW 0x82A1 +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#define GL_TEXTURE_TARGET 0x1006 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_TEXTURE_VIEW 0x82B5 +#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD +#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB +#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE +#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF +#define GL_TIMESTAMP 0x8E28 +#define GL_TIME_ELAPSED 0x88BF +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C +#define GL_TRANSFORM_FEEDBACK_OVERFLOW 0x82EC +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW 0x82ED +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_FAN 0x0006 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_TRUE 1 +#define GL_TYPE 0x92FA +#define GL_UNDEFINED_VERTEX 0x8260 +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNKNOWN_CONTEXT_RESET 0x8255 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 +#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 +#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A +#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNSIGNALED 0x9118 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C +#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_VENDOR 0x1F00 +#define GL_VERSION 0x1F02 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_BUFFER 0x8F4F +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_VERTEX_SHADER_INVOCATIONS 0x82F0 +#define GL_VERTEX_SUBROUTINE 0x92E8 +#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE +#define GL_VERTEX_TEXTURE 0x829B +#define GL_VERTICES_SUBMITTED 0x82EE +#define GL_VIEWPORT 0x0BA2 +#define GL_VIEWPORT_BOUNDS_RANGE 0x825D +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F +#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C +#define GL_VIEW_CLASS_128_BITS 0x82C4 +#define GL_VIEW_CLASS_16_BITS 0x82CA +#define GL_VIEW_CLASS_24_BITS 0x82C9 +#define GL_VIEW_CLASS_32_BITS 0x82C8 +#define GL_VIEW_CLASS_48_BITS 0x82C7 +#define GL_VIEW_CLASS_64_BITS 0x82C6 +#define GL_VIEW_CLASS_8_BITS 0x82CB +#define GL_VIEW_CLASS_96_BITS 0x82C5 +#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 +#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 +#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 +#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 +#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC +#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD +#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE +#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF +#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 +#define GL_WAIT_FAILED 0x911D +#define GL_WRITE_ONLY 0x88B9 +#define GL_XOR 0x1506 +#define GL_ZERO 0 +#define GL_ZERO_TO_ONE 0x935F + + +#include +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef void GLvoid; +typedef khronos_int8_t GLbyte; +typedef khronos_uint8_t GLubyte; +typedef khronos_int16_t GLshort; +typedef khronos_uint16_t GLushort; +typedef int GLint; +typedef unsigned int GLuint; +typedef khronos_int32_t GLclampx; +typedef int GLsizei; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void *GLeglClientBufferEXT; +typedef void *GLeglImageOES; +typedef char GLchar; +typedef char GLcharARB; +#ifdef __APPLE__ +typedef void *GLhandleARB; +#else +typedef unsigned int GLhandleARB; +#endif +typedef khronos_uint16_t GLhalf; +typedef khronos_uint16_t GLhalfARB; +typedef khronos_int32_t GLfixed; +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_intptr_t GLintptr; +#else +typedef khronos_intptr_t GLintptr; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_intptr_t GLintptrARB; +#else +typedef khronos_intptr_t GLintptrARB; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_ssize_t GLsizeiptr; +#else +typedef khronos_ssize_t GLsizeiptr; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_ssize_t GLsizeiptrARB; +#else +typedef khronos_ssize_t GLsizeiptrARB; +#endif +typedef khronos_int64_t GLint64; +typedef khronos_int64_t GLint64EXT; +typedef khronos_uint64_t GLuint64; +typedef khronos_uint64_t GLuint64EXT; +typedef struct __GLsync *GLsync; +struct _cl_context; +struct _cl_event; +typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); +typedef unsigned short GLhalfNV; +typedef GLintptr GLvdpauSurfaceNV; +typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void); + + +#define GL_VERSION_1_0 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_0; +#define GL_VERSION_1_1 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_1; +#define GL_VERSION_1_2 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_2; +#define GL_VERSION_1_3 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_3; +#define GL_VERSION_1_4 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_4; +#define GL_VERSION_1_5 1 +GLAD_API_CALL int GLAD_GL_VERSION_1_5; +#define GL_VERSION_2_0 1 +GLAD_API_CALL int GLAD_GL_VERSION_2_0; +#define GL_VERSION_2_1 1 +GLAD_API_CALL int GLAD_GL_VERSION_2_1; +#define GL_VERSION_3_0 1 +GLAD_API_CALL int GLAD_GL_VERSION_3_0; +#define GL_VERSION_3_1 1 +GLAD_API_CALL int GLAD_GL_VERSION_3_1; +#define GL_VERSION_3_2 1 +GLAD_API_CALL int GLAD_GL_VERSION_3_2; +#define GL_VERSION_3_3 1 +GLAD_API_CALL int GLAD_GL_VERSION_3_3; +#define GL_VERSION_4_0 1 +GLAD_API_CALL int GLAD_GL_VERSION_4_0; +#define GL_VERSION_4_1 1 +GLAD_API_CALL int GLAD_GL_VERSION_4_1; +#define GL_VERSION_4_2 1 +GLAD_API_CALL int GLAD_GL_VERSION_4_2; +#define GL_VERSION_4_3 1 +GLAD_API_CALL int GLAD_GL_VERSION_4_3; +#define GL_VERSION_4_4 1 +GLAD_API_CALL int GLAD_GL_VERSION_4_4; +#define GL_VERSION_4_5 1 +GLAD_API_CALL int GLAD_GL_VERSION_4_5; +#define GL_VERSION_4_6 1 +GLAD_API_CALL int GLAD_GL_VERSION_4_6; + + +typedef void (GLAD_API_PTR *PFNGLACTIVESHADERPROGRAMPROC)(GLuint pipeline, GLuint program); +typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture); +typedef void (GLAD_API_PTR *PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); +typedef void (GLAD_API_PTR *PFNGLBEGINCONDITIONALRENDERPROC)(GLuint id, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBEGINQUERYPROC)(GLenum target, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBEGINQUERYINDEXEDPROC)(GLenum target, GLuint index, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode); +typedef void (GLAD_API_PTR *PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERSBASEPROC)(GLenum target, GLuint first, GLsizei count, const GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERSRANGEPROC)(GLenum target, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizeiptr * sizes); +typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONPROC)(GLuint program, GLuint color, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint program, GLuint colorNumber, GLuint index, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); +typedef void (GLAD_API_PTR *PFNGLBINDIMAGETEXTUREPROC)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +typedef void (GLAD_API_PTR *PFNGLBINDIMAGETEXTURESPROC)(GLuint first, GLsizei count, const GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLBINDPROGRAMPIPELINEPROC)(GLuint pipeline); +typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler); +typedef void (GLAD_API_PTR *PFNGLBINDSAMPLERSPROC)(GLuint first, GLsizei count, const GLuint * samplers); +typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); +typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREUNITPROC)(GLuint unit, GLuint texture); +typedef void (GLAD_API_PTR *PFNGLBINDTEXTURESPROC)(GLuint first, GLsizei count, const GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLBINDTRANSFORMFEEDBACKPROC)(GLenum target, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBINDVERTEXARRAYPROC)(GLuint array); +typedef void (GLAD_API_PTR *PFNGLBINDVERTEXBUFFERPROC)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLBINDVERTEXBUFFERSPROC)(GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides); +typedef void (GLAD_API_PTR *PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEIPROC)(GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONIPROC)(GLuint buf, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEIPROC)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCIPROC)(GLuint buf, GLenum src, GLenum dst); +typedef void (GLAD_API_PTR *PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAD_API_PTR *PFNGLBLITNAMEDFRAMEBUFFERPROC)(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAD_API_PTR *PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void * data, GLenum usage); +typedef void (GLAD_API_PTR *PFNGLBUFFERSTORAGEPROC)(GLenum target, GLsizeiptr size, const void * data, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void * data); +typedef GLenum (GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target); +typedef GLenum (GLAD_API_PTR *PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)(GLuint framebuffer, GLenum target); +typedef void (GLAD_API_PTR *PFNGLCLAMPCOLORPROC)(GLenum target, GLenum clamp); +typedef void (GLAD_API_PTR *PFNGLCLEARPROC)(GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERDATAPROC)(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERSUBDATAPROC)(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHPROC)(GLdouble depth); +typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHFPROC)(GLfloat d); +typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDBUFFERDATAPROC)(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLCLEARSTENCILPROC)(GLint s); +typedef void (GLAD_API_PTR *PFNGLCLEARTEXIMAGEPROC)(GLuint texture, GLint level, GLenum format, GLenum type, const void * data); +typedef void (GLAD_API_PTR *PFNGLCLEARTEXSUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * data); +typedef GLenum (GLAD_API_PTR *PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GLAD_API_PTR *PFNGLCLIPCONTROLPROC)(GLenum origin, GLenum depth); +typedef void (GLAD_API_PTR *PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (GLAD_API_PTR *PFNGLCOLORMASKIPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAD_API_PTR *PFNGLCOMPILESHADERPROC)(GLuint shader); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLCOPYIMAGESUBDATAPROC)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +typedef void (GLAD_API_PTR *PFNGLCOPYNAMEDBUFFERSUBDATAPROC)(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCREATEBUFFERSPROC)(GLsizei n, GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLCREATEFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers); +typedef GLuint (GLAD_API_PTR *PFNGLCREATEPROGRAMPROC)(void); +typedef void (GLAD_API_PTR *PFNGLCREATEPROGRAMPIPELINESPROC)(GLsizei n, GLuint * pipelines); +typedef void (GLAD_API_PTR *PFNGLCREATEQUERIESPROC)(GLenum target, GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLCREATERENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLCREATESAMPLERSPROC)(GLsizei n, GLuint * samplers); +typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROC)(GLenum type); +typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROGRAMVPROC)(GLenum type, GLsizei count, const GLchar *const* strings); +typedef void (GLAD_API_PTR *PFNGLCREATETEXTURESPROC)(GLenum target, GLsizei n, GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLCREATETRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLCREATEVERTEXARRAYSPROC)(GLsizei n, GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLCULLFACEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECALLBACKPROC)(GLDEBUGPROC callback, const void * userParam); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECONTROLPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGEINSERTPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf); +typedef void (GLAD_API_PTR *PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPIPELINESPROC)(GLsizei n, const GLuint * pipelines); +typedef void (GLAD_API_PTR *PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint * samplers); +typedef void (GLAD_API_PTR *PFNGLDELETESHADERPROC)(GLuint shader); +typedef void (GLAD_API_PTR *PFNGLDELETESYNCPROC)(GLsync sync); +typedef void (GLAD_API_PTR *PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLDELETETRANSFORMFEEDBACKSPROC)(GLsizei n, const GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLDEPTHFUNCPROC)(GLenum func); +typedef void (GLAD_API_PTR *PFNGLDEPTHMASKPROC)(GLboolean flag); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEPROC)(GLdouble n, GLdouble f); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEARRAYVPROC)(GLuint first, GLsizei count, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEINDEXEDPROC)(GLuint index, GLdouble n, GLdouble f); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEFPROC)(GLfloat n, GLfloat f); +typedef void (GLAD_API_PTR *PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); +typedef void (GLAD_API_PTR *PFNGLDISABLEPROC)(GLenum cap); +typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXARRAYATTRIBPROC)(GLuint vaobj, GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISABLEIPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLDISPATCHCOMPUTEPROC)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (GLAD_API_PTR *PFNGLDISPATCHCOMPUTEINDIRECTPROC)(GLintptr indirect); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINDIRECTPROC)(GLenum mode, const void * indirect); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERPROC)(GLenum buf); +typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum * bufs); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINDIRECTPROC)(GLenum mode, GLenum type, const void * indirect); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices); +typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices, GLint basevertex); +typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKPROC)(GLenum mode, GLuint id); +typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)(GLenum mode, GLuint id, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)(GLenum mode, GLuint id, GLuint stream); +typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLENABLEPROC)(GLenum cap); +typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXARRAYATTRIBPROC)(GLuint vaobj, GLuint index); +typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLENABLEIPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLENDCONDITIONALRENDERPROC)(void); +typedef void (GLAD_API_PTR *PFNGLENDQUERYPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLENDQUERYINDEXEDPROC)(GLenum target, GLuint index); +typedef void (GLAD_API_PTR *PFNGLENDTRANSFORMFEEDBACKPROC)(void); +typedef GLsync (GLAD_API_PTR *PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLFINISHPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFLUSHPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length); +typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAD_API_PTR *PFNGLFRONTFACEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLGENBUFFERSPROC)(GLsizei n, GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLGENPROGRAMPIPELINESPROC)(GLsizei n, GLuint * pipelines); +typedef void (GLAD_API_PTR *PFNGLGENQUERIESPROC)(GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint * samplers); +typedef void (GLAD_API_PTR *PFNGLGENTEXTURESPROC)(GLsizei n, GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLGENTRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLGENERATEMIPMAPPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLGENERATETEXTUREMIPMAPPROC)(GLuint texture); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)(GLuint program, GLuint bufferIndex, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINENAMEPROC)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint * values); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformBlockName); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformName); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders); +typedef GLint (GLAD_API_PTR *PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean * data); +typedef void (GLAD_API_PTR *PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean * data); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, void * data); +typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint level, void * img); +typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC)(GLuint texture, GLint level, GLsizei bufSize, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void * pixels); +typedef GLuint (GLAD_API_PTR *PFNGLGETDEBUGMESSAGELOGPROC)(GLuint count, GLsizei bufSize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog); +typedef void (GLAD_API_PTR *PFNGLGETDOUBLEI_VPROC)(GLenum target, GLuint index, GLdouble * data); +typedef void (GLAD_API_PTR *PFNGLGETDOUBLEVPROC)(GLenum pname, GLdouble * data); +typedef GLenum (GLAD_API_PTR *PFNGLGETERRORPROC)(void); +typedef void (GLAD_API_PTR *PFNGLGETFLOATI_VPROC)(GLenum target, GLuint index, GLfloat * data); +typedef void (GLAD_API_PTR *PFNGLGETFLOATVPROC)(GLenum pname, GLfloat * data); +typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATAINDEXPROC)(GLuint program, const GLchar * name); +typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef GLenum (GLAD_API_PTR *PFNGLGETGRAPHICSRESETSTATUSPROC)(void); +typedef void (GLAD_API_PTR *PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERVPROC)(GLenum pname, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETINTERNALFORMATI64VPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETINTERNALFORMATIVPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat * val); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPARAMETERI64VPROC)(GLuint buffer, GLenum pname, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPARAMETERIVPROC)(GLuint buffer, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPOINTERVPROC)(GLuint buffer, GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, void * data); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLuint framebuffer, GLenum attachment, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC)(GLuint framebuffer, GLenum pname, GLint * param); +typedef void (GLAD_API_PTR *PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC)(GLuint renderbuffer, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei * length, GLchar * label); +typedef void (GLAD_API_PTR *PFNGLGETOBJECTPTRLABELPROC)(const void * ptr, GLsizei bufSize, GLsizei * length, GLchar * label); +typedef void (GLAD_API_PTR *PFNGLGETPOINTERVPROC)(GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMBINARYPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLenum * binaryFormat, void * binary); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINTERFACEIVPROC)(GLuint program, GLenum programInterface, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEINFOLOGPROC)(GLuint pipeline, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEIVPROC)(GLuint pipeline, GLenum pname, GLint * params); +typedef GLuint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEINDEXPROC)(GLuint program, GLenum programInterface, const GLchar * name); +typedef GLint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCELOCATIONPROC)(GLuint program, GLenum programInterface, const GLchar * name); +typedef GLint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)(GLuint program, GLenum programInterface, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCENAMEPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEIVPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei count, GLsizei * length, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMSTAGEIVPROC)(GLuint program, GLenum shadertype, GLenum pname, GLint * values); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTI64VPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTIVPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTUI64VPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTUIVPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (GLAD_API_PTR *PFNGLGETQUERYINDEXEDIVPROC)(GLenum target, GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTI64VPROC)(GLuint id, GLenum pname, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTIVPROC)(GLuint id, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUI64VPROC)(GLuint id, GLenum pname, GLuint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum shadertype, GLenum precisiontype, GLint * range, GLint * precision); +typedef void (GLAD_API_PTR *PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source); +typedef void (GLAD_API_PTR *PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint * params); +typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGPROC)(GLenum name); +typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); +typedef GLuint (GLAD_API_PTR *PFNGLGETSUBROUTINEINDEXPROC)(GLuint program, GLenum shadertype, const GLchar * name); +typedef GLint (GLAD_API_PTR *PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)(GLuint program, GLenum shadertype, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei count, GLsizei * length, GLint * values); +typedef void (GLAD_API_PTR *PFNGLGETTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREIMAGEPROC)(GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETTEXTURELEVELPARAMETERFVPROC)(GLuint texture, GLint level, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTURELEVELPARAMETERIVPROC)(GLuint texture, GLint level, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIIVPROC)(GLuint texture, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIUIVPROC)(GLuint texture, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERFVPROC)(GLuint texture, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIVPROC)(GLuint texture, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXTURESUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKI64_VPROC)(GLuint xfb, GLenum pname, GLuint index, GLint64 * param); +typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKI_VPROC)(GLuint xfb, GLenum pname, GLuint index, GLint * param); +typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKIVPROC)(GLuint xfb, GLenum pname, GLint * param); +typedef GLuint (GLAD_API_PTR *PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar * uniformBlockName); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint * uniformIndices); +typedef GLint (GLAD_API_PTR *PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMSUBROUTINEUIVPROC)(GLenum shadertype, GLint location, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMDVPROC)(GLuint program, GLint location, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYINDEXED64IVPROC)(GLuint vaobj, GLuint index, GLenum pname, GLint64 * param); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYINDEXEDIVPROC)(GLuint vaobj, GLuint index, GLenum pname, GLint * param); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYIVPROC)(GLuint vaobj, GLenum pname, GLint * param); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBLDVPROC)(GLuint index, GLenum pname, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void ** pointer); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBDVPROC)(GLuint index, GLenum pname, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint lod, GLsizei bufSize, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETNTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * pixels); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMDVPROC)(GLuint program, GLint location, GLsizei bufSize, GLdouble * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMFVPROC)(GLuint program, GLint location, GLsizei bufSize, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMIVPROC)(GLuint program, GLint location, GLsizei bufSize, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMUIVPROC)(GLuint program, GLint location, GLsizei bufSize, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLHINTPROC)(GLenum target, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLINVALIDATEBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (GLAD_API_PTR *PFNGLINVALIDATEFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments); +typedef void (GLAD_API_PTR *PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC)(GLuint framebuffer, GLsizei numAttachments, const GLenum * attachments); +typedef void (GLAD_API_PTR *PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC)(GLuint framebuffer, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLINVALIDATESUBFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLINVALIDATETEXIMAGEPROC)(GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLINVALIDATETEXSUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); +typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERPROC)(GLuint buffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDPROC)(GLenum cap); +typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDIPROC)(GLenum target, GLuint index); +typedef GLboolean (GLAD_API_PTR *PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPROC)(GLuint program); +typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPIPELINEPROC)(GLuint pipeline); +typedef GLboolean (GLAD_API_PTR *PFNGLISQUERYPROC)(GLuint id); +typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISSAMPLERPROC)(GLuint sampler); +typedef GLboolean (GLAD_API_PTR *PFNGLISSHADERPROC)(GLuint shader); +typedef GLboolean (GLAD_API_PTR *PFNGLISSYNCPROC)(GLsync sync); +typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREPROC)(GLuint texture); +typedef GLboolean (GLAD_API_PTR *PFNGLISTRANSFORMFEEDBACKPROC)(GLuint id); +typedef GLboolean (GLAD_API_PTR *PFNGLISVERTEXARRAYPROC)(GLuint array); +typedef void (GLAD_API_PTR *PFNGLLINEWIDTHPROC)(GLfloat width); +typedef void (GLAD_API_PTR *PFNGLLINKPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLLOGICOPPROC)(GLenum opcode); +typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERPROC)(GLenum target, GLenum access); +typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void * (GLAD_API_PTR *PFNGLMAPNAMEDBUFFERPROC)(GLuint buffer, GLenum access); +typedef void * (GLAD_API_PTR *PFNGLMAPNAMEDBUFFERRANGEPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GLAD_API_PTR *PFNGLMEMORYBARRIERPROC)(GLbitfield barriers); +typedef void (GLAD_API_PTR *PFNGLMEMORYBARRIERBYREGIONPROC)(GLbitfield barriers); +typedef void (GLAD_API_PTR *PFNGLMINSAMPLESHADINGPROC)(GLfloat value); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSPROC)(GLenum mode, const GLint * first, const GLsizei * count, GLsizei drawcount); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTPROC)(GLenum mode, const void * indirect, GLsizei drawcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC)(GLenum mode, const void * indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount, const GLint * basevertex); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTPROC)(GLenum mode, GLenum type, const void * indirect, GLsizei drawcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC)(GLenum mode, GLenum type, const void * indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERDATAPROC)(GLuint buffer, GLsizeiptr size, const void * data, GLenum usage); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSTORAGEPROC)(GLuint buffer, GLsizeiptr size, const void * data, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, const void * data); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC)(GLuint framebuffer, GLenum buf); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC)(GLuint framebuffer, GLsizei n, const GLenum * bufs); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC)(GLuint framebuffer, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC)(GLuint framebuffer, GLenum src); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC)(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTUREPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEPROC)(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei length, const GLchar * label); +typedef void (GLAD_API_PTR *PFNGLOBJECTPTRLABELPROC)(const void * ptr, GLsizei length, const GLchar * label); +typedef void (GLAD_API_PTR *PFNGLPATCHPARAMETERFVPROC)(GLenum pname, const GLfloat * values); +typedef void (GLAD_API_PTR *PFNGLPATCHPARAMETERIPROC)(GLenum pname, GLint value); +typedef void (GLAD_API_PTR *PFNGLPAUSETRANSFORMFEEDBACKPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPIXELSTOREFPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFPROC)(GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFVPROC)(GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIVPROC)(GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLPOINTSIZEPROC)(GLfloat size); +typedef void (GLAD_API_PTR *PFNGLPOLYGONMODEPROC)(GLenum face, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units); +typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETCLAMPPROC)(GLfloat factor, GLfloat units, GLfloat clamp); +typedef void (GLAD_API_PTR *PFNGLPOPDEBUGGROUPPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLPROGRAMBINARYPROC)(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length); +typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETERIPROC)(GLuint program, GLenum pname, GLint value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1DPROC)(GLuint program, GLint location, GLdouble v0); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FPROC)(GLuint program, GLint location, GLfloat v0); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IPROC)(GLuint program, GLint location, GLint v0); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIPROC)(GLuint program, GLint location, GLuint v0); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IPROC)(GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROVOKINGVERTEXPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLPUSHDEBUGGROUPPROC)(GLenum source, GLuint id, GLsizei length, const GLchar * message); +typedef void (GLAD_API_PTR *PFNGLQUERYCOUNTERPROC)(GLuint id, GLenum target); +typedef void (GLAD_API_PTR *PFNGLREADBUFFERPROC)(GLenum src); +typedef void (GLAD_API_PTR *PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels); +typedef void (GLAD_API_PTR *PFNGLREADNPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void * data); +typedef void (GLAD_API_PTR *PFNGLRELEASESHADERCOMPILERPROC)(void); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRESUMETRANSFORMFEEDBACKPROC)(void); +typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert); +typedef void (GLAD_API_PTR *PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, const GLint * param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, const GLuint * param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat * param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint * param); +typedef void (GLAD_API_PTR *PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLSCISSORARRAYVPROC)(GLuint first, GLsizei count, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLSCISSORINDEXEDPROC)(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLSCISSORINDEXEDVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLSHADERBINARYPROC)(GLsizei count, const GLuint * shaders, GLenum binaryFormat, const void * binary, GLsizei length); +typedef void (GLAD_API_PTR *PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const* string, const GLint * length); +typedef void (GLAD_API_PTR *PFNGLSHADERSTORAGEBLOCKBINDINGPROC)(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); +typedef void (GLAD_API_PTR *PFNGLSPECIALIZESHADERPROC)(GLuint shader, const GLchar * pEntryPoint, GLuint numSpecializationConstants, const GLuint * pConstantIndex, const GLuint * pConstantValue); +typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILMASKPROC)(GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass); +typedef void (GLAD_API_PTR *PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GLAD_API_PTR *PFNGLTEXBUFFERPROC)(GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLTEXBUFFERRANGEPROC)(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE1DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE1DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE2DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTUREBARRIERPROC)(void); +typedef void (GLAD_API_PTR *PFNGLTEXTUREBUFFERPROC)(GLuint texture, GLenum internalformat, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLTEXTUREBUFFERRANGEPROC)(GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIIVPROC)(GLuint texture, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIUIVPROC)(GLuint texture, GLenum pname, const GLuint * params); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERFPROC)(GLuint texture, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERFVPROC)(GLuint texture, GLenum pname, const GLfloat * param); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIPROC)(GLuint texture, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIVPROC)(GLuint texture, GLenum pname, const GLint * param); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE1DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE2DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE3DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTUREVIEWPROC)(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC)(GLuint xfb, GLuint index, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC)(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1DPROC)(GLint location, GLdouble x); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1DVPROC)(GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1IPROC)(GLint location, GLint v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2DPROC)(GLint location, GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2DVPROC)(GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3DPROC)(GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3DVPROC)(GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4DPROC)(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4DVPROC)(GLint location, GLsizei count, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMSUBROUTINESUIVPROC)(GLenum shadertype, GLsizei count, const GLuint * indices); +typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPBUFFERPROC)(GLenum target); +typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPNAMEDBUFFERPROC)(GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMSTAGESPROC)(GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPIPELINEPROC)(GLuint pipeline); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBBINDINGPROC)(GLuint vaobj, GLuint attribindex, GLuint bindingindex); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBIFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBLFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYBINDINGDIVISORPROC)(GLuint vaobj, GLuint bindingindex, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYELEMENTBUFFERPROC)(GLuint vaobj, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXBUFFERPROC)(GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXBUFFERSPROC)(GLuint vaobj, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DPROC)(GLuint index, GLdouble x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SPROC)(GLuint index, GLshort x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DPROC)(GLuint index, GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SPROC)(GLuint index, GLshort x, GLshort y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SPROC)(GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NBVPROC)(GLuint index, const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NIVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NSVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBPROC)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBVPROC)(GLuint index, const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUSVPROC)(GLuint index, const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4BVPROC)(GLuint index, const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UBVPROC)(GLuint index, const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4USVPROC)(GLuint index, const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBBINDINGPROC)(GLuint attribindex, GLuint bindingindex); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IPROC)(GLuint index, GLint x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIPROC)(GLuint index, GLuint x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IPROC)(GLuint index, GLint x, GLint y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIPROC)(GLuint index, GLuint x, GLuint y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IPROC)(GLuint index, GLint x, GLint y, GLint z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4BVPROC)(GLuint index, const GLbyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4SVPROC)(GLuint index, const GLshort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UBVPROC)(GLuint index, const GLubyte * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4USVPROC)(GLuint index, const GLushort * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1DPROC)(GLuint index, GLdouble x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2DPROC)(GLuint index, GLdouble x, GLdouble y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4DVPROC)(GLuint index, const GLdouble * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBLFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBLPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXBINDINGDIVISORPROC)(GLuint bindingindex, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTARRAYVPROC)(GLuint first, GLsizei count, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); + +GLAD_API_CALL PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram; +#define glActiveShaderProgram glad_glActiveShaderProgram +GLAD_API_CALL PFNGLACTIVETEXTUREPROC glad_glActiveTexture; +#define glActiveTexture glad_glActiveTexture +GLAD_API_CALL PFNGLATTACHSHADERPROC glad_glAttachShader; +#define glAttachShader glad_glAttachShader +GLAD_API_CALL PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; +#define glBeginConditionalRender glad_glBeginConditionalRender +GLAD_API_CALL PFNGLBEGINQUERYPROC glad_glBeginQuery; +#define glBeginQuery glad_glBeginQuery +GLAD_API_CALL PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed; +#define glBeginQueryIndexed glad_glBeginQueryIndexed +GLAD_API_CALL PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; +#define glBeginTransformFeedback glad_glBeginTransformFeedback +GLAD_API_CALL PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; +#define glBindAttribLocation glad_glBindAttribLocation +GLAD_API_CALL PFNGLBINDBUFFERPROC glad_glBindBuffer; +#define glBindBuffer glad_glBindBuffer +GLAD_API_CALL PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; +#define glBindBufferBase glad_glBindBufferBase +GLAD_API_CALL PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; +#define glBindBufferRange glad_glBindBufferRange +GLAD_API_CALL PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase; +#define glBindBuffersBase glad_glBindBuffersBase +GLAD_API_CALL PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange; +#define glBindBuffersRange glad_glBindBuffersRange +GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; +#define glBindFragDataLocation glad_glBindFragDataLocation +GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; +#define glBindFragDataLocationIndexed glad_glBindFragDataLocationIndexed +GLAD_API_CALL PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; +#define glBindFramebuffer glad_glBindFramebuffer +GLAD_API_CALL PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture; +#define glBindImageTexture glad_glBindImageTexture +GLAD_API_CALL PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures; +#define glBindImageTextures glad_glBindImageTextures +GLAD_API_CALL PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline; +#define glBindProgramPipeline glad_glBindProgramPipeline +GLAD_API_CALL PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; +#define glBindRenderbuffer glad_glBindRenderbuffer +GLAD_API_CALL PFNGLBINDSAMPLERPROC glad_glBindSampler; +#define glBindSampler glad_glBindSampler +GLAD_API_CALL PFNGLBINDSAMPLERSPROC glad_glBindSamplers; +#define glBindSamplers glad_glBindSamplers +GLAD_API_CALL PFNGLBINDTEXTUREPROC glad_glBindTexture; +#define glBindTexture glad_glBindTexture +GLAD_API_CALL PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit; +#define glBindTextureUnit glad_glBindTextureUnit +GLAD_API_CALL PFNGLBINDTEXTURESPROC glad_glBindTextures; +#define glBindTextures glad_glBindTextures +GLAD_API_CALL PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback; +#define glBindTransformFeedback glad_glBindTransformFeedback +GLAD_API_CALL PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; +#define glBindVertexArray glad_glBindVertexArray +GLAD_API_CALL PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer; +#define glBindVertexBuffer glad_glBindVertexBuffer +GLAD_API_CALL PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers; +#define glBindVertexBuffers glad_glBindVertexBuffers +GLAD_API_CALL PFNGLBLENDCOLORPROC glad_glBlendColor; +#define glBlendColor glad_glBlendColor +GLAD_API_CALL PFNGLBLENDEQUATIONPROC glad_glBlendEquation; +#define glBlendEquation glad_glBlendEquation +GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; +#define glBlendEquationSeparate glad_glBlendEquationSeparate +GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEIPROC glad_glBlendEquationSeparatei; +#define glBlendEquationSeparatei glad_glBlendEquationSeparatei +GLAD_API_CALL PFNGLBLENDEQUATIONIPROC glad_glBlendEquationi; +#define glBlendEquationi glad_glBlendEquationi +GLAD_API_CALL PFNGLBLENDFUNCPROC glad_glBlendFunc; +#define glBlendFunc glad_glBlendFunc +GLAD_API_CALL PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; +#define glBlendFuncSeparate glad_glBlendFuncSeparate +GLAD_API_CALL PFNGLBLENDFUNCSEPARATEIPROC glad_glBlendFuncSeparatei; +#define glBlendFuncSeparatei glad_glBlendFuncSeparatei +GLAD_API_CALL PFNGLBLENDFUNCIPROC glad_glBlendFunci; +#define glBlendFunci glad_glBlendFunci +GLAD_API_CALL PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; +#define glBlitFramebuffer glad_glBlitFramebuffer +GLAD_API_CALL PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer; +#define glBlitNamedFramebuffer glad_glBlitNamedFramebuffer +GLAD_API_CALL PFNGLBUFFERDATAPROC glad_glBufferData; +#define glBufferData glad_glBufferData +GLAD_API_CALL PFNGLBUFFERSTORAGEPROC glad_glBufferStorage; +#define glBufferStorage glad_glBufferStorage +GLAD_API_CALL PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; +#define glBufferSubData glad_glBufferSubData +GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; +#define glCheckFramebufferStatus glad_glCheckFramebufferStatus +GLAD_API_CALL PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus; +#define glCheckNamedFramebufferStatus glad_glCheckNamedFramebufferStatus +GLAD_API_CALL PFNGLCLAMPCOLORPROC glad_glClampColor; +#define glClampColor glad_glClampColor +GLAD_API_CALL PFNGLCLEARPROC glad_glClear; +#define glClear glad_glClear +GLAD_API_CALL PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData; +#define glClearBufferData glad_glClearBufferData +GLAD_API_CALL PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData; +#define glClearBufferSubData glad_glClearBufferSubData +GLAD_API_CALL PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; +#define glClearBufferfi glad_glClearBufferfi +GLAD_API_CALL PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; +#define glClearBufferfv glad_glClearBufferfv +GLAD_API_CALL PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; +#define glClearBufferiv glad_glClearBufferiv +GLAD_API_CALL PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; +#define glClearBufferuiv glad_glClearBufferuiv +GLAD_API_CALL PFNGLCLEARCOLORPROC glad_glClearColor; +#define glClearColor glad_glClearColor +GLAD_API_CALL PFNGLCLEARDEPTHPROC glad_glClearDepth; +#define glClearDepth glad_glClearDepth +GLAD_API_CALL PFNGLCLEARDEPTHFPROC glad_glClearDepthf; +#define glClearDepthf glad_glClearDepthf +GLAD_API_CALL PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData; +#define glClearNamedBufferData glad_glClearNamedBufferData +GLAD_API_CALL PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData; +#define glClearNamedBufferSubData glad_glClearNamedBufferSubData +GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi; +#define glClearNamedFramebufferfi glad_glClearNamedFramebufferfi +GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv; +#define glClearNamedFramebufferfv glad_glClearNamedFramebufferfv +GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv; +#define glClearNamedFramebufferiv glad_glClearNamedFramebufferiv +GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv; +#define glClearNamedFramebufferuiv glad_glClearNamedFramebufferuiv +GLAD_API_CALL PFNGLCLEARSTENCILPROC glad_glClearStencil; +#define glClearStencil glad_glClearStencil +GLAD_API_CALL PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage; +#define glClearTexImage glad_glClearTexImage +GLAD_API_CALL PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage; +#define glClearTexSubImage glad_glClearTexSubImage +GLAD_API_CALL PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; +#define glClientWaitSync glad_glClientWaitSync +GLAD_API_CALL PFNGLCLIPCONTROLPROC glad_glClipControl; +#define glClipControl glad_glClipControl +GLAD_API_CALL PFNGLCOLORMASKPROC glad_glColorMask; +#define glColorMask glad_glColorMask +GLAD_API_CALL PFNGLCOLORMASKIPROC glad_glColorMaski; +#define glColorMaski glad_glColorMaski +GLAD_API_CALL PFNGLCOMPILESHADERPROC glad_glCompileShader; +#define glCompileShader glad_glCompileShader +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; +#define glCompressedTexImage1D glad_glCompressedTexImage1D +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; +#define glCompressedTexImage2D glad_glCompressedTexImage2D +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; +#define glCompressedTexImage3D glad_glCompressedTexImage3D +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; +#define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; +#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; +#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D +GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D; +#define glCompressedTextureSubImage1D glad_glCompressedTextureSubImage1D +GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D; +#define glCompressedTextureSubImage2D glad_glCompressedTextureSubImage2D +GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D; +#define glCompressedTextureSubImage3D glad_glCompressedTextureSubImage3D +GLAD_API_CALL PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; +#define glCopyBufferSubData glad_glCopyBufferSubData +GLAD_API_CALL PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData; +#define glCopyImageSubData glad_glCopyImageSubData +GLAD_API_CALL PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData; +#define glCopyNamedBufferSubData glad_glCopyNamedBufferSubData +GLAD_API_CALL PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; +#define glCopyTexImage1D glad_glCopyTexImage1D +GLAD_API_CALL PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; +#define glCopyTexImage2D glad_glCopyTexImage2D +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; +#define glCopyTexSubImage1D glad_glCopyTexSubImage1D +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; +#define glCopyTexSubImage2D glad_glCopyTexSubImage2D +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; +#define glCopyTexSubImage3D glad_glCopyTexSubImage3D +GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D; +#define glCopyTextureSubImage1D glad_glCopyTextureSubImage1D +GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D; +#define glCopyTextureSubImage2D glad_glCopyTextureSubImage2D +GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D; +#define glCopyTextureSubImage3D glad_glCopyTextureSubImage3D +GLAD_API_CALL PFNGLCREATEBUFFERSPROC glad_glCreateBuffers; +#define glCreateBuffers glad_glCreateBuffers +GLAD_API_CALL PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers; +#define glCreateFramebuffers glad_glCreateFramebuffers +GLAD_API_CALL PFNGLCREATEPROGRAMPROC glad_glCreateProgram; +#define glCreateProgram glad_glCreateProgram +GLAD_API_CALL PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines; +#define glCreateProgramPipelines glad_glCreateProgramPipelines +GLAD_API_CALL PFNGLCREATEQUERIESPROC glad_glCreateQueries; +#define glCreateQueries glad_glCreateQueries +GLAD_API_CALL PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers; +#define glCreateRenderbuffers glad_glCreateRenderbuffers +GLAD_API_CALL PFNGLCREATESAMPLERSPROC glad_glCreateSamplers; +#define glCreateSamplers glad_glCreateSamplers +GLAD_API_CALL PFNGLCREATESHADERPROC glad_glCreateShader; +#define glCreateShader glad_glCreateShader +GLAD_API_CALL PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv; +#define glCreateShaderProgramv glad_glCreateShaderProgramv +GLAD_API_CALL PFNGLCREATETEXTURESPROC glad_glCreateTextures; +#define glCreateTextures glad_glCreateTextures +GLAD_API_CALL PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks; +#define glCreateTransformFeedbacks glad_glCreateTransformFeedbacks +GLAD_API_CALL PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays; +#define glCreateVertexArrays glad_glCreateVertexArrays +GLAD_API_CALL PFNGLCULLFACEPROC glad_glCullFace; +#define glCullFace glad_glCullFace +GLAD_API_CALL PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback; +#define glDebugMessageCallback glad_glDebugMessageCallback +GLAD_API_CALL PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl; +#define glDebugMessageControl glad_glDebugMessageControl +GLAD_API_CALL PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert; +#define glDebugMessageInsert glad_glDebugMessageInsert +GLAD_API_CALL PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; +#define glDeleteBuffers glad_glDeleteBuffers +GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; +#define glDeleteFramebuffers glad_glDeleteFramebuffers +GLAD_API_CALL PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; +#define glDeleteProgram glad_glDeleteProgram +GLAD_API_CALL PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines; +#define glDeleteProgramPipelines glad_glDeleteProgramPipelines +GLAD_API_CALL PFNGLDELETEQUERIESPROC glad_glDeleteQueries; +#define glDeleteQueries glad_glDeleteQueries +GLAD_API_CALL PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; +#define glDeleteRenderbuffers glad_glDeleteRenderbuffers +GLAD_API_CALL PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; +#define glDeleteSamplers glad_glDeleteSamplers +GLAD_API_CALL PFNGLDELETESHADERPROC glad_glDeleteShader; +#define glDeleteShader glad_glDeleteShader +GLAD_API_CALL PFNGLDELETESYNCPROC glad_glDeleteSync; +#define glDeleteSync glad_glDeleteSync +GLAD_API_CALL PFNGLDELETETEXTURESPROC glad_glDeleteTextures; +#define glDeleteTextures glad_glDeleteTextures +GLAD_API_CALL PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks; +#define glDeleteTransformFeedbacks glad_glDeleteTransformFeedbacks +GLAD_API_CALL PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; +#define glDeleteVertexArrays glad_glDeleteVertexArrays +GLAD_API_CALL PFNGLDEPTHFUNCPROC glad_glDepthFunc; +#define glDepthFunc glad_glDepthFunc +GLAD_API_CALL PFNGLDEPTHMASKPROC glad_glDepthMask; +#define glDepthMask glad_glDepthMask +GLAD_API_CALL PFNGLDEPTHRANGEPROC glad_glDepthRange; +#define glDepthRange glad_glDepthRange +GLAD_API_CALL PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv; +#define glDepthRangeArrayv glad_glDepthRangeArrayv +GLAD_API_CALL PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed; +#define glDepthRangeIndexed glad_glDepthRangeIndexed +GLAD_API_CALL PFNGLDEPTHRANGEFPROC glad_glDepthRangef; +#define glDepthRangef glad_glDepthRangef +GLAD_API_CALL PFNGLDETACHSHADERPROC glad_glDetachShader; +#define glDetachShader glad_glDetachShader +GLAD_API_CALL PFNGLDISABLEPROC glad_glDisable; +#define glDisable glad_glDisable +GLAD_API_CALL PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib; +#define glDisableVertexArrayAttrib glad_glDisableVertexArrayAttrib +GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; +#define glDisableVertexAttribArray glad_glDisableVertexAttribArray +GLAD_API_CALL PFNGLDISABLEIPROC glad_glDisablei; +#define glDisablei glad_glDisablei +GLAD_API_CALL PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute; +#define glDispatchCompute glad_glDispatchCompute +GLAD_API_CALL PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect; +#define glDispatchComputeIndirect glad_glDispatchComputeIndirect +GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays; +#define glDrawArrays glad_glDrawArrays +GLAD_API_CALL PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect; +#define glDrawArraysIndirect glad_glDrawArraysIndirect +GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; +#define glDrawArraysInstanced glad_glDrawArraysInstanced +GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance; +#define glDrawArraysInstancedBaseInstance glad_glDrawArraysInstancedBaseInstance +GLAD_API_CALL PFNGLDRAWBUFFERPROC glad_glDrawBuffer; +#define glDrawBuffer glad_glDrawBuffer +GLAD_API_CALL PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; +#define glDrawBuffers glad_glDrawBuffers +GLAD_API_CALL PFNGLDRAWELEMENTSPROC glad_glDrawElements; +#define glDrawElements glad_glDrawElements +GLAD_API_CALL PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; +#define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex +GLAD_API_CALL PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect; +#define glDrawElementsIndirect glad_glDrawElementsIndirect +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; +#define glDrawElementsInstanced glad_glDrawElementsInstanced +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance; +#define glDrawElementsInstancedBaseInstance glad_glDrawElementsInstancedBaseInstance +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; +#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance; +#define glDrawElementsInstancedBaseVertexBaseInstance glad_glDrawElementsInstancedBaseVertexBaseInstance +GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; +#define glDrawRangeElements glad_glDrawRangeElements +GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; +#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex +GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback; +#define glDrawTransformFeedback glad_glDrawTransformFeedback +GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced; +#define glDrawTransformFeedbackInstanced glad_glDrawTransformFeedbackInstanced +GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream; +#define glDrawTransformFeedbackStream glad_glDrawTransformFeedbackStream +GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced; +#define glDrawTransformFeedbackStreamInstanced glad_glDrawTransformFeedbackStreamInstanced +GLAD_API_CALL PFNGLENABLEPROC glad_glEnable; +#define glEnable glad_glEnable +GLAD_API_CALL PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib; +#define glEnableVertexArrayAttrib glad_glEnableVertexArrayAttrib +GLAD_API_CALL PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; +#define glEnableVertexAttribArray glad_glEnableVertexAttribArray +GLAD_API_CALL PFNGLENABLEIPROC glad_glEnablei; +#define glEnablei glad_glEnablei +GLAD_API_CALL PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; +#define glEndConditionalRender glad_glEndConditionalRender +GLAD_API_CALL PFNGLENDQUERYPROC glad_glEndQuery; +#define glEndQuery glad_glEndQuery +GLAD_API_CALL PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed; +#define glEndQueryIndexed glad_glEndQueryIndexed +GLAD_API_CALL PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; +#define glEndTransformFeedback glad_glEndTransformFeedback +GLAD_API_CALL PFNGLFENCESYNCPROC glad_glFenceSync; +#define glFenceSync glad_glFenceSync +GLAD_API_CALL PFNGLFINISHPROC glad_glFinish; +#define glFinish glad_glFinish +GLAD_API_CALL PFNGLFLUSHPROC glad_glFlush; +#define glFlush glad_glFlush +GLAD_API_CALL PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; +#define glFlushMappedBufferRange glad_glFlushMappedBufferRange +GLAD_API_CALL PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange; +#define glFlushMappedNamedBufferRange glad_glFlushMappedNamedBufferRange +GLAD_API_CALL PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri; +#define glFramebufferParameteri glad_glFramebufferParameteri +GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; +#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; +#define glFramebufferTexture glad_glFramebufferTexture +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; +#define glFramebufferTexture1D glad_glFramebufferTexture1D +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; +#define glFramebufferTexture2D glad_glFramebufferTexture2D +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; +#define glFramebufferTexture3D glad_glFramebufferTexture3D +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; +#define glFramebufferTextureLayer glad_glFramebufferTextureLayer +GLAD_API_CALL PFNGLFRONTFACEPROC glad_glFrontFace; +#define glFrontFace glad_glFrontFace +GLAD_API_CALL PFNGLGENBUFFERSPROC glad_glGenBuffers; +#define glGenBuffers glad_glGenBuffers +GLAD_API_CALL PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; +#define glGenFramebuffers glad_glGenFramebuffers +GLAD_API_CALL PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines; +#define glGenProgramPipelines glad_glGenProgramPipelines +GLAD_API_CALL PFNGLGENQUERIESPROC glad_glGenQueries; +#define glGenQueries glad_glGenQueries +GLAD_API_CALL PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; +#define glGenRenderbuffers glad_glGenRenderbuffers +GLAD_API_CALL PFNGLGENSAMPLERSPROC glad_glGenSamplers; +#define glGenSamplers glad_glGenSamplers +GLAD_API_CALL PFNGLGENTEXTURESPROC glad_glGenTextures; +#define glGenTextures glad_glGenTextures +GLAD_API_CALL PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks; +#define glGenTransformFeedbacks glad_glGenTransformFeedbacks +GLAD_API_CALL PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; +#define glGenVertexArrays glad_glGenVertexArrays +GLAD_API_CALL PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; +#define glGenerateMipmap glad_glGenerateMipmap +GLAD_API_CALL PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap; +#define glGenerateTextureMipmap glad_glGenerateTextureMipmap +GLAD_API_CALL PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv; +#define glGetActiveAtomicCounterBufferiv glad_glGetActiveAtomicCounterBufferiv +GLAD_API_CALL PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; +#define glGetActiveAttrib glad_glGetActiveAttrib +GLAD_API_CALL PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName; +#define glGetActiveSubroutineName glad_glGetActiveSubroutineName +GLAD_API_CALL PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName; +#define glGetActiveSubroutineUniformName glad_glGetActiveSubroutineUniformName +GLAD_API_CALL PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv; +#define glGetActiveSubroutineUniformiv glad_glGetActiveSubroutineUniformiv +GLAD_API_CALL PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; +#define glGetActiveUniform glad_glGetActiveUniform +GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; +#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName +GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; +#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv +GLAD_API_CALL PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; +#define glGetActiveUniformName glad_glGetActiveUniformName +GLAD_API_CALL PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; +#define glGetActiveUniformsiv glad_glGetActiveUniformsiv +GLAD_API_CALL PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; +#define glGetAttachedShaders glad_glGetAttachedShaders +GLAD_API_CALL PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; +#define glGetAttribLocation glad_glGetAttribLocation +GLAD_API_CALL PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; +#define glGetBooleani_v glad_glGetBooleani_v +GLAD_API_CALL PFNGLGETBOOLEANVPROC glad_glGetBooleanv; +#define glGetBooleanv glad_glGetBooleanv +GLAD_API_CALL PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; +#define glGetBufferParameteri64v glad_glGetBufferParameteri64v +GLAD_API_CALL PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; +#define glGetBufferParameteriv glad_glGetBufferParameteriv +GLAD_API_CALL PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; +#define glGetBufferPointerv glad_glGetBufferPointerv +GLAD_API_CALL PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; +#define glGetBufferSubData glad_glGetBufferSubData +GLAD_API_CALL PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; +#define glGetCompressedTexImage glad_glGetCompressedTexImage +GLAD_API_CALL PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage; +#define glGetCompressedTextureImage glad_glGetCompressedTextureImage +GLAD_API_CALL PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage; +#define glGetCompressedTextureSubImage glad_glGetCompressedTextureSubImage +GLAD_API_CALL PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog; +#define glGetDebugMessageLog glad_glGetDebugMessageLog +GLAD_API_CALL PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v; +#define glGetDoublei_v glad_glGetDoublei_v +GLAD_API_CALL PFNGLGETDOUBLEVPROC glad_glGetDoublev; +#define glGetDoublev glad_glGetDoublev +GLAD_API_CALL PFNGLGETERRORPROC glad_glGetError; +#define glGetError glad_glGetError +GLAD_API_CALL PFNGLGETFLOATI_VPROC glad_glGetFloati_v; +#define glGetFloati_v glad_glGetFloati_v +GLAD_API_CALL PFNGLGETFLOATVPROC glad_glGetFloatv; +#define glGetFloatv glad_glGetFloatv +GLAD_API_CALL PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; +#define glGetFragDataIndex glad_glGetFragDataIndex +GLAD_API_CALL PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; +#define glGetFragDataLocation glad_glGetFragDataLocation +GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; +#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv +GLAD_API_CALL PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv; +#define glGetFramebufferParameteriv glad_glGetFramebufferParameteriv +GLAD_API_CALL PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus; +#define glGetGraphicsResetStatus glad_glGetGraphicsResetStatus +GLAD_API_CALL PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; +#define glGetInteger64i_v glad_glGetInteger64i_v +GLAD_API_CALL PFNGLGETINTEGER64VPROC glad_glGetInteger64v; +#define glGetInteger64v glad_glGetInteger64v +GLAD_API_CALL PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; +#define glGetIntegeri_v glad_glGetIntegeri_v +GLAD_API_CALL PFNGLGETINTEGERVPROC glad_glGetIntegerv; +#define glGetIntegerv glad_glGetIntegerv +GLAD_API_CALL PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v; +#define glGetInternalformati64v glad_glGetInternalformati64v +GLAD_API_CALL PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ; +#define glGetInternalformativ glad_glGetInternalformativ +GLAD_API_CALL PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; +#define glGetMultisamplefv glad_glGetMultisamplefv +GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v; +#define glGetNamedBufferParameteri64v glad_glGetNamedBufferParameteri64v +GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv; +#define glGetNamedBufferParameteriv glad_glGetNamedBufferParameteriv +GLAD_API_CALL PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv; +#define glGetNamedBufferPointerv glad_glGetNamedBufferPointerv +GLAD_API_CALL PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData; +#define glGetNamedBufferSubData glad_glGetNamedBufferSubData +GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv; +#define glGetNamedFramebufferAttachmentParameteriv glad_glGetNamedFramebufferAttachmentParameteriv +GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv; +#define glGetNamedFramebufferParameteriv glad_glGetNamedFramebufferParameteriv +GLAD_API_CALL PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv; +#define glGetNamedRenderbufferParameteriv glad_glGetNamedRenderbufferParameteriv +GLAD_API_CALL PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel; +#define glGetObjectLabel glad_glGetObjectLabel +GLAD_API_CALL PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel; +#define glGetObjectPtrLabel glad_glGetObjectPtrLabel +GLAD_API_CALL PFNGLGETPOINTERVPROC glad_glGetPointerv; +#define glGetPointerv glad_glGetPointerv +GLAD_API_CALL PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary; +#define glGetProgramBinary glad_glGetProgramBinary +GLAD_API_CALL PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; +#define glGetProgramInfoLog glad_glGetProgramInfoLog +GLAD_API_CALL PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv; +#define glGetProgramInterfaceiv glad_glGetProgramInterfaceiv +GLAD_API_CALL PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog; +#define glGetProgramPipelineInfoLog glad_glGetProgramPipelineInfoLog +GLAD_API_CALL PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv; +#define glGetProgramPipelineiv glad_glGetProgramPipelineiv +GLAD_API_CALL PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex; +#define glGetProgramResourceIndex glad_glGetProgramResourceIndex +GLAD_API_CALL PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation; +#define glGetProgramResourceLocation glad_glGetProgramResourceLocation +GLAD_API_CALL PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex; +#define glGetProgramResourceLocationIndex glad_glGetProgramResourceLocationIndex +GLAD_API_CALL PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName; +#define glGetProgramResourceName glad_glGetProgramResourceName +GLAD_API_CALL PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv; +#define glGetProgramResourceiv glad_glGetProgramResourceiv +GLAD_API_CALL PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv; +#define glGetProgramStageiv glad_glGetProgramStageiv +GLAD_API_CALL PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; +#define glGetProgramiv glad_glGetProgramiv +GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v; +#define glGetQueryBufferObjecti64v glad_glGetQueryBufferObjecti64v +GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv; +#define glGetQueryBufferObjectiv glad_glGetQueryBufferObjectiv +GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v; +#define glGetQueryBufferObjectui64v glad_glGetQueryBufferObjectui64v +GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv; +#define glGetQueryBufferObjectuiv glad_glGetQueryBufferObjectuiv +GLAD_API_CALL PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv; +#define glGetQueryIndexediv glad_glGetQueryIndexediv +GLAD_API_CALL PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v; +#define glGetQueryObjecti64v glad_glGetQueryObjecti64v +GLAD_API_CALL PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; +#define glGetQueryObjectiv glad_glGetQueryObjectiv +GLAD_API_CALL PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; +#define glGetQueryObjectui64v glad_glGetQueryObjectui64v +GLAD_API_CALL PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; +#define glGetQueryObjectuiv glad_glGetQueryObjectuiv +GLAD_API_CALL PFNGLGETQUERYIVPROC glad_glGetQueryiv; +#define glGetQueryiv glad_glGetQueryiv +GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; +#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv; +#define glGetSamplerParameterIiv glad_glGetSamplerParameterIiv +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv; +#define glGetSamplerParameterIuiv glad_glGetSamplerParameterIuiv +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; +#define glGetSamplerParameterfv glad_glGetSamplerParameterfv +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; +#define glGetSamplerParameteriv glad_glGetSamplerParameteriv +GLAD_API_CALL PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; +#define glGetShaderInfoLog glad_glGetShaderInfoLog +GLAD_API_CALL PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat; +#define glGetShaderPrecisionFormat glad_glGetShaderPrecisionFormat +GLAD_API_CALL PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; +#define glGetShaderSource glad_glGetShaderSource +GLAD_API_CALL PFNGLGETSHADERIVPROC glad_glGetShaderiv; +#define glGetShaderiv glad_glGetShaderiv +GLAD_API_CALL PFNGLGETSTRINGPROC glad_glGetString; +#define glGetString glad_glGetString +GLAD_API_CALL PFNGLGETSTRINGIPROC glad_glGetStringi; +#define glGetStringi glad_glGetStringi +GLAD_API_CALL PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex; +#define glGetSubroutineIndex glad_glGetSubroutineIndex +GLAD_API_CALL PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation; +#define glGetSubroutineUniformLocation glad_glGetSubroutineUniformLocation +GLAD_API_CALL PFNGLGETSYNCIVPROC glad_glGetSynciv; +#define glGetSynciv glad_glGetSynciv +GLAD_API_CALL PFNGLGETTEXIMAGEPROC glad_glGetTexImage; +#define glGetTexImage glad_glGetTexImage +GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; +#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv +GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; +#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv +GLAD_API_CALL PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; +#define glGetTexParameterIiv glad_glGetTexParameterIiv +GLAD_API_CALL PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; +#define glGetTexParameterIuiv glad_glGetTexParameterIuiv +GLAD_API_CALL PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; +#define glGetTexParameterfv glad_glGetTexParameterfv +GLAD_API_CALL PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; +#define glGetTexParameteriv glad_glGetTexParameteriv +GLAD_API_CALL PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage; +#define glGetTextureImage glad_glGetTextureImage +GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv; +#define glGetTextureLevelParameterfv glad_glGetTextureLevelParameterfv +GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv; +#define glGetTextureLevelParameteriv glad_glGetTextureLevelParameteriv +GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv; +#define glGetTextureParameterIiv glad_glGetTextureParameterIiv +GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv; +#define glGetTextureParameterIuiv glad_glGetTextureParameterIuiv +GLAD_API_CALL PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv; +#define glGetTextureParameterfv glad_glGetTextureParameterfv +GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv; +#define glGetTextureParameteriv glad_glGetTextureParameteriv +GLAD_API_CALL PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage; +#define glGetTextureSubImage glad_glGetTextureSubImage +GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; +#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying +GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v; +#define glGetTransformFeedbacki64_v glad_glGetTransformFeedbacki64_v +GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v; +#define glGetTransformFeedbacki_v glad_glGetTransformFeedbacki_v +GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv; +#define glGetTransformFeedbackiv glad_glGetTransformFeedbackiv +GLAD_API_CALL PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; +#define glGetUniformBlockIndex glad_glGetUniformBlockIndex +GLAD_API_CALL PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; +#define glGetUniformIndices glad_glGetUniformIndices +GLAD_API_CALL PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; +#define glGetUniformLocation glad_glGetUniformLocation +GLAD_API_CALL PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv; +#define glGetUniformSubroutineuiv glad_glGetUniformSubroutineuiv +GLAD_API_CALL PFNGLGETUNIFORMDVPROC glad_glGetUniformdv; +#define glGetUniformdv glad_glGetUniformdv +GLAD_API_CALL PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; +#define glGetUniformfv glad_glGetUniformfv +GLAD_API_CALL PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; +#define glGetUniformiv glad_glGetUniformiv +GLAD_API_CALL PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; +#define glGetUniformuiv glad_glGetUniformuiv +GLAD_API_CALL PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv; +#define glGetVertexArrayIndexed64iv glad_glGetVertexArrayIndexed64iv +GLAD_API_CALL PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv; +#define glGetVertexArrayIndexediv glad_glGetVertexArrayIndexediv +GLAD_API_CALL PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv; +#define glGetVertexArrayiv glad_glGetVertexArrayiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; +#define glGetVertexAttribIiv glad_glGetVertexAttribIiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; +#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv; +#define glGetVertexAttribLdv glad_glGetVertexAttribLdv +GLAD_API_CALL PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; +#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv +GLAD_API_CALL PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; +#define glGetVertexAttribdv glad_glGetVertexAttribdv +GLAD_API_CALL PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; +#define glGetVertexAttribfv glad_glGetVertexAttribfv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; +#define glGetVertexAttribiv glad_glGetVertexAttribiv +GLAD_API_CALL PFNGLGETNCOMPRESSEDTEXIMAGEPROC glad_glGetnCompressedTexImage; +#define glGetnCompressedTexImage glad_glGetnCompressedTexImage +GLAD_API_CALL PFNGLGETNTEXIMAGEPROC glad_glGetnTexImage; +#define glGetnTexImage glad_glGetnTexImage +GLAD_API_CALL PFNGLGETNUNIFORMDVPROC glad_glGetnUniformdv; +#define glGetnUniformdv glad_glGetnUniformdv +GLAD_API_CALL PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv; +#define glGetnUniformfv glad_glGetnUniformfv +GLAD_API_CALL PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv; +#define glGetnUniformiv glad_glGetnUniformiv +GLAD_API_CALL PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv; +#define glGetnUniformuiv glad_glGetnUniformuiv +GLAD_API_CALL PFNGLHINTPROC glad_glHint; +#define glHint glad_glHint +GLAD_API_CALL PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData; +#define glInvalidateBufferData glad_glInvalidateBufferData +GLAD_API_CALL PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData; +#define glInvalidateBufferSubData glad_glInvalidateBufferSubData +GLAD_API_CALL PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer; +#define glInvalidateFramebuffer glad_glInvalidateFramebuffer +GLAD_API_CALL PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData; +#define glInvalidateNamedFramebufferData glad_glInvalidateNamedFramebufferData +GLAD_API_CALL PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData; +#define glInvalidateNamedFramebufferSubData glad_glInvalidateNamedFramebufferSubData +GLAD_API_CALL PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer; +#define glInvalidateSubFramebuffer glad_glInvalidateSubFramebuffer +GLAD_API_CALL PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage; +#define glInvalidateTexImage glad_glInvalidateTexImage +GLAD_API_CALL PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage; +#define glInvalidateTexSubImage glad_glInvalidateTexSubImage +GLAD_API_CALL PFNGLISBUFFERPROC glad_glIsBuffer; +#define glIsBuffer glad_glIsBuffer +GLAD_API_CALL PFNGLISENABLEDPROC glad_glIsEnabled; +#define glIsEnabled glad_glIsEnabled +GLAD_API_CALL PFNGLISENABLEDIPROC glad_glIsEnabledi; +#define glIsEnabledi glad_glIsEnabledi +GLAD_API_CALL PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; +#define glIsFramebuffer glad_glIsFramebuffer +GLAD_API_CALL PFNGLISPROGRAMPROC glad_glIsProgram; +#define glIsProgram glad_glIsProgram +GLAD_API_CALL PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline; +#define glIsProgramPipeline glad_glIsProgramPipeline +GLAD_API_CALL PFNGLISQUERYPROC glad_glIsQuery; +#define glIsQuery glad_glIsQuery +GLAD_API_CALL PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; +#define glIsRenderbuffer glad_glIsRenderbuffer +GLAD_API_CALL PFNGLISSAMPLERPROC glad_glIsSampler; +#define glIsSampler glad_glIsSampler +GLAD_API_CALL PFNGLISSHADERPROC glad_glIsShader; +#define glIsShader glad_glIsShader +GLAD_API_CALL PFNGLISSYNCPROC glad_glIsSync; +#define glIsSync glad_glIsSync +GLAD_API_CALL PFNGLISTEXTUREPROC glad_glIsTexture; +#define glIsTexture glad_glIsTexture +GLAD_API_CALL PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback; +#define glIsTransformFeedback glad_glIsTransformFeedback +GLAD_API_CALL PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; +#define glIsVertexArray glad_glIsVertexArray +GLAD_API_CALL PFNGLLINEWIDTHPROC glad_glLineWidth; +#define glLineWidth glad_glLineWidth +GLAD_API_CALL PFNGLLINKPROGRAMPROC glad_glLinkProgram; +#define glLinkProgram glad_glLinkProgram +GLAD_API_CALL PFNGLLOGICOPPROC glad_glLogicOp; +#define glLogicOp glad_glLogicOp +GLAD_API_CALL PFNGLMAPBUFFERPROC glad_glMapBuffer; +#define glMapBuffer glad_glMapBuffer +GLAD_API_CALL PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; +#define glMapBufferRange glad_glMapBufferRange +GLAD_API_CALL PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer; +#define glMapNamedBuffer glad_glMapNamedBuffer +GLAD_API_CALL PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange; +#define glMapNamedBufferRange glad_glMapNamedBufferRange +GLAD_API_CALL PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier; +#define glMemoryBarrier glad_glMemoryBarrier +GLAD_API_CALL PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion; +#define glMemoryBarrierByRegion glad_glMemoryBarrierByRegion +GLAD_API_CALL PFNGLMINSAMPLESHADINGPROC glad_glMinSampleShading; +#define glMinSampleShading glad_glMinSampleShading +GLAD_API_CALL PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; +#define glMultiDrawArrays glad_glMultiDrawArrays +GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect; +#define glMultiDrawArraysIndirect glad_glMultiDrawArraysIndirect +GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glad_glMultiDrawArraysIndirectCount; +#define glMultiDrawArraysIndirectCount glad_glMultiDrawArraysIndirectCount +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; +#define glMultiDrawElements glad_glMultiDrawElements +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; +#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect; +#define glMultiDrawElementsIndirect glad_glMultiDrawElementsIndirect +GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glad_glMultiDrawElementsIndirectCount; +#define glMultiDrawElementsIndirectCount glad_glMultiDrawElementsIndirectCount +GLAD_API_CALL PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData; +#define glNamedBufferData glad_glNamedBufferData +GLAD_API_CALL PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage; +#define glNamedBufferStorage glad_glNamedBufferStorage +GLAD_API_CALL PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData; +#define glNamedBufferSubData glad_glNamedBufferSubData +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer; +#define glNamedFramebufferDrawBuffer glad_glNamedFramebufferDrawBuffer +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers; +#define glNamedFramebufferDrawBuffers glad_glNamedFramebufferDrawBuffers +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri; +#define glNamedFramebufferParameteri glad_glNamedFramebufferParameteri +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer; +#define glNamedFramebufferReadBuffer glad_glNamedFramebufferReadBuffer +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer; +#define glNamedFramebufferRenderbuffer glad_glNamedFramebufferRenderbuffer +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture; +#define glNamedFramebufferTexture glad_glNamedFramebufferTexture +GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer; +#define glNamedFramebufferTextureLayer glad_glNamedFramebufferTextureLayer +GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage; +#define glNamedRenderbufferStorage glad_glNamedRenderbufferStorage +GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample; +#define glNamedRenderbufferStorageMultisample glad_glNamedRenderbufferStorageMultisample +GLAD_API_CALL PFNGLOBJECTLABELPROC glad_glObjectLabel; +#define glObjectLabel glad_glObjectLabel +GLAD_API_CALL PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel; +#define glObjectPtrLabel glad_glObjectPtrLabel +GLAD_API_CALL PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv; +#define glPatchParameterfv glad_glPatchParameterfv +GLAD_API_CALL PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri; +#define glPatchParameteri glad_glPatchParameteri +GLAD_API_CALL PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback; +#define glPauseTransformFeedback glad_glPauseTransformFeedback +GLAD_API_CALL PFNGLPIXELSTOREFPROC glad_glPixelStoref; +#define glPixelStoref glad_glPixelStoref +GLAD_API_CALL PFNGLPIXELSTOREIPROC glad_glPixelStorei; +#define glPixelStorei glad_glPixelStorei +GLAD_API_CALL PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; +#define glPointParameterf glad_glPointParameterf +GLAD_API_CALL PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; +#define glPointParameterfv glad_glPointParameterfv +GLAD_API_CALL PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; +#define glPointParameteri glad_glPointParameteri +GLAD_API_CALL PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; +#define glPointParameteriv glad_glPointParameteriv +GLAD_API_CALL PFNGLPOINTSIZEPROC glad_glPointSize; +#define glPointSize glad_glPointSize +GLAD_API_CALL PFNGLPOLYGONMODEPROC glad_glPolygonMode; +#define glPolygonMode glad_glPolygonMode +GLAD_API_CALL PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; +#define glPolygonOffset glad_glPolygonOffset +GLAD_API_CALL PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp; +#define glPolygonOffsetClamp glad_glPolygonOffsetClamp +GLAD_API_CALL PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup; +#define glPopDebugGroup glad_glPopDebugGroup +GLAD_API_CALL PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; +#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex +GLAD_API_CALL PFNGLPROGRAMBINARYPROC glad_glProgramBinary; +#define glProgramBinary glad_glProgramBinary +GLAD_API_CALL PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri; +#define glProgramParameteri glad_glProgramParameteri +GLAD_API_CALL PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d; +#define glProgramUniform1d glad_glProgramUniform1d +GLAD_API_CALL PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv; +#define glProgramUniform1dv glad_glProgramUniform1dv +GLAD_API_CALL PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f; +#define glProgramUniform1f glad_glProgramUniform1f +GLAD_API_CALL PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv; +#define glProgramUniform1fv glad_glProgramUniform1fv +GLAD_API_CALL PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i; +#define glProgramUniform1i glad_glProgramUniform1i +GLAD_API_CALL PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv; +#define glProgramUniform1iv glad_glProgramUniform1iv +GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui; +#define glProgramUniform1ui glad_glProgramUniform1ui +GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv; +#define glProgramUniform1uiv glad_glProgramUniform1uiv +GLAD_API_CALL PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d; +#define glProgramUniform2d glad_glProgramUniform2d +GLAD_API_CALL PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv; +#define glProgramUniform2dv glad_glProgramUniform2dv +GLAD_API_CALL PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f; +#define glProgramUniform2f glad_glProgramUniform2f +GLAD_API_CALL PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv; +#define glProgramUniform2fv glad_glProgramUniform2fv +GLAD_API_CALL PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i; +#define glProgramUniform2i glad_glProgramUniform2i +GLAD_API_CALL PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv; +#define glProgramUniform2iv glad_glProgramUniform2iv +GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui; +#define glProgramUniform2ui glad_glProgramUniform2ui +GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv; +#define glProgramUniform2uiv glad_glProgramUniform2uiv +GLAD_API_CALL PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d; +#define glProgramUniform3d glad_glProgramUniform3d +GLAD_API_CALL PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv; +#define glProgramUniform3dv glad_glProgramUniform3dv +GLAD_API_CALL PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f; +#define glProgramUniform3f glad_glProgramUniform3f +GLAD_API_CALL PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv; +#define glProgramUniform3fv glad_glProgramUniform3fv +GLAD_API_CALL PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i; +#define glProgramUniform3i glad_glProgramUniform3i +GLAD_API_CALL PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv; +#define glProgramUniform3iv glad_glProgramUniform3iv +GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui; +#define glProgramUniform3ui glad_glProgramUniform3ui +GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv; +#define glProgramUniform3uiv glad_glProgramUniform3uiv +GLAD_API_CALL PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d; +#define glProgramUniform4d glad_glProgramUniform4d +GLAD_API_CALL PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv; +#define glProgramUniform4dv glad_glProgramUniform4dv +GLAD_API_CALL PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f; +#define glProgramUniform4f glad_glProgramUniform4f +GLAD_API_CALL PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv; +#define glProgramUniform4fv glad_glProgramUniform4fv +GLAD_API_CALL PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i; +#define glProgramUniform4i glad_glProgramUniform4i +GLAD_API_CALL PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv; +#define glProgramUniform4iv glad_glProgramUniform4iv +GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui; +#define glProgramUniform4ui glad_glProgramUniform4ui +GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv; +#define glProgramUniform4uiv glad_glProgramUniform4uiv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv; +#define glProgramUniformMatrix2dv glad_glProgramUniformMatrix2dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv; +#define glProgramUniformMatrix2fv glad_glProgramUniformMatrix2fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv; +#define glProgramUniformMatrix2x3dv glad_glProgramUniformMatrix2x3dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv; +#define glProgramUniformMatrix2x3fv glad_glProgramUniformMatrix2x3fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv; +#define glProgramUniformMatrix2x4dv glad_glProgramUniformMatrix2x4dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv; +#define glProgramUniformMatrix2x4fv glad_glProgramUniformMatrix2x4fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv; +#define glProgramUniformMatrix3dv glad_glProgramUniformMatrix3dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv; +#define glProgramUniformMatrix3fv glad_glProgramUniformMatrix3fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv; +#define glProgramUniformMatrix3x2dv glad_glProgramUniformMatrix3x2dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv; +#define glProgramUniformMatrix3x2fv glad_glProgramUniformMatrix3x2fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv; +#define glProgramUniformMatrix3x4dv glad_glProgramUniformMatrix3x4dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv; +#define glProgramUniformMatrix3x4fv glad_glProgramUniformMatrix3x4fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv; +#define glProgramUniformMatrix4dv glad_glProgramUniformMatrix4dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv; +#define glProgramUniformMatrix4fv glad_glProgramUniformMatrix4fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv; +#define glProgramUniformMatrix4x2dv glad_glProgramUniformMatrix4x2dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv; +#define glProgramUniformMatrix4x2fv glad_glProgramUniformMatrix4x2fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv; +#define glProgramUniformMatrix4x3dv glad_glProgramUniformMatrix4x3dv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv; +#define glProgramUniformMatrix4x3fv glad_glProgramUniformMatrix4x3fv +GLAD_API_CALL PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; +#define glProvokingVertex glad_glProvokingVertex +GLAD_API_CALL PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup; +#define glPushDebugGroup glad_glPushDebugGroup +GLAD_API_CALL PFNGLQUERYCOUNTERPROC glad_glQueryCounter; +#define glQueryCounter glad_glQueryCounter +GLAD_API_CALL PFNGLREADBUFFERPROC glad_glReadBuffer; +#define glReadBuffer glad_glReadBuffer +GLAD_API_CALL PFNGLREADPIXELSPROC glad_glReadPixels; +#define glReadPixels glad_glReadPixels +GLAD_API_CALL PFNGLREADNPIXELSPROC glad_glReadnPixels; +#define glReadnPixels glad_glReadnPixels +GLAD_API_CALL PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; +#define glReleaseShaderCompiler glad_glReleaseShaderCompiler +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; +#define glRenderbufferStorage glad_glRenderbufferStorage +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; +#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample +GLAD_API_CALL PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback; +#define glResumeTransformFeedback glad_glResumeTransformFeedback +GLAD_API_CALL PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; +#define glSampleCoverage glad_glSampleCoverage +GLAD_API_CALL PFNGLSAMPLEMASKIPROC glad_glSampleMaski; +#define glSampleMaski glad_glSampleMaski +GLAD_API_CALL PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv; +#define glSamplerParameterIiv glad_glSamplerParameterIiv +GLAD_API_CALL PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv; +#define glSamplerParameterIuiv glad_glSamplerParameterIuiv +GLAD_API_CALL PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; +#define glSamplerParameterf glad_glSamplerParameterf +GLAD_API_CALL PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; +#define glSamplerParameterfv glad_glSamplerParameterfv +GLAD_API_CALL PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; +#define glSamplerParameteri glad_glSamplerParameteri +GLAD_API_CALL PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; +#define glSamplerParameteriv glad_glSamplerParameteriv +GLAD_API_CALL PFNGLSCISSORPROC glad_glScissor; +#define glScissor glad_glScissor +GLAD_API_CALL PFNGLSCISSORARRAYVPROC glad_glScissorArrayv; +#define glScissorArrayv glad_glScissorArrayv +GLAD_API_CALL PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed; +#define glScissorIndexed glad_glScissorIndexed +GLAD_API_CALL PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv; +#define glScissorIndexedv glad_glScissorIndexedv +GLAD_API_CALL PFNGLSHADERBINARYPROC glad_glShaderBinary; +#define glShaderBinary glad_glShaderBinary +GLAD_API_CALL PFNGLSHADERSOURCEPROC glad_glShaderSource; +#define glShaderSource glad_glShaderSource +GLAD_API_CALL PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding; +#define glShaderStorageBlockBinding glad_glShaderStorageBlockBinding +GLAD_API_CALL PFNGLSPECIALIZESHADERPROC glad_glSpecializeShader; +#define glSpecializeShader glad_glSpecializeShader +GLAD_API_CALL PFNGLSTENCILFUNCPROC glad_glStencilFunc; +#define glStencilFunc glad_glStencilFunc +GLAD_API_CALL PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; +#define glStencilFuncSeparate glad_glStencilFuncSeparate +GLAD_API_CALL PFNGLSTENCILMASKPROC glad_glStencilMask; +#define glStencilMask glad_glStencilMask +GLAD_API_CALL PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; +#define glStencilMaskSeparate glad_glStencilMaskSeparate +GLAD_API_CALL PFNGLSTENCILOPPROC glad_glStencilOp; +#define glStencilOp glad_glStencilOp +GLAD_API_CALL PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; +#define glStencilOpSeparate glad_glStencilOpSeparate +GLAD_API_CALL PFNGLTEXBUFFERPROC glad_glTexBuffer; +#define glTexBuffer glad_glTexBuffer +GLAD_API_CALL PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange; +#define glTexBufferRange glad_glTexBufferRange +GLAD_API_CALL PFNGLTEXIMAGE1DPROC glad_glTexImage1D; +#define glTexImage1D glad_glTexImage1D +GLAD_API_CALL PFNGLTEXIMAGE2DPROC glad_glTexImage2D; +#define glTexImage2D glad_glTexImage2D +GLAD_API_CALL PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; +#define glTexImage2DMultisample glad_glTexImage2DMultisample +GLAD_API_CALL PFNGLTEXIMAGE3DPROC glad_glTexImage3D; +#define glTexImage3D glad_glTexImage3D +GLAD_API_CALL PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; +#define glTexImage3DMultisample glad_glTexImage3DMultisample +GLAD_API_CALL PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; +#define glTexParameterIiv glad_glTexParameterIiv +GLAD_API_CALL PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; +#define glTexParameterIuiv glad_glTexParameterIuiv +GLAD_API_CALL PFNGLTEXPARAMETERFPROC glad_glTexParameterf; +#define glTexParameterf glad_glTexParameterf +GLAD_API_CALL PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; +#define glTexParameterfv glad_glTexParameterfv +GLAD_API_CALL PFNGLTEXPARAMETERIPROC glad_glTexParameteri; +#define glTexParameteri glad_glTexParameteri +GLAD_API_CALL PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; +#define glTexParameteriv glad_glTexParameteriv +GLAD_API_CALL PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D; +#define glTexStorage1D glad_glTexStorage1D +GLAD_API_CALL PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D; +#define glTexStorage2D glad_glTexStorage2D +GLAD_API_CALL PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample; +#define glTexStorage2DMultisample glad_glTexStorage2DMultisample +GLAD_API_CALL PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D; +#define glTexStorage3D glad_glTexStorage3D +GLAD_API_CALL PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample; +#define glTexStorage3DMultisample glad_glTexStorage3DMultisample +GLAD_API_CALL PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; +#define glTexSubImage1D glad_glTexSubImage1D +GLAD_API_CALL PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; +#define glTexSubImage2D glad_glTexSubImage2D +GLAD_API_CALL PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; +#define glTexSubImage3D glad_glTexSubImage3D +GLAD_API_CALL PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier; +#define glTextureBarrier glad_glTextureBarrier +GLAD_API_CALL PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer; +#define glTextureBuffer glad_glTextureBuffer +GLAD_API_CALL PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange; +#define glTextureBufferRange glad_glTextureBufferRange +GLAD_API_CALL PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv; +#define glTextureParameterIiv glad_glTextureParameterIiv +GLAD_API_CALL PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv; +#define glTextureParameterIuiv glad_glTextureParameterIuiv +GLAD_API_CALL PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf; +#define glTextureParameterf glad_glTextureParameterf +GLAD_API_CALL PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv; +#define glTextureParameterfv glad_glTextureParameterfv +GLAD_API_CALL PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri; +#define glTextureParameteri glad_glTextureParameteri +GLAD_API_CALL PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv; +#define glTextureParameteriv glad_glTextureParameteriv +GLAD_API_CALL PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D; +#define glTextureStorage1D glad_glTextureStorage1D +GLAD_API_CALL PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D; +#define glTextureStorage2D glad_glTextureStorage2D +GLAD_API_CALL PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample; +#define glTextureStorage2DMultisample glad_glTextureStorage2DMultisample +GLAD_API_CALL PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D; +#define glTextureStorage3D glad_glTextureStorage3D +GLAD_API_CALL PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample; +#define glTextureStorage3DMultisample glad_glTextureStorage3DMultisample +GLAD_API_CALL PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D; +#define glTextureSubImage1D glad_glTextureSubImage1D +GLAD_API_CALL PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D; +#define glTextureSubImage2D glad_glTextureSubImage2D +GLAD_API_CALL PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D; +#define glTextureSubImage3D glad_glTextureSubImage3D +GLAD_API_CALL PFNGLTEXTUREVIEWPROC glad_glTextureView; +#define glTextureView glad_glTextureView +GLAD_API_CALL PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase; +#define glTransformFeedbackBufferBase glad_glTransformFeedbackBufferBase +GLAD_API_CALL PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange; +#define glTransformFeedbackBufferRange glad_glTransformFeedbackBufferRange +GLAD_API_CALL PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; +#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings +GLAD_API_CALL PFNGLUNIFORM1DPROC glad_glUniform1d; +#define glUniform1d glad_glUniform1d +GLAD_API_CALL PFNGLUNIFORM1DVPROC glad_glUniform1dv; +#define glUniform1dv glad_glUniform1dv +GLAD_API_CALL PFNGLUNIFORM1FPROC glad_glUniform1f; +#define glUniform1f glad_glUniform1f +GLAD_API_CALL PFNGLUNIFORM1FVPROC glad_glUniform1fv; +#define glUniform1fv glad_glUniform1fv +GLAD_API_CALL PFNGLUNIFORM1IPROC glad_glUniform1i; +#define glUniform1i glad_glUniform1i +GLAD_API_CALL PFNGLUNIFORM1IVPROC glad_glUniform1iv; +#define glUniform1iv glad_glUniform1iv +GLAD_API_CALL PFNGLUNIFORM1UIPROC glad_glUniform1ui; +#define glUniform1ui glad_glUniform1ui +GLAD_API_CALL PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; +#define glUniform1uiv glad_glUniform1uiv +GLAD_API_CALL PFNGLUNIFORM2DPROC glad_glUniform2d; +#define glUniform2d glad_glUniform2d +GLAD_API_CALL PFNGLUNIFORM2DVPROC glad_glUniform2dv; +#define glUniform2dv glad_glUniform2dv +GLAD_API_CALL PFNGLUNIFORM2FPROC glad_glUniform2f; +#define glUniform2f glad_glUniform2f +GLAD_API_CALL PFNGLUNIFORM2FVPROC glad_glUniform2fv; +#define glUniform2fv glad_glUniform2fv +GLAD_API_CALL PFNGLUNIFORM2IPROC glad_glUniform2i; +#define glUniform2i glad_glUniform2i +GLAD_API_CALL PFNGLUNIFORM2IVPROC glad_glUniform2iv; +#define glUniform2iv glad_glUniform2iv +GLAD_API_CALL PFNGLUNIFORM2UIPROC glad_glUniform2ui; +#define glUniform2ui glad_glUniform2ui +GLAD_API_CALL PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; +#define glUniform2uiv glad_glUniform2uiv +GLAD_API_CALL PFNGLUNIFORM3DPROC glad_glUniform3d; +#define glUniform3d glad_glUniform3d +GLAD_API_CALL PFNGLUNIFORM3DVPROC glad_glUniform3dv; +#define glUniform3dv glad_glUniform3dv +GLAD_API_CALL PFNGLUNIFORM3FPROC glad_glUniform3f; +#define glUniform3f glad_glUniform3f +GLAD_API_CALL PFNGLUNIFORM3FVPROC glad_glUniform3fv; +#define glUniform3fv glad_glUniform3fv +GLAD_API_CALL PFNGLUNIFORM3IPROC glad_glUniform3i; +#define glUniform3i glad_glUniform3i +GLAD_API_CALL PFNGLUNIFORM3IVPROC glad_glUniform3iv; +#define glUniform3iv glad_glUniform3iv +GLAD_API_CALL PFNGLUNIFORM3UIPROC glad_glUniform3ui; +#define glUniform3ui glad_glUniform3ui +GLAD_API_CALL PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; +#define glUniform3uiv glad_glUniform3uiv +GLAD_API_CALL PFNGLUNIFORM4DPROC glad_glUniform4d; +#define glUniform4d glad_glUniform4d +GLAD_API_CALL PFNGLUNIFORM4DVPROC glad_glUniform4dv; +#define glUniform4dv glad_glUniform4dv +GLAD_API_CALL PFNGLUNIFORM4FPROC glad_glUniform4f; +#define glUniform4f glad_glUniform4f +GLAD_API_CALL PFNGLUNIFORM4FVPROC glad_glUniform4fv; +#define glUniform4fv glad_glUniform4fv +GLAD_API_CALL PFNGLUNIFORM4IPROC glad_glUniform4i; +#define glUniform4i glad_glUniform4i +GLAD_API_CALL PFNGLUNIFORM4IVPROC glad_glUniform4iv; +#define glUniform4iv glad_glUniform4iv +GLAD_API_CALL PFNGLUNIFORM4UIPROC glad_glUniform4ui; +#define glUniform4ui glad_glUniform4ui +GLAD_API_CALL PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; +#define glUniform4uiv glad_glUniform4uiv +GLAD_API_CALL PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; +#define glUniformBlockBinding glad_glUniformBlockBinding +GLAD_API_CALL PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv; +#define glUniformMatrix2dv glad_glUniformMatrix2dv +GLAD_API_CALL PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; +#define glUniformMatrix2fv glad_glUniformMatrix2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv; +#define glUniformMatrix2x3dv glad_glUniformMatrix2x3dv +GLAD_API_CALL PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; +#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv +GLAD_API_CALL PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv; +#define glUniformMatrix2x4dv glad_glUniformMatrix2x4dv +GLAD_API_CALL PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; +#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv; +#define glUniformMatrix3dv glad_glUniformMatrix3dv +GLAD_API_CALL PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; +#define glUniformMatrix3fv glad_glUniformMatrix3fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv; +#define glUniformMatrix3x2dv glad_glUniformMatrix3x2dv +GLAD_API_CALL PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; +#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv; +#define glUniformMatrix3x4dv glad_glUniformMatrix3x4dv +GLAD_API_CALL PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; +#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv; +#define glUniformMatrix4dv glad_glUniformMatrix4dv +GLAD_API_CALL PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; +#define glUniformMatrix4fv glad_glUniformMatrix4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv; +#define glUniformMatrix4x2dv glad_glUniformMatrix4x2dv +GLAD_API_CALL PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; +#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv; +#define glUniformMatrix4x3dv glad_glUniformMatrix4x3dv +GLAD_API_CALL PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; +#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv +GLAD_API_CALL PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv; +#define glUniformSubroutinesuiv glad_glUniformSubroutinesuiv +GLAD_API_CALL PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; +#define glUnmapBuffer glad_glUnmapBuffer +GLAD_API_CALL PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer; +#define glUnmapNamedBuffer glad_glUnmapNamedBuffer +GLAD_API_CALL PFNGLUSEPROGRAMPROC glad_glUseProgram; +#define glUseProgram glad_glUseProgram +GLAD_API_CALL PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages; +#define glUseProgramStages glad_glUseProgramStages +GLAD_API_CALL PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; +#define glValidateProgram glad_glValidateProgram +GLAD_API_CALL PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline; +#define glValidateProgramPipeline glad_glValidateProgramPipeline +GLAD_API_CALL PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding; +#define glVertexArrayAttribBinding glad_glVertexArrayAttribBinding +GLAD_API_CALL PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat; +#define glVertexArrayAttribFormat glad_glVertexArrayAttribFormat +GLAD_API_CALL PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat; +#define glVertexArrayAttribIFormat glad_glVertexArrayAttribIFormat +GLAD_API_CALL PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat; +#define glVertexArrayAttribLFormat glad_glVertexArrayAttribLFormat +GLAD_API_CALL PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor; +#define glVertexArrayBindingDivisor glad_glVertexArrayBindingDivisor +GLAD_API_CALL PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer; +#define glVertexArrayElementBuffer glad_glVertexArrayElementBuffer +GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer; +#define glVertexArrayVertexBuffer glad_glVertexArrayVertexBuffer +GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers; +#define glVertexArrayVertexBuffers glad_glVertexArrayVertexBuffers +GLAD_API_CALL PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; +#define glVertexAttrib1d glad_glVertexAttrib1d +GLAD_API_CALL PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; +#define glVertexAttrib1dv glad_glVertexAttrib1dv +GLAD_API_CALL PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; +#define glVertexAttrib1f glad_glVertexAttrib1f +GLAD_API_CALL PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; +#define glVertexAttrib1fv glad_glVertexAttrib1fv +GLAD_API_CALL PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; +#define glVertexAttrib1s glad_glVertexAttrib1s +GLAD_API_CALL PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; +#define glVertexAttrib1sv glad_glVertexAttrib1sv +GLAD_API_CALL PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; +#define glVertexAttrib2d glad_glVertexAttrib2d +GLAD_API_CALL PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; +#define glVertexAttrib2dv glad_glVertexAttrib2dv +GLAD_API_CALL PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; +#define glVertexAttrib2f glad_glVertexAttrib2f +GLAD_API_CALL PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; +#define glVertexAttrib2fv glad_glVertexAttrib2fv +GLAD_API_CALL PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; +#define glVertexAttrib2s glad_glVertexAttrib2s +GLAD_API_CALL PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; +#define glVertexAttrib2sv glad_glVertexAttrib2sv +GLAD_API_CALL PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; +#define glVertexAttrib3d glad_glVertexAttrib3d +GLAD_API_CALL PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; +#define glVertexAttrib3dv glad_glVertexAttrib3dv +GLAD_API_CALL PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; +#define glVertexAttrib3f glad_glVertexAttrib3f +GLAD_API_CALL PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; +#define glVertexAttrib3fv glad_glVertexAttrib3fv +GLAD_API_CALL PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; +#define glVertexAttrib3s glad_glVertexAttrib3s +GLAD_API_CALL PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; +#define glVertexAttrib3sv glad_glVertexAttrib3sv +GLAD_API_CALL PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; +#define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv +GLAD_API_CALL PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; +#define glVertexAttrib4Niv glad_glVertexAttrib4Niv +GLAD_API_CALL PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; +#define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv +GLAD_API_CALL PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; +#define glVertexAttrib4Nub glad_glVertexAttrib4Nub +GLAD_API_CALL PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; +#define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv +GLAD_API_CALL PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; +#define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv +GLAD_API_CALL PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; +#define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv +GLAD_API_CALL PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; +#define glVertexAttrib4bv glad_glVertexAttrib4bv +GLAD_API_CALL PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; +#define glVertexAttrib4d glad_glVertexAttrib4d +GLAD_API_CALL PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; +#define glVertexAttrib4dv glad_glVertexAttrib4dv +GLAD_API_CALL PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; +#define glVertexAttrib4f glad_glVertexAttrib4f +GLAD_API_CALL PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; +#define glVertexAttrib4fv glad_glVertexAttrib4fv +GLAD_API_CALL PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; +#define glVertexAttrib4iv glad_glVertexAttrib4iv +GLAD_API_CALL PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; +#define glVertexAttrib4s glad_glVertexAttrib4s +GLAD_API_CALL PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; +#define glVertexAttrib4sv glad_glVertexAttrib4sv +GLAD_API_CALL PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; +#define glVertexAttrib4ubv glad_glVertexAttrib4ubv +GLAD_API_CALL PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; +#define glVertexAttrib4uiv glad_glVertexAttrib4uiv +GLAD_API_CALL PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; +#define glVertexAttrib4usv glad_glVertexAttrib4usv +GLAD_API_CALL PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding; +#define glVertexAttribBinding glad_glVertexAttribBinding +GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; +#define glVertexAttribDivisor glad_glVertexAttribDivisor +GLAD_API_CALL PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat; +#define glVertexAttribFormat glad_glVertexAttribFormat +GLAD_API_CALL PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; +#define glVertexAttribI1i glad_glVertexAttribI1i +GLAD_API_CALL PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; +#define glVertexAttribI1iv glad_glVertexAttribI1iv +GLAD_API_CALL PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; +#define glVertexAttribI1ui glad_glVertexAttribI1ui +GLAD_API_CALL PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; +#define glVertexAttribI1uiv glad_glVertexAttribI1uiv +GLAD_API_CALL PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; +#define glVertexAttribI2i glad_glVertexAttribI2i +GLAD_API_CALL PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; +#define glVertexAttribI2iv glad_glVertexAttribI2iv +GLAD_API_CALL PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; +#define glVertexAttribI2ui glad_glVertexAttribI2ui +GLAD_API_CALL PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; +#define glVertexAttribI2uiv glad_glVertexAttribI2uiv +GLAD_API_CALL PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; +#define glVertexAttribI3i glad_glVertexAttribI3i +GLAD_API_CALL PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; +#define glVertexAttribI3iv glad_glVertexAttribI3iv +GLAD_API_CALL PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; +#define glVertexAttribI3ui glad_glVertexAttribI3ui +GLAD_API_CALL PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; +#define glVertexAttribI3uiv glad_glVertexAttribI3uiv +GLAD_API_CALL PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; +#define glVertexAttribI4bv glad_glVertexAttribI4bv +GLAD_API_CALL PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; +#define glVertexAttribI4i glad_glVertexAttribI4i +GLAD_API_CALL PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; +#define glVertexAttribI4iv glad_glVertexAttribI4iv +GLAD_API_CALL PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; +#define glVertexAttribI4sv glad_glVertexAttribI4sv +GLAD_API_CALL PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; +#define glVertexAttribI4ubv glad_glVertexAttribI4ubv +GLAD_API_CALL PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; +#define glVertexAttribI4ui glad_glVertexAttribI4ui +GLAD_API_CALL PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; +#define glVertexAttribI4uiv glad_glVertexAttribI4uiv +GLAD_API_CALL PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; +#define glVertexAttribI4usv glad_glVertexAttribI4usv +GLAD_API_CALL PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat; +#define glVertexAttribIFormat glad_glVertexAttribIFormat +GLAD_API_CALL PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; +#define glVertexAttribIPointer glad_glVertexAttribIPointer +GLAD_API_CALL PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d; +#define glVertexAttribL1d glad_glVertexAttribL1d +GLAD_API_CALL PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv; +#define glVertexAttribL1dv glad_glVertexAttribL1dv +GLAD_API_CALL PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d; +#define glVertexAttribL2d glad_glVertexAttribL2d +GLAD_API_CALL PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv; +#define glVertexAttribL2dv glad_glVertexAttribL2dv +GLAD_API_CALL PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d; +#define glVertexAttribL3d glad_glVertexAttribL3d +GLAD_API_CALL PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv; +#define glVertexAttribL3dv glad_glVertexAttribL3dv +GLAD_API_CALL PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d; +#define glVertexAttribL4d glad_glVertexAttribL4d +GLAD_API_CALL PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv; +#define glVertexAttribL4dv glad_glVertexAttribL4dv +GLAD_API_CALL PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat; +#define glVertexAttribLFormat glad_glVertexAttribLFormat +GLAD_API_CALL PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer; +#define glVertexAttribLPointer glad_glVertexAttribLPointer +GLAD_API_CALL PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui; +#define glVertexAttribP1ui glad_glVertexAttribP1ui +GLAD_API_CALL PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv; +#define glVertexAttribP1uiv glad_glVertexAttribP1uiv +GLAD_API_CALL PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui; +#define glVertexAttribP2ui glad_glVertexAttribP2ui +GLAD_API_CALL PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv; +#define glVertexAttribP2uiv glad_glVertexAttribP2uiv +GLAD_API_CALL PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui; +#define glVertexAttribP3ui glad_glVertexAttribP3ui +GLAD_API_CALL PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv; +#define glVertexAttribP3uiv glad_glVertexAttribP3uiv +GLAD_API_CALL PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui; +#define glVertexAttribP4ui glad_glVertexAttribP4ui +GLAD_API_CALL PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv; +#define glVertexAttribP4uiv glad_glVertexAttribP4uiv +GLAD_API_CALL PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; +#define glVertexAttribPointer glad_glVertexAttribPointer +GLAD_API_CALL PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor; +#define glVertexBindingDivisor glad_glVertexBindingDivisor +GLAD_API_CALL PFNGLVIEWPORTPROC glad_glViewport; +#define glViewport glad_glViewport +GLAD_API_CALL PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv; +#define glViewportArrayv glad_glViewportArrayv +GLAD_API_CALL PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf; +#define glViewportIndexedf glad_glViewportIndexedf +GLAD_API_CALL PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv; +#define glViewportIndexedfv glad_glViewportIndexedfv +GLAD_API_CALL PFNGLWAITSYNCPROC glad_glWaitSync; +#define glWaitSync glad_glWaitSync + + + + + +GLAD_API_CALL int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr); +GLAD_API_CALL int gladLoadGL( GLADloadfunc load); + + +#ifdef GLAD_GL + +GLAD_API_CALL int gladLoaderLoadGL(void); +GLAD_API_CALL void gladLoaderUnloadGL(void); + +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/libvgcode/glad/include/glad/gles2.h b/src/libvgcode/glad/include/glad/gles2.h new file mode 100644 index 0000000000..2983e1df52 --- /dev/null +++ b/src/libvgcode/glad/include/glad/gles2.h @@ -0,0 +1,1637 @@ +/** + * Loader generated by glad 2.0.4 on Thu Feb 1 07:09:02 2024 + * + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + * + * Generator: C/C++ + * Specification: gl + * Extensions: 0 + * + * APIs: + * - gles2=3.0 + * + * Options: + * - ALIAS = False + * - DEBUG = False + * - HEADER_ONLY = False + * - LOADER = True + * - MX = False + * - ON_DEMAND = False + * + * Commandline: + * --api='gles2=3.0' --extensions='' c --loader + * + * Online: + * http://glad.sh/#api=gles2%3D3.0&extensions=&generator=c&options=LOADER + * + */ + +#ifndef GLAD_GLES2_H_ +#define GLAD_GLES2_H_ + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-id-macro" +#endif +#ifdef __gl2_h_ + #error OpenGL ES 2 header already included (API: gles2), remove previous include! +#endif +#define __gl2_h_ 1 +#ifdef __gles2_gl2_h_ + #error OpenGL ES 2 header already included (API: gles2), remove previous include! +#endif +#define __gles2_gl2_h_ 1 +#ifdef __gl3_h_ + #error OpenGL ES 3 header already included (API: gles2), remove previous include! +#endif +#define __gl3_h_ 1 +#ifdef __gles2_gl3_h_ + #error OpenGL ES 3 header already included (API: gles2), remove previous include! +#endif +#define __gles2_gl3_h_ 1 +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#define GLAD_GLES2 +#define GLAD_OPTION_GLES2_LOADER + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GLAD_PLATFORM_H_ +#define GLAD_PLATFORM_H_ + +#ifndef GLAD_PLATFORM_WIN32 + #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__) + #define GLAD_PLATFORM_WIN32 1 + #else + #define GLAD_PLATFORM_WIN32 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_APPLE + #ifdef __APPLE__ + #define GLAD_PLATFORM_APPLE 1 + #else + #define GLAD_PLATFORM_APPLE 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_EMSCRIPTEN + #ifdef __EMSCRIPTEN__ + #define GLAD_PLATFORM_EMSCRIPTEN 1 + #else + #define GLAD_PLATFORM_EMSCRIPTEN 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_UWP + #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) + #ifdef __has_include + #if __has_include() + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #endif + + #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY + #include + #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) + #define GLAD_PLATFORM_UWP 1 + #endif + #endif + + #ifndef GLAD_PLATFORM_UWP + #define GLAD_PLATFORM_UWP 0 + #endif +#endif + +#ifdef __GNUC__ + #define GLAD_GNUC_EXTENSION __extension__ +#else + #define GLAD_GNUC_EXTENSION +#endif + +#define GLAD_UNUSED(x) (void)(x) + +#ifndef GLAD_API_CALL + #if defined(GLAD_API_CALL_EXPORT) + #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) + #if defined(GLAD_API_CALL_EXPORT_BUILD) + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllexport)) extern + #else + #define GLAD_API_CALL __declspec(dllexport) extern + #endif + #else + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllimport)) extern + #else + #define GLAD_API_CALL __declspec(dllimport) extern + #endif + #endif + #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) + #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern + #else + #define GLAD_API_CALL extern + #endif + #else + #define GLAD_API_CALL extern + #endif +#endif + +#ifdef APIENTRY + #define GLAD_API_PTR APIENTRY +#elif GLAD_PLATFORM_WIN32 + #define GLAD_API_PTR __stdcall +#else + #define GLAD_API_PTR +#endif + +#ifndef GLAPI +#define GLAPI GLAD_API_CALL +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY GLAD_API_PTR +#endif + +#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) +#define GLAD_VERSION_MAJOR(version) (version / 10000) +#define GLAD_VERSION_MINOR(version) (version % 10000) + +#define GLAD_GENERATOR_VERSION "2.0.4" + +typedef void (*GLADapiproc)(void); + +typedef GLADapiproc (*GLADloadfunc)(const char *name); +typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name); + +typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); +typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); + +#endif /* GLAD_PLATFORM_H_ */ + +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALPHA 0x1906 +#define GL_ALPHA_BITS 0x0D55 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_ALWAYS 0x0207 +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_BACK 0x0405 +#define GL_BLEND 0x0BE2 +#define GL_BLEND_COLOR 0x8005 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLUE 0x1905 +#define GL_BLUE_BITS 0x0D54 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_BYTE 0x1400 +#define GL_CCW 0x0901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_COLOR 0x1800 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_COLOR_ATTACHMENT16 0x8CF0 +#define GL_COLOR_ATTACHMENT17 0x8CF1 +#define GL_COLOR_ATTACHMENT18 0x8CF2 +#define GL_COLOR_ATTACHMENT19 0x8CF3 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT20 0x8CF4 +#define GL_COLOR_ATTACHMENT21 0x8CF5 +#define GL_COLOR_ATTACHMENT22 0x8CF6 +#define GL_COLOR_ATTACHMENT23 0x8CF7 +#define GL_COLOR_ATTACHMENT24 0x8CF8 +#define GL_COLOR_ATTACHMENT25 0x8CF9 +#define GL_COLOR_ATTACHMENT26 0x8CFA +#define GL_COLOR_ATTACHMENT27 0x8CFB +#define GL_COLOR_ATTACHMENT28 0x8CFC +#define GL_COLOR_ATTACHMENT29 0x8CFD +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT30 0x8CFE +#define GL_COLOR_ATTACHMENT31 0x8CFF +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#define GL_COMPILE_STATUS 0x8B81 +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CONDITION_SATISFIED 0x911C +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_CURRENT_QUERY 0x8865 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_CW 0x0900 +#define GL_DECR 0x1E03 +#define GL_DECR_WRAP 0x8508 +#define GL_DELETE_STATUS 0x8B80 +#define GL_DEPTH 0x1801 +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_DEPTH_BITS 0x0D56 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH_FUNC 0x0B74 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DITHER 0x0BD0 +#define GL_DONT_CARE 0x1100 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DST_ALPHA 0x0304 +#define GL_DST_COLOR 0x0306 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_EQUAL 0x0202 +#define GL_EXTENSIONS 0x1F03 +#define GL_FALSE 0 +#define GL_FASTEST 0x1101 +#define GL_FIXED 0x140C +#define GL_FLOAT 0x1406 +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4 0x8B5C +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_FRAMEBUFFER 0x8D40 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_FRONT 0x0404 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_FRONT_FACE 0x0B46 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_FUNC_SUBTRACT 0x800A +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_GEQUAL 0x0206 +#define GL_GREATER 0x0204 +#define GL_GREEN 0x1904 +#define GL_GREEN_BITS 0x0D53 +#define GL_HALF_FLOAT 0x140B +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_HIGH_INT 0x8DF5 +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_INCR 0x1E02 +#define GL_INCR_WRAP 0x8507 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_INT 0x1404 +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_INVALID_INDEX 0xFFFFFFFF +#define GL_INVALID_OPERATION 0x0502 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVERT 0x150A +#define GL_KEEP 0x1E00 +#define GL_LEQUAL 0x0203 +#define GL_LESS 0x0201 +#define GL_LINEAR 0x2601 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINK_STATUS 0x8B82 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_LOW_INT 0x8DF3 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_MAJOR_VERSION 0x821B +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAX 0x8008 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_MIN 0x8007 +#define GL_MINOR_VERSION 0x821C +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_NEAREST 0x2600 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_NEVER 0x0200 +#define GL_NICEST 0x1102 +#define GL_NONE 0 +#define GL_NOTEQUAL 0x0205 +#define GL_NO_ERROR 0 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_NUM_EXTENSIONS 0x821D +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_OBJECT_TYPE 0x9112 +#define GL_ONE 1 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_POINTS 0x0000 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_R16F 0x822D +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32F 0x822E +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_R8 0x8229 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R8_SNORM 0x8F94 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_READ_BUFFER 0x0C02 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RED 0x1903 +#define GL_RED_BITS 0x0D52 +#define GL_RED_INTEGER 0x8D94 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERER 0x1F01 +#define GL_REPEAT 0x2901 +#define GL_REPLACE 0x1E01 +#define GL_RG 0x8227 +#define GL_RG16F 0x822F +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32F 0x8230 +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_RG8 0x822B +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB 0x1907 +#define GL_RGB10_A2 0x8059 +#define GL_RGB10_A2UI 0x906F +#define GL_RGB16F 0x881B +#define GL_RGB16I 0x8D89 +#define GL_RGB16UI 0x8D77 +#define GL_RGB32F 0x8815 +#define GL_RGB32I 0x8D83 +#define GL_RGB32UI 0x8D71 +#define GL_RGB565 0x8D62 +#define GL_RGB5_A1 0x8057 +#define GL_RGB8 0x8051 +#define GL_RGB8I 0x8D8F +#define GL_RGB8UI 0x8D7D +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGB9_E5 0x8C3D +#define GL_RGBA 0x1908 +#define GL_RGBA16F 0x881A +#define GL_RGBA16I 0x8D88 +#define GL_RGBA16UI 0x8D76 +#define GL_RGBA32F 0x8814 +#define GL_RGBA32I 0x8D82 +#define GL_RGBA32UI 0x8D70 +#define GL_RGBA4 0x8056 +#define GL_RGBA8 0x8058 +#define GL_RGBA8I 0x8D8E +#define GL_RGBA8UI 0x8D7C +#define GL_RGBA8_SNORM 0x8F97 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RG_INTEGER 0x8228 +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_BINDING 0x8919 +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_TYPE 0x8B4F +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_SHORT 0x1402 +#define GL_SIGNALED 0x9119 +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_SRC_ALPHA 0x0302 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_SRC_COLOR 0x0300 +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_STATIC_COPY 0x88E6 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STENCIL 0x1802 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_STENCIL_BITS 0x0D57 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STREAM_COPY 0x88E2 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_SYNC_STATUS 0x9114 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRUE 1 +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNSIGNALED 0x9118 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_VENDOR 0x1F00 +#define GL_VERSION 0x1F02 +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_VIEWPORT 0x0BA2 +#define GL_WAIT_FAILED 0x911D +#define GL_ZERO 0 + + +#include +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef void GLvoid; +typedef khronos_int8_t GLbyte; +typedef khronos_uint8_t GLubyte; +typedef khronos_int16_t GLshort; +typedef khronos_uint16_t GLushort; +typedef int GLint; +typedef unsigned int GLuint; +typedef khronos_int32_t GLclampx; +typedef int GLsizei; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void *GLeglClientBufferEXT; +typedef void *GLeglImageOES; +typedef char GLchar; +typedef char GLcharARB; +#ifdef __APPLE__ +typedef void *GLhandleARB; +#else +typedef unsigned int GLhandleARB; +#endif +typedef khronos_uint16_t GLhalf; +typedef khronos_uint16_t GLhalfARB; +typedef khronos_int32_t GLfixed; +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_intptr_t GLintptr; +#else +typedef khronos_intptr_t GLintptr; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_intptr_t GLintptrARB; +#else +typedef khronos_intptr_t GLintptrARB; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_ssize_t GLsizeiptr; +#else +typedef khronos_ssize_t GLsizeiptr; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_ssize_t GLsizeiptrARB; +#else +typedef khronos_ssize_t GLsizeiptrARB; +#endif +typedef khronos_int64_t GLint64; +typedef khronos_int64_t GLint64EXT; +typedef khronos_uint64_t GLuint64; +typedef khronos_uint64_t GLuint64EXT; +typedef struct __GLsync *GLsync; +struct _cl_context; +struct _cl_event; +typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); +typedef unsigned short GLhalfNV; +typedef GLintptr GLvdpauSurfaceNV; +typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void); + + +#define GL_ES_VERSION_2_0 1 +GLAD_API_CALL int GLAD_GL_ES_VERSION_2_0; +#define GL_ES_VERSION_3_0 1 +GLAD_API_CALL int GLAD_GL_ES_VERSION_3_0; + + +typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture); +typedef void (GLAD_API_PTR *PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); +typedef void (GLAD_API_PTR *PFNGLBEGINQUERYPROC)(GLenum target, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode); +typedef void (GLAD_API_PTR *PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); +typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler); +typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); +typedef void (GLAD_API_PTR *PFNGLBINDTRANSFORMFEEDBACKPROC)(GLenum target, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBINDVERTEXARRAYPROC)(GLuint array); +typedef void (GLAD_API_PTR *PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAD_API_PTR *PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAD_API_PTR *PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void * data, GLenum usage); +typedef void (GLAD_API_PTR *PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void * data); +typedef GLenum (GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLCLEARPROC)(GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHFPROC)(GLfloat d); +typedef void (GLAD_API_PTR *PFNGLCLEARSTENCILPROC)(GLint s); +typedef GLenum (GLAD_API_PTR *PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GLAD_API_PTR *PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (GLAD_API_PTR *PFNGLCOMPILESHADERPROC)(GLuint shader); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef GLuint (GLAD_API_PTR *PFNGLCREATEPROGRAMPROC)(void); +typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROC)(GLenum type); +typedef void (GLAD_API_PTR *PFNGLCULLFACEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint * samplers); +typedef void (GLAD_API_PTR *PFNGLDELETESHADERPROC)(GLuint shader); +typedef void (GLAD_API_PTR *PFNGLDELETESYNCPROC)(GLsync sync); +typedef void (GLAD_API_PTR *PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLDELETETRANSFORMFEEDBACKSPROC)(GLsizei n, const GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLDEPTHFUNCPROC)(GLenum func); +typedef void (GLAD_API_PTR *PFNGLDEPTHMASKPROC)(GLboolean flag); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEFPROC)(GLfloat n, GLfloat f); +typedef void (GLAD_API_PTR *PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); +typedef void (GLAD_API_PTR *PFNGLDISABLEPROC)(GLenum cap); +typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum * bufs); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices); +typedef void (GLAD_API_PTR *PFNGLENABLEPROC)(GLenum cap); +typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLENDQUERYPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLENDTRANSFORMFEEDBACKPROC)(void); +typedef GLsync (GLAD_API_PTR *PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLFINISHPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFLUSHPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAD_API_PTR *PFNGLFRONTFACEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLGENBUFFERSPROC)(GLsizei n, GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLGENQUERIESPROC)(GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint * samplers); +typedef void (GLAD_API_PTR *PFNGLGENTEXTURESPROC)(GLsizei n, GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLGENTRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLGENERATEMIPMAPPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformBlockName); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders); +typedef GLint (GLAD_API_PTR *PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean * data); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void ** params); +typedef GLenum (GLAD_API_PTR *PFNGLGETERRORPROC)(void); +typedef void (GLAD_API_PTR *PFNGLGETFLOATVPROC)(GLenum pname, GLfloat * data); +typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERVPROC)(GLenum pname, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETINTERNALFORMATIVPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMBINARYPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLenum * binaryFormat, void * binary); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum shadertype, GLenum precisiontype, GLint * range, GLint * precision); +typedef void (GLAD_API_PTR *PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source); +typedef void (GLAD_API_PTR *PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint * params); +typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGPROC)(GLenum name); +typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); +typedef void (GLAD_API_PTR *PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei count, GLsizei * length, GLint * values); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); +typedef GLuint (GLAD_API_PTR *PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar * uniformBlockName); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint * uniformIndices); +typedef GLint (GLAD_API_PTR *PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void ** pointer); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLHINTPROC)(GLenum target, GLenum mode); +typedef void (GLAD_API_PTR *PFNGLINVALIDATEFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments); +typedef void (GLAD_API_PTR *PFNGLINVALIDATESUBFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERPROC)(GLuint buffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDPROC)(GLenum cap); +typedef GLboolean (GLAD_API_PTR *PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPROC)(GLuint program); +typedef GLboolean (GLAD_API_PTR *PFNGLISQUERYPROC)(GLuint id); +typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISSAMPLERPROC)(GLuint sampler); +typedef GLboolean (GLAD_API_PTR *PFNGLISSHADERPROC)(GLuint shader); +typedef GLboolean (GLAD_API_PTR *PFNGLISSYNCPROC)(GLsync sync); +typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREPROC)(GLuint texture); +typedef GLboolean (GLAD_API_PTR *PFNGLISTRANSFORMFEEDBACKPROC)(GLuint id); +typedef GLboolean (GLAD_API_PTR *PFNGLISVERTEXARRAYPROC)(GLuint array); +typedef void (GLAD_API_PTR *PFNGLLINEWIDTHPROC)(GLfloat width); +typedef void (GLAD_API_PTR *PFNGLLINKPROGRAMPROC)(GLuint program); +typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GLAD_API_PTR *PFNGLPAUSETRANSFORMFEEDBACKPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units); +typedef void (GLAD_API_PTR *PFNGLPROGRAMBINARYPROC)(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length); +typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETERIPROC)(GLuint program, GLenum pname, GLint value); +typedef void (GLAD_API_PTR *PFNGLREADBUFFERPROC)(GLenum src); +typedef void (GLAD_API_PTR *PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels); +typedef void (GLAD_API_PTR *PFNGLRELEASESHADERCOMPILERPROC)(void); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRESUMETRANSFORMFEEDBACKPROC)(void); +typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat * param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint * param); +typedef void (GLAD_API_PTR *PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLSHADERBINARYPROC)(GLsizei count, const GLuint * shaders, GLenum binaryFormat, const void * binary, GLsizei length); +typedef void (GLAD_API_PTR *PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const* string, const GLint * length); +typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILMASKPROC)(GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass); +typedef void (GLAD_API_PTR *PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE2DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1IPROC)(GLint location, GLint v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPBUFFERPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); + +GLAD_API_CALL PFNGLACTIVETEXTUREPROC glad_glActiveTexture; +#define glActiveTexture glad_glActiveTexture +GLAD_API_CALL PFNGLATTACHSHADERPROC glad_glAttachShader; +#define glAttachShader glad_glAttachShader +GLAD_API_CALL PFNGLBEGINQUERYPROC glad_glBeginQuery; +#define glBeginQuery glad_glBeginQuery +GLAD_API_CALL PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; +#define glBeginTransformFeedback glad_glBeginTransformFeedback +GLAD_API_CALL PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; +#define glBindAttribLocation glad_glBindAttribLocation +GLAD_API_CALL PFNGLBINDBUFFERPROC glad_glBindBuffer; +#define glBindBuffer glad_glBindBuffer +GLAD_API_CALL PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; +#define glBindBufferBase glad_glBindBufferBase +GLAD_API_CALL PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; +#define glBindBufferRange glad_glBindBufferRange +GLAD_API_CALL PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; +#define glBindFramebuffer glad_glBindFramebuffer +GLAD_API_CALL PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; +#define glBindRenderbuffer glad_glBindRenderbuffer +GLAD_API_CALL PFNGLBINDSAMPLERPROC glad_glBindSampler; +#define glBindSampler glad_glBindSampler +GLAD_API_CALL PFNGLBINDTEXTUREPROC glad_glBindTexture; +#define glBindTexture glad_glBindTexture +GLAD_API_CALL PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback; +#define glBindTransformFeedback glad_glBindTransformFeedback +GLAD_API_CALL PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; +#define glBindVertexArray glad_glBindVertexArray +GLAD_API_CALL PFNGLBLENDCOLORPROC glad_glBlendColor; +#define glBlendColor glad_glBlendColor +GLAD_API_CALL PFNGLBLENDEQUATIONPROC glad_glBlendEquation; +#define glBlendEquation glad_glBlendEquation +GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; +#define glBlendEquationSeparate glad_glBlendEquationSeparate +GLAD_API_CALL PFNGLBLENDFUNCPROC glad_glBlendFunc; +#define glBlendFunc glad_glBlendFunc +GLAD_API_CALL PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; +#define glBlendFuncSeparate glad_glBlendFuncSeparate +GLAD_API_CALL PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; +#define glBlitFramebuffer glad_glBlitFramebuffer +GLAD_API_CALL PFNGLBUFFERDATAPROC glad_glBufferData; +#define glBufferData glad_glBufferData +GLAD_API_CALL PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; +#define glBufferSubData glad_glBufferSubData +GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; +#define glCheckFramebufferStatus glad_glCheckFramebufferStatus +GLAD_API_CALL PFNGLCLEARPROC glad_glClear; +#define glClear glad_glClear +GLAD_API_CALL PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; +#define glClearBufferfi glad_glClearBufferfi +GLAD_API_CALL PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; +#define glClearBufferfv glad_glClearBufferfv +GLAD_API_CALL PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; +#define glClearBufferiv glad_glClearBufferiv +GLAD_API_CALL PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; +#define glClearBufferuiv glad_glClearBufferuiv +GLAD_API_CALL PFNGLCLEARCOLORPROC glad_glClearColor; +#define glClearColor glad_glClearColor +GLAD_API_CALL PFNGLCLEARDEPTHFPROC glad_glClearDepthf; +#define glClearDepthf glad_glClearDepthf +GLAD_API_CALL PFNGLCLEARSTENCILPROC glad_glClearStencil; +#define glClearStencil glad_glClearStencil +GLAD_API_CALL PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; +#define glClientWaitSync glad_glClientWaitSync +GLAD_API_CALL PFNGLCOLORMASKPROC glad_glColorMask; +#define glColorMask glad_glColorMask +GLAD_API_CALL PFNGLCOMPILESHADERPROC glad_glCompileShader; +#define glCompileShader glad_glCompileShader +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; +#define glCompressedTexImage2D glad_glCompressedTexImage2D +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; +#define glCompressedTexImage3D glad_glCompressedTexImage3D +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; +#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; +#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D +GLAD_API_CALL PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; +#define glCopyBufferSubData glad_glCopyBufferSubData +GLAD_API_CALL PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; +#define glCopyTexImage2D glad_glCopyTexImage2D +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; +#define glCopyTexSubImage2D glad_glCopyTexSubImage2D +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; +#define glCopyTexSubImage3D glad_glCopyTexSubImage3D +GLAD_API_CALL PFNGLCREATEPROGRAMPROC glad_glCreateProgram; +#define glCreateProgram glad_glCreateProgram +GLAD_API_CALL PFNGLCREATESHADERPROC glad_glCreateShader; +#define glCreateShader glad_glCreateShader +GLAD_API_CALL PFNGLCULLFACEPROC glad_glCullFace; +#define glCullFace glad_glCullFace +GLAD_API_CALL PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; +#define glDeleteBuffers glad_glDeleteBuffers +GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; +#define glDeleteFramebuffers glad_glDeleteFramebuffers +GLAD_API_CALL PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; +#define glDeleteProgram glad_glDeleteProgram +GLAD_API_CALL PFNGLDELETEQUERIESPROC glad_glDeleteQueries; +#define glDeleteQueries glad_glDeleteQueries +GLAD_API_CALL PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; +#define glDeleteRenderbuffers glad_glDeleteRenderbuffers +GLAD_API_CALL PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; +#define glDeleteSamplers glad_glDeleteSamplers +GLAD_API_CALL PFNGLDELETESHADERPROC glad_glDeleteShader; +#define glDeleteShader glad_glDeleteShader +GLAD_API_CALL PFNGLDELETESYNCPROC glad_glDeleteSync; +#define glDeleteSync glad_glDeleteSync +GLAD_API_CALL PFNGLDELETETEXTURESPROC glad_glDeleteTextures; +#define glDeleteTextures glad_glDeleteTextures +GLAD_API_CALL PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks; +#define glDeleteTransformFeedbacks glad_glDeleteTransformFeedbacks +GLAD_API_CALL PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; +#define glDeleteVertexArrays glad_glDeleteVertexArrays +GLAD_API_CALL PFNGLDEPTHFUNCPROC glad_glDepthFunc; +#define glDepthFunc glad_glDepthFunc +GLAD_API_CALL PFNGLDEPTHMASKPROC glad_glDepthMask; +#define glDepthMask glad_glDepthMask +GLAD_API_CALL PFNGLDEPTHRANGEFPROC glad_glDepthRangef; +#define glDepthRangef glad_glDepthRangef +GLAD_API_CALL PFNGLDETACHSHADERPROC glad_glDetachShader; +#define glDetachShader glad_glDetachShader +GLAD_API_CALL PFNGLDISABLEPROC glad_glDisable; +#define glDisable glad_glDisable +GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; +#define glDisableVertexAttribArray glad_glDisableVertexAttribArray +GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays; +#define glDrawArrays glad_glDrawArrays +GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; +#define glDrawArraysInstanced glad_glDrawArraysInstanced +GLAD_API_CALL PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; +#define glDrawBuffers glad_glDrawBuffers +GLAD_API_CALL PFNGLDRAWELEMENTSPROC glad_glDrawElements; +#define glDrawElements glad_glDrawElements +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; +#define glDrawElementsInstanced glad_glDrawElementsInstanced +GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; +#define glDrawRangeElements glad_glDrawRangeElements +GLAD_API_CALL PFNGLENABLEPROC glad_glEnable; +#define glEnable glad_glEnable +GLAD_API_CALL PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; +#define glEnableVertexAttribArray glad_glEnableVertexAttribArray +GLAD_API_CALL PFNGLENDQUERYPROC glad_glEndQuery; +#define glEndQuery glad_glEndQuery +GLAD_API_CALL PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; +#define glEndTransformFeedback glad_glEndTransformFeedback +GLAD_API_CALL PFNGLFENCESYNCPROC glad_glFenceSync; +#define glFenceSync glad_glFenceSync +GLAD_API_CALL PFNGLFINISHPROC glad_glFinish; +#define glFinish glad_glFinish +GLAD_API_CALL PFNGLFLUSHPROC glad_glFlush; +#define glFlush glad_glFlush +GLAD_API_CALL PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; +#define glFlushMappedBufferRange glad_glFlushMappedBufferRange +GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; +#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; +#define glFramebufferTexture2D glad_glFramebufferTexture2D +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; +#define glFramebufferTextureLayer glad_glFramebufferTextureLayer +GLAD_API_CALL PFNGLFRONTFACEPROC glad_glFrontFace; +#define glFrontFace glad_glFrontFace +GLAD_API_CALL PFNGLGENBUFFERSPROC glad_glGenBuffers; +#define glGenBuffers glad_glGenBuffers +GLAD_API_CALL PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; +#define glGenFramebuffers glad_glGenFramebuffers +GLAD_API_CALL PFNGLGENQUERIESPROC glad_glGenQueries; +#define glGenQueries glad_glGenQueries +GLAD_API_CALL PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; +#define glGenRenderbuffers glad_glGenRenderbuffers +GLAD_API_CALL PFNGLGENSAMPLERSPROC glad_glGenSamplers; +#define glGenSamplers glad_glGenSamplers +GLAD_API_CALL PFNGLGENTEXTURESPROC glad_glGenTextures; +#define glGenTextures glad_glGenTextures +GLAD_API_CALL PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks; +#define glGenTransformFeedbacks glad_glGenTransformFeedbacks +GLAD_API_CALL PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; +#define glGenVertexArrays glad_glGenVertexArrays +GLAD_API_CALL PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; +#define glGenerateMipmap glad_glGenerateMipmap +GLAD_API_CALL PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; +#define glGetActiveAttrib glad_glGetActiveAttrib +GLAD_API_CALL PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; +#define glGetActiveUniform glad_glGetActiveUniform +GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; +#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName +GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; +#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv +GLAD_API_CALL PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; +#define glGetActiveUniformsiv glad_glGetActiveUniformsiv +GLAD_API_CALL PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; +#define glGetAttachedShaders glad_glGetAttachedShaders +GLAD_API_CALL PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; +#define glGetAttribLocation glad_glGetAttribLocation +GLAD_API_CALL PFNGLGETBOOLEANVPROC glad_glGetBooleanv; +#define glGetBooleanv glad_glGetBooleanv +GLAD_API_CALL PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; +#define glGetBufferParameteri64v glad_glGetBufferParameteri64v +GLAD_API_CALL PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; +#define glGetBufferParameteriv glad_glGetBufferParameteriv +GLAD_API_CALL PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; +#define glGetBufferPointerv glad_glGetBufferPointerv +GLAD_API_CALL PFNGLGETERRORPROC glad_glGetError; +#define glGetError glad_glGetError +GLAD_API_CALL PFNGLGETFLOATVPROC glad_glGetFloatv; +#define glGetFloatv glad_glGetFloatv +GLAD_API_CALL PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; +#define glGetFragDataLocation glad_glGetFragDataLocation +GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; +#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv +GLAD_API_CALL PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; +#define glGetInteger64i_v glad_glGetInteger64i_v +GLAD_API_CALL PFNGLGETINTEGER64VPROC glad_glGetInteger64v; +#define glGetInteger64v glad_glGetInteger64v +GLAD_API_CALL PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; +#define glGetIntegeri_v glad_glGetIntegeri_v +GLAD_API_CALL PFNGLGETINTEGERVPROC glad_glGetIntegerv; +#define glGetIntegerv glad_glGetIntegerv +GLAD_API_CALL PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ; +#define glGetInternalformativ glad_glGetInternalformativ +GLAD_API_CALL PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary; +#define glGetProgramBinary glad_glGetProgramBinary +GLAD_API_CALL PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; +#define glGetProgramInfoLog glad_glGetProgramInfoLog +GLAD_API_CALL PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; +#define glGetProgramiv glad_glGetProgramiv +GLAD_API_CALL PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; +#define glGetQueryObjectuiv glad_glGetQueryObjectuiv +GLAD_API_CALL PFNGLGETQUERYIVPROC glad_glGetQueryiv; +#define glGetQueryiv glad_glGetQueryiv +GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; +#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; +#define glGetSamplerParameterfv glad_glGetSamplerParameterfv +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; +#define glGetSamplerParameteriv glad_glGetSamplerParameteriv +GLAD_API_CALL PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; +#define glGetShaderInfoLog glad_glGetShaderInfoLog +GLAD_API_CALL PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat; +#define glGetShaderPrecisionFormat glad_glGetShaderPrecisionFormat +GLAD_API_CALL PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; +#define glGetShaderSource glad_glGetShaderSource +GLAD_API_CALL PFNGLGETSHADERIVPROC glad_glGetShaderiv; +#define glGetShaderiv glad_glGetShaderiv +GLAD_API_CALL PFNGLGETSTRINGPROC glad_glGetString; +#define glGetString glad_glGetString +GLAD_API_CALL PFNGLGETSTRINGIPROC glad_glGetStringi; +#define glGetStringi glad_glGetStringi +GLAD_API_CALL PFNGLGETSYNCIVPROC glad_glGetSynciv; +#define glGetSynciv glad_glGetSynciv +GLAD_API_CALL PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; +#define glGetTexParameterfv glad_glGetTexParameterfv +GLAD_API_CALL PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; +#define glGetTexParameteriv glad_glGetTexParameteriv +GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; +#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying +GLAD_API_CALL PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; +#define glGetUniformBlockIndex glad_glGetUniformBlockIndex +GLAD_API_CALL PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; +#define glGetUniformIndices glad_glGetUniformIndices +GLAD_API_CALL PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; +#define glGetUniformLocation glad_glGetUniformLocation +GLAD_API_CALL PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; +#define glGetUniformfv glad_glGetUniformfv +GLAD_API_CALL PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; +#define glGetUniformiv glad_glGetUniformiv +GLAD_API_CALL PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; +#define glGetUniformuiv glad_glGetUniformuiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; +#define glGetVertexAttribIiv glad_glGetVertexAttribIiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; +#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; +#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv +GLAD_API_CALL PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; +#define glGetVertexAttribfv glad_glGetVertexAttribfv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; +#define glGetVertexAttribiv glad_glGetVertexAttribiv +GLAD_API_CALL PFNGLHINTPROC glad_glHint; +#define glHint glad_glHint +GLAD_API_CALL PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer; +#define glInvalidateFramebuffer glad_glInvalidateFramebuffer +GLAD_API_CALL PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer; +#define glInvalidateSubFramebuffer glad_glInvalidateSubFramebuffer +GLAD_API_CALL PFNGLISBUFFERPROC glad_glIsBuffer; +#define glIsBuffer glad_glIsBuffer +GLAD_API_CALL PFNGLISENABLEDPROC glad_glIsEnabled; +#define glIsEnabled glad_glIsEnabled +GLAD_API_CALL PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; +#define glIsFramebuffer glad_glIsFramebuffer +GLAD_API_CALL PFNGLISPROGRAMPROC glad_glIsProgram; +#define glIsProgram glad_glIsProgram +GLAD_API_CALL PFNGLISQUERYPROC glad_glIsQuery; +#define glIsQuery glad_glIsQuery +GLAD_API_CALL PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; +#define glIsRenderbuffer glad_glIsRenderbuffer +GLAD_API_CALL PFNGLISSAMPLERPROC glad_glIsSampler; +#define glIsSampler glad_glIsSampler +GLAD_API_CALL PFNGLISSHADERPROC glad_glIsShader; +#define glIsShader glad_glIsShader +GLAD_API_CALL PFNGLISSYNCPROC glad_glIsSync; +#define glIsSync glad_glIsSync +GLAD_API_CALL PFNGLISTEXTUREPROC glad_glIsTexture; +#define glIsTexture glad_glIsTexture +GLAD_API_CALL PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback; +#define glIsTransformFeedback glad_glIsTransformFeedback +GLAD_API_CALL PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; +#define glIsVertexArray glad_glIsVertexArray +GLAD_API_CALL PFNGLLINEWIDTHPROC glad_glLineWidth; +#define glLineWidth glad_glLineWidth +GLAD_API_CALL PFNGLLINKPROGRAMPROC glad_glLinkProgram; +#define glLinkProgram glad_glLinkProgram +GLAD_API_CALL PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; +#define glMapBufferRange glad_glMapBufferRange +GLAD_API_CALL PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback; +#define glPauseTransformFeedback glad_glPauseTransformFeedback +GLAD_API_CALL PFNGLPIXELSTOREIPROC glad_glPixelStorei; +#define glPixelStorei glad_glPixelStorei +GLAD_API_CALL PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; +#define glPolygonOffset glad_glPolygonOffset +GLAD_API_CALL PFNGLPROGRAMBINARYPROC glad_glProgramBinary; +#define glProgramBinary glad_glProgramBinary +GLAD_API_CALL PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri; +#define glProgramParameteri glad_glProgramParameteri +GLAD_API_CALL PFNGLREADBUFFERPROC glad_glReadBuffer; +#define glReadBuffer glad_glReadBuffer +GLAD_API_CALL PFNGLREADPIXELSPROC glad_glReadPixels; +#define glReadPixels glad_glReadPixels +GLAD_API_CALL PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; +#define glReleaseShaderCompiler glad_glReleaseShaderCompiler +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; +#define glRenderbufferStorage glad_glRenderbufferStorage +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; +#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample +GLAD_API_CALL PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback; +#define glResumeTransformFeedback glad_glResumeTransformFeedback +GLAD_API_CALL PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; +#define glSampleCoverage glad_glSampleCoverage +GLAD_API_CALL PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; +#define glSamplerParameterf glad_glSamplerParameterf +GLAD_API_CALL PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; +#define glSamplerParameterfv glad_glSamplerParameterfv +GLAD_API_CALL PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; +#define glSamplerParameteri glad_glSamplerParameteri +GLAD_API_CALL PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; +#define glSamplerParameteriv glad_glSamplerParameteriv +GLAD_API_CALL PFNGLSCISSORPROC glad_glScissor; +#define glScissor glad_glScissor +GLAD_API_CALL PFNGLSHADERBINARYPROC glad_glShaderBinary; +#define glShaderBinary glad_glShaderBinary +GLAD_API_CALL PFNGLSHADERSOURCEPROC glad_glShaderSource; +#define glShaderSource glad_glShaderSource +GLAD_API_CALL PFNGLSTENCILFUNCPROC glad_glStencilFunc; +#define glStencilFunc glad_glStencilFunc +GLAD_API_CALL PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; +#define glStencilFuncSeparate glad_glStencilFuncSeparate +GLAD_API_CALL PFNGLSTENCILMASKPROC glad_glStencilMask; +#define glStencilMask glad_glStencilMask +GLAD_API_CALL PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; +#define glStencilMaskSeparate glad_glStencilMaskSeparate +GLAD_API_CALL PFNGLSTENCILOPPROC glad_glStencilOp; +#define glStencilOp glad_glStencilOp +GLAD_API_CALL PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; +#define glStencilOpSeparate glad_glStencilOpSeparate +GLAD_API_CALL PFNGLTEXIMAGE2DPROC glad_glTexImage2D; +#define glTexImage2D glad_glTexImage2D +GLAD_API_CALL PFNGLTEXIMAGE3DPROC glad_glTexImage3D; +#define glTexImage3D glad_glTexImage3D +GLAD_API_CALL PFNGLTEXPARAMETERFPROC glad_glTexParameterf; +#define glTexParameterf glad_glTexParameterf +GLAD_API_CALL PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; +#define glTexParameterfv glad_glTexParameterfv +GLAD_API_CALL PFNGLTEXPARAMETERIPROC glad_glTexParameteri; +#define glTexParameteri glad_glTexParameteri +GLAD_API_CALL PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; +#define glTexParameteriv glad_glTexParameteriv +GLAD_API_CALL PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D; +#define glTexStorage2D glad_glTexStorage2D +GLAD_API_CALL PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D; +#define glTexStorage3D glad_glTexStorage3D +GLAD_API_CALL PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; +#define glTexSubImage2D glad_glTexSubImage2D +GLAD_API_CALL PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; +#define glTexSubImage3D glad_glTexSubImage3D +GLAD_API_CALL PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; +#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings +GLAD_API_CALL PFNGLUNIFORM1FPROC glad_glUniform1f; +#define glUniform1f glad_glUniform1f +GLAD_API_CALL PFNGLUNIFORM1FVPROC glad_glUniform1fv; +#define glUniform1fv glad_glUniform1fv +GLAD_API_CALL PFNGLUNIFORM1IPROC glad_glUniform1i; +#define glUniform1i glad_glUniform1i +GLAD_API_CALL PFNGLUNIFORM1IVPROC glad_glUniform1iv; +#define glUniform1iv glad_glUniform1iv +GLAD_API_CALL PFNGLUNIFORM1UIPROC glad_glUniform1ui; +#define glUniform1ui glad_glUniform1ui +GLAD_API_CALL PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; +#define glUniform1uiv glad_glUniform1uiv +GLAD_API_CALL PFNGLUNIFORM2FPROC glad_glUniform2f; +#define glUniform2f glad_glUniform2f +GLAD_API_CALL PFNGLUNIFORM2FVPROC glad_glUniform2fv; +#define glUniform2fv glad_glUniform2fv +GLAD_API_CALL PFNGLUNIFORM2IPROC glad_glUniform2i; +#define glUniform2i glad_glUniform2i +GLAD_API_CALL PFNGLUNIFORM2IVPROC glad_glUniform2iv; +#define glUniform2iv glad_glUniform2iv +GLAD_API_CALL PFNGLUNIFORM2UIPROC glad_glUniform2ui; +#define glUniform2ui glad_glUniform2ui +GLAD_API_CALL PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; +#define glUniform2uiv glad_glUniform2uiv +GLAD_API_CALL PFNGLUNIFORM3FPROC glad_glUniform3f; +#define glUniform3f glad_glUniform3f +GLAD_API_CALL PFNGLUNIFORM3FVPROC glad_glUniform3fv; +#define glUniform3fv glad_glUniform3fv +GLAD_API_CALL PFNGLUNIFORM3IPROC glad_glUniform3i; +#define glUniform3i glad_glUniform3i +GLAD_API_CALL PFNGLUNIFORM3IVPROC glad_glUniform3iv; +#define glUniform3iv glad_glUniform3iv +GLAD_API_CALL PFNGLUNIFORM3UIPROC glad_glUniform3ui; +#define glUniform3ui glad_glUniform3ui +GLAD_API_CALL PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; +#define glUniform3uiv glad_glUniform3uiv +GLAD_API_CALL PFNGLUNIFORM4FPROC glad_glUniform4f; +#define glUniform4f glad_glUniform4f +GLAD_API_CALL PFNGLUNIFORM4FVPROC glad_glUniform4fv; +#define glUniform4fv glad_glUniform4fv +GLAD_API_CALL PFNGLUNIFORM4IPROC glad_glUniform4i; +#define glUniform4i glad_glUniform4i +GLAD_API_CALL PFNGLUNIFORM4IVPROC glad_glUniform4iv; +#define glUniform4iv glad_glUniform4iv +GLAD_API_CALL PFNGLUNIFORM4UIPROC glad_glUniform4ui; +#define glUniform4ui glad_glUniform4ui +GLAD_API_CALL PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; +#define glUniform4uiv glad_glUniform4uiv +GLAD_API_CALL PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; +#define glUniformBlockBinding glad_glUniformBlockBinding +GLAD_API_CALL PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; +#define glUniformMatrix2fv glad_glUniformMatrix2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; +#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv +GLAD_API_CALL PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; +#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; +#define glUniformMatrix3fv glad_glUniformMatrix3fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; +#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; +#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; +#define glUniformMatrix4fv glad_glUniformMatrix4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; +#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; +#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv +GLAD_API_CALL PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; +#define glUnmapBuffer glad_glUnmapBuffer +GLAD_API_CALL PFNGLUSEPROGRAMPROC glad_glUseProgram; +#define glUseProgram glad_glUseProgram +GLAD_API_CALL PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; +#define glValidateProgram glad_glValidateProgram +GLAD_API_CALL PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; +#define glVertexAttrib1f glad_glVertexAttrib1f +GLAD_API_CALL PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; +#define glVertexAttrib1fv glad_glVertexAttrib1fv +GLAD_API_CALL PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; +#define glVertexAttrib2f glad_glVertexAttrib2f +GLAD_API_CALL PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; +#define glVertexAttrib2fv glad_glVertexAttrib2fv +GLAD_API_CALL PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; +#define glVertexAttrib3f glad_glVertexAttrib3f +GLAD_API_CALL PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; +#define glVertexAttrib3fv glad_glVertexAttrib3fv +GLAD_API_CALL PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; +#define glVertexAttrib4f glad_glVertexAttrib4f +GLAD_API_CALL PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; +#define glVertexAttrib4fv glad_glVertexAttrib4fv +GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; +#define glVertexAttribDivisor glad_glVertexAttribDivisor +GLAD_API_CALL PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; +#define glVertexAttribI4i glad_glVertexAttribI4i +GLAD_API_CALL PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; +#define glVertexAttribI4iv glad_glVertexAttribI4iv +GLAD_API_CALL PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; +#define glVertexAttribI4ui glad_glVertexAttribI4ui +GLAD_API_CALL PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; +#define glVertexAttribI4uiv glad_glVertexAttribI4uiv +GLAD_API_CALL PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; +#define glVertexAttribIPointer glad_glVertexAttribIPointer +GLAD_API_CALL PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; +#define glVertexAttribPointer glad_glVertexAttribPointer +GLAD_API_CALL PFNGLVIEWPORTPROC glad_glViewport; +#define glViewport glad_glViewport +GLAD_API_CALL PFNGLWAITSYNCPROC glad_glWaitSync; +#define glWaitSync glad_glWaitSync + + + + + +GLAD_API_CALL int gladLoadGLES2UserPtr( GLADuserptrloadfunc load, void *userptr); +GLAD_API_CALL int gladLoadGLES2( GLADloadfunc load); + + +#ifdef GLAD_GLES2 + +GLAD_API_CALL int gladLoaderLoadGLES2(void); +GLAD_API_CALL void gladLoaderUnloadGLES2(void); + +#endif /* GLAD_GLES2 */ + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/libvgcode/glad/src/gl.c b/src/libvgcode/glad/src/gl.c new file mode 100644 index 0000000000..3a09be685d --- /dev/null +++ b/src/libvgcode/glad/src/gl.c @@ -0,0 +1,1786 @@ +/** + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + */ +#include +#include +#include +#include + +#ifndef GLAD_IMPL_UTIL_C_ +#define GLAD_IMPL_UTIL_C_ + +#ifdef _MSC_VER +#define GLAD_IMPL_UTIL_SSCANF sscanf_s +#else +#define GLAD_IMPL_UTIL_SSCANF sscanf +#endif + +#endif /* GLAD_IMPL_UTIL_C_ */ + +#ifdef __cplusplus +extern "C" { +#endif + + + +int GLAD_GL_VERSION_1_0 = 0; +int GLAD_GL_VERSION_1_1 = 0; +int GLAD_GL_VERSION_1_2 = 0; +int GLAD_GL_VERSION_1_3 = 0; +int GLAD_GL_VERSION_1_4 = 0; +int GLAD_GL_VERSION_1_5 = 0; +int GLAD_GL_VERSION_2_0 = 0; +int GLAD_GL_VERSION_2_1 = 0; +int GLAD_GL_VERSION_3_0 = 0; +int GLAD_GL_VERSION_3_1 = 0; +int GLAD_GL_VERSION_3_2 = 0; +int GLAD_GL_VERSION_3_3 = 0; +int GLAD_GL_VERSION_4_0 = 0; +int GLAD_GL_VERSION_4_1 = 0; +int GLAD_GL_VERSION_4_2 = 0; +int GLAD_GL_VERSION_4_3 = 0; +int GLAD_GL_VERSION_4_4 = 0; +int GLAD_GL_VERSION_4_5 = 0; +int GLAD_GL_VERSION_4_6 = 0; + + + +PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram = NULL; +PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; +PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; +PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; +PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; +PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed = NULL; +PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; +PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; +PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; +PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; +PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; +PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase = NULL; +PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange = NULL; +PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL; +PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL; +PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; +PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture = NULL; +PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures = NULL; +PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline = NULL; +PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; +PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; +PFNGLBINDSAMPLERSPROC glad_glBindSamplers = NULL; +PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; +PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit = NULL; +PFNGLBINDTEXTURESPROC glad_glBindTextures = NULL; +PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL; +PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; +PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer = NULL; +PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers = NULL; +PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; +PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; +PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; +PFNGLBLENDEQUATIONSEPARATEIPROC glad_glBlendEquationSeparatei = NULL; +PFNGLBLENDEQUATIONIPROC glad_glBlendEquationi = NULL; +PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; +PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; +PFNGLBLENDFUNCSEPARATEIPROC glad_glBlendFuncSeparatei = NULL; +PFNGLBLENDFUNCIPROC glad_glBlendFunci = NULL; +PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; +PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer = NULL; +PFNGLBUFFERDATAPROC glad_glBufferData = NULL; +PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL; +PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; +PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus = NULL; +PFNGLCLAMPCOLORPROC glad_glClampColor = NULL; +PFNGLCLEARPROC glad_glClear = NULL; +PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData = NULL; +PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData = NULL; +PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; +PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; +PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; +PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; +PFNGLCLEARCOLORPROC glad_glClearColor = NULL; +PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; +PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL; +PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData = NULL; +PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv = NULL; +PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; +PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage = NULL; +PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage = NULL; +PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; +PFNGLCLIPCONTROLPROC glad_glClipControl = NULL; +PFNGLCOLORMASKPROC glad_glColorMask = NULL; +PFNGLCOLORMASKIPROC glad_glColorMaski = NULL; +PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; +PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D = NULL; +PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; +PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData = NULL; +PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData = NULL; +PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; +PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; +PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; +PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; +PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; +PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D = NULL; +PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D = NULL; +PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D = NULL; +PFNGLCREATEBUFFERSPROC glad_glCreateBuffers = NULL; +PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers = NULL; +PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; +PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines = NULL; +PFNGLCREATEQUERIESPROC glad_glCreateQueries = NULL; +PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers = NULL; +PFNGLCREATESAMPLERSPROC glad_glCreateSamplers = NULL; +PFNGLCREATESHADERPROC glad_glCreateShader = NULL; +PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv = NULL; +PFNGLCREATETEXTURESPROC glad_glCreateTextures = NULL; +PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks = NULL; +PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays = NULL; +PFNGLCULLFACEPROC glad_glCullFace = NULL; +PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback = NULL; +PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl = NULL; +PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert = NULL; +PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; +PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; +PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; +PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines = NULL; +PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; +PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; +PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; +PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; +PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; +PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; +PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks = NULL; +PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; +PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; +PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; +PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; +PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL; +PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL; +PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL; +PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; +PFNGLDISABLEPROC glad_glDisable = NULL; +PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; +PFNGLDISABLEIPROC glad_glDisablei = NULL; +PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute = NULL; +PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect = NULL; +PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; +PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect = NULL; +PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; +PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance = NULL; +PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; +PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; +PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; +PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL; +PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect = NULL; +PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance = NULL; +PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; +PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL; +PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback = NULL; +PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced = NULL; +PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream = NULL; +PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced = NULL; +PFNGLENABLEPROC glad_glEnable = NULL; +PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib = NULL; +PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; +PFNGLENABLEIPROC glad_glEnablei = NULL; +PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; +PFNGLENDQUERYPROC glad_glEndQuery = NULL; +PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed = NULL; +PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; +PFNGLFENCESYNCPROC glad_glFenceSync = NULL; +PFNGLFINISHPROC glad_glFinish = NULL; +PFNGLFLUSHPROC glad_glFlush = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; +PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange = NULL; +PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri = NULL; +PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; +PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL; +PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; +PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; +PFNGLFRONTFACEPROC glad_glFrontFace = NULL; +PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; +PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; +PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines = NULL; +PFNGLGENQUERIESPROC glad_glGenQueries = NULL; +PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; +PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; +PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; +PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks = NULL; +PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; +PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; +PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap = NULL; +PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv = NULL; +PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; +PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName = NULL; +PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName = NULL; +PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv = NULL; +PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; +PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; +PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; +PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL; +PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; +PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; +PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; +PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; +PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; +PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; +PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; +PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; +PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; +PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage = NULL; +PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage = NULL; +PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog = NULL; +PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v = NULL; +PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL; +PFNGLGETERRORPROC glad_glGetError = NULL; +PFNGLGETFLOATI_VPROC glad_glGetFloati_v = NULL; +PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; +PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL; +PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; +PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv = NULL; +PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus = NULL; +PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; +PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; +PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; +PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; +PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v = NULL; +PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL; +PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; +PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v = NULL; +PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv = NULL; +PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv = NULL; +PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData = NULL; +PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv = NULL; +PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv = NULL; +PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv = NULL; +PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel = NULL; +PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel = NULL; +PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL; +PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL; +PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; +PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv = NULL; +PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog = NULL; +PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv = NULL; +PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex = NULL; +PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation = NULL; +PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex = NULL; +PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName = NULL; +PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv = NULL; +PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv = NULL; +PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; +PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v = NULL; +PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv = NULL; +PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v = NULL; +PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv = NULL; +PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv = NULL; +PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL; +PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL; +PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL; +PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; +PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; +PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL; +PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL; +PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; +PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; +PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; +PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL; +PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; +PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; +PFNGLGETSTRINGPROC glad_glGetString = NULL; +PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; +PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex = NULL; +PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation = NULL; +PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; +PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; +PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; +PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; +PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL; +PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL; +PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; +PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; +PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage = NULL; +PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv = NULL; +PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv = NULL; +PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv = NULL; +PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv = NULL; +PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv = NULL; +PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv = NULL; +PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; +PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v = NULL; +PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v = NULL; +PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv = NULL; +PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; +PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; +PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; +PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv = NULL; +PFNGLGETUNIFORMDVPROC glad_glGetUniformdv = NULL; +PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; +PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; +PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; +PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv = NULL; +PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv = NULL; +PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv = NULL; +PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; +PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; +PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv = NULL; +PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; +PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL; +PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; +PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; +PFNGLGETNCOMPRESSEDTEXIMAGEPROC glad_glGetnCompressedTexImage = NULL; +PFNGLGETNTEXIMAGEPROC glad_glGetnTexImage = NULL; +PFNGLGETNUNIFORMDVPROC glad_glGetnUniformdv = NULL; +PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv = NULL; +PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv = NULL; +PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv = NULL; +PFNGLHINTPROC glad_glHint = NULL; +PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData = NULL; +PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData = NULL; +PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL; +PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData = NULL; +PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData = NULL; +PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer = NULL; +PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage = NULL; +PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage = NULL; +PFNGLISBUFFERPROC glad_glIsBuffer = NULL; +PFNGLISENABLEDPROC glad_glIsEnabled = NULL; +PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL; +PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; +PFNGLISPROGRAMPROC glad_glIsProgram = NULL; +PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline = NULL; +PFNGLISQUERYPROC glad_glIsQuery = NULL; +PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; +PFNGLISSAMPLERPROC glad_glIsSampler = NULL; +PFNGLISSHADERPROC glad_glIsShader = NULL; +PFNGLISSYNCPROC glad_glIsSync = NULL; +PFNGLISTEXTUREPROC glad_glIsTexture = NULL; +PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = NULL; +PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; +PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; +PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; +PFNGLLOGICOPPROC glad_glLogicOp = NULL; +PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; +PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; +PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer = NULL; +PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange = NULL; +PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier = NULL; +PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion = NULL; +PFNGLMINSAMPLESHADINGPROC glad_glMinSampleShading = NULL; +PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; +PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect = NULL; +PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glad_glMultiDrawArraysIndirectCount = NULL; +PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; +PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glad_glMultiDrawElementsIndirectCount = NULL; +PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData = NULL; +PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage = NULL; +PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData = NULL; +PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer = NULL; +PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers = NULL; +PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri = NULL; +PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer = NULL; +PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample = NULL; +PFNGLOBJECTLABELPROC glad_glObjectLabel = NULL; +PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel = NULL; +PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv = NULL; +PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri = NULL; +PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = NULL; +PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; +PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; +PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; +PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL; +PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL; +PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL; +PFNGLPOINTSIZEPROC glad_glPointSize = NULL; +PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; +PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; +PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp = NULL; +PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup = NULL; +PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL; +PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL; +PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL; +PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d = NULL; +PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv = NULL; +PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f = NULL; +PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv = NULL; +PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i = NULL; +PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv = NULL; +PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui = NULL; +PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv = NULL; +PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d = NULL; +PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv = NULL; +PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f = NULL; +PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv = NULL; +PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i = NULL; +PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv = NULL; +PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui = NULL; +PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv = NULL; +PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d = NULL; +PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv = NULL; +PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f = NULL; +PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv = NULL; +PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i = NULL; +PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv = NULL; +PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui = NULL; +PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv = NULL; +PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d = NULL; +PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv = NULL; +PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f = NULL; +PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv = NULL; +PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i = NULL; +PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv = NULL; +PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui = NULL; +PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv = NULL; +PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL; +PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup = NULL; +PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL; +PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; +PFNGLREADPIXELSPROC glad_glReadPixels = NULL; +PFNGLREADNPIXELSPROC glad_glReadnPixels = NULL; +PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL; +PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; +PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL; +PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; +PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL; +PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL; +PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL; +PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; +PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; +PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; +PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL; +PFNGLSCISSORPROC glad_glScissor = NULL; +PFNGLSCISSORARRAYVPROC glad_glScissorArrayv = NULL; +PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed = NULL; +PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv = NULL; +PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL; +PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; +PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding = NULL; +PFNGLSPECIALIZESHADERPROC glad_glSpecializeShader = NULL; +PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; +PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; +PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; +PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; +PFNGLSTENCILOPPROC glad_glStencilOp = NULL; +PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; +PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL; +PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange = NULL; +PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; +PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; +PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL; +PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; +PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL; +PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL; +PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL; +PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; +PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; +PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; +PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; +PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D = NULL; +PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D = NULL; +PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample = NULL; +PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D = NULL; +PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample = NULL; +PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL; +PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; +PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; +PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier = NULL; +PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer = NULL; +PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange = NULL; +PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv = NULL; +PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv = NULL; +PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf = NULL; +PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv = NULL; +PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri = NULL; +PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv = NULL; +PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D = NULL; +PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D = NULL; +PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample = NULL; +PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D = NULL; +PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample = NULL; +PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D = NULL; +PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D = NULL; +PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D = NULL; +PFNGLTEXTUREVIEWPROC glad_glTextureView = NULL; +PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase = NULL; +PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; +PFNGLUNIFORM1DPROC glad_glUniform1d = NULL; +PFNGLUNIFORM1DVPROC glad_glUniform1dv = NULL; +PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; +PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; +PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; +PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; +PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; +PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; +PFNGLUNIFORM2DPROC glad_glUniform2d = NULL; +PFNGLUNIFORM2DVPROC glad_glUniform2dv = NULL; +PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; +PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; +PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; +PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; +PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; +PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; +PFNGLUNIFORM3DPROC glad_glUniform3d = NULL; +PFNGLUNIFORM3DVPROC glad_glUniform3dv = NULL; +PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; +PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; +PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; +PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; +PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; +PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; +PFNGLUNIFORM4DPROC glad_glUniform4d = NULL; +PFNGLUNIFORM4DVPROC glad_glUniform4dv = NULL; +PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; +PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; +PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; +PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; +PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; +PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; +PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; +PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv = NULL; +PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; +PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv = NULL; +PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; +PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv = NULL; +PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; +PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv = NULL; +PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; +PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv = NULL; +PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; +PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv = NULL; +PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; +PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv = NULL; +PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; +PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv = NULL; +PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; +PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv = NULL; +PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; +PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv = NULL; +PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; +PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer = NULL; +PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; +PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages = NULL; +PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; +PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline = NULL; +PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding = NULL; +PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat = NULL; +PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat = NULL; +PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat = NULL; +PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor = NULL; +PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer = NULL; +PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer = NULL; +PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers = NULL; +PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL; +PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL; +PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; +PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; +PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL; +PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL; +PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL; +PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL; +PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; +PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; +PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL; +PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL; +PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL; +PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL; +PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; +PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; +PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL; +PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL; +PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL; +PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL; +PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL; +PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL; +PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL; +PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL; +PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL; +PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL; +PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL; +PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL; +PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; +PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; +PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL; +PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL; +PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL; +PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL; +PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL; +PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL; +PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding = NULL; +PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; +PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat = NULL; +PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL; +PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL; +PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL; +PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL; +PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL; +PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL; +PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL; +PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL; +PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL; +PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL; +PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL; +PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL; +PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL; +PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; +PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; +PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL; +PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL; +PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; +PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; +PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL; +PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat = NULL; +PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; +PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d = NULL; +PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv = NULL; +PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d = NULL; +PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv = NULL; +PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d = NULL; +PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv = NULL; +PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d = NULL; +PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv = NULL; +PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat = NULL; +PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer = NULL; +PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL; +PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL; +PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL; +PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL; +PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL; +PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL; +PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL; +PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL; +PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; +PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor = NULL; +PFNGLVIEWPORTPROC glad_glViewport = NULL; +PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv = NULL; +PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf = NULL; +PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv = NULL; +PFNGLWAITSYNCPROC glad_glWaitSync = NULL; + + +static void glad_gl_load_GL_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_0) return; + glad_glBlendFunc = (PFNGLBLENDFUNCPROC) load(userptr, "glBlendFunc"); + glad_glClear = (PFNGLCLEARPROC) load(userptr, "glClear"); + glad_glClearColor = (PFNGLCLEARCOLORPROC) load(userptr, "glClearColor"); + glad_glClearDepth = (PFNGLCLEARDEPTHPROC) load(userptr, "glClearDepth"); + glad_glClearStencil = (PFNGLCLEARSTENCILPROC) load(userptr, "glClearStencil"); + glad_glColorMask = (PFNGLCOLORMASKPROC) load(userptr, "glColorMask"); + glad_glCullFace = (PFNGLCULLFACEPROC) load(userptr, "glCullFace"); + glad_glDepthFunc = (PFNGLDEPTHFUNCPROC) load(userptr, "glDepthFunc"); + glad_glDepthMask = (PFNGLDEPTHMASKPROC) load(userptr, "glDepthMask"); + glad_glDepthRange = (PFNGLDEPTHRANGEPROC) load(userptr, "glDepthRange"); + glad_glDisable = (PFNGLDISABLEPROC) load(userptr, "glDisable"); + glad_glDrawBuffer = (PFNGLDRAWBUFFERPROC) load(userptr, "glDrawBuffer"); + glad_glEnable = (PFNGLENABLEPROC) load(userptr, "glEnable"); + glad_glFinish = (PFNGLFINISHPROC) load(userptr, "glFinish"); + glad_glFlush = (PFNGLFLUSHPROC) load(userptr, "glFlush"); + glad_glFrontFace = (PFNGLFRONTFACEPROC) load(userptr, "glFrontFace"); + glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC) load(userptr, "glGetBooleanv"); + glad_glGetDoublev = (PFNGLGETDOUBLEVPROC) load(userptr, "glGetDoublev"); + glad_glGetError = (PFNGLGETERRORPROC) load(userptr, "glGetError"); + glad_glGetFloatv = (PFNGLGETFLOATVPROC) load(userptr, "glGetFloatv"); + glad_glGetIntegerv = (PFNGLGETINTEGERVPROC) load(userptr, "glGetIntegerv"); + glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + glad_glGetTexImage = (PFNGLGETTEXIMAGEPROC) load(userptr, "glGetTexImage"); + glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) load(userptr, "glGetTexLevelParameterfv"); + glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) load(userptr, "glGetTexLevelParameteriv"); + glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load(userptr, "glGetTexParameterfv"); + glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load(userptr, "glGetTexParameteriv"); + glad_glHint = (PFNGLHINTPROC) load(userptr, "glHint"); + glad_glIsEnabled = (PFNGLISENABLEDPROC) load(userptr, "glIsEnabled"); + glad_glLineWidth = (PFNGLLINEWIDTHPROC) load(userptr, "glLineWidth"); + glad_glLogicOp = (PFNGLLOGICOPPROC) load(userptr, "glLogicOp"); + glad_glPixelStoref = (PFNGLPIXELSTOREFPROC) load(userptr, "glPixelStoref"); + glad_glPixelStorei = (PFNGLPIXELSTOREIPROC) load(userptr, "glPixelStorei"); + glad_glPointSize = (PFNGLPOINTSIZEPROC) load(userptr, "glPointSize"); + glad_glPolygonMode = (PFNGLPOLYGONMODEPROC) load(userptr, "glPolygonMode"); + glad_glReadBuffer = (PFNGLREADBUFFERPROC) load(userptr, "glReadBuffer"); + glad_glReadPixels = (PFNGLREADPIXELSPROC) load(userptr, "glReadPixels"); + glad_glScissor = (PFNGLSCISSORPROC) load(userptr, "glScissor"); + glad_glStencilFunc = (PFNGLSTENCILFUNCPROC) load(userptr, "glStencilFunc"); + glad_glStencilMask = (PFNGLSTENCILMASKPROC) load(userptr, "glStencilMask"); + glad_glStencilOp = (PFNGLSTENCILOPPROC) load(userptr, "glStencilOp"); + glad_glTexImage1D = (PFNGLTEXIMAGE1DPROC) load(userptr, "glTexImage1D"); + glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC) load(userptr, "glTexImage2D"); + glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC) load(userptr, "glTexParameterf"); + glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load(userptr, "glTexParameterfv"); + glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC) load(userptr, "glTexParameteri"); + glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load(userptr, "glTexParameteriv"); + glad_glViewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport"); +} +static void glad_gl_load_GL_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_1) return; + glad_glBindTexture = (PFNGLBINDTEXTUREPROC) load(userptr, "glBindTexture"); + glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC) load(userptr, "glCopyTexImage1D"); + glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load(userptr, "glCopyTexImage2D"); + glad_glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC) load(userptr, "glCopyTexSubImage1D"); + glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load(userptr, "glCopyTexSubImage2D"); + glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC) load(userptr, "glDeleteTextures"); + glad_glDrawArrays = (PFNGLDRAWARRAYSPROC) load(userptr, "glDrawArrays"); + glad_glDrawElements = (PFNGLDRAWELEMENTSPROC) load(userptr, "glDrawElements"); + glad_glGenTextures = (PFNGLGENTEXTURESPROC) load(userptr, "glGenTextures"); + glad_glGetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv"); + glad_glIsTexture = (PFNGLISTEXTUREPROC) load(userptr, "glIsTexture"); + glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load(userptr, "glPolygonOffset"); + glad_glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC) load(userptr, "glTexSubImage1D"); + glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load(userptr, "glTexSubImage2D"); +} +static void glad_gl_load_GL_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_2) return; + glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load(userptr, "glCopyTexSubImage3D"); + glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load(userptr, "glDrawRangeElements"); + glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC) load(userptr, "glTexImage3D"); + glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load(userptr, "glTexSubImage3D"); +} +static void glad_gl_load_GL_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_3) return; + glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC) load(userptr, "glActiveTexture"); + glad_glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC) load(userptr, "glCompressedTexImage1D"); + glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load(userptr, "glCompressedTexImage2D"); + glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load(userptr, "glCompressedTexImage3D"); + glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) load(userptr, "glCompressedTexSubImage1D"); + glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load(userptr, "glCompressedTexSubImage2D"); + glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load(userptr, "glCompressedTexSubImage3D"); + glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC) load(userptr, "glGetCompressedTexImage"); + glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load(userptr, "glSampleCoverage"); +} +static void glad_gl_load_GL_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_4) return; + glad_glBlendColor = (PFNGLBLENDCOLORPROC) load(userptr, "glBlendColor"); + glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC) load(userptr, "glBlendEquation"); + glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load(userptr, "glBlendFuncSeparate"); + glad_glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC) load(userptr, "glMultiDrawArrays"); + glad_glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC) load(userptr, "glMultiDrawElements"); + glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC) load(userptr, "glPointParameterf"); + glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC) load(userptr, "glPointParameterfv"); + glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC) load(userptr, "glPointParameteri"); + glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC) load(userptr, "glPointParameteriv"); +} +static void glad_gl_load_GL_VERSION_1_5( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_1_5) return; + glad_glBeginQuery = (PFNGLBEGINQUERYPROC) load(userptr, "glBeginQuery"); + glad_glBindBuffer = (PFNGLBINDBUFFERPROC) load(userptr, "glBindBuffer"); + glad_glBufferData = (PFNGLBUFFERDATAPROC) load(userptr, "glBufferData"); + glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load(userptr, "glBufferSubData"); + glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load(userptr, "glDeleteBuffers"); + glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC) load(userptr, "glDeleteQueries"); + glad_glEndQuery = (PFNGLENDQUERYPROC) load(userptr, "glEndQuery"); + glad_glGenBuffers = (PFNGLGENBUFFERSPROC) load(userptr, "glGenBuffers"); + glad_glGenQueries = (PFNGLGENQUERIESPROC) load(userptr, "glGenQueries"); + glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load(userptr, "glGetBufferParameteriv"); + glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load(userptr, "glGetBufferPointerv"); + glad_glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC) load(userptr, "glGetBufferSubData"); + glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC) load(userptr, "glGetQueryObjectiv"); + glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load(userptr, "glGetQueryObjectuiv"); + glad_glGetQueryiv = (PFNGLGETQUERYIVPROC) load(userptr, "glGetQueryiv"); + glad_glIsBuffer = (PFNGLISBUFFERPROC) load(userptr, "glIsBuffer"); + glad_glIsQuery = (PFNGLISQUERYPROC) load(userptr, "glIsQuery"); + glad_glMapBuffer = (PFNGLMAPBUFFERPROC) load(userptr, "glMapBuffer"); + glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) load(userptr, "glUnmapBuffer"); +} +static void glad_gl_load_GL_VERSION_2_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_2_0) return; + glad_glAttachShader = (PFNGLATTACHSHADERPROC) load(userptr, "glAttachShader"); + glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load(userptr, "glBindAttribLocation"); + glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load(userptr, "glBlendEquationSeparate"); + glad_glCompileShader = (PFNGLCOMPILESHADERPROC) load(userptr, "glCompileShader"); + glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC) load(userptr, "glCreateProgram"); + glad_glCreateShader = (PFNGLCREATESHADERPROC) load(userptr, "glCreateShader"); + glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC) load(userptr, "glDeleteProgram"); + glad_glDeleteShader = (PFNGLDELETESHADERPROC) load(userptr, "glDeleteShader"); + glad_glDetachShader = (PFNGLDETACHSHADERPROC) load(userptr, "glDetachShader"); + glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load(userptr, "glDisableVertexAttribArray"); + glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC) load(userptr, "glDrawBuffers"); + glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load(userptr, "glEnableVertexAttribArray"); + glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load(userptr, "glGetActiveAttrib"); + glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load(userptr, "glGetActiveUniform"); + glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load(userptr, "glGetAttachedShaders"); + glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load(userptr, "glGetAttribLocation"); + glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load(userptr, "glGetProgramInfoLog"); + glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC) load(userptr, "glGetProgramiv"); + glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load(userptr, "glGetShaderInfoLog"); + glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC) load(userptr, "glGetShaderSource"); + glad_glGetShaderiv = (PFNGLGETSHADERIVPROC) load(userptr, "glGetShaderiv"); + glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load(userptr, "glGetUniformLocation"); + glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC) load(userptr, "glGetUniformfv"); + glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC) load(userptr, "glGetUniformiv"); + glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load(userptr, "glGetVertexAttribPointerv"); + glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC) load(userptr, "glGetVertexAttribdv"); + glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load(userptr, "glGetVertexAttribfv"); + glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load(userptr, "glGetVertexAttribiv"); + glad_glIsProgram = (PFNGLISPROGRAMPROC) load(userptr, "glIsProgram"); + glad_glIsShader = (PFNGLISSHADERPROC) load(userptr, "glIsShader"); + glad_glLinkProgram = (PFNGLLINKPROGRAMPROC) load(userptr, "glLinkProgram"); + glad_glShaderSource = (PFNGLSHADERSOURCEPROC) load(userptr, "glShaderSource"); + glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load(userptr, "glStencilFuncSeparate"); + glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load(userptr, "glStencilMaskSeparate"); + glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load(userptr, "glStencilOpSeparate"); + glad_glUniform1f = (PFNGLUNIFORM1FPROC) load(userptr, "glUniform1f"); + glad_glUniform1fv = (PFNGLUNIFORM1FVPROC) load(userptr, "glUniform1fv"); + glad_glUniform1i = (PFNGLUNIFORM1IPROC) load(userptr, "glUniform1i"); + glad_glUniform1iv = (PFNGLUNIFORM1IVPROC) load(userptr, "glUniform1iv"); + glad_glUniform2f = (PFNGLUNIFORM2FPROC) load(userptr, "glUniform2f"); + glad_glUniform2fv = (PFNGLUNIFORM2FVPROC) load(userptr, "glUniform2fv"); + glad_glUniform2i = (PFNGLUNIFORM2IPROC) load(userptr, "glUniform2i"); + glad_glUniform2iv = (PFNGLUNIFORM2IVPROC) load(userptr, "glUniform2iv"); + glad_glUniform3f = (PFNGLUNIFORM3FPROC) load(userptr, "glUniform3f"); + glad_glUniform3fv = (PFNGLUNIFORM3FVPROC) load(userptr, "glUniform3fv"); + glad_glUniform3i = (PFNGLUNIFORM3IPROC) load(userptr, "glUniform3i"); + glad_glUniform3iv = (PFNGLUNIFORM3IVPROC) load(userptr, "glUniform3iv"); + glad_glUniform4f = (PFNGLUNIFORM4FPROC) load(userptr, "glUniform4f"); + glad_glUniform4fv = (PFNGLUNIFORM4FVPROC) load(userptr, "glUniform4fv"); + glad_glUniform4i = (PFNGLUNIFORM4IPROC) load(userptr, "glUniform4i"); + glad_glUniform4iv = (PFNGLUNIFORM4IVPROC) load(userptr, "glUniform4iv"); + glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load(userptr, "glUniformMatrix2fv"); + glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load(userptr, "glUniformMatrix3fv"); + glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load(userptr, "glUniformMatrix4fv"); + glad_glUseProgram = (PFNGLUSEPROGRAMPROC) load(userptr, "glUseProgram"); + glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load(userptr, "glValidateProgram"); + glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC) load(userptr, "glVertexAttrib1d"); + glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC) load(userptr, "glVertexAttrib1dv"); + glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load(userptr, "glVertexAttrib1f"); + glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load(userptr, "glVertexAttrib1fv"); + glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC) load(userptr, "glVertexAttrib1s"); + glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC) load(userptr, "glVertexAttrib1sv"); + glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC) load(userptr, "glVertexAttrib2d"); + glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC) load(userptr, "glVertexAttrib2dv"); + glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load(userptr, "glVertexAttrib2f"); + glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load(userptr, "glVertexAttrib2fv"); + glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC) load(userptr, "glVertexAttrib2s"); + glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC) load(userptr, "glVertexAttrib2sv"); + glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC) load(userptr, "glVertexAttrib3d"); + glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC) load(userptr, "glVertexAttrib3dv"); + glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load(userptr, "glVertexAttrib3f"); + glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load(userptr, "glVertexAttrib3fv"); + glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC) load(userptr, "glVertexAttrib3s"); + glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC) load(userptr, "glVertexAttrib3sv"); + glad_glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC) load(userptr, "glVertexAttrib4Nbv"); + glad_glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC) load(userptr, "glVertexAttrib4Niv"); + glad_glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC) load(userptr, "glVertexAttrib4Nsv"); + glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC) load(userptr, "glVertexAttrib4Nub"); + glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC) load(userptr, "glVertexAttrib4Nubv"); + glad_glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC) load(userptr, "glVertexAttrib4Nuiv"); + glad_glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC) load(userptr, "glVertexAttrib4Nusv"); + glad_glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC) load(userptr, "glVertexAttrib4bv"); + glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC) load(userptr, "glVertexAttrib4d"); + glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC) load(userptr, "glVertexAttrib4dv"); + glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load(userptr, "glVertexAttrib4f"); + glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load(userptr, "glVertexAttrib4fv"); + glad_glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC) load(userptr, "glVertexAttrib4iv"); + glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC) load(userptr, "glVertexAttrib4s"); + glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC) load(userptr, "glVertexAttrib4sv"); + glad_glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC) load(userptr, "glVertexAttrib4ubv"); + glad_glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC) load(userptr, "glVertexAttrib4uiv"); + glad_glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC) load(userptr, "glVertexAttrib4usv"); + glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load(userptr, "glVertexAttribPointer"); +} +static void glad_gl_load_GL_VERSION_2_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_2_1) return; + glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load(userptr, "glUniformMatrix2x3fv"); + glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load(userptr, "glUniformMatrix2x4fv"); + glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load(userptr, "glUniformMatrix3x2fv"); + glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load(userptr, "glUniformMatrix3x4fv"); + glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load(userptr, "glUniformMatrix4x2fv"); + glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load(userptr, "glUniformMatrix4x3fv"); +} +static void glad_gl_load_GL_VERSION_3_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_3_0) return; + glad_glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC) load(userptr, "glBeginConditionalRender"); + glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load(userptr, "glBeginTransformFeedback"); + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); + glad_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC) load(userptr, "glBindFragDataLocation"); + glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer"); + glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer"); + glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load(userptr, "glBindVertexArray"); + glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load(userptr, "glBlitFramebuffer"); + glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus"); + glad_glClampColor = (PFNGLCLAMPCOLORPROC) load(userptr, "glClampColor"); + glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load(userptr, "glClearBufferfi"); + glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load(userptr, "glClearBufferfv"); + glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load(userptr, "glClearBufferiv"); + glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load(userptr, "glClearBufferuiv"); + glad_glColorMaski = (PFNGLCOLORMASKIPROC) load(userptr, "glColorMaski"); + glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers"); + glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers"); + glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load(userptr, "glDeleteVertexArrays"); + glad_glDisablei = (PFNGLDISABLEIPROC) load(userptr, "glDisablei"); + glad_glEnablei = (PFNGLENABLEIPROC) load(userptr, "glEnablei"); + glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC) load(userptr, "glEndConditionalRender"); + glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load(userptr, "glEndTransformFeedback"); + glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load(userptr, "glFlushMappedBufferRange"); + glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer"); + glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) load(userptr, "glFramebufferTexture1D"); + glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D"); + glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) load(userptr, "glFramebufferTexture3D"); + glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glFramebufferTextureLayer"); + glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers"); + glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers"); + glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load(userptr, "glGenVertexArrays"); + glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap"); + glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC) load(userptr, "glGetBooleani_v"); + glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load(userptr, "glGetFragDataLocation"); + glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); + glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv"); + glad_glGetStringi = (PFNGLGETSTRINGIPROC) load(userptr, "glGetStringi"); + glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC) load(userptr, "glGetTexParameterIiv"); + glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC) load(userptr, "glGetTexParameterIuiv"); + glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load(userptr, "glGetTransformFeedbackVarying"); + glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load(userptr, "glGetUniformuiv"); + glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load(userptr, "glGetVertexAttribIiv"); + glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load(userptr, "glGetVertexAttribIuiv"); + glad_glIsEnabledi = (PFNGLISENABLEDIPROC) load(userptr, "glIsEnabledi"); + glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer"); + glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer"); + glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC) load(userptr, "glIsVertexArray"); + glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load(userptr, "glMapBufferRange"); + glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage"); + glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glRenderbufferStorageMultisample"); + glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC) load(userptr, "glTexParameterIiv"); + glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC) load(userptr, "glTexParameterIuiv"); + glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load(userptr, "glTransformFeedbackVaryings"); + glad_glUniform1ui = (PFNGLUNIFORM1UIPROC) load(userptr, "glUniform1ui"); + glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC) load(userptr, "glUniform1uiv"); + glad_glUniform2ui = (PFNGLUNIFORM2UIPROC) load(userptr, "glUniform2ui"); + glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC) load(userptr, "glUniform2uiv"); + glad_glUniform3ui = (PFNGLUNIFORM3UIPROC) load(userptr, "glUniform3ui"); + glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC) load(userptr, "glUniform3uiv"); + glad_glUniform4ui = (PFNGLUNIFORM4UIPROC) load(userptr, "glUniform4ui"); + glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC) load(userptr, "glUniform4uiv"); + glad_glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC) load(userptr, "glVertexAttribI1i"); + glad_glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC) load(userptr, "glVertexAttribI1iv"); + glad_glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC) load(userptr, "glVertexAttribI1ui"); + glad_glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC) load(userptr, "glVertexAttribI1uiv"); + glad_glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC) load(userptr, "glVertexAttribI2i"); + glad_glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC) load(userptr, "glVertexAttribI2iv"); + glad_glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC) load(userptr, "glVertexAttribI2ui"); + glad_glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC) load(userptr, "glVertexAttribI2uiv"); + glad_glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC) load(userptr, "glVertexAttribI3i"); + glad_glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC) load(userptr, "glVertexAttribI3iv"); + glad_glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC) load(userptr, "glVertexAttribI3ui"); + glad_glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC) load(userptr, "glVertexAttribI3uiv"); + glad_glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC) load(userptr, "glVertexAttribI4bv"); + glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load(userptr, "glVertexAttribI4i"); + glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load(userptr, "glVertexAttribI4iv"); + glad_glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC) load(userptr, "glVertexAttribI4sv"); + glad_glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC) load(userptr, "glVertexAttribI4ubv"); + glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load(userptr, "glVertexAttribI4ui"); + glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load(userptr, "glVertexAttribI4uiv"); + glad_glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC) load(userptr, "glVertexAttribI4usv"); + glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load(userptr, "glVertexAttribIPointer"); +} +static void glad_gl_load_GL_VERSION_3_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_3_1) return; + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); + glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) load(userptr, "glCopyBufferSubData"); + glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) load(userptr, "glDrawArraysInstanced"); + glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) load(userptr, "glDrawElementsInstanced"); + glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) load(userptr, "glGetActiveUniformBlockName"); + glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) load(userptr, "glGetActiveUniformBlockiv"); + glad_glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC) load(userptr, "glGetActiveUniformName"); + glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) load(userptr, "glGetActiveUniformsiv"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); + glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) load(userptr, "glGetUniformBlockIndex"); + glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) load(userptr, "glGetUniformIndices"); + glad_glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC) load(userptr, "glPrimitiveRestartIndex"); + glad_glTexBuffer = (PFNGLTEXBUFFERPROC) load(userptr, "glTexBuffer"); + glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) load(userptr, "glUniformBlockBinding"); +} +static void glad_gl_load_GL_VERSION_3_2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_3_2) return; + glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load(userptr, "glClientWaitSync"); + glad_glDeleteSync = (PFNGLDELETESYNCPROC) load(userptr, "glDeleteSync"); + glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glDrawElementsBaseVertex"); + glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) load(userptr, "glDrawElementsInstancedBaseVertex"); + glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) load(userptr, "glDrawRangeElementsBaseVertex"); + glad_glFenceSync = (PFNGLFENCESYNCPROC) load(userptr, "glFenceSync"); + glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC) load(userptr, "glFramebufferTexture"); + glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) load(userptr, "glGetBufferParameteri64v"); + glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) load(userptr, "glGetInteger64i_v"); + glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC) load(userptr, "glGetInteger64v"); + glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) load(userptr, "glGetMultisamplefv"); + glad_glGetSynciv = (PFNGLGETSYNCIVPROC) load(userptr, "glGetSynciv"); + glad_glIsSync = (PFNGLISSYNCPROC) load(userptr, "glIsSync"); + glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glMultiDrawElementsBaseVertex"); + glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC) load(userptr, "glProvokingVertex"); + glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC) load(userptr, "glSampleMaski"); + glad_glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) load(userptr, "glTexImage2DMultisample"); + glad_glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) load(userptr, "glTexImage3DMultisample"); + glad_glWaitSync = (PFNGLWAITSYNCPROC) load(userptr, "glWaitSync"); +} +static void glad_gl_load_GL_VERSION_3_3( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_3_3) return; + glad_glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) load(userptr, "glBindFragDataLocationIndexed"); + glad_glBindSampler = (PFNGLBINDSAMPLERPROC) load(userptr, "glBindSampler"); + glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) load(userptr, "glDeleteSamplers"); + glad_glGenSamplers = (PFNGLGENSAMPLERSPROC) load(userptr, "glGenSamplers"); + glad_glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC) load(userptr, "glGetFragDataIndex"); + glad_glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) load(userptr, "glGetQueryObjecti64v"); + glad_glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) load(userptr, "glGetQueryObjectui64v"); + glad_glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC) load(userptr, "glGetSamplerParameterIiv"); + glad_glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC) load(userptr, "glGetSamplerParameterIuiv"); + glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load(userptr, "glGetSamplerParameterfv"); + glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load(userptr, "glGetSamplerParameteriv"); + glad_glIsSampler = (PFNGLISSAMPLERPROC) load(userptr, "glIsSampler"); + glad_glQueryCounter = (PFNGLQUERYCOUNTERPROC) load(userptr, "glQueryCounter"); + glad_glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC) load(userptr, "glSamplerParameterIiv"); + glad_glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC) load(userptr, "glSamplerParameterIuiv"); + glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load(userptr, "glSamplerParameterf"); + glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load(userptr, "glSamplerParameterfv"); + glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load(userptr, "glSamplerParameteri"); + glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load(userptr, "glSamplerParameteriv"); + glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) load(userptr, "glVertexAttribDivisor"); + glad_glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC) load(userptr, "glVertexAttribP1ui"); + glad_glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC) load(userptr, "glVertexAttribP1uiv"); + glad_glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC) load(userptr, "glVertexAttribP2ui"); + glad_glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC) load(userptr, "glVertexAttribP2uiv"); + glad_glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC) load(userptr, "glVertexAttribP3ui"); + glad_glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC) load(userptr, "glVertexAttribP3uiv"); + glad_glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC) load(userptr, "glVertexAttribP4ui"); + glad_glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC) load(userptr, "glVertexAttribP4uiv"); +} +static void glad_gl_load_GL_VERSION_4_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_4_0) return; + glad_glBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC) load(userptr, "glBeginQueryIndexed"); + glad_glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) load(userptr, "glBindTransformFeedback"); + glad_glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC) load(userptr, "glBlendEquationSeparatei"); + glad_glBlendEquationi = (PFNGLBLENDEQUATIONIPROC) load(userptr, "glBlendEquationi"); + glad_glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC) load(userptr, "glBlendFuncSeparatei"); + glad_glBlendFunci = (PFNGLBLENDFUNCIPROC) load(userptr, "glBlendFunci"); + glad_glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) load(userptr, "glDeleteTransformFeedbacks"); + glad_glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC) load(userptr, "glDrawArraysIndirect"); + glad_glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC) load(userptr, "glDrawElementsIndirect"); + glad_glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC) load(userptr, "glDrawTransformFeedback"); + glad_glDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) load(userptr, "glDrawTransformFeedbackStream"); + glad_glEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC) load(userptr, "glEndQueryIndexed"); + glad_glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) load(userptr, "glGenTransformFeedbacks"); + glad_glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC) load(userptr, "glGetActiveSubroutineName"); + glad_glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) load(userptr, "glGetActiveSubroutineUniformName"); + glad_glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) load(userptr, "glGetActiveSubroutineUniformiv"); + glad_glGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC) load(userptr, "glGetProgramStageiv"); + glad_glGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC) load(userptr, "glGetQueryIndexediv"); + glad_glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC) load(userptr, "glGetSubroutineIndex"); + glad_glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) load(userptr, "glGetSubroutineUniformLocation"); + glad_glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC) load(userptr, "glGetUniformSubroutineuiv"); + glad_glGetUniformdv = (PFNGLGETUNIFORMDVPROC) load(userptr, "glGetUniformdv"); + glad_glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) load(userptr, "glIsTransformFeedback"); + glad_glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC) load(userptr, "glMinSampleShading"); + glad_glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC) load(userptr, "glPatchParameterfv"); + glad_glPatchParameteri = (PFNGLPATCHPARAMETERIPROC) load(userptr, "glPatchParameteri"); + glad_glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) load(userptr, "glPauseTransformFeedback"); + glad_glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) load(userptr, "glResumeTransformFeedback"); + glad_glUniform1d = (PFNGLUNIFORM1DPROC) load(userptr, "glUniform1d"); + glad_glUniform1dv = (PFNGLUNIFORM1DVPROC) load(userptr, "glUniform1dv"); + glad_glUniform2d = (PFNGLUNIFORM2DPROC) load(userptr, "glUniform2d"); + glad_glUniform2dv = (PFNGLUNIFORM2DVPROC) load(userptr, "glUniform2dv"); + glad_glUniform3d = (PFNGLUNIFORM3DPROC) load(userptr, "glUniform3d"); + glad_glUniform3dv = (PFNGLUNIFORM3DVPROC) load(userptr, "glUniform3dv"); + glad_glUniform4d = (PFNGLUNIFORM4DPROC) load(userptr, "glUniform4d"); + glad_glUniform4dv = (PFNGLUNIFORM4DVPROC) load(userptr, "glUniform4dv"); + glad_glUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC) load(userptr, "glUniformMatrix2dv"); + glad_glUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC) load(userptr, "glUniformMatrix2x3dv"); + glad_glUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC) load(userptr, "glUniformMatrix2x4dv"); + glad_glUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC) load(userptr, "glUniformMatrix3dv"); + glad_glUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC) load(userptr, "glUniformMatrix3x2dv"); + glad_glUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC) load(userptr, "glUniformMatrix3x4dv"); + glad_glUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC) load(userptr, "glUniformMatrix4dv"); + glad_glUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC) load(userptr, "glUniformMatrix4x2dv"); + glad_glUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC) load(userptr, "glUniformMatrix4x3dv"); + glad_glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC) load(userptr, "glUniformSubroutinesuiv"); +} +static void glad_gl_load_GL_VERSION_4_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_4_1) return; + glad_glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC) load(userptr, "glActiveShaderProgram"); + glad_glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC) load(userptr, "glBindProgramPipeline"); + glad_glClearDepthf = (PFNGLCLEARDEPTHFPROC) load(userptr, "glClearDepthf"); + glad_glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC) load(userptr, "glCreateShaderProgramv"); + glad_glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC) load(userptr, "glDeleteProgramPipelines"); + glad_glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC) load(userptr, "glDepthRangeArrayv"); + glad_glDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC) load(userptr, "glDepthRangeIndexed"); + glad_glDepthRangef = (PFNGLDEPTHRANGEFPROC) load(userptr, "glDepthRangef"); + glad_glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC) load(userptr, "glGenProgramPipelines"); + glad_glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC) load(userptr, "glGetDoublei_v"); + glad_glGetFloati_v = (PFNGLGETFLOATI_VPROC) load(userptr, "glGetFloati_v"); + glad_glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) load(userptr, "glGetProgramBinary"); + glad_glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC) load(userptr, "glGetProgramPipelineInfoLog"); + glad_glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC) load(userptr, "glGetProgramPipelineiv"); + glad_glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) load(userptr, "glGetShaderPrecisionFormat"); + glad_glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC) load(userptr, "glGetVertexAttribLdv"); + glad_glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC) load(userptr, "glIsProgramPipeline"); + glad_glProgramBinary = (PFNGLPROGRAMBINARYPROC) load(userptr, "glProgramBinary"); + glad_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) load(userptr, "glProgramParameteri"); + glad_glProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC) load(userptr, "glProgramUniform1d"); + glad_glProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC) load(userptr, "glProgramUniform1dv"); + glad_glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC) load(userptr, "glProgramUniform1f"); + glad_glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC) load(userptr, "glProgramUniform1fv"); + glad_glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC) load(userptr, "glProgramUniform1i"); + glad_glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC) load(userptr, "glProgramUniform1iv"); + glad_glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC) load(userptr, "glProgramUniform1ui"); + glad_glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC) load(userptr, "glProgramUniform1uiv"); + glad_glProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC) load(userptr, "glProgramUniform2d"); + glad_glProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC) load(userptr, "glProgramUniform2dv"); + glad_glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC) load(userptr, "glProgramUniform2f"); + glad_glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC) load(userptr, "glProgramUniform2fv"); + glad_glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC) load(userptr, "glProgramUniform2i"); + glad_glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC) load(userptr, "glProgramUniform2iv"); + glad_glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC) load(userptr, "glProgramUniform2ui"); + glad_glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC) load(userptr, "glProgramUniform2uiv"); + glad_glProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC) load(userptr, "glProgramUniform3d"); + glad_glProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC) load(userptr, "glProgramUniform3dv"); + glad_glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC) load(userptr, "glProgramUniform3f"); + glad_glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC) load(userptr, "glProgramUniform3fv"); + glad_glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC) load(userptr, "glProgramUniform3i"); + glad_glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC) load(userptr, "glProgramUniform3iv"); + glad_glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC) load(userptr, "glProgramUniform3ui"); + glad_glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC) load(userptr, "glProgramUniform3uiv"); + glad_glProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC) load(userptr, "glProgramUniform4d"); + glad_glProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC) load(userptr, "glProgramUniform4dv"); + glad_glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC) load(userptr, "glProgramUniform4f"); + glad_glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC) load(userptr, "glProgramUniform4fv"); + glad_glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC) load(userptr, "glProgramUniform4i"); + glad_glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC) load(userptr, "glProgramUniform4iv"); + glad_glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC) load(userptr, "glProgramUniform4ui"); + glad_glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC) load(userptr, "glProgramUniform4uiv"); + glad_glProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC) load(userptr, "glProgramUniformMatrix2dv"); + glad_glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC) load(userptr, "glProgramUniformMatrix2fv"); + glad_glProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) load(userptr, "glProgramUniformMatrix2x3dv"); + glad_glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) load(userptr, "glProgramUniformMatrix2x3fv"); + glad_glProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) load(userptr, "glProgramUniformMatrix2x4dv"); + glad_glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) load(userptr, "glProgramUniformMatrix2x4fv"); + glad_glProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC) load(userptr, "glProgramUniformMatrix3dv"); + glad_glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC) load(userptr, "glProgramUniformMatrix3fv"); + glad_glProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) load(userptr, "glProgramUniformMatrix3x2dv"); + glad_glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) load(userptr, "glProgramUniformMatrix3x2fv"); + glad_glProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) load(userptr, "glProgramUniformMatrix3x4dv"); + glad_glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) load(userptr, "glProgramUniformMatrix3x4fv"); + glad_glProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC) load(userptr, "glProgramUniformMatrix4dv"); + glad_glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC) load(userptr, "glProgramUniformMatrix4fv"); + glad_glProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) load(userptr, "glProgramUniformMatrix4x2dv"); + glad_glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) load(userptr, "glProgramUniformMatrix4x2fv"); + glad_glProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) load(userptr, "glProgramUniformMatrix4x3dv"); + glad_glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) load(userptr, "glProgramUniformMatrix4x3fv"); + glad_glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) load(userptr, "glReleaseShaderCompiler"); + glad_glScissorArrayv = (PFNGLSCISSORARRAYVPROC) load(userptr, "glScissorArrayv"); + glad_glScissorIndexed = (PFNGLSCISSORINDEXEDPROC) load(userptr, "glScissorIndexed"); + glad_glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC) load(userptr, "glScissorIndexedv"); + glad_glShaderBinary = (PFNGLSHADERBINARYPROC) load(userptr, "glShaderBinary"); + glad_glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC) load(userptr, "glUseProgramStages"); + glad_glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC) load(userptr, "glValidateProgramPipeline"); + glad_glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC) load(userptr, "glVertexAttribL1d"); + glad_glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC) load(userptr, "glVertexAttribL1dv"); + glad_glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC) load(userptr, "glVertexAttribL2d"); + glad_glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC) load(userptr, "glVertexAttribL2dv"); + glad_glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC) load(userptr, "glVertexAttribL3d"); + glad_glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC) load(userptr, "glVertexAttribL3dv"); + glad_glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC) load(userptr, "glVertexAttribL4d"); + glad_glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC) load(userptr, "glVertexAttribL4dv"); + glad_glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC) load(userptr, "glVertexAttribLPointer"); + glad_glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC) load(userptr, "glViewportArrayv"); + glad_glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC) load(userptr, "glViewportIndexedf"); + glad_glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC) load(userptr, "glViewportIndexedfv"); +} +static void glad_gl_load_GL_VERSION_4_2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_4_2) return; + glad_glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC) load(userptr, "glBindImageTexture"); + glad_glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) load(userptr, "glDrawArraysInstancedBaseInstance"); + glad_glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) load(userptr, "glDrawElementsInstancedBaseInstance"); + glad_glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) load(userptr, "glDrawElementsInstancedBaseVertexBaseInstance"); + glad_glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) load(userptr, "glDrawTransformFeedbackInstanced"); + glad_glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) load(userptr, "glDrawTransformFeedbackStreamInstanced"); + glad_glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) load(userptr, "glGetActiveAtomicCounterBufferiv"); + glad_glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) load(userptr, "glGetInternalformativ"); + glad_glMemoryBarrier = (PFNGLMEMORYBARRIERPROC) load(userptr, "glMemoryBarrier"); + glad_glTexStorage1D = (PFNGLTEXSTORAGE1DPROC) load(userptr, "glTexStorage1D"); + glad_glTexStorage2D = (PFNGLTEXSTORAGE2DPROC) load(userptr, "glTexStorage2D"); + glad_glTexStorage3D = (PFNGLTEXSTORAGE3DPROC) load(userptr, "glTexStorage3D"); +} +static void glad_gl_load_GL_VERSION_4_3( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_4_3) return; + glad_glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC) load(userptr, "glBindVertexBuffer"); + glad_glClearBufferData = (PFNGLCLEARBUFFERDATAPROC) load(userptr, "glClearBufferData"); + glad_glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC) load(userptr, "glClearBufferSubData"); + glad_glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC) load(userptr, "glCopyImageSubData"); + glad_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC) load(userptr, "glDebugMessageCallback"); + glad_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC) load(userptr, "glDebugMessageControl"); + glad_glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC) load(userptr, "glDebugMessageInsert"); + glad_glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC) load(userptr, "glDispatchCompute"); + glad_glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC) load(userptr, "glDispatchComputeIndirect"); + glad_glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC) load(userptr, "glFramebufferParameteri"); + glad_glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC) load(userptr, "glGetDebugMessageLog"); + glad_glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC) load(userptr, "glGetFramebufferParameteriv"); + glad_glGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC) load(userptr, "glGetInternalformati64v"); + glad_glGetObjectLabel = (PFNGLGETOBJECTLABELPROC) load(userptr, "glGetObjectLabel"); + glad_glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC) load(userptr, "glGetObjectPtrLabel"); + glad_glGetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv"); + glad_glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC) load(userptr, "glGetProgramInterfaceiv"); + glad_glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC) load(userptr, "glGetProgramResourceIndex"); + glad_glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC) load(userptr, "glGetProgramResourceLocation"); + glad_glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) load(userptr, "glGetProgramResourceLocationIndex"); + glad_glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC) load(userptr, "glGetProgramResourceName"); + glad_glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC) load(userptr, "glGetProgramResourceiv"); + glad_glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC) load(userptr, "glInvalidateBufferData"); + glad_glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC) load(userptr, "glInvalidateBufferSubData"); + glad_glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) load(userptr, "glInvalidateFramebuffer"); + glad_glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) load(userptr, "glInvalidateSubFramebuffer"); + glad_glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC) load(userptr, "glInvalidateTexImage"); + glad_glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC) load(userptr, "glInvalidateTexSubImage"); + glad_glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC) load(userptr, "glMultiDrawArraysIndirect"); + glad_glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC) load(userptr, "glMultiDrawElementsIndirect"); + glad_glObjectLabel = (PFNGLOBJECTLABELPROC) load(userptr, "glObjectLabel"); + glad_glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC) load(userptr, "glObjectPtrLabel"); + glad_glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC) load(userptr, "glPopDebugGroup"); + glad_glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC) load(userptr, "glPushDebugGroup"); + glad_glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC) load(userptr, "glShaderStorageBlockBinding"); + glad_glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC) load(userptr, "glTexBufferRange"); + glad_glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC) load(userptr, "glTexStorage2DMultisample"); + glad_glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC) load(userptr, "glTexStorage3DMultisample"); + glad_glTextureView = (PFNGLTEXTUREVIEWPROC) load(userptr, "glTextureView"); + glad_glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC) load(userptr, "glVertexAttribBinding"); + glad_glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC) load(userptr, "glVertexAttribFormat"); + glad_glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC) load(userptr, "glVertexAttribIFormat"); + glad_glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC) load(userptr, "glVertexAttribLFormat"); + glad_glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC) load(userptr, "glVertexBindingDivisor"); +} +static void glad_gl_load_GL_VERSION_4_4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_4_4) return; + glad_glBindBuffersBase = (PFNGLBINDBUFFERSBASEPROC) load(userptr, "glBindBuffersBase"); + glad_glBindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC) load(userptr, "glBindBuffersRange"); + glad_glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC) load(userptr, "glBindImageTextures"); + glad_glBindSamplers = (PFNGLBINDSAMPLERSPROC) load(userptr, "glBindSamplers"); + glad_glBindTextures = (PFNGLBINDTEXTURESPROC) load(userptr, "glBindTextures"); + glad_glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC) load(userptr, "glBindVertexBuffers"); + glad_glBufferStorage = (PFNGLBUFFERSTORAGEPROC) load(userptr, "glBufferStorage"); + glad_glClearTexImage = (PFNGLCLEARTEXIMAGEPROC) load(userptr, "glClearTexImage"); + glad_glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC) load(userptr, "glClearTexSubImage"); +} +static void glad_gl_load_GL_VERSION_4_5( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_4_5) return; + glad_glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC) load(userptr, "glBindTextureUnit"); + glad_glBlitNamedFramebuffer = (PFNGLBLITNAMEDFRAMEBUFFERPROC) load(userptr, "glBlitNamedFramebuffer"); + glad_glCheckNamedFramebufferStatus = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckNamedFramebufferStatus"); + glad_glClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATAPROC) load(userptr, "glClearNamedBufferData"); + glad_glClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATAPROC) load(userptr, "glClearNamedBufferSubData"); + glad_glClearNamedFramebufferfi = (PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) load(userptr, "glClearNamedFramebufferfi"); + glad_glClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) load(userptr, "glClearNamedFramebufferfv"); + glad_glClearNamedFramebufferiv = (PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) load(userptr, "glClearNamedFramebufferiv"); + glad_glClearNamedFramebufferuiv = (PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) load(userptr, "glClearNamedFramebufferuiv"); + glad_glClipControl = (PFNGLCLIPCONTROLPROC) load(userptr, "glClipControl"); + glad_glCompressedTextureSubImage1D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) load(userptr, "glCompressedTextureSubImage1D"); + glad_glCompressedTextureSubImage2D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) load(userptr, "glCompressedTextureSubImage2D"); + glad_glCompressedTextureSubImage3D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) load(userptr, "glCompressedTextureSubImage3D"); + glad_glCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATAPROC) load(userptr, "glCopyNamedBufferSubData"); + glad_glCopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC) load(userptr, "glCopyTextureSubImage1D"); + glad_glCopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC) load(userptr, "glCopyTextureSubImage2D"); + glad_glCopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC) load(userptr, "glCopyTextureSubImage3D"); + glad_glCreateBuffers = (PFNGLCREATEBUFFERSPROC) load(userptr, "glCreateBuffers"); + glad_glCreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC) load(userptr, "glCreateFramebuffers"); + glad_glCreateProgramPipelines = (PFNGLCREATEPROGRAMPIPELINESPROC) load(userptr, "glCreateProgramPipelines"); + glad_glCreateQueries = (PFNGLCREATEQUERIESPROC) load(userptr, "glCreateQueries"); + glad_glCreateRenderbuffers = (PFNGLCREATERENDERBUFFERSPROC) load(userptr, "glCreateRenderbuffers"); + glad_glCreateSamplers = (PFNGLCREATESAMPLERSPROC) load(userptr, "glCreateSamplers"); + glad_glCreateTextures = (PFNGLCREATETEXTURESPROC) load(userptr, "glCreateTextures"); + glad_glCreateTransformFeedbacks = (PFNGLCREATETRANSFORMFEEDBACKSPROC) load(userptr, "glCreateTransformFeedbacks"); + glad_glCreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC) load(userptr, "glCreateVertexArrays"); + glad_glDisableVertexArrayAttrib = (PFNGLDISABLEVERTEXARRAYATTRIBPROC) load(userptr, "glDisableVertexArrayAttrib"); + glad_glEnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC) load(userptr, "glEnableVertexArrayAttrib"); + glad_glFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) load(userptr, "glFlushMappedNamedBufferRange"); + glad_glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC) load(userptr, "glGenerateTextureMipmap"); + glad_glGetCompressedTextureImage = (PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) load(userptr, "glGetCompressedTextureImage"); + glad_glGetCompressedTextureSubImage = (PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) load(userptr, "glGetCompressedTextureSubImage"); + glad_glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC) load(userptr, "glGetGraphicsResetStatus"); + glad_glGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) load(userptr, "glGetNamedBufferParameteri64v"); + glad_glGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedBufferParameteriv"); + glad_glGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERVPROC) load(userptr, "glGetNamedBufferPointerv"); + glad_glGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATAPROC) load(userptr, "glGetNamedBufferSubData"); + glad_glGetNamedFramebufferAttachmentParameteriv = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetNamedFramebufferAttachmentParameteriv"); + glad_glGetNamedFramebufferParameteriv = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedFramebufferParameteriv"); + glad_glGetNamedRenderbufferParameteriv = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedRenderbufferParameteriv"); + glad_glGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECTI64VPROC) load(userptr, "glGetQueryBufferObjecti64v"); + glad_glGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECTIVPROC) load(userptr, "glGetQueryBufferObjectiv"); + glad_glGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECTUI64VPROC) load(userptr, "glGetQueryBufferObjectui64v"); + glad_glGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECTUIVPROC) load(userptr, "glGetQueryBufferObjectuiv"); + glad_glGetTextureImage = (PFNGLGETTEXTUREIMAGEPROC) load(userptr, "glGetTextureImage"); + glad_glGetTextureLevelParameterfv = (PFNGLGETTEXTURELEVELPARAMETERFVPROC) load(userptr, "glGetTextureLevelParameterfv"); + glad_glGetTextureLevelParameteriv = (PFNGLGETTEXTURELEVELPARAMETERIVPROC) load(userptr, "glGetTextureLevelParameteriv"); + glad_glGetTextureParameterIiv = (PFNGLGETTEXTUREPARAMETERIIVPROC) load(userptr, "glGetTextureParameterIiv"); + glad_glGetTextureParameterIuiv = (PFNGLGETTEXTUREPARAMETERIUIVPROC) load(userptr, "glGetTextureParameterIuiv"); + glad_glGetTextureParameterfv = (PFNGLGETTEXTUREPARAMETERFVPROC) load(userptr, "glGetTextureParameterfv"); + glad_glGetTextureParameteriv = (PFNGLGETTEXTUREPARAMETERIVPROC) load(userptr, "glGetTextureParameteriv"); + glad_glGetTextureSubImage = (PFNGLGETTEXTURESUBIMAGEPROC) load(userptr, "glGetTextureSubImage"); + glad_glGetTransformFeedbacki64_v = (PFNGLGETTRANSFORMFEEDBACKI64_VPROC) load(userptr, "glGetTransformFeedbacki64_v"); + glad_glGetTransformFeedbacki_v = (PFNGLGETTRANSFORMFEEDBACKI_VPROC) load(userptr, "glGetTransformFeedbacki_v"); + glad_glGetTransformFeedbackiv = (PFNGLGETTRANSFORMFEEDBACKIVPROC) load(userptr, "glGetTransformFeedbackiv"); + glad_glGetVertexArrayIndexed64iv = (PFNGLGETVERTEXARRAYINDEXED64IVPROC) load(userptr, "glGetVertexArrayIndexed64iv"); + glad_glGetVertexArrayIndexediv = (PFNGLGETVERTEXARRAYINDEXEDIVPROC) load(userptr, "glGetVertexArrayIndexediv"); + glad_glGetVertexArrayiv = (PFNGLGETVERTEXARRAYIVPROC) load(userptr, "glGetVertexArrayiv"); + glad_glGetnCompressedTexImage = (PFNGLGETNCOMPRESSEDTEXIMAGEPROC) load(userptr, "glGetnCompressedTexImage"); + glad_glGetnTexImage = (PFNGLGETNTEXIMAGEPROC) load(userptr, "glGetnTexImage"); + glad_glGetnUniformdv = (PFNGLGETNUNIFORMDVPROC) load(userptr, "glGetnUniformdv"); + glad_glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC) load(userptr, "glGetnUniformfv"); + glad_glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC) load(userptr, "glGetnUniformiv"); + glad_glGetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC) load(userptr, "glGetnUniformuiv"); + glad_glInvalidateNamedFramebufferData = (PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) load(userptr, "glInvalidateNamedFramebufferData"); + glad_glInvalidateNamedFramebufferSubData = (PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) load(userptr, "glInvalidateNamedFramebufferSubData"); + glad_glMapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC) load(userptr, "glMapNamedBuffer"); + glad_glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC) load(userptr, "glMapNamedBufferRange"); + glad_glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC) load(userptr, "glMemoryBarrierByRegion"); + glad_glNamedBufferData = (PFNGLNAMEDBUFFERDATAPROC) load(userptr, "glNamedBufferData"); + glad_glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC) load(userptr, "glNamedBufferStorage"); + glad_glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC) load(userptr, "glNamedBufferSubData"); + glad_glNamedFramebufferDrawBuffer = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) load(userptr, "glNamedFramebufferDrawBuffer"); + glad_glNamedFramebufferDrawBuffers = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) load(userptr, "glNamedFramebufferDrawBuffers"); + glad_glNamedFramebufferParameteri = (PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) load(userptr, "glNamedFramebufferParameteri"); + glad_glNamedFramebufferReadBuffer = (PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) load(userptr, "glNamedFramebufferReadBuffer"); + glad_glNamedFramebufferRenderbuffer = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glNamedFramebufferRenderbuffer"); + glad_glNamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) load(userptr, "glNamedFramebufferTexture"); + glad_glNamedFramebufferTextureLayer = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glNamedFramebufferTextureLayer"); + glad_glNamedRenderbufferStorage = (PFNGLNAMEDRENDERBUFFERSTORAGEPROC) load(userptr, "glNamedRenderbufferStorage"); + glad_glNamedRenderbufferStorageMultisample = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glNamedRenderbufferStorageMultisample"); + glad_glReadnPixels = (PFNGLREADNPIXELSPROC) load(userptr, "glReadnPixels"); + glad_glTextureBarrier = (PFNGLTEXTUREBARRIERPROC) load(userptr, "glTextureBarrier"); + glad_glTextureBuffer = (PFNGLTEXTUREBUFFERPROC) load(userptr, "glTextureBuffer"); + glad_glTextureBufferRange = (PFNGLTEXTUREBUFFERRANGEPROC) load(userptr, "glTextureBufferRange"); + glad_glTextureParameterIiv = (PFNGLTEXTUREPARAMETERIIVPROC) load(userptr, "glTextureParameterIiv"); + glad_glTextureParameterIuiv = (PFNGLTEXTUREPARAMETERIUIVPROC) load(userptr, "glTextureParameterIuiv"); + glad_glTextureParameterf = (PFNGLTEXTUREPARAMETERFPROC) load(userptr, "glTextureParameterf"); + glad_glTextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC) load(userptr, "glTextureParameterfv"); + glad_glTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC) load(userptr, "glTextureParameteri"); + glad_glTextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC) load(userptr, "glTextureParameteriv"); + glad_glTextureStorage1D = (PFNGLTEXTURESTORAGE1DPROC) load(userptr, "glTextureStorage1D"); + glad_glTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC) load(userptr, "glTextureStorage2D"); + glad_glTextureStorage2DMultisample = (PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) load(userptr, "glTextureStorage2DMultisample"); + glad_glTextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC) load(userptr, "glTextureStorage3D"); + glad_glTextureStorage3DMultisample = (PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) load(userptr, "glTextureStorage3DMultisample"); + glad_glTextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC) load(userptr, "glTextureSubImage1D"); + glad_glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC) load(userptr, "glTextureSubImage2D"); + glad_glTextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC) load(userptr, "glTextureSubImage3D"); + glad_glTransformFeedbackBufferBase = (PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) load(userptr, "glTransformFeedbackBufferBase"); + glad_glTransformFeedbackBufferRange = (PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) load(userptr, "glTransformFeedbackBufferRange"); + glad_glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC) load(userptr, "glUnmapNamedBuffer"); + glad_glVertexArrayAttribBinding = (PFNGLVERTEXARRAYATTRIBBINDINGPROC) load(userptr, "glVertexArrayAttribBinding"); + glad_glVertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC) load(userptr, "glVertexArrayAttribFormat"); + glad_glVertexArrayAttribIFormat = (PFNGLVERTEXARRAYATTRIBIFORMATPROC) load(userptr, "glVertexArrayAttribIFormat"); + glad_glVertexArrayAttribLFormat = (PFNGLVERTEXARRAYATTRIBLFORMATPROC) load(userptr, "glVertexArrayAttribLFormat"); + glad_glVertexArrayBindingDivisor = (PFNGLVERTEXARRAYBINDINGDIVISORPROC) load(userptr, "glVertexArrayBindingDivisor"); + glad_glVertexArrayElementBuffer = (PFNGLVERTEXARRAYELEMENTBUFFERPROC) load(userptr, "glVertexArrayElementBuffer"); + glad_glVertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC) load(userptr, "glVertexArrayVertexBuffer"); + glad_glVertexArrayVertexBuffers = (PFNGLVERTEXARRAYVERTEXBUFFERSPROC) load(userptr, "glVertexArrayVertexBuffers"); +} +static void glad_gl_load_GL_VERSION_4_6( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_VERSION_4_6) return; + glad_glMultiDrawArraysIndirectCount = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC) load(userptr, "glMultiDrawArraysIndirectCount"); + glad_glMultiDrawElementsIndirectCount = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC) load(userptr, "glMultiDrawElementsIndirectCount"); + glad_glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC) load(userptr, "glPolygonOffsetClamp"); + glad_glSpecializeShader = (PFNGLSPECIALIZESHADERPROC) load(userptr, "glSpecializeShader"); +} + + + +static void glad_gl_free_extensions(char **exts_i) { + if (exts_i != NULL) { + unsigned int index; + for(index = 0; exts_i[index]; index++) { + free((void *) (exts_i[index])); + } + free((void *)exts_i); + exts_i = NULL; + } +} +static int glad_gl_get_extensions( const char **out_exts, char ***out_exts_i) { +#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) + if (glad_glGetStringi != NULL && glad_glGetIntegerv != NULL) { + unsigned int index = 0; + unsigned int num_exts_i = 0; + char **exts_i = NULL; + glad_glGetIntegerv(GL_NUM_EXTENSIONS, (int*) &num_exts_i); + exts_i = (char **) malloc((num_exts_i + 1) * (sizeof *exts_i)); + if (exts_i == NULL) { + return 0; + } + for(index = 0; index < num_exts_i; index++) { + const char *gl_str_tmp = (const char*) glad_glGetStringi(GL_EXTENSIONS, index); + size_t len = strlen(gl_str_tmp) + 1; + + char *local_str = (char*) malloc(len * sizeof(char)); + if(local_str == NULL) { + exts_i[index] = NULL; + glad_gl_free_extensions(exts_i); + return 0; + } + + memcpy(local_str, gl_str_tmp, len * sizeof(char)); + exts_i[index] = local_str; + } + exts_i[index] = NULL; + + *out_exts_i = exts_i; + + return 1; + } +#else + GLAD_UNUSED(out_exts_i); +#endif + if (glad_glGetString == NULL) { + return 0; + } + *out_exts = (const char *)glad_glGetString(GL_EXTENSIONS); + return 1; +} +static int glad_gl_has_extension(const char *exts, char **exts_i, const char *ext) { + if(exts_i) { + unsigned int index; + for(index = 0; exts_i[index]; index++) { + const char *e = exts_i[index]; + if(strcmp(e, ext) == 0) { + return 1; + } + } + } else { + const char *extensions; + const char *loc; + const char *terminator; + extensions = exts; + if(extensions == NULL || ext == NULL) { + return 0; + } + while(1) { + loc = strstr(extensions, ext); + if(loc == NULL) { + return 0; + } + terminator = loc + strlen(ext); + if((loc == extensions || *(loc - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0')) { + return 1; + } + extensions = terminator; + } + } + return 0; +} + +static GLADapiproc glad_gl_get_proc_from_userptr(void *userptr, const char* name) { + return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); +} + +static int glad_gl_find_extensions_gl(void) { + const char *exts = NULL; + char **exts_i = NULL; + if (!glad_gl_get_extensions(&exts, &exts_i)) return 0; + + GLAD_UNUSED(glad_gl_has_extension); + + glad_gl_free_extensions(exts_i); + + return 1; +} + +static int glad_gl_find_core_gl(void) { + int i; + const char* version; + const char* prefixes[] = { + "OpenGL ES-CM ", + "OpenGL ES-CL ", + "OpenGL ES ", + "OpenGL SC ", + NULL + }; + int major = 0; + int minor = 0; + version = (const char*) glad_glGetString(GL_VERSION); + if (!version) return 0; + for (i = 0; prefixes[i]; i++) { + const size_t length = strlen(prefixes[i]); + if (strncmp(version, prefixes[i], length) == 0) { + version += length; + break; + } + } + + GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); + + GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; + GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; + GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; + GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; + GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; + GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; + GLAD_GL_VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; + GLAD_GL_VERSION_4_0 = (major == 4 && minor >= 0) || major > 4; + GLAD_GL_VERSION_4_1 = (major == 4 && minor >= 1) || major > 4; + GLAD_GL_VERSION_4_2 = (major == 4 && minor >= 2) || major > 4; + GLAD_GL_VERSION_4_3 = (major == 4 && minor >= 3) || major > 4; + GLAD_GL_VERSION_4_4 = (major == 4 && minor >= 4) || major > 4; + GLAD_GL_VERSION_4_5 = (major == 4 && minor >= 5) || major > 4; + GLAD_GL_VERSION_4_6 = (major == 4 && minor >= 6) || major > 4; + + return GLAD_MAKE_VERSION(major, minor); +} + +int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr) { + int version; + + glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + if(glad_glGetString == NULL) return 0; + version = glad_gl_find_core_gl(); + + glad_gl_load_GL_VERSION_1_0(load, userptr); + glad_gl_load_GL_VERSION_1_1(load, userptr); + glad_gl_load_GL_VERSION_1_2(load, userptr); + glad_gl_load_GL_VERSION_1_3(load, userptr); + glad_gl_load_GL_VERSION_1_4(load, userptr); + glad_gl_load_GL_VERSION_1_5(load, userptr); + glad_gl_load_GL_VERSION_2_0(load, userptr); + glad_gl_load_GL_VERSION_2_1(load, userptr); + glad_gl_load_GL_VERSION_3_0(load, userptr); + glad_gl_load_GL_VERSION_3_1(load, userptr); + glad_gl_load_GL_VERSION_3_2(load, userptr); + glad_gl_load_GL_VERSION_3_3(load, userptr); + glad_gl_load_GL_VERSION_4_0(load, userptr); + glad_gl_load_GL_VERSION_4_1(load, userptr); + glad_gl_load_GL_VERSION_4_2(load, userptr); + glad_gl_load_GL_VERSION_4_3(load, userptr); + glad_gl_load_GL_VERSION_4_4(load, userptr); + glad_gl_load_GL_VERSION_4_5(load, userptr); + glad_gl_load_GL_VERSION_4_6(load, userptr); + + if (!glad_gl_find_extensions_gl()) return 0; + + + + return version; +} + + +int gladLoadGL( GLADloadfunc load) { + return gladLoadGLUserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +} + + + + + +#ifdef GLAD_GL + +#ifndef GLAD_LOADER_LIBRARY_C_ +#define GLAD_LOADER_LIBRARY_C_ + +#include +#include + +#if GLAD_PLATFORM_WIN32 +#include +#else +#include +#endif + + +static void* glad_get_dlopen_handle(const char *lib_names[], int length) { + void *handle = NULL; + int i; + + for (i = 0; i < length; ++i) { +#if GLAD_PLATFORM_WIN32 + #if GLAD_PLATFORM_UWP + size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR); + LPWSTR buffer = (LPWSTR) malloc(buffer_size); + if (buffer != NULL) { + int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size); + if (ret != 0) { + handle = (void*) LoadPackagedLibrary(buffer, 0); + } + free((void*) buffer); + } + #else + handle = (void*) LoadLibraryA(lib_names[i]); + #endif +#else + handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL); +#endif + if (handle != NULL) { + return handle; + } + } + + return NULL; +} + +static void glad_close_dlopen_handle(void* handle) { + if (handle != NULL) { +#if GLAD_PLATFORM_WIN32 + FreeLibrary((HMODULE) handle); +#else + dlclose(handle); +#endif + } +} + +static GLADapiproc glad_dlsym_handle(void* handle, const char *name) { + if (handle == NULL) { + return NULL; + } + +#if GLAD_PLATFORM_WIN32 + return (GLADapiproc) GetProcAddress((HMODULE) handle, name); +#else + return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name); +#endif +} + +#endif /* GLAD_LOADER_LIBRARY_C_ */ + +typedef void* (GLAD_API_PTR *GLADglprocaddrfunc)(const char*); +struct _glad_gl_userptr { + void *handle; + GLADglprocaddrfunc gl_get_proc_address_ptr; +}; + +static GLADapiproc glad_gl_get_proc(void *vuserptr, const char *name) { + struct _glad_gl_userptr userptr = *(struct _glad_gl_userptr*) vuserptr; + GLADapiproc result = NULL; + + if(userptr.gl_get_proc_address_ptr != NULL) { + result = GLAD_GNUC_EXTENSION (GLADapiproc) userptr.gl_get_proc_address_ptr(name); + } + if(result == NULL) { + result = glad_dlsym_handle(userptr.handle, name); + } + + return result; +} + +static void* _glad_GL_loader_handle = NULL; + +static void* glad_gl_dlopen_handle(void) { +#if GLAD_PLATFORM_APPLE + static const char *NAMES[] = { + "../Frameworks/OpenGL.framework/OpenGL", + "/Library/Frameworks/OpenGL.framework/OpenGL", + "/System/Library/Frameworks/OpenGL.framework/OpenGL", + "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL" + }; +#elif GLAD_PLATFORM_WIN32 + static const char *NAMES[] = {"opengl32.dll"}; +#else + static const char *NAMES[] = { + #if defined(__CYGWIN__) + "libGL-1.so", + #endif + "libGL.so.1", + "libGL.so" + }; +#endif + + if (_glad_GL_loader_handle == NULL) { + _glad_GL_loader_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); + } + + return _glad_GL_loader_handle; +} + +static struct _glad_gl_userptr glad_gl_build_userptr(void *handle) { + struct _glad_gl_userptr userptr; + + userptr.handle = handle; +#if GLAD_PLATFORM_APPLE || defined(__HAIKU__) + userptr.gl_get_proc_address_ptr = NULL; +#elif GLAD_PLATFORM_WIN32 + userptr.gl_get_proc_address_ptr = + (GLADglprocaddrfunc) glad_dlsym_handle(handle, "wglGetProcAddress"); +#else + userptr.gl_get_proc_address_ptr = + (GLADglprocaddrfunc) glad_dlsym_handle(handle, "glXGetProcAddressARB"); +#endif + + return userptr; +} + +int gladLoaderLoadGL(void) { + int version = 0; + void *handle; + int did_load = 0; + struct _glad_gl_userptr userptr; + + did_load = _glad_GL_loader_handle == NULL; + handle = glad_gl_dlopen_handle(); + if (handle) { + userptr = glad_gl_build_userptr(handle); + + version = gladLoadGLUserPtr(glad_gl_get_proc, &userptr); + + if (did_load) { + gladLoaderUnloadGL(); + } + } + + return version; +} + + + +void gladLoaderUnloadGL(void) { + if (_glad_GL_loader_handle != NULL) { + glad_close_dlopen_handle(_glad_GL_loader_handle); + _glad_GL_loader_handle = NULL; + } +} + +#endif /* GLAD_GL */ + +#ifdef __cplusplus +} +#endif diff --git a/src/libvgcode/glad/src/gles2.c b/src/libvgcode/glad/src/gles2.c new file mode 100644 index 0000000000..e9642e97f4 --- /dev/null +++ b/src/libvgcode/glad/src/gles2.c @@ -0,0 +1,877 @@ +/** + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + */ +#include +#include +#include +#include + +#ifndef GLAD_IMPL_UTIL_C_ +#define GLAD_IMPL_UTIL_C_ + +#ifdef _MSC_VER +#define GLAD_IMPL_UTIL_SSCANF sscanf_s +#else +#define GLAD_IMPL_UTIL_SSCANF sscanf +#endif + +#endif /* GLAD_IMPL_UTIL_C_ */ + +#ifdef __cplusplus +extern "C" { +#endif + + + +int GLAD_GL_ES_VERSION_2_0 = 0; +int GLAD_GL_ES_VERSION_3_0 = 0; + + + +PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; +PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; +PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; +PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; +PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; +PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; +PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; +PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; +PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; +PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; +PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; +PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; +PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL; +PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; +PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; +PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; +PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; +PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; +PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; +PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; +PFNGLBUFFERDATAPROC glad_glBufferData = NULL; +PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; +PFNGLCLEARPROC glad_glClear = NULL; +PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; +PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; +PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; +PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; +PFNGLCLEARCOLORPROC glad_glClearColor = NULL; +PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL; +PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; +PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; +PFNGLCOLORMASKPROC glad_glColorMask = NULL; +PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; +PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; +PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; +PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; +PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; +PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; +PFNGLCREATESHADERPROC glad_glCreateShader = NULL; +PFNGLCULLFACEPROC glad_glCullFace = NULL; +PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; +PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; +PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; +PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; +PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; +PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; +PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; +PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; +PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; +PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks = NULL; +PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; +PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; +PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; +PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL; +PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; +PFNGLDISABLEPROC glad_glDisable = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; +PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; +PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; +PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; +PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; +PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; +PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; +PFNGLENABLEPROC glad_glEnable = NULL; +PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; +PFNGLENDQUERYPROC glad_glEndQuery = NULL; +PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; +PFNGLFENCESYNCPROC glad_glFenceSync = NULL; +PFNGLFINISHPROC glad_glFinish = NULL; +PFNGLFLUSHPROC glad_glFlush = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; +PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; +PFNGLFRONTFACEPROC glad_glFrontFace = NULL; +PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; +PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; +PFNGLGENQUERIESPROC glad_glGenQueries = NULL; +PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; +PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; +PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; +PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks = NULL; +PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; +PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; +PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; +PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; +PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; +PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; +PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; +PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; +PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; +PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; +PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; +PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; +PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; +PFNGLGETERRORPROC glad_glGetError = NULL; +PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; +PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; +PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; +PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; +PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; +PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; +PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL; +PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL; +PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; +PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; +PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; +PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; +PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; +PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; +PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; +PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL; +PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; +PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; +PFNGLGETSTRINGPROC glad_glGetString = NULL; +PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; +PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; +PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; +PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; +PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; +PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; +PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; +PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; +PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; +PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; +PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; +PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; +PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; +PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; +PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; +PFNGLHINTPROC glad_glHint = NULL; +PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL; +PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer = NULL; +PFNGLISBUFFERPROC glad_glIsBuffer = NULL; +PFNGLISENABLEDPROC glad_glIsEnabled = NULL; +PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; +PFNGLISPROGRAMPROC glad_glIsProgram = NULL; +PFNGLISQUERYPROC glad_glIsQuery = NULL; +PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; +PFNGLISSAMPLERPROC glad_glIsSampler = NULL; +PFNGLISSHADERPROC glad_glIsShader = NULL; +PFNGLISSYNCPROC glad_glIsSync = NULL; +PFNGLISTEXTUREPROC glad_glIsTexture = NULL; +PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = NULL; +PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; +PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; +PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; +PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; +PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = NULL; +PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; +PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; +PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL; +PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL; +PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; +PFNGLREADPIXELSPROC glad_glReadPixels = NULL; +PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL; +PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; +PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL; +PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; +PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; +PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; +PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; +PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL; +PFNGLSCISSORPROC glad_glScissor = NULL; +PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL; +PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; +PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; +PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; +PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; +PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; +PFNGLSTENCILOPPROC glad_glStencilOp = NULL; +PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; +PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; +PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; +PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; +PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; +PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; +PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; +PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D = NULL; +PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D = NULL; +PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; +PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; +PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; +PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; +PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; +PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; +PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; +PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; +PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; +PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; +PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; +PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; +PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; +PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; +PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; +PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; +PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; +PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; +PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; +PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; +PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; +PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; +PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; +PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; +PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; +PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; +PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; +PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; +PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; +PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; +PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; +PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; +PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; +PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; +PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; +PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; +PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; +PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; +PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; +PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; +PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; +PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; +PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; +PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; +PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; +PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; +PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; +PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; +PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; +PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; +PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; +PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; +PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; +PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; +PFNGLVIEWPORTPROC glad_glViewport = NULL; +PFNGLWAITSYNCPROC glad_glWaitSync = NULL; + + +static void glad_gl_load_GL_ES_VERSION_2_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ES_VERSION_2_0) return; + glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC) load(userptr, "glActiveTexture"); + glad_glAttachShader = (PFNGLATTACHSHADERPROC) load(userptr, "glAttachShader"); + glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load(userptr, "glBindAttribLocation"); + glad_glBindBuffer = (PFNGLBINDBUFFERPROC) load(userptr, "glBindBuffer"); + glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer"); + glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer"); + glad_glBindTexture = (PFNGLBINDTEXTUREPROC) load(userptr, "glBindTexture"); + glad_glBlendColor = (PFNGLBLENDCOLORPROC) load(userptr, "glBlendColor"); + glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC) load(userptr, "glBlendEquation"); + glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load(userptr, "glBlendEquationSeparate"); + glad_glBlendFunc = (PFNGLBLENDFUNCPROC) load(userptr, "glBlendFunc"); + glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load(userptr, "glBlendFuncSeparate"); + glad_glBufferData = (PFNGLBUFFERDATAPROC) load(userptr, "glBufferData"); + glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load(userptr, "glBufferSubData"); + glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus"); + glad_glClear = (PFNGLCLEARPROC) load(userptr, "glClear"); + glad_glClearColor = (PFNGLCLEARCOLORPROC) load(userptr, "glClearColor"); + glad_glClearDepthf = (PFNGLCLEARDEPTHFPROC) load(userptr, "glClearDepthf"); + glad_glClearStencil = (PFNGLCLEARSTENCILPROC) load(userptr, "glClearStencil"); + glad_glColorMask = (PFNGLCOLORMASKPROC) load(userptr, "glColorMask"); + glad_glCompileShader = (PFNGLCOMPILESHADERPROC) load(userptr, "glCompileShader"); + glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load(userptr, "glCompressedTexImage2D"); + glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load(userptr, "glCompressedTexSubImage2D"); + glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load(userptr, "glCopyTexImage2D"); + glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load(userptr, "glCopyTexSubImage2D"); + glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC) load(userptr, "glCreateProgram"); + glad_glCreateShader = (PFNGLCREATESHADERPROC) load(userptr, "glCreateShader"); + glad_glCullFace = (PFNGLCULLFACEPROC) load(userptr, "glCullFace"); + glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load(userptr, "glDeleteBuffers"); + glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers"); + glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC) load(userptr, "glDeleteProgram"); + glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers"); + glad_glDeleteShader = (PFNGLDELETESHADERPROC) load(userptr, "glDeleteShader"); + glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC) load(userptr, "glDeleteTextures"); + glad_glDepthFunc = (PFNGLDEPTHFUNCPROC) load(userptr, "glDepthFunc"); + glad_glDepthMask = (PFNGLDEPTHMASKPROC) load(userptr, "glDepthMask"); + glad_glDepthRangef = (PFNGLDEPTHRANGEFPROC) load(userptr, "glDepthRangef"); + glad_glDetachShader = (PFNGLDETACHSHADERPROC) load(userptr, "glDetachShader"); + glad_glDisable = (PFNGLDISABLEPROC) load(userptr, "glDisable"); + glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load(userptr, "glDisableVertexAttribArray"); + glad_glDrawArrays = (PFNGLDRAWARRAYSPROC) load(userptr, "glDrawArrays"); + glad_glDrawElements = (PFNGLDRAWELEMENTSPROC) load(userptr, "glDrawElements"); + glad_glEnable = (PFNGLENABLEPROC) load(userptr, "glEnable"); + glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load(userptr, "glEnableVertexAttribArray"); + glad_glFinish = (PFNGLFINISHPROC) load(userptr, "glFinish"); + glad_glFlush = (PFNGLFLUSHPROC) load(userptr, "glFlush"); + glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer"); + glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D"); + glad_glFrontFace = (PFNGLFRONTFACEPROC) load(userptr, "glFrontFace"); + glad_glGenBuffers = (PFNGLGENBUFFERSPROC) load(userptr, "glGenBuffers"); + glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers"); + glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers"); + glad_glGenTextures = (PFNGLGENTEXTURESPROC) load(userptr, "glGenTextures"); + glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap"); + glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load(userptr, "glGetActiveAttrib"); + glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load(userptr, "glGetActiveUniform"); + glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load(userptr, "glGetAttachedShaders"); + glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load(userptr, "glGetAttribLocation"); + glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC) load(userptr, "glGetBooleanv"); + glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load(userptr, "glGetBufferParameteriv"); + glad_glGetError = (PFNGLGETERRORPROC) load(userptr, "glGetError"); + glad_glGetFloatv = (PFNGLGETFLOATVPROC) load(userptr, "glGetFloatv"); + glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv"); + glad_glGetIntegerv = (PFNGLGETINTEGERVPROC) load(userptr, "glGetIntegerv"); + glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load(userptr, "glGetProgramInfoLog"); + glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC) load(userptr, "glGetProgramiv"); + glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv"); + glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load(userptr, "glGetShaderInfoLog"); + glad_glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) load(userptr, "glGetShaderPrecisionFormat"); + glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC) load(userptr, "glGetShaderSource"); + glad_glGetShaderiv = (PFNGLGETSHADERIVPROC) load(userptr, "glGetShaderiv"); + glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load(userptr, "glGetTexParameterfv"); + glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load(userptr, "glGetTexParameteriv"); + glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load(userptr, "glGetUniformLocation"); + glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC) load(userptr, "glGetUniformfv"); + glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC) load(userptr, "glGetUniformiv"); + glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load(userptr, "glGetVertexAttribPointerv"); + glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load(userptr, "glGetVertexAttribfv"); + glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load(userptr, "glGetVertexAttribiv"); + glad_glHint = (PFNGLHINTPROC) load(userptr, "glHint"); + glad_glIsBuffer = (PFNGLISBUFFERPROC) load(userptr, "glIsBuffer"); + glad_glIsEnabled = (PFNGLISENABLEDPROC) load(userptr, "glIsEnabled"); + glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer"); + glad_glIsProgram = (PFNGLISPROGRAMPROC) load(userptr, "glIsProgram"); + glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer"); + glad_glIsShader = (PFNGLISSHADERPROC) load(userptr, "glIsShader"); + glad_glIsTexture = (PFNGLISTEXTUREPROC) load(userptr, "glIsTexture"); + glad_glLineWidth = (PFNGLLINEWIDTHPROC) load(userptr, "glLineWidth"); + glad_glLinkProgram = (PFNGLLINKPROGRAMPROC) load(userptr, "glLinkProgram"); + glad_glPixelStorei = (PFNGLPIXELSTOREIPROC) load(userptr, "glPixelStorei"); + glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load(userptr, "glPolygonOffset"); + glad_glReadPixels = (PFNGLREADPIXELSPROC) load(userptr, "glReadPixels"); + glad_glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) load(userptr, "glReleaseShaderCompiler"); + glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage"); + glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load(userptr, "glSampleCoverage"); + glad_glScissor = (PFNGLSCISSORPROC) load(userptr, "glScissor"); + glad_glShaderBinary = (PFNGLSHADERBINARYPROC) load(userptr, "glShaderBinary"); + glad_glShaderSource = (PFNGLSHADERSOURCEPROC) load(userptr, "glShaderSource"); + glad_glStencilFunc = (PFNGLSTENCILFUNCPROC) load(userptr, "glStencilFunc"); + glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load(userptr, "glStencilFuncSeparate"); + glad_glStencilMask = (PFNGLSTENCILMASKPROC) load(userptr, "glStencilMask"); + glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load(userptr, "glStencilMaskSeparate"); + glad_glStencilOp = (PFNGLSTENCILOPPROC) load(userptr, "glStencilOp"); + glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load(userptr, "glStencilOpSeparate"); + glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC) load(userptr, "glTexImage2D"); + glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC) load(userptr, "glTexParameterf"); + glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load(userptr, "glTexParameterfv"); + glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC) load(userptr, "glTexParameteri"); + glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load(userptr, "glTexParameteriv"); + glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load(userptr, "glTexSubImage2D"); + glad_glUniform1f = (PFNGLUNIFORM1FPROC) load(userptr, "glUniform1f"); + glad_glUniform1fv = (PFNGLUNIFORM1FVPROC) load(userptr, "glUniform1fv"); + glad_glUniform1i = (PFNGLUNIFORM1IPROC) load(userptr, "glUniform1i"); + glad_glUniform1iv = (PFNGLUNIFORM1IVPROC) load(userptr, "glUniform1iv"); + glad_glUniform2f = (PFNGLUNIFORM2FPROC) load(userptr, "glUniform2f"); + glad_glUniform2fv = (PFNGLUNIFORM2FVPROC) load(userptr, "glUniform2fv"); + glad_glUniform2i = (PFNGLUNIFORM2IPROC) load(userptr, "glUniform2i"); + glad_glUniform2iv = (PFNGLUNIFORM2IVPROC) load(userptr, "glUniform2iv"); + glad_glUniform3f = (PFNGLUNIFORM3FPROC) load(userptr, "glUniform3f"); + glad_glUniform3fv = (PFNGLUNIFORM3FVPROC) load(userptr, "glUniform3fv"); + glad_glUniform3i = (PFNGLUNIFORM3IPROC) load(userptr, "glUniform3i"); + glad_glUniform3iv = (PFNGLUNIFORM3IVPROC) load(userptr, "glUniform3iv"); + glad_glUniform4f = (PFNGLUNIFORM4FPROC) load(userptr, "glUniform4f"); + glad_glUniform4fv = (PFNGLUNIFORM4FVPROC) load(userptr, "glUniform4fv"); + glad_glUniform4i = (PFNGLUNIFORM4IPROC) load(userptr, "glUniform4i"); + glad_glUniform4iv = (PFNGLUNIFORM4IVPROC) load(userptr, "glUniform4iv"); + glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load(userptr, "glUniformMatrix2fv"); + glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load(userptr, "glUniformMatrix3fv"); + glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load(userptr, "glUniformMatrix4fv"); + glad_glUseProgram = (PFNGLUSEPROGRAMPROC) load(userptr, "glUseProgram"); + glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load(userptr, "glValidateProgram"); + glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load(userptr, "glVertexAttrib1f"); + glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load(userptr, "glVertexAttrib1fv"); + glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load(userptr, "glVertexAttrib2f"); + glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load(userptr, "glVertexAttrib2fv"); + glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load(userptr, "glVertexAttrib3f"); + glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load(userptr, "glVertexAttrib3fv"); + glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load(userptr, "glVertexAttrib4f"); + glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load(userptr, "glVertexAttrib4fv"); + glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load(userptr, "glVertexAttribPointer"); + glad_glViewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport"); +} +static void glad_gl_load_GL_ES_VERSION_3_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ES_VERSION_3_0) return; + glad_glBeginQuery = (PFNGLBEGINQUERYPROC) load(userptr, "glBeginQuery"); + glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load(userptr, "glBeginTransformFeedback"); + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); + glad_glBindSampler = (PFNGLBINDSAMPLERPROC) load(userptr, "glBindSampler"); + glad_glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) load(userptr, "glBindTransformFeedback"); + glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load(userptr, "glBindVertexArray"); + glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load(userptr, "glBlitFramebuffer"); + glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load(userptr, "glClearBufferfi"); + glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load(userptr, "glClearBufferfv"); + glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load(userptr, "glClearBufferiv"); + glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load(userptr, "glClearBufferuiv"); + glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load(userptr, "glClientWaitSync"); + glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load(userptr, "glCompressedTexImage3D"); + glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load(userptr, "glCompressedTexSubImage3D"); + glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) load(userptr, "glCopyBufferSubData"); + glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load(userptr, "glCopyTexSubImage3D"); + glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC) load(userptr, "glDeleteQueries"); + glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) load(userptr, "glDeleteSamplers"); + glad_glDeleteSync = (PFNGLDELETESYNCPROC) load(userptr, "glDeleteSync"); + glad_glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) load(userptr, "glDeleteTransformFeedbacks"); + glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load(userptr, "glDeleteVertexArrays"); + glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) load(userptr, "glDrawArraysInstanced"); + glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC) load(userptr, "glDrawBuffers"); + glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) load(userptr, "glDrawElementsInstanced"); + glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load(userptr, "glDrawRangeElements"); + glad_glEndQuery = (PFNGLENDQUERYPROC) load(userptr, "glEndQuery"); + glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load(userptr, "glEndTransformFeedback"); + glad_glFenceSync = (PFNGLFENCESYNCPROC) load(userptr, "glFenceSync"); + glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load(userptr, "glFlushMappedBufferRange"); + glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glFramebufferTextureLayer"); + glad_glGenQueries = (PFNGLGENQUERIESPROC) load(userptr, "glGenQueries"); + glad_glGenSamplers = (PFNGLGENSAMPLERSPROC) load(userptr, "glGenSamplers"); + glad_glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) load(userptr, "glGenTransformFeedbacks"); + glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load(userptr, "glGenVertexArrays"); + glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) load(userptr, "glGetActiveUniformBlockName"); + glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) load(userptr, "glGetActiveUniformBlockiv"); + glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) load(userptr, "glGetActiveUniformsiv"); + glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) load(userptr, "glGetBufferParameteri64v"); + glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load(userptr, "glGetBufferPointerv"); + glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load(userptr, "glGetFragDataLocation"); + glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) load(userptr, "glGetInteger64i_v"); + glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC) load(userptr, "glGetInteger64v"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); + glad_glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) load(userptr, "glGetInternalformativ"); + glad_glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) load(userptr, "glGetProgramBinary"); + glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load(userptr, "glGetQueryObjectuiv"); + glad_glGetQueryiv = (PFNGLGETQUERYIVPROC) load(userptr, "glGetQueryiv"); + glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load(userptr, "glGetSamplerParameterfv"); + glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load(userptr, "glGetSamplerParameteriv"); + glad_glGetStringi = (PFNGLGETSTRINGIPROC) load(userptr, "glGetStringi"); + glad_glGetSynciv = (PFNGLGETSYNCIVPROC) load(userptr, "glGetSynciv"); + glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load(userptr, "glGetTransformFeedbackVarying"); + glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) load(userptr, "glGetUniformBlockIndex"); + glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) load(userptr, "glGetUniformIndices"); + glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load(userptr, "glGetUniformuiv"); + glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load(userptr, "glGetVertexAttribIiv"); + glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load(userptr, "glGetVertexAttribIuiv"); + glad_glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) load(userptr, "glInvalidateFramebuffer"); + glad_glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) load(userptr, "glInvalidateSubFramebuffer"); + glad_glIsQuery = (PFNGLISQUERYPROC) load(userptr, "glIsQuery"); + glad_glIsSampler = (PFNGLISSAMPLERPROC) load(userptr, "glIsSampler"); + glad_glIsSync = (PFNGLISSYNCPROC) load(userptr, "glIsSync"); + glad_glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) load(userptr, "glIsTransformFeedback"); + glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC) load(userptr, "glIsVertexArray"); + glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load(userptr, "glMapBufferRange"); + glad_glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) load(userptr, "glPauseTransformFeedback"); + glad_glProgramBinary = (PFNGLPROGRAMBINARYPROC) load(userptr, "glProgramBinary"); + glad_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) load(userptr, "glProgramParameteri"); + glad_glReadBuffer = (PFNGLREADBUFFERPROC) load(userptr, "glReadBuffer"); + glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glRenderbufferStorageMultisample"); + glad_glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) load(userptr, "glResumeTransformFeedback"); + glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load(userptr, "glSamplerParameterf"); + glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load(userptr, "glSamplerParameterfv"); + glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load(userptr, "glSamplerParameteri"); + glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load(userptr, "glSamplerParameteriv"); + glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC) load(userptr, "glTexImage3D"); + glad_glTexStorage2D = (PFNGLTEXSTORAGE2DPROC) load(userptr, "glTexStorage2D"); + glad_glTexStorage3D = (PFNGLTEXSTORAGE3DPROC) load(userptr, "glTexStorage3D"); + glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load(userptr, "glTexSubImage3D"); + glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load(userptr, "glTransformFeedbackVaryings"); + glad_glUniform1ui = (PFNGLUNIFORM1UIPROC) load(userptr, "glUniform1ui"); + glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC) load(userptr, "glUniform1uiv"); + glad_glUniform2ui = (PFNGLUNIFORM2UIPROC) load(userptr, "glUniform2ui"); + glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC) load(userptr, "glUniform2uiv"); + glad_glUniform3ui = (PFNGLUNIFORM3UIPROC) load(userptr, "glUniform3ui"); + glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC) load(userptr, "glUniform3uiv"); + glad_glUniform4ui = (PFNGLUNIFORM4UIPROC) load(userptr, "glUniform4ui"); + glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC) load(userptr, "glUniform4uiv"); + glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) load(userptr, "glUniformBlockBinding"); + glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load(userptr, "glUniformMatrix2x3fv"); + glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load(userptr, "glUniformMatrix2x4fv"); + glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load(userptr, "glUniformMatrix3x2fv"); + glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load(userptr, "glUniformMatrix3x4fv"); + glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load(userptr, "glUniformMatrix4x2fv"); + glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load(userptr, "glUniformMatrix4x3fv"); + glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) load(userptr, "glUnmapBuffer"); + glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) load(userptr, "glVertexAttribDivisor"); + glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load(userptr, "glVertexAttribI4i"); + glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load(userptr, "glVertexAttribI4iv"); + glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load(userptr, "glVertexAttribI4ui"); + glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load(userptr, "glVertexAttribI4uiv"); + glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load(userptr, "glVertexAttribIPointer"); + glad_glWaitSync = (PFNGLWAITSYNCPROC) load(userptr, "glWaitSync"); +} + + + +static void glad_gl_free_extensions(char **exts_i) { + if (exts_i != NULL) { + unsigned int index; + for(index = 0; exts_i[index]; index++) { + free((void *) (exts_i[index])); + } + free((void *)exts_i); + exts_i = NULL; + } +} +static int glad_gl_get_extensions( const char **out_exts, char ***out_exts_i) { +#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) + if (glad_glGetStringi != NULL && glad_glGetIntegerv != NULL) { + unsigned int index = 0; + unsigned int num_exts_i = 0; + char **exts_i = NULL; + glad_glGetIntegerv(GL_NUM_EXTENSIONS, (int*) &num_exts_i); + exts_i = (char **) malloc((num_exts_i + 1) * (sizeof *exts_i)); + if (exts_i == NULL) { + return 0; + } + for(index = 0; index < num_exts_i; index++) { + const char *gl_str_tmp = (const char*) glad_glGetStringi(GL_EXTENSIONS, index); + size_t len = strlen(gl_str_tmp) + 1; + + char *local_str = (char*) malloc(len * sizeof(char)); + if(local_str == NULL) { + exts_i[index] = NULL; + glad_gl_free_extensions(exts_i); + return 0; + } + + memcpy(local_str, gl_str_tmp, len * sizeof(char)); + exts_i[index] = local_str; + } + exts_i[index] = NULL; + + *out_exts_i = exts_i; + + return 1; + } +#else + GLAD_UNUSED(out_exts_i); +#endif + if (glad_glGetString == NULL) { + return 0; + } + *out_exts = (const char *)glad_glGetString(GL_EXTENSIONS); + return 1; +} +static int glad_gl_has_extension(const char *exts, char **exts_i, const char *ext) { + if(exts_i) { + unsigned int index; + for(index = 0; exts_i[index]; index++) { + const char *e = exts_i[index]; + if(strcmp(e, ext) == 0) { + return 1; + } + } + } else { + const char *extensions; + const char *loc; + const char *terminator; + extensions = exts; + if(extensions == NULL || ext == NULL) { + return 0; + } + while(1) { + loc = strstr(extensions, ext); + if(loc == NULL) { + return 0; + } + terminator = loc + strlen(ext); + if((loc == extensions || *(loc - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0')) { + return 1; + } + extensions = terminator; + } + } + return 0; +} + +static GLADapiproc glad_gl_get_proc_from_userptr(void *userptr, const char* name) { + return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); +} + +static int glad_gl_find_extensions_gles2(void) { + const char *exts = NULL; + char **exts_i = NULL; + if (!glad_gl_get_extensions(&exts, &exts_i)) return 0; + + GLAD_UNUSED(glad_gl_has_extension); + + glad_gl_free_extensions(exts_i); + + return 1; +} + +static int glad_gl_find_core_gles2(void) { + int i; + const char* version; + const char* prefixes[] = { + "OpenGL ES-CM ", + "OpenGL ES-CL ", + "OpenGL ES ", + "OpenGL SC ", + NULL + }; + int major = 0; + int minor = 0; + version = (const char*) glad_glGetString(GL_VERSION); + if (!version) return 0; + for (i = 0; prefixes[i]; i++) { + const size_t length = strlen(prefixes[i]); + if (strncmp(version, prefixes[i], length) == 0) { + version += length; + break; + } + } + + GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); + + GLAD_GL_ES_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; + GLAD_GL_ES_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; + + return GLAD_MAKE_VERSION(major, minor); +} + +int gladLoadGLES2UserPtr( GLADuserptrloadfunc load, void *userptr) { + int version; + + glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + if(glad_glGetString == NULL) return 0; + version = glad_gl_find_core_gles2(); + + glad_gl_load_GL_ES_VERSION_2_0(load, userptr); + glad_gl_load_GL_ES_VERSION_3_0(load, userptr); + + if (!glad_gl_find_extensions_gles2()) return 0; + + + + return version; +} + + +int gladLoadGLES2( GLADloadfunc load) { + return gladLoadGLES2UserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +} + + + + + +#ifdef GLAD_GLES2 + +#ifndef GLAD_LOADER_LIBRARY_C_ +#define GLAD_LOADER_LIBRARY_C_ + +#include +#include + +#if GLAD_PLATFORM_WIN32 +#include +#else +#include +#endif + + +static void* glad_get_dlopen_handle(const char *lib_names[], int length) { + void *handle = NULL; + int i; + + for (i = 0; i < length; ++i) { +#if GLAD_PLATFORM_WIN32 + #if GLAD_PLATFORM_UWP + size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR); + LPWSTR buffer = (LPWSTR) malloc(buffer_size); + if (buffer != NULL) { + int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size); + if (ret != 0) { + handle = (void*) LoadPackagedLibrary(buffer, 0); + } + free((void*) buffer); + } + #else + handle = (void*) LoadLibraryA(lib_names[i]); + #endif +#else + handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL); +#endif + if (handle != NULL) { + return handle; + } + } + + return NULL; +} + +static void glad_close_dlopen_handle(void* handle) { + if (handle != NULL) { +#if GLAD_PLATFORM_WIN32 + FreeLibrary((HMODULE) handle); +#else + dlclose(handle); +#endif + } +} + +static GLADapiproc glad_dlsym_handle(void* handle, const char *name) { + if (handle == NULL) { + return NULL; + } + +#if GLAD_PLATFORM_WIN32 + return (GLADapiproc) GetProcAddress((HMODULE) handle, name); +#else + return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name); +#endif +} + +#endif /* GLAD_LOADER_LIBRARY_C_ */ + +#if GLAD_PLATFORM_EMSCRIPTEN +#ifndef GLAD_EGL_H_ + typedef void (*__eglMustCastToProperFunctionPointerType)(void); + typedef __eglMustCastToProperFunctionPointerType (GLAD_API_PTR *PFNEGLGETPROCADDRESSPROC)(const char *name); +#endif + extern __eglMustCastToProperFunctionPointerType emscripten_GetProcAddress(const char *name); +#elif GLAD_GLES2_USE_SYSTEM_EGL + #include + typedef __eglMustCastToProperFunctionPointerType (GLAD_API_PTR *PFNEGLGETPROCADDRESSPROC)(const char *name); +#else + #include +#endif + + +struct _glad_gles2_userptr { + void *handle; + PFNEGLGETPROCADDRESSPROC get_proc_address_ptr; +}; + + +static GLADapiproc glad_gles2_get_proc(void *vuserptr, const char* name) { + struct _glad_gles2_userptr userptr = *(struct _glad_gles2_userptr*) vuserptr; + GLADapiproc result = NULL; + +#if GLAD_PLATFORM_EMSCRIPTEN + GLAD_UNUSED(glad_dlsym_handle); +#else + result = glad_dlsym_handle(userptr.handle, name); +#endif + if (result == NULL) { + result = userptr.get_proc_address_ptr(name); + } + + return result; +} + +static void* _glad_GLES2_loader_handle = NULL; + +static void* glad_gles2_dlopen_handle(void) { +#if GLAD_PLATFORM_EMSCRIPTEN +#elif GLAD_PLATFORM_APPLE + static const char *NAMES[] = {"libGLESv2.dylib"}; +#elif GLAD_PLATFORM_WIN32 + static const char *NAMES[] = {"GLESv2.dll", "libGLESv2.dll"}; +#else + static const char *NAMES[] = {"libGLESv2.so.2", "libGLESv2.so"}; +#endif + +#if GLAD_PLATFORM_EMSCRIPTEN + GLAD_UNUSED(glad_get_dlopen_handle); + return NULL; +#else + if (_glad_GLES2_loader_handle == NULL) { + _glad_GLES2_loader_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); + } + + return _glad_GLES2_loader_handle; +#endif +} + +static struct _glad_gles2_userptr glad_gles2_build_userptr(void *handle) { + struct _glad_gles2_userptr userptr; +#if GLAD_PLATFORM_EMSCRIPTEN + GLAD_UNUSED(handle); + userptr.get_proc_address_ptr = emscripten_GetProcAddress; +#else + userptr.handle = handle; + userptr.get_proc_address_ptr = eglGetProcAddress; +#endif + return userptr; +} + +int gladLoaderLoadGLES2(void) { + int version = 0; + void *handle = NULL; + int did_load = 0; + struct _glad_gles2_userptr userptr; + +#if GLAD_PLATFORM_EMSCRIPTEN + GLAD_UNUSED(handle); + GLAD_UNUSED(did_load); + GLAD_UNUSED(glad_gles2_dlopen_handle); + GLAD_UNUSED(glad_gles2_build_userptr); + userptr.get_proc_address_ptr = emscripten_GetProcAddress; + version = gladLoadGLES2UserPtr(glad_gles2_get_proc, &userptr); +#else + if (eglGetProcAddress == NULL) { + return 0; + } + + did_load = _glad_GLES2_loader_handle == NULL; + handle = glad_gles2_dlopen_handle(); + if (handle != NULL) { + userptr = glad_gles2_build_userptr(handle); + + version = gladLoadGLES2UserPtr(glad_gles2_get_proc, &userptr); + + if (!version && did_load) { + gladLoaderUnloadGLES2(); + } + } +#endif + + return version; +} + + + +void gladLoaderUnloadGLES2(void) { + if (_glad_GLES2_loader_handle != NULL) { + glad_close_dlopen_handle(_glad_GLES2_loader_handle); + _glad_GLES2_loader_handle = NULL; + } +} + +#endif /* GLAD_GLES2 */ + +#ifdef __cplusplus +} +#endif diff --git a/src/libvgcode/include/ColorPrint.hpp b/src/libvgcode/include/ColorPrint.hpp new file mode 100644 index 0000000000..071b93a708 --- /dev/null +++ b/src/libvgcode/include/ColorPrint.hpp @@ -0,0 +1,22 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_COLORPRINT_HPP +#define VGCODE_COLORPRINT_HPP + +#include "../include/Types.hpp" + +namespace libvgcode { + +struct ColorPrint +{ + uint8_t extruder_id{ 0 }; + uint8_t color_id{ 0 }; + uint32_t layer_id{ 0 }; + std::array times{ 0.0f, 0.0f }; +}; + +} // namespace libvgcode + +#endif // VGCODE_COLORPRINT_HPP \ No newline at end of file diff --git a/src/libvgcode/include/ColorRange.hpp b/src/libvgcode/include/ColorRange.hpp new file mode 100644 index 0000000000..e6c83cb21d --- /dev/null +++ b/src/libvgcode/include/ColorRange.hpp @@ -0,0 +1,107 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_COLORRANGE_HPP +#define VGCODE_COLORRANGE_HPP + +#include "../include/Types.hpp" + +#include + +namespace libvgcode { + +static const Palette DEFAULT_RANGES_COLORS{ { + { 11, 44, 122 }, // bluish + { 19, 89, 133 }, + { 28, 136, 145 }, + { 4, 214, 15 }, + { 170, 242, 0 }, + { 252, 249, 3 }, + { 245, 206, 10 }, + { 227, 136, 32 }, + { 209, 104, 48 }, + { 194, 82, 60 }, + { 148, 38, 22 } // reddish +} }; + +class ColorRange +{ +public: + // + // Constructor + // + explicit ColorRange(EColorRangeType type = EColorRangeType::Linear); + // + // Return the type of this ColorRange. + // + EColorRangeType get_type() const; + // + // Return the palette used by this ColorRange. + // Default is DEFAULT_RANGES_COLORS + // + const Palette& get_palette() const; + // + // Set the palette to be used by this ColorRange. + // The given palette must contain at least two colors. + // + void set_palette(const Palette& palette); + // + // Return the interpolated color at the given value. + // Value is clamped to [get_range()[0]..get_range()[1]]. + // + Color get_color_at(float value) const; + // + // Return the range of this ColorRange. + // The range is detected during the call to Viewer::load(). + // [0] -> min + // [1] -> max + // + const std::array& get_range() const; + // + // Return the values corresponding to the detected color bins of this ColorRange. + // The size of the returned vector can be: + // 1 - If only one value was detected while setting up this ColorRange. + // 2 - If only two values were detected while setting up this ColorRange. + // get_palette().size() - If more than two distinct values were detected while setting up this ColorRange. + // + std::vector get_values() const; + // + // Return the size of the palette, in bytes + // + std::size_t size_in_bytes_cpu() const; + + static const ColorRange DUMMY_COLOR_RANGE; + +private: + EColorRangeType m_type{ EColorRangeType::Linear }; + // + // The palette used by this ColorRange + // + Palette m_palette; + // + // [0] = min + // [1] = max + // + std::array m_range{ FLT_MAX, -FLT_MAX }; + // + // Count of different values passed to update() + // + std::size_t m_count{ 0 }; + + // + // Use the passed value to update the range. + // + void update(float value); + // + // Reset the range + // Call this method before reuse an instance of ColorRange. + // + void reset(); + + friend class ViewerImpl; +}; + +} // namespace libvgcode + +#endif // VGCODE_COLORRANGE_HPP diff --git a/src/libvgcode/include/GCodeInputData.hpp b/src/libvgcode/include/GCodeInputData.hpp new file mode 100644 index 0000000000..5085322e37 --- /dev/null +++ b/src/libvgcode/include/GCodeInputData.hpp @@ -0,0 +1,36 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_GCODEINPUTDATA_HPP +#define VGCODE_GCODEINPUTDATA_HPP + +#include "PathVertex.hpp" + +namespace libvgcode { + +struct GCodeInputData +{ + // + // Whether or not the gcode was generated with spiral vase mode enabled. + // Required to properly detect fictitious layer changes when spiral vase mode is enabled. + // + bool spiral_vase_mode{ false }; + // + // List of path vertices (gcode moves) + // See: PathVertex + // + std::vector vertices; + // + // Palette for extruders colors + // + Palette tools_colors; + // + // Palette for color print colors + // + Palette color_print_colors; +}; + +} // namespace libvgcode + +#endif // VGCODE_BITSET_HPP diff --git a/src/libvgcode/include/PathVertex.hpp b/src/libvgcode/include/PathVertex.hpp new file mode 100644 index 0000000000..d2c39ce40d --- /dev/null +++ b/src/libvgcode/include/PathVertex.hpp @@ -0,0 +1,121 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_PATHVERTEX_HPP +#define VGCODE_PATHVERTEX_HPP + +#include "Types.hpp" + +#include + +namespace libvgcode { + +// +// Struct representating a gcode move (toolpath segment) +// +struct PathVertex +{ + // + // Segment end position + // + Vec3 position{ FLT_MAX, FLT_MAX, FLT_MAX }; + // + // Segment height + // + float height{ 0.0f }; + // + // Segment width + // + float width{ 0.0f }; + // + // Segment speed + // + float feedrate{ 0.0f }; + // + // Segment actual speed + // + float actual_feedrate{ 0.0f }; + // + // Segment mm3_per_mm + // + float mm3_per_mm{ 0.0f }; + // + // Segment fan speed + // + float fan_speed{ 0.0f }; + // + // Segment temperature + // + float temperature{ 0.0f }; +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + // + // Segment weight + // + float weight{ 0.0f }; +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + // + // Segment extrusion role + // + EGCodeExtrusionRole role{ EGCodeExtrusionRole::None }; + // + // Segment move type + // + EMoveType type{ EMoveType::Noop }; + // + // Segment gcode line id + // + uint32_t gcode_id{ 0 }; + // + // Segment layer id + // + uint32_t layer_id{ 0 }; + // + // Segment extruder id + // + uint8_t extruder_id{ 0 }; + // + // Segment color id + // + uint8_t color_id{ 0 }; + // + // Segment estimated times + // + std::array times{ 0.0f, 0.0f }; + + // + // Return true if the segment is an extrusion move + // + bool is_extrusion() const; + // + // Return true if the segment is an travel move + // + bool is_travel() const; + // + // Return true if the segment is an option + // See: EOptionType + // + bool is_option() const; + // + // Return true if the segment is a wipe move + // + bool is_wipe() const; + // + // Return true if the segment was generated by custom gcode + // + bool is_custom_gcode() const; + // + // Return the volumetric flow rate of the segment + // + float volumetric_rate() const { return feedrate * mm3_per_mm; } + // + // Return the acutal volumetric flow rate of the segment + // + float actual_volumetric_rate() const { return actual_feedrate * mm3_per_mm; } + + static const PathVertex DUMMY_PATH_VERTEX; +}; + +} // namespace libvgcode + +#endif // VGCODE_PATHVERTEX_HPP \ No newline at end of file diff --git a/src/libvgcode/include/Types.hpp b/src/libvgcode/include/Types.hpp new file mode 100644 index 0000000000..f637d9c290 --- /dev/null +++ b/src/libvgcode/include/Types.hpp @@ -0,0 +1,225 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_TYPES_HPP +#define VGCODE_TYPES_HPP + +#define VGCODE_ENABLE_COG_AND_TOOL_MARKERS 0 + +#include +#include +#include + +namespace libvgcode { + +static constexpr float PI = 3.141592f; + +// +// Predefined values for the radius, in mm, of the cylinders used to render the travel moves. +// +static constexpr float DEFAULT_TRAVELS_RADIUS_MM = 0.1f; +static constexpr float MIN_TRAVELS_RADIUS_MM = 0.05f; +static constexpr float MAX_TRAVELS_RADIUS_MM = 1.0f; + +// +// Predefined values for the radius, in mm, of the cylinders used to render the wipe moves. +// +static constexpr float DEFAULT_WIPES_RADIUS_MM = 0.1f; +static constexpr float MIN_WIPES_RADIUS_MM = 0.05f; +static constexpr float MAX_WIPES_RADIUS_MM = 1.0f; + +// +// Vector in 3 dimensions +// [0] -> x +// [1] -> y +// [2] -> z +// Used for positions, displacements and so on. +// +using Vec3 = std::array; + +// +// 4x4 square matrix with elements in column-major order: +// | a[0] a[4] a[8] a[12] | +// | a[1] a[5] a[9] a[13] | +// | a[2] a[6] a[10] a[14] | +// | a[3] a[7] a[11] a[15] | +// +using Mat4x4 = std::array; + +// +// RGB color +// [0] -> red +// [1] -> green +// [2] -> blue +// +using Color = std::array; + +// +// Color palette +// +using Palette = std::vector; + +// +// Axis aligned box in 3 dimensions +// [0] -> { min_x, min_y, min_z } +// [1] -> { max_x, max_y, max_z } +// +using AABox = std::array; + +// +// One dimensional natural numbers interval +// [0] -> min +// [1] -> max +// +using Interval = std::array; + +// +// View types +// +enum class EViewType : uint8_t +{ + Summary, // ORCA + FeatureType, + ColorPrint, + Speed, + ActualSpeed, + Height, + Width, + VolumetricFlowRate, + ActualVolumetricFlowRate, + LayerTimeLinear, + LayerTimeLogarithmic, + FanSpeed, + Temperature, + Tool, + COUNT +}; + +static constexpr std::size_t VIEW_TYPES_COUNT = static_cast(EViewType::COUNT); + +// +// Move types +// +enum class EMoveType : uint8_t +{ + Noop, + Retract, + Unretract, + Seam, + ToolChange, + ColorChange, + PausePrint, + CustomGCode, + Travel, + Wipe, + Extrude, + COUNT +}; + +static constexpr std::size_t MOVE_TYPES_COUNT = static_cast(EMoveType::COUNT); + +// +// Extrusion roles +// +enum class EGCodeExtrusionRole : uint8_t +{ + // This enum is used as in index into extrusion_roles_visibility. + // Better only add things to the end. + None, + Perimeter, + ExternalPerimeter, + OverhangPerimeter, + InternalInfill, + SolidInfill, + TopSolidInfill, + Ironing, + BridgeInfill, + GapFill, + Skirt, + SupportMaterial, + SupportMaterialInterface, + WipeTower, + Custom, + // ORCA + BottomSurface, + InternalBridgeInfill, + Brim, + SupportTransition, + Mixed, + COUNT +}; + +static constexpr std::size_t GCODE_EXTRUSION_ROLES_COUNT = static_cast(EGCodeExtrusionRole::COUNT); + +// +// Option types +// +enum class EOptionType : uint8_t +{ + // This enum is used as in index into options_visibility. + // Better only add things to the end. + Travels, + Wipes, + Retractions, + Unretractions, + Seams, + ToolChanges, + ColorChanges, + PausePrints, + CustomGCodes, +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + CenterOfGravity, + ToolMarker, +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + COUNT +}; + +static constexpr std::size_t OPTION_TYPES_COUNT = static_cast(EOptionType::COUNT); + +// +// Time modes +// +enum class ETimeMode : uint8_t +{ + Normal, + Stealth, + COUNT +}; + +static constexpr std::size_t TIME_MODES_COUNT = static_cast(ETimeMode::COUNT); + +// +// Color range types +// +enum class EColorRangeType : uint8_t +{ + Linear, + Logarithmic, + COUNT +}; + +static constexpr std::size_t COLOR_RANGE_TYPES_COUNT = static_cast(EColorRangeType::COUNT); + +// +// Predefined colors +// +static const Color DUMMY_COLOR{ 64, 64, 64 }; + +// +// Mapping from EMoveType to EOptionType +// Returns EOptionType::COUNT if the given move type does not correspond +// to any option type. +// +extern EOptionType move_type_to_option(EMoveType type); + +// +// Returns the linear interpolation between the two given colors +// at the given t. +// t is clamped in the range [0..1] +// +extern Color lerp(const Color& c1, const Color& c2, float t); + +} // namespace libvgcode + +#endif // VGCODE_TYPES_HPP diff --git a/src/libvgcode/include/Viewer.hpp b/src/libvgcode/include/Viewer.hpp new file mode 100644 index 0000000000..45636b465d --- /dev/null +++ b/src/libvgcode/include/Viewer.hpp @@ -0,0 +1,423 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_VIEWER_HPP +#define VGCODE_VIEWER_HPP + +#include "Types.hpp" + +#include + +namespace libvgcode { + +class ViewerImpl; +struct GCodeInputData; +struct PathVertex; +class ColorRange; +struct ColorPrint; + +class Viewer +{ +public: + Viewer(); + ~Viewer(); + Viewer(const Viewer& other) = delete; + Viewer(Viewer&& other) = delete; + Viewer& operator = (const Viewer& other) = delete; + Viewer& operator = (Viewer&& other) = delete; + + // + // Initialize the viewer. + // Param opengl_context_version must be the string returned by glGetString(GL_VERSION). + // This method must be called after a valid OpenGL context has been already created + // and before calling any other method of the viewer. + // Throws an std::runtime_error exception if: + // * the method is called before creating an OpenGL context + // * the created OpenGL context does not support OpenGL 3.2 or greater + // * when using OpenGL ES, the created OpenGL ES context does not support OpenGL ES 2.0 or greater + // * any of the shaders fails to compile + // + void init(const std::string& opengl_context_version); + // + // Release the resources used by the viewer. + // This method must be called before releasing the OpenGL context if the viewer + // goes out of scope after releasing it. + // + void shutdown(); + // + // Reset the contents of the viewer. + // Automatically called by load() method. + // + void reset(); + // + // Setup the viewer content from the given data. + // See: GCodeInputData + // + void load(GCodeInputData&& gcode_data); + // + // Render the toolpaths according to the current settings and + // using the given camera matrices. + // + void render(const Mat4x4& view_matrix, const Mat4x4& projection_matrix); + + // + // ************************************************************************ + // Settings + // The following methods can be used to query/customize the parameters + // used to render the toolpaths. + // ************************************************************************ + // + + // + // View type + // See: EViewType + // + EViewType get_view_type() const; + void set_view_type(EViewType type); + // + // Time mode + // See: ETimeMode + // + ETimeMode get_time_mode() const; + void set_time_mode(ETimeMode mode); + // + // Top layer only + // Whether or not the visible range is limited to the current top layer only. + // + bool is_top_layer_only_view_range() const; + // + // Toggle the top layer only state. + // + void toggle_top_layer_only_view_range(); + // + // Returns true if the given option is visible. + // + bool is_option_visible(EOptionType type) const; + // + // Toggle the visibility state of the given option. + // + void toggle_option_visibility(EOptionType type); + // + // Returns true if the given extrusion role is visible. + // + bool is_extrusion_role_visible(EGCodeExtrusionRole role) const; + // + // Toggle the visibility state of the given extrusion role. + // + void toggle_extrusion_role_visibility(EGCodeExtrusionRole role); + // + // Return the color used to render the given extrusion rols. + // + const Color& get_extrusion_role_color(EGCodeExtrusionRole role) const; + // + // Set the color used to render the given extrusion role. + // + void set_extrusion_role_color(EGCodeExtrusionRole role, const Color& color); + // + // Reset the colors used to render the extrusion roles to the default value. + // + void reset_default_extrusion_roles_colors(); + // + // Return the color used to render the given option. + // + const Color& get_option_color(EOptionType type) const; + // + // Set the color used to render the given option. + // + void set_option_color(EOptionType type, const Color& color); + // + // Reset the colors used to render the options to the default value. + // + void reset_default_options_colors(); + // + // Return the count of colors in the palette used to render + // the toolpaths when the view type is EViewType::Tool. + // + size_t get_tool_colors_count() const; + // + // Return the palette used to render the toolpaths when + // the view type is EViewType::Tool. + // + const Palette& get_tool_colors() const; + // + // Set the palette used to render the toolpaths when + // the view type is EViewType::Tool with the given one. + // + void set_tool_colors(const Palette& colors); + // + // Return the count of colors in the palette used to render + // the toolpaths when the view type is EViewType::ColorPrint. + // + size_t get_color_print_colors_count() const; + // + // Return the palette used to render the toolpaths when + // the view type is EViewType::ColorPrint. + // + const Palette& get_color_print_colors() const; + // + // Set the palette used to render the toolpaths when + // the view type is EViewType::ColorPrint with the given one. + // + void set_color_print_colors(const Palette& colors); + // + // Get the color range for the given view type. + // Valid view types are: + // EViewType::Height + // EViewType::Width + // EViewType::Speed + // EViewType::ActualSpeed + // EViewType::FanSpeed + // EViewType::Temperature + // EViewType::VolumetricFlowRate + // EViewType::ActualVolumetricFlowRate + // EViewType::LayerTimeLinear + // EViewType::LayerTimeLogarithmic + // + const ColorRange& get_color_range(EViewType type) const; + // + // Set the palette for the color range corresponding to the given view type + // with the given value. + // Valid view types are: + // EViewType::Height + // EViewType::Width + // EViewType::Speed + // EViewType::ActualSpeed + // EViewType::FanSpeed + // EViewType::Temperature + // EViewType::VolumetricFlowRate + // EViewType::ActualVolumetricFlowRate + // EViewType::LayerTimeLinear + // EViewType::LayerTimeLogarithmic + // + void set_color_range_palette(EViewType type, const Palette& palette); + // + // Get the radius, in mm, of the cylinders used to render the travel moves. + // + float get_travels_radius() const; + // + // Set the radius, in mm, of the cylinders used to render the travel moves. + // Radius is clamped to [MIN_TRAVELS_RADIUS_MM..MAX_TRAVELS_RADIUS_MM] + // + void set_travels_radius(float radius); + // + // Get the radius, in mm, of the cylinders used to render the wipe moves. + // + float get_wipes_radius() const; + // + // Set the radius, in mm, of the cylinders used to render the wipe moves. + // Radius is clamped to [MIN_WIPES_RADIUS_MM..MAX_WIPES_RADIUS_MM] + // + void set_wipes_radius(float radius); + // + // Return the count of detected layers. + // + size_t get_layers_count() const; + // + // Return the current visible layers range. + // + const Interval& get_layers_view_range() const; + // + // Set the current visible layers range with the given interval. + // Values are clamped to [0..get_layers_count() - 1]. + // + void set_layers_view_range(const Interval& range); + // + // Set the current visible layers range with the given min and max values. + // Values are clamped to [0..get_layers_count() - 1]. + // + void set_layers_view_range(Interval::value_type min, Interval::value_type max); + // + // Return the current visible range. + // Three ranges are defined: full, enabled and visible. + // For all of them the range endpoints represent: + // [0] -> min vertex id + // [1] -> max vertex id + // Full is the range of vertices that could potentially be visualized accordingly to the current settings. + // Enabled is the part of the full range that is selected for visualization accordingly to the current settings. + // Visible is the part of the enabled range that is actually visualized accordingly to the current settings. + // + const Interval& get_view_visible_range() const; + // + // Set the current visible range. + // Values are clamped to the current view enabled range; + // + void set_view_visible_range(Interval::value_type min, Interval::value_type max); + // + // Return the current full range. + // + const Interval& get_view_full_range() const; + // + // Return the current enabled range. + // + const Interval& get_view_enabled_range() const; + + // + // ************************************************************************ + // Property getters + // The following methods can be used to query detected properties. + // ************************************************************************ + // + + // + // Spiral vase mode + // Whether or not the gcode was generated with spiral vase mode enabled. + // See: GCodeInputData + // + bool is_spiral_vase_mode() const; + // + // Return the z of the layer with the given id + // or 0.0f if the id does not belong to [0..get_layers_count() - 1]. + // + float get_layer_z(size_t layer_id) const; + // + // Return the list of zs of the detected layers. + // + std::vector get_layers_zs() const; + // + // Return the id of the layer closest to the given z. + // + size_t get_layer_id_at(float z) const; + // + // Return the count of detected used extruders. + // + size_t get_used_extruders_count() const; + // + // Return the list of ids of the detected used extruders. + // + std::vector get_used_extruders_ids() const; + // + // Return the list of detected time modes. + // + std::vector get_time_modes() const; + // + // Return the count of vertices used to render the toolpaths + // + size_t get_vertices_count() const; + // + // Return the vertex pointed by the max value of the view visible range + // + const PathVertex& get_current_vertex() const; + // + // Return the index of vertex pointed by the max value of the view visible range + // + size_t get_current_vertex_id() const; + // + // Return the vertex at the given index + // + const PathVertex& get_vertex_at(size_t id) const; + // + // Return the total estimated time, in seconds, using the current time mode. + // + float get_estimated_time() const; + // + // Return the estimated time, in seconds, at the vertex with the given index + // using the current time mode. + // + float get_estimated_time_at(size_t id) const; + // + // Return the color used to render the given vertex with the current settings. + // + Color get_vertex_color(const PathVertex& vertex) const; + // + // Return the count of detected extrusion roles + // + size_t get_extrusion_roles_count() const; + // + // Return the list of detected extrusion roles + // + std::vector get_extrusion_roles() const; + // + // Return the count of detected options. + // + size_t get_options_count() const; + // + // Return the list of detected options. + // + const std::vector& get_options() const; + // + // Return the count of detected color prints. + // + size_t get_color_prints_count(uint8_t extruder_id) const; + // + // Return the list of detected color prints. + // + std::vector get_color_prints(uint8_t extruder_id) const; + // + // Return the estimated time for the given role and the current time mode. + // + float get_extrusion_role_estimated_time(EGCodeExtrusionRole role) const; + // + // Return the estimated time for the travel moves and the current time mode. + // + float get_travels_estimated_time() const; + // + // Return the list of layers time for the current time mode. + // + std::vector get_layers_estimated_times() const; + // + // Return the axes aligned bounding box containing all the given types. + // + AABox get_bounding_box(const std::vector& types = { + EMoveType::Retract, EMoveType::Unretract, EMoveType::Seam, EMoveType::ToolChange, + EMoveType::ColorChange, EMoveType::PausePrint, EMoveType::CustomGCode, EMoveType::Travel, + EMoveType::Wipe, EMoveType::Extrude }) const; + // + // Return the axes aligned bounding box containing all the extrusions with the given roles. + // + AABox get_extrusion_bounding_box(const std::vector& roles = { + EGCodeExtrusionRole::Perimeter, EGCodeExtrusionRole::ExternalPerimeter, EGCodeExtrusionRole::OverhangPerimeter, + EGCodeExtrusionRole::InternalInfill, EGCodeExtrusionRole::SolidInfill, EGCodeExtrusionRole::TopSolidInfill, + EGCodeExtrusionRole::Ironing, EGCodeExtrusionRole::BridgeInfill, EGCodeExtrusionRole::GapFill, + EGCodeExtrusionRole::Skirt, EGCodeExtrusionRole::SupportMaterial, EGCodeExtrusionRole::SupportMaterialInterface, + EGCodeExtrusionRole::WipeTower, EGCodeExtrusionRole::Custom, + // ORCA + EGCodeExtrusionRole::BottomSurface, EGCodeExtrusionRole::InternalBridgeInfill, EGCodeExtrusionRole::Brim, + EGCodeExtrusionRole::SupportTransition, EGCodeExtrusionRole::Mixed + }) const; + // + // Return the size of the used cpu memory, in bytes + // + size_t get_used_cpu_memory() const; + // + // Return the size of the used gpu memory, in bytes + // + size_t get_used_gpu_memory() const; + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + // + // Returns the position of the center of gravity of the toolpaths. + // It does not take in account extrusions of type: + // Skirt + // Support Material + // Support Material Interface + // WipeTower + // Custom + // + Vec3 get_cog_position() const; + + float get_cog_marker_scale_factor() const; + void set_cog_marker_scale_factor(float factor); + + const Vec3& get_tool_marker_position() const; + + float get_tool_marker_offset_z() const; + void set_tool_marker_offset_z(float offset_z); + + float get_tool_marker_scale_factor() const; + void set_tool_marker_scale_factor(float factor); + + const Color& get_tool_marker_color() const; + void set_tool_marker_color(const Color& color); + + float get_tool_marker_alpha() const; + void set_tool_marker_alpha(float alpha); +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + +private: + ViewerImpl* m_impl{ nullptr }; +}; + +} // namespace libvgcode + +#endif // VGCODE_VIEWER_HPP diff --git a/src/libvgcode/src/Bitset.cpp b/src/libvgcode/src/Bitset.cpp new file mode 100644 index 0000000000..1896dc62f1 --- /dev/null +++ b/src/libvgcode/src/Bitset.cpp @@ -0,0 +1,8 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "Bitset.hpp" + +namespace libvgcode { +} // namespace libvgcode diff --git a/src/libvgcode/src/Bitset.hpp b/src/libvgcode/src/Bitset.hpp new file mode 100644 index 0000000000..eebe297262 --- /dev/null +++ b/src/libvgcode/src/Bitset.hpp @@ -0,0 +1,103 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_BITSET_HPP +#define VGCODE_BITSET_HPP + +#include +#include + +namespace libvgcode { + +// By default, types are not atomic, +template auto constexpr is_atomic = false; + +// but std::atomic types are, +template auto constexpr is_atomic> = true; + +template +struct BitSet +{ + BitSet() = default; + BitSet(std::size_t size) : size(size), blocks(1 + (size / (sizeof(T) * 8))) { clear(); } + + void clear() { + for (std::size_t i = 0; i < blocks.size(); ++i) { + blocks[i] &= T(0); + } + } + + void setAll() { + for (std::size_t i = 0; i < blocks.size(); ++i) { + blocks[i] |= ~T(0); + } + } + + //return true if bit changed + bool set(std::size_t index) { + const auto [block_idx, bit_idx] = get_coords(index); + const T mask = (T(1) << bit_idx); + bool flip = mask ^ blocks[block_idx]; + blocks[block_idx] |= mask; + return flip; + } + + //return true if bit changed + bool reset(std::size_t index) { + const auto [block_idx, bit_idx] = get_coords(index); + const T mask = (T(1) << bit_idx); + const bool flip = mask ^ blocks[block_idx]; + blocks[block_idx] &= (~mask); + return flip; + } + + bool operator [] (std::size_t index) const { + const auto [block_idx, bit_idx] = get_coords(index); + return ((blocks[block_idx] >> bit_idx) & 1) != 0; + } + + template + BitSet& operator &= (const BitSet& other) { + static_assert(sizeof(T) == sizeof(U), "Type1 and Type2 must be of the same size."); + for (std::size_t i = 0; i < blocks.size(); ++i) { + blocks[i] &= other.blocks[i]; + } + return *this; + } + + // Atomic set operation (enabled only for atomic types), return true if bit changed + template + inline typename std::enable_if, bool>::type set_atomic(std::size_t index) { + const auto [block_idx, bit_idx] = get_coords(index); + const T mask = static_cast(1) << bit_idx; + const T oldval = blocks[block_idx].fetch_or(mask, std::memory_order_relaxed); + return oldval ^ (oldval or mask); + } + + // Atomic reset operation (enabled only for atomic types), return true if bit changed + template + inline typename std::enable_if, bool>::type reset_atomic(std::size_t index) { + const auto [block_idx, bit_idx] = get_coords(index); + const T mask = ~(static_cast(1) << bit_idx); + const T oldval = blocks[block_idx].fetch_and(mask, std::memory_order_relaxed); + return oldval ^ (oldval and mask); + } + + std::pair get_coords(std::size_t index) const { + const std::size_t block_idx = index / (sizeof(T) * 8); + const std::size_t bit_idx = index % (sizeof(T) * 8); + return { block_idx, bit_idx }; + } + + std::size_t size_in_bytes_cpu() const { + return blocks.size() * sizeof(T); + } + + std::size_t size{ 0 }; + std::vector blocks{ 0 }; +}; + +} // namespace libvgcode + +#endif // VGCODE_BITSET_HPP diff --git a/src/libvgcode/src/CogMarker.cpp b/src/libvgcode/src/CogMarker.cpp new file mode 100644 index 0000000000..dd8ea53644 --- /dev/null +++ b/src/libvgcode/src/CogMarker.cpp @@ -0,0 +1,173 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +// needed for tech VGCODE_ENABLE_COG_AND_TOOL_MARKERS +#include "../include/Types.hpp" +#include "CogMarker.hpp" +#include "OpenGLUtils.hpp" +#include "Utils.hpp" + +#include +#include +#include + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + +namespace libvgcode { + +// Geometry: +// sphere with 'resolution' sides, centered at (0.0, 0.0, 0.0) and radius equal to 'radius' +void CogMarker::init(uint8_t resolution, float radius) +{ + if (m_vao_id != 0) + return; + + // ensure vertices count does not exceed 65536 + resolution = std::clamp(resolution, 4, 105); + + const uint16_t sector_count = (uint16_t)resolution; + const uint16_t stack_count = (uint16_t)resolution; + + const float sector_step = 2.0f * PI / float(sector_count); + const float stack_step = PI / float(stack_count); + + std::vector vertices; + const uint16_t vertices_count = (stack_count - 1) * sector_count + 2; + vertices.reserve(6 * vertices_count); + + m_indices_count = 3 * (2 * (stack_count - 1) * sector_count); + std::vector indices; + indices.reserve(m_indices_count); + + // vertices + for (uint16_t i = 0; i <= stack_count; ++i) { + // from pi/2 to -pi/2 + const float stack_angle = 0.5f * PI - stack_step * float(i); + const float xy = radius * std::cos(stack_angle); + const float z = radius * std::sin(stack_angle); + if (i == 0 || i == stack_count) { + const Vec3 pos = { xy, 0.0f, z }; + const Vec3 norm = normalize(pos); + add_vertex(pos, norm, vertices); + } + else { + for (uint16_t j = 0; j < sector_count; ++j) { + // from 0 to 2pi + const float sector_angle = sector_step * float(j); + const Vec3 pos = { xy * std::cos(sector_angle), xy * std::sin(sector_angle), z }; + const Vec3 norm = normalize(pos); + add_vertex(pos, norm, vertices); + } + } + } + + // indices + for (uint16_t i = 0; i < stack_count; ++i) { + // Beginning of current stack. + uint16_t k1 = (i == 0) ? 0 : (1 + (i - 1) * sector_count); + const uint16_t k1_first = k1; + // Beginning of next stack. + uint16_t k2 = (i == 0) ? 1 : (k1 + sector_count); + const uint16_t k2_first = k2; + for (uint16_t j = 0; j < sector_count; ++j) { + // 2 triangles per sector excluding first and last stacks + uint16_t k1_next = k1; + uint16_t k2_next = k2; + if (i != 0) { + k1_next = (j + 1 == sector_count) ? k1_first : (k1 + 1); + add_triangle(k1, k2, k1_next, indices); + } + if (i + 1 != stack_count) { + k2_next = (j + 1 == sector_count) ? k2_first : (k2 + 1); + add_triangle(k1_next, k2, k2_next, indices); + } + k1 = k1_next; + k2 = k2_next; + } + } + + m_size_in_bytes_gpu += vertices.size() * sizeof(float); + m_size_in_bytes_gpu += indices.size() * sizeof(uint16_t); + + const size_t vertex_stride = 6 * sizeof(float); + const size_t position_offset = 0; + const size_t normal_offset = 3 * sizeof(float); + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + int curr_array_buffer; + glsafe(glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &curr_array_buffer)); + + glsafe(glGenVertexArrays(1, &m_vao_id)); + glsafe(glBindVertexArray(m_vao_id)); + glsafe(glGenBuffers(1, &m_vbo_id)); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); + glsafe(glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW)); + glsafe(glEnableVertexAttribArray(0)); + glsafe(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)position_offset)); + glsafe(glEnableVertexAttribArray(1)); + glsafe(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)normal_offset)); + + glsafe(glGenBuffers(1, &m_ibo_id)); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo_id)); + glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), indices.data(), GL_STATIC_DRAW)); + + glsafe(glBindBuffer(GL_ARRAY_BUFFER, curr_array_buffer)); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +void CogMarker::shutdown() +{ + if (m_ibo_id != 0) { + glsafe(glDeleteBuffers(1, &m_ibo_id)); + m_ibo_id = 0; + } + if (m_vbo_id != 0) { + glsafe(glDeleteBuffers(1, &m_vbo_id)); + m_vbo_id = 0; + } + if (m_vao_id != 0) { + glsafe(glDeleteVertexArrays(1, &m_vao_id)); + m_vao_id = 0; + } + + m_size_in_bytes_gpu = 0; +} + +void CogMarker::render() +{ + if (m_vao_id == 0 || m_vbo_id == 0 || m_ibo_id == 0 || m_indices_count == 0) + return; + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + glcheck(); + + glsafe(glBindVertexArray(m_vao_id)); + glsafe(glDrawElements(GL_TRIANGLES, m_indices_count, GL_UNSIGNED_SHORT, (const void*)0)); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +void CogMarker::update(const Vec3& position, float mass) +{ + m_total_position = m_total_position + mass * position; + m_total_mass += mass; +} + +void CogMarker::reset() +{ + m_total_position = { 0.0f, 0.0f, 0.0f }; + m_total_mass = 0.0f; +} + +Vec3 CogMarker::get_position() const +{ + assert(m_total_mass > 0.0f); + const float inv_total_mass = 1.0f / m_total_mass; + return inv_total_mass * m_total_position; +} + +} // namespace libvgcode + +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS diff --git a/src/libvgcode/src/CogMarker.hpp b/src/libvgcode/src/CogMarker.hpp new file mode 100644 index 0000000000..df0c683aca --- /dev/null +++ b/src/libvgcode/src/CogMarker.hpp @@ -0,0 +1,77 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_COGMARKER_HPP +#define VGCODE_COGMARKER_HPP + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + +namespace libvgcode { + +class CogMarker +{ +public: + CogMarker() = default; + ~CogMarker() { shutdown(); } + CogMarker(const CogMarker& other) = delete; + CogMarker(CogMarker&& other) = delete; + CogMarker& operator = (const CogMarker& other) = delete; + CogMarker& operator = (CogMarker&& other) = delete; + + // + // Initialize gpu buffers + // + void init(uint8_t resolution, float radius); + // + // Release gpu buffers + // + void shutdown(); + // + // Render the marker + // + void render(); + // + // Update values used to calculate the center of gravity + // + void update(const Vec3& position, float mass); + // + // Reset values used to calculate the center of gravity + // + void reset(); + // + // Return the calculated center of gravity position + // + Vec3 get_position() const; + // + // Return the size of the data sent to gpu, in bytes. + // + size_t size_in_bytes_gpu() const { return m_size_in_bytes_gpu; } + +private: + // + // Values used to calculate the center of gravity + // + float m_total_mass{ 0.0f }; + Vec3 m_total_position{ 0.0f, 0.0f, 0.0f }; + // + // The count of indices stored into the ibo buffer. + // + uint16_t m_indices_count{ 0 }; + // + // gpu buffers ids. + // + unsigned int m_vao_id{ 0 }; + unsigned int m_vbo_id{ 0 }; + unsigned int m_ibo_id{ 0 }; + // + // Size of the data sent to gpu, in bytes. + // + size_t m_size_in_bytes_gpu{ 0 }; +}; + +} // namespace libvgcode + +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + +#endif // VGCODE_COGMARKER_HPP \ No newline at end of file diff --git a/src/libvgcode/src/ColorPrint.cpp b/src/libvgcode/src/ColorPrint.cpp new file mode 100644 index 0000000000..d6f40b9f52 --- /dev/null +++ b/src/libvgcode/src/ColorPrint.cpp @@ -0,0 +1,8 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "../include/ColorPrint.hpp" + +namespace libvgcode { +} // namespace libvgcode diff --git a/src/libvgcode/src/ColorRange.cpp b/src/libvgcode/src/ColorRange.cpp new file mode 100644 index 0000000000..1ba0dfc526 --- /dev/null +++ b/src/libvgcode/src/ColorRange.cpp @@ -0,0 +1,139 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "../include/ColorRange.hpp" + +#include "Utils.hpp" + +#include +#include +#include + +namespace libvgcode { + +const ColorRange ColorRange::DUMMY_COLOR_RANGE = ColorRange(); + +static float get_step_size(const ColorRange& color_range) +{ + const std::array& range = color_range.get_range(); + const Palette& palette = color_range.get_palette(); + switch (color_range.get_type()) + { + default: + case EColorRangeType::Linear: + { + return (range[1] - range[0]) / (static_cast(palette.size()) - 1.0f); + } + case EColorRangeType::Logarithmic: + { + return (range[0] != 0.0f) ? std::log(range[1] / range[0]) / (static_cast(palette.size()) - 1.0f) : 0.0f; + } + } +} + +ColorRange::ColorRange(EColorRangeType type) +: m_type(type) +, m_palette(DEFAULT_RANGES_COLORS) +{ +} + +EColorRangeType ColorRange::get_type() const +{ + return m_type; +} + +const Palette& ColorRange::get_palette() const +{ + return m_palette; +} + +void ColorRange::set_palette(const Palette& palette) +{ + if (palette.size() > 1) + m_palette = palette; +} + +Color ColorRange::get_color_at(float value) const +{ + // Input value scaled to the colors range + float global_t = 0.0f; + value = std::clamp(value, m_range[0], m_range[1]); + const float step = get_step_size(*this); + if (step > 0.0f) { + if (m_type == EColorRangeType::Logarithmic) { + if (m_range[0] != 0.0f) + global_t = std::log(value / m_range[0]) / step; + } + else + global_t = (value - m_range[0]) / step; + } + + const size_t color_max_idx = m_palette.size() - 1; + + // Compute the two colors just below (low) and above (high) the input value + const size_t color_low_idx = std::clamp(static_cast(global_t), 0, color_max_idx); + const size_t color_high_idx = std::clamp(color_low_idx + 1, 0, color_max_idx); + + // Interpolate between the low and high colors to find exactly which color the input value should get + return lerp(m_palette[color_low_idx], m_palette[color_high_idx], global_t - static_cast(color_low_idx)); +} + +const std::array& ColorRange::get_range() const +{ + return m_range; +} + +std::vector ColorRange::get_values() const +{ + std::vector ret; + + if (m_count == 1) { + // single item use case + ret.emplace_back(m_range[0]); + } + else if (m_count == 2) { + // two items use case + ret.emplace_back(m_range[0]); + ret.emplace_back(m_range[1]); + } + else { + const float step_size = get_step_size(*this); + for (size_t i = 0; i < m_palette.size(); ++i) { + float value = 0.0f; + switch (m_type) + { + default: + case EColorRangeType::Linear: { value = m_range[0] + static_cast(i) * step_size; break; } + case EColorRangeType::Logarithmic: { value = ::exp(::log(m_range[0]) + static_cast(i) * step_size); break; } + } + ret.emplace_back(value); + } + } + + return ret; +} + +size_t ColorRange::size_in_bytes_cpu() const +{ + size_t ret = STDVEC_MEMSIZE(m_palette, Color); + return ret; +} + +void ColorRange::update(float value) +{ + if (value != m_range[0] && value != m_range[1]) + ++m_count; + + m_range[0] = std::min(m_range[0], value); + m_range[1] = std::max(m_range[1], value); +} + +void ColorRange::reset() +{ + m_range = { FLT_MAX, -FLT_MAX }; + m_count = 0; +} + +} // namespace libvgcode + diff --git a/src/libvgcode/src/ExtrusionRoles.cpp b/src/libvgcode/src/ExtrusionRoles.cpp new file mode 100644 index 0000000000..e38886c57b --- /dev/null +++ b/src/libvgcode/src/ExtrusionRoles.cpp @@ -0,0 +1,39 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "ExtrusionRoles.hpp" + +namespace libvgcode { + +void ExtrusionRoles::add(EGCodeExtrusionRole role, const std::array& times) +{ + auto role_it = m_items.find(role); + if (role_it == m_items.end()) + role_it = m_items.insert(std::make_pair(role, Item())).first; + + for (std::size_t i = 0; i < TIME_MODES_COUNT; ++i) { + role_it->second.times[i] += times[i]; + } +} + +std::vector ExtrusionRoles::get_roles() const +{ + std::vector ret; + ret.reserve(m_items.size()); + for (const auto& [role, item] : m_items) { + ret.emplace_back(role); + } + return ret; +} + +float ExtrusionRoles::get_time(EGCodeExtrusionRole role, ETimeMode mode) const +{ + const auto role_it = m_items.find(role); + if (role_it == m_items.end()) + return 0.0f; + + return (mode < ETimeMode::COUNT) ? role_it->second.times[static_cast(mode)] : 0.0f; +} + +} // namespace libvgcode diff --git a/src/libvgcode/src/ExtrusionRoles.hpp b/src/libvgcode/src/ExtrusionRoles.hpp new file mode 100644 index 0000000000..ee949fbf0d --- /dev/null +++ b/src/libvgcode/src/ExtrusionRoles.hpp @@ -0,0 +1,36 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_EXTRUSION_ROLES_HPP +#define VGCODE_EXTRUSION_ROLES_HPP + +#include "../include/Types.hpp" + +#include + +namespace libvgcode { + +class ExtrusionRoles +{ +public: + struct Item + { + std::array times; + }; + + void add(EGCodeExtrusionRole role, const std::array& times); + + std::size_t get_roles_count() const { return m_items.size(); } + std::vector get_roles() const; + float get_time(EGCodeExtrusionRole role, ETimeMode mode) const; + + void reset() { m_items.clear(); } + +private: + std::map m_items; +}; + +} // namespace libvgcode + +#endif // VGCODE_EXTRUSION_ROLES_HPP diff --git a/src/libvgcode/src/GCodeInputData.cpp b/src/libvgcode/src/GCodeInputData.cpp new file mode 100644 index 0000000000..527508a572 --- /dev/null +++ b/src/libvgcode/src/GCodeInputData.cpp @@ -0,0 +1,8 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "../include/GCodeInputData.hpp" + +namespace libvgcode { +} // namespace libvgcode diff --git a/src/libvgcode/src/Layers.cpp b/src/libvgcode/src/Layers.cpp new file mode 100644 index 0000000000..16a2e38fcd --- /dev/null +++ b/src/libvgcode/src/Layers.cpp @@ -0,0 +1,83 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "Layers.hpp" + +#include "../include/PathVertex.hpp" +#include "Utils.hpp" + +#include +#include + +namespace libvgcode { + +static bool is_colorprint_option(const PathVertex& v) +{ + return v.type == EMoveType::PausePrint || v.type == EMoveType::CustomGCode; +} + +void Layers::update(const PathVertex& vertex, uint32_t vertex_id) +{ + if (m_items.empty() || vertex.layer_id == m_items.size()) { + // this code assumes that gcode paths are sent sequentially, one layer after the other + assert(vertex.layer_id == static_cast(m_items.size())); + Item& item = m_items.emplace_back(Item()); + if (vertex.type == EMoveType::Extrude && vertex.role != EGCodeExtrusionRole::Custom) + item.z = vertex.position[2]; + item.range.set(vertex_id, vertex_id); + item.times = vertex.times; + item.contains_colorprint_options |= is_colorprint_option(vertex); + } + else { + Item& item = m_items.back(); + if (vertex.type == EMoveType::Extrude && vertex.role != EGCodeExtrusionRole::Custom && item.z != vertex.position[2]) + item.z = vertex.position[2]; + item.range.set_max(vertex_id); + for (size_t i = 0; i < TIME_MODES_COUNT; ++i) { + item.times[i] += vertex.times[i]; + } + item.contains_colorprint_options |= is_colorprint_option(vertex); + } +} + +void Layers::reset() +{ + m_items.clear(); + m_view_range.reset(); +} + +std::vector Layers::get_times(ETimeMode mode) const +{ + std::vector ret; + if (mode < ETimeMode::COUNT) { + for (const Item& item : m_items) { + ret.emplace_back(item.times[static_cast(mode)]); + } + } + return ret; +} + +std::vector Layers::get_zs() const +{ + std::vector ret; + ret.reserve(m_items.size()); + for (const Item& item : m_items) { + ret.emplace_back(item.z); + } + return ret; +} + +size_t Layers::get_layer_id_at(float z) const +{ + auto iter = std::upper_bound(m_items.begin(), m_items.end(), z, [](float z, const Item& item) { return item.z < z; }); + return std::distance(m_items.begin(), iter); +} + +size_t Layers::size_in_bytes_cpu() const +{ + size_t ret = STDVEC_MEMSIZE(m_items, Item); + return ret; +} + +} // namespace libvgcode diff --git a/src/libvgcode/src/Layers.hpp b/src/libvgcode/src/Layers.hpp new file mode 100644 index 0000000000..bf3386016c --- /dev/null +++ b/src/libvgcode/src/Layers.hpp @@ -0,0 +1,60 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_LAYERS_HPP +#define VGCODE_LAYERS_HPP + +#include "Range.hpp" + +namespace libvgcode { + +struct PathVertex; + +class Layers +{ +public: + void update(const PathVertex& vertex, uint32_t vertex_id); + void reset(); + + bool empty() const { return m_items.empty(); } + std::size_t count() const { return m_items.size(); } + + std::vector get_times(ETimeMode mode) const; + std::vector get_zs() const; + + float get_layer_time(ETimeMode mode, std::size_t layer_id) const { + return (mode < ETimeMode::COUNT&& layer_id < m_items.size()) ? + m_items[layer_id].times[static_cast(mode)] : 0.0f; + } + float get_layer_z(std::size_t layer_id) const { + return (layer_id < m_items.size()) ? m_items[layer_id].z : 0.0f; + } + std::size_t get_layer_id_at(float z) const; + + const Interval& get_view_range() const { return m_view_range.get(); } + void set_view_range(const Interval& range) { set_view_range(range[0], range[1]); } + void set_view_range(Interval::value_type min, Interval::value_type max) { m_view_range.set(min, max); } + + bool layer_contains_colorprint_options(std::size_t layer_id) const { + return (layer_id < m_items.size()) ? m_items[layer_id].contains_colorprint_options : false; + } + + std::size_t size_in_bytes_cpu() const; + +private: + struct Item + { + float z{ 0.0f }; + Range range; + std::array times{ 0.0f, 0.0f }; + bool contains_colorprint_options{ false }; + }; + + std::vector m_items; + Range m_view_range; +}; + +} // namespace libvgcode + +#endif // VGCODE_LAYERS_HPP diff --git a/src/libvgcode/src/OpenGLUtils.cpp b/src/libvgcode/src/OpenGLUtils.cpp new file mode 100644 index 0000000000..bc39b29a4d --- /dev/null +++ b/src/libvgcode/src/OpenGLUtils.cpp @@ -0,0 +1,98 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak, VojtÄ›ch Bubník @bubnikv +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ + +#include "OpenGLUtils.hpp" + +#include +#include +#include +#include +#include + +namespace libvgcode { + +#ifdef HAS_GLSAFE +void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char* function_name) +{ + const GLenum err = glGetError(); + if (err == GL_NO_ERROR) + return; + const char* sErr = 0; + switch (err) { + case GL_INVALID_ENUM: { sErr = "Invalid Enum"; break; } + case GL_INVALID_VALUE: { sErr = "Invalid Value"; break; } + // be aware that GL_INVALID_OPERATION is generated if glGetError is executed between the execution of glBegin / glEnd + case GL_INVALID_OPERATION: { sErr = "Invalid Operation"; break; } + case GL_OUT_OF_MEMORY: { sErr = "Out Of Memory"; break; } + case GL_INVALID_FRAMEBUFFER_OPERATION: { sErr = "Invalid framebuffer operation"; break; } +#if !defined(ENABLE_OPENGL_ES) + case GL_STACK_OVERFLOW: { sErr = "Stack Overflow"; break; } + case GL_STACK_UNDERFLOW: { sErr = "Stack Underflow"; break; } +#endif // ENABLE_OPENGL_ES + default: { sErr = "Unknown"; break; } + } + std::cout << "OpenGL error in " << file_name << ":" << line << ", function " << function_name << "() : " << (int)err << " - " << sErr << "\n"; + assert(false); +} +#endif // HAS_GLSAFE + +static const char* OPENGL_ES_PREFIXES[] = { "OpenGL ES-CM ", "OpenGL ES-CL ", "OpenGL ES ", nullptr }; + +bool OpenGLWrapper::s_valid_context = false; +#ifdef ENABLE_OPENGL_ES +int OpenGLWrapper::s_max_texture_size = 0; +#endif // ENABLE_OPENGL_ES + +bool OpenGLWrapper::load_opengl(const std::string& context_version) +{ + s_valid_context = false; + + const char* version = context_version.c_str(); + for (int i = 0; OPENGL_ES_PREFIXES[i] != nullptr; ++i) { + const size_t length = strlen(OPENGL_ES_PREFIXES[i]); + if (strncmp(version, OPENGL_ES_PREFIXES[i], length) == 0) { + version += length; + break; + } + } + + GLint major = 0; + GLint minor = 0; +#ifdef _MSC_VER + const int res = sscanf_s(version, "%d.%d", &major, &minor); +#else + const int res = sscanf(version, "%d.%d", &major, &minor); +#endif // _MSC_VER + if (res != 2) + return false; + +#ifdef ENABLE_OPENGL_ES + s_valid_context = major > 3 || (major == 3 && minor >= 0); + const int glad_res = gladLoaderLoadGLES2(); +#else + s_valid_context = major > 3 || (major == 3 && minor >= 2); + const int glad_res = gladLoaderLoadGL(); +#endif // ENABLE_OPENGL_ES + + if (glad_res == 0) + return false; + +#ifdef ENABLE_OPENGL_ES + glsafe(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &s_max_texture_size)); +#endif // ENABLE_OPENGL_ES + + return s_valid_context; +} + +void OpenGLWrapper::unload_opengl() +{ +#ifdef ENABLE_OPENGL_ES + gladLoaderUnloadGLES2(); +#else + gladLoaderUnloadGL(); +#endif // ENABLE_OPENGL_ES +} + +} // namespace libvgcode diff --git a/src/libvgcode/src/OpenGLUtils.hpp b/src/libvgcode/src/OpenGLUtils.hpp new file mode 100644 index 0000000000..ad7b370aa2 --- /dev/null +++ b/src/libvgcode/src/OpenGLUtils.hpp @@ -0,0 +1,52 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak, VojtÄ›ch Bubník @bubnikv +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_OPENGLUTILS_HPP +#define VGCODE_OPENGLUTILS_HPP + +// OpenGL loader +#ifdef ENABLE_OPENGL_ES +#include "../glad/include/glad/gles2.h" +#else +#include "../glad/include/glad/gl.h" +#endif // ENABLE_OPENGL_ES + +#include + +namespace libvgcode { +#ifndef NDEBUG +#define HAS_GLSAFE +#endif // NDEBUG + +#ifdef HAS_GLSAFE +extern void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char* function_name); +inline void glAssertRecentCall() { glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); } +#define glsafe(cmd) do { cmd; glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); } while (false) +#define glcheck() do { glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); } while (false) +#else +inline void glAssertRecentCall() { } +#define glsafe(cmd) cmd +#define glcheck() +#endif // HAS_GLSAFE + +class OpenGLWrapper +{ +public: + static bool load_opengl(const std::string& context_version); + static void unload_opengl(); + static bool is_valid_context() { return s_valid_context; } +#ifdef ENABLE_OPENGL_ES + static size_t max_texture_size() { return static_cast(s_max_texture_size); } +#endif // ENABLE_OPENGL_ES + +private: + static bool s_valid_context; +#ifdef ENABLE_OPENGL_ES + static int s_max_texture_size; +#endif // ENABLE_OPENGL_ES +}; + +} // namespace libvgcode + +#endif // VGCODE_OPENGLUTILS_HPP diff --git a/src/libvgcode/src/OptionTemplate.cpp b/src/libvgcode/src/OptionTemplate.cpp new file mode 100644 index 0000000000..ba1123210a --- /dev/null +++ b/src/libvgcode/src/OptionTemplate.cpp @@ -0,0 +1,126 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "OptionTemplate.hpp" +#include "OpenGLUtils.hpp" +#include "Utils.hpp" + +#include +#include +#include + +namespace libvgcode { + +// Geometry: +// diamond with 'resolution' sides, centered at (0.0, 0.0, 0.0) +// height and width of the diamond are equal to 1.0 +void OptionTemplate::init(uint8_t resolution) +{ + if (m_top_vao_id != 0) + return; + + m_resolution = std::max(resolution, 3); + m_vertices_count = 2 + resolution; + const float step = 2.0f * PI / float(m_resolution); + + // + // top fan + // + std::vector top_vertices; + top_vertices.reserve(6 * m_vertices_count); + add_vertex({ 0.0f, 0.0f, 0.5f }, { 0.0f, 0.0f, 1.0f }, top_vertices); + for (uint8_t i = 0; i <= m_resolution; ++i) { + const float ii = float(i) * step; + const Vec3 pos = { 0.5f * std::cos(ii), 0.5f * std::sin(ii), 0.0f }; + const Vec3 norm = normalize(pos); + add_vertex(pos, norm, top_vertices); + } + + // + // bottom fan + // + std::vector bottom_vertices; + bottom_vertices.reserve(6 * m_vertices_count); + add_vertex({ 0.0f, 0.0f, -0.5f }, { 0.0f, 0.0f, -1.0f }, bottom_vertices); + for (uint8_t i = 0; i <= m_resolution; ++i) { + const float ii = -float(i) * step; + const Vec3 pos = { 0.5f * std::cos(ii), 0.5f * std::sin(ii), 0.0f }; + const Vec3 norm = normalize(pos); + add_vertex(pos, norm, bottom_vertices); + } + + m_size_in_bytes_gpu += top_vertices.size() * sizeof(float); + m_size_in_bytes_gpu += bottom_vertices.size() * sizeof(float); + + const size_t vertex_stride = 6 * sizeof(float); + const size_t position_offset = 0; + const size_t normal_offset = 3 * sizeof(float); + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + int curr_array_buffer; + glsafe(glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &curr_array_buffer)); + + glsafe(glGenVertexArrays(1, &m_top_vao_id)); + glsafe(glBindVertexArray(m_top_vao_id)); + glsafe(glGenBuffers(1, &m_top_vbo_id)); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_top_vbo_id)); + glsafe(glBufferData(GL_ARRAY_BUFFER, top_vertices.size() * sizeof(float), top_vertices.data(), GL_STATIC_DRAW)); + glsafe(glEnableVertexAttribArray(0)); + glsafe(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)position_offset)); + glsafe(glEnableVertexAttribArray(1)); + glsafe(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)normal_offset)); + + glsafe(glGenVertexArrays(1, &m_bottom_vao_id)); + glsafe(glBindVertexArray(m_bottom_vao_id)); + glsafe(glGenBuffers(1, &m_bottom_vbo_id)); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_bottom_vbo_id)); + glsafe(glBufferData(GL_ARRAY_BUFFER, bottom_vertices.size() * sizeof(float), bottom_vertices.data(), GL_STATIC_DRAW)); + glsafe(glEnableVertexAttribArray(0)); + glsafe(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)position_offset)); + glsafe(glEnableVertexAttribArray(1)); + glsafe(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)normal_offset)); + + glsafe(glBindBuffer(GL_ARRAY_BUFFER, curr_array_buffer)); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +void OptionTemplate::shutdown() +{ + if (m_bottom_vbo_id != 0) { + glsafe(glDeleteBuffers(1, &m_bottom_vbo_id)); + m_bottom_vbo_id = 0; + } + if (m_bottom_vao_id != 0) { + glsafe(glDeleteVertexArrays(1, &m_bottom_vao_id)); + m_bottom_vao_id = 0; + } + if (m_top_vbo_id != 0) { + glsafe(glDeleteBuffers(1, &m_top_vbo_id)); + m_top_vbo_id = 0; + } + if (m_top_vao_id != 0) { + glsafe(glDeleteVertexArrays(1, &m_top_vao_id)); + m_top_vao_id = 0; + } + + m_size_in_bytes_gpu = 0; +} + +void OptionTemplate::render(size_t count) +{ + if (m_top_vao_id == 0 || m_top_vbo_id == 0 || m_bottom_vao_id == 0 || m_bottom_vbo_id == 0 || count == 0) + return; + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + + glsafe(glBindVertexArray(m_top_vao_id)); + glsafe(glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, static_cast(m_vertices_count), static_cast(count))); + glsafe(glBindVertexArray(m_bottom_vao_id)); + glsafe(glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, static_cast(m_vertices_count), static_cast(count))); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +} // namespace libvgcode diff --git a/src/libvgcode/src/OptionTemplate.hpp b/src/libvgcode/src/OptionTemplate.hpp new file mode 100644 index 0000000000..e51c9e556d --- /dev/null +++ b/src/libvgcode/src/OptionTemplate.hpp @@ -0,0 +1,56 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_OPTIONTEMPLATE_HPP +#define VGCODE_OPTIONTEMPLATE_HPP + +#include +#include + +namespace libvgcode { + +class OptionTemplate +{ +public: + OptionTemplate() = default; + ~OptionTemplate() { shutdown(); } + OptionTemplate(const OptionTemplate& other) = delete; + OptionTemplate(OptionTemplate&& other) = delete; + OptionTemplate& operator = (const OptionTemplate& other) = delete; + OptionTemplate& operator = (OptionTemplate&& other) = delete; + + // + // Initialize gpu buffers. + // + void init(uint8_t resolution); + // + // Release gpu buffers. + // + void shutdown(); + void render(size_t count); + + // + // Return the size of the data sent to gpu, in bytes. + // + size_t size_in_bytes_gpu() const { return m_size_in_bytes_gpu; } + +private: + uint8_t m_resolution{ 0 }; + uint8_t m_vertices_count{ 0 }; + // + // gpu buffers ids. + // + unsigned int m_top_vao_id{ 0 }; + unsigned int m_top_vbo_id{ 0 }; + unsigned int m_bottom_vao_id{ 0 }; + unsigned int m_bottom_vbo_id{ 0 }; + // + // Size of the data sent to gpu, in bytes. + // + size_t m_size_in_bytes_gpu{ 0 }; +}; + +} // namespace libvgcode + +#endif // VGCODE_OPTIONTEMPLATE_HPP \ No newline at end of file diff --git a/src/libvgcode/src/PathVertex.cpp b/src/libvgcode/src/PathVertex.cpp new file mode 100644 index 0000000000..ed1569bc36 --- /dev/null +++ b/src/libvgcode/src/PathVertex.cpp @@ -0,0 +1,52 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "../include/PathVertex.hpp" + +namespace libvgcode { + +const PathVertex PathVertex::DUMMY_PATH_VERTEX = PathVertex(); + +bool PathVertex::is_extrusion() const +{ + return type == EMoveType::Extrude; +} + +bool PathVertex::is_travel() const +{ + return type == EMoveType::Travel; +} + +bool PathVertex::is_wipe() const +{ + return type == EMoveType::Wipe; +} + +bool PathVertex::is_option() const +{ + switch (type) + { + case EMoveType::Retract: + case EMoveType::Unretract: + case EMoveType::Seam: + case EMoveType::ToolChange: + case EMoveType::ColorChange: + case EMoveType::PausePrint: + case EMoveType::CustomGCode: + { + return true; + } + default: + { + return false; + } + } +} + +bool PathVertex::is_custom_gcode() const +{ + return type == EMoveType::Extrude && role == EGCodeExtrusionRole::Custom; +} + +} // namespace libvgcode diff --git a/src/libvgcode/src/Range.cpp b/src/libvgcode/src/Range.cpp new file mode 100644 index 0000000000..4d8df12f3d --- /dev/null +++ b/src/libvgcode/src/Range.cpp @@ -0,0 +1,25 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "Range.hpp" + +#include + +namespace libvgcode { + +void Range::set(Interval::value_type min, Interval::value_type max) +{ + if (max < min) + std::swap(min, max); + m_range[0] = min; + m_range[1] = max; +} + +void Range::clamp(Range& other) +{ + other.m_range[0] = std::clamp(other.m_range[0], m_range[0], m_range[1]); + other.m_range[1] = std::clamp(other.m_range[1], m_range[0], m_range[1]); +} + +} // namespace libvgcode diff --git a/src/libvgcode/src/Range.hpp b/src/libvgcode/src/Range.hpp new file mode 100644 index 0000000000..b5d07d69f1 --- /dev/null +++ b/src/libvgcode/src/Range.hpp @@ -0,0 +1,39 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_RANGE_HPP +#define VGCODE_RANGE_HPP + +#include "../include/Types.hpp" + +namespace libvgcode { + +class Range +{ +public: + const Interval& get() const { return m_range; } + void set(const Range& other) { m_range = other.m_range; } + void set(const Interval& range) { set(range[0], range[1]); } + void set(Interval::value_type min, Interval::value_type max); + + Interval::value_type get_min() const { return m_range[0]; } + void set_min(Interval::value_type min) { set(min, m_range[1]); } + + Interval::value_type get_max() const { return m_range[1]; } + void set_max(Interval::value_type max) { set(m_range[0], max); } + + // clamp the given range to stay inside this range + void clamp(Range& other); + void reset() { m_range = { 0, 0 }; } + + bool operator == (const Range& other) const { return m_range == other.m_range; } + bool operator != (const Range& other) const { return m_range != other.m_range; } + +private: + Interval m_range{ 0, 0 }; +}; + +} // namespace libvgcode + +#endif // VGCODE_RANGE_HPP \ No newline at end of file diff --git a/src/libvgcode/src/SegmentTemplate.cpp b/src/libvgcode/src/SegmentTemplate.cpp new file mode 100644 index 0000000000..4e692d5b10 --- /dev/null +++ b/src/libvgcode/src/SegmentTemplate.cpp @@ -0,0 +1,85 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "SegmentTemplate.hpp" +#include "OpenGLUtils.hpp" + +#include +#include + +namespace libvgcode { + +//| /1-------6\ | +//| / | | \ | +//| 2--0-------5--7 | +//| \ | | / | +//| 3-------4 | +static constexpr const std::array VERTEX_DATA = { + 0, 1, 2, // front spike + 0, 2, 3, // front spike + 0, 3, 4, // right/bottom body + 0, 4, 5, // right/bottom body + 0, 5, 6, // left/top body + 0, 6, 1, // left/top body + 5, 4, 7, // back spike + 5, 7, 6, // back spike +}; + +void SegmentTemplate::init() +{ + if (m_vao_id != 0) + return; + + m_size_in_bytes_gpu += VERTEX_DATA.size() * sizeof(uint8_t); + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + int curr_array_buffer; + glsafe(glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &curr_array_buffer)); + + glsafe(glGenVertexArrays(1, &m_vao_id)); + glsafe(glBindVertexArray(m_vao_id)); + + glsafe(glGenBuffers(1, &m_vbo_id)); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); + glsafe(glBufferData(GL_ARRAY_BUFFER, VERTEX_DATA.size() * sizeof(uint8_t), VERTEX_DATA.data(), GL_STATIC_DRAW)); + glsafe(glEnableVertexAttribArray(0)); +#ifdef ENABLE_OPENGL_ES + glsafe(glVertexAttribPointer(0, 1, GL_UNSIGNED_BYTE, GL_FALSE, 0, (const void*)0)); +#else + glsafe(glVertexAttribIPointer(0, 1, GL_UNSIGNED_BYTE, 0, (const void*)0)); +#endif // ENABLE_OPENGL_ES + + glsafe(glBindBuffer(GL_ARRAY_BUFFER, curr_array_buffer)); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +void SegmentTemplate::shutdown() +{ + if (m_vbo_id != 0) { + glsafe(glDeleteBuffers(1, &m_vbo_id)); + m_vbo_id = 0; + } + if (m_vao_id != 0) { + glsafe(glDeleteVertexArrays(1, &m_vao_id)); + m_vao_id = 0; + } + + m_size_in_bytes_gpu = 0; +} + +void SegmentTemplate::render(size_t count) +{ + if (m_vao_id == 0 || m_vbo_id == 0 || count == 0) + return; + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + + glsafe(glBindVertexArray(m_vao_id)); + glsafe(glDrawArraysInstanced(GL_TRIANGLES, 0, static_cast(VERTEX_DATA.size()), static_cast(count))); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +} // namespace libvgcode diff --git a/src/libvgcode/src/SegmentTemplate.hpp b/src/libvgcode/src/SegmentTemplate.hpp new file mode 100644 index 0000000000..f104eef5d2 --- /dev/null +++ b/src/libvgcode/src/SegmentTemplate.hpp @@ -0,0 +1,51 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_SEGMENTTEMPLATE_HPP +#define VGCODE_SEGMENTTEMPLATE_HPP + +#include + +namespace libvgcode { + +class SegmentTemplate +{ +public: + SegmentTemplate() = default; + ~SegmentTemplate() { shutdown(); } + SegmentTemplate(const SegmentTemplate& other) = delete; + SegmentTemplate(SegmentTemplate&& other) = delete; + SegmentTemplate& operator = (const SegmentTemplate& other) = delete; + SegmentTemplate& operator = (SegmentTemplate&& other) = delete; + + // + // Initialize gpu buffers. + // + void init(); + // + // Release gpu buffers. + // + void shutdown(); + void render(size_t count); + + // + // Return the size of the data sent to gpu, in bytes. + // + size_t size_in_bytes_gpu() const { return m_size_in_bytes_gpu; } + +private: + // + // gpu buffers ids. + // + unsigned int m_vao_id{ 0 }; + unsigned int m_vbo_id{ 0 }; + // + // Size of the data sent to gpu, in bytes. + // + size_t m_size_in_bytes_gpu{ 0 }; +}; + +} // namespace libvgcode + +#endif // VGCODE_SEGMENTTEMPLATE_HPP \ No newline at end of file diff --git a/src/libvgcode/src/Settings.cpp b/src/libvgcode/src/Settings.cpp new file mode 100644 index 0000000000..eacb4c37a3 --- /dev/null +++ b/src/libvgcode/src/Settings.cpp @@ -0,0 +1,9 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "Settings.hpp" + +namespace libvgcode { +} // namespace libvgcode + diff --git a/src/libvgcode/src/Settings.hpp b/src/libvgcode/src/Settings.hpp new file mode 100644 index 0000000000..37ddb5a8b9 --- /dev/null +++ b/src/libvgcode/src/Settings.hpp @@ -0,0 +1,76 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_SETTINGS_HPP +#define VGCODE_SETTINGS_HPP + +#include "../include/Types.hpp" + +#include + +namespace libvgcode { + +struct Settings +{ + // + // Visualization parameters + // + EViewType view_type{ EViewType::FeatureType }; + ETimeMode time_mode{ ETimeMode::Normal }; + bool top_layer_only_view_range{ false }; + bool spiral_vase_mode{ false }; + // + // Required update flags + // + bool update_view_full_range{ true }; + bool update_enabled_entities{ true }; + bool update_colors{ true }; + + // + // Visibility maps + // + std::array options_visibility{ + false, // Travels + false, // Wipes + false, // Retractions + false, // Unretractions + true, // Seams + false, // ToolChanges + false, // ColorChanges + false, // PausePrints + false, // CustomGCodes +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + false, // CenterOfGravity + true // ToolMarker +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + }; + + std::array extrusion_roles_visibility{ + true, // None + true, // Perimeter + true, // ExternalPerimeter + true, // OverhangPerimeter + true, // InternalInfill + true, // SolidInfill + true, // TopSolidInfill + true, // Ironing + true, // BridgeInfill + true, // GapFill + true, // Skirt + true, // SupportMaterial + true, // SupportMaterialInterface + true, // WipeTower + true, // Custom + // ORCA + true, // BottomSurface + true, // InternalBridgeInfill + true, // Brim + true, // SupportTransition + true, // Mixed + }; +}; + +} // namespace libvgcode + +#endif // VGCODE_SETTINGS_HPP diff --git a/src/libvgcode/src/Shaders.hpp b/src/libvgcode/src/Shaders.hpp new file mode 100644 index 0000000000..826f9a4805 --- /dev/null +++ b/src/libvgcode/src/Shaders.hpp @@ -0,0 +1,303 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_SHADERS_HPP +#define VGCODE_SHADERS_HPP + +// needed for tech VGCODE_ENABLE_COG_AND_TOOL_MARKERS +#include "../include/Types.hpp" + +namespace libvgcode { + +static const char* Segments_Vertex_Shader = +"#version 150\n" +"#define POINTY_CAPS\n" +"#define FIX_TWISTING\n" +"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n" +"const float light_top_diffuse = 0.6 * 0.8;\n" +"const float light_top_specular = 0.6 * 0.125;\n" +"const float light_top_shininess = 20.0;\n" +"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n" +"const float light_front_diffuse = 0.6 * 0.2;\n" +"const float ambient = 0.2;\n" +"const float emission = 0.15;\n" +"const vec3 UP = vec3(0, 0, 1);\n" +"uniform mat4 view_matrix;\n" +"uniform mat4 projection_matrix;\n" +"uniform vec3 camera_position;\n" +"uniform samplerBuffer position_tex;\n" +"uniform samplerBuffer height_width_angle_tex;\n" +"uniform samplerBuffer color_tex;\n" +"uniform usamplerBuffer segment_index_tex;\n" +"in int vertex_id;\n" +"out vec3 color;\n" +"vec3 decode_color(float color) {\n" +" int c = int(round(color));\n" +" int r = (c >> 16) & 0xFF;\n" +" int g = (c >> 8) & 0xFF;\n" +" int b = (c >> 0) & 0xFF;\n" +" float f = 1.0 / 255.0f;\n" +" return f * vec3(r, g, b);\n" +"}\n" +"float lighting(vec3 eye_position, vec3 eye_normal) {\n" +" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n" +" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n" +" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n" +" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n" +"}\n" +"void main() {\n" +" int id_a = int(texelFetch(segment_index_tex, gl_InstanceID).r);\n" +" int id_b = id_a + 1;\n" +" vec3 pos_a = texelFetch(position_tex, id_a).xyz;\n" +" vec3 pos_b = texelFetch(position_tex, id_b).xyz;\n" +" vec3 line = pos_b - pos_a;\n" +" // directions of the line box in world space\n" +" float line_len = length(line);\n" +" vec3 line_dir;\n" +" if (line_len < 1e-4)\n" +" line_dir = vec3(1.0, 0.0, 0.0);\n" +" else\n" +" line_dir = line / line_len;\n" +" vec3 line_right_dir;\n" +" if (abs(dot(line_dir, UP)) > 0.9) {\n" +" // For vertical lines, the width and height should be same, there is no concept of up and down.\n" +" // For simplicity, the code will expand width in the x axis, and height in the y axis\n" +" line_right_dir = normalize(cross(vec3(1, 0, 0), line_dir));\n" +" }\n" +" else\n" +" line_right_dir = normalize(cross(line_dir, UP));\n" +" vec3 line_up_dir = normalize(cross(line_right_dir, line_dir));\n" +" const vec2 horizontal_vertical_view_signs_array[16] = vec2[](\n" +" //horizontal view (from right)\n" +" vec2(1.0, 0.0),\n" +" vec2(0.0, 1.0),\n" +" vec2(0.0, 0.0),\n" +" vec2(0.0, -1.0),\n" +" vec2(0.0, -1.0),\n" +" vec2(1.0, 0.0),\n" +" vec2(0.0, 1.0),\n" +" vec2(0.0, 0.0),\n" +" // vertical view (from top)\n" +" vec2(0.0, 1.0),\n" +" vec2(-1.0, 0.0),\n" +" vec2(0.0, 0.0),\n" +" vec2(1.0, 0.0),\n" +" vec2(1.0, 0.0),\n" +" vec2(0.0, 1.0),\n" +" vec2(-1.0, 0.0),\n" +" vec2(0.0, 0.0)\n" +" );\n" +" int id = vertex_id < 4 ? id_a : id_b;\n" +" vec3 endpoint_pos = vertex_id < 4 ? pos_a : pos_b;\n" +" vec3 height_width_angle = texelFetch(height_width_angle_tex, id).xyz;\n" +"#ifdef FIX_TWISTING\n" +" int closer_id = (dot(camera_position - pos_a, camera_position - pos_a) < dot(camera_position - pos_b, camera_position - pos_b)) ? id_a : id_b;\n" +" vec3 closer_pos = (closer_id == id_a) ? pos_a : pos_b;\n" +" vec3 camera_view_dir = normalize(closer_pos - camera_position);\n" +" vec3 closer_height_width_angle = texelFetch(height_width_angle_tex, closer_id).xyz;\n" +" vec3 diagonal_dir_border = normalize(closer_height_width_angle.x * line_up_dir + closer_height_width_angle.y * line_right_dir);\n" +"#else\n" +" vec3 camera_view_dir = normalize(endpoint_pos - camera_position);\n" +" vec3 diagonal_dir_border = normalize(height_width_angle.x * line_up_dir + height_width_angle.y * line_right_dir);\n" +"#endif\n" +" bool is_vertical_view = abs(dot(camera_view_dir, line_up_dir)) / abs(dot(diagonal_dir_border, line_up_dir)) >\n" +" abs(dot(camera_view_dir, line_right_dir)) / abs(dot(diagonal_dir_border, line_right_dir));\n" +" vec2 signs = horizontal_vertical_view_signs_array[vertex_id + 8 * int(is_vertical_view)];\n" +"#ifndef POINTY_CAPS\n" +" if (vertex_id == 2 || vertex_id == 7) signs = -horizontal_vertical_view_signs_array[(vertex_id - 2) + 8 * int(is_vertical_view)];\n" +"#endif\n" +" float view_right_sign = sign(dot(-camera_view_dir, line_right_dir));\n" +" float view_top_sign = sign(dot(-camera_view_dir, line_up_dir));\n" +" float half_height = 0.5 * height_width_angle.x;\n" +" float half_width = 0.5 * height_width_angle.y;\n" +" vec3 horizontal_dir = half_width * line_right_dir;\n" +" vec3 vertical_dir = half_height * line_up_dir;\n" +" float horizontal_sign = signs.x * view_right_sign;\n" +" float vertical_sign = signs.y * view_top_sign;\n" +" vec3 pos = endpoint_pos + horizontal_sign * horizontal_dir + vertical_sign * vertical_dir;\n" +" if (vertex_id == 2 || vertex_id == 7) {\n" +" float line_dir_sign = (vertex_id == 2) ? -1.0 : 1.0;\n" +" if (height_width_angle.z == 0) {\n" +"#ifdef POINTY_CAPS\n" +" // There I add a cap to lines that do not have a following line\n" +" // (or they have one, but perfectly aligned, so the cap is hidden inside the next line).\n" +" pos += line_dir_sign * line_dir * half_width;\n" +"#endif\n" +" }\n" +" else {\n" +" pos += line_dir_sign * line_dir * half_width * sin(abs(height_width_angle.z) * 0.5);\n" +" pos += sign(height_width_angle.z) * horizontal_dir * cos(abs(height_width_angle.z) * 0.5);\n" +" }\n" +" }\n" +" vec3 eye_position = (view_matrix * vec4(pos, 1.0)).xyz;\n" +" vec3 eye_normal = (view_matrix * vec4(normalize(pos - endpoint_pos), 0.0)).xyz;\n" +" vec3 color_base = decode_color(texelFetch(color_tex, id).r);\n" +" color = color_base * lighting(eye_position, eye_normal);\n" +" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n" +"}\n"; + +static const char* Segments_Fragment_Shader = +"#version 150\n" +"in vec3 color;\n" +"out vec4 fragment_color;\n" +"void main() {\n" +" fragment_color = vec4(color, 1.0);\n" +"}\n"; + +static const char* Options_Vertex_Shader = +"#version 150\n" +"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n" +"const float light_top_diffuse = 0.6 * 0.8;\n" +"const float light_top_specular = 0.6 * 0.125;\n" +"const float light_top_shininess = 20.0;\n" +"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n" +"const float light_front_diffuse = 0.6 * 0.3;\n" +"const float ambient = 0.3;\n" +"const float emission = 0.25;\n" +#ifndef _WIN32 +"const float scaling_factor = 0.75;\n" +#else +"const float scaling_factor = 1.5;\n" +#endif +"uniform mat4 view_matrix;\n" +"uniform mat4 projection_matrix;\n" +"uniform samplerBuffer position_tex;\n" +"uniform samplerBuffer height_width_angle_tex;\n" +"uniform samplerBuffer color_tex;\n" +"uniform usamplerBuffer segment_index_tex;\n" +"in vec3 in_position;\n" +"in vec3 in_normal;\n" +"out vec3 color;\n" +"vec3 decode_color(float color) {\n" +" int c = int(round(color));\n" +" int r = (c >> 16) & 0xFF;\n" +" int g = (c >> 8) & 0xFF;\n" +" int b = (c >> 0) & 0xFF;\n" +" float f = 1.0 / 255.0f;\n" +" return f * vec3(r, g, b);\n" +"}\n" +"float lighting(vec3 eye_position, vec3 eye_normal) {\n" +" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n" +" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n" +" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n" +" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n" +"}\n" +"void main() {\n" +" int id = int(texelFetch(segment_index_tex, gl_InstanceID).r);\n" +" vec2 height_width = texelFetch(height_width_angle_tex, id).xy;\n" +" vec3 offset = texelFetch(position_tex, id).xyz - vec3(0.0, 0.0, 0.5 * height_width.x);\n" +" height_width *= scaling_factor;\n" +" mat3 scale_matrix = mat3(\n" +" height_width.y, 0.0, 0.0,\n" +" 0.0, height_width.y, 0.0,\n" +" 0.0, 0.0, height_width.x);\n" +" vec3 eye_position = (view_matrix * vec4(scale_matrix * in_position + offset, 1.0)).xyz;\n" +" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n" +" vec3 color_base = decode_color(texelFetch(color_tex, id).r);\n" +" color = color_base * lighting(eye_position, eye_normal);\n" +" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n" +"}\n"; + +static const char* Options_Fragment_Shader = +"#version 150\n" +"in vec3 color;\n" +"out vec4 fragment_color;\n" +"void main() {\n" +" fragment_color = vec4(color, 1.0);\n" +"}\n"; + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS +static const char* Cog_Marker_Vertex_Shader = +"#version 150\n" +"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n" +"const float light_top_diffuse = 0.6 * 0.8;\n" +"const float light_top_specular = 0.6 * 0.125;\n" +"const float light_top_shininess = 20.0;\n" +"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n" +"const float light_front_diffuse = 0.6 * 0.3;\n" +"const float ambient = 0.3;\n" +"const float emission = 0.25;\n" +"uniform vec3 world_center_position;\n" +"uniform float scale_factor;\n" +"uniform mat4 view_matrix;\n" +"uniform mat4 projection_matrix;\n" +"in vec3 in_position;\n" +"in vec3 in_normal;\n" +"out float intensity;\n" +"out vec3 world_position;\n" +"float lighting(vec3 eye_position, vec3 eye_normal) {\n" +" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n" +" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n" +" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n" +" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n" +"}\n" +"void main() {\n" +" world_position = scale_factor * in_position + world_center_position;\n" +" vec3 eye_position = (view_matrix * vec4(world_position, 1.0)).xyz;\n" +" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n" +" intensity = lighting(eye_position, eye_normal);\n" +" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n" +"}\n"; + +static const char* Cog_Marker_Fragment_Shader = +"#version 150\n" +"const vec3 BLACK = vec3(0.05);\n" +"const vec3 WHITE = vec3(0.95);\n" +"uniform vec3 world_center_position;\n" +"in float intensity;\n" +"in vec3 world_position;\n" +"out vec4 out_color;\n" +"void main()\n" +"{\n" +" vec3 delta = world_position - world_center_position;\n" +" vec3 color = delta.x * delta.y * delta.z > 0.0 ? BLACK : WHITE;\n" +" out_color = intensity * vec4(color, 1.0);\n" +"}\n"; + +static const char* Tool_Marker_Vertex_Shader = +"#version 150\n" +"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n" +"const float light_top_diffuse = 0.6 * 0.8;\n" +"const float light_top_specular = 0.6 * 0.125;\n" +"const float light_top_shininess = 20.0;\n" +"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n" +"const float light_front_diffuse = 0.6 * 0.3;\n" +"const float ambient = 0.3;\n" +"const float emission = 0.25;\n" +"uniform vec3 world_origin;\n" +"uniform float scale_factor;\n" +"uniform mat4 view_matrix;\n" +"uniform mat4 projection_matrix;\n" +"uniform vec4 color_base;\n" +"in vec3 in_position;\n" +"in vec3 in_normal;\n" +"out vec4 color;\n" +"float lighting(vec3 eye_position, vec3 eye_normal) {\n" +" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n" +" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n" +" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n" +" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n" +"}\n" +"void main() {\n" +" vec3 world_position = scale_factor * in_position + world_origin;\n" +" vec3 eye_position = (view_matrix * vec4(world_position, 1.0)).xyz;\n" +" // no need of normal matrix as the scaling is uniform\n" +" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n" +" color = vec4(color_base.rgb * lighting(eye_position, eye_normal), color_base.a);\n" +" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n" +"}\n"; + +static const char* Tool_Marker_Fragment_Shader = +"#version 150\n" +"in vec4 color;\n" +"out vec4 fragment_color;\n" +"void main() {\n" +" fragment_color = color;\n" +"}\n"; +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + +} // namespace libvgcode + +#endif // VGCODE_SHADERS_HPP + diff --git a/src/libvgcode/src/ShadersES.hpp b/src/libvgcode/src/ShadersES.hpp new file mode 100644 index 0000000000..e688fa7b4c --- /dev/null +++ b/src/libvgcode/src/ShadersES.hpp @@ -0,0 +1,322 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_SHADERSES_HPP +#define VGCODE_SHADERSES_HPP + +// needed for tech VGCODE_ENABLE_COG_AND_TOOL_MARKERS +#include "../include/Types.hpp" + +namespace libvgcode { + +static const char* Segments_Vertex_Shader_ES = +"#version 300 es\n" +"precision lowp usampler2D;\n" +"#define POINTY_CAPS\n" +"#define FIX_TWISTING\n" +"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n" +"const float light_top_diffuse = 0.6 * 0.8;\n" +"const float light_top_specular = 0.6 * 0.125;\n" +"const float light_top_shininess = 20.0;\n" +"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n" +"const float light_front_diffuse = 0.6 * 0.3;\n" +"const float ambient = 0.3;\n" +"const float emission = 0.15;\n" +"const vec3 UP = vec3(0, 0, 1);\n" +"uniform mat4 view_matrix;\n" +"uniform mat4 projection_matrix;\n" +"uniform vec3 camera_position;\n" +"uniform sampler2D position_tex;\n" +"uniform sampler2D height_width_angle_tex;\n" +"uniform sampler2D color_tex;\n" +"uniform usampler2D segment_index_tex;\n" +"in float vertex_id_float;\n" +"out vec3 color;\n" +"vec3 decode_color(float color) {\n" +" int c = int(round(color));\n" +" int r = (c >> 16) & 0xFF;\n" +" int g = (c >> 8) & 0xFF;\n" +" int b = (c >> 0) & 0xFF;\n" +" float f = 1.0 / 255.0f;\n" +" return f * vec3(r, g, b);\n" +"}\n" +"float lighting(vec3 eye_position, vec3 eye_normal) {\n" +" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n" +" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n" +" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n" +" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n" +"}\n" +"ivec2 tex_coord(sampler2D sampler, int id) {\n" +" ivec2 tex_size = textureSize(sampler, 0);\n" +" return (tex_size.y == 1) ? ivec2(id, 0) : ivec2(id % tex_size.x, id / tex_size.x);\n" +"}\n" +"ivec2 tex_coord_u(usampler2D sampler, int id) {\n" +" ivec2 tex_size = textureSize(sampler, 0);\n" +" return (tex_size.y == 1) ? ivec2(id, 0) : ivec2(id % tex_size.x, id / tex_size.x);\n" +"}\n" +"void main() {\n" +" int vertex_id = int(vertex_id_float);\n" +" int id_a = int(texelFetch(segment_index_tex, tex_coord_u(segment_index_tex, gl_InstanceID), 0).r);\n" +" int id_b = id_a + 1;\n" +" vec3 pos_a = texelFetch(position_tex, tex_coord(position_tex, id_a), 0).xyz;\n" +" vec3 pos_b = texelFetch(position_tex, tex_coord(position_tex, id_b), 0).xyz;\n" +" vec3 line = pos_b - pos_a;\n" +" // directions of the line box in world space\n" +" float line_len = length(line);\n" +" vec3 line_dir;\n" +" if (line_len < 1e-4)\n" +" line_dir = vec3(1.0, 0.0, 0.0);\n" +" else\n" +" line_dir = line / line_len;\n" +" vec3 line_right_dir;\n" +" if (abs(dot(line_dir, UP)) > 0.9) {\n" +" // For vertical lines, the width and height should be same, there is no concept of up and down.\n" +" // For simplicity, the code will expand width in the x axis, and height in the y axis\n" +" line_right_dir = normalize(cross(vec3(1, 0, 0), line_dir));\n" +" }\n" +" else\n" +" line_right_dir = normalize(cross(line_dir, UP));\n" +" vec3 line_up_dir = normalize(cross(line_right_dir, line_dir));\n" +" const vec2 horizontal_vertical_view_signs_array[16] = vec2[](\n" +" //horizontal view (from right)\n" +" vec2(1.0, 0.0),\n" +" vec2(0.0, 1.0),\n" +" vec2(0.0, 0.0),\n" +" vec2(0.0, -1.0),\n" +" vec2(0.0, -1.0),\n" +" vec2(1.0, 0.0),\n" +" vec2(0.0, 1.0),\n" +" vec2(0.0, 0.0),\n" +" // vertical view (from top)\n" +" vec2(0.0, 1.0),\n" +" vec2(-1.0, 0.0),\n" +" vec2(0.0, 0.0),\n" +" vec2(1.0, 0.0),\n" +" vec2(1.0, 0.0),\n" +" vec2(0.0, 1.0),\n" +" vec2(-1.0, 0.0),\n" +" vec2(0.0, 0.0)\n" +" );\n" +" int id = vertex_id < 4 ? id_a : id_b;\n" +" vec3 endpoint_pos = vertex_id < 4 ? pos_a : pos_b;\n" +" vec3 height_width_angle = texelFetch(height_width_angle_tex, tex_coord(height_width_angle_tex, id), 0).xyz;\n" +"#ifdef FIX_TWISTING\n" +" int closer_id = (dot(camera_position - pos_a, camera_position - pos_a) < dot(camera_position - pos_b, camera_position - pos_b)) ? id_a : id_b;\n" +" vec3 closer_pos = (closer_id == id_a) ? pos_a : pos_b;\n" +" vec3 camera_view_dir = normalize(closer_pos - camera_position);\n" +" vec3 closer_height_width_angle = texelFetch(height_width_angle_tex, tex_coord(height_width_angle_tex, closer_id), 0).xyz;\n" +" vec3 diagonal_dir_border = normalize(closer_height_width_angle.x * line_up_dir + closer_height_width_angle.y * line_right_dir);\n" +"#else\n" +" vec3 camera_view_dir = normalize(endpoint_pos - camera_position);\n" +" vec3 diagonal_dir_border = normalize(height_width_angle.x * line_up_dir + height_width_angle.y * line_right_dir);\n" +"#endif\n" +" bool is_vertical_view = abs(dot(camera_view_dir, line_up_dir)) / abs(dot(diagonal_dir_border, line_up_dir)) >\n" +" abs(dot(camera_view_dir, line_right_dir)) / abs(dot(diagonal_dir_border, line_right_dir));\n" +" vec2 signs = horizontal_vertical_view_signs_array[vertex_id + 8 * int(is_vertical_view)];\n" +"#ifndef POINTY_CAPS\n" +" if (vertex_id == 2 || vertex_id == 7) signs = -horizontal_vertical_view_signs_array[(vertex_id - 2) + 8 * int(is_vertical_view)];\n" +"#endif\n" +" float view_right_sign = sign(dot(-camera_view_dir, line_right_dir));\n" +" float view_top_sign = sign(dot(-camera_view_dir, line_up_dir));\n" +" float half_height = 0.5 * height_width_angle.x;\n" +" float half_width = 0.5 * height_width_angle.y;\n" +" vec3 horizontal_dir = half_width * line_right_dir;\n" +" vec3 vertical_dir = half_height * line_up_dir;\n" +" float horizontal_sign = signs.x * view_right_sign;\n" +" float vertical_sign = signs.y * view_top_sign;\n" +" vec3 pos = endpoint_pos + horizontal_sign * horizontal_dir + vertical_sign * vertical_dir;\n" +" if (vertex_id == 2 || vertex_id == 7) {\n" +" float line_dir_sign = (vertex_id == 2) ? -1.0 : 1.0;\n" +" if (height_width_angle.z == 0.0) {\n" +"#ifdef POINTY_CAPS\n" +" // There I add a cap to lines that do not have a following line\n" +" // (or they have one, but perfectly aligned, so the cap is hidden inside the next line).\n" +" pos += line_dir_sign * line_dir * half_width;\n" +"#endif\n" +" }\n" +" else {\n" +" pos += line_dir_sign * line_dir * half_width * sin(abs(height_width_angle.z) * 0.5);\n" +" pos += sign(height_width_angle.z) * horizontal_dir * cos(abs(height_width_angle.z) * 0.5);\n" +" }\n" +" }\n" +" vec3 eye_position = (view_matrix * vec4(pos, 1.0)).xyz;\n" +" vec3 eye_normal = (view_matrix * vec4(normalize(pos - endpoint_pos), 0.0)).xyz;\n" +" vec3 color_base = decode_color(texelFetch(color_tex, tex_coord(color_tex, id), 0).r);\n" +" color = color_base * lighting(eye_position, eye_normal);\n" +" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n" +"}\n"; + +static const char* Segments_Fragment_Shader_ES = +"#version 300 es\n" +"precision highp float;\n" +"in vec3 color;\n" +"out vec4 fragment_color;\n" +"void main() {\n" +" fragment_color = vec4(color, 1.0);\n" +"}\n"; + +static const char* Options_Vertex_Shader_ES = +"#version 300 es\n" +"precision lowp usampler2D;\n" +"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n" +"const float light_top_diffuse = 0.6 * 0.8;\n" +"const float light_top_specular = 0.6 * 0.125;\n" +"const float light_top_shininess = 20.0;\n" +"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n" +"const float light_front_diffuse = 0.6 * 0.3;\n" +"const float ambient = 0.3;\n" +"const float emission = 0.25;\n" +"const float scaling_factor = 1.5;\n" +"uniform mat4 view_matrix;\n" +"uniform mat4 projection_matrix;\n" +"uniform sampler2D position_tex;\n" +"uniform sampler2D height_width_angle_tex;\n" +"uniform sampler2D color_tex;\n" +"uniform usampler2D segment_index_tex;\n" +"in vec3 in_position;\n" +"in vec3 in_normal;\n" +"out vec3 color;\n" +"vec3 decode_color(float color) {\n" +" int c = int(round(color));\n" +" int r = (c >> 16) & 0xFF;\n" +" int g = (c >> 8) & 0xFF;\n" +" int b = (c >> 0) & 0xFF;\n" +" float f = 1.0 / 255.0f;\n" +" return f * vec3(r, g, b);\n" +"}\n" +"float lighting(vec3 eye_position, vec3 eye_normal) {\n" +" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n" +" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n" +" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n" +" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n" +"}\n" +"ivec2 tex_coord(sampler2D sampler, int id) {\n" +" ivec2 tex_size = textureSize(sampler, 0);\n" +" return (tex_size.y == 1) ? ivec2(id, 0) : ivec2(id % tex_size.x, id / tex_size.x);\n" +"}\n" +"ivec2 tex_coord_u(usampler2D sampler, int id) {\n" +" ivec2 tex_size = textureSize(sampler, 0);\n" +" return (tex_size.y == 1) ? ivec2(id, 0) : ivec2(id % tex_size.x, id / tex_size.x);\n" +"}\n" +"void main() {\n" +" int id = int(texelFetch(segment_index_tex, tex_coord_u(segment_index_tex, gl_InstanceID), 0).r);\n" +" vec2 height_width = texelFetch(height_width_angle_tex, tex_coord(height_width_angle_tex, id), 0).xy;\n" +" vec3 offset = texelFetch(position_tex, tex_coord(position_tex, id), 0).xyz - vec3(0.0, 0.0, 0.5 * height_width.x);\n" +" height_width *= scaling_factor;\n" +" mat3 scale_matrix = mat3(\n" +" height_width.y, 0.0, 0.0,\n" +" 0.0, height_width.y, 0.0,\n" +" 0.0, 0.0, height_width.x);\n" +" vec3 eye_position = (view_matrix * vec4(scale_matrix * in_position + offset, 1.0)).xyz;\n" +" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n" +" vec3 color_base = decode_color(texelFetch(color_tex, tex_coord(color_tex, id), 0).r);\n" +" color = color_base * lighting(eye_position, eye_normal);\n" +" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n" +"}\n"; + +static const char* Options_Fragment_Shader_ES = +"#version 300 es\n" +"precision highp float;\n" +"in vec3 color;\n" +"out vec4 fragment_color;\n" +"void main() {\n" +" fragment_color = vec4(color, 1.0);\n" +"}\n"; + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS +static const char* Cog_Marker_Vertex_Shader_ES = +"#version 300 es\n" +"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n" +"const float light_top_diffuse = 0.6 * 0.8;\n" +"const float light_top_specular = 0.6 * 0.125;\n" +"const float light_top_shininess = 20.0;\n" +"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n" +"const float light_front_diffuse = 0.6 * 0.3;\n" +"const float ambient = 0.3;\n" +"const float emission = 0.25;\n" +"uniform vec3 world_center_position;\n" +"uniform float scale_factor;\n" +"uniform mat4 view_matrix;\n" +"uniform mat4 projection_matrix;\n" +"in vec3 in_position;\n" +"in vec3 in_normal;\n" +"out float intensity;\n" +"out vec3 world_position;\n" +"float lighting(vec3 eye_position, vec3 eye_normal) {\n" +" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n" +" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n" +" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n" +" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n" +"}\n" +"void main() {\n" +" world_position = scale_factor * in_position + world_center_position;\n" +" vec3 eye_position = (view_matrix * vec4(world_position, 1.0)).xyz;\n" +" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n" +" intensity = lighting(eye_position, eye_normal);\n" +" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n" +"}\n"; + +static const char* Cog_Marker_Fragment_Shader_ES = +"#version 300 es\n" +"precision highp float;\n" +"const vec3 BLACK = vec3(0.05);\n" +"const vec3 WHITE = vec3(0.95);\n" +"uniform vec3 world_center_position;\n" +"in float intensity;\n" +"in vec3 world_position;\n" +"out vec4 out_color;\n" +"void main()\n" +"{\n" +" vec3 delta = world_position - world_center_position;\n" +" vec3 color = delta.x * delta.y * delta.z > 0.0 ? BLACK : WHITE;\n" +" out_color = intensity * vec4(color, 1.0);\n" +"}\n"; + +static const char* Tool_Marker_Vertex_Shader_ES = +"#version 300 es\n" +"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n" +"const float light_top_diffuse = 0.6 * 0.8;\n" +"const float light_top_specular = 0.6 * 0.125;\n" +"const float light_top_shininess = 20.0;\n" +"const vec3 light_front_dir = vec3(0.6985074, 0.1397015, 0.6985074);\n" +"const float light_front_diffuse = 0.6 * 0.3;\n" +"const float ambient = 0.3;\n" +"const float emission = 0.25;\n" +"uniform vec3 world_origin;\n" +"uniform float scale_factor;\n" +"uniform mat4 view_matrix;\n" +"uniform mat4 projection_matrix;\n" +"uniform vec4 color_base;\n" +"in vec3 in_position;\n" +"in vec3 in_normal;\n" +"out vec4 color;\n" +"float lighting(vec3 eye_position, vec3 eye_normal) {\n" +" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n" +" float front_diffuse = light_front_diffuse * max(dot(eye_normal, light_front_dir), 0.0);\n" +" float top_specular = light_top_specular * pow(max(dot(-normalize(eye_position), reflect(-light_top_dir, eye_normal)), 0.0), light_top_shininess);\n" +" return ambient + top_diffuse + front_diffuse + top_specular + emission;\n" +"}\n" +"void main() {\n" +" vec3 world_position = scale_factor * in_position + world_origin;\n" +" vec3 eye_position = (view_matrix * vec4(world_position, 1.0)).xyz;\n" +" // no need of normal matrix as the scaling is uniform\n" +" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n" +" color = vec4(color_base.rgb * lighting(eye_position, eye_normal), color_base.a);\n" +" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n" +"}\n"; + +static const char* Tool_Marker_Fragment_Shader_ES = +"#version 300 es\n" +"precision highp float;\n" +"in vec4 color;\n" +"out vec4 fragment_color;\n" +"void main() {\n" +" fragment_color = color;\n" +"}\n"; +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + +} // namespace libvgcode + +#endif // VGCODE_SHADERSES_HPP + diff --git a/src/libvgcode/src/ToolMarker.cpp b/src/libvgcode/src/ToolMarker.cpp new file mode 100644 index 0000000000..3e595faec0 --- /dev/null +++ b/src/libvgcode/src/ToolMarker.cpp @@ -0,0 +1,172 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "ToolMarker.hpp" +#include "OpenGLUtils.hpp" +#include "Utils.hpp" + +#include + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + +namespace libvgcode { + +// Geometry: +// Arrow with cylindrical stem and conical tip, with the given dimensions and resolution +// The origin of the arrow is at the tip of the conical section +// The axis of symmetry is along the Z axis +// The arrow is pointing downward +void ToolMarker::init(uint16_t resolution, float tip_radius, float tip_height, float stem_radius, float stem_height) +{ + if (m_vao_id != 0) + return; + + // ensure vertices count does not exceed 65536 + resolution = std::clamp(resolution, 4, 10922); + + std::vector vertices; + const uint16_t vertices_count = 6 * resolution + 2; + vertices.reserve(6 * vertices_count); + + m_indices_count = 6 * resolution * 3; + std::vector indices; + indices.reserve(m_indices_count); + + const float angle_step = 2.0f * PI / float(resolution); + std::vector cosines(resolution); + std::vector sines(resolution); + + for (uint16_t i = 0; i < resolution; ++i) { + const float angle = angle_step * float(i); + cosines[i] = std::cos(angle); + sines[i] = -std::sin(angle); + } + + const float total_height = tip_height + stem_height; + + // tip vertices + add_vertex({ 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, -1.0f }, vertices); + for (uint16_t i = 0; i < resolution; ++i) { + add_vertex({ tip_radius * sines[i], tip_radius * cosines[i], tip_height }, { sines[i], cosines[i], 0.0f }, vertices); + } + + // tip triangles + for (uint16_t i = 0; i < resolution; ++i) { + const uint16_t v3 = (i < resolution - 1) ? i + 2 : 1; + add_triangle(0, i + 1, v3, indices); + } + + // tip cap outer perimeter vertices + for (uint16_t i = 0; i < resolution; ++i) { + add_vertex({ tip_radius * sines[i], tip_radius * cosines[i], tip_height }, { 0.0f, 0.0f, 1.0f }, vertices); + } + + // tip cap inner perimeter vertices + for (uint16_t i = 0; i < resolution; ++i) { + add_vertex({ stem_radius * sines[i], stem_radius * cosines[i], tip_height }, { 0.0f, 0.0f, 1.0f }, vertices); + } + + // tip cap triangles + for (uint16_t i = 0; i < resolution; ++i) { + const uint16_t v2 = (i < resolution - 1) ? i + resolution + 2 : resolution + 1; + const uint16_t v3 = (i < resolution - 1) ? i + 2 * resolution + 2 : 2 * resolution + 1; + add_triangle(i + resolution + 1, v3, v2, indices); + add_triangle(i + resolution + 1, i + 2 * resolution + 1, v3, indices); + } + + // stem bottom vertices + for (uint16_t i = 0; i < resolution; ++i) { + add_vertex({ stem_radius * sines[i], stem_radius * cosines[i], tip_height }, { sines[i], cosines[i], 0.0f }, vertices); + } + + // stem top vertices + for (uint16_t i = 0; i < resolution; ++i) { + add_vertex({ stem_radius * sines[i], stem_radius * cosines[i], total_height }, { sines[i], cosines[i], 0.0f }, vertices); + } + + // stem triangles + for (uint16_t i = 0; i < resolution; ++i) { + const uint16_t v2 = (i < resolution - 1) ? i + 3 * resolution + 2 : 3 * resolution + 1; + const uint16_t v3 = (i < resolution - 1) ? i + 4 * resolution + 2 : 4 * resolution + 1; + add_triangle(i + 3 * resolution + 1, v3, v2, indices); + add_triangle(i + 3 * resolution + 1, i + 4 * resolution + 1, v3, indices); + } + + // stem cap vertices + add_vertex({ 0.0f, 0.0f, total_height }, { 0.0f, 0.0f, 1.0f }, vertices); + for (uint16_t i = 0; i < resolution; ++i) { + add_vertex({ stem_radius * sines[i], stem_radius * cosines[i], total_height }, { 0.0f, 0.0f, 1.0f }, vertices); + } + + // stem cap triangles + for (uint16_t i = 0; i < resolution; ++i) { + const uint16_t v3 = (i < resolution - 1) ? i + 5 * resolution + 3 : 5 * resolution + 2; + add_triangle(5 * resolution + 1, v3, i + 5 * resolution + 2, indices); + } + + m_size_in_bytes_gpu += vertices.size() * sizeof(float); + m_size_in_bytes_gpu += indices.size() * sizeof(uint16_t); + + const size_t vertex_stride = 6 * sizeof(float); + const size_t position_offset = 0; + const size_t normal_offset = 3 * sizeof(float); + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + int curr_array_buffer; + glsafe(glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &curr_array_buffer)); + + glsafe(glGenVertexArrays(1, &m_vao_id)); + glsafe(glBindVertexArray(m_vao_id)); + glsafe(glGenBuffers(1, &m_vbo_id)); + glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); + glsafe(glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW)); + glsafe(glEnableVertexAttribArray(0)); + glsafe(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)position_offset)); + glsafe(glEnableVertexAttribArray(1)); + glsafe(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)normal_offset)); + + glsafe(glGenBuffers(1, &m_ibo_id)); + glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo_id)); + glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), indices.data(), GL_STATIC_DRAW)); + + glsafe(glBindBuffer(GL_ARRAY_BUFFER, curr_array_buffer)); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +void ToolMarker::shutdown() +{ + if (m_ibo_id != 0) { + glsafe(glDeleteBuffers(1, &m_ibo_id)); + m_ibo_id = 0; + } + if (m_vbo_id != 0) { + glsafe(glDeleteBuffers(1, &m_vbo_id)); + m_vbo_id = 0; + } + if (m_vao_id != 0) { + glsafe(glDeleteVertexArrays(1, &m_vao_id)); + m_vao_id = 0; + } + + m_size_in_bytes_gpu = 0; +} + +void ToolMarker::render() +{ + if (m_vao_id == 0 || m_vbo_id == 0 || m_ibo_id == 0) + return; + + int curr_vertex_array; + glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); + glcheck(); + + glsafe(glBindVertexArray(m_vao_id)); + glsafe(glDrawElements(GL_TRIANGLES, m_indices_count, GL_UNSIGNED_SHORT, (const void*)0)); + glsafe(glBindVertexArray(curr_vertex_array)); +} + +} // namespace libvgcode + +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS diff --git a/src/libvgcode/src/ToolMarker.hpp b/src/libvgcode/src/ToolMarker.hpp new file mode 100644 index 0000000000..83d6fa02f8 --- /dev/null +++ b/src/libvgcode/src/ToolMarker.hpp @@ -0,0 +1,75 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_TOOLMARKER_HPP +#define VGCODE_TOOLMARKER_HPP + +#include "../include/Types.hpp" + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS +#include + +namespace libvgcode { + +class ToolMarker +{ +public: + ToolMarker() = default; + ~ToolMarker() { shutdown(); } + ToolMarker(const ToolMarker& other) = delete; + ToolMarker(ToolMarker&& other) = delete; + ToolMarker& operator = (const ToolMarker& other) = delete; + ToolMarker& operator = (ToolMarker&& other) = delete; + + // + // Initialize gpu buffers. + // + void init(uint16_t resolution, float tip_radius, float tip_height, float stem_radius, float stem_height); + // + // Release gpu buffers. + // + void shutdown(); + void render(); + + const Vec3& get_position() const { return m_position; } + void set_position(const Vec3& position) { m_position = position; } + + float get_offset_z() const { return m_offset_z; } + void set_offset_z(float offset_z) { m_offset_z = std::max(offset_z, 0.0f); } + + const Color& get_color() const { return m_color; } + void set_color(const Color& color) { m_color = color; } + + float get_alpha() const { return m_alpha; } + void set_alpha(float alpha) { m_alpha = std::clamp(alpha, 0.25f, 0.75f); } + + // + // Return the size of the data sent to gpu, in bytes. + // + size_t size_in_bytes_gpu() const { return m_size_in_bytes_gpu; } + +private: + Vec3 m_position{ 0.0f, 0.0f, 0.0f }; + float m_offset_z{ 0.5f }; + Color m_color{ 255, 255, 255 }; + float m_alpha{ 0.5f }; + + uint16_t m_indices_count{ 0 }; + // + // gpu buffers ids. + // + unsigned int m_vao_id{ 0 }; + unsigned int m_vbo_id{ 0 }; + unsigned int m_ibo_id{ 0 }; + // + // Size of the data sent to gpu, in bytes. + // + size_t m_size_in_bytes_gpu{ 0 }; +}; + +} // namespace libvgcode + +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + +#endif // VGCODE_TOOLMARKER_HPP \ No newline at end of file diff --git a/src/libvgcode/src/Types.cpp b/src/libvgcode/src/Types.cpp new file mode 100644 index 0000000000..2aa8a40e9d --- /dev/null +++ b/src/libvgcode/src/Types.cpp @@ -0,0 +1,42 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "../include/Types.hpp" + +#include + +namespace libvgcode { + +// mapping from EMoveType to EOptionType +EOptionType move_type_to_option(EMoveType type) +{ + switch (type) + { + case EMoveType::Travel: { return EOptionType::Travels; } + case EMoveType::Wipe: { return EOptionType::Wipes; } + case EMoveType::Retract: { return EOptionType::Retractions; } + case EMoveType::Unretract: { return EOptionType::Unretractions; } + case EMoveType::Seam: { return EOptionType::Seams; } + case EMoveType::ToolChange: { return EOptionType::ToolChanges; } + case EMoveType::ColorChange: { return EOptionType::ColorChanges; } + case EMoveType::PausePrint: { return EOptionType::PausePrints; } + case EMoveType::CustomGCode: { return EOptionType::CustomGCodes; } + default: { return EOptionType::COUNT; } + } +} + +static uint8_t lerp(uint8_t f1, uint8_t f2, float t) +{ + const float one_minus_t = 1.0f - t; + return static_cast(one_minus_t * static_cast(f1) + t * static_cast(f2)); +} + +// It will be possible to replace this with std::lerp when using c++20 +Color lerp(const Color& c1, const Color& c2, float t) +{ + t = std::clamp(t, 0.0f, 1.0f); + return { lerp(c1[0], c2[0], t), lerp(c1[1], c2[1], t), lerp(c1[2], c2[2], t) }; +} + +} // namespace libvgcode diff --git a/src/libvgcode/src/Utils.cpp b/src/libvgcode/src/Utils.cpp new file mode 100644 index 0000000000..aee2cd4875 --- /dev/null +++ b/src/libvgcode/src/Utils.cpp @@ -0,0 +1,68 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "Utils.hpp" + +#include +#include + +namespace libvgcode { + +void add_vertex(const Vec3& position, const Vec3& normal, std::vector& vertices) +{ + vertices.emplace_back(position[0]); + vertices.emplace_back(position[1]); + vertices.emplace_back(position[2]); + vertices.emplace_back(normal[0]); + vertices.emplace_back(normal[1]); + vertices.emplace_back(normal[2]); +} + +void add_triangle(uint16_t v1, uint16_t v2, uint16_t v3, std::vector& indices) +{ + indices.emplace_back(v1); + indices.emplace_back(v2); + indices.emplace_back(v3); +} + +Vec3 normalize(const Vec3& v) +{ + const float length = std::sqrt(dot(v, v)); + assert(length > 0.0f); + const float inv_length = 1.0f / length; + return { v[0] * inv_length, v[1] * inv_length, v[2] * inv_length }; +} + +float dot(const Vec3& v1, const Vec3& v2) +{ + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; +} + +float length(const Vec3& v) +{ + return std::sqrt(dot(v, v)); +} + +bool operator == (const Vec3& v1, const Vec3& v2) { + return v1[0] == v2[0] && v1[1] == v2[1] && v1[2] == v2[2]; +} + +bool operator != (const Vec3& v1, const Vec3& v2) { + return v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]; +} + +Vec3 operator + (const Vec3& v1, const Vec3& v2) { + return { v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2] }; +} + +Vec3 operator - (const Vec3& v1, const Vec3& v2) { + return { v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2] }; +} + +Vec3 operator * (float f, const Vec3& v) { + return { f * v[0], f * v[1], f * v[2] }; +} + +} // namespace libvgcode + diff --git a/src/libvgcode/src/Utils.hpp b/src/libvgcode/src/Utils.hpp new file mode 100644 index 0000000000..84c3deb3c5 --- /dev/null +++ b/src/libvgcode/src/Utils.hpp @@ -0,0 +1,31 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_UTILS_HPP +#define VGCODE_UTILS_HPP + +#include "../include/Types.hpp" + +#ifdef _WIN32 +#define STDVEC_MEMSIZE(NAME, TYPE) NAME.capacity() * ((sizeof(TYPE) + __alignof(TYPE) - 1) / __alignof(TYPE)) * __alignof(TYPE) +#else +#define STDVEC_MEMSIZE(NAME, TYPE) NAME.capacity() * ((sizeof(TYPE) + alignof(TYPE) - 1) / alignof(TYPE)) * alignof(TYPE) +#endif // _WIN32 + +namespace libvgcode { + +extern void add_vertex(const Vec3& position, const Vec3& normal, std::vector& vertices); +extern void add_triangle(uint16_t v1, uint16_t v2, uint16_t v3, std::vector& indices); +extern Vec3 normalize(const Vec3& v); +extern float dot(const Vec3& v1, const Vec3& v2); +extern float length(const Vec3& v); +extern bool operator == (const Vec3& v1, const Vec3& v2); +extern bool operator != (const Vec3& v1, const Vec3& v2); +extern Vec3 operator + (const Vec3& v1, const Vec3& v2); +extern Vec3 operator - (const Vec3& v1, const Vec3& v2); +extern Vec3 operator * (float f, const Vec3& v); + +} // namespace libvgcode + +#endif // VGCODE_UTILS_HPP \ No newline at end of file diff --git a/src/libvgcode/src/ViewRange.cpp b/src/libvgcode/src/ViewRange.cpp new file mode 100644 index 0000000000..ea2f1e916e --- /dev/null +++ b/src/libvgcode/src/ViewRange.cpp @@ -0,0 +1,39 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "ViewRange.hpp" + +namespace libvgcode { + +void ViewRange::set_full(Interval::value_type min, Interval::value_type max) +{ + m_full.set(min, max); + // force the enabled range to stay inside the modified full range + m_full.clamp(m_enabled); + // force the visible range to stay inside the modified enabled range + m_enabled.clamp(m_visible); +} + +void ViewRange::set_enabled(Interval::value_type min, Interval::value_type max) +{ + m_enabled.set(min, max); + // force the visible range to stay inside the modified enabled range + m_enabled.clamp(m_visible); +} + +void ViewRange::set_visible(Interval::value_type min, Interval::value_type max) +{ + m_visible.set(min, max); + // force the visible range to stay inside the enabled range + m_enabled.clamp(m_visible); +} + +void ViewRange::reset() +{ + m_full.reset(); + m_enabled.reset(); + m_visible.reset(); +} + +} // namespace libvgcode diff --git a/src/libvgcode/src/ViewRange.hpp b/src/libvgcode/src/ViewRange.hpp new file mode 100644 index 0000000000..b9356fc760 --- /dev/null +++ b/src/libvgcode/src/ViewRange.hpp @@ -0,0 +1,56 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_VIEWRANGE_HPP +#define VGCODE_VIEWRANGE_HPP + +#include "Range.hpp" + +namespace libvgcode { + +class ViewRange +{ +public: + const Interval& get_full() const { return m_full.get(); } + void set_full(const Range& other) { set_full(other.get()); } + void set_full(const Interval& range) { set_full(range[0], range[1]); } + void set_full(Interval::value_type min, Interval::value_type max); + + const Interval& get_enabled() const { return m_enabled.get(); } + void set_enabled(const Range& other) { set_enabled(other.get()); } + void set_enabled(const Interval& range) { set_enabled(range[0], range[1]); } + void set_enabled(Interval::value_type min, Interval::value_type max); + + const Interval& get_visible() const { return m_visible.get(); } + void set_visible(const Range& other) { set_visible(other.get()); } + void set_visible(const Interval& range) { set_visible(range[0], range[1]); } + void set_visible(Interval::value_type min, Interval::value_type max); + + void reset(); + +private: + // + // Full range + // The range of moves that could potentially be visible. + // It is usually equal to the enabled range, unless Settings::top_layer_only_view_range is set to true. + // + Range m_full; + + // + // Enabled range + // The range of moves that are enabled for visualization. + // It is usually equal to the full range, unless Settings::top_layer_only_view_range is set to true. + // + Range m_enabled; + + // + // Visible range + // The range of moves that are currently rendered. + // + Range m_visible; +}; + +} // namespace libvgcode + +#endif // VGCODE_VIEWRANGE_HPP \ No newline at end of file diff --git a/src/libvgcode/src/Viewer.cpp b/src/libvgcode/src/Viewer.cpp new file mode 100644 index 0000000000..612a1ed0a8 --- /dev/null +++ b/src/libvgcode/src/Viewer.cpp @@ -0,0 +1,422 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "../include/Viewer.hpp" +#include "ViewerImpl.hpp" + +namespace libvgcode { + +Viewer::Viewer() +{ + m_impl = new ViewerImpl(); +} + +Viewer::~Viewer() +{ + delete m_impl; +} + +void Viewer::init(const std::string& opengl_context_version) +{ + m_impl->init(opengl_context_version); +} + +void Viewer::shutdown() +{ + m_impl->shutdown(); +} + +void Viewer::reset() +{ + m_impl->reset(); +} + +void Viewer::load(GCodeInputData&& gcode_data) +{ + m_impl->load(std::move(gcode_data)); +} + +void Viewer::render(const Mat4x4& view_matrix, const Mat4x4& projection_matrix) +{ + m_impl->render(view_matrix, projection_matrix); +} + +EViewType Viewer::get_view_type() const +{ + return m_impl->get_view_type(); +} + +void Viewer::set_view_type(EViewType type) +{ + m_impl->set_view_type(type); +} + +ETimeMode Viewer::get_time_mode() const +{ + return m_impl->get_time_mode(); +} + +void Viewer::set_time_mode(ETimeMode mode) +{ + m_impl->set_time_mode(mode); +} + +bool Viewer::is_top_layer_only_view_range() const +{ + return m_impl->is_top_layer_only_view_range(); +} + +void Viewer::toggle_top_layer_only_view_range() +{ + m_impl->toggle_top_layer_only_view_range(); +} + +bool Viewer::is_option_visible(EOptionType type) const +{ + return m_impl->is_option_visible(type); +} + +void Viewer::toggle_option_visibility(EOptionType type) +{ + m_impl->toggle_option_visibility(type); +} + +bool Viewer::is_extrusion_role_visible(EGCodeExtrusionRole role) const +{ + return m_impl->is_extrusion_role_visible(role); +} + +void Viewer::toggle_extrusion_role_visibility(EGCodeExtrusionRole role) +{ + m_impl->toggle_extrusion_role_visibility(role); +} + +const Color& Viewer::get_extrusion_role_color(EGCodeExtrusionRole role) const +{ + return m_impl->get_extrusion_role_color(role); +} + +void Viewer::set_extrusion_role_color(EGCodeExtrusionRole role, const Color& color) +{ + m_impl->set_extrusion_role_color(role, color); +} + +void Viewer::reset_default_extrusion_roles_colors() +{ + m_impl->reset_default_extrusion_roles_colors(); +} + +const Color& Viewer::get_option_color(EOptionType type) const +{ + return m_impl->get_option_color(type); +} + +void Viewer::set_option_color(EOptionType type, const Color& color) +{ + m_impl->set_option_color(type, color); +} + +void Viewer::reset_default_options_colors() +{ + m_impl->reset_default_options_colors(); +} + +size_t Viewer::get_tool_colors_count() const +{ + return m_impl->get_tool_colors_count(); +} + +const Palette& Viewer::get_tool_colors() const +{ + return m_impl->get_tool_colors(); +} + +void Viewer::set_tool_colors(const Palette& colors) +{ + m_impl->set_tool_colors(colors); +} + +size_t Viewer::get_color_print_colors_count() const +{ + return m_impl->get_color_print_colors_count(); +} + +const Palette& Viewer::get_color_print_colors() const +{ + return m_impl->get_color_print_colors(); +} + +void Viewer::set_color_print_colors(const Palette& colors) +{ + m_impl->set_color_print_colors(colors); +} + +const ColorRange& Viewer::get_color_range(EViewType type) const +{ + return m_impl->get_color_range(type); +} + +void Viewer::set_color_range_palette(EViewType type, const Palette& palette) +{ + m_impl->set_color_range_palette(type, palette); +} + +float Viewer::get_travels_radius() const +{ + return m_impl->get_travels_radius(); +} + +void Viewer::set_travels_radius(float radius) +{ + m_impl->set_travels_radius(radius); +} + +float Viewer::get_wipes_radius() const +{ + return m_impl->get_wipes_radius(); +} + +void Viewer::set_wipes_radius(float radius) +{ + m_impl->set_wipes_radius(radius); +} + +size_t Viewer::get_layers_count() const +{ + return m_impl->get_layers_count(); +} + +const Interval& Viewer::get_layers_view_range() const +{ + return m_impl->get_layers_view_range(); +} + +void Viewer::set_layers_view_range(const Interval& range) +{ + m_impl->set_layers_view_range(range); +} + +void Viewer::set_layers_view_range(Interval::value_type min, Interval::value_type max) +{ + m_impl->set_layers_view_range(min, max); +} + +const Interval& Viewer::get_view_visible_range() const +{ + return m_impl->get_view_visible_range(); +} + +void Viewer::set_view_visible_range(Interval::value_type min, Interval::value_type max) +{ + m_impl->set_view_visible_range(min, max); +} + +const Interval& Viewer::get_view_full_range() const +{ + return m_impl->get_view_full_range(); +} + +const Interval& Viewer::get_view_enabled_range() const +{ + return m_impl->get_view_enabled_range(); +} + +bool Viewer::is_spiral_vase_mode() const +{ + return m_impl->is_spiral_vase_mode(); +} + +float Viewer::get_layer_z(size_t layer_id) const +{ + return m_impl->get_layer_z(layer_id); +} + +std::vector Viewer::get_layers_zs() const +{ + return m_impl->get_layers_zs(); +} + +size_t Viewer::get_layer_id_at(float z) const +{ + return m_impl->get_layer_id_at(z); +} + +size_t Viewer::get_used_extruders_count() const +{ + return m_impl->get_used_extruders_count(); +} + +std::vector Viewer::get_used_extruders_ids() const +{ + return m_impl->get_used_extruders_ids(); +} + +std::vector Viewer::get_time_modes() const +{ + return m_impl->get_time_modes(); +} + +size_t Viewer::get_vertices_count() const +{ + return m_impl->get_vertices_count(); +} + +const PathVertex& Viewer::get_current_vertex() const +{ + return m_impl->get_current_vertex(); +} + +size_t Viewer::get_current_vertex_id() const +{ + return m_impl->get_current_vertex_id(); +} + +const PathVertex& Viewer::get_vertex_at(size_t id) const +{ + return m_impl->get_vertex_at(id); +} + +float Viewer::get_estimated_time() const +{ + return m_impl->get_estimated_time(); +} + +float Viewer::get_estimated_time_at(size_t id) const +{ + return m_impl->get_estimated_time_at(id); +} + +Color Viewer::get_vertex_color(const PathVertex& vertex) const +{ + return m_impl->get_vertex_color(vertex); +} + +size_t Viewer::get_extrusion_roles_count() const +{ + return m_impl->get_extrusion_roles_count(); +} + +std::vector Viewer::get_extrusion_roles() const +{ + return m_impl->get_extrusion_roles(); +} + +size_t Viewer::get_options_count() const +{ + return m_impl->get_options_count(); +} + +const std::vector& Viewer::get_options() const +{ + return m_impl->get_options(); +} + +size_t Viewer::get_color_prints_count(uint8_t extruder_id) const +{ + return m_impl->get_color_prints_count(extruder_id); +} + +std::vector Viewer::get_color_prints(uint8_t extruder_id) const +{ + return m_impl->get_color_prints(extruder_id); +} + +float Viewer::get_extrusion_role_estimated_time(EGCodeExtrusionRole role) const +{ + return m_impl->get_extrusion_role_estimated_time(role); +} + +float Viewer::get_travels_estimated_time() const +{ + return m_impl->get_travels_estimated_time(); +} + +std::vector Viewer::get_layers_estimated_times() const +{ + return m_impl->get_layers_estimated_times(); +} + +AABox Viewer::get_bounding_box(const std::vector& types) const +{ + return m_impl->get_bounding_box(types); +} + +AABox Viewer::get_extrusion_bounding_box(const std::vector& roles) const +{ + return m_impl->get_extrusion_bounding_box(roles); +} + +size_t Viewer::get_used_cpu_memory() const +{ + return m_impl->get_used_cpu_memory(); +} + +size_t Viewer::get_used_gpu_memory() const +{ + return m_impl->get_used_gpu_memory(); +} + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS +Vec3 Viewer::get_cog_position() const +{ + return m_impl->get_cog_marker_position(); +} + +float Viewer::get_cog_marker_scale_factor() const +{ + return m_impl->get_cog_marker_scale_factor(); +} + +void Viewer::set_cog_marker_scale_factor(float factor) +{ + m_impl->set_cog_marker_scale_factor(factor); +} + +const Vec3& Viewer::get_tool_marker_position() const +{ + return m_impl->get_tool_marker_position(); +} + +float Viewer::get_tool_marker_offset_z() const +{ + return m_impl->get_tool_marker_offset_z(); +} + +void Viewer::set_tool_marker_offset_z(float offset_z) +{ + m_impl->set_tool_marker_offset_z(offset_z); +} + +float Viewer::get_tool_marker_scale_factor() const +{ + return m_impl->get_tool_marker_scale_factor(); +} + +void Viewer::set_tool_marker_scale_factor(float factor) +{ + m_impl->set_tool_marker_scale_factor(factor); +} + +const Color& Viewer::get_tool_marker_color() const +{ + return m_impl->get_tool_marker_color(); +} + +void Viewer::set_tool_marker_color(const Color& color) +{ + m_impl->set_tool_marker_color(color); +} + +float Viewer::get_tool_marker_alpha() const +{ + return m_impl->get_tool_marker_alpha(); +} + +void Viewer::set_tool_marker_alpha(float alpha) +{ + m_impl->set_tool_marker_alpha(alpha); +} +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + +} // namespace libvgcode diff --git a/src/libvgcode/src/ViewerImpl.cpp b/src/libvgcode/src/ViewerImpl.cpp new file mode 100644 index 0000000000..a9b6b7ae81 --- /dev/null +++ b/src/libvgcode/src/ViewerImpl.cpp @@ -0,0 +1,2107 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak, VojtÄ›ch Bubník @bubnikv, Oleksandra Iushchenko @YuSanka +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "ViewerImpl.hpp" +#include "../include/GCodeInputData.hpp" +#include "Shaders.hpp" +#include "ShadersES.hpp" +#include "OpenGLUtils.hpp" +#include "Utils.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace libvgcode { + +template +using IntegerOnly = std::enable_if_t::value, O>; + +// Rounding up. +// 1.5 is rounded to 2 +// 1.49 is rounded to 1 +// 0.5 is rounded to 1, +// 0.49 is rounded to 0 +// -0.5 is rounded to 0, +// -0.51 is rounded to -1, +// -1.5 is rounded to -1. +// -1.51 is rounded to -2. +// If input is not a valid float (it is infinity NaN or if it does not fit) +// the float to int conversion produces a max int on Intel and +-max int on ARM. +template +inline IntegerOnly fast_round_up(double a) +{ + // Why does Java Math.round(0.49999999999999994) return 1? + // https://stackoverflow.com/questions/9902968/why-does-math-round0-49999999999999994-return-1 + return a == 0.49999999999999994 ? I(0) : I(floor(a + 0.5)); +} + +// Round to a bin with minimum two digits resolution. +// Equivalent to conversion to string with sprintf(buf, "%.2g", value) and conversion back to float, but faster. +static float round_to_bin(const float value) +{ +// assert(value >= 0); + constexpr float const scale[5] = { 100.f, 1000.f, 10000.f, 100000.f, 1000000.f }; + constexpr float const invscale[5] = { 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f }; + constexpr float const threshold[5] = { 0.095f, 0.0095f, 0.00095f, 0.000095f, 0.0000095f }; + // Scaling factor, pointer to the tables above. + int i = 0; + // While the scaling factor is not yet large enough to get two integer digits after scaling and rounding: + for (; value < threshold[i] && i < 4; ++i); + // At least on MSVC std::round() calls a complex function, which is pretty expensive. + // our fast_round_up is much cheaper and it could be inlined. +// return std::round(value * scale[i]) * invscale[i]; + double a = value * scale[i]; + assert(std::abs(a) < double(std::numeric_limits::max())); + return fast_round_up(a) * invscale[i]; +} + +static Mat4x4 inverse(const Mat4x4& m) +{ + // ref: https://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix + + Mat4x4 inv; + + inv[0] = m[5] * m[10] * m[15] - + m[5] * m[11] * m[14] - + m[9] * m[6] * m[15] + + m[9] * m[7] * m[14] + + m[13] * m[6] * m[11] - + m[13] * m[7] * m[10]; + + inv[4] = -m[4] * m[10] * m[15] + + m[4] * m[11] * m[14] + + m[8] * m[6] * m[15] - + m[8] * m[7] * m[14] - + m[12] * m[6] * m[11] + + m[12] * m[7] * m[10]; + + inv[8] = m[4] * m[9] * m[15] - + m[4] * m[11] * m[13] - + m[8] * m[5] * m[15] + + m[8] * m[7] * m[13] + + m[12] * m[5] * m[11] - + m[12] * m[7] * m[9]; + + inv[12] = -m[4] * m[9] * m[14] + + m[4] * m[10] * m[13] + + m[8] * m[5] * m[14] - + m[8] * m[6] * m[13] - + m[12] * m[5] * m[10] + + m[12] * m[6] * m[9]; + + inv[1] = -m[1] * m[10] * m[15] + + m[1] * m[11] * m[14] + + m[9] * m[2] * m[15] - + m[9] * m[3] * m[14] - + m[13] * m[2] * m[11] + + m[13] * m[3] * m[10]; + + inv[5] = m[0] * m[10] * m[15] - + m[0] * m[11] * m[14] - + m[8] * m[2] * m[15] + + m[8] * m[3] * m[14] + + m[12] * m[2] * m[11] - + m[12] * m[3] * m[10]; + + inv[9] = -m[0] * m[9] * m[15] + + m[0] * m[11] * m[13] + + m[8] * m[1] * m[15] - + m[8] * m[3] * m[13] - + m[12] * m[1] * m[11] + + m[12] * m[3] * m[9]; + + inv[13] = m[0] * m[9] * m[14] - + m[0] * m[10] * m[13] - + m[8] * m[1] * m[14] + + m[8] * m[2] * m[13] + + m[12] * m[1] * m[10] - + m[12] * m[2] * m[9]; + + inv[2] = m[1] * m[6] * m[15] - + m[1] * m[7] * m[14] - + m[5] * m[2] * m[15] + + m[5] * m[3] * m[14] + + m[13] * m[2] * m[7] - + m[13] * m[3] * m[6]; + + inv[6] = -m[0] * m[6] * m[15] + + m[0] * m[7] * m[14] + + m[4] * m[2] * m[15] - + m[4] * m[3] * m[14] - + m[12] * m[2] * m[7] + + m[12] * m[3] * m[6]; + + inv[10] = m[0] * m[5] * m[15] - + m[0] * m[7] * m[13] - + m[4] * m[1] * m[15] + + m[4] * m[3] * m[13] + + m[12] * m[1] * m[7] - + m[12] * m[3] * m[5]; + + inv[14] = -m[0] * m[5] * m[14] + + m[0] * m[6] * m[13] + + m[4] * m[1] * m[14] - + m[4] * m[2] * m[13] - + m[12] * m[1] * m[6] + + m[12] * m[2] * m[5]; + + inv[3] = -m[1] * m[6] * m[11] + + m[1] * m[7] * m[10] + + m[5] * m[2] * m[11] - + m[5] * m[3] * m[10] - + m[9] * m[2] * m[7] + + m[9] * m[3] * m[6]; + + inv[7] = m[0] * m[6] * m[11] - + m[0] * m[7] * m[10] - + m[4] * m[2] * m[11] + + m[4] * m[3] * m[10] + + m[8] * m[2] * m[7] - + m[8] * m[3] * m[6]; + + inv[11] = -m[0] * m[5] * m[11] + + m[0] * m[7] * m[9] + + m[4] * m[1] * m[11] - + m[4] * m[3] * m[9] - + m[8] * m[1] * m[7] + + m[8] * m[3] * m[5]; + + inv[15] = m[0] * m[5] * m[10] - + m[0] * m[6] * m[9] - + m[4] * m[1] * m[10] + + m[4] * m[2] * m[9] + + m[8] * m[1] * m[6] - + m[8] * m[2] * m[5]; + + float det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12]; + assert(det != 0.0f); + + det = 1.0f / det; + + std::array ret = {}; + for (int i = 0; i < 16; ++i) { + ret[i] = inv[i] * det; + } + + return ret; +} + +std::string check_shader(GLuint handle) +{ + std::string ret; + GLint params; + glsafe(glGetShaderiv(handle, GL_COMPILE_STATUS, ¶ms)); + if (params == GL_FALSE) { + glsafe(glGetShaderiv(handle, GL_INFO_LOG_LENGTH, ¶ms)); + ret.resize(params); + glsafe(glGetShaderInfoLog(handle, params, ¶ms, ret.data())); + } + return ret; +} + +std::string check_program(GLuint handle) +{ + std::string ret; + GLint params; + glsafe(glGetProgramiv(handle, GL_LINK_STATUS, ¶ms)); + if (params == GL_FALSE) { + glsafe(glGetProgramiv(handle, GL_INFO_LOG_LENGTH, ¶ms)); + ret.resize(params); + glsafe(glGetProgramInfoLog(handle, params, ¶ms, ret.data())); + } + return ret; +} + +unsigned int init_shader(const std::string& shader_name, const char* vertex_shader, const char* fragment_shader) +{ + const GLuint vs_id = glCreateShader(GL_VERTEX_SHADER); + glcheck(); + glsafe(glShaderSource(vs_id, 1, &vertex_shader, nullptr)); + glsafe(glCompileShader(vs_id)); + std::string res = check_shader(vs_id); + if (!res.empty()) { + glsafe(glDeleteShader(vs_id)); + throw std::runtime_error("LibVGCode: Unable to compile vertex shader:\n" + shader_name + "\n" + res + "\n"); + } + + const GLuint fs_id = glCreateShader(GL_FRAGMENT_SHADER); + glcheck(); + glsafe(glShaderSource(fs_id, 1, &fragment_shader, nullptr)); + glsafe(glCompileShader(fs_id)); + res = check_shader(fs_id); + if (!res.empty()) { + glsafe(glDeleteShader(vs_id)); + glsafe(glDeleteShader(fs_id)); + throw std::runtime_error("LibVGCode: Unable to compile fragment shader:\n" + shader_name + "\n" + res + "\n"); + } + + const GLuint shader_id = glCreateProgram(); + glcheck(); + glsafe(glAttachShader(shader_id, vs_id)); + glsafe(glAttachShader(shader_id, fs_id)); + glsafe(glLinkProgram(shader_id)); + res = check_program(shader_id); + if (!res.empty()) { + glsafe(glDetachShader(shader_id, vs_id)); + glsafe(glDetachShader(shader_id, fs_id)); + glsafe(glDeleteShader(vs_id)); + glsafe(glDeleteShader(fs_id)); + glsafe(glDeleteProgram(shader_id)); + throw std::runtime_error("LibVGCode: Unable to link shader program:\n" + shader_name + "\n" + res + "\n"); + } + + glsafe(glDetachShader(shader_id, vs_id)); + glsafe(glDetachShader(shader_id, fs_id)); + glsafe(glDeleteShader(vs_id)); + glsafe(glDeleteShader(fs_id)); + return shader_id; +} + +static void delete_textures(unsigned int& id) +{ + if (id != 0) { + glsafe(glDeleteTextures(1, &id)); + id = 0; + } +} + +static void delete_buffers(unsigned int& id) +{ + if (id != 0) { + glsafe(glDeleteBuffers(1, &id)); + id = 0; + } +} + +static const std::array DEFAULT_EXTRUSION_ROLES_COLORS = { { + { 230, 179, 179 }, // None + { 255, 230, 77 }, // Perimeter + { 255, 125, 56 }, // ExternalPerimeter + { 31, 31, 255 }, // OverhangPerimeter + { 176, 48, 41 }, // InternalInfill + { 150, 84, 204 }, // SolidInfill + { 240, 64, 64 }, // TopSolidInfill + { 255, 140, 105 }, // Ironing + { 77, 128, 186 }, // BridgeInfill + { 255, 255, 255 }, // GapFill + { 0, 135, 110 }, // Skirt + { 0, 255, 0 }, // SupportMaterial + { 0, 128, 0 }, // SupportMaterialInterface + { 179, 227, 171 }, // WipeTower + { 94, 209, 148 }, // Custom + // ORCA + { 102, 92, 199 }, // BottomSurface + { 77, 128, 186 }, // InternalBridgeInfill + { 0, 59, 110 }, // Brim + { 0, 64, 0 }, // SupportTransition + { 128, 128, 128 }, // Mixed +} }; + +static const std::array DEFAULT_OPTIONS_COLORS{ { + { 56, 72, 155 }, // Travels + { 255, 255, 0 }, // Wipes + { 205, 34, 214 }, // Retractions + { 73, 173, 207 }, // Unretractions + { 230, 230, 230 }, // Seams + { 193, 190, 99 }, // ToolChanges + { 218, 148, 139 }, // ColorChanges + { 82, 240, 131 }, // PausePrints + { 226, 210, 67 } // CustomGCodes +} }; + +#ifdef ENABLE_OPENGL_ES +static std::pair width_height(size_t count) +{ + std::pair ret; + ret.first = std::min(count, OpenGLWrapper::max_texture_size()); + size_t rows_count = count / ret.first; + if (count > rows_count * ret.first) + ++rows_count; + ret.second = std::min(rows_count, OpenGLWrapper::max_texture_size()); + return ret; +} + +void ViewerImpl::TextureData::init(size_t vertices_count) +{ + if (vertices_count == 0) + return; + + m_width = std::min(vertices_count, OpenGLWrapper::max_texture_size()); + size_t rows_count = vertices_count / m_width; + if (vertices_count > rows_count * m_width) + ++rows_count; + m_height = std::min(rows_count, OpenGLWrapper::max_texture_size()); + m_count = rows_count / m_height; + if (rows_count > m_count * m_height) + ++m_count; + + const std::pair test = width_height(vertices_count); + assert(test.first == m_width); + assert(test.second == m_height); + + m_tex_ids = std::vector(m_count); +} + +void ViewerImpl::TextureData::set_positions(const std::vector& positions) +{ + if (m_count == 0) + return; + + for (TexIds& ids : m_tex_ids) { + delete_textures(ids.positions.first); + ids.positions.second = 0; + } + + m_positions_size = 0; + + if (positions.empty()) + return; + + int curr_bound_texture = 0; + glsafe(glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_bound_texture)); + int curr_unpack_alignment = 0; + glsafe(glGetIntegerv(GL_UNPACK_ALIGNMENT, &curr_unpack_alignment)); + + glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + + const size_t tex_capacity = max_texture_capacity(); + size_t remaining = positions.size(); + for (size_t i = 0; i < m_count; ++i) { + const auto [w, h] = width_height(std::min(remaining, tex_capacity)); + const size_t offset = i * tex_capacity; + + glsafe(glGenTextures(1, &m_tex_ids[i].positions.first)); + glsafe(glBindTexture(GL_TEXTURE_2D, m_tex_ids[i].positions.first)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); + if (remaining >= tex_capacity) { + glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, static_cast(w), static_cast(h), 0, GL_RGB, GL_FLOAT, &positions[offset])); + m_tex_ids[i].positions.second = w * h; + } + else { + // the last row is only partially fitted with data, send it separately + glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, static_cast(w), static_cast(h), 0, GL_RGB, GL_FLOAT, nullptr)); + glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, static_cast(w), static_cast(h - 1), GL_RGB, GL_FLOAT, &positions[offset])); + glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, static_cast(h - 1), static_cast(remaining % w), 1, GL_RGB, GL_FLOAT, &positions[offset + w * (h - 1)])); + m_tex_ids[i].positions.second = w * (h - 1) + remaining % w; + } + m_positions_size += m_tex_ids[i].positions.second * sizeof(Vec3); + + remaining = (remaining > tex_capacity) ? remaining - tex_capacity: 0; + } + + glsafe(glBindTexture(GL_TEXTURE_2D, curr_bound_texture)); + glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, curr_unpack_alignment)); +} + +void ViewerImpl::TextureData::set_heights_widths_angles(const std::vector& heights_widths_angles) +{ + if (m_count == 0) + return; + + for (TexIds& ids : m_tex_ids) { + delete_textures(ids.heights_widths_angles.first); + ids.heights_widths_angles.second = 0; + } + + m_height_width_angle_size = 0; + + if (heights_widths_angles.empty()) + return; + + int curr_bound_texture = 0; + glsafe(glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_bound_texture)); + int curr_unpack_alignment = 0; + glsafe(glGetIntegerv(GL_UNPACK_ALIGNMENT, &curr_unpack_alignment)); + + glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + + const size_t tex_capacity = max_texture_capacity(); + size_t remaining = heights_widths_angles.size(); + for (size_t i = 0; i < m_count; ++i) { + const auto [w, h] = width_height(std::min(remaining, tex_capacity)); + const size_t offset = i * tex_capacity; + + glsafe(glGenTextures(1, &m_tex_ids[i].heights_widths_angles.first)); + glsafe(glBindTexture(GL_TEXTURE_2D, m_tex_ids[i].heights_widths_angles.first)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); + if (remaining >= tex_capacity) { + glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, static_cast(w), static_cast(h), 0, GL_RGB, GL_FLOAT, &heights_widths_angles[offset])); + m_tex_ids[i].heights_widths_angles.second = w * h; + } + else { + // the last row is only partially fitted with data, send it separately + glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, static_cast(w), static_cast(h), 0, GL_RGB, GL_FLOAT, nullptr)); + glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, static_cast(w), static_cast(h - 1), GL_RGB, GL_FLOAT, &heights_widths_angles[offset])); + glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, static_cast(h - 1), static_cast(remaining % w), 1, GL_RGB, GL_FLOAT, &heights_widths_angles[offset + w * (h - 1)])); + m_tex_ids[i].heights_widths_angles.second = w * (h - 1) + remaining % w; + } + m_height_width_angle_size += m_tex_ids[i].heights_widths_angles.second * sizeof(Vec3); + + remaining = (remaining > tex_capacity) ? remaining - tex_capacity : 0; + } + + glsafe(glBindTexture(GL_TEXTURE_2D, curr_bound_texture)); + glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, curr_unpack_alignment)); +} + +void ViewerImpl::TextureData::set_colors(const std::vector& colors) +{ + if (m_count == 0) + return; + + for (TexIds& ids : m_tex_ids) { + delete_textures(ids.colors.first); + ids.colors.second = 0; + } + + m_colors_size = 0; + + if (colors.empty()) + return; + + int curr_bound_texture = 0; + glsafe(glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_bound_texture)); + int curr_unpack_alignment = 0; + glsafe(glGetIntegerv(GL_UNPACK_ALIGNMENT, &curr_unpack_alignment)); + + glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + + const size_t tex_capacity = max_texture_capacity(); + size_t remaining = colors.size(); + for (size_t i = 0; i < m_count; ++i) { + const auto [w, h] = width_height(std::min(remaining, tex_capacity)); + const size_t offset = i * tex_capacity; + + glsafe(glGenTextures(1, &m_tex_ids[i].colors.first)); + glsafe(glBindTexture(GL_TEXTURE_2D, m_tex_ids[i].colors.first)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); + if (remaining >= tex_capacity) { + glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, static_cast(w), static_cast(h), 0, GL_RED, GL_FLOAT, &colors[offset])); + m_tex_ids[i].colors.second = w * h; + } + else { + // the last row is only partially fitted with data, send it separately + glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, static_cast(w), static_cast(h), 0, GL_RED, GL_FLOAT, nullptr)); + glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, static_cast(w), static_cast(h - 1), GL_RED, GL_FLOAT, &colors[offset])); + glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, static_cast(h - 1), static_cast(remaining % w), 1, GL_RED, GL_FLOAT, &colors[offset + w * (h - 1)])); + m_tex_ids[i].colors.second = w * (h - 1) + remaining % w; + } + m_colors_size += m_tex_ids[i].colors.second * sizeof(float); + + remaining = (remaining > tex_capacity) ? remaining - tex_capacity : 0; + } + + glsafe(glBindTexture(GL_TEXTURE_2D, curr_bound_texture)); + glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, curr_unpack_alignment)); +} + +void ViewerImpl::TextureData::set_enabled_segments(const std::vector& enabled_segments) +{ + if (m_count == 0) + return; + + for (TexIds& ids : m_tex_ids) { + delete_textures(ids.enabled_segments.first); + ids.enabled_segments.second = 0; + } + + m_enabled_segments_size = 0; + + if (enabled_segments.empty()) + return; + + int curr_bound_texture = 0; + glsafe(glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_bound_texture)); + int curr_unpack_alignment = 0; + glsafe(glGetIntegerv(GL_UNPACK_ALIGNMENT, &curr_unpack_alignment)); + + glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + + const size_t tex_capacity = max_texture_capacity(); + size_t curr_tex_id = 0; + std::vector curr_segments; + for (size_t i = 0; i < enabled_segments.size(); ++i) { + uint32_t seg = enabled_segments[i]; + const bool new_tex = static_cast(seg) > (curr_tex_id + 1) * tex_capacity; + if (!new_tex) + curr_segments.push_back(seg - static_cast(curr_tex_id * tex_capacity)); + if (i + 1 == enabled_segments.size() || new_tex) { + const auto [w, h] = width_height(curr_segments.size()); + + glsafe(glGenTextures(1, &m_tex_ids[curr_tex_id].enabled_segments.first)); + glsafe(glBindTexture(GL_TEXTURE_2D, m_tex_ids[curr_tex_id].enabled_segments.first)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); + if (curr_segments.size() == tex_capacity) { + glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, static_cast(w), static_cast(h), 0, GL_RED_INTEGER, GL_UNSIGNED_INT, curr_segments.data())); + m_tex_ids[curr_tex_id].enabled_segments.second = w * h; + } + else { + glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, static_cast(w), static_cast(h), 0, GL_RED_INTEGER, GL_UNSIGNED_INT, nullptr)); + if (h == 1) { + glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, static_cast(w), 1, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, curr_segments.data())); + m_tex_ids[curr_tex_id].enabled_segments.second = w; + } + else { + // the last row is only partially fitted with data, send it separately + glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, static_cast(w), static_cast(h - 1), GL_RED_INTEGER, GL_UNSIGNED_INT, curr_segments.data())); + glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, static_cast(h - 1), static_cast(curr_segments.size() % w), 1, GL_RED_INTEGER, GL_UNSIGNED_INT, &curr_segments[w * (h - 1)])); + m_tex_ids[curr_tex_id].enabled_segments.second = w * (h - 1) + curr_segments.size() % w; + } + } + m_enabled_segments_size += m_tex_ids[curr_tex_id].enabled_segments.second * sizeof(uint32_t); + if (new_tex) { + curr_segments.clear(); + ++curr_tex_id; + curr_segments.push_back(seg - static_cast(curr_tex_id * tex_capacity)); + } + } + } + + glsafe(glBindTexture(GL_TEXTURE_2D, curr_bound_texture)); + glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, curr_unpack_alignment)); +} + +void ViewerImpl::TextureData::set_enabled_options(const std::vector& enabled_options) +{ + if (m_count == 0) + return; + + for (TexIds& ids : m_tex_ids) { + delete_textures(ids.enabled_options.first); + ids.enabled_options.second = 0; + } + + m_enabled_options_size = 0; + + if (enabled_options.empty()) + return; + + int curr_bound_texture = 0; + glsafe(glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_bound_texture)); + int curr_unpack_alignment = 0; + glsafe(glGetIntegerv(GL_UNPACK_ALIGNMENT, &curr_unpack_alignment)); + + glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + + const size_t tex_capacity = max_texture_capacity(); + size_t curr_tex_id = 0; + std::vector curr_options; + for (size_t i = 0; i < enabled_options.size(); ++i) { + uint32_t opt = enabled_options[i]; + const bool new_tex = static_cast(opt) > (curr_tex_id + 1) * tex_capacity; + if (!new_tex) + curr_options.push_back(opt - static_cast(curr_tex_id * tex_capacity)); + if (i + 1 == enabled_options.size() || new_tex) { + const auto [w, h] = width_height(curr_options.size()); + + glsafe(glGenTextures(1, &m_tex_ids[curr_tex_id].enabled_options.first)); + glsafe(glBindTexture(GL_TEXTURE_2D, m_tex_ids[curr_tex_id].enabled_options.first)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); + if (curr_options.size() == tex_capacity) { + glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, static_cast(w), static_cast(h), 0, GL_RED_INTEGER, GL_UNSIGNED_INT, curr_options.data())); + m_tex_ids[curr_tex_id].enabled_options.second = w * h; + } + else { + glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, static_cast(w), static_cast(h), 0, GL_RED_INTEGER, GL_UNSIGNED_INT, nullptr)); + if (h == 1) { + glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, static_cast(w), 1, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, curr_options.data())); + m_tex_ids[curr_tex_id].enabled_options.second = w; + } + else { + // the last row is only partially fitted with data, send it separately + glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, static_cast(w), static_cast(h - 1), GL_RED_INTEGER, GL_UNSIGNED_INT, curr_options.data())); + glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, static_cast(h - 1), static_cast(curr_options.size() % w), 1, GL_RED_INTEGER, GL_UNSIGNED_INT, &curr_options[w * (h - 1)])); + m_tex_ids[curr_tex_id].enabled_options.second = w * (h - 1) + curr_options.size() % w; + } + } + m_enabled_options_size += m_tex_ids[curr_tex_id].enabled_options.second * sizeof(uint32_t); + if (new_tex) { + curr_options.clear(); + ++curr_tex_id; + curr_options.push_back(opt - static_cast(curr_tex_id * tex_capacity)); + } + } + } + + glsafe(glBindTexture(GL_TEXTURE_2D, curr_bound_texture)); + glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, curr_unpack_alignment)); +} + +void ViewerImpl::TextureData::reset() +{ + for (TexIds& ids : m_tex_ids) { + delete_textures(ids.enabled_options.first); + delete_textures(ids.enabled_segments.first); + delete_textures(ids.colors.first); + delete_textures(ids.heights_widths_angles.first); + delete_textures(ids.positions.first); + } + m_tex_ids.clear(); + + m_width = 0; + m_height = 0; + m_count = 0; + + m_positions_size = 0; + m_height_width_angle_size = 0; + m_colors_size = 0; + m_enabled_segments_size = 0; + m_enabled_options_size = 0; +} + +std::pair ViewerImpl::TextureData::get_positions_tex_id(size_t id) const +{ + assert(id < m_tex_ids.size()); + return m_tex_ids[id].positions; +} + +std::pair ViewerImpl::TextureData::get_heights_widths_angles_tex_id(size_t id) const +{ + assert(id < m_tex_ids.size()); + return m_tex_ids[id].heights_widths_angles; +} + +std::pair ViewerImpl::TextureData::get_colors_tex_id(size_t id) const +{ + assert(id < m_tex_ids.size()); + return m_tex_ids[id].colors; +} + +std::pair ViewerImpl::TextureData::get_enabled_segments_tex_id(size_t id) const +{ + assert(id < m_tex_ids.size()); + return m_tex_ids[id].enabled_segments; +} + +std::pair ViewerImpl::TextureData::get_enabled_options_tex_id(size_t id) const +{ + assert(id < m_tex_ids.size()); + return m_tex_ids[id].enabled_options; +} + +size_t ViewerImpl::TextureData::get_enabled_segments_count() const +{ + size_t ret = 0; + for (size_t i = 0; i < m_count; ++i) { + ret += m_tex_ids[i].enabled_segments.second; + } + return ret; +} + +size_t ViewerImpl::TextureData::get_enabled_options_count() const +{ + size_t ret = 0; + for (size_t i = 0; i < m_count; ++i) { + ret += m_tex_ids[i].enabled_options.second; + } + return ret; +} + +size_t ViewerImpl::TextureData::get_used_gpu_memory() const +{ + size_t ret = 0; + ret += m_positions_size; + ret += m_height_width_angle_size; + ret += m_colors_size; + ret += m_enabled_segments_size; + ret += m_enabled_options_size; + return ret; +} +#endif // ENABLE_OPENGL_ES + +ViewerImpl::ViewerImpl() +{ + reset_default_extrusion_roles_colors(); + reset_default_options_colors(); +} + +void ViewerImpl::init(const std::string& opengl_context_version) +{ + if (m_initialized) + return; + + if (!OpenGLWrapper::load_opengl(opengl_context_version)) { + if (OpenGLWrapper::is_valid_context()) + throw std::runtime_error("LibVGCode was unable to initialize the GLAD library.\n"); + else { +#ifdef ENABLE_OPENGL_ES + throw std::runtime_error("LibVGCode requires an OpenGL ES context based on OpenGL ES 3.0 or higher.\n"); +#else + throw std::runtime_error("LibVGCode requires an OpenGL context based on OpenGL 3.2 or higher.\n"); +#endif // ENABLE_OPENGL_ES + } + } + + // segments shader +#ifdef ENABLE_OPENGL_ES + m_segments_shader_id = init_shader("segments", Segments_Vertex_Shader_ES, Segments_Fragment_Shader_ES); +#else + m_segments_shader_id = init_shader("segments", Segments_Vertex_Shader, Segments_Fragment_Shader); +#endif // ENABLE_OPENGL_ES + + m_uni_segments_view_matrix_id = glGetUniformLocation(m_segments_shader_id, "view_matrix"); + m_uni_segments_projection_matrix_id = glGetUniformLocation(m_segments_shader_id, "projection_matrix"); + m_uni_segments_camera_position_id = glGetUniformLocation(m_segments_shader_id, "camera_position"); + m_uni_segments_positions_tex_id = glGetUniformLocation(m_segments_shader_id, "position_tex"); + m_uni_segments_height_width_angle_tex_id = glGetUniformLocation(m_segments_shader_id, "height_width_angle_tex"); + m_uni_segments_colors_tex_id = glGetUniformLocation(m_segments_shader_id, "color_tex"); + m_uni_segments_segment_index_tex_id = glGetUniformLocation(m_segments_shader_id, "segment_index_tex"); + glcheck(); + assert(m_uni_segments_view_matrix_id != -1 && + m_uni_segments_projection_matrix_id != -1 && + m_uni_segments_camera_position_id != -1 && + m_uni_segments_positions_tex_id != -1 && + m_uni_segments_height_width_angle_tex_id != -1 && + m_uni_segments_colors_tex_id != -1 && + m_uni_segments_segment_index_tex_id != -1); + + m_segment_template.init(); + + // options shader +#ifdef ENABLE_OPENGL_ES + m_options_shader_id = init_shader("options", Options_Vertex_Shader_ES, Options_Fragment_Shader_ES); +#else + m_options_shader_id = init_shader("options", Options_Vertex_Shader, Options_Fragment_Shader); +#endif // ENABLE_OPENGL_ES + + m_uni_options_view_matrix_id = glGetUniformLocation(m_options_shader_id, "view_matrix"); + m_uni_options_projection_matrix_id = glGetUniformLocation(m_options_shader_id, "projection_matrix"); + m_uni_options_positions_tex_id = glGetUniformLocation(m_options_shader_id, "position_tex"); + m_uni_options_height_width_angle_tex_id = glGetUniformLocation(m_options_shader_id, "height_width_angle_tex"); + m_uni_options_colors_tex_id = glGetUniformLocation(m_options_shader_id, "color_tex"); + m_uni_options_segment_index_tex_id = glGetUniformLocation(m_options_shader_id, "segment_index_tex"); + glcheck(); + assert(m_uni_options_view_matrix_id != -1 && + m_uni_options_projection_matrix_id != -1 && + m_uni_options_positions_tex_id != -1 && + m_uni_options_height_width_angle_tex_id != -1 && + m_uni_options_colors_tex_id != -1 && + m_uni_options_segment_index_tex_id != -1); + + m_option_template.init(16); + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + // cog marker shader +#ifdef ENABLE_OPENGL_ES + m_cog_marker_shader_id = init_shader("cog_marker", Cog_Marker_Vertex_Shader_ES, Cog_Marker_Fragment_Shader_ES); +#else + m_cog_marker_shader_id = init_shader("cog_marker", Cog_Marker_Vertex_Shader, Cog_Marker_Fragment_Shader); +#endif // ENABLE_OPENGL_ES + + m_uni_cog_marker_world_center_position = glGetUniformLocation(m_cog_marker_shader_id, "world_center_position"); + m_uni_cog_marker_scale_factor = glGetUniformLocation(m_cog_marker_shader_id, "scale_factor"); + m_uni_cog_marker_view_matrix = glGetUniformLocation(m_cog_marker_shader_id, "view_matrix"); + m_uni_cog_marker_projection_matrix = glGetUniformLocation(m_cog_marker_shader_id, "projection_matrix"); + glcheck(); + assert(m_uni_cog_marker_world_center_position != -1 && + m_uni_cog_marker_scale_factor != -1 && + m_uni_cog_marker_view_matrix != -1 && + m_uni_cog_marker_projection_matrix != -1); + + m_cog_marker.init(32, 1.0f); + + // tool marker shader +#ifdef ENABLE_OPENGL_ES + m_tool_marker_shader_id = init_shader("tool_marker", Tool_Marker_Vertex_Shader_ES, Tool_Marker_Fragment_Shader_ES); +#else + m_tool_marker_shader_id = init_shader("tool_marker", Tool_Marker_Vertex_Shader, Tool_Marker_Fragment_Shader); +#endif // ENABLE_OPENGL_ES + + m_uni_tool_marker_world_origin = glGetUniformLocation(m_tool_marker_shader_id, "world_origin"); + m_uni_tool_marker_scale_factor = glGetUniformLocation(m_tool_marker_shader_id, "scale_factor"); + m_uni_tool_marker_view_matrix = glGetUniformLocation(m_tool_marker_shader_id, "view_matrix"); + m_uni_tool_marker_projection_matrix = glGetUniformLocation(m_tool_marker_shader_id, "projection_matrix"); + m_uni_tool_marker_color_base = glGetUniformLocation(m_tool_marker_shader_id, "color_base"); + + glcheck(); + assert(m_uni_tool_marker_world_origin != -1 && + m_uni_tool_marker_scale_factor != -1 && + m_uni_tool_marker_view_matrix != -1 && + m_uni_tool_marker_projection_matrix != -1 && + m_uni_tool_marker_color_base != -1); + + m_tool_marker.init(32, 2.0f, 4.0f, 1.0f, 8.0f); +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + + m_initialized = true; +} + +void ViewerImpl::shutdown() +{ + reset(); +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + m_tool_marker.shutdown(); + m_cog_marker.shutdown(); +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + m_option_template.shutdown(); + m_segment_template.shutdown(); + if (m_options_shader_id != 0) { + glsafe(glDeleteProgram(m_options_shader_id)); + m_options_shader_id = 0; + } + if (m_segments_shader_id != 0) { + glsafe(glDeleteProgram(m_segments_shader_id)); + m_segments_shader_id = 0; + } + m_initialized = false; + OpenGLWrapper::unload_opengl(); +} + +void ViewerImpl::reset() +{ + m_layers.reset(); + m_view_range.reset(); + m_extrusion_roles.reset(); + m_options.clear(); + m_used_extruders.clear(); + m_total_time = { 0.0f, 0.0f }; + m_travels_time = { 0.0f, 0.0f }; + m_vertices.clear(); + m_vertices_colors.clear(); + m_valid_lines_bitset.clear(); +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + m_cog_marker.reset(); +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + +#ifdef ENABLE_OPENGL_ES + m_texture_data.reset(); +#else + m_enabled_segments_count = 0; + m_enabled_options_count = 0; + + m_settings_used_for_ranges = std::nullopt; + + delete_textures(m_enabled_options_tex_id); + delete_buffers(m_enabled_options_buf_id); + delete_textures(m_enabled_segments_tex_id); + delete_buffers(m_enabled_segments_buf_id); + delete_textures(m_colors_tex_id); + delete_buffers(m_colors_buf_id); + delete_textures(m_heights_widths_angles_tex_id); + delete_buffers(m_heights_widths_angles_buf_id); + delete_textures(m_positions_tex_id); + delete_buffers(m_positions_buf_id); +#endif // ENABLE_OPENGL_ES +} + +// On some graphic cards texture buffers using GL_RGB32F format do not work, see: +// https://dev.prusa3d.com/browse/SPE-2411 +// https://github.com/prusa3d/PrusaSlicer/issues/12908 +// To let all drivers be happy, we use GL_RGBA32F format, so we need to add an extra (currently unused) float +// to position and heights_widths_angles vectors +using Vec4 = std::array; + +static void extract_pos_and_or_hwa(const std::vector& vertices, float travels_radius, float wipes_radius, BitSet<>& valid_lines_bitset, + std::vector* positions = nullptr, std::vector* heights_widths_angles = nullptr, bool update_bitset = false) { + static constexpr const Vec3 ZERO = { 0.0f, 0.0f, 0.0f }; + if (positions == nullptr && heights_widths_angles == nullptr) + return; + if (vertices.empty()) + return; + if (travels_radius <= 0.0f || wipes_radius <= 0.0f) + return; + + if (positions != nullptr) + positions->reserve(vertices.size()); + if (heights_widths_angles != nullptr) + heights_widths_angles->reserve(vertices.size()); + for (size_t i = 0; i < vertices.size(); ++i) { + const PathVertex& v = vertices[i]; + const EMoveType move_type = v.type; + const bool prev_line_valid = i > 0 && valid_lines_bitset[i - 1]; + const Vec3 prev_line = prev_line_valid ? v.position - vertices[i - 1].position : ZERO; + const bool this_line_valid = i + 1 < vertices.size() && + vertices[i + 1].position != v.position && + vertices[i + 1].type == move_type && + move_type != EMoveType::Seam; + const Vec3 this_line = this_line_valid ? vertices[i + 1].position - v.position : ZERO; + + if (this_line_valid) { + // there is a valid path between point i and i+1. + } + else { + // the connection is invalid, there should be no line rendered, ever + if (update_bitset) + valid_lines_bitset.reset(i); + } + + if (positions != nullptr) { + // the last component is a dummy float to comply with GL_RGBA32F format + Vec4 position = { v.position[0], v.position[1], v.position[2], 0.0f }; + if (move_type == EMoveType::Extrude) + // push down extrusion vertices by half height to render them at the right z + position[2] -= 0.5f * v.height; + positions->emplace_back(position); + } + + if (heights_widths_angles != nullptr) { + float height = 0.0f; + float width = 0.0f; + if (v.is_travel()) { + height = travels_radius; + width = travels_radius; + } + else if (v.is_wipe()) { + height = wipes_radius; + width = wipes_radius; + } + else { + height = v.height; + width = v.width; + } + // the last component is a dummy float to comply with GL_RGBA32F format + heights_widths_angles->push_back({ height, width, + std::atan2(prev_line[0] * this_line[1] - prev_line[1] * this_line[0], dot(prev_line, this_line)), 0.0f }); + } + } +} + +void ViewerImpl::load(GCodeInputData&& gcode_data) +{ + if (!m_initialized) + return; + + if (gcode_data.vertices.empty()) + return; + + reset(); + + m_vertices = std::move(gcode_data.vertices); + m_tool_colors = std::move(gcode_data.tools_colors); + m_color_print_colors = std::move(gcode_data.color_print_colors); + m_vertices_colors.resize(m_vertices.size()); + + m_settings.spiral_vase_mode = gcode_data.spiral_vase_mode; + + for (size_t i = 0; i < m_vertices.size(); ++i) { + const PathVertex& v = m_vertices[i]; + + m_layers.update(v, static_cast(i)); + + for (size_t j = 0; j < TIME_MODES_COUNT; ++j) { + m_total_time[j] += v.times[j]; + if (v.type == EMoveType::Travel) + m_travels_time[j] += v.times[j]; + } + + const EOptionType option_type = move_type_to_option(v.type); + if (option_type != EOptionType::COUNT) + m_options.emplace_back(option_type); + + if (v.type == EMoveType::Extrude) { + m_extrusion_roles.add(v.role, v.times); + + auto estruder_it = m_used_extruders.find(v.extruder_id); + if (estruder_it == m_used_extruders.end()) + estruder_it = m_used_extruders.insert({ v.extruder_id, std::vector() }).first; + if (estruder_it->second.empty() || estruder_it->second.back().color_id != v.color_id) { + const ColorPrint cp = { v.extruder_id, v.color_id, v.layer_id, m_total_time }; + estruder_it->second.emplace_back(cp); + } + } + + if (i > 0) { +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + // updates calculation for center of gravity + if (v.type == EMoveType::Extrude && + v.role != EGCodeExtrusionRole::Skirt && + v.role != EGCodeExtrusionRole::SupportMaterial && + v.role != EGCodeExtrusionRole::SupportMaterialInterface && + v.role != EGCodeExtrusionRole::WipeTower && + v.role != EGCodeExtrusionRole::Custom && + v.role != EGCodeExtrusionRole::Brim && + v.role != EGCodeExtrusionRole::SupportTransition) { + m_cog_marker.update(0.5f * (v.position + m_vertices[i - 1].position), v.weight); + } +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + } + } + + if (!m_layers.empty()) + m_layers.set_view_range(0, static_cast(m_layers.count()) - 1); + + std::sort(m_options.begin(), m_options.end()); + m_options.erase(std::unique(m_options.begin(), m_options.end()), m_options.end()); + m_options.shrink_to_fit(); + + // reset segments visibility bitset + m_valid_lines_bitset = BitSet<>(m_vertices.size()); + m_valid_lines_bitset.setAll(); + + if (m_settings.time_mode != ETimeMode::Normal && m_total_time[static_cast(m_settings.time_mode)] == 0.0f) + m_settings.time_mode = ETimeMode::Normal; + + // buffers to send to gpu + // the last component is a dummy float to comply with GL_RGBA32F format + std::vector positions; + std::vector heights_widths_angles; + positions.reserve(m_vertices.size()); + heights_widths_angles.reserve(m_vertices.size()); + extract_pos_and_or_hwa(m_vertices, m_travels_radius, m_wipes_radius, m_valid_lines_bitset, &positions, &heights_widths_angles, true); + + if (!positions.empty()) { +#ifdef ENABLE_OPENGL_ES + m_texture_data.init(positions.size()); + // create and fill position textures + m_texture_data.set_positions(positions); + // create and fill height, width and angle textures + m_texture_data.set_heights_widths_angles(heights_widths_angles); +#else + m_positions_tex_size = positions.size() * sizeof(Vec3); + m_height_width_angle_tex_size = heights_widths_angles.size() * sizeof(Vec3); + + int old_bound_texture = 0; + glsafe(glGetIntegerv(GL_TEXTURE_BINDING_BUFFER, &old_bound_texture)); + + // create and fill positions buffer + glsafe(glGenBuffers(1, &m_positions_buf_id)); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_positions_buf_id)); + glsafe(glBufferData(GL_TEXTURE_BUFFER, positions.size() * sizeof(Vec4), positions.data(), GL_STATIC_DRAW)); + glsafe(glGenTextures(1, &m_positions_tex_id)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_positions_tex_id)); + + // create and fill height, width and angles buffer + glsafe(glGenBuffers(1, &m_heights_widths_angles_buf_id)); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_heights_widths_angles_buf_id)); + glsafe(glBufferData(GL_TEXTURE_BUFFER, heights_widths_angles.size() * sizeof(Vec4), heights_widths_angles.data(), GL_DYNAMIC_DRAW)); + glsafe(glGenTextures(1, &m_heights_widths_angles_tex_id)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_heights_widths_angles_tex_id)); + + // create (but do not fill) colors buffer (data is set in update_colors()) + glsafe(glGenBuffers(1, &m_colors_buf_id)); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_colors_buf_id)); + glsafe(glGenTextures(1, &m_colors_tex_id)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_colors_tex_id)); + + // create (but do not fill) enabled segments buffer (data is set in update_enabled_entities()) + glsafe(glGenBuffers(1, &m_enabled_segments_buf_id)); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_segments_buf_id)); + glsafe(glGenTextures(1, &m_enabled_segments_tex_id)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_enabled_segments_tex_id)); + + // create (but do not fill) enabled options buffer (data is set in update_enabled_entities()) + glsafe(glGenBuffers(1, &m_enabled_options_buf_id)); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_options_buf_id)); + glsafe(glGenTextures(1, &m_enabled_options_tex_id)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_enabled_options_tex_id)); + + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, 0)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, old_bound_texture)); +#endif // ENABLE_OPENGL_ES + } + + update_view_full_range(); + m_view_range.set_visible(m_view_range.get_enabled()); + update_enabled_entities(); + update_colors(); +} + +void ViewerImpl::update_enabled_entities() +{ + if (m_vertices.empty()) + return; + + std::vector enabled_segments; + std::vector enabled_options; + Interval range = m_view_range.get_visible(); + + // when top layer only visualization is enabled, we need to render + // all the toolpaths in the other layers as grayed, so extend the range + // to contain them + if (m_settings.top_layer_only_view_range) + range[0] = m_view_range.get_full()[0]; + + // to show the options at the current tool marker position we need to extend the range by one extra step + if (m_vertices[range[1]].is_option() && range[1] < static_cast(m_vertices.size()) - 1) + ++range[1]; + + if (m_settings.spiral_vase_mode) { + // when spiral vase mode is enabled and only one layer is shown, extend the range by one step + const Interval& layers_range = m_layers.get_view_range(); + if (layers_range[0] > 0 && layers_range[0] == layers_range[1]) + --range[0]; + } + + for (size_t i = range[0]; i < range[1]; ++i) { + const PathVertex& v = m_vertices[i]; + + if (!m_valid_lines_bitset[i] && !v.is_option()) + continue; + if (v.is_travel()) { + if (!m_settings.options_visibility[size_t(EOptionType::Travels)]) + continue; + } + else if (v.is_wipe()) { + if (!m_settings.options_visibility[size_t(EOptionType::Wipes)]) + continue; + } + else if (v.is_option()) { + if (!m_settings.options_visibility[size_t(move_type_to_option(v.type))]) + continue; + } + else if (v.is_extrusion()) { + if (!m_settings.extrusion_roles_visibility[size_t(v.role)]) + continue; + } + else + continue; + + if (v.is_option()) + enabled_options.push_back(static_cast(i)); + else + enabled_segments.push_back(static_cast(i)); + } + +#ifdef ENABLE_OPENGL_ES + m_texture_data.set_enabled_segments(enabled_segments); + m_texture_data.set_enabled_options(enabled_options); +#else + m_enabled_segments_count = enabled_segments.size(); + m_enabled_options_count = enabled_options.size(); + + m_enabled_segments_tex_size = enabled_segments.size() * sizeof(uint32_t); + m_enabled_options_tex_size = enabled_options.size() * sizeof(uint32_t); + + // update gpu buffer for enabled segments + assert(m_enabled_segments_buf_id > 0); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_segments_buf_id)); + if (!enabled_segments.empty()) + glsafe(glBufferData(GL_TEXTURE_BUFFER, enabled_segments.size() * sizeof(uint32_t), enabled_segments.data(), GL_STATIC_DRAW)); + else + glsafe(glBufferData(GL_TEXTURE_BUFFER, 0, nullptr, GL_STATIC_DRAW)); + + // update gpu buffer for enabled options + assert(m_enabled_options_buf_id > 0); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_options_buf_id)); + if (!enabled_options.empty()) + glsafe(glBufferData(GL_TEXTURE_BUFFER, enabled_options.size() * sizeof(uint32_t), enabled_options.data(), GL_STATIC_DRAW)); + else + glsafe(glBufferData(GL_TEXTURE_BUFFER, 0, nullptr, GL_STATIC_DRAW)); + + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, 0)); +#endif // ENABLE_OPENGL_ES + + m_settings.update_enabled_entities = false; +} + +static float encode_color(const Color& color) { + const int r = static_cast(color[0]); + const int g = static_cast(color[1]); + const int b = static_cast(color[2]); + const int i_color = r << 16 | g << 8 | b; + return static_cast(i_color); +} + + +void ViewerImpl::update_colors_texture() +{ +#if !defined(ENABLE_OPENGL_ES) + if (m_colors_buf_id == 0) + return; +#endif // ENABLE_OPENGL_ES + + const size_t top_layer_id = m_settings.top_layer_only_view_range ? m_layers.get_view_range()[1] : 0; + const bool color_top_layer_only = m_view_range.get_full()[1] != m_view_range.get_visible()[1]; + + // Based on current settings and slider position, we might want to render some + // vertices as dark grey. Use either that or the normal color (from the cache). + std::vector colors(m_vertices_colors.size()); + assert(colors.size() == m_vertices.size() && m_vertices_colors.size() == m_vertices.size()); + for (size_t i=0; i(m_used_extruders.rbegin()->first); + const size_t tool_colors_size = m_tool_colors.size(); + if (m_tool_colors.size() < max_used_extruder_id) { + for (size_t i = 0; i < max_used_extruder_id - tool_colors_size; ++i) { + m_tool_colors.emplace_back(DUMMY_COLOR); + } + } + } + + update_color_ranges(); + + // Recalculate "normal" colors of all the vertices for current view settings. + // If some part of the preview should be rendered in dark grey, it is taken + // care of in update_colors_texture. That is to avoid the need to recalculate + // the "normal" color on every slider move. + for (size_t i = 0; i < m_vertices.size(); ++i) + m_vertices_colors[i] = encode_color(get_vertex_color(m_vertices[i])); + + update_colors_texture(); + m_settings.update_colors = false; +} + +void ViewerImpl::render(const Mat4x4& view_matrix, const Mat4x4& projection_matrix) +{ + if (m_settings.update_view_full_range) + update_view_full_range(); + + if (m_settings.update_enabled_entities) + update_enabled_entities(); + + if (m_settings.update_colors) + update_colors(); + + const Mat4x4 inv_view_matrix = inverse(view_matrix); + const Vec3 camera_position = { inv_view_matrix[12], inv_view_matrix[13], inv_view_matrix[14] }; + render_segments(view_matrix, projection_matrix, camera_position); + render_options(view_matrix, projection_matrix); + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + if (m_settings.options_visibility[size_t(EOptionType::ToolMarker)]) + render_tool_marker(view_matrix, projection_matrix); + if (m_settings.options_visibility[size_t(EOptionType::CenterOfGravity)]) + render_cog_marker(view_matrix, projection_matrix); +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS +} + +void ViewerImpl::set_view_type(EViewType type) +{ + m_settings.view_type = type; + m_settings.update_colors = true; +} + +void ViewerImpl::set_time_mode(ETimeMode mode) +{ + m_settings.time_mode = mode; + m_settings.update_colors = true; +} + +void ViewerImpl::set_layers_view_range(Interval::value_type min, Interval::value_type max) +{ + min = std::clamp(min, 0, m_layers.count() - 1); + max = std::clamp(max, 0, m_layers.count() - 1); + m_layers.set_view_range(min, max); + // force immediate update of the full range + update_view_full_range(); + m_view_range.set_visible(m_view_range.get_enabled()); + m_settings.update_enabled_entities = true; + //m_settings.update_colors = true; + update_colors_texture(); +} + +void ViewerImpl::toggle_top_layer_only_view_range() +{ + m_settings.top_layer_only_view_range = !m_settings.top_layer_only_view_range; + update_view_full_range(); + m_view_range.set_visible(m_view_range.get_enabled()); + m_settings.update_enabled_entities = true; + //m_settings.update_colors = true; + update_colors_texture(); +} + +std::vector ViewerImpl::get_time_modes() const +{ + std::vector ret; + for (size_t i = 0; i < TIME_MODES_COUNT; ++i) { + if (std::accumulate(m_vertices.begin(), m_vertices.end(), 0.0f, + [i](float a, const PathVertex& v) { return a + v.times[i]; }) > 0.0f) + ret.push_back(static_cast(i)); + } + return ret; +} + +std::vector ViewerImpl::get_used_extruders_ids() const +{ + std::vector ret; + ret.reserve(m_used_extruders.size()); + for (const auto& [id, colors] : m_used_extruders) { + ret.emplace_back(id); + } + return ret; +} + +size_t ViewerImpl::get_color_prints_count(uint8_t extruder_id) const +{ + const auto it = m_used_extruders.find(extruder_id); + return (it == m_used_extruders.end()) ? 0 : it->second.size(); +} + +std::vector ViewerImpl::get_color_prints(uint8_t extruder_id) const +{ + const auto it = m_used_extruders.find(extruder_id); + return (it == m_used_extruders.end()) ? std::vector() : it->second; +} + +AABox ViewerImpl::get_bounding_box(const std::vector& types) const +{ + Vec3 min = { FLT_MAX, FLT_MAX, FLT_MAX }; + Vec3 max = { -FLT_MAX, -FLT_MAX, -FLT_MAX }; + for (const PathVertex& v : m_vertices) { + if (std::find(types.begin(), types.end(), v.type) != types.end()) { + for (int j = 0; j < 3; ++j) { + min[j] = std::min(min[j], v.position[j]); + max[j] = std::max(max[j], v.position[j]); + } + } + } + return { min, max }; +} + +AABox ViewerImpl::get_extrusion_bounding_box(const std::vector& roles) const +{ + Vec3 min = { FLT_MAX, FLT_MAX, FLT_MAX }; + Vec3 max = { -FLT_MAX, -FLT_MAX, -FLT_MAX }; + for (const PathVertex& v : m_vertices) { + if (v.is_extrusion() && std::find(roles.begin(), roles.end(), v.role) != roles.end()) { + for (int j = 0; j < 3; ++j) { + min[j] = std::min(min[j], v.position[j]); + max[j] = std::max(max[j], v.position[j]); + } + } + } + return { min, max }; +} + +bool ViewerImpl::is_option_visible(EOptionType type) const +{ + return m_settings.options_visibility[size_t(type)]; +} + +void ViewerImpl::toggle_option_visibility(EOptionType type) +{ + m_settings.options_visibility[size_t(type)] = ! m_settings.options_visibility[size_t(type)]; + const Interval old_enabled_range = m_view_range.get_enabled(); + update_view_full_range(); + const Interval& new_enabled_range = m_view_range.get_enabled(); + if (old_enabled_range != new_enabled_range) { + const Interval& visible_range = m_view_range.get_visible(); + if (old_enabled_range == visible_range) + m_view_range.set_visible(new_enabled_range); + else if (m_settings.top_layer_only_view_range && new_enabled_range[0] < visible_range[0]) + m_view_range.set_visible(new_enabled_range[0], visible_range[1]); + } + m_settings.update_enabled_entities = true; + m_settings.update_colors = true; +} + +bool ViewerImpl::is_extrusion_role_visible(EGCodeExtrusionRole role) const +{ + return m_settings.extrusion_roles_visibility[size_t(role)]; +} + +void ViewerImpl::toggle_extrusion_role_visibility(EGCodeExtrusionRole role) +{ + m_settings.extrusion_roles_visibility[size_t(role)] = ! m_settings.extrusion_roles_visibility[size_t(role)]; + update_view_full_range(); + m_settings.update_enabled_entities = true; + m_settings.update_colors = true; +} + +void ViewerImpl::set_view_visible_range(Interval::value_type min, Interval::value_type max) +{ + // force update of the full range, to avoid clamping the visible range with full old values + // when calling m_view_range.set_visible() + update_view_full_range(); + m_view_range.set_visible(min, max); + update_enabled_entities(); + //m_settings.update_colors = true; + update_colors_texture(); +} + +float ViewerImpl::get_estimated_time_at(size_t id) const +{ + return std::accumulate(m_vertices.begin(), m_vertices.begin() + id + 1, 0.0f, + [this](float a, const PathVertex& v) { return a + v.times[static_cast(m_settings.time_mode)]; }); +} + +Color ViewerImpl::get_vertex_color(const PathVertex& v) const +{ + if (v.type == EMoveType::Noop) + return DUMMY_COLOR; + + if ((v.is_wipe() && (m_settings.view_type != EViewType::Speed && m_settings.view_type != EViewType::ActualSpeed)) || v.is_option()) + return get_option_color(move_type_to_option(v.type)); + + switch (m_settings.view_type) + { + case EViewType::FeatureType: + { + return v.is_travel() ? get_option_color(move_type_to_option(v.type)) : get_extrusion_role_color(v.role); + } + case EViewType::Height: + { + return v.is_travel() ? get_option_color(move_type_to_option(v.type)) : m_height_range.get_color_at(v.height); + } + case EViewType::Width: + { + return v.is_travel() ? get_option_color(move_type_to_option(v.type)) : m_width_range.get_color_at(v.width); + } + case EViewType::Speed: + { + return m_speed_range.get_color_at(v.feedrate); + } + case EViewType::ActualSpeed: + { + return m_actual_speed_range.get_color_at(v.actual_feedrate); + } + case EViewType::FanSpeed: + { + return v.is_travel() ? get_option_color(move_type_to_option(v.type)) : m_fan_speed_range.get_color_at(v.fan_speed); + } + case EViewType::Temperature: + { + return v.is_travel() ? get_option_color(move_type_to_option(v.type)) : m_temperature_range.get_color_at(v.temperature); + } + case EViewType::VolumetricFlowRate: + { + return v.is_travel() ? get_option_color(move_type_to_option(v.type)) : m_volumetric_rate_range.get_color_at(v.volumetric_rate()); + } + case EViewType::ActualVolumetricFlowRate: + { + return v.is_travel() ? get_option_color(move_type_to_option(v.type)) : m_actual_volumetric_rate_range.get_color_at(v.actual_volumetric_rate()); + } + case EViewType::LayerTimeLinear: + { + return v.is_travel() ? get_option_color(move_type_to_option(v.type)) : + m_layer_time_range[0].get_color_at(m_layers.get_layer_time(m_settings.time_mode, static_cast(v.layer_id))); + } + case EViewType::LayerTimeLogarithmic: + { + return v.is_travel() ? get_option_color(move_type_to_option(v.type)) : + m_layer_time_range[1].get_color_at(m_layers.get_layer_time(m_settings.time_mode, static_cast(v.layer_id))); + } + case EViewType::Tool: + { + assert(static_cast(v.extruder_id) < m_tool_colors.size()); + return m_tool_colors[v.extruder_id]; + } + case EViewType::Summary: // ORCA + case EViewType::ColorPrint: + { + return m_layers.layer_contains_colorprint_options(static_cast(v.layer_id)) ? DUMMY_COLOR : + m_color_print_colors[static_cast(v.color_id) % m_color_print_colors.size()]; + } + default: { break; } + } + + return DUMMY_COLOR; +} + +void ViewerImpl::set_tool_colors(const Palette& colors) +{ + m_tool_colors = colors; + m_settings.update_colors = true; +} + +void ViewerImpl::set_color_print_colors(const Palette& colors) +{ + m_color_print_colors = colors; + m_settings.update_colors = true; +} + +const Color& ViewerImpl::get_extrusion_role_color(EGCodeExtrusionRole role) const +{ + return m_extrusion_roles_colors[size_t(role)]; +} + +void ViewerImpl::set_extrusion_role_color(EGCodeExtrusionRole role, const Color& color) +{ + m_extrusion_roles_colors[size_t(role)] = color; + m_settings.update_colors = true; +} + +void ViewerImpl::reset_default_extrusion_roles_colors() +{ + m_extrusion_roles_colors = DEFAULT_EXTRUSION_ROLES_COLORS; +} + +const Color& ViewerImpl::get_option_color(EOptionType type) const +{ + return m_options_colors[size_t(type)]; +} + +void ViewerImpl::set_option_color(EOptionType type, const Color& color) +{ + m_options_colors[size_t(type)] = color; + m_settings.update_colors = true; +} + +void ViewerImpl::reset_default_options_colors() +{ + m_options_colors = DEFAULT_OPTIONS_COLORS; +} + +const ColorRange& ViewerImpl::get_color_range(EViewType type) const +{ + switch (type) + { + case EViewType::Height: { return m_height_range; } + case EViewType::Width: { return m_width_range; } + case EViewType::Speed: { return m_speed_range; } + case EViewType::ActualSpeed: { return m_actual_speed_range; } + case EViewType::FanSpeed: { return m_fan_speed_range; } + case EViewType::Temperature: { return m_temperature_range; } + case EViewType::VolumetricFlowRate: { return m_volumetric_rate_range; } + case EViewType::ActualVolumetricFlowRate: { return m_actual_volumetric_rate_range; } + case EViewType::LayerTimeLinear: { return m_layer_time_range[0]; } + case EViewType::LayerTimeLogarithmic: { return m_layer_time_range[1]; } + default: { return ColorRange::DUMMY_COLOR_RANGE; } + } +} + +void ViewerImpl::set_color_range_palette(EViewType type, const Palette& palette) +{ + switch (type) + { + case EViewType::Height: { m_height_range.set_palette(palette); break; } + case EViewType::Width: { m_width_range.set_palette(palette); break; } + case EViewType::Speed: { m_speed_range.set_palette(palette); break; } + case EViewType::ActualSpeed: { m_actual_speed_range.set_palette(palette); break; } + case EViewType::FanSpeed: { m_fan_speed_range.set_palette(palette); break; } + case EViewType::Temperature: { m_temperature_range.set_palette(palette); break; } + case EViewType::VolumetricFlowRate: { m_volumetric_rate_range.set_palette(palette); break; } + case EViewType::ActualVolumetricFlowRate: { m_actual_volumetric_rate_range.set_palette(palette); break; } + case EViewType::LayerTimeLinear: { m_layer_time_range[0].set_palette(palette); break; } + case EViewType::LayerTimeLogarithmic: { m_layer_time_range[1].set_palette(palette); break; } + default: { break; } + } + m_settings.update_colors = true; +} + +void ViewerImpl::set_travels_radius(float radius) +{ + m_travels_radius = std::clamp(radius, MIN_TRAVELS_RADIUS_MM, MAX_TRAVELS_RADIUS_MM); + update_heights_widths(); +} + +void ViewerImpl::set_wipes_radius(float radius) +{ + m_wipes_radius = std::clamp(radius, MIN_WIPES_RADIUS_MM, MAX_WIPES_RADIUS_MM); + update_heights_widths(); +} + +size_t ViewerImpl::get_used_cpu_memory() const +{ + size_t ret = sizeof(*this); + ret += m_layers.size_in_bytes_cpu(); + ret += STDVEC_MEMSIZE(m_options, EOptionType); + ret += m_used_extruders.size() * sizeof(std::map::value_type); + ret += sizeof(m_extrusion_roles_colors); + ret += sizeof(m_options_colors); + ret += STDVEC_MEMSIZE(m_vertices, PathVertex); + ret += m_valid_lines_bitset.size_in_bytes_cpu(); + ret += m_height_range.size_in_bytes_cpu(); + ret += m_width_range.size_in_bytes_cpu(); + ret += m_speed_range.size_in_bytes_cpu(); + ret += m_actual_speed_range.size_in_bytes_cpu(); + ret += m_fan_speed_range.size_in_bytes_cpu(); + ret += m_temperature_range.size_in_bytes_cpu(); + ret += m_volumetric_rate_range.size_in_bytes_cpu(); + ret += m_actual_volumetric_rate_range.size_in_bytes_cpu(); + for (size_t i = 0; i < COLOR_RANGE_TYPES_COUNT; ++i) { + ret += m_layer_time_range[i].size_in_bytes_cpu(); + } + ret += STDVEC_MEMSIZE(m_tool_colors, Color); + ret += STDVEC_MEMSIZE(m_color_print_colors, Color); + return ret; +} + +size_t ViewerImpl::get_used_gpu_memory() const +{ + size_t ret = 0; + ret += m_segment_template.size_in_bytes_gpu(); + ret += m_option_template.size_in_bytes_gpu(); +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + ret += m_tool_marker.size_in_bytes_gpu(); + ret += m_cog_marker.size_in_bytes_gpu(); +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS +#ifdef ENABLE_OPENGL_ES + ret += m_texture_data.get_used_gpu_memory(); +#else + ret += m_positions_tex_size; + ret += m_height_width_angle_tex_size; + ret += m_colors_tex_size; + ret += m_enabled_segments_tex_size; + ret += m_enabled_options_tex_size; +#endif // ENABLE_OPENGL_ES + return ret; +} + +static bool is_visible(const PathVertex& v, const Settings& settings) +{ + const EOptionType option_type = move_type_to_option(v.type); + try + { + return (option_type == EOptionType::COUNT) ? + (v.type == EMoveType::Extrude) ? settings.extrusion_roles_visibility[size_t(v.role)] : false : + settings.options_visibility[size_t(option_type)]; + } + catch (...) + { + return false; + } +} + +void ViewerImpl::update_view_full_range() +{ + const Interval& layers_range = m_layers.get_view_range(); + const bool travels_visible = m_settings.options_visibility[size_t(EOptionType::Travels)]; + const bool wipes_visible = m_settings.options_visibility[size_t(EOptionType::Wipes)]; + + auto first_it = m_vertices.begin(); + while (first_it != m_vertices.end() && + (first_it->layer_id < layers_range[0] || !is_visible(*first_it, m_settings))) { + ++first_it; + } + + // If the first vertex is an extrusion, add an extra step to properly detect the first segment + if (first_it != m_vertices.begin() && first_it != m_vertices.end() && first_it->type == EMoveType::Extrude) + --first_it; + + if (first_it == m_vertices.end()) + m_view_range.set_full(Range()); + else { + if (travels_visible || wipes_visible) { + // if the global range starts with a travel/wipe move, extend it to the travel/wipe start + while (first_it != m_vertices.begin() && + ((travels_visible && first_it->is_travel()) || + (wipes_visible && first_it->is_wipe()))) { + --first_it; + } + } + + auto last_it = first_it; + while (last_it != m_vertices.end() && last_it->layer_id <= layers_range[1]) { + ++last_it; + } + if (last_it != first_it) + --last_it; + + // remove disabled trailing options, if any + auto rev_first_it = std::make_reverse_iterator(first_it); + if (rev_first_it != m_vertices.rbegin()) + --rev_first_it; + auto rev_last_it = std::make_reverse_iterator(last_it); + if (rev_last_it != m_vertices.rbegin()) + --rev_last_it; + + bool reduced = false; + while (rev_last_it != rev_first_it && !is_visible(*rev_last_it, m_settings)) { + ++rev_last_it; + reduced = true; + } + + if (reduced && rev_last_it != m_vertices.rend()) + last_it = rev_last_it.base() - 1; + + if (travels_visible || wipes_visible) { + // if the global range ends with a travel/wipe move, extend it to the travel/wipe end + while (last_it != m_vertices.end() && last_it + 1 != m_vertices.end() && + ((travels_visible && last_it->is_travel() && (last_it + 1)->is_travel()) || + (wipes_visible && last_it->is_wipe() && (last_it + 1)->is_wipe()))) { + ++last_it; + } + } + + if (first_it != last_it) + m_view_range.set_full(std::distance(m_vertices.begin(), first_it), std::distance(m_vertices.begin(), last_it)); + else + m_view_range.set_full(Range()); + + if (m_settings.top_layer_only_view_range) { + const Interval& full_range = m_view_range.get_full(); + auto top_first_it = m_vertices.begin() + full_range[0]; + bool shortened = false; + while (top_first_it != m_vertices.end() && (top_first_it->layer_id < layers_range[1] || !is_visible(*top_first_it, m_settings))) { + ++top_first_it; + shortened = true; + } + if (shortened) + --top_first_it; + + // when spiral vase mode is enabled and only one layer is shown, extend the range by one step + if (m_settings.spiral_vase_mode && layers_range[0] > 0 && layers_range[0] == layers_range[1]) + --top_first_it; + m_view_range.set_enabled(std::distance(m_vertices.begin(), top_first_it), full_range[1]); + } + else + m_view_range.set_enabled(m_view_range.get_full()); + } + + m_settings.update_view_full_range = false; +} + +void ViewerImpl::update_color_ranges() +{ + // Color ranges do not need to be recalculated that often. If the following settings are the same + // as last time, the current ranges are still valid. The recalculation is quite expensive. + if (m_settings_used_for_ranges.has_value() && + m_settings.extrusion_roles_visibility == m_settings_used_for_ranges->extrusion_roles_visibility && + m_settings.options_visibility == m_settings_used_for_ranges->options_visibility) + return; + + m_width_range.reset(); + m_height_range.reset(); + m_speed_range.reset(); + m_actual_speed_range.reset(); + m_fan_speed_range.reset(); + m_temperature_range.reset(); + m_volumetric_rate_range.reset(); + m_actual_volumetric_rate_range.reset(); + m_layer_time_range[0].reset(); // ColorRange::EType::Linear + m_layer_time_range[1].reset(); // ColorRange::EType::Logarithmic + + for (size_t i = 0; i < m_vertices.size(); i++) { + const PathVertex& v = m_vertices[i]; + if (v.is_extrusion()) { + m_height_range.update(round_to_bin(v.height)); + if (!v.is_custom_gcode() || m_settings.extrusion_roles_visibility[size_t(EGCodeExtrusionRole::Custom)]) { + m_width_range.update(round_to_bin(v.width)); + m_volumetric_rate_range.update(round_to_bin(v.volumetric_rate())); + m_actual_volumetric_rate_range.update(round_to_bin(v.actual_volumetric_rate())); + } + m_fan_speed_range.update(round_to_bin(v.fan_speed)); + m_temperature_range.update(round_to_bin(v.temperature)); + } + if ((v.is_travel() && m_settings.options_visibility[size_t(EOptionType::Travels)]) || + (v.is_wipe() && m_settings.options_visibility[size_t(EOptionType::Wipes)]) || + v.is_extrusion()) { + m_speed_range.update(v.feedrate); + m_actual_speed_range.update(v.actual_feedrate); + } + } + + const std::vector times = m_layers.get_times(m_settings.time_mode); + for (size_t i = 0; i < m_layer_time_range.size(); ++i) { + for (float t : times) { + m_layer_time_range[i].update(t); + } + } + + m_settings_used_for_ranges = m_settings; +} + +void ViewerImpl::update_heights_widths() +{ +#ifdef ENABLE_OPENGL_ES + std::vector heights_widths_angles; + heights_widths_angles.reserve(m_vertices.size()); + extract_pos_and_or_hwa(m_vertices, m_travels_radius, m_wipes_radius, m_valid_lines_bitset, nullptr, &heights_widths_angles); + m_texture_data.set_heights_widths_angles(heights_widths_angles); +#else + if (m_heights_widths_angles_buf_id == 0) + return; + + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_heights_widths_angles_buf_id)); + + Vec3* buffer = static_cast(glMapBuffer(GL_TEXTURE_BUFFER, GL_WRITE_ONLY)); + glcheck(); + + for (size_t i = 0; i < m_vertices.size(); ++i) { + const PathVertex& v = m_vertices[i]; + if (v.is_travel()) { + buffer[i][0] = m_travels_radius; + buffer[i][1] = m_travels_radius; + } + else if (v.is_wipe()) { + buffer[i][0] = m_wipes_radius; + buffer[i][1] = m_wipes_radius; + } + } + + glsafe(glUnmapBuffer(GL_TEXTURE_BUFFER)); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, 0)); +#endif // ENABLE_OPENGL_ES +} + +void ViewerImpl::render_segments(const Mat4x4& view_matrix, const Mat4x4& projection_matrix, const Vec3& camera_position) +{ + if (m_segments_shader_id == 0) + return; + +#ifdef ENABLE_OPENGL_ES + if (m_texture_data.get_enabled_segments_count() == 0) +#else + if (m_enabled_segments_count == 0) +#endif // ENABLE_OPENGL_ES + return; + + int curr_active_texture = 0; + glsafe(glGetIntegerv(GL_ACTIVE_TEXTURE, &curr_active_texture)); + int curr_shader; + glsafe(glGetIntegerv(GL_CURRENT_PROGRAM, &curr_shader)); + const bool curr_cull_face = glIsEnabled(GL_CULL_FACE); + glcheck(); + + glsafe(glUseProgram(m_segments_shader_id)); + + glsafe(glUniform1i(m_uni_segments_positions_tex_id, 0)); + glsafe(glUniform1i(m_uni_segments_height_width_angle_tex_id, 1)); + glsafe(glUniform1i(m_uni_segments_colors_tex_id, 2)); + glsafe(glUniform1i(m_uni_segments_segment_index_tex_id, 3)); + glsafe(glUniformMatrix4fv(m_uni_segments_view_matrix_id, 1, GL_FALSE, view_matrix.data())); + glsafe(glUniformMatrix4fv(m_uni_segments_projection_matrix_id, 1, GL_FALSE, projection_matrix.data())); + glsafe(glUniform3fv(m_uni_segments_camera_position_id, 1, camera_position.data())); + + glsafe(glDisable(GL_CULL_FACE)); + +#ifdef ENABLE_OPENGL_ES + int curr_bound_texture = 0; + glsafe(glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_bound_texture)); + + for (size_t i = 0; i < m_texture_data.get_count(); ++i) { + const auto [id, count] = m_texture_data.get_enabled_segments_tex_id(i); + if (count == 0) + continue; + glsafe(glActiveTexture(GL_TEXTURE0)); + glsafe(glBindTexture(GL_TEXTURE_2D, m_texture_data.get_positions_tex_id(i).first)); + glsafe(glActiveTexture(GL_TEXTURE1)); + glsafe(glBindTexture(GL_TEXTURE_2D, m_texture_data.get_heights_widths_angles_tex_id(i).first)); + glsafe(glActiveTexture(GL_TEXTURE2)); + glsafe(glBindTexture(GL_TEXTURE_2D, m_texture_data.get_colors_tex_id(i).first)); + glsafe(glActiveTexture(GL_TEXTURE3)); + glsafe(glBindTexture(GL_TEXTURE_2D, id)); + m_segment_template.render(count); + } +#else + std::array curr_bound_texture = { 0, 0, 0, 0 }; + for (int i = 0; i < curr_bound_texture.size(); ++i) { + glsafe(glActiveTexture(GL_TEXTURE0 + i)); + glsafe(glGetIntegerv(GL_TEXTURE_BINDING_BUFFER, &curr_bound_texture[i])); + //assert(curr_bound_texture[i] == 0); + } + + glsafe(glActiveTexture(GL_TEXTURE0)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_positions_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_positions_buf_id)); + glsafe(glActiveTexture(GL_TEXTURE1)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_heights_widths_angles_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_heights_widths_angles_buf_id)); + glsafe(glActiveTexture(GL_TEXTURE2)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_colors_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, m_colors_buf_id)); + glsafe(glActiveTexture(GL_TEXTURE3)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_enabled_segments_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, m_enabled_segments_buf_id)); + + m_segment_template.render(m_enabled_segments_count); +#endif // ENABLE_OPENGL_ES + + if (curr_cull_face) + glsafe(glEnable(GL_CULL_FACE)); + + glsafe(glUseProgram(curr_shader)); +#ifdef ENABLE_OPENGL_ES + glsafe(glBindTexture(GL_TEXTURE_2D, curr_bound_texture)); +#else + for (int i = 0; i < curr_bound_texture.size(); ++i) { + glsafe(glActiveTexture(GL_TEXTURE0 + i)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, curr_bound_texture[i])); + } +#endif // ENABLE_OPENGL_ES + glsafe(glActiveTexture(curr_active_texture)); +} + +void ViewerImpl::render_options(const Mat4x4& view_matrix, const Mat4x4& projection_matrix) +{ + if (m_options_shader_id == 0) + return; + +#ifdef ENABLE_OPENGL_ES + if (m_texture_data.get_enabled_options_count() == 0) +#else + if (m_enabled_options_count == 0) +#endif // ENABLE_OPENGL_ES + return; + + int curr_active_texture = 0; + glsafe(glGetIntegerv(GL_ACTIVE_TEXTURE, &curr_active_texture)); + int curr_shader; + glsafe(glGetIntegerv(GL_CURRENT_PROGRAM, &curr_shader)); + const bool curr_cull_face = glIsEnabled(GL_CULL_FACE); + glcheck(); + + glsafe(glUseProgram(m_options_shader_id)); + + glsafe(glUniform1i(m_uni_options_positions_tex_id, 0)); + glsafe(glUniform1i(m_uni_options_height_width_angle_tex_id, 1)); + glsafe(glUniform1i(m_uni_options_colors_tex_id, 2)); + glsafe(glUniform1i(m_uni_options_segment_index_tex_id, 3)); + glsafe(glUniformMatrix4fv(m_uni_options_view_matrix_id, 1, GL_FALSE, view_matrix.data())); + glsafe(glUniformMatrix4fv(m_uni_options_projection_matrix_id, 1, GL_FALSE, projection_matrix.data())); + + glsafe(glEnable(GL_CULL_FACE)); + +#ifdef ENABLE_OPENGL_ES + int curr_bound_texture = 0; + glsafe(glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_bound_texture)); + + for (size_t i = 0; i < m_texture_data.get_count(); ++i) { + const auto [id, count] = m_texture_data.get_enabled_options_tex_id(i); + if (count == 0) + continue; + glsafe(glActiveTexture(GL_TEXTURE0)); + glsafe(glBindTexture(GL_TEXTURE_2D, m_texture_data.get_positions_tex_id(i).first)); + glsafe(glActiveTexture(GL_TEXTURE1)); + glsafe(glBindTexture(GL_TEXTURE_2D, m_texture_data.get_heights_widths_angles_tex_id(i).first)); + glsafe(glActiveTexture(GL_TEXTURE2)); + glsafe(glBindTexture(GL_TEXTURE_2D, m_texture_data.get_colors_tex_id(i).first)); + glsafe(glActiveTexture(GL_TEXTURE3)); + glsafe(glBindTexture(GL_TEXTURE_2D, id)); + m_option_template.render(count); + } +#else + std::array curr_bound_texture = { 0, 0, 0, 0 }; + for (int i = 0; i < curr_bound_texture.size(); ++i) { + glsafe(glActiveTexture(GL_TEXTURE0 + i)); + glsafe(glGetIntegerv(GL_TEXTURE_BINDING_BUFFER, &curr_bound_texture[i])); + //assert(curr_bound_texture[i] == 0); + } + + glsafe(glActiveTexture(GL_TEXTURE0)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_positions_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_positions_buf_id)); + glsafe(glActiveTexture(GL_TEXTURE1)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_heights_widths_angles_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_heights_widths_angles_buf_id)); + glsafe(glActiveTexture(GL_TEXTURE2)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_colors_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, m_colors_buf_id)); + glsafe(glActiveTexture(GL_TEXTURE3)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_enabled_options_tex_id)); + glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, m_enabled_options_buf_id)); + + m_option_template.render(m_enabled_options_count); +#endif // ENABLE_OPENGL_ES + + if (!curr_cull_face) + glsafe(glDisable(GL_CULL_FACE)); + + glsafe(glUseProgram(curr_shader)); +#ifdef ENABLE_OPENGL_ES + glsafe(glBindTexture(GL_TEXTURE_2D, curr_bound_texture)); +#else + for (int i = 0; i < curr_bound_texture.size(); ++i) { + glsafe(glActiveTexture(GL_TEXTURE0 + i)); + glsafe(glBindTexture(GL_TEXTURE_BUFFER, curr_bound_texture[i])); + } +#endif // ENABLE_OPENGL_ES + glsafe(glActiveTexture(curr_active_texture)); +} + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS +void ViewerImpl::render_cog_marker(const Mat4x4& view_matrix, const Mat4x4& projection_matrix) +{ + if (m_cog_marker_shader_id == 0) + return; + + int curr_shader; + glsafe(glGetIntegerv(GL_CURRENT_PROGRAM, &curr_shader)); + const bool curr_cull_face = glIsEnabled(GL_CULL_FACE); + const bool curr_depth_test = glIsEnabled(GL_DEPTH_TEST); + glcheck(); + + glsafe(glEnable(GL_CULL_FACE)); + glsafe(glDisable(GL_DEPTH_TEST)); + + glsafe(glUseProgram(m_cog_marker_shader_id)); + + glsafe(glUniform3fv(m_uni_cog_marker_world_center_position, 1, m_cog_marker.get_position().data())); + glsafe(glUniform1f(m_uni_cog_marker_scale_factor, m_cog_marker_scale_factor)); + glsafe(glUniformMatrix4fv(m_uni_cog_marker_view_matrix, 1, GL_FALSE, view_matrix.data())); + glsafe(glUniformMatrix4fv(m_uni_cog_marker_projection_matrix, 1, GL_FALSE, projection_matrix.data())); + + m_cog_marker.render(); + + if (curr_depth_test) + glsafe(glEnable(GL_DEPTH_TEST)); + if (!curr_cull_face) + glsafe(glDisable(GL_CULL_FACE)); + + glsafe(glUseProgram(curr_shader)); +} + +void ViewerImpl::render_tool_marker(const Mat4x4& view_matrix, const Mat4x4& projection_matrix) +{ + if (m_tool_marker_shader_id == 0) + return; + + if (m_view_range.get_visible()[1] == m_view_range.get_enabled()[1]) + return; + + m_tool_marker.set_position(get_current_vertex().position); + + int curr_shader; + glsafe(glGetIntegerv(GL_CURRENT_PROGRAM, &curr_shader)); + const bool curr_cull_face = glIsEnabled(GL_CULL_FACE); + GLboolean curr_depth_mask; + glsafe(glGetBooleanv(GL_DEPTH_WRITEMASK, &curr_depth_mask)); + const bool curr_blend = glIsEnabled(GL_BLEND); + glcheck(); + int curr_blend_func; + glsafe(glGetIntegerv(GL_BLEND_SRC_ALPHA, &curr_blend_func)); + + glsafe(glDisable(GL_CULL_FACE)); + glsafe(glDepthMask(GL_FALSE)); + glsafe(glEnable(GL_BLEND)); + glsafe(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + + glsafe(glUseProgram(m_tool_marker_shader_id)); + + const Vec3& origin = m_tool_marker.get_position(); + const Vec3 offset = { 0.0f, 0.0f, m_tool_marker.get_offset_z() }; + const Vec3 position = origin + offset; + glsafe(glUniform3fv(m_uni_tool_marker_world_origin, 1, position.data())); + glsafe(glUniform1f(m_uni_tool_marker_scale_factor, m_tool_marker_scale_factor)); + glsafe(glUniformMatrix4fv(m_uni_tool_marker_view_matrix, 1, GL_FALSE, view_matrix.data())); + glsafe(glUniformMatrix4fv(m_uni_tool_marker_projection_matrix, 1, GL_FALSE, projection_matrix.data())); + const Color& color = m_tool_marker.get_color(); + glsafe(glUniform4f(m_uni_tool_marker_color_base, color[0], color[1], color[2], m_tool_marker.get_alpha())); + + m_tool_marker.render(); + + glsafe(glBlendFunc(GL_SRC_ALPHA, curr_blend_func)); + if (!curr_blend) + glsafe(glDisable(GL_BLEND)); + if (curr_depth_mask == GL_TRUE) + glsafe(glDepthMask(GL_TRUE)); + if (curr_cull_face) + glsafe(glEnable(GL_CULL_FACE)); + + glsafe(glUseProgram(curr_shader)); +} +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + +} // namespace libvgcode diff --git a/src/libvgcode/src/ViewerImpl.hpp b/src/libvgcode/src/ViewerImpl.hpp new file mode 100644 index 0000000000..e506274615 --- /dev/null +++ b/src/libvgcode/src/ViewerImpl.hpp @@ -0,0 +1,470 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel MikuÅ¡ @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_VIEWERIMPL_HPP +#define VGCODE_VIEWERIMPL_HPP + +#include "Settings.hpp" +#include "SegmentTemplate.hpp" +#include "OptionTemplate.hpp" +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS +#include "CogMarker.hpp" +#include "ToolMarker.hpp" +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS +#include "../include/PathVertex.hpp" +#include "../include/ColorRange.hpp" +#include "../include/ColorPrint.hpp" +#include "Bitset.hpp" +#include "ViewRange.hpp" +#include "Layers.hpp" +#include "ExtrusionRoles.hpp" + +#include +#include + +namespace libvgcode { + +struct GCodeInputData; + +class ViewerImpl +{ +public: + ViewerImpl(); + ~ViewerImpl() { shutdown(); } + ViewerImpl(const ViewerImpl& other) = delete; + ViewerImpl(ViewerImpl&& other) = delete; + ViewerImpl& operator = (const ViewerImpl& other) = delete; + ViewerImpl& operator = (ViewerImpl&& other) = delete; + + // + // Initialize shaders, uniform indices and segment geometry. + // + void init(const std::string& opengl_context_version); + // + // Release the resources used by the viewer. + // + void shutdown(); + // + // Reset all caches and free gpu memory. + // + void reset(); + // + // Setup all the variables used for visualization of the toolpaths + // from the given gcode data. + // + void load(GCodeInputData&& gcode_data); + + // + // Update the visibility property of toolpaths in dependence + // of the current settings + // + void update_enabled_entities(); + // + // Update the color of toolpaths in dependence of the current + // view type and settings + // + void update_colors(); + void update_colors_texture(); + + // + // Render the toolpaths + // + void render(const Mat4x4& view_matrix, const Mat4x4& projection_matrix); + + EViewType get_view_type() const { return m_settings.view_type; } + void set_view_type(EViewType type); + + ETimeMode get_time_mode() const { return m_settings.time_mode; } + void set_time_mode(ETimeMode mode); + + const Interval& get_layers_view_range() const { return m_layers.get_view_range(); } + void set_layers_view_range(const Interval& range) { set_layers_view_range(range[0], range[1]); } + void set_layers_view_range(Interval::value_type min, Interval::value_type max); + + bool is_top_layer_only_view_range() const { return m_settings.top_layer_only_view_range; } + void toggle_top_layer_only_view_range(); + + bool is_spiral_vase_mode() const { return m_settings.spiral_vase_mode; } + + std::vector get_time_modes() const; + + size_t get_layers_count() const { return m_layers.count(); } + float get_layer_z(size_t layer_id) const { return m_layers.get_layer_z(layer_id); } + std::vector get_layers_zs() const { return m_layers.get_zs(); } + + size_t get_layer_id_at(float z) const { return m_layers.get_layer_id_at(z); } + + size_t get_used_extruders_count() const { return m_used_extruders.size(); } + std::vector get_used_extruders_ids() const; + + size_t get_color_prints_count(uint8_t extruder_id) const; + std::vector get_color_prints(uint8_t extruder_id) const; + + AABox get_bounding_box(const std::vector& types = { + EMoveType::Retract, EMoveType::Unretract, EMoveType::Seam, EMoveType::ToolChange, + EMoveType::ColorChange, EMoveType::PausePrint, EMoveType::CustomGCode, EMoveType::Travel, + EMoveType::Wipe, EMoveType::Extrude }) const; + AABox get_extrusion_bounding_box(const std::vector& roles = { + EGCodeExtrusionRole::Perimeter, EGCodeExtrusionRole::ExternalPerimeter, EGCodeExtrusionRole::OverhangPerimeter, + EGCodeExtrusionRole::InternalInfill, EGCodeExtrusionRole::SolidInfill, EGCodeExtrusionRole::TopSolidInfill, + EGCodeExtrusionRole::Ironing, EGCodeExtrusionRole::BridgeInfill, EGCodeExtrusionRole::GapFill, + EGCodeExtrusionRole::Skirt, EGCodeExtrusionRole::SupportMaterial, EGCodeExtrusionRole::SupportMaterialInterface, + EGCodeExtrusionRole::WipeTower, EGCodeExtrusionRole::Custom, + // ORCA + EGCodeExtrusionRole::BottomSurface, EGCodeExtrusionRole::InternalBridgeInfill, EGCodeExtrusionRole::Brim, + EGCodeExtrusionRole::SupportTransition, EGCodeExtrusionRole::Mixed + }) const; + + bool is_option_visible(EOptionType type) const; + void toggle_option_visibility(EOptionType type); + + bool is_extrusion_role_visible(EGCodeExtrusionRole role) const; + void toggle_extrusion_role_visibility(EGCodeExtrusionRole role); + + const Interval& get_view_full_range() const { return m_view_range.get_full(); } + const Interval& get_view_enabled_range() const { return m_view_range.get_enabled(); } + const Interval& get_view_visible_range() const { return m_view_range.get_visible(); } + void set_view_visible_range(Interval::value_type min, Interval::value_type max); + + size_t get_vertices_count() const { return m_vertices.size(); } + const PathVertex& get_current_vertex() const { return get_vertex_at(get_current_vertex_id()); } + size_t get_current_vertex_id() const { return static_cast(m_view_range.get_visible()[1]); } + const PathVertex& get_vertex_at(size_t id) const { + return (id < m_vertices.size()) ? m_vertices[id] : PathVertex::DUMMY_PATH_VERTEX; + } + float get_estimated_time() const { return m_total_time[static_cast(m_settings.time_mode)]; } + float get_estimated_time_at(size_t id) const; + Color get_vertex_color(const PathVertex& vertex) const; + + size_t get_extrusion_roles_count() const { return m_extrusion_roles.get_roles_count(); } + std::vector get_extrusion_roles() const { return m_extrusion_roles.get_roles(); } + float get_extrusion_role_estimated_time(EGCodeExtrusionRole role) const { return m_extrusion_roles.get_time(role, m_settings.time_mode); } + + size_t get_options_count() const { return m_options.size(); } + const std::vector& get_options() const { return m_options; } + + float get_travels_estimated_time() const { return m_travels_time[static_cast(m_settings.time_mode)]; } + std::vector get_layers_estimated_times() const { return m_layers.get_times(m_settings.time_mode); } + + size_t get_tool_colors_count() const { return m_tool_colors.size(); } + const Palette& get_tool_colors() const { return m_tool_colors; } + void set_tool_colors(const Palette& colors); + + size_t get_color_print_colors_count() const { return m_color_print_colors.size(); } + const Palette& get_color_print_colors() const { return m_color_print_colors; } + void set_color_print_colors(const Palette& colors); + + const Color& get_extrusion_role_color(EGCodeExtrusionRole role) const; + void set_extrusion_role_color(EGCodeExtrusionRole role, const Color& color); + void reset_default_extrusion_roles_colors(); + + const Color& get_option_color(EOptionType type) const; + void set_option_color(EOptionType type, const Color& color); + void reset_default_options_colors(); + + const ColorRange& get_color_range(EViewType type) const; + void set_color_range_palette(EViewType type, const Palette& palette); + + float get_travels_radius() const { return m_travels_radius; } + void set_travels_radius(float radius); + float get_wipes_radius() const { return m_wipes_radius; } + void set_wipes_radius(float radius); + + size_t get_used_cpu_memory() const; + size_t get_used_gpu_memory() const; + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + Vec3 get_cog_marker_position() const { return m_cog_marker.get_position(); } + + float get_cog_marker_scale_factor() const { return m_cog_marker_scale_factor; } + void set_cog_marker_scale_factor(float factor) { m_cog_marker_scale_factor = std::max(factor, 0.001f); } + + const Vec3& get_tool_marker_position() const { return m_tool_marker.get_position(); } + + float get_tool_marker_offset_z() const { return m_tool_marker.get_offset_z(); } + void set_tool_marker_offset_z(float offset_z) { m_tool_marker.set_offset_z(offset_z); } + + float get_tool_marker_scale_factor() const { return m_tool_marker_scale_factor; } + void set_tool_marker_scale_factor(float factor) { m_tool_marker_scale_factor = std::max(factor, 0.001f); } + + const Color& get_tool_marker_color() const { return m_tool_marker.get_color(); } + void set_tool_marker_color(const Color& color) { m_tool_marker.set_color(color); } + + float get_tool_marker_alpha() const { return m_tool_marker.get_alpha(); } + void set_tool_marker_alpha(float alpha) { m_tool_marker.set_alpha(alpha); } +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + +private: + // + // Settings used to render the toolpaths + // + Settings m_settings; + // + // Detected layers + // + Layers m_layers; + // + // Detected extrusion roles + // + ExtrusionRoles m_extrusion_roles; + // + // Detected options + // + std::vector m_options; + // + // Detected used extruders ids + // + std::map> m_used_extruders; + // + // Vertices ranges for visualization + // + ViewRange m_view_range; + // + // Detected total moves times + // + std::array m_total_time{ 0.0f, 0.0f }; + // + // Detected travel moves times + // + std::array m_travels_time{ 0.0f, 0.0f }; + // + // Radius of cylinders used to render travel moves segments + // + float m_travels_radius{ DEFAULT_TRAVELS_RADIUS_MM }; + // + // Radius of cylinders used to render wipe moves segments + // + float m_wipes_radius{ DEFAULT_WIPES_RADIUS_MM }; + // + // Palette used to render extrusion roles + // + std::array m_extrusion_roles_colors; + // + // Palette used to render options + // + std::array m_options_colors; + + bool m_initialized{ false }; + + // + // The OpenGL element used to represent all toolpath segments + // + SegmentTemplate m_segment_template; + // + // The OpenGL element used to represent all option markers + // + OptionTemplate m_option_template; +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + // + // The OpenGL element used to represent the center of gravity + // + CogMarker m_cog_marker; + float m_cog_marker_scale_factor{ 1.0f }; + // + // The OpenGL element used to represent the tool nozzle + // + ToolMarker m_tool_marker; + float m_tool_marker_scale_factor{ 1.0f }; +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + // + // cpu buffer to store vertices + // + std::vector m_vertices; + + // Cache for the colors to reduce the need to recalculate colors of all the vertices. + std::vector m_vertices_colors; + + // + // Variables used for toolpaths visibiliity + // + BitSet<> m_valid_lines_bitset; + // + // Variables used for toolpaths coloring + // + std::optional m_settings_used_for_ranges; + ColorRange m_height_range; + ColorRange m_width_range; + ColorRange m_speed_range; + ColorRange m_actual_speed_range; + ColorRange m_fan_speed_range; + ColorRange m_temperature_range; + ColorRange m_volumetric_rate_range; + ColorRange m_actual_volumetric_rate_range; + std::array m_layer_time_range{ + ColorRange(EColorRangeType::Linear), ColorRange(EColorRangeType::Logarithmic) + }; + Palette m_tool_colors; + Palette m_color_print_colors; + // + // OpenGL shaders ids + // + unsigned int m_segments_shader_id{ 0 }; + unsigned int m_options_shader_id{ 0 }; +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + unsigned int m_cog_marker_shader_id{ 0 }; + unsigned int m_tool_marker_shader_id{ 0 }; +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + // + // Caches for OpenGL uniforms id for segments shader + // + int m_uni_segments_view_matrix_id{ -1 }; + int m_uni_segments_projection_matrix_id{ -1 }; + int m_uni_segments_camera_position_id{ -1 }; + int m_uni_segments_positions_tex_id{ -1 }; + int m_uni_segments_height_width_angle_tex_id{ -1 }; + int m_uni_segments_colors_tex_id{ -1 }; + int m_uni_segments_segment_index_tex_id{ -1 }; + // + // Caches for OpenGL uniforms id for options shader + // + int m_uni_options_view_matrix_id{ -1 }; + int m_uni_options_projection_matrix_id{ -1 }; + int m_uni_options_positions_tex_id{ -1 }; + int m_uni_options_height_width_angle_tex_id{ -1 }; + int m_uni_options_colors_tex_id{ -1 }; + int m_uni_options_segment_index_tex_id{ -1 }; +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + // + // Caches for OpenGL uniforms id for cog marker shader + // + int m_uni_cog_marker_world_center_position{ -1 }; + int m_uni_cog_marker_scale_factor{ -1 }; + int m_uni_cog_marker_view_matrix{ -1 }; + int m_uni_cog_marker_projection_matrix{ -1 }; + // + // Caches for OpenGL uniforms id for tool marker shader + // + int m_uni_tool_marker_world_origin{ -1 }; + int m_uni_tool_marker_scale_factor{ -1 }; + int m_uni_tool_marker_view_matrix{ -1 }; + int m_uni_tool_marker_projection_matrix{ -1 }; + int m_uni_tool_marker_color_base{ -1 }; +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + +#ifdef ENABLE_OPENGL_ES + class TextureData + { + public: + void init(size_t vertices_count); + void set_positions(const std::vector& positions); + void set_heights_widths_angles(const std::vector& heights_widths_angles); + void set_colors(const std::vector& colors); + void set_enabled_segments(const std::vector& enabled_segments); + void set_enabled_options(const std::vector& enabled_options); + void reset(); + size_t get_count() const { return m_count; } + std::pair get_positions_tex_id(size_t id) const; + std::pair get_heights_widths_angles_tex_id(size_t id) const; + std::pair get_colors_tex_id(size_t id) const; + std::pair get_enabled_segments_tex_id(size_t id) const; + std::pair get_enabled_options_tex_id(size_t id) const; + + size_t get_enabled_segments_count() const; + size_t get_enabled_options_count() const; + + size_t max_texture_capacity() const { return m_width * m_height; } + size_t get_used_gpu_memory() const; + + private: + // + // Texture width + // + size_t m_width{ 0 }; + // + // Texture height + // + size_t m_height{ 0 }; + // + // Count of textures + // + size_t m_count{ 0 }; + // + // Caches for size of data sent to gpu, in bytes + // + size_t m_positions_size{ 0 }; + size_t m_height_width_angle_size{ 0 }; + size_t m_colors_size{ 0 }; + size_t m_enabled_segments_size{ 0 }; + size_t m_enabled_options_size{ 0 }; + + struct TexIds + { + // + // OpenGL texture to store positions + // + std::pair positions{ 0, 0 }; + // + // OpenGL texture to store heights, widths and angles + // + std::pair heights_widths_angles{ 0, 0 }; + // + // OpenGL texture to store colors + // + std::pair colors{ 0, 0 }; + // + // OpenGL texture to store enabled segments + // + std::pair enabled_segments{ 0, 0 }; + // + // OpenGL texture to store enabled options + // + std::pair enabled_options{ 0, 0 }; + }; + + std::vector m_tex_ids; + }; + + TextureData m_texture_data; +#else + // + // OpenGL buffers to store positions + // + unsigned int m_positions_buf_id{ 0 }; + unsigned int m_positions_tex_id{ 0 }; + // + // OpenGL buffers to store heights, widths and angles + // + unsigned int m_heights_widths_angles_buf_id{ 0 }; + unsigned int m_heights_widths_angles_tex_id{ 0 }; + // + // OpenGL buffers to store colors + // + unsigned int m_colors_buf_id{ 0 }; + unsigned int m_colors_tex_id{ 0 }; + // + // OpenGL buffers to store enabled segments + // + unsigned int m_enabled_segments_buf_id{ 0 }; + unsigned int m_enabled_segments_tex_id{ 0 }; + size_t m_enabled_segments_count{ 0 }; + // + // OpenGL buffers to store enabled options + // + unsigned int m_enabled_options_buf_id{ 0 }; + unsigned int m_enabled_options_tex_id{ 0 }; + size_t m_enabled_options_count{ 0 }; + // + // Caches for size of data sent to gpu, in bytes + // + size_t m_positions_tex_size{ 0 }; + size_t m_height_width_angle_tex_size{ 0 }; + size_t m_colors_tex_size{ 0 }; + size_t m_enabled_segments_tex_size{ 0 }; + size_t m_enabled_options_tex_size{ 0 }; +#endif // ENABLE_OPENGL_ES + + void update_view_full_range(); + void update_color_ranges(); + void update_heights_widths(); + void render_segments(const Mat4x4& view_matrix, const Mat4x4& projection_matrix, const Vec3& camera_position); + void render_options(const Mat4x4& view_matrix, const Mat4x4& projection_matrix); +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + void render_cog_marker(const Mat4x4& view_matrix, const Mat4x4& projection_matrix); + void render_tool_marker(const Mat4x4& view_matrix, const Mat4x4& projection_matrix); +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS +}; + +} // namespace libvgcode + +#endif // VGCODE_VIEWERIMPL_HPP \ No newline at end of file diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index e6f28b68fe..051b5e5519 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -299,6 +299,8 @@ set(SLIC3R_GUI_SOURCES GUI/Jobs/Worker.hpp GUI/KBShortcutsDialog.cpp GUI/KBShortcutsDialog.hpp + GUI/LibVGCode/LibVGCodeWrapper.hpp + GUI/LibVGCode/LibVGCodeWrapper.cpp GUI/MainFrame.cpp GUI/MainFrame.hpp GUI/MarkdownTip.cpp @@ -707,13 +709,15 @@ source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SLIC3R_GUI_SOURCES}) encoding_check(libslic3r_gui) + if(APPLE AND CMAKE_VERSION VERSION_GREATER_EQUAL "4.0") set(_opengl_link_lib "") else() set(_opengl_link_lib OpenGL::GL) endif() -target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo GLEW::GLEW ${_opengl_link_lib} hidapi ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto noise::noise) +target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo libvgcode GLEW::GLEW OpenGL::GL hidapi ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto noise::noise) + if (MSVC) target_link_libraries(libslic3r_gui Setupapi.lib) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 4c43757834..6cc33dc169 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -936,7 +936,11 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, return; GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat"); - GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat"); +#if SLIC3R_OPENGL_ES + GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("dashed_lines"); +#else + GLShaderProgram* edges_shader = GUI::OpenGLManager::get_gl_info().is_core_profile() ? GUI::wxGetApp().get_shader("dashed_thick_lines") : GUI::wxGetApp().get_shader("flat"); +#endif // SLIC3R_OPENGL_ES if (type == ERenderType::Transparent) { glsafe(::glEnable(GL_BLEND)); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 7d97cabf9c..0774d06324 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -25,7 +25,11 @@ #include "libslic3r/Print.hpp" #include "libslic3r/Layer.hpp" #include "Widgets/ProgressDialog.hpp" +#include "MsgDialog.hpp" +#if ENABLE_ACTUAL_SPEED_DEBUG +#define IMGUI_DEFINE_MATH_OPERATORS +#endif // ENABLE_ACTUAL_SPEED_DEBUG #include #include @@ -40,6 +44,7 @@ #include #include + namespace Slic3r { namespace GUI { @@ -56,58 +61,39 @@ namespace GUI { // _u8L("Filament") // }; -static std::string get_view_type_string(GCodeViewer::EViewType view_type) +static std::string get_view_type_string(libvgcode::EViewType view_type) { - if (view_type == GCodeViewer::EViewType::Summary) + if (view_type == libvgcode::EViewType::Summary) return _u8L("Summary"); - else if (view_type == GCodeViewer::EViewType::FeatureType) + else if (view_type == libvgcode::EViewType::FeatureType) return _u8L("Line Type"); - else if (view_type == GCodeViewer::EViewType::Height) + else if (view_type == libvgcode::EViewType::Height) return _u8L("Layer Height"); - else if (view_type == GCodeViewer::EViewType::Width) + else if (view_type == libvgcode::EViewType::Width) return _u8L("Line Width"); - else if (view_type == GCodeViewer::EViewType::Feedrate) + else if (view_type == libvgcode::EViewType::Speed) return _u8L("Speed"); - else if (view_type == GCodeViewer::EViewType::FanSpeed) + else if (view_type == libvgcode::EViewType::ActualSpeed) + return _u8L("Actual Speed"); + else if (view_type == libvgcode::EViewType::FanSpeed) return _u8L("Fan Speed"); - else if (view_type == GCodeViewer::EViewType::Temperature) + else if (view_type == libvgcode::EViewType::Temperature) return _u8L("Temperature"); - else if (view_type == GCodeViewer::EViewType::VolumetricRate) + else if (view_type == libvgcode::EViewType::VolumetricFlowRate) return _u8L("Flow"); - else if (view_type == GCodeViewer::EViewType::Tool) + else if (view_type == libvgcode::EViewType::ActualVolumetricFlowRate) + return _u8L("Actual Flow"); + else if (view_type == libvgcode::EViewType::Tool) return _u8L("Tool"); - else if (view_type == GCodeViewer::EViewType::ColorPrint) + else if (view_type == libvgcode::EViewType::ColorPrint) return _u8L("Filament"); - else if (view_type == GCodeViewer::EViewType::LayerTime) + else if (view_type == libvgcode::EViewType::LayerTimeLinear) return _u8L("Layer Time"); -else if (view_type == GCodeViewer::EViewType::LayerTimeLog) +else if (view_type == libvgcode::EViewType::LayerTimeLogarithmic) return _u8L("Layer Time (log)"); return ""; } -static unsigned char buffer_id(EMoveType type) { - return static_cast(type) - static_cast(EMoveType::Retract); -} - -static EMoveType buffer_type(unsigned char id) { - return static_cast(static_cast(EMoveType::Retract) + id); -} - -// Round to a bin with minimum two digits resolution. -// Equivalent to conversion to string with sprintf(buf, "%.2g", value) and conversion back to float, but faster. -static float round_to_bin(const float value) -{ -// assert(value > 0); - constexpr float const scale [5] = { 100.f, 1000.f, 10000.f, 100000.f, 1000000.f }; - constexpr float const invscale [5] = { 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f }; - constexpr float const threshold[5] = { 0.095f, 0.0095f, 0.00095f, 0.000095f, 0.0000095f }; - // Scaling factor, pointer to the tables above. - int i = 0; - // While the scaling factor is not yet large enough to get two integer digits after scaling and rounding: - for (; value < threshold[i] && i < 4; ++ i) ; - return std::round(value * scale[i]) * invscale[i]; -} - // Find an index of a value in a sorted vector, which is in . // Returns -1 if there is no such member. static int find_close_layer_idx(const std::vector &zs, double &z, double eps) @@ -130,159 +116,87 @@ static int find_close_layer_idx(const std::vector &zs, double &z, double return -1; } -void GCodeViewer::VBuffer::reset() +#if ENABLE_ACTUAL_SPEED_DEBUG +int GCodeViewer::SequentialView::ActualSpeedImguiWidget::plot(const char* label, const std::array& frame_size) { - // release gpu memory - if (!vbos.empty()) { - glsafe(::glDeleteBuffers(static_cast(vbos.size()), static_cast(vbos.data()))); - vbos.clear(); - } - sizes.clear(); - count = 0; -} + ImGuiWindow* window = ImGui::GetCurrentWindow(); + if (window->SkipItems) + return -1; -void GCodeViewer::InstanceVBuffer::Ranges::reset() -{ - for (Range& range : ranges) { - // release gpu memory - if (range.vbo > 0) - glsafe(::glDeleteBuffers(1, &range.vbo)); + const ImGuiStyle& style = ImGui::GetStyle(); + const ImGuiIO& io = ImGui::GetIO(); + const ImGuiID id = window->GetID(label); + + const ImVec2 label_size = ImGui::CalcTextSize(label, nullptr, true); + ImVec2 internal_frame_size(frame_size[0], frame_size[1]); + internal_frame_size = ImGui::CalcItemSize(internal_frame_size, ImGui::CalcItemWidth(), label_size.y + style.FramePadding.y * 2.0f); + + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + internal_frame_size); + const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); + ImGui::ItemSize(total_bb, style.FramePadding.y); + if (!ImGui::ItemAdd(total_bb, 0, &frame_bb)) + return -1; + + const bool hovered = ImGui::ItemHoverable(frame_bb, id); + + ImGui::RenderFrame(frame_bb.Min, frame_bb.Max, ImGui::GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); + + static const int values_count_min = 2; + const int values_count = static_cast(data.size()); + int idx_hovered = -1; + + const ImVec2 offset(10.0f, 0.0f); + + const float size_y = y_range.second - y_range.first; + const float size_x = data.back().pos - data.front().pos; + if (size_x > 0.0f && values_count >= values_count_min) { + const float inv_scale_y = (size_y == 0.0f) ? 0.0f : 1.0f / size_y; + const float inv_scale_x = 1.0f / size_x; + const float x0 = data.front().pos; + const float y0 = y_range.first; + + const ImU32 grid_main_color = ImGui::GetColorU32(ImVec4(0.5f, 0.5f, 0.5f, 0.5f)); + const ImU32 grid_secondary_color = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.5f, 0.5f)); + + // horizontal levels + for (const auto& [level, color] : levels) { + const float y = 1.0f - ImSaturate((level - y_range.first) * inv_scale_y); + window->DrawList->AddLine(ImLerp(inner_bb.Min, ImVec2(inner_bb.Min.x + offset.x, inner_bb.Max.y), ImVec2(0.1f, y)), + ImLerp(inner_bb.Min, ImVec2(inner_bb.Min.x + offset.x, inner_bb.Max.y), ImVec2(0.9f, y)), ImGuiWrapper::to_ImU32(color), 3.0f); + } + + // vertical positions + for (int n = 0; n < values_count - 1; ++n) { + const float x = ImSaturate((data[n].pos - x0) * inv_scale_x); + window->DrawList->AddLine(ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(x, 0.0f)), + ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(x, 1.0f)), data[n].internal ? grid_secondary_color : grid_main_color); + } + window->DrawList->AddLine(ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(1.0f, 0.0f)), + ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(1.0f, 1.0f)), grid_main_color); + + // profiile + const ImU32 col_base = ImGui::GetColorU32(ImVec4(0.8f, 0.8f, 0.8f, 1.0f)); + const ImU32 col_hovered = ImGui::GetColorU32(ImGuiCol_PlotLinesHovered); + for (int n = 0; n < values_count - 1; ++n) { + const ImVec2 tp1(ImSaturate((data[n].pos - x0) * inv_scale_x), 1.0f - ImSaturate((data[n].speed - y0) * inv_scale_y)); + const ImVec2 tp2(ImSaturate((data[n + 1].pos - x0) * inv_scale_x), 1.0f - ImSaturate((data[n + 1].speed - y0) * inv_scale_y)); + // Tooltip on hover + if (hovered && inner_bb.Contains(io.MousePos)) { + const float t = ImClamp((io.MousePos.x - inner_bb.Min.x - offset.x) / (inner_bb.Max.x - inner_bb.Min.x - offset.x), 0.0f, 0.9999f); + if (tp1.x < t && t < tp2.x) + idx_hovered = n; + } + window->DrawList->AddLine(ImLerp(inner_bb.Min + offset, inner_bb.Max, tp1), ImLerp(inner_bb.Min + offset, inner_bb.Max, tp2), + idx_hovered == n ? col_hovered : col_base, 2.0f); + } } - ranges.clear(); -} - -void GCodeViewer::InstanceVBuffer::reset() -{ - s_ids.clear(); - s_ids.shrink_to_fit(); - buffer.clear(); - buffer.shrink_to_fit(); - render_ranges.reset(); -} - -void GCodeViewer::IBuffer::reset() -{ - // release gpu memory - if (ibo > 0) { - glsafe(::glDeleteBuffers(1, &ibo)); - ibo = 0; - } - - vbo = 0; - count = 0; -} - -bool GCodeViewer::Path::matches(const GCodeProcessorResult::MoveVertex& move) const -{ - auto matches_percent = [](float value1, float value2, float max_percent) { - return std::abs(value2 - value1) / value1 <= max_percent; - }; - - switch (move.type) - { - case EMoveType::Tool_change: - case EMoveType::Color_change: - case EMoveType::Pause_Print: - case EMoveType::Custom_GCode: - case EMoveType::Retract: - case EMoveType::Unretract: - case EMoveType::Seam: - case EMoveType::Extrude: { - // use rounding to reduce the number of generated paths - return type == move.type && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id && role == move.extrusion_role && - move.position.z() <= sub_paths.front().first.position.z() && feedrate == move.feedrate && fan_speed == move.fan_speed && - height == round_to_bin(move.height) && width == round_to_bin(move.width) && - matches_percent(volumetric_rate, move.volumetric_rate(), 0.05f) && layer_time == move.layer_duration; - } - case EMoveType::Travel: { - return type == move.type && feedrate == move.feedrate && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id; - } - default: { return false; } - } -} - -void GCodeViewer::TBuffer::Model::reset() -{ - instances.reset(); -} - -void GCodeViewer::TBuffer::reset() -{ - vertices.reset(); - for (IBuffer& buffer : indices) { - buffer.reset(); - } - - indices.clear(); - paths.clear(); - render_paths.clear(); - model.reset(); -} - -void GCodeViewer::TBuffer::add_path(const GCodeProcessorResult::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id) -{ - Path::Endpoint endpoint = { b_id, i_id, s_id, move.position }; - // use rounding to reduce the number of generated paths - paths.push_back({ move.type, move.extrusion_role, move.delta_extruder, - round_to_bin(move.height), round_to_bin(move.width), - move.feedrate, move.fan_speed, move.temperature, - move.volumetric_rate(), move.layer_duration, move.extruder_id, move.cp_color_id, { { endpoint, endpoint } } }); -} - -ColorRGBA GCodeViewer::Extrusions::Range::get_color_at(float value) const -{ - // Input value scaled to the colors range - const float step = step_size(); - float _min = min; - if(log_scale) { - value = std::log(value); - _min = std::log(min); - } - const float global_t = (step != 0.0f) ? std::max(0.0f, value - _min) / step : 0.0f; // lower limit of 0.0f - - const size_t color_max_idx = Range_Colors.size() - 1; - - // Compute the two colors just below (low) and above (high) the input value - const size_t color_low_idx = std::clamp(static_cast(global_t), 0, color_max_idx); - const size_t color_high_idx = std::clamp(color_low_idx + 1, 0, color_max_idx); - - // Interpolate between the low and high colors to find exactly which color the input value should get - return lerp(Range_Colors[color_low_idx], Range_Colors[color_high_idx], global_t - static_cast(color_low_idx)); -} - -float GCodeViewer::Extrusions::Range::step_size() const { -if (log_scale) - { - float min_range = min; - if (min_range == 0) - min_range = 0.001f; - return (std::log(max / min_range) / (static_cast(Range_Colors.size()) - 1.0f)); - } else - return (max - min) / (static_cast(Range_Colors.size()) - 1.0f); -} - -float GCodeViewer::Extrusions::Range::get_value_at_step(int step) const { - if (!log_scale) - return min + static_cast(step) * step_size(); - else - return std::exp(std::log(min) + static_cast(step) * step_size()); - -} -GCodeViewer::SequentialRangeCap::~SequentialRangeCap() { - if (ibo > 0) - glsafe(::glDeleteBuffers(1, &ibo)); -} - -void GCodeViewer::SequentialRangeCap::reset() { - if (ibo > 0) - glsafe(::glDeleteBuffers(1, &ibo)); - - buffer = nullptr; - ibo = 0; - vbo = 0; - color = { 0.0f, 0.0f, 0.0f, 1.0f }; + if (label_size.x > 0.0f) + ImGui::RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); + return idx_hovered; } +#endif // ENABLE_ACTUAL_SPEED_DEBUG void GCodeViewer::SequentialView::Marker::init(std::string filename) { @@ -294,18 +208,8 @@ void GCodeViewer::SequentialView::Marker::init(std::string filename) m_model.set_color({ 1.0f, 1.0f, 1.0f, 0.5f }); } -void GCodeViewer::SequentialView::Marker::set_world_position(const Vec3f& position) -{ - m_world_position = position; - m_world_transform = (Geometry::assemble_transform((position + m_z_offset * Vec3f::UnitZ()).cast()) * Geometry::assemble_transform(m_model.get_bounding_box().size().z() * Vec3d::UnitZ(), { M_PI, 0.0, 0.0 })).cast(); -} - -void GCodeViewer::SequentialView::Marker::update_curr_move(const GCodeProcessorResult::MoveVertex move) { - m_curr_move = move; -} - //BBS: GUI refactor: add canvas size from parameters -void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_height, const EViewType& view_type) +void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_height, const libvgcode::EViewType& view_type) { if (!m_visible) return; @@ -322,7 +226,10 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he const Camera& camera = wxGetApp().plater()->get_camera(); const Transform3d& view_matrix = camera.get_view_matrix(); - const Transform3d model_matrix = m_world_transform.cast(); + float scale_factor = m_scale_factor; + const Transform3d model_matrix = (Geometry::translation_transform((m_world_position + m_model_z_offset * Vec3f::UnitZ()).cast()) * + Geometry::translation_transform(scale_factor * m_model.get_bounding_box().size().z() * Vec3d::UnitZ()) * Geometry::rotation_transform({ M_PI, 0.0, 0.0 })) * + Geometry::scale_transform(scale_factor); shader->set_uniform("view_model_matrix", view_matrix * model_matrix); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose(); @@ -333,153 +240,264 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he shader->stop_using(); glsafe(::glDisable(GL_BLEND)); +} - static float last_window_width = 0.0f; - size_t text_line = 0; - static size_t last_text_line = 0; - const ImU32 text_name_clr = m_is_dark ? IM_COL32(255, 255, 255, 0.88 * 255) : IM_COL32(38, 46, 48, 255); - const ImU32 text_value_clr = m_is_dark ? IM_COL32(255, 255, 255, 0.4 * 255) : IM_COL32(144, 144, 144, 255); - - ImGuiWrapper& imgui = *wxGetApp().imgui(); - //BBS: GUI refactor: add canvas size from parameters - imgui.set_next_window_pos(0.5f * static_cast(canvas_width), static_cast(canvas_height), ImGuiCond_Always, 0.5f, 1.0f); - imgui.push_toolbar_style(m_scale); - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0, 4.0 * m_scale)); - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0 * m_scale, 6.0 * m_scale)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, text_name_clr); - ImGui::PushStyleColor(ImGuiCol_Text, text_value_clr); - imgui.begin(std::string("ExtruderPosition"), ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar); - ImGui::AlignTextToFramePadding(); - //BBS: minus the plate offset when show tool position - PartPlateList& partplate_list = wxGetApp().plater()->get_partplate_list(); - PartPlate* plate = partplate_list.get_curr_plate(); - const Vec3f position = m_world_position + m_world_offset; - std::string x = ImGui::ColorMarkerStart + std::string("X: ") + ImGui::ColorMarkerEnd; - std::string y = ImGui::ColorMarkerStart + std::string("Y: ") + ImGui::ColorMarkerEnd; - std::string z = ImGui::ColorMarkerStart + std::string("Z: ") + ImGui::ColorMarkerEnd; - std::string height = ImGui::ColorMarkerStart + _u8L("Height: ") + ImGui::ColorMarkerEnd; - std::string width = ImGui::ColorMarkerStart + _u8L("Width: ") + ImGui::ColorMarkerEnd; - std::string speed = ImGui::ColorMarkerStart + _u8L("Speed: ") + ImGui::ColorMarkerEnd; - std::string flow = ImGui::ColorMarkerStart + _u8L("Flow: ") + ImGui::ColorMarkerEnd; - std::string layer_time = ImGui::ColorMarkerStart + _u8L("Layer Time: ") + ImGui::ColorMarkerEnd; - std::string fanspeed = ImGui::ColorMarkerStart + _u8L("Fan: ") + ImGui::ColorMarkerEnd; - std::string temperature = ImGui::ColorMarkerStart + _u8L("Temperature: ") + ImGui::ColorMarkerEnd; - const float item_size = imgui.calc_text_size(std::string_view{"X: 000.000 "}).x; - const float item_spacing = imgui.get_item_spacing().x; - const float window_padding = ImGui::GetStyle().WindowPadding.x; - - char buf[1024]; - if (true) +static std::string to_string(libvgcode::EMoveType type) +{ + switch (type) { - float startx2 = window_padding + item_size + item_spacing; - float startx3 = window_padding + 2*(item_size + item_spacing); - sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x()); - ImGui::PushItemWidth(item_size); - imgui.text(buf); - - ImGui::SameLine(startx2); - sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y()); - ImGui::PushItemWidth(item_size); - imgui.text(buf); - - ImGui::SameLine(startx3); - sprintf(buf, "%s%.3f", z.c_str(), position.z()); - ImGui::PushItemWidth(item_size); - imgui.text(buf); - - sprintf(buf, "%s%.0f", speed.c_str(), m_curr_move.feedrate); - ImGui::PushItemWidth(item_size); - imgui.text(buf); - - switch (view_type) { - case EViewType::Height: { - ImGui::SameLine(startx2); - sprintf(buf, "%s%.2f", height.c_str(), m_curr_move.height); - ImGui::PushItemWidth(item_size); - imgui.text(buf); - break; - } - case EViewType::Width: { - ImGui::SameLine(startx2); - sprintf(buf, "%s%.2f", width.c_str(), m_curr_move.width); - ImGui::PushItemWidth(item_size); - imgui.text(buf); - break; - } - // case EViewType::Feedrate: { - // ImGui::SameLine(startx2); - // sprintf(buf, "%s%.0f", speed.c_str(), m_curr_move.feedrate); - // ImGui::PushItemWidth(item_size); - // imgui.text(buf); - // break; - // } - case EViewType::VolumetricRate: { - if (m_curr_move.type != EMoveType::Extrude) break; - ImGui::SameLine(startx2); - sprintf(buf, "%s%.2f", flow.c_str(), m_curr_move.volumetric_rate()); - ImGui::PushItemWidth(item_size); - imgui.text(buf); - break; - } - case EViewType::FanSpeed: { - ImGui::SameLine(startx2); - sprintf(buf, "%s%.0f", fanspeed.c_str(), m_curr_move.fan_speed); - ImGui::PushItemWidth(item_size); - imgui.text(buf); - break; - } - case EViewType::Temperature: { - ImGui::SameLine(startx2); - sprintf(buf, "%s%.0f", temperature.c_str(), m_curr_move.temperature); - ImGui::PushItemWidth(item_size); - imgui.text(buf); - break; - } - case EViewType::LayerTime: - case EViewType::LayerTimeLog: { - ImGui::SameLine(startx2); - sprintf(buf, "%s%.1f", layer_time.c_str(), m_curr_move.layer_duration); - ImGui::PushItemWidth(item_size); - imgui.text(buf); - break; - } - default: - break; - } - text_line = 2; + case libvgcode::EMoveType::Noop: { return _u8L("Noop"); } + case libvgcode::EMoveType::Retract: { return _u8L("Retract"); } + case libvgcode::EMoveType::Unretract: { return _u8L("Unretract"); } + case libvgcode::EMoveType::Seam: { return _u8L("Seam"); } + case libvgcode::EMoveType::ToolChange: { return _u8L("Tool Change"); } + case libvgcode::EMoveType::ColorChange: { return _u8L("Color Change"); } + case libvgcode::EMoveType::PausePrint: { return _u8L("Pause Print"); } + case libvgcode::EMoveType::CustomGCode: { return _u8L("Custom GCode"); } + case libvgcode::EMoveType::Travel: { return _u8L("Travel"); } + case libvgcode::EMoveType::Wipe: { return _u8L("Wipe"); } + case libvgcode::EMoveType::Extrude: { return _u8L("Extrude"); } + default: { return _u8L("Unknown"); } } - // else { - // sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x()); - // imgui.text(buf); +} - // ImGui::SameLine(); - // sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y()); - // imgui.text(buf); - - // ImGui::SameLine(); - // sprintf(buf, "%s%.3f", z.c_str(), position.z()); - // imgui.text(buf); - - // text_line = 1; - // } - - // force extra frame to automatically update window size - float window_width = ImGui::GetWindowWidth(); - if (window_width != last_window_width || text_line != last_text_line) { - last_window_width = window_width; - last_text_line = text_line; -#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT - imgui.set_requires_extra_frame(); -#else - wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); - wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); -#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT +static std::string to_string(libvgcode::EGCodeExtrusionRole role) +{ + switch (role) + { + case libvgcode::EGCodeExtrusionRole::None: { return _u8L("Unknown"); } + case libvgcode::EGCodeExtrusionRole::Perimeter: { return _u8L("Perimeter"); } + case libvgcode::EGCodeExtrusionRole::ExternalPerimeter: { return _u8L("External perimeter"); } + case libvgcode::EGCodeExtrusionRole::OverhangPerimeter: { return _u8L("Overhang perimeter"); } + case libvgcode::EGCodeExtrusionRole::InternalInfill: { return _u8L("Internal infill"); } + case libvgcode::EGCodeExtrusionRole::SolidInfill: { return _u8L("Solid infill"); } + case libvgcode::EGCodeExtrusionRole::TopSolidInfill: { return _u8L("Top solid infill"); } + case libvgcode::EGCodeExtrusionRole::Ironing: { return _u8L("Ironing"); } + case libvgcode::EGCodeExtrusionRole::BridgeInfill: { return _u8L("Bridge infill"); } + case libvgcode::EGCodeExtrusionRole::GapFill: { return _u8L("Gap fill"); } + case libvgcode::EGCodeExtrusionRole::Skirt: { return _u8L("Skirt"); } // ORCA + case libvgcode::EGCodeExtrusionRole::SupportMaterial: { return _u8L("Support material"); } + case libvgcode::EGCodeExtrusionRole::SupportMaterialInterface: { return _u8L("Support material interface"); } + case libvgcode::EGCodeExtrusionRole::WipeTower: { return _u8L("Wipe tower"); } + case libvgcode::EGCodeExtrusionRole::Custom: { return _u8L("Custom"); } + // ORCA + case libvgcode::EGCodeExtrusionRole::BottomSurface: { return _u8L("Bottom surface"); } + case libvgcode::EGCodeExtrusionRole::InternalBridgeInfill: { return _u8L("Internal bridge infill"); } + case libvgcode::EGCodeExtrusionRole::Brim: { return _u8L("Brim"); } + case libvgcode::EGCodeExtrusionRole::SupportTransition: { return _u8L("Support transition"); } + case libvgcode::EGCodeExtrusionRole::Mixed: { return _u8L("Mixed"); } + default: { return _u8L("Unknown"); } } +} - imgui.end(); - ImGui::PopStyleVar(2); - ImGui::PopStyleColor(2); - imgui.pop_toolbar_style(); +void GCodeViewer::SequentialView::Marker::render_position_window(const libvgcode::Viewer* viewer, int canvas_width, int canvas_height) +{ + static float last_window_width = 0.0f; + static size_t last_text_length = 0; + static bool properties_shown = false; + + if (viewer != nullptr) { + ImGuiWrapper& imgui = *wxGetApp().imgui(); + // const Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); + imgui.set_next_window_pos(0.5f * static_cast(canvas_width), static_cast(canvas_height), ImGuiCond_Always, 0.5f, 1.0f); + ImGui::PushStyleColor(ImGuiCol_Button, ImGuiWrapper::COL_BUTTON_BACKGROUND); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGuiWrapper::COL_BUTTON_ACTIVE); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGuiWrapper::COL_BUTTON_HOVERED); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::SetNextWindowBgAlpha(0.8f); + imgui.begin(std::string("ToolPosition"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); + ImGui::AlignTextToFramePadding(); + ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORCA, _u8L("Position") + ":"); + ImGui::SameLine(); + libvgcode::PathVertex vertex = viewer->get_current_vertex(); + size_t vertex_id = viewer->get_current_vertex_id(); + if (vertex.type == libvgcode::EMoveType::Seam) { + vertex_id = static_cast(viewer->get_view_visible_range()[1]) - 1; + vertex = viewer->get_vertex_at(vertex_id); + } + + char buf[1024]; + sprintf(buf, "X: %.3f, Y: %.3f, Z: %.3f", vertex.position[0], vertex.position[1], vertex.position[2]); + ImGuiWrapper::text(std::string(buf)); + + ImGui::SameLine(); + if (imgui.image_button(properties_shown ? ImGui::HorizontalHide : ImGui::HorizontalShow, properties_shown ? _u8L("Hide properties") : _u8L("Show properties"))) { + properties_shown = !properties_shown; + } + + if (properties_shown) { + auto append_table_row = [](const std::string& label, std::function value_callback) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORCA, label); + ImGui::TableSetColumnIndex(1); + value_callback(); + }; + + ImGui::Separator(); + if (ImGui::BeginTable("Properties", 2)) { + char buff[1024]; + + append_table_row(_u8L("Type"), [&vertex]() { + ImGuiWrapper::text(_u8L(to_string(vertex.type))); + }); + append_table_row(_u8L("Feature type"), [&vertex]() { + std::string text; + if (vertex.is_extrusion()) + text = _u8L(to_string(vertex.role)); + else + text = _u8L("N/A"); + ImGuiWrapper::text(text); + }); + append_table_row(_u8L("Width") + " (" + _u8L("mm") + ")", [&vertex, &buff]() { + std::string text; + if (vertex.is_extrusion()) { + sprintf(buff, "%.3f", vertex.width); + text = std::string(buff); + } + else + text = _u8L("N/A"); + ImGuiWrapper::text(text); + }); + append_table_row(_u8L("Height") + " (" + _u8L("mm") + ")", [&vertex, &buff]() { + std::string text; + if (vertex.is_extrusion()) { + sprintf(buff, "%.3f", vertex.height); + text = std::string(buff); + } + else + text = _u8L("N/A"); + ImGuiWrapper::text(text); + }); + append_table_row(_u8L("Layer"), [&vertex, &buff]() { + sprintf(buff, "%d", vertex.layer_id + 1); + const std::string text = std::string(buff); + ImGuiWrapper::text(text); + }); + append_table_row(_u8L("Speed") + " (" + _u8L("mm/s") + ")", [&vertex, &buff]() { + sprintf(buff, "%.1f", vertex.feedrate); + const std::string text = std::string(buff); + ImGuiWrapper::text(text); + }); + append_table_row(_u8L("Volumetric flow rate") + " (" + _u8L("mm³/s") + ")", [&vertex, &buff]() { + std::string text; + if (vertex.is_extrusion()) { + sprintf(buff, "%.3f", vertex.volumetric_rate()); + text = std::string(buff); + } + else + text = _u8L("N/A"); + ImGuiWrapper::text(text); + }); + append_table_row(_u8L("Fan speed") + " (" + _u8L("%") + ")", [&vertex, &buff]() { + sprintf(buff, "%.0f", vertex.fan_speed); + const std::string text = std::string(buff); + ImGuiWrapper::text(text); + }); + append_table_row(_u8L("Temperature") + " (" + _u8L("°C") + ")", [&vertex, &buff]() { + sprintf(buff, "%.0f", vertex.temperature); + ImGuiWrapper::text(std::string(buff)); + }); + append_table_row(_u8L("Time"), [viewer, &vertex, &buff, vertex_id]() { + const float estimated_time = viewer->get_estimated_time_at(vertex_id); + sprintf(buff, "%s (%.3fs)", get_time_dhms(estimated_time).c_str(), vertex.times[static_cast(viewer->get_time_mode())]); + const std::string text = std::string(buff); + ImGuiWrapper::text(text); + }); + + ImGui::EndTable(); + } + +#if ENABLE_ACTUAL_SPEED_DEBUG + if (vertex.is_extrusion() || vertex.is_travel() || vertex.is_wipe()) { + ImGui::Spacing(); + ImGuiWrapper::text(_u8L("Actual speed profile")); + ImGui::SameLine(); + static bool table_shown = false; + if (imgui.button(table_shown ? _u8L("Hide table") : _u8L("Show table"))) + table_shown = !table_shown; + ImGui::Separator(); + const int hover_id = m_actual_speed_imgui_widget.plot("##ActualSpeedProfile", { -1.0f, 150.0f }); + if (table_shown) { + static float table_wnd_height = 0.0f; + const ImVec2 wnd_size = ImGui::GetWindowSize(); + imgui.set_next_window_pos(ImGui::GetWindowPos().x + wnd_size.x, static_cast(canvas_height), ImGuiCond_Always, 0.0f, 1.0f); + ImGui::SetNextWindowSizeConstraints({ 0.0f, 0.0f }, { -1.0f, wnd_size.y }); + imgui.begin(std::string("ToolPositionTableWnd"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove); + if (ImGui::BeginTable("ToolPositionTable", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_ScrollY)) { + char buff[1024]; + ImGui::TableSetupScrollFreeze(0, 1); // Make top row always visible + ImGui::TableSetupColumn("Position (mm)"); + ImGui::TableSetupColumn("Speed (mm/s)"); + ImGui::TableHeadersRow(); + int counter = 0; + for (const ActualSpeedImguiWidget::Item& item : m_actual_speed_imgui_widget.data) { + const bool highlight = hover_id >= 0 && (counter == hover_id || counter == hover_id + 1); + if (highlight && counter == hover_id) + ImGui::SetScrollHereY(); + ImGui::TableNextRow(); + const ImU32 row_bg_color = ImGui::GetColorU32(item.internal ? ImVec4(0.0f, 0.0f, 0.5f, 0.25f) : ImVec4(0.5f, 0.5f, 0.5f, 0.25f)); + ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, row_bg_color); + ImGui::TableSetColumnIndex(0); + sprintf(buff, "%.3f", item.pos); + imgui.text_colored(highlight ? ImGuiWrapper::COL_ORCA : ImGuiWrapper::to_ImVec4(ColorRGBA::WHITE()), buff); + ImGui::TableSetColumnIndex(1); + sprintf(buff, "%.1f", item.speed); + imgui.text_colored(highlight ? ImGuiWrapper::COL_ORCA : ImGuiWrapper::to_ImVec4(ColorRGBA::WHITE()), buff); + ++counter; + } + ImGui::EndTable(); + } + const float curr_table_wnd_height = ImGui::GetWindowHeight(); + if (table_wnd_height != curr_table_wnd_height) { + table_wnd_height = curr_table_wnd_height; + // require extra frame to hide the table scroll bar (bug in imgui) + imgui.set_requires_extra_frame(); + } + imgui.end(); + } + } +#endif // ENABLE_ACTUAL_SPEED_DEBUG + } + + // force extra frame to automatically update window size + const float width = ImGui::GetWindowWidth(); + const size_t length = strlen(buf); + if (width != last_window_width || length != last_text_length) { + last_window_width = width; + last_text_length = length; + imgui.set_requires_extra_frame(); + } + + imgui.end(); + ImGui::PopStyleVar(); + } + else { + ImGuiWrapper& imgui = *wxGetApp().imgui(); + const Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); + imgui.set_next_window_pos(0.5f * static_cast(cnv_size.get_width()), static_cast(cnv_size.get_height()), ImGuiCond_Always, 0.5f, 1.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::SetNextWindowBgAlpha(0.8f); + imgui.begin(std::string("ToolPosition"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); + imgui.text_colored(ImGuiWrapper::COL_ORCA, _u8L("Tool position") + ":"); + ImGui::SameLine(); + char buf[1024]; + const Vec3f position = m_world_position + m_world_offset + m_z_offset * Vec3f::UnitZ(); + sprintf(buf, "X: %.3f, Y: %.3f, Z: %.3f", position.x(), position.y(), position.z()); + ImGuiWrapper::text(std::string(buf)); + + // force extra frame to automatically update window size + const float width = ImGui::GetWindowWidth(); + const size_t length = strlen(buf); + if (width != last_window_width || length != last_text_length) { + last_window_width = width; + last_text_length = length; + imgui.set_requires_extra_frame(); + } + imgui.end(); + ImGui::PopStyleVar(); + } } void GCodeViewer::SequentialView::GCodeWindow::load_gcode(const std::string& filename, const std::vector &lines_ends) @@ -508,7 +526,6 @@ void GCodeViewer::SequentialView::GCodeWindow::load_gcode(const std::string& fil //BBS: GUI refactor: move to right void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, float right, uint64_t curr_line_id) const -//void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, uint64_t curr_line_id) const { // Orca: truncate long lines(>55 characters), add "..." at the end auto update_lines = [this](uint64_t start_id, uint64_t end_id) { @@ -595,15 +612,39 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, f // line number's column width const float id_width = ImGui::CalcTextSize(std::to_string(end_id).c_str()).x; + float required_width = 0.0f; + { // --- Compute required G-code window width --- + float max_text_width = id_width; + for (const Line& line : m_lines) { + float w = 0.0f; + + if (!line.command.empty()) + w += ImGui::CalcTextSize(line.command.c_str()).x; + + if (!line.parameters.empty()) + w += ImGui::CalcTextSize(line.parameters.c_str()).x; + + if (!line.comment.empty()) + w += ImGui::CalcTextSize(line.comment.c_str()).x; + + // spacing between segments + w += 3 * ImGui::GetStyle().ItemSpacing.x; + + if (w > max_text_width) + max_text_width = w; + } + + required_width = id_width + max_text_width + 2.0f * ImGui::GetStyle().WindowPadding.x; + } + ImGuiWrapper& imgui = *wxGetApp().imgui(); //BBS: GUI refactor: move to right - //imgui.set_next_window_pos(0.0f, top, ImGuiCond_Always, 0.0f, 0.0f); imgui.set_next_window_pos(right, top + 6 * m_scale, ImGuiCond_Always, 1.0f, 0.0f); // ORCA add a small gap between legend and code viewer - imgui.set_next_window_size(0.0f, wnd_height, ImGuiCond_Always); + ImGui::SetNextWindowSize(ImVec2(required_width, wnd_height), ImGuiCond_Always); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 8.0f * m_scale); // ORCA add window rounding to modernize / match style ImGui::SetNextWindowBgAlpha(0.8f); - imgui.begin(std::string("G-code"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); + imgui.begin(std::string("G-code"), ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); // center the text in the window by pushing down the first line const float f_lines_count = static_cast(lines_count); @@ -677,13 +718,12 @@ void GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file() BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": finished mapping file " << m_filename; } } -void GCodeViewer::SequentialView::render(const bool has_render_path, float legend_height, int canvas_width, int canvas_height, int right_margin, const EViewType& view_type) +void GCodeViewer::SequentialView::render(const bool has_render_path, float legend_height, const libvgcode::Viewer* viewer, uint32_t gcode_id, int canvas_width, int canvas_height, int right_margin, const libvgcode::EViewType& view_type) { if (has_render_path && m_show_marker) { - marker.set_world_position(current_position); - marker.set_world_offset(current_offset); - + // marker.set_world_offset(current_offset); marker.render(canvas_width, canvas_height, view_type); + marker.render_position_window(viewer, canvas_width, canvas_height); } //float bottom = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_height(); @@ -693,73 +733,13 @@ void GCodeViewer::SequentialView::render(const bool has_render_path, float legen bottom -= wxGetApp().plater()->get_view_toolbar().get_height(); #endif if (has_render_path) - gcode_window.render(legend_height + 2, std::max(10.f, (float)canvas_height - 40), (float)canvas_width - (float)right_margin, static_cast(gcode_ids[current.last])); + gcode_window.render(legend_height + 2, std::max(10.f, (float)canvas_height - 40), (float)canvas_width - (float)right_margin, gcode_id); } -const std::vector GCodeViewer::Extrusion_Role_Colors{ { - { 0.90f, 0.70f, 0.70f, 1.0f }, // erNone - { 1.00f, 0.90f, 0.30f, 1.0f }, // erPerimeter - { 1.00f, 0.49f, 0.22f, 1.0f }, // erExternalPerimeter - { 0.12f, 0.12f, 1.00f, 1.0f }, // erOverhangPerimeter - { 0.69f, 0.19f, 0.16f, 1.0f }, // erInternalInfill - { 0.59f, 0.33f, 0.80f, 1.0f }, // erSolidInfill - { 0.94f, 0.25f, 0.25f, 1.0f }, // erTopSolidInfill - { 0.40f, 0.36f, 0.78f, 1.0f }, // erBottomSurface - { 1.00f, 0.55f, 0.41f, 1.0f }, // erIroning - { 0.30f, 0.40f, 0.63f, 1.0f }, // erBridgeInfill - { 0.30f, 0.50f, 0.73f, 1.0f }, // erInternalBridgeInfill - { 1.00f, 1.00f, 1.00f, 1.0f }, // erGapFill - { 0.00f, 0.53f, 0.43f, 1.0f }, // erSkirt - { 0.00f, 0.23f, 0.43f, 1.0f }, // erBrim - { 0.00f, 1.00f, 0.00f, 1.0f }, // erSupportMaterial - { 0.00f, 0.50f, 0.00f, 1.0f }, // erSupportMaterialInterface - { 0.00f, 0.25f, 0.00f, 1.0f }, // erSupportTransition - { 0.70f, 0.89f, 0.67f, 1.0f }, // erWipeTower - { 0.37f, 0.82f, 0.58f, 1.0f } // erCustom -}}; - -const std::vector GCodeViewer::Options_Colors{ { - { 0.803f, 0.135f, 0.839f, 1.0f }, // Retractions - { 0.287f, 0.679f, 0.810f, 1.0f }, // Unretractions - { 0.900f, 0.900f, 0.900f, 1.0f }, // Seams - { 0.758f, 0.744f, 0.389f, 1.0f }, // ToolChanges - { 0.856f, 0.582f, 0.546f, 1.0f }, // ColorChanges - { 0.322f, 0.942f, 0.512f, 1.0f }, // PausePrints - { 0.886f, 0.825f, 0.262f, 1.0f } // CustomGCodes -}}; - -const std::vector GCodeViewer::Travel_Colors{ { - { 0.219f, 0.282f, 0.609f, 1.0f }, // Move - { 0.112f, 0.422f, 0.103f, 1.0f }, // Extrude - { 0.505f, 0.064f, 0.028f, 1.0f } // Retract -}}; - -// Normal ranges -// blue to red -const std::vector GCodeViewer::Range_Colors{ { - decode_color_to_float_array("#0b2c7a"), // bluish - decode_color_to_float_array("#135985"), - decode_color_to_float_array("#1c8891"), - decode_color_to_float_array("#04d60f"), - decode_color_to_float_array("#aaf200"), - decode_color_to_float_array("#fcf903"), - decode_color_to_float_array("#f5ce0a"), - //decode_color_to_float_array("#e38820"), - decode_color_to_float_array("#d16830"), - decode_color_to_float_array("#c2523c"), - decode_color_to_float_array("#942616") // reddish -}}; - -const ColorRGBA GCodeViewer::Wipe_Color = ColorRGBA::YELLOW(); -const ColorRGBA GCodeViewer::Neutral_Color = ColorRGBA::DARK_GRAY(); - GCodeViewer::GCodeViewer() { m_moves_slider = new IMSlider(0, 0, 0, 100, wxSL_HORIZONTAL); m_layers_slider = new IMSlider(0, 0, 0, 100, wxSL_VERTICAL); - m_extrusions.reset_role_visibility_flags(); - -// m_sequential_view.skip_invisible_moves = true; } GCodeViewer::~GCodeViewer() @@ -780,61 +760,6 @@ void GCodeViewer::init(ConfigOptionMode mode, PresetBundle* preset_bundle) if (m_gl_data_initialized) return; - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": enter, m_buffers.size=%1%") - %m_buffers.size(); - // initializes opengl data of TBuffers - for (size_t i = 0; i < m_buffers.size(); ++i) { - TBuffer& buffer = m_buffers[i]; - EMoveType type = buffer_type(i); - switch (type) - { - default: { break; } - case EMoveType::Tool_change: - case EMoveType::Color_change: - case EMoveType::Pause_Print: - case EMoveType::Custom_GCode: - case EMoveType::Retract: - case EMoveType::Unretract: - case EMoveType::Seam: { -// if (wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) { -// buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::InstancedModel; -// buffer.shader = "gouraud_light_instanced"; -// buffer.model.model.init_from(diamond(16)); -// buffer.model.color = option_color(type); -// buffer.model.instances.format = InstanceVBuffer::EFormat::InstancedModel; -// } -// else { - if(type == EMoveType::Seam) - buffer.visible = true; - - buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::BatchedModel; - buffer.vertices.format = VBuffer::EFormat::PositionNormal3; - buffer.shader = "gouraud_light"; - - buffer.model.data = diamond(16); - buffer.model.color = option_color(type); - buffer.model.instances.format = InstanceVBuffer::EFormat::BatchedModel; -// } - break; - } - case EMoveType::Wipe: - case EMoveType::Extrude: { - buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Triangle; - buffer.vertices.format = VBuffer::EFormat::PositionNormal3; - buffer.shader = "gouraud_light"; - break; - } - case EMoveType::Travel: { - buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Line; - buffer.vertices.format = VBuffer::EFormat::Position; - buffer.shader = "flat"; - break; - } - } - - set_toolpath_move_type_visible(EMoveType::Extrude, true); - } - // initializes tool marker std::string filename; if (preset_bundle != nullptr) { @@ -868,13 +793,24 @@ void GCodeViewer::init(ConfigOptionMode mode, PresetBundle* preset_bundle) m_gl_data_initialized = true; + try + { + m_viewer.init(reinterpret_cast(glGetString(GL_VERSION))); + glcheck(); + } + catch (const std::exception& e) + { + MessageDialog msg_dlg(wxGetApp().plater(), e.what(), _L("Error"), wxICON_ERROR | wxOK); + msg_dlg.ShowModal(); + } + // Orca: // Default view type at first slice. // May be overridden in load() once we know how many tools are actually used in the G-code. m_nozzle_nums = preset_bundle ? preset_bundle->get_printer_extruder_count() : 1; - auto it = std::find(view_type_items.begin(), view_type_items.end(), EViewType::FeatureType); + auto it = std::find(view_type_items.begin(), view_type_items.end(), libvgcode::EViewType::FeatureType); m_view_type_sel = (it != view_type_items.end()) ? std::distance(view_type_items.begin(), it) : 0; - set_view_type(EViewType::FeatureType); + set_view_type(libvgcode::EViewType::FeatureType); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": finished"); } @@ -902,17 +838,19 @@ void GCodeViewer::update_by_mode(ConfigOptionMode mode) options_items.clear(); // BBS initialzed view_type items - view_type_items.push_back(EViewType::Summary); - view_type_items.push_back(EViewType::FeatureType); - view_type_items.push_back(EViewType::ColorPrint); - view_type_items.push_back(EViewType::Feedrate); - view_type_items.push_back(EViewType::Height); - view_type_items.push_back(EViewType::Width); - view_type_items.push_back(EViewType::VolumetricRate); - view_type_items.push_back(EViewType::LayerTime); -view_type_items.push_back(EViewType::LayerTimeLog); - view_type_items.push_back(EViewType::FanSpeed); - view_type_items.push_back(EViewType::Temperature); + view_type_items.push_back(libvgcode::EViewType::Summary); + view_type_items.push_back(libvgcode::EViewType::FeatureType); + view_type_items.push_back(libvgcode::EViewType::ColorPrint); + view_type_items.push_back(libvgcode::EViewType::Speed); + view_type_items.push_back(libvgcode::EViewType::ActualSpeed); + view_type_items.push_back(libvgcode::EViewType::Height); + view_type_items.push_back(libvgcode::EViewType::Width); + view_type_items.push_back(libvgcode::EViewType::VolumetricFlowRate); + view_type_items.push_back(libvgcode::EViewType::ActualVolumetricFlowRate); + view_type_items.push_back(libvgcode::EViewType::LayerTimeLinear); + view_type_items.push_back(libvgcode::EViewType::LayerTimeLogarithmic); + view_type_items.push_back(libvgcode::EViewType::FanSpeed); + view_type_items.push_back(libvgcode::EViewType::Temperature); //if (mode == ConfigOptionMode::comDevelop) { // view_type_items.push_back(EViewType::Tool); //} @@ -922,7 +860,7 @@ view_type_items.push_back(EViewType::LayerTimeLog); } // BBS for first layer inspection - view_type_items.push_back(EViewType::FilamentId); + view_type_items.push_back(libvgcode::EViewType::Tool); options_items.push_back(EMoveType::Travel); options_items.push_back(EMoveType::Retract); @@ -941,13 +879,38 @@ std::vector GCodeViewer::get_plater_extruder() } //BBS: always load shell at preview -void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& print, const BuildVolume& build_volume, +void GCodeViewer::load_as_gcode(const GCodeProcessorResult& gcode_result, const Print& print, const std::vector& str_tool_colors, + const std::vector& str_color_print_colors, const BuildVolume& build_volume, const std::vector& exclude_bounding_box, ConfigOptionMode mode, bool only_gcode) { + m_loaded_as_preview = false; + + const bool current_top_layer_only = m_viewer.is_top_layer_only_view_range(); + const bool required_top_layer_only = get_app_config()->get_bool("seq_top_layer_only"); + if (current_top_layer_only != required_top_layer_only) + m_viewer.toggle_top_layer_only_view_range(); + // avoid processing if called with the same gcode_result - if (m_last_result_id == gcode_result.id) { + if (m_last_result_id == gcode_result.id && wxGetApp().is_editor()) { //BBS: add logs BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": the same id %1%, return directly, result %2% ") % m_last_result_id % (&gcode_result); + + // collect tool colors + libvgcode::Palette tools_colors; + tools_colors.reserve(str_tool_colors.size()); + for (const std::string& color : str_tool_colors) { + tools_colors.emplace_back(libvgcode::convert(color)); + } + m_viewer.set_tool_colors(tools_colors); + + // collect color print colors + libvgcode::Palette color_print_colors; + const std::vector& str_colors = str_color_print_colors.empty() ? str_tool_colors : str_color_print_colors; + color_print_colors.reserve(str_colors.size()); + for (const std::string& color : str_colors) { + color_print_colors.emplace_back(libvgcode::convert(color)); + } + m_viewer.set_color_print_colors(color_print_colors); return; } @@ -969,6 +932,142 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr return; } + // convert data from PrusaSlicer format to libvgcode format + libvgcode::GCodeInputData data = libvgcode::convert(gcode_result, str_tool_colors, str_color_print_colors, m_viewer); + +//#define ENABLE_DATA_EXPORT 1 +//#if ENABLE_DATA_EXPORT +// auto extrusion_role_to_string = [](libvgcode::EGCodeExtrusionRole role) { +// switch (role) { +// case libvgcode::EGCodeExtrusionRole::None: { return "EGCodeExtrusionRole::None"; } +// case libvgcode::EGCodeExtrusionRole::Perimeter: { return "EGCodeExtrusionRole::Perimeter"; } +// case libvgcode::EGCodeExtrusionRole::ExternalPerimeter: { return "EGCodeExtrusionRole::ExternalPerimeter"; } +// case libvgcode::EGCodeExtrusionRole::OverhangPerimeter: { return "EGCodeExtrusionRole::OverhangPerimeter"; } +// case libvgcode::EGCodeExtrusionRole::InternalInfill: { return "EGCodeExtrusionRole::InternalInfill"; } +// case libvgcode::EGCodeExtrusionRole::SolidInfill: { return "EGCodeExtrusionRole::SolidInfill"; } +// case libvgcode::EGCodeExtrusionRole::TopSolidInfill: { return "EGCodeExtrusionRole::TopSolidInfill"; } +// case libvgcode::EGCodeExtrusionRole::Ironing: { return "EGCodeExtrusionRole::Ironing"; } +// case libvgcode::EGCodeExtrusionRole::BridgeInfill: { return "EGCodeExtrusionRole::BridgeInfill"; } +// case libvgcode::EGCodeExtrusionRole::GapFill: { return "EGCodeExtrusionRole::GapFill"; } +// case libvgcode::EGCodeExtrusionRole::Skirt: { return "EGCodeExtrusionRole::Skirt"; } +// case libvgcode::EGCodeExtrusionRole::SupportMaterial: { return "EGCodeExtrusionRole::SupportMaterial"; } +// case libvgcode::EGCodeExtrusionRole::SupportMaterialInterface: { return "EGCodeExtrusionRole::SupportMaterialInterface"; } +// case libvgcode::EGCodeExtrusionRole::WipeTower: { return "EGCodeExtrusionRole::WipeTower"; } +// case libvgcode::EGCodeExtrusionRole::Custom: { return "EGCodeExtrusionRole::Custom"; } +// case libvgcode::EGCodeExtrusionRole::COUNT: { return "EGCodeExtrusionRole::COUNT"; } +// } +// }; +// +// auto move_type_to_string = [](libvgcode::EMoveType type) { +// switch (type) { +// case libvgcode::EMoveType::Noop: { return "EMoveType::Noop"; } +// case libvgcode::EMoveType::Retract: { return "EMoveType::Retract"; } +// case libvgcode::EMoveType::Unretract: { return "EMoveType::Unretract"; } +// case libvgcode::EMoveType::Seam: { return "EMoveType::Seam"; } +// case libvgcode::EMoveType::ToolChange: { return "EMoveType::ToolChange"; } +// case libvgcode::EMoveType::ColorChange: { return "EMoveType::ColorChange"; } +// case libvgcode::EMoveType::PausePrint: { return "EMoveType::PausePrint"; } +// case libvgcode::EMoveType::CustomGCode: { return "EMoveType::CustomGCode"; } +// case libvgcode::EMoveType::Travel: { return "EMoveType::Travel"; } +// case libvgcode::EMoveType::Wipe: { return "EMoveType::Wipe"; } +// case libvgcode::EMoveType::Extrude: { return "EMoveType::Extrude"; } +// case libvgcode::EMoveType::COUNT: { return "EMoveType::COUNT"; } +// } +// }; +// +// FilePtr out{ boost::nowide::fopen("C:/prusa/slicer/test_output/spe1872/test.data", "wb") }; +// if (out.f != nullptr) { +// const uint32_t vertices_count = static_cast(data.vertices.size()); +// fwrite((void*)&vertices_count, 1, sizeof(uint32_t), out.f); +// for (const libvgcode::PathVertex& v : data.vertices) { +// fwrite((void*)&v.position[0], 1, sizeof(float), out.f); +// fwrite((void*)&v.position[1], 1, sizeof(float), out.f); +// fwrite((void*)&v.position[2], 1, sizeof(float), out.f); +// fwrite((void*)&v.height, 1, sizeof(float), out.f); +// fwrite((void*)&v.width, 1, sizeof(float), out.f); +// fwrite((void*)&v.feedrate, 1, sizeof(float), out.f); +// fwrite((void*)&v.actual_feedrate, 1, sizeof(float), out.f); +// fwrite((void*)&v.mm3_per_mm, 1, sizeof(float), out.f); +// fwrite((void*)&v.fan_speed, 1, sizeof(float), out.f); +// fwrite((void*)&v.temperature, 1, sizeof(float), out.f); +// fwrite((void*)&v.role, 1, sizeof(uint8_t), out.f); +// fwrite((void*)&v.type, 1, sizeof(uint8_t), out.f); +// fwrite((void*)&v.gcode_id, 1, sizeof(uint32_t), out.f); +// fwrite((void*)&v.layer_id, 1, sizeof(uint32_t), out.f); +// fwrite((void*)&v.extruder_id, 1, sizeof(uint32_t), out.f); +// fwrite((void*)&v.color_id, 1, sizeof(uint32_t), out.f); +// fwrite((void*)&v.times[0], 1, sizeof(float), out.f); +// fwrite((void*)&v.times[1], 1, sizeof(float), out.f); +//#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS +// const float weight = v.weight; +//#else +// const float weight = 0.0f; +//#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS +// fwrite((void*)&weight, 1, sizeof(float), out.f); +// } +// +// const uint8_t spiral_vase_mode = data.spiral_vase_mode ? 1 : 0; +// fwrite((void*)&spiral_vase_mode, 1, sizeof(uint8_t), out.f); +// +// const uint32_t tool_colors_count = static_cast(data.tools_colors.size()); +// fwrite((void*)&tool_colors_count, 1, sizeof(uint32_t), out.f); +// for (const libvgcode::Color& c : data.tools_colors) { +// fwrite((void*)&c[0], 1, sizeof(uint8_t), out.f); +// fwrite((void*)&c[1], 1, sizeof(uint8_t), out.f); +// fwrite((void*)&c[2], 1, sizeof(uint8_t), out.f); +// } +// +// const uint32_t color_print_colors_count = static_cast(data.color_print_colors.size()); +// fwrite((void*)&color_print_colors_count, 1, sizeof(uint32_t), out.f); +// for (const libvgcode::Color& c : data.color_print_colors) { +// fwrite((void*)&c[0], 1, sizeof(uint8_t), out.f); +// fwrite((void*)&c[1], 1, sizeof(uint8_t), out.f); +// fwrite((void*)&c[2], 1, sizeof(uint8_t), out.f); +// } +// } +//#endif // ENABLE_DATA_EXPORT + + // send data to the viewer + m_viewer.reset_default_extrusion_roles_colors(); + m_viewer.load(std::move(data)); + +// #if !VGCODE_ENABLE_COG_AND_TOOL_MARKERS +// const size_t vertices_count = m_viewer.get_vertices_count(); +// m_cog.reset(); +// for (size_t i = 1; i < vertices_count; ++i) { +// const libvgcode::PathVertex& curr = m_viewer.get_vertex_at(i); +// if (curr.type == libvgcode::EMoveType::Extrude && +// curr.role != libvgcode::EGCodeExtrusionRole::Skirt && +// curr.role != libvgcode::EGCodeExtrusionRole::SupportMaterial && +// curr.role != libvgcode::EGCodeExtrusionRole::SupportMaterialInterface && +// curr.role != libvgcode::EGCodeExtrusionRole::WipeTower && +// curr.role != libvgcode::EGCodeExtrusionRole::Custom) { +// const Vec3d curr_pos = libvgcode::convert(curr.position).cast(); +// const Vec3d prev_pos = libvgcode::convert(m_viewer.get_vertex_at(i - 1).position).cast(); +// m_cog.add_segment(curr_pos, prev_pos, gcode_result.filament_densities[curr.extruder_id] * curr.mm3_per_mm * (curr_pos - prev_pos).norm()); +// } +// } +// #endif // !VGCODE_ENABLE_COG_AND_TOOL_MARKERS + + const libvgcode::AABox bbox = wxGetApp().is_gcode_viewer() ? + m_viewer.get_bounding_box() : + m_viewer.get_extrusion_bounding_box({ + libvgcode::EGCodeExtrusionRole::Perimeter, libvgcode::EGCodeExtrusionRole::ExternalPerimeter, libvgcode::EGCodeExtrusionRole::OverhangPerimeter, + libvgcode::EGCodeExtrusionRole::InternalInfill, libvgcode::EGCodeExtrusionRole::SolidInfill, libvgcode::EGCodeExtrusionRole::TopSolidInfill, + libvgcode::EGCodeExtrusionRole::Ironing, libvgcode::EGCodeExtrusionRole::BridgeInfill, libvgcode::EGCodeExtrusionRole::GapFill, + libvgcode::EGCodeExtrusionRole::Skirt, libvgcode::EGCodeExtrusionRole::SupportMaterial, libvgcode::EGCodeExtrusionRole::SupportMaterialInterface, + libvgcode::EGCodeExtrusionRole::WipeTower, + // ORCA + libvgcode::EGCodeExtrusionRole::BottomSurface, libvgcode::EGCodeExtrusionRole::InternalBridgeInfill, libvgcode::EGCodeExtrusionRole::Brim, + libvgcode::EGCodeExtrusionRole::SupportTransition, libvgcode::EGCodeExtrusionRole::Mixed + }); + m_paths_bounding_box = BoundingBoxf3(libvgcode::convert(bbox[0]).cast(), libvgcode::convert(bbox[1]).cast()); + + if (wxGetApp().is_editor()) + m_contained_in_bed = wxGetApp().plater()->build_volume().all_paths_inside(gcode_result, m_paths_bounding_box); + + m_extruders_count = gcode_result.filaments_count; + //BBS: move the id to the end of reset m_last_result_id = gcode_result.id; m_gcode_result = &gcode_result; @@ -982,21 +1081,22 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr m_custom_gcode_per_print_z = gcode_result.custom_gcode_per_print_z; m_max_print_height = gcode_result.printable_height; + m_z_offset = gcode_result.z_offset; - load_toolpaths(gcode_result, build_volume, exclude_bounding_box); + // load_toolpaths(gcode_result, build_volume, exclude_bounding_box); // ORCA: Only show filament/color print preview if more than one tool/extruder is actually used in the toolpaths. // Only reset back to Toolpaths (FeatureType) if we are currently in ColorPrint and this load is single-tool. - if (m_extruder_ids.size() > 1) { - auto it = std::find(view_type_items.begin(), view_type_items.end(), EViewType::ColorPrint); + if (m_viewer.get_used_extruders_count() > 1) { + auto it = std::find(view_type_items.begin(), view_type_items.end(), libvgcode::EViewType::ColorPrint); if (it != view_type_items.end()) m_view_type_sel = std::distance(view_type_items.begin(), it); - set_view_type(EViewType::ColorPrint); - } else if (m_view_type == EViewType::ColorPrint) { - auto it = std::find(view_type_items.begin(), view_type_items.end(), EViewType::FeatureType); + set_view_type(libvgcode::EViewType::ColorPrint); + } else if (get_view_type() == libvgcode::EViewType::ColorPrint) { + auto it = std::find(view_type_items.begin(), view_type_items.end(), libvgcode::EViewType::FeatureType); if (it != view_type_items.end()) m_view_type_sel = std::distance(view_type_items.begin(), it); - set_view_type(EViewType::FeatureType); + set_view_type(libvgcode::EViewType::FeatureType); } // BBS: data for rendering color arrangement recommendation @@ -1007,19 +1107,13 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr std::vector color_opt = print.config().option("filament_colour")->values; std::vector type_opt = print.config().option("filament_type")->values; std::vector support_filament_opt = print.config().option("filament_is_support")->values; - for (auto extruder_id : m_extruder_ids) { + for (auto extruder_id : m_viewer.get_used_extruders_ids()) { if (filament_maps[extruder_id] == 1) { m_left_extruder_filament.push_back({type_opt[extruder_id], color_opt[extruder_id], extruder_id, (bool)(support_filament_opt[extruder_id])}); } else { m_right_extruder_filament.push_back({type_opt[extruder_id], color_opt[extruder_id], extruder_id, (bool)(support_filament_opt[extruder_id])}); } } - //BBS: add mutex for protection of gcode result - if (m_layers.empty()) { - gcode_result.unlock(); - wxGetApp().plater()->schedule_background_process(); - return; - } m_settings_ids = gcode_result.settings_ids; m_filament_diameters = gcode_result.filament_diameters; @@ -1094,13 +1188,25 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr m_print_statistics = gcode_result.print_statistics; - if (m_time_estimate_mode != PrintEstimatedStatistics::ETimeMode::Normal) { - const float time = m_print_statistics.modes[static_cast(m_time_estimate_mode)].time; + PrintEstimatedStatistics::ETimeMode time_mode = convert(m_viewer.get_time_mode()); + if (m_viewer.get_time_mode() != libvgcode::ETimeMode::Normal) { + const float time = m_print_statistics.modes[static_cast(time_mode)].time; if (time == 0.0f || short_time(get_time_dhms(time)) == short_time(get_time_dhms(m_print_statistics.modes[static_cast(PrintEstimatedStatistics::ETimeMode::Normal)].time))) - m_time_estimate_mode = PrintEstimatedStatistics::ETimeMode::Normal; + m_viewer.set_time_mode(libvgcode::convert(PrintEstimatedStatistics::ETimeMode::Normal)); } + // set to color print by default if use multi extruders + if (m_viewer.get_used_extruders_count() > 1) { + for (int i = 0; i < view_type_items.size(); i++) { + if (view_type_items[i] == libvgcode::EViewType::ColorPrint) { + m_view_type_sel = i; + break; + } + } + + set_view_type(libvgcode::EViewType::ColorPrint); + } bool only_gcode_3mf = false; PartPlate* current_plate = wxGetApp().plater()->get_partplate_list().get_curr_plate(); @@ -1113,7 +1219,7 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr //BBS m_conflict_result = gcode_result.conflict_result; - if (m_conflict_result) { m_conflict_result.value().layer = m_layers.get_l_at(m_conflict_result.value()._height); } + if (m_conflict_result) { m_conflict_result.value().layer = m_viewer.get_layer_id_at(static_cast(m_conflict_result.value()._height)); } m_gcode_check_result = gcode_result.gcode_check_result; @@ -1121,118 +1227,24 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr //BBS: add mutex for protection of gcode result gcode_result.unlock(); wxGetApp().plater()->schedule_background_process(); - //BBS: add logs - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": finished, m_buffers size %1%!")%m_buffers.size(); } -void GCodeViewer::refresh(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors) +void GCodeViewer::load_as_preview(libvgcode::GCodeInputData&& data) { -#if ENABLE_GCODE_VIEWER_STATISTICS - auto start_time = std::chrono::high_resolution_clock::now(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS + m_loaded_as_preview = true; - //BBS: add mutex for protection of gcode result - gcode_result.lock(); + m_viewer.set_extrusion_role_color(libvgcode::EGCodeExtrusionRole::Skirt, { 127, 255, 127 }); + m_viewer.set_extrusion_role_color(libvgcode::EGCodeExtrusionRole::ExternalPerimeter, { 255, 255, 0 }); + m_viewer.set_extrusion_role_color(libvgcode::EGCodeExtrusionRole::SupportMaterial, { 127, 255, 127 }); + m_viewer.set_extrusion_role_color(libvgcode::EGCodeExtrusionRole::SupportMaterialInterface, { 127, 255, 127 }); + m_viewer.set_extrusion_role_color(libvgcode::EGCodeExtrusionRole::InternalInfill, { 255, 127, 127 }); + m_viewer.set_extrusion_role_color(libvgcode::EGCodeExtrusionRole::SolidInfill, { 255, 127, 127 }); + m_viewer.set_extrusion_role_color(libvgcode::EGCodeExtrusionRole::WipeTower, { 127, 255, 127 }); + m_viewer.load(std::move(data)); - //BBS: add safe check - if (gcode_result.moves.size() == 0) { - //result cleaned before slicing ,should return here - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": gcode result reset before, return directly!"); - gcode_result.unlock(); - return; - } - - //BBS: add mutex for protection of gcode result - if (m_moves_count == 0) { - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": gcode result m_moves_count is 0, return directly!"); - gcode_result.unlock(); - return; - } - - wxBusyCursor busy; - - if (m_view_type == EViewType::Tool && !gcode_result.extruder_colors.empty()) { - // update tool colors from config stored in the gcode - decode_colors(gcode_result.extruder_colors, m_tools.m_tool_colors); - m_tools.m_tool_visibles = std::vector(m_tools.m_tool_colors.size()); - for (auto item: m_tools.m_tool_visibles) item = true; - } - else { - // update tool colors - decode_colors(str_tool_colors, m_tools.m_tool_colors); - m_tools.m_tool_visibles = std::vector(m_tools.m_tool_colors.size()); - for (auto item : m_tools.m_tool_visibles) item = true; - } - - for (int i = 0; i < m_tools.m_tool_colors.size(); i++) { - m_tools.m_tool_colors[i] = adjust_color_for_rendering(m_tools.m_tool_colors[i]); - } - ColorRGBA default_color; - decode_color("#FF8000", default_color); - // ensure there are enough colors defined - while (m_tools.m_tool_colors.size() < std::max(size_t(1), gcode_result.filaments_count)) { - m_tools.m_tool_colors.push_back(default_color); - m_tools.m_tool_visibles.push_back(true); - } - - // update ranges for coloring / legend - m_extrusions.reset_ranges(); - for (size_t i = 0; i < m_moves_count; ++i) { - // skip first vertex - if (i == 0) - continue; - - const GCodeProcessorResult::MoveVertex& curr = gcode_result.moves[i]; - - switch (curr.type) - { - case EMoveType::Extrude: - { - if (curr.extrusion_role != ExtrusionRole::erCustom) { - m_extrusions.ranges.height.update_from(round_to_bin(curr.height)); - m_extrusions.ranges.width.update_from(round_to_bin(curr.width)); - } // prevent the start code extrude extreme height/width and make the range deviate from the normal range - m_extrusions.ranges.fan_speed.update_from(curr.fan_speed); - m_extrusions.ranges.temperature.update_from(curr.temperature); - if (curr.delta_extruder > 0.005 && curr.travel_dist > 0.01) { - // Ignore very tiny extrusions from flow rate calculation, because - // it could give very imprecise result due to rounding in gcode generation - if (curr.extrusion_role != erCustom || is_visible(erCustom)) - m_extrusions.ranges.volumetric_rate.update_from(round_to_bin(curr.volumetric_rate())); - } - - if (curr.layer_duration > 0.f) { - m_extrusions.ranges.layer_duration.update_from(curr.layer_duration); -m_extrusions.ranges.layer_duration_log.update_from(curr.layer_duration); - } - [[fallthrough]]; - } - case EMoveType::Travel: - { - if (m_buffers[buffer_id(curr.type)].visible) - m_extrusions.ranges.feedrate.update_from(curr.feedrate); - - break; - } - default: { break; } - } - } - -#if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.refresh_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - //BBS: add mutex for protection of gcode result - gcode_result.unlock(); - - // update buffers' render paths - refresh_render_paths(); - log_memory_used("Refreshed G-code extrusion paths, "); -} - -void GCodeViewer::refresh_render_paths() -{ - refresh_render_paths(false, false); + const libvgcode::AABox bbox = m_viewer.get_extrusion_bounding_box(); + const BoundingBoxf3 paths_bounding_box(libvgcode::convert(bbox[0]).cast(), libvgcode::convert(bbox[1]).cast()); + m_contained_in_bed = wxGetApp().plater()->build_volume().all_paths_inside(GCodeProcessorResult(), paths_bounding_box); } void GCodeViewer::update_shells_color_by_extruder(const DynamicPrintConfig *config) @@ -1259,53 +1271,34 @@ void GCodeViewer::reset() //BBS: add only gcode mode m_only_gcode_in_preview = false; - m_moves_count = 0; - m_ssid_to_moveid_map.clear(); - m_ssid_to_moveid_map.shrink_to_fit(); - for (TBuffer& buffer : m_buffers) { - buffer.reset(); - } + m_viewer.reset(); + m_paths_bounding_box = BoundingBoxf3(); m_max_bounding_box = BoundingBoxf3(); m_max_print_height = 0.0f; - m_tools.m_tool_colors = std::vector(); - m_tools.m_tool_visibles = std::vector(); + m_z_offset = 0.0f; m_extruders_count = 0; - m_extruder_ids = std::vector(); m_filament_diameters = std::vector(); m_filament_densities = std::vector(); - m_extrusions.reset_ranges(); - //BBS: always load shell at preview - //m_shells.volumes.clear(); - m_layers.reset(); - m_layers_z_range = { 0, 0 }; - m_roles = std::vector(); m_print_statistics.reset(); m_custom_gcode_per_print_z = std::vector(); - m_sequential_view.gcode_window.reset(); m_left_extruder_filament.clear(); m_right_extruder_filament.clear(); -#if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.reset_all(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS + m_sequential_view.gcode_window.reset(); m_contained_in_bed = true; } //BBS: GUI refactor: add canvas width and height void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin) { -#if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.reset_opengl(); - m_statistics.total_instances_gpu_size = 0; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - glsafe(::glEnable(GL_DEPTH_TEST)); render_shells(canvas_width, canvas_height); - if (m_roles.empty()) + if (m_viewer.get_extrusion_roles().empty()) return; render_toolpaths(); + float legend_height = 0.0f; render_legend(legend_height, canvas_width, canvas_height, right_margin); @@ -1316,12 +1309,49 @@ void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin) //BBS fixed bottom_margin for space to render horiz slider int bottom_margin = SLIDER_BOTTOM_MARGIN * GCODE_VIEWER_SLIDER_SCALE; - m_sequential_view.m_show_marker = m_sequential_view.m_show_marker || (m_sequential_view.current.last != m_sequential_view.endpoints.last && !m_no_render_path); + auto current = m_viewer.get_view_visible_range(); + auto endpoints = m_viewer.get_view_full_range(); + m_sequential_view.m_show_marker = m_sequential_view.m_show_marker || (current.back() != endpoints.back() && !m_no_render_path); + const libvgcode::PathVertex& curr_vertex = m_viewer.get_current_vertex(); + m_sequential_view.marker.set_world_position(libvgcode::convert(curr_vertex.position)); + m_sequential_view.marker.set_z_offset(m_z_offset + 0.5f); // BBS fixed buttom margin. m_moves_slider.pos_y - m_sequential_view.render(!m_no_render_path, legend_height, canvas_width, canvas_height - bottom_margin * m_scale, right_margin * m_scale, m_view_type); -#if ENABLE_GCODE_VIEWER_STATISTICS - render_statistics(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS + m_sequential_view.render(!m_no_render_path, legend_height, &m_viewer, m_viewer.get_current_vertex().gcode_id, canvas_width, canvas_height - bottom_margin * m_scale, right_margin * m_scale, m_viewer.get_view_type()); + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + if (is_legend_shown()) { + ImGuiWrapper& imgui = *Slic3r::GUI::wxGetApp().imgui(); + const Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); + ImGuiPureWrap::set_next_window_pos(static_cast(cnv_size.get_width()), static_cast(cnv_size.get_height()), ImGuiCond_Always, 1.0f, 1.0f); + ImGuiPureWrap::begin(std::string("LibVGCode Viewer Controller"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize); + + ImGuiPureWrap::checkbox("Cog marker fixed screen size", m_cog_marker_fixed_screen_size); + if (ImGui::BeginTable("Cog", 2)) { + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiPureWrap::text_colored(ImGuiPureWrap::COL_ORANGE_LIGHT, "Cog marker size"); + ImGui::TableSetColumnIndex(1); + imgui.slider_float("##CogSize", &m_cog_marker_size, 1.0f, 5.0f); + + ImGui::EndTable(); + } + + ImGuiPureWrap::checkbox("Tool marker fixed screen size", m_tool_marker_fixed_screen_size); + if (ImGui::BeginTable("Tool", 2)) { + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiPureWrap::text_colored(ImGuiPureWrap::COL_ORANGE_LIGHT, "Tool marker size"); + ImGui::TableSetColumnIndex(1); + imgui.slider_float("##ToolSize", &m_tool_marker_size, 1.0f, 5.0f); + + ImGui::EndTable(); + } + + ImGuiPureWrap::end(); + } +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS //BBS render slider render_slider(canvas_width, canvas_height); @@ -1350,415 +1380,73 @@ static void debug_calibration_output_thumbnail(const ThumbnailData& thumbnail_da } #endif -void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager) -{ - int plate_idx = thumbnail_params.plate_id; - PartPlate* plate = partplate_list.get_plate(plate_idx); - BoundingBoxf3 plate_box = plate->get_bounding_box(false); - plate_box.min.z() = 0.0; - plate_box.max.z() = 0.0; - Vec3d center = plate_box.center(); - -#if 1 - Camera camera; - camera.set_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); - camera.apply_viewport(); - camera.set_scene_box(plate_box); - camera.set_type(Camera::EType::Ortho); - camera.set_target(center); - camera.select_view("top"); - camera.zoom_to_box(plate_box, 1.0f); - camera.apply_projection(plate_box); - - auto render_as_triangles = [ -#if ENABLE_GCODE_VIEWER_STATISTICS - this -#endif // ENABLE_GCODE_VIEWER_STATISTICS - ](TBuffer &buffer, std::vector::iterator it_path, std::vector::iterator it_end, GLShaderProgram& shader, int uniform_color) { - for (auto it = it_path; it != it_end && it_path->ibuffer_id == it->ibuffer_id; ++it) { - const RenderPath& path = *it; - // Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415. - assert(!path.sizes.empty()); - assert(!path.offsets.empty()); - shader.set_uniform(uniform_color, path.color); - glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_triangles_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - }; - - auto render_as_instanced_model = [ -#if ENABLE_GCODE_VIEWER_STATISTICS - this -#endif // ENABLE_GCODE_VIEWER_STATISTICS - ](TBuffer& buffer, GLShaderProgram& shader) { - for (auto& range : buffer.model.instances.render_ranges.ranges) { - if (range.vbo == 0 && range.count > 0) { - glsafe(::glGenBuffers(1, &range.vbo)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, range.vbo)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, range.count * buffer.model.instances.instance_size_bytes(), (const void*)&buffer.model.instances.buffer[range.offset * buffer.model.instances.instance_size_floats()], GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - } - - if (range.vbo > 0) { - buffer.model.model.set_color(range.color); - buffer.model.model.render_instanced(range.vbo, range.count); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_instanced_models_calls_count; - m_statistics.total_instances_gpu_size += static_cast(range.count * buffer.model.instances.instance_size_bytes()); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - } - }; - -#if ENABLE_GCODE_VIEWER_STATISTICS - auto render_as_batched_model = [this](TBuffer& buffer, GLShaderProgram& shader) { -#else - auto render_as_batched_model = [](TBuffer& buffer, GLShaderProgram& shader, int position_id, int normal_id) { -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - struct Range - { - unsigned int first; - unsigned int last; - bool intersects(const Range& other) const { return (other.last < first || other.first > last) ? false : true; } - }; - Range buffer_range = { 0, 0 }; - size_t indices_per_instance = buffer.model.data.indices_count(); - - for (size_t j = 0; j < buffer.indices.size(); ++j) { - const IBuffer& i_buffer = buffer.indices[j]; - buffer_range.last = buffer_range.first + i_buffer.count / indices_per_instance; - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); - if (position_id != -1) { - glsafe(::glVertexAttribPointer(position_id, buffer.vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes())); - glsafe(::glEnableVertexAttribArray(position_id)); - } - bool has_normals = buffer.vertices.normal_size_floats() > 0; - if (has_normals) { - if (normal_id != -1) { - glsafe(::glVertexAttribPointer(normal_id, buffer.vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); - glsafe(::glEnableVertexAttribArray(normal_id)); - } - } - - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); - - for (auto& range : buffer.model.instances.render_ranges.ranges) { - Range range_range = { range.offset, range.offset + range.count }; - if (range_range.intersects(buffer_range)) { - shader.set_uniform("uniform_color", range.color); - unsigned int offset = (range_range.first > buffer_range.first) ? range_range.first - buffer_range.first : 0; - size_t offset_bytes = static_cast(offset) * indices_per_instance * sizeof(IBufferType); - Range render_range = { std::max(range_range.first, buffer_range.first), std::min(range_range.last, buffer_range.last) }; - size_t count = static_cast(render_range.last - render_range.first) * indices_per_instance; - if (count > 0) { - glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)count, GL_UNSIGNED_SHORT, (const void*)offset_bytes)); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_batched_models_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - } - } - - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - - if (normal_id != -1) - glsafe(::glDisableVertexAttribArray(normal_id)); - if (position_id != -1) - glsafe(::glDisableVertexAttribArray(position_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - - buffer_range.first = buffer_range.last; - } - }; - - unsigned char begin_id = buffer_id(EMoveType::Retract); - unsigned char end_id = buffer_id(EMoveType::Count); - - BOOST_LOG_TRIVIAL(info) << boost::format("render_calibration_thumbnail: begin_id %1%, end_id %2%")%begin_id %end_id; - for (unsigned char i = begin_id; i < end_id; ++i) { - TBuffer& buffer = m_buffers[i]; - if (!buffer.visible || !buffer.has_data()) - continue; - - GLShaderProgram* shader = opengl_manager.get_shader("flat"); - if (shader != nullptr) { - shader->start_using(); - - shader->set_uniform("view_model_matrix", camera.get_view_matrix()); - shader->set_uniform("projection_matrix", camera.get_projection_matrix()); - int position_id = shader->get_attrib_location("v_position"); - int normal_id = shader->get_attrib_location("v_normal"); - - if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel) { - //shader->set_uniform("emission_factor", 0.25f); - render_as_instanced_model(buffer, *shader); - //shader->set_uniform("emission_factor", 0.0f); - } - else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) { - //shader->set_uniform("emission_factor", 0.25f); - render_as_batched_model(buffer, *shader, position_id, normal_id); - //shader->set_uniform("emission_factor", 0.0f); - } - else { - int uniform_color = shader->get_uniform_location("uniform_color"); - auto it_path = buffer.render_paths.begin(); - for (unsigned int ibuffer_id = 0; ibuffer_id < static_cast(buffer.indices.size()); ++ibuffer_id) { - const IBuffer& i_buffer = buffer.indices[ibuffer_id]; - // Skip all paths with ibuffer_id < ibuffer_id. - for (; it_path != buffer.render_paths.end() && it_path->ibuffer_id < ibuffer_id; ++it_path); - if (it_path == buffer.render_paths.end() || it_path->ibuffer_id > ibuffer_id) - // Not found. This shall not happen. - continue; - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); - if (position_id != -1) { - glsafe(::glVertexAttribPointer(position_id, buffer.vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes())); - glsafe(::glEnableVertexAttribArray(position_id)); - } - bool has_normals = false;// buffer.vertices.normal_size_floats() > 0; - if (has_normals) { - if (normal_id != -1) { - glsafe(::glVertexAttribPointer(normal_id, buffer.vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); - glsafe(::glEnableVertexAttribArray(normal_id)); - } - } - - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); - - // Render all elements with it_path->ibuffer_id == ibuffer_id, possible with varying colors. - switch (buffer.render_primitive_type) - { - case TBuffer::ERenderPrimitiveType::Triangle: { - render_as_triangles(buffer, it_path, buffer.render_paths.end(), *shader, uniform_color); - break; - } - default: { break; } - } - - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - - if (normal_id != -1) - glsafe(::glDisableVertexAttribArray(normal_id)); - if (position_id != -1) - glsafe(::glDisableVertexAttribArray(position_id)); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - } - } - - shader->stop_using(); - } - else { - BOOST_LOG_TRIVIAL(info) << boost::format("render_calibration_thumbnail: can not find shader"); - } - } -#endif - BOOST_LOG_TRIVIAL(info) << boost::format("render_calibration_thumbnail: exit"); - -} - -void GCodeViewer::_render_calibration_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager) -{ - BOOST_LOG_TRIVIAL(info) << boost::format("render_calibration_thumbnail prepare: width %1%, height %2%")%w %h; - thumbnail_data.set(w, h); - if (!thumbnail_data.is_valid()) - return; - - //TODO bool multisample = m_multisample_allowed; - bool multisample = OpenGLManager::can_multisample(); - //if (!multisample) - // glsafe(::glEnable(GL_MULTISAMPLE)); - - GLint max_samples; - glsafe(::glGetIntegerv(GL_MAX_SAMPLES, &max_samples)); - GLsizei num_samples = max_samples / 2; - - GLuint render_fbo; - glsafe(::glGenFramebuffers(1, &render_fbo)); - glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, render_fbo)); - BOOST_LOG_TRIVIAL(info) << boost::format("render_calibration_thumbnail prepare: max_samples %1%, multisample %2%, render_fbo %3%")%max_samples %multisample %render_fbo; - - GLuint render_tex = 0; - GLuint render_tex_buffer = 0; - if (multisample) { - // use renderbuffer instead of texture to avoid the need to use glTexImage2DMultisample which is available only since OpenGL 3.2 - glsafe(::glGenRenderbuffers(1, &render_tex_buffer)); - glsafe(::glBindRenderbuffer(GL_RENDERBUFFER, render_tex_buffer)); - glsafe(::glRenderbufferStorageMultisample(GL_RENDERBUFFER, num_samples, GL_RGBA8, w, h)); - glsafe(::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, render_tex_buffer)); - } - else { - glsafe(::glGenTextures(1, &render_tex)); - glsafe(::glBindTexture(GL_TEXTURE_2D, render_tex)); - glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); - glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, render_tex, 0)); - } - - GLuint render_depth; - glsafe(::glGenRenderbuffers(1, &render_depth)); - glsafe(::glBindRenderbuffer(GL_RENDERBUFFER, render_depth)); - if (multisample) - glsafe(::glRenderbufferStorageMultisample(GL_RENDERBUFFER, num_samples, GL_DEPTH_COMPONENT24, w, h)); - else - glsafe(::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h)); - - glsafe(::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, render_depth)); - - GLenum drawBufs[] = { GL_COLOR_ATTACHMENT0 }; - glsafe(::glDrawBuffers(1, drawBufs)); - - - if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) { - _render_calibration_thumbnail_internal(thumbnail_data, thumbnail_params, partplate_list, opengl_manager); - - if (multisample) { - GLuint resolve_fbo; - glsafe(::glGenFramebuffers(1, &resolve_fbo)); - glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, resolve_fbo)); - - GLuint resolve_tex; - glsafe(::glGenTextures(1, &resolve_tex)); - glsafe(::glBindTexture(GL_TEXTURE_2D, resolve_tex)); - glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); - glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolve_tex, 0)); - - glsafe(::glDrawBuffers(1, drawBufs)); - - if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) { - glsafe(::glBindFramebuffer(GL_READ_FRAMEBUFFER, render_fbo)); - glsafe(::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolve_fbo)); - glsafe(::glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_LINEAR)); - - glsafe(::glBindFramebuffer(GL_READ_FRAMEBUFFER, resolve_fbo)); - glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); - } - - glsafe(::glDeleteTextures(1, &resolve_tex)); - glsafe(::glDeleteFramebuffers(1, &resolve_fbo)); - } - else - glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); - } -#if ENABLE_CALIBRATION_THUMBNAIL_OUTPUT - debug_calibration_output_thumbnail(thumbnail_data); -#endif - - glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, 0)); - glsafe(::glDeleteRenderbuffers(1, &render_depth)); - if (render_tex_buffer != 0) - glsafe(::glDeleteRenderbuffers(1, &render_tex_buffer)); - if (render_tex != 0) - glsafe(::glDeleteTextures(1, &render_tex)); - glsafe(::glDeleteFramebuffers(1, &render_fbo)); - - //if (!multisample) - // glsafe(::glDisable(GL_MULTISAMPLE)); - BOOST_LOG_TRIVIAL(info) << boost::format("render_calibration_thumbnail prepare: exit"); -} - -//BBS -void GCodeViewer::render_calibration_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager) -{ - // reset values and refresh render - int last_view_type_sel = m_view_type_sel; - EViewType last_view_type = m_view_type; - unsigned int last_role_visibility_flags = m_extrusions.role_visibility_flags; - // set color scheme to FilamentId - for (int i = 0; i < view_type_items.size(); i++) { - if (view_type_items[i] == EViewType::FilamentId) { - m_view_type_sel = i; - break; - } - } - set_view_type(EViewType::FilamentId, false); - // set m_layers_z_range to 0, 1; - // To be safe, we include both layers here although layer 1 seems enough - // layer 0: custom extrusions such as flow calibration etc. - // layer 1: the real first layer of object - std::array tmp_layers_z_range = m_layers_z_range; - m_layers_z_range = {0, 1}; - // BBS exclude feature types - m_extrusions.role_visibility_flags = m_extrusions.role_visibility_flags & ~(1 << erSkirt); - m_extrusions.role_visibility_flags = m_extrusions.role_visibility_flags & ~(1 << erCustom); - // BBS include feature types - m_extrusions.role_visibility_flags = m_extrusions.role_visibility_flags | (1 << erWipeTower); - m_extrusions.role_visibility_flags = m_extrusions.role_visibility_flags | (1 << erPerimeter); - m_extrusions.role_visibility_flags = m_extrusions.role_visibility_flags | (1 << erExternalPerimeter); - m_extrusions.role_visibility_flags = m_extrusions.role_visibility_flags | (1 << erOverhangPerimeter); - m_extrusions.role_visibility_flags = m_extrusions.role_visibility_flags | (1 << erSolidInfill); - m_extrusions.role_visibility_flags = m_extrusions.role_visibility_flags | (1 << erTopSolidInfill); - m_extrusions.role_visibility_flags = m_extrusions.role_visibility_flags | (1 << erInternalInfill); - m_extrusions.role_visibility_flags = m_extrusions.role_visibility_flags | (1 << erBottomSurface); - - refresh_render_paths(false, false); - - _render_calibration_thumbnail_framebuffer(thumbnail_data, w, h, thumbnail_params, partplate_list, opengl_manager); - - // restore values and refresh render - // reset m_layers_z_range and view type - m_view_type_sel = last_view_type_sel; - set_view_type(last_view_type, false); - m_layers_z_range = tmp_layers_z_range; - m_extrusions.role_visibility_flags = last_role_visibility_flags; - refresh_render_paths(false, false); -} - bool GCodeViewer::can_export_toolpaths() const { - return has_data() && m_buffers[buffer_id(EMoveType::Extrude)].render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle; + const libvgcode::Interval& visible_range = m_viewer.get_view_visible_range(); + for (size_t i = visible_range[0]; i <= visible_range[1]; ++i) { + if (m_viewer.get_vertex_at(i).is_extrusion()) + return true; + } + return false; } void GCodeViewer::update_sequential_view_current(unsigned int first, unsigned int last) { - auto is_visible = [this](unsigned int id) { - for (const TBuffer &buffer : m_buffers) { - if (buffer.visible) { - for (const Path &path : buffer.paths) { - if (path.sub_paths.front().first.s_id <= id && id <= path.sub_paths.back().last.s_id) return true; - } + m_viewer.set_view_visible_range(static_cast(first), static_cast(last)); + const libvgcode::Interval& enabled_range = m_viewer.get_view_enabled_range(); + enable_moves_slider(enabled_range[1] > enabled_range[0]); + +#if ENABLE_ACTUAL_SPEED_DEBUG + if (enabled_range[1] != m_viewer.get_view_visible_range()[1]) { + const libvgcode::PathVertex& curr_vertex = m_viewer.get_current_vertex(); + if (curr_vertex.is_extrusion() || curr_vertex.is_travel() || curr_vertex.is_wipe() || + curr_vertex.type == libvgcode::EMoveType::Seam) { + const libvgcode::ColorRange& color_range = m_viewer.get_color_range(libvgcode::EViewType::ActualSpeed); + const std::array& interval = color_range.get_range(); + const size_t vertices_count = m_viewer.get_vertices_count(); + std::vector actual_speed_data; + // collect vertices sharing the same gcode_id + const size_t curr_id = m_viewer.get_current_vertex_id(); + size_t start_id = curr_id; + while (start_id > 0) { + --start_id; + if (curr_vertex.gcode_id != m_viewer.get_vertex_at(start_id).gcode_id) + break; + } + size_t end_id = curr_id; + while (end_id < vertices_count - 1) { + ++end_id; + if (curr_vertex.gcode_id != m_viewer.get_vertex_at(end_id).gcode_id) + break; } - } - return false; - }; - const int first_diff = static_cast(first) - static_cast(m_sequential_view.last_current.first); - const int last_diff = static_cast(last) - static_cast(m_sequential_view.last_current.last); + if (m_viewer.get_vertex_at(end_id - 1).type == libvgcode::convert(EMoveType::Seam)) + --end_id; - unsigned int new_first = first; - unsigned int new_last = last; + assert(end_id - start_id >= 2); - if (m_sequential_view.skip_invisible_moves) { - while (!is_visible(new_first)) { - if (first_diff > 0) - ++new_first; - else - --new_first; - } + float total_len = 0.0f; + for (size_t i = start_id; i < end_id; ++i) { + const libvgcode::PathVertex& v = m_viewer.get_vertex_at(i); + const float len = (i > start_id) ? + (libvgcode::convert(v.position) - libvgcode::convert(m_viewer.get_vertex_at(i - 1).position)).norm() : 0.0f; + total_len += len; + if (i == start_id || len > EPSILON) + actual_speed_data.push_back({ total_len, v.actual_feedrate, v.times[0] == 0.0f }); + } - while (!is_visible(new_last)) { - if (last_diff > 0) - ++new_last; - else - --new_last; + std::vector> levels; + const std::vector values = color_range.get_values(); + for (float value : values) { + levels.push_back(std::make_pair(value, libvgcode::convert(color_range.get_color_at(value)))); + levels.back().second.a(0.5f); + } + m_sequential_view.marker.set_actual_speed_data(actual_speed_data); + m_sequential_view.marker.set_actual_speed_y_range(std::make_pair(interval[0], interval[1])); + m_sequential_view.marker.set_actual_speed_levels(levels); } } - - m_sequential_view.current.first = new_first; - m_sequential_view.current.last = new_last; - m_sequential_view.last_current = m_sequential_view.current; - - refresh_render_paths(true, true); - - if (new_first != first || new_last != last) { - update_moves_slider(); - } +#endif // ENABLE_ACTUAL_SPEED_DEBUG } void GCodeViewer::enable_moves_slider(bool enable) const @@ -1772,25 +1460,58 @@ void GCodeViewer::enable_moves_slider(bool enable) const void GCodeViewer::update_moves_slider(bool set_to_max) { - const GCodeViewer::SequentialView &view = get_sequential_view(); - // this should not be needed, but it is here to try to prevent rambling crashes on Mac Asan - if (view.endpoints.last < view.endpoints.first) return; + if (m_gcode_result->moves.empty()) + return; - std::vector values(view.endpoints.last - view.endpoints.first + 1); - std::vector alternate_values(view.endpoints.last - view.endpoints.first + 1); - unsigned int count = 0; - for (unsigned int i = view.endpoints.first; i <= view.endpoints.last; ++i) { - values[count] = static_cast(i + 1); - if (view.gcode_ids[i] > 0) alternate_values[count] = static_cast(view.gcode_ids[i]); - ++count; + const libvgcode::Interval& range = m_viewer.get_view_enabled_range(); + const libvgcode::Interval& visible_range = m_viewer.get_view_visible_range(); + uint32_t last_gcode_id = get_gcode_vertex_at(range[0]).gcode_id; + uint32_t gcode_id_min = get_gcode_vertex_at(visible_range[0]).gcode_id; + uint32_t gcode_id_max = get_gcode_vertex_at(visible_range[1]).gcode_id; + + const size_t range_size = range[1] - range[0] + 1; + std::vector values; + values.reserve(range_size); + std::vector alternate_values; + alternate_values.reserve(range_size); + + std::optional visible_range_min_id; + std::optional visible_range_max_id; + uint32_t counter = 0; + + for (size_t i = range[0]; i <= range[1]; ++i) { + const uint32_t gcode_id = get_gcode_vertex_at(i).gcode_id; + bool skip = false; + if (i > range[0]) { + // skip consecutive moves with same gcode id (resulting from processing G2 and G3 lines) + if (last_gcode_id == gcode_id) { + values.back() = i + 1; + skip = true; + } + else + last_gcode_id = gcode_id; + } + + if (!skip) { + values.emplace_back(i + 1); + alternate_values.emplace_back(gcode_id); + if (alternate_values.back() == gcode_id_min) + visible_range_min_id = counter; + else if (alternate_values.back() == gcode_id_max) + visible_range_max_id = counter; + ++counter; + } } + const int span_min_id = visible_range_min_id.has_value() ? *visible_range_min_id : 0; + const int span_max_id = visible_range_max_id.has_value() ? *visible_range_max_id : static_cast(values.size()) - 1; + bool keep_min = m_moves_slider->GetActiveValue() == m_moves_slider->GetMinValue(); m_moves_slider->SetSliderValues(values); m_moves_slider->SetSliderAlternateValues(alternate_values); - m_moves_slider->SetMaxValue(view.endpoints.last - view.endpoints.first); - m_moves_slider->SetSelectionSpan(view.current.first - view.endpoints.first, view.current.last - view.endpoints.first); + m_moves_slider->SetMaxValue(static_cast(values.size()) - 1); + m_moves_slider->SetSelectionSpan(span_min_id, span_max_id); if (set_to_max) m_moves_slider->SetHigherValue(keep_min ? m_moves_slider->GetMinValue() : m_moves_slider->GetMaxValue()); } @@ -1836,83 +1557,314 @@ void GCodeViewer::update_layers_slider_mode() // TODO m_layers_slider->SetModeAndOnlyExtruder(one_extruder_printed_model, only_extruder); } -void GCodeViewer::update_marker_curr_move() { - if ((int)m_last_result_id != -1) { - auto it = std::find_if(m_gcode_result->moves.begin(), m_gcode_result->moves.end(), [this](auto move) { - if (m_sequential_view.current.last < m_sequential_view.gcode_ids.size() && m_sequential_view.current.last >= 0) { - return move.gcode_id == static_cast(m_sequential_view.gcode_ids[m_sequential_view.current.last]); - } - return false; - }); - if (it != m_gcode_result->moves.end()) - m_sequential_view.marker.update_curr_move(*it); - } -} - -bool GCodeViewer::is_toolpath_move_type_visible(EMoveType type) const -{ - size_t id = static_cast(buffer_id(type)); - return (id < m_buffers.size()) ? m_buffers[id].visible : false; -} - -void GCodeViewer::set_toolpath_move_type_visible(EMoveType type, bool visible) -{ - size_t id = static_cast(buffer_id(type)); - if (id < m_buffers.size()) - m_buffers[id].visible = visible; -} - -unsigned int GCodeViewer::get_options_visibility_flags() const -{ - auto set_flag = [](unsigned int flags, unsigned int flag, bool active) { - return active ? (flags | (1 << flag)) : flags; - }; - - unsigned int flags = 0; - flags = set_flag(flags, static_cast(Preview::OptionType::Travel), is_toolpath_move_type_visible(EMoveType::Travel)); - flags = set_flag(flags, static_cast(Preview::OptionType::Wipe), is_toolpath_move_type_visible(EMoveType::Wipe)); - flags = set_flag(flags, static_cast(Preview::OptionType::Retractions), is_toolpath_move_type_visible(EMoveType::Retract)); - flags = set_flag(flags, static_cast(Preview::OptionType::Unretractions), is_toolpath_move_type_visible(EMoveType::Unretract)); - flags = set_flag(flags, static_cast(Preview::OptionType::Seams), is_toolpath_move_type_visible(EMoveType::Seam)); - flags = set_flag(flags, static_cast(Preview::OptionType::ToolChanges), is_toolpath_move_type_visible(EMoveType::Tool_change)); - flags = set_flag(flags, static_cast(Preview::OptionType::ColorChanges), is_toolpath_move_type_visible(EMoveType::Color_change)); - flags = set_flag(flags, static_cast(Preview::OptionType::PausePrints), is_toolpath_move_type_visible(EMoveType::Pause_Print)); - flags = set_flag(flags, static_cast(Preview::OptionType::CustomGCodes), is_toolpath_move_type_visible(EMoveType::Custom_GCode)); - flags = set_flag(flags, static_cast(Preview::OptionType::Shells), m_shells.visible); - flags = set_flag(flags, static_cast(Preview::OptionType::ToolMarker), m_sequential_view.marker.is_visible()); - flags = set_flag(flags, static_cast(Preview::OptionType::Legend), is_legend_enabled()); - return flags; -} - -void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) -{ - auto is_flag_set = [flags](unsigned int flag) { - return (flags & (1 << flag)) != 0; - }; - - set_toolpath_move_type_visible(EMoveType::Travel, is_flag_set(static_cast(Preview::OptionType::Travel))); - set_toolpath_move_type_visible(EMoveType::Wipe, is_flag_set(static_cast(Preview::OptionType::Wipe))); - set_toolpath_move_type_visible(EMoveType::Retract, is_flag_set(static_cast(Preview::OptionType::Retractions))); - set_toolpath_move_type_visible(EMoveType::Unretract, is_flag_set(static_cast(Preview::OptionType::Unretractions))); - set_toolpath_move_type_visible(EMoveType::Seam, is_flag_set(static_cast(Preview::OptionType::Seams))); - set_toolpath_move_type_visible(EMoveType::Tool_change, is_flag_set(static_cast(Preview::OptionType::ToolChanges))); - set_toolpath_move_type_visible(EMoveType::Color_change, is_flag_set(static_cast(Preview::OptionType::ColorChanges))); - set_toolpath_move_type_visible(EMoveType::Pause_Print, is_flag_set(static_cast(Preview::OptionType::PausePrints))); - set_toolpath_move_type_visible(EMoveType::Custom_GCode, is_flag_set(static_cast(Preview::OptionType::CustomGCodes))); - m_shells.visible = is_flag_set(static_cast(Preview::OptionType::Shells)); - m_sequential_view.marker.set_visible(is_flag_set(static_cast(Preview::OptionType::ToolMarker))); - enable_legend(is_flag_set(static_cast(Preview::OptionType::Legend))); -} - void GCodeViewer::set_layers_z_range(const std::array& layers_z_range) { - bool keep_sequential_current_first = layers_z_range[0] >= m_layers_z_range[0]; - bool keep_sequential_current_last = layers_z_range[1] <= m_layers_z_range[1]; - m_layers_z_range = layers_z_range; - refresh_render_paths(keep_sequential_current_first, keep_sequential_current_last); + m_viewer.set_layers_view_range(static_cast(layers_z_range[0]), static_cast(layers_z_range[1])); update_moves_slider(true); } +class ToolpathsObjExporter +{ +public: + explicit ToolpathsObjExporter(const libvgcode::Viewer& viewer) + : m_viewer(viewer) { + } + + void export_to(const std::string& filename) { + CNumericLocalesSetter locales_setter; + + // open geometry file + FilePtr f_geo = boost::nowide::fopen(filename.c_str(), "w"); + if (f_geo.f == nullptr) { + BOOST_LOG_TRIVIAL(error) << "ToolpathsObjExporter: Couldn't open " << filename << " for writing"; + return; + } + + boost::filesystem::path materials_filename(filename); + materials_filename.replace_extension("mtl"); + + // write header to geometry file + fprintf(f_geo.f, "# G-Code Toolpaths\n"); + fprintf(f_geo.f, "# Generated by %s-%s based on Slic3r\n", SLIC3R_APP_NAME, SoftFever_VERSION); + fprintf(f_geo.f, "\nmtllib ./%s\n", materials_filename.filename().string().c_str()); + + // open material file + FilePtr f_mat = boost::nowide::fopen(materials_filename.string().c_str(), "w"); + if (f_mat.f == nullptr) { + BOOST_LOG_TRIVIAL(error) << "ToolpathsObjExporter: Couldn't open " << materials_filename.string() << " for writing"; + return; + } + + // write header to material file + fprintf(f_mat.f, "# G-Code Toolpaths Materials\n"); + fprintf(f_mat.f, "# Generated by %s-%s based on Slic3r\n", SLIC3R_APP_NAME, SoftFever_VERSION); + + libvgcode::Interval visible_range = m_viewer.get_view_visible_range(); + if (m_viewer.is_top_layer_only_view_range()) + visible_range[0] = m_viewer.get_view_full_range()[0]; + for (size_t i = visible_range[0]; i <= visible_range[1]; ++i) { + const libvgcode::PathVertex& curr = m_viewer.get_vertex_at(i); + const libvgcode::PathVertex& next = m_viewer.get_vertex_at(i + 1); + if (!curr.is_extrusion() || !next.is_extrusion()) + continue; + + const libvgcode::PathVertex& nextnext = m_viewer.get_vertex_at(i + 2); + unsigned char flags = 0; + if (curr.gcode_id == next.gcode_id) + flags |= Flag_First; + if (i + 1 == visible_range[1] || !nextnext.is_extrusion()) + flags |= Flag_Last; + else + flags |= Flag_Internal; + export_segment(*f_geo.f, flags, i, curr, next, nextnext); + } + export_materials(*f_mat.f); + } + +private: + const libvgcode::Viewer& m_viewer; + size_t m_vertices_count{ 0 }; + std::vector m_colors; + static const unsigned char Flag_First = 0x01; + static const unsigned char Flag_Last = 0x02; + static const unsigned char Flag_Internal = 0x04; + static const float Cap_Rounding_Factor; + + struct SegmentLocalAxes + { + Vec3f forward; + Vec3f right; + Vec3f up; + }; + + SegmentLocalAxes segment_local_axes(const Vec3f& v1, const Vec3f& v2) { + SegmentLocalAxes ret; + ret.forward = (v2 - v1).normalized(); + ret.right = ret.forward.cross(Vec3f::UnitZ()).normalized(); + ret.up = ret.right.cross(ret.forward); + return ret; + } + + struct Vertex + { + Vec3f position; + Vec3f normal; + }; + + struct CrossSection + { + Vertex right; + Vertex top; + Vertex left; + Vertex bottom; + }; + + CrossSection cross_section(const Vec3f& v, const Vec3f& right, const Vec3f& up, float width, float height) { + CrossSection ret; + const Vec3f w_shift = 0.5f * width * right; + const Vec3f h_shift = 0.5f * height * up; + ret.right.position = v + w_shift; + ret.right.normal = right; + ret.top.position = v + h_shift; + ret.top.normal = up; + ret.left.position = v - w_shift; + ret.left.normal = -right; + ret.bottom.position = v - h_shift; + ret.bottom.normal = -up; + return ret; + } + + CrossSection normal_cross_section(const Vec3f& v, const SegmentLocalAxes& axes, float width, float height) { + return cross_section(v, axes.right, axes.up, width, height); + } + + enum CornerType : unsigned char + { + RightTurn, + LeftTurn, + Straight + }; + + CrossSection corner_cross_section(const Vec3f& v, const SegmentLocalAxes& axes1, const SegmentLocalAxes& axes2, + float width, float height, CornerType& corner_type) { + if (std::abs(std::abs(axes1.forward.dot(axes2.forward)) - 1.0f) < EPSILON) + corner_type = CornerType::Straight; + else if (axes1.up.dot(axes1.forward.cross(axes2.forward)) < 0.0f) + corner_type = CornerType::RightTurn; + else + corner_type = CornerType::LeftTurn; + const Vec3f right = (0.5f * (axes1.right + axes2.right)).normalized(); + return cross_section(v, right, axes1.up, width, height); + } + + void export_segment(FILE& f, unsigned char flags, size_t v1_id, const libvgcode::PathVertex& v1, const libvgcode::PathVertex& v2, const libvgcode::PathVertex& v3) { + const Vec3f v1_pos = libvgcode::convert(v1.position); + const Vec3f v2_pos = libvgcode::convert(v2.position); + const Vec3f v3_pos = libvgcode::convert(v3.position); + const SegmentLocalAxes v1_v2 = segment_local_axes(v1_pos, v2_pos); + const SegmentLocalAxes v2_v3 = segment_local_axes(v2_pos, v3_pos); + + // starting cap + if ((flags & Flag_First) > 0) { + const Vertex v0 = { v1_pos - Cap_Rounding_Factor * v1.width * v1_v2.forward, -v1_v2.forward }; + const CrossSection ncs = normal_cross_section(v1_pos, v1_v2, v1.width, v1.height); + export_vertex(f, v0); // 0 + export_vertex(f, ncs.right); // 1 + export_vertex(f, ncs.top); // 2 + export_vertex(f, ncs.left); // 3 + export_vertex(f, ncs.bottom); // 4 + export_material(f, color_id(v1_id)); + export_triangle(f, vertex_id(0), vertex_id(1), vertex_id(2)); + export_triangle(f, vertex_id(0), vertex_id(2), vertex_id(3)); + export_triangle(f, vertex_id(0), vertex_id(3), vertex_id(4)); + export_triangle(f, vertex_id(0), vertex_id(4), vertex_id(1)); + m_vertices_count += 5; + } + // segment body + ending cap + if ((flags & Flag_Last) > 0) { + const Vertex v0 = { v2_pos + Cap_Rounding_Factor * v2.width * v1_v2.forward, v1_v2.forward }; + const CrossSection ncs = normal_cross_section(v2_pos, v1_v2, v2.width, v2.height); + export_vertex(f, v0); // 0 + export_vertex(f, ncs.right); // 1 + export_vertex(f, ncs.top); // 2 + export_vertex(f, ncs.left); // 3 + export_vertex(f, ncs.bottom); // 4 + export_material(f, color_id(v1_id + 1)); + // segment body + export_triangle(f, vertex_id(-4), vertex_id(1), vertex_id(2)); + export_triangle(f, vertex_id(-4), vertex_id(2), vertex_id(-3)); + export_triangle(f, vertex_id(-3), vertex_id(2), vertex_id(3)); + export_triangle(f, vertex_id(-3), vertex_id(3), vertex_id(-2)); + export_triangle(f, vertex_id(-2), vertex_id(3), vertex_id(4)); + export_triangle(f, vertex_id(-2), vertex_id(4), vertex_id(-1)); + export_triangle(f, vertex_id(-1), vertex_id(4), vertex_id(1)); + export_triangle(f, vertex_id(-1), vertex_id(1), vertex_id(-4)); + // ending cap + export_triangle(f, vertex_id(0), vertex_id(3), vertex_id(2)); + export_triangle(f, vertex_id(0), vertex_id(2), vertex_id(1)); + export_triangle(f, vertex_id(0), vertex_id(1), vertex_id(4)); + export_triangle(f, vertex_id(0), vertex_id(4), vertex_id(3)); + m_vertices_count += 5; + } + else { + CornerType corner_type; + const CrossSection ccs = corner_cross_section(v2_pos, v1_v2, v2_v3, v2.width, v2.height, corner_type); + const CrossSection ncs12 = normal_cross_section(v2_pos, v1_v2, v2.width, v2.height); + const CrossSection ncs23 = normal_cross_section(v2_pos, v2_v3, v2.width, v2.height); + if (corner_type == CornerType::Straight) { + export_vertex(f, ncs12.right); // 0 + export_vertex(f, ncs12.top); // 1 + export_vertex(f, ncs12.left); // 2 + export_vertex(f, ncs12.bottom); // 3 + export_material(f, color_id(v1_id + 1)); + // segment body + export_triangle(f, vertex_id(-4), vertex_id(0), vertex_id(1)); + export_triangle(f, vertex_id(-4), vertex_id(1), vertex_id(-3)); + export_triangle(f, vertex_id(-3), vertex_id(1), vertex_id(2)); + export_triangle(f, vertex_id(-3), vertex_id(2), vertex_id(-2)); + export_triangle(f, vertex_id(-2), vertex_id(2), vertex_id(3)); + export_triangle(f, vertex_id(-2), vertex_id(3), vertex_id(-1)); + export_triangle(f, vertex_id(-1), vertex_id(3), vertex_id(0)); + export_triangle(f, vertex_id(-1), vertex_id(0), vertex_id(-4)); + m_vertices_count += 4; + } + else if (corner_type == CornerType::RightTurn) { + export_vertex(f, ncs12.left); // 0 + export_vertex(f, ccs.left); // 1 + export_vertex(f, ccs.right); // 2 + export_vertex(f, ncs12.top); // 3 + export_vertex(f, ncs23.left); // 4 + export_vertex(f, ncs12.bottom); // 5 + export_material(f, color_id(v1_id + 1)); + // segment body + export_triangle(f, vertex_id(-4), vertex_id(2), vertex_id(3)); + export_triangle(f, vertex_id(-4), vertex_id(3), vertex_id(-3)); + export_triangle(f, vertex_id(-3), vertex_id(3), vertex_id(0)); + export_triangle(f, vertex_id(-3), vertex_id(0), vertex_id(-2)); + export_triangle(f, vertex_id(-2), vertex_id(0), vertex_id(5)); + export_triangle(f, vertex_id(-2), vertex_id(5), vertex_id(-1)); + export_triangle(f, vertex_id(-1), vertex_id(5), vertex_id(2)); + export_triangle(f, vertex_id(-1), vertex_id(2), vertex_id(-4)); + // corner + export_triangle(f, vertex_id(1), vertex_id(0), vertex_id(3)); + export_triangle(f, vertex_id(1), vertex_id(3), vertex_id(4)); + export_triangle(f, vertex_id(1), vertex_id(4), vertex_id(5)); + export_triangle(f, vertex_id(1), vertex_id(5), vertex_id(0)); + m_vertices_count += 6; + } + else { + export_vertex(f, ncs12.right); // 0 + export_vertex(f, ccs.right); // 1 + export_vertex(f, ncs23.right); // 2 + export_vertex(f, ncs12.top); // 3 + export_vertex(f, ccs.left); // 4 + export_vertex(f, ncs12.bottom); // 5 + export_material(f, color_id(v1_id + 1)); + // segment body + export_triangle(f, vertex_id(-4), vertex_id(0), vertex_id(3)); + export_triangle(f, vertex_id(-4), vertex_id(3), vertex_id(-3)); + export_triangle(f, vertex_id(-3), vertex_id(3), vertex_id(4)); + export_triangle(f, vertex_id(-3), vertex_id(4), vertex_id(-2)); + export_triangle(f, vertex_id(-2), vertex_id(4), vertex_id(5)); + export_triangle(f, vertex_id(-2), vertex_id(5), vertex_id(-1)); + export_triangle(f, vertex_id(-1), vertex_id(5), vertex_id(0)); + export_triangle(f, vertex_id(-1), vertex_id(0), vertex_id(-4)); + // corner + export_triangle(f, vertex_id(1), vertex_id(2), vertex_id(3)); + export_triangle(f, vertex_id(1), vertex_id(3), vertex_id(0)); + export_triangle(f, vertex_id(1), vertex_id(0), vertex_id(5)); + export_triangle(f, vertex_id(1), vertex_id(5), vertex_id(2)); + m_vertices_count += 6; + } + } + } + + size_t vertex_id(int id) { return static_cast(1 + static_cast(m_vertices_count) + id); } + + void export_vertex(FILE& f, const Vertex& v) { + fprintf(&f, "v %g %g %g\n", v.position.x(), v.position.y(), v.position.z()); + fprintf(&f, "vn %g %g %g\n", v.normal.x(), v.normal.y(), v.normal.z()); + } + + void export_material(FILE& f, size_t material_id) { + fprintf(&f, "\nusemtl material_%zu\n", material_id + 1); + } + + void export_triangle(FILE& f, size_t v1, size_t v2, size_t v3) { + fprintf(&f, "f %zu//%zu %zu//%zu %zu//%zu\n", v1, v1, v2, v2, v3, v3); + } + + void export_materials(FILE& f) { + static const float inv_255 = 1.0f / 255.0f; + size_t materials_counter = 0; + for (const auto& color : m_colors) { + fprintf(&f, "\nnewmtl material_%zu\n", ++materials_counter); + fprintf(&f, "Ka 1 1 1\n"); + fprintf(&f, "Kd %g %g %g\n", static_cast(color[0]) * inv_255, + static_cast(color[1]) * inv_255, + static_cast(color[2]) * inv_255); + fprintf(&f, "Ks 0 0 0\n"); + } + } + + size_t color_id(size_t vertex_id) { + const libvgcode::PathVertex& v = m_viewer.get_vertex_at(vertex_id); + const size_t top_layer_id = m_viewer.is_top_layer_only_view_range() ? m_viewer.get_layers_view_range()[1] : 0; + const bool color_top_layer_only = m_viewer.get_view_full_range()[1] != m_viewer.get_view_visible_range()[1]; + const libvgcode::Color color = (color_top_layer_only && v.layer_id < top_layer_id && + (!m_viewer.is_spiral_vase_mode() || vertex_id != m_viewer.get_view_enabled_range()[0])) ? + libvgcode::DUMMY_COLOR : m_viewer.get_vertex_color(v); + auto color_it = std::find_if(m_colors.begin(), m_colors.end(), [&color](const libvgcode::Color& m) { return m == color; }); + if (color_it == m_colors.end()) { + m_colors.emplace_back(color); + color_it = std::prev(m_colors.end()); + } + return std::distance(m_colors.begin(), color_it); + } +}; + +const float ToolpathsObjExporter::Cap_Rounding_Factor = 0.25f; + void GCodeViewer::export_toolpaths_to_obj(const char* filename) const { if (filename == nullptr) @@ -1922,1212 +1874,8 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const return; wxBusyCursor busy; - - // the data needed is contained into the Extrude TBuffer - const TBuffer& t_buffer = m_buffers[buffer_id(EMoveType::Extrude)]; - if (!t_buffer.has_data()) - return; - - if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Triangle) - return; - - // collect color information to generate materials - std::vector colors; - for (const RenderPath& path : t_buffer.render_paths) { - colors.push_back(path.color); - } - sort_remove_duplicates(colors); - - // save materials file - boost::filesystem::path mat_filename(filename); - mat_filename.replace_extension("mtl"); - - CNumericLocalesSetter locales_setter; - - FILE* fp = boost::nowide::fopen(mat_filename.string().c_str(), "w"); - if (fp == nullptr) { - BOOST_LOG_TRIVIAL(error) << "GCodeViewer::export_toolpaths_to_obj: Couldn't open " << mat_filename.string().c_str() << " for writing"; - return; - } - - fprintf(fp, "# G-Code Toolpaths Materials\n"); - fprintf(fp, "# Generated by %s-%s based on Slic3r\n", SLIC3R_APP_NAME, SoftFever_VERSION); - - unsigned int colors_count = 1; - for (const ColorRGBA& color : colors) { - fprintf(fp, "\nnewmtl material_%d\n", colors_count++); - fprintf(fp, "Ka 1 1 1\n"); - fprintf(fp, "Kd %g %g %g\n", color.r(), color.g(), color.b()); - fprintf(fp, "Ks 0 0 0\n"); - } - - fclose(fp); - - // save geometry file - fp = boost::nowide::fopen(filename, "w"); - if (fp == nullptr) { - BOOST_LOG_TRIVIAL(error) << "GCodeViewer::export_toolpaths_to_obj: Couldn't open " << filename << " for writing"; - return; - } - - fprintf(fp, "# G-Code Toolpaths\n"); - fprintf(fp, "# Generated by %s-%s based on Slic3r\n", SLIC3R_APP_NAME, SoftFever_VERSION); - fprintf(fp, "\nmtllib ./%s\n", mat_filename.filename().string().c_str()); - - const size_t floats_per_vertex = t_buffer.vertices.vertex_size_floats(); - - std::vector out_vertices; - std::vector out_normals; - - struct VerticesOffset - { - unsigned int vbo; - size_t offset; - }; - std::vector vertices_offsets; - vertices_offsets.push_back({ t_buffer.vertices.vbos.front(), 0 }); - - // get vertices/normals data from vertex buffers on gpu - for (size_t i = 0; i < t_buffer.vertices.vbos.size(); ++i) { - const size_t floats_count = t_buffer.vertices.sizes[i] / sizeof(float); - VertexBuffer vertices(floats_count); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, t_buffer.vertices.vbos[i])); - glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, 0, static_cast(t_buffer.vertices.sizes[i]), static_cast(vertices.data()))); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - const size_t vertices_count = floats_count / floats_per_vertex; - for (size_t j = 0; j < vertices_count; ++j) { - const size_t base = j * floats_per_vertex; - out_vertices.push_back({ vertices[base + 0], vertices[base + 1], vertices[base + 2] }); - out_normals.push_back({ vertices[base + 3], vertices[base + 4], vertices[base + 5] }); - } - - if (i < t_buffer.vertices.vbos.size() - 1) - vertices_offsets.push_back({ t_buffer.vertices.vbos[i + 1], vertices_offsets.back().offset + vertices_count }); - } - - // save vertices to file - fprintf(fp, "\n# vertices\n"); - for (const Vec3f& v : out_vertices) { - fprintf(fp, "v %g %g %g\n", v.x(), v.y(), v.z()); - } - - // save normals to file - fprintf(fp, "\n# normals\n"); - for (const Vec3f& n : out_normals) { - fprintf(fp, "vn %g %g %g\n", n.x(), n.y(), n.z()); - } - - size_t i = 0; - for (const ColorRGBA& color : colors) { - // save material triangles to file - fprintf(fp, "\nusemtl material_%zu\n", i + 1); - fprintf(fp, "# triangles material %zu\n", i + 1); - - for (const RenderPath& render_path : t_buffer.render_paths) { - if (render_path.color != color) - continue; - - const IBuffer& ibuffer = t_buffer.indices[render_path.ibuffer_id]; - size_t vertices_offset = 0; - for (size_t j = 0; j < vertices_offsets.size(); ++j) { - const VerticesOffset& offset = vertices_offsets[j]; - if (offset.vbo == ibuffer.vbo) { - vertices_offset = offset.offset; - break; - } - } - - // get indices data from index buffer on gpu - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuffer.ibo)); - for (size_t j = 0; j < render_path.sizes.size(); ++j) { - IndexBuffer indices(render_path.sizes[j]); - glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast(render_path.offsets[j]), - static_cast(render_path.sizes[j] * sizeof(IBufferType)), static_cast(indices.data()))); - - const size_t triangles_count = render_path.sizes[j] / 3; - for (size_t k = 0; k < triangles_count; ++k) { - const size_t base = k * 3; - const size_t v1 = 1 + static_cast(indices[base + 0]) + vertices_offset; - const size_t v2 = 1 + static_cast(indices[base + 1]) + vertices_offset; - const size_t v3 = 1 + static_cast(indices[base + 2]) + vertices_offset; - if (v1 != v2) - // do not export dummy triangles - fprintf(fp, "f %zu//%zu %zu//%zu %zu//%zu\n", v1, v1, v2, v2, v3, v3); - } - } - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - } - ++i; - } - - fclose(fp); -} - -void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result, const BuildVolume& build_volume, const std::vector& exclude_bounding_box) -{ - // max index buffer size, in bytes - static const size_t IBUFFER_THRESHOLD_BYTES = 64 * 1024 * 1024; - - //BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(",build_volume center{%1%, %2%}, moves count %3%\n")%build_volume.bed_center().x() % build_volume.bed_center().y() %gcode_result.moves.size(); - auto log_memory_usage = [this](const std::string& label, const std::vector& vertices, const std::vector& indices) { - int64_t vertices_size = 0; - for (const MultiVertexBuffer& buffers : vertices) { - for (const VertexBuffer& buffer : buffers) { - vertices_size += SLIC3R_STDVEC_MEMSIZE(buffer, float); - } - //BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format("vertices count %1%\n")%buffers.size(); - } - int64_t indices_size = 0; - for (const MultiIndexBuffer& buffers : indices) { - for (const IndexBuffer& buffer : buffers) { - indices_size += SLIC3R_STDVEC_MEMSIZE(buffer, IBufferType); - } - //BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format("indices count %1%\n")%buffers.size(); - } - log_memory_used(label, vertices_size + indices_size); - }; - - // format data into the buffers to be rendered as lines - auto add_vertices_as_line = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, VertexBuffer& vertices) { - auto add_vertex = [&vertices](const Vec3f& position) { - // add position - vertices.push_back(position.x()); - vertices.push_back(position.y()); - vertices.push_back(position.z()); - }; - // x component of the normal to the current segment (the normal is parallel to the XY plane) - //BBS: Has modified a lot for this function to support arc move - size_t loop_num = curr.is_arc_move_with_interpolation_points() ? curr.interpolation_points.size() : 0; - for (size_t i = 0; i < loop_num + 1; i++) { - const Vec3f &previous = (i == 0? prev.position : curr.interpolation_points[i-1]); - const Vec3f ¤t = (i == loop_num? curr.position : curr.interpolation_points[i]); - // add previous vertex - add_vertex(previous); - // add current vertex - add_vertex(current); - } - }; - //BBS: modify a lot to support arc travel - auto add_indices_as_line = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, TBuffer& buffer, - size_t& vbuffer_size, unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) { - - if (buffer.paths.empty() || prev.type != curr.type || !buffer.paths.back().matches(curr)) { - buffer.add_path(curr, ibuffer_id, indices.size(), move_id - 1); - buffer.paths.back().sub_paths.front().first.position = prev.position; - } - - Path& last_path = buffer.paths.back(); - size_t loop_num = curr.is_arc_move_with_interpolation_points() ? curr.interpolation_points.size() : 0; - for (size_t i = 0; i < loop_num + 1; i++) { - //BBS: add previous index - indices.push_back(static_cast(indices.size())); - //BBS: add current index - indices.push_back(static_cast(indices.size())); - vbuffer_size += buffer.max_vertices_per_segment(); - } - last_path.sub_paths.back().last = { ibuffer_id, indices.size() - 1, move_id, curr.position }; - }; - - // format data into the buffers to be rendered as solid. - auto add_vertices_as_solid = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, TBuffer& buffer, unsigned int vbuffer_id, VertexBuffer& vertices, size_t move_id) { - auto store_vertex = [](VertexBuffer& vertices, const Vec3f& position, const Vec3f& normal) { - // append position - vertices.push_back(position.x()); - vertices.push_back(position.y()); - vertices.push_back(position.z()); - // append normal - vertices.push_back(normal.x()); - vertices.push_back(normal.y()); - vertices.push_back(normal.z()); - }; - - if (buffer.paths.empty() || prev.type != curr.type || !buffer.paths.back().matches(curr)) { - buffer.add_path(curr, vbuffer_id, vertices.size(), move_id - 1); - buffer.paths.back().sub_paths.back().first.position = prev.position; - } - - Path& last_path = buffer.paths.back(); - //BBS: Has modified a lot for this function to support arc move - size_t loop_num = curr.is_arc_move_with_interpolation_points() ? curr.interpolation_points.size() : 0; - for (size_t i = 0; i < loop_num + 1; i++) { - const Vec3f &prev_position = (i == 0? prev.position : curr.interpolation_points[i-1]); - const Vec3f &curr_position = (i == loop_num? curr.position : curr.interpolation_points[i]); - - const Vec3f dir = (curr_position - prev_position).normalized(); - const Vec3f right = Vec3f(dir.y(), -dir.x(), 0.0f).normalized(); - const Vec3f left = -right; - const Vec3f up = right.cross(dir); - const Vec3f down = -up; - const float half_width = 0.5f * last_path.width; - const float half_height = 0.5f * last_path.height; - const Vec3f prev_pos = prev_position - half_height * up; - const Vec3f curr_pos = curr_position - half_height * up; - const Vec3f d_up = half_height * up; - const Vec3f d_down = -half_height * up; - const Vec3f d_right = half_width * right; - const Vec3f d_left = -half_width * right; - - if ((last_path.vertices_count() == 1 || vertices.empty()) && i == 0) { - store_vertex(vertices, prev_pos + d_up, up); - store_vertex(vertices, prev_pos + d_right, right); - store_vertex(vertices, prev_pos + d_down, down); - store_vertex(vertices, prev_pos + d_left, left); - } else { - store_vertex(vertices, prev_pos + d_right, right); - store_vertex(vertices, prev_pos + d_left, left); - } - - store_vertex(vertices, curr_pos + d_up, up); - store_vertex(vertices, curr_pos + d_right, right); - store_vertex(vertices, curr_pos + d_down, down); - store_vertex(vertices, curr_pos + d_left, left); - } - - last_path.sub_paths.back().last = { vbuffer_id, vertices.size(), move_id, curr.position }; - }; - auto add_indices_as_solid = [&](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, const GCodeProcessorResult::MoveVertex* next, - TBuffer& buffer, size_t& vbuffer_size, unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) { - static Vec3f prev_dir; - static Vec3f prev_up; - static float sq_prev_length; - auto store_triangle = [](IndexBuffer& indices, IBufferType i1, IBufferType i2, IBufferType i3) { - indices.push_back(i1); - indices.push_back(i2); - indices.push_back(i3); - }; - auto append_dummy_cap = [store_triangle](IndexBuffer& indices, IBufferType id) { - store_triangle(indices, id, id, id); - store_triangle(indices, id, id, id); - }; - auto convert_vertices_offset = [](size_t vbuffer_size, const std::array& v_offsets) { - std::array ret = { - static_cast(static_cast(vbuffer_size) + v_offsets[0]), - static_cast(static_cast(vbuffer_size) + v_offsets[1]), - static_cast(static_cast(vbuffer_size) + v_offsets[2]), - static_cast(static_cast(vbuffer_size) + v_offsets[3]), - static_cast(static_cast(vbuffer_size) + v_offsets[4]), - static_cast(static_cast(vbuffer_size) + v_offsets[5]), - static_cast(static_cast(vbuffer_size) + v_offsets[6]), - static_cast(static_cast(vbuffer_size) + v_offsets[7]) - }; - return ret; - }; - auto append_starting_cap_triangles = [&](IndexBuffer& indices, const std::array& v_offsets) { - store_triangle(indices, v_offsets[0], v_offsets[2], v_offsets[1]); - store_triangle(indices, v_offsets[0], v_offsets[3], v_offsets[2]); - }; - auto append_stem_triangles = [&](IndexBuffer& indices, const std::array& v_offsets) { - store_triangle(indices, v_offsets[0], v_offsets[1], v_offsets[4]); - store_triangle(indices, v_offsets[1], v_offsets[5], v_offsets[4]); - store_triangle(indices, v_offsets[1], v_offsets[2], v_offsets[5]); - store_triangle(indices, v_offsets[2], v_offsets[6], v_offsets[5]); - store_triangle(indices, v_offsets[2], v_offsets[3], v_offsets[6]); - store_triangle(indices, v_offsets[3], v_offsets[7], v_offsets[6]); - store_triangle(indices, v_offsets[3], v_offsets[0], v_offsets[7]); - store_triangle(indices, v_offsets[0], v_offsets[4], v_offsets[7]); - }; - auto append_ending_cap_triangles = [&](IndexBuffer& indices, const std::array& v_offsets) { - store_triangle(indices, v_offsets[4], v_offsets[6], v_offsets[7]); - store_triangle(indices, v_offsets[4], v_offsets[5], v_offsets[6]); - }; - - if (buffer.paths.empty() || prev.type != curr.type || !buffer.paths.back().matches(curr)) { - buffer.add_path(curr, ibuffer_id, indices.size(), move_id - 1); - buffer.paths.back().sub_paths.back().first.position = prev.position; - } - - Path& last_path = buffer.paths.back(); - bool is_first_segment = (last_path.vertices_count() == 1); - //BBS: has modified a lot for this function to support arc move - std::array first_seg_v_offsets = convert_vertices_offset(vbuffer_size, { 0, 1, 2, 3, 4, 5, 6, 7 }); - std::array non_first_seg_v_offsets = convert_vertices_offset(vbuffer_size, { -4, 0, -2, 1, 2, 3, 4, 5 }); - - size_t loop_num = curr.is_arc_move_with_interpolation_points() ? curr.interpolation_points.size() : 0; - for (size_t i = 0; i < loop_num + 1; i++) { - const Vec3f &prev_position = (i == 0? prev.position : curr.interpolation_points[i-1]); - const Vec3f &curr_position = (i == loop_num? curr.position : curr.interpolation_points[i]); - - const Vec3f dir = (curr_position - prev_position).normalized(); - const Vec3f right = Vec3f(dir.y(), -dir.x(), 0.0f).normalized(); - const Vec3f up = right.cross(dir); - const float sq_length = (curr_position - prev_position).squaredNorm(); - - if ((is_first_segment || vbuffer_size == 0) && i == 0) { - if (is_first_segment && i == 0) - // starting cap triangles - append_starting_cap_triangles(indices, first_seg_v_offsets); - // dummy triangles outer corner cap - append_dummy_cap(indices, vbuffer_size); - // stem triangles - append_stem_triangles(indices, first_seg_v_offsets); - - vbuffer_size += 8; - } else { - float displacement = 0.0f; - float cos_dir = prev_dir.dot(dir); - if (cos_dir > -0.9998477f) { - // if the angle between adjacent segments is smaller than 179 degrees - const Vec3f med_dir = (prev_dir + dir).normalized(); - const float half_width = 0.5f * last_path.width; - displacement = half_width * ::tan(::acos(std::clamp(dir.dot(med_dir), -1.0f, 1.0f))); - } - - float sq_displacement = sqr(displacement); - bool can_displace = displacement > 0.0f && sq_displacement < sq_prev_length&& sq_displacement < sq_length; - - bool is_right_turn = prev_up.dot(prev_dir.cross(dir)) <= 0.0f; - // whether the angle between adjacent segments is greater than 45 degrees - bool is_sharp = cos_dir < 0.7071068f; - - bool right_displaced = false; - bool left_displaced = false; - - if (!is_sharp && can_displace) { - if (is_right_turn) - left_displaced = true; - else - right_displaced = true; - } - - // triangles outer corner cap - if (is_right_turn) { - if (left_displaced) - // dummy triangles - append_dummy_cap(indices, vbuffer_size); - else { - store_triangle(indices, vbuffer_size - 4, vbuffer_size + 1, vbuffer_size - 1); - store_triangle(indices, vbuffer_size + 1, vbuffer_size - 2, vbuffer_size - 1); - } - } - else { - if (right_displaced) - // dummy triangles - append_dummy_cap(indices, vbuffer_size); - else { - store_triangle(indices, vbuffer_size - 4, vbuffer_size - 3, vbuffer_size + 0); - store_triangle(indices, vbuffer_size - 3, vbuffer_size - 2, vbuffer_size + 0); - } - } - // stem triangles - non_first_seg_v_offsets = convert_vertices_offset(vbuffer_size, { -4, 0, -2, 1, 2, 3, 4, 5 }); - append_stem_triangles(indices, non_first_seg_v_offsets); - vbuffer_size += 6; - } - prev_dir = dir; - prev_up = up; - sq_prev_length = sq_length; - } - - if (next != nullptr && (curr.type != next->type || !last_path.matches(*next))) - // ending cap triangles - append_ending_cap_triangles(indices, (is_first_segment && !curr.is_arc_move_with_interpolation_points()) ? first_seg_v_offsets : non_first_seg_v_offsets); - - last_path.sub_paths.back().last = { ibuffer_id, indices.size() - 1, move_id, curr.position }; - }; - - // format data into the buffers to be rendered as instanced model - auto add_model_instance = [](const GCodeProcessorResult::MoveVertex& curr, InstanceBuffer& instances, InstanceIdBuffer& instances_ids, size_t move_id) { - // append position - instances.push_back(curr.position.x()); - instances.push_back(curr.position.y()); - instances.push_back(curr.position.z()); - // append width - instances.push_back(curr.width); - // append height - instances.push_back(curr.height); - - // append id - instances_ids.push_back(move_id); - }; - - // format data into the buffers to be rendered as batched model - auto add_vertices_as_model_batch = [](const GCodeProcessorResult::MoveVertex& curr, const GLModel::Geometry& data, VertexBuffer& vertices, InstanceBuffer& instances, InstanceIdBuffer& instances_ids, size_t move_id) { - const double width = static_cast(1.5f * curr.width); - const double height = static_cast(1.5f * curr.height); - - const Transform3d trafo = Geometry::assemble_transform((curr.position - 0.5f * curr.height * Vec3f::UnitZ()).cast(), Vec3d::Zero(), { width, width, height }); - const Eigen::Matrix normal_matrix = trafo.matrix().template block<3, 3>(0, 0).inverse().transpose(); - - // append vertices - const size_t vertices_count = data.vertices_count(); - for (size_t i = 0; i < vertices_count; ++i) { - // append position - const Vec3d position = trafo * data.extract_position_3(i).cast(); - vertices.push_back(float(position.x())); - vertices.push_back(float(position.y())); - vertices.push_back(float(position.z())); - - // append normal - const Vec3d normal = normal_matrix * data.extract_normal_3(i).cast(); - vertices.push_back(float(normal.x())); - vertices.push_back(float(normal.y())); - vertices.push_back(float(normal.z())); - } - - // append instance position - instances.push_back(curr.position.x()); - instances.push_back(curr.position.y()); - instances.push_back(curr.position.z()); - // append instance id - instances_ids.push_back(move_id); - }; - - auto add_indices_as_model_batch = [](const GLModel::Geometry& data, IndexBuffer& indices, IBufferType base_index) { - const size_t indices_count = data.indices_count(); - for (size_t i = 0; i < indices_count; ++i) { - indices.push_back(static_cast(data.extract_index(i) + base_index)); - } - }; - -#if ENABLE_GCODE_VIEWER_STATISTICS - auto start_time = std::chrono::high_resolution_clock::now(); - m_statistics.results_size = SLIC3R_STDVEC_MEMSIZE(gcode_result.moves, GCodeProcessorResult::MoveVertex); - m_statistics.results_time = gcode_result.time; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - m_moves_count = gcode_result.moves.size(); - if (m_moves_count == 0) - return; - - m_extruders_count = gcode_result.filaments_count; - - unsigned int progress_count = 0; - static const unsigned int progress_threshold = 1000; - //BBS: add only gcode mode - ProgressDialog * progress_dialog = m_only_gcode_in_preview ? - new ProgressDialog(_L("Loading G-code"), "...", - 100, wxGetApp().mainframe, wxPD_AUTO_HIDE | wxPD_APP_MODAL) : nullptr; - - wxBusyCursor busy; - - //BBS: use convex_hull for toolpath outside check - Points pts; - - // extract approximate paths bounding box from result - //BBS: add only gcode mode - for (const GCodeProcessorResult::MoveVertex& move : gcode_result.moves) { - //if (wxGetApp().is_gcode_viewer()) { - //if (m_only_gcode_in_preview) { - // for the gcode viewer we need to take in account all moves to correctly size the printbed - // m_paths_bounding_box.merge(move.position.cast()); - //} - //else { - if (move.type == EMoveType::Extrude && move.extrusion_role != erCustom && move.width != 0.0f && move.height != 0.0f) { - m_paths_bounding_box.merge(move.position.cast()); - //BBS: use convex_hull for toolpath outside check - pts.emplace_back(Point(scale_(move.position.x()), scale_(move.position.y()))); - } - //} - } - - // BBS: also merge the point on arc to bounding box - for (const GCodeProcessorResult::MoveVertex& move : gcode_result.moves) { - // continue if not arc path - if (!move.is_arc_move_with_interpolation_points()) - continue; - - //if (wxGetApp().is_gcode_viewer()) - //if (m_only_gcode_in_preview) - // for (int i = 0; i < move.interpolation_points.size(); i++) - // m_paths_bounding_box.merge(move.interpolation_points[i].cast()); - //else { - if (move.type == EMoveType::Extrude && move.width != 0.0f && move.height != 0.0f) - for (int i = 0; i < move.interpolation_points.size(); i++) { - m_paths_bounding_box.merge(move.interpolation_points[i].cast()); - //BBS: use convex_hull for toolpath outside check - pts.emplace_back(Point(scale_(move.interpolation_points[i].x()), scale_(move.interpolation_points[i].y()))); - } - //} - } - - // set approximate max bounding box (take in account also the tool marker) - m_max_bounding_box = m_paths_bounding_box; - m_max_bounding_box.merge(m_paths_bounding_box.max + m_sequential_view.marker.get_bounding_box().size().z() * Vec3d::UnitZ()); - - BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(",m_paths_bounding_box {%1%, %2%}-{%3%, %4%}\n") - %m_paths_bounding_box.min.x() %m_paths_bounding_box.min.y() %m_paths_bounding_box.max.x() %m_paths_bounding_box.max.y(); - - //if (wxGetApp().is_editor()) - { - //BBS: use convex_hull for toolpath outside check - m_contained_in_bed = build_volume.all_paths_inside(gcode_result, m_paths_bounding_box); - if (m_contained_in_bed) { - //PartPlateList& partplate_list = wxGetApp().plater()->get_partplate_list(); - //PartPlate* plate = partplate_list.get_curr_plate(); - //const std::vector& exclude_bounding_box = plate->get_exclude_areas(); - if (exclude_bounding_box.size() > 0) - { - int index; - Slic3r::Polygon convex_hull_2d = Slic3r::Geometry::convex_hull(std::move(pts)); - for (index = 0; index < exclude_bounding_box.size(); index ++) - { - Slic3r::Polygon p = exclude_bounding_box[index].polygon(true); // instance convex hull is scaled, so we need to scale here - if (intersection({ p }, { convex_hull_2d }).empty() == false) - { - m_contained_in_bed = false; - break; - } - } - } - } - (const_cast(gcode_result)).toolpath_outside = !m_contained_in_bed; - } - - m_sequential_view.gcode_ids.clear(); - for (size_t i = 0; i < gcode_result.moves.size(); ++i) { - const GCodeProcessorResult::MoveVertex& move = gcode_result.moves[i]; - if (move.type != EMoveType::Seam) - m_sequential_view.gcode_ids.push_back(move.gcode_id); - } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(",m_contained_in_bed %1%\n")%m_contained_in_bed; - - std::vector vertices(m_buffers.size()); - std::vector indices(m_buffers.size()); - std::vector instances(m_buffers.size()); - std::vector instances_ids(m_buffers.size()); - std::vector instances_offsets(m_buffers.size()); - std::vector options_zs; - - size_t seams_count = 0; - std::vector biased_seams_ids; - - // toolpaths data -> extract vertices from result - for (size_t i = 0; i < m_moves_count; ++i) { - const GCodeProcessorResult::MoveVertex& curr = gcode_result.moves[i]; - if (curr.type == EMoveType::Seam) { - ++seams_count; - biased_seams_ids.push_back(i - biased_seams_ids.size() - 1); - } - - size_t move_id = i - seams_count; - - // skip first vertex - if (i == 0) - continue; - - const GCodeProcessorResult::MoveVertex& prev = gcode_result.moves[i - 1]; - - // update progress dialog - ++progress_count; - if (progress_dialog != nullptr && progress_count % progress_threshold == 0) { - progress_dialog->Update(int(100.0f * float(i) / (2.0f * float(m_moves_count))), - _L("Generating geometry vertex data") + ": " + wxNumberFormatter::ToString(100.0 * double(i) / double(m_moves_count), 0, wxNumberFormatter::Style_None) + "%"); - progress_dialog->Fit(); - progress_count = 0; - } - - const unsigned char id = buffer_id(curr.type); - TBuffer& t_buffer = m_buffers[id]; - MultiVertexBuffer& v_multibuffer = vertices[id]; - InstanceBuffer& inst_buffer = instances[id]; - InstanceIdBuffer& inst_id_buffer = instances_ids[id]; - InstancesOffsets& inst_offsets = instances_offsets[id]; - - /*if (i%1000 == 1) { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":i=%1%, buffer_id %2% render_type %3%, gcode_id %4%\n") - %i %(int)id %(int)t_buffer.render_primitive_type %curr.gcode_id; - }*/ - - // ensure there is at least one vertex buffer - if (v_multibuffer.empty()) - v_multibuffer.push_back(VertexBuffer()); - - // if adding the vertices for the current segment exceeds the threshold size of the current vertex buffer - // add another vertex buffer - // BBS: get the point number and then judge whether the remaining buffer is enough - size_t points_num = curr.is_arc_move_with_interpolation_points() ? curr.interpolation_points.size() + 1 : 1; - size_t vertices_size_to_add = (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) ? t_buffer.model.data.vertices_size_bytes() : points_num * t_buffer.max_vertices_per_segment_size_bytes(); - if (v_multibuffer.back().size() * sizeof(float) > t_buffer.vertices.max_size_bytes() - vertices_size_to_add) { - v_multibuffer.push_back(VertexBuffer()); - if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) { - Path& last_path = t_buffer.paths.back(); - if (prev.type == curr.type && last_path.matches(curr)) - last_path.add_sub_path(prev, static_cast(v_multibuffer.size()) - 1, 0, move_id - 1); - } - } - - VertexBuffer& v_buffer = v_multibuffer.back(); - - switch (t_buffer.render_primitive_type) - { - case TBuffer::ERenderPrimitiveType::Line: { add_vertices_as_line(prev, curr, v_buffer); break; } - case TBuffer::ERenderPrimitiveType::Triangle: { add_vertices_as_solid(prev, curr, t_buffer, static_cast(v_multibuffer.size()) - 1, v_buffer, move_id); break; } - case TBuffer::ERenderPrimitiveType::InstancedModel: - { - add_model_instance(curr, inst_buffer, inst_id_buffer, move_id); - inst_offsets.push_back(prev.position - curr.position); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.instances_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - break; - } - case TBuffer::ERenderPrimitiveType::BatchedModel: - { - add_vertices_as_model_batch(curr, t_buffer.model.data, v_buffer, inst_buffer, inst_id_buffer, move_id); - inst_offsets.push_back(prev.position - curr.position); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.batched_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - break; - } - } - - // collect options zs for later use - if (curr.type == EMoveType::Pause_Print || curr.type == EMoveType::Custom_GCode) { - const float* const last_z = options_zs.empty() ? nullptr : &options_zs.back(); - if (last_z == nullptr || curr.position[2] < *last_z - EPSILON || *last_z + EPSILON < curr.position[2]) - options_zs.emplace_back(curr.position[2]); - } - } - - /*for (size_t b = 0; b < vertices.size(); ++b) { - MultiVertexBuffer& v_multibuffer = vertices[b]; - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":b=%1%, vertex buffer count %2%\n") - %b %v_multibuffer.size(); - }*/ - auto extract_move_id = [&biased_seams_ids](size_t id) { - size_t new_id = size_t(-1); - auto it = std::lower_bound(biased_seams_ids.begin(), biased_seams_ids.end(), id); - if (it == biased_seams_ids.end()) - new_id = id + biased_seams_ids.size(); - else { - if (it == biased_seams_ids.begin() && *it < id) - new_id = id; - else if (it != biased_seams_ids.begin()) - new_id = id + std::distance(biased_seams_ids.begin(), it); - } - return (new_id == size_t(-1)) ? id : new_id; - }; - //BBS: generate map from ssid to move id in advance to reduce computation - m_ssid_to_moveid_map.clear(); - m_ssid_to_moveid_map.reserve( m_moves_count - biased_seams_ids.size()); - for (size_t i = 0; i < m_moves_count - biased_seams_ids.size(); i++) - m_ssid_to_moveid_map.push_back(extract_move_id(i)); - - //BBS: smooth toolpaths corners for the given TBuffer using triangles - auto smooth_triangle_toolpaths_corners = [&gcode_result, this](const TBuffer& t_buffer, MultiVertexBuffer& v_multibuffer) { - auto extract_position_at = [](const VertexBuffer& vertices, size_t offset) { - return Vec3f(vertices[offset + 0], vertices[offset + 1], vertices[offset + 2]); - }; - auto update_position_at = [](VertexBuffer& vertices, size_t offset, const Vec3f& position) { - vertices[offset + 0] = position.x(); - vertices[offset + 1] = position.y(); - vertices[offset + 2] = position.z(); - }; - auto match_right_vertices_with_internal_point = [&](const Path::Sub_Path& prev_sub_path, const Path::Sub_Path& next_sub_path, - size_t curr_s_id, bool is_internal_point, size_t interpolation_point_id, size_t vertex_size_floats, const Vec3f& displacement_vec) { - if (&prev_sub_path == &next_sub_path || is_internal_point) { // previous and next segment are both contained into to the same vertex buffer - VertexBuffer& vbuffer = v_multibuffer[prev_sub_path.first.b_id]; - // offset into the vertex buffer of the next segment 1st vertex - size_t temp_offset = prev_sub_path.last.s_id - curr_s_id; - for (size_t i = prev_sub_path.last.s_id; i > curr_s_id; i--) { - size_t move_id = m_ssid_to_moveid_map[i]; - temp_offset += (gcode_result.moves[move_id].is_arc_move() ? gcode_result.moves[move_id].interpolation_points.size() : 0); - } - if (is_internal_point) { - size_t move_id = m_ssid_to_moveid_map[curr_s_id]; - temp_offset += (gcode_result.moves[move_id].interpolation_points.size() - interpolation_point_id); - } - const size_t next_1st_offset = temp_offset * 6 * vertex_size_floats; - // offset into the vertex buffer of the right vertex of the previous segment - const size_t prev_right_offset = prev_sub_path.last.i_id - next_1st_offset - 3 * vertex_size_floats; - // new position of the right vertices - const Vec3f shared_vertex = extract_position_at(vbuffer, prev_right_offset) + displacement_vec; - // update previous segment - update_position_at(vbuffer, prev_right_offset, shared_vertex); - // offset into the vertex buffer of the right vertex of the next segment - const size_t next_right_offset = prev_sub_path.last.i_id - next_1st_offset; - // update next segment - update_position_at(vbuffer, next_right_offset, shared_vertex); - } - else { // previous and next segment are contained into different vertex buffers - VertexBuffer& prev_vbuffer = v_multibuffer[prev_sub_path.first.b_id]; - VertexBuffer& next_vbuffer = v_multibuffer[next_sub_path.first.b_id]; - // offset into the previous vertex buffer of the right vertex of the previous segment - const size_t prev_right_offset = prev_sub_path.last.i_id - 3 * vertex_size_floats; - // new position of the right vertices - const Vec3f shared_vertex = extract_position_at(prev_vbuffer, prev_right_offset) + displacement_vec; - // update previous segment - update_position_at(prev_vbuffer, prev_right_offset, shared_vertex); - // offset into the next vertex buffer of the right vertex of the next segment - const size_t next_right_offset = next_sub_path.first.i_id + 1 * vertex_size_floats; - // update next segment - update_position_at(next_vbuffer, next_right_offset, shared_vertex); - } - }; - //BBS: modify a lot of this function to support arc move - auto match_left_vertices_with_internal_point = [&](const Path::Sub_Path& prev_sub_path, const Path::Sub_Path& next_sub_path, - size_t curr_s_id, bool is_internal_point, size_t interpolation_point_id, size_t vertex_size_floats, const Vec3f& displacement_vec) { - if (&prev_sub_path == &next_sub_path || is_internal_point) { // previous and next segment are both contained into to the same vertex buffer - VertexBuffer& vbuffer = v_multibuffer[prev_sub_path.first.b_id]; - // offset into the vertex buffer of the next segment 1st vertex - size_t temp_offset = prev_sub_path.last.s_id - curr_s_id; - for (size_t i = prev_sub_path.last.s_id; i > curr_s_id; i--) { - size_t move_id = m_ssid_to_moveid_map[i]; - temp_offset += (gcode_result.moves[move_id].is_arc_move() ? gcode_result.moves[move_id].interpolation_points.size() : 0); - } - if (is_internal_point) { - size_t move_id = m_ssid_to_moveid_map[curr_s_id]; - temp_offset += (gcode_result.moves[move_id].interpolation_points.size() - interpolation_point_id); - } - const size_t next_1st_offset = temp_offset * 6 * vertex_size_floats; - // offset into the vertex buffer of the left vertex of the previous segment - const size_t prev_left_offset = prev_sub_path.last.i_id - next_1st_offset - 1 * vertex_size_floats; - // new position of the left vertices - const Vec3f shared_vertex = extract_position_at(vbuffer, prev_left_offset) + displacement_vec; - // update previous segment - update_position_at(vbuffer, prev_left_offset, shared_vertex); - // offset into the vertex buffer of the left vertex of the next segment - const size_t next_left_offset = prev_sub_path.last.i_id - next_1st_offset + 1 * vertex_size_floats; - // update next segment - update_position_at(vbuffer, next_left_offset, shared_vertex); - } - else { // previous and next segment are contained into different vertex buffers - VertexBuffer& prev_vbuffer = v_multibuffer[prev_sub_path.first.b_id]; - VertexBuffer& next_vbuffer = v_multibuffer[next_sub_path.first.b_id]; - // offset into the previous vertex buffer of the left vertex of the previous segment - const size_t prev_left_offset = prev_sub_path.last.i_id - 1 * vertex_size_floats; - // new position of the left vertices - const Vec3f shared_vertex = extract_position_at(prev_vbuffer, prev_left_offset) + displacement_vec; - // update previous segment - update_position_at(prev_vbuffer, prev_left_offset, shared_vertex); - // offset into the next vertex buffer of the left vertex of the next segment - const size_t next_left_offset = next_sub_path.first.i_id + 3 * vertex_size_floats; - // update next segment - update_position_at(next_vbuffer, next_left_offset, shared_vertex); - } - }; - - size_t vertex_size_floats = t_buffer.vertices.vertex_size_floats(); - for (const Path& path : t_buffer.paths) { - //BBS: the two segments of the path sharing the current vertex may belong - //to two different vertex buffers - size_t prev_sub_path_id = 0; - size_t next_sub_path_id = 0; - const size_t path_vertices_count = path.vertices_count(); - const float half_width = 0.5f * path.width; - // BBS: modify a lot to support arc move which has internal points - for (size_t j = 1; j < path_vertices_count; ++j) { - size_t curr_s_id = path.sub_paths.front().first.s_id + j; - size_t move_id = m_ssid_to_moveid_map[curr_s_id]; - int interpolation_points_num = gcode_result.moves[move_id].is_arc_move_with_interpolation_points()? - gcode_result.moves[move_id].interpolation_points.size() : 0; - int loop_num = interpolation_points_num; - //BBS: select the subpaths which contains the previous/next segments - if (!path.sub_paths[prev_sub_path_id].contains(curr_s_id)) - ++prev_sub_path_id; - if (j == path_vertices_count - 1) { - if (!gcode_result.moves[move_id].is_arc_move_with_interpolation_points()) - break; // BBS: the last move has no internal point. - loop_num--; //BBS: don't need to handle the endpoint of the last arc move of path - next_sub_path_id = prev_sub_path_id; - } else { - if (!path.sub_paths[next_sub_path_id].contains(curr_s_id + 1)) - ++next_sub_path_id; - } - const Path::Sub_Path& prev_sub_path = path.sub_paths[prev_sub_path_id]; - const Path::Sub_Path& next_sub_path = path.sub_paths[next_sub_path_id]; - - // BBS: smooth triangle toolpaths corners including arc move which has internal interpolation point - for (int k = 0; k <= loop_num; k++) { - const Vec3f& prev = k==0? - gcode_result.moves[move_id - 1].position : - gcode_result.moves[move_id].interpolation_points[k-1]; - const Vec3f& curr = k==interpolation_points_num? - gcode_result.moves[move_id].position : - gcode_result.moves[move_id].interpolation_points[k]; - const Vec3f& next = k < interpolation_points_num - 1? - gcode_result.moves[move_id].interpolation_points[k+1]: - (k == interpolation_points_num - 1? gcode_result.moves[move_id].position : - (gcode_result.moves[move_id + 1].is_arc_move_with_interpolation_points()? - gcode_result.moves[move_id + 1].interpolation_points[0] : - gcode_result.moves[move_id + 1].position)); - - const Vec3f prev_dir = (curr - prev).normalized(); - const Vec3f prev_right = Vec3f(prev_dir.y(), -prev_dir.x(), 0.0f).normalized(); - const Vec3f prev_up = prev_right.cross(prev_dir); - - const Vec3f next_dir = (next - curr).normalized(); - - const bool is_right_turn = prev_up.dot(prev_dir.cross(next_dir)) <= 0.0f; - const float cos_dir = prev_dir.dot(next_dir); - // whether the angle between adjacent segments is greater than 45 degrees - const bool is_sharp = cos_dir < 0.7071068f; - - float displacement = 0.0f; - if (cos_dir > -0.9998477f) { - // if the angle between adjacent segments is smaller than 179 degrees - Vec3f med_dir = (prev_dir + next_dir).normalized(); - displacement = half_width * ::tan(::acos(std::clamp(next_dir.dot(med_dir), -1.0f, 1.0f))); - } - - const float sq_prev_length = (curr - prev).squaredNorm(); - const float sq_next_length = (next - curr).squaredNorm(); - const float sq_displacement = sqr(displacement); - const bool can_displace = displacement > 0.0f && sq_displacement < sq_prev_length&& sq_displacement < sq_next_length; - bool is_internal_point = interpolation_points_num > k; - - if (can_displace) { - // displacement to apply to the vertices to match - Vec3f displacement_vec = displacement * prev_dir; - // matches inner corner vertices - if (is_right_turn) - match_right_vertices_with_internal_point(prev_sub_path, next_sub_path, curr_s_id, is_internal_point, k, vertex_size_floats, -displacement_vec); - else - match_left_vertices_with_internal_point(prev_sub_path, next_sub_path, curr_s_id, is_internal_point, k, vertex_size_floats, -displacement_vec); - - if (!is_sharp) { - //BBS: matches outer corner vertices - if (is_right_turn) - match_left_vertices_with_internal_point(prev_sub_path, next_sub_path, curr_s_id, is_internal_point, k, vertex_size_floats, displacement_vec); - else - match_right_vertices_with_internal_point(prev_sub_path, next_sub_path, curr_s_id, is_internal_point, k, vertex_size_floats, displacement_vec); - } - } - } - } - } - }; - -#if ENABLE_GCODE_VIEWER_STATISTICS - auto load_vertices_time = std::chrono::high_resolution_clock::now(); - m_statistics.load_vertices = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - // smooth toolpaths corners for TBuffers using triangles - for (size_t i = 0; i < m_buffers.size(); ++i) { - const TBuffer& t_buffer = m_buffers[i]; - if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) { - smooth_triangle_toolpaths_corners(t_buffer, vertices[i]); - } - } - - // dismiss, no more needed - std::vector().swap(biased_seams_ids); - - for (MultiVertexBuffer& v_multibuffer : vertices) { - for (VertexBuffer& v_buffer : v_multibuffer) { - v_buffer.shrink_to_fit(); - } - } - - // move the wipe toolpaths half height up to render them on proper position - MultiVertexBuffer& wipe_vertices = vertices[buffer_id(EMoveType::Wipe)]; - for (VertexBuffer& v_buffer : wipe_vertices) { - for (size_t i = 2; i < v_buffer.size(); i += 3) { - v_buffer[i] += 0.5f * GCodeProcessor::Wipe_Height; - } - } - - // send vertices data to gpu, where needed - for (size_t i = 0; i < m_buffers.size(); ++i) { - TBuffer& t_buffer = m_buffers[i]; - if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel) { - const InstanceBuffer& inst_buffer = instances[i]; - if (!inst_buffer.empty()) { - t_buffer.model.instances.buffer = inst_buffer; - t_buffer.model.instances.s_ids = instances_ids[i]; - t_buffer.model.instances.offsets = instances_offsets[i]; - } - } - else { - if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) { - const InstanceBuffer& inst_buffer = instances[i]; - if (!inst_buffer.empty()) { - t_buffer.model.instances.buffer = inst_buffer; - t_buffer.model.instances.s_ids = instances_ids[i]; - t_buffer.model.instances.offsets = instances_offsets[i]; - } - } - const MultiVertexBuffer& v_multibuffer = vertices[i]; - for (const VertexBuffer& v_buffer : v_multibuffer) { - const size_t size_elements = v_buffer.size(); - const size_t size_bytes = size_elements * sizeof(float); - const size_t vertices_count = size_elements / t_buffer.vertices.vertex_size_floats(); - t_buffer.vertices.count += vertices_count; - -#if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.total_vertices_gpu_size += static_cast(size_bytes); - m_statistics.max_vbuffer_gpu_size = std::max(m_statistics.max_vbuffer_gpu_size, static_cast(size_bytes)); - ++m_statistics.vbuffers_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - GLuint id = 0; - glsafe(::glGenBuffers(1, &id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, id)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, size_bytes, v_buffer.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - - t_buffer.vertices.vbos.push_back(static_cast(id)); - t_buffer.vertices.sizes.push_back(size_bytes); - } - } - } - -#if ENABLE_GCODE_VIEWER_STATISTICS - auto smooth_vertices_time = std::chrono::high_resolution_clock::now(); - m_statistics.smooth_vertices = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - load_vertices_time).count(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - log_memory_usage("Loaded G-code generated vertex buffers ", vertices, indices); - - // dismiss vertices data, no more needed - std::vector().swap(vertices); - std::vector().swap(instances); - std::vector().swap(instances_ids); - - // toolpaths data -> extract indices from result - // paths may have been filled while extracting vertices, - // so reset them, they will be filled again while extracting indices - for (TBuffer& buffer : m_buffers) { - buffer.paths.clear(); - } - - // variable used to keep track of the current vertex buffers index and size - using CurrVertexBuffer = std::pair; - std::vector curr_vertex_buffers(m_buffers.size(), { 0, 0 }); - - // variable used to keep track of the vertex buffers ids - using VboIndexList = std::vector; - std::vector vbo_indices(m_buffers.size()); - - seams_count = 0; - - for (size_t i = 0; i < m_moves_count; ++i) { - const GCodeProcessorResult::MoveVertex& curr = gcode_result.moves[i]; - if (curr.type == EMoveType::Seam) - ++seams_count; - - size_t move_id = i - seams_count; - - // skip first vertex - if (i == 0) - continue; - - const GCodeProcessorResult::MoveVertex& prev = gcode_result.moves[i - 1]; - const GCodeProcessorResult::MoveVertex* next = nullptr; - if (i < m_moves_count - 1) - next = &gcode_result.moves[i + 1]; - - ++progress_count; - if (progress_dialog != nullptr && progress_count % progress_threshold == 0) { - progress_dialog->Update(int(100.0f * float(m_moves_count + i) / (2.0f * float(m_moves_count))), - _L("Generating geometry index data") + ": " + wxNumberFormatter::ToString(100.0 * double(i) / double(m_moves_count), 0, wxNumberFormatter::Style_None) + "%"); - progress_dialog->Fit(); - progress_count = 0; - } - - const unsigned char id = buffer_id(curr.type); - TBuffer& t_buffer = m_buffers[id]; - MultiIndexBuffer& i_multibuffer = indices[id]; - CurrVertexBuffer& curr_vertex_buffer = curr_vertex_buffers[id]; - VboIndexList& vbo_index_list = vbo_indices[id]; - - // ensure there is at least one index buffer - if (i_multibuffer.empty()) { - i_multibuffer.push_back(IndexBuffer()); - if (!t_buffer.vertices.vbos.empty()) - vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]); - } - - // if adding the indices for the current segment exceeds the threshold size of the current index buffer - // create another index buffer - // BBS: get the point number and then judge whether the remaining buffer is enough - size_t points_num = curr.is_arc_move_with_interpolation_points() ? curr.interpolation_points.size() + 1 : 1; - size_t indiced_size_to_add = (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) ? t_buffer.model.data.indices_size_bytes() : points_num * t_buffer.max_indices_per_segment_size_bytes(); - if (i_multibuffer.back().size() * sizeof(IBufferType) >= IBUFFER_THRESHOLD_BYTES - indiced_size_to_add) { - i_multibuffer.push_back(IndexBuffer()); - vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]); - if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) { - Path& last_path = t_buffer.paths.back(); - last_path.add_sub_path(prev, static_cast(i_multibuffer.size()) - 1, 0, move_id - 1); - } - } - - // if adding the vertices for the current segment exceeds the threshold size of the current vertex buffer - // create another index buffer - // BBS: support multi points in one MoveVertice, should multiply point number - size_t vertices_size_to_add = (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) ? t_buffer.model.data.vertices_size_bytes() : points_num * t_buffer.max_vertices_per_segment_size_bytes(); - if (curr_vertex_buffer.second * t_buffer.vertices.vertex_size_bytes() > t_buffer.vertices.max_size_bytes() - vertices_size_to_add) { - i_multibuffer.push_back(IndexBuffer()); - - ++curr_vertex_buffer.first; - curr_vertex_buffer.second = 0; - vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]); - - if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) { - Path& last_path = t_buffer.paths.back(); - last_path.add_sub_path(prev, static_cast(i_multibuffer.size()) - 1, 0, move_id - 1); - } - } - - IndexBuffer& i_buffer = i_multibuffer.back(); - - switch (t_buffer.render_primitive_type) - { - case TBuffer::ERenderPrimitiveType::Line: { - add_indices_as_line(prev, curr, t_buffer, curr_vertex_buffer.second, static_cast(i_multibuffer.size()) - 1, i_buffer, move_id); - break; - } - case TBuffer::ERenderPrimitiveType::Triangle: { - add_indices_as_solid(prev, curr, next, t_buffer, curr_vertex_buffer.second, static_cast(i_multibuffer.size()) - 1, i_buffer, move_id); - break; - } - case TBuffer::ERenderPrimitiveType::BatchedModel: { - add_indices_as_model_batch(t_buffer.model.data, i_buffer, curr_vertex_buffer.second); - curr_vertex_buffer.second += t_buffer.model.data.vertices_count(); - break; - } - default: { break; } - } - } - - for (MultiIndexBuffer& i_multibuffer : indices) { - for (IndexBuffer& i_buffer : i_multibuffer) { - i_buffer.shrink_to_fit(); - } - } - - // toolpaths data -> send indices data to gpu - for (size_t i = 0; i < m_buffers.size(); ++i) { - TBuffer& t_buffer = m_buffers[i]; - if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::InstancedModel) { - const MultiIndexBuffer& i_multibuffer = indices[i]; - for (const IndexBuffer& i_buffer : i_multibuffer) { - const size_t size_elements = i_buffer.size(); - const size_t size_bytes = size_elements * sizeof(IBufferType); - - // stores index buffer informations into TBuffer - t_buffer.indices.push_back(IBuffer()); - IBuffer& ibuf = t_buffer.indices.back(); - ibuf.count = size_elements; - ibuf.vbo = vbo_indices[i][t_buffer.indices.size() - 1]; - -#if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.total_indices_gpu_size += static_cast(size_bytes); - m_statistics.max_ibuffer_gpu_size = std::max(m_statistics.max_ibuffer_gpu_size, static_cast(size_bytes)); - ++m_statistics.ibuffers_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - glsafe(::glGenBuffers(1, &ibuf.ibo)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf.ibo)); - glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, size_bytes, i_buffer.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - } - } - } - - if (progress_dialog != nullptr) { - progress_dialog->Update(100, ""); - progress_dialog->Fit(); - } - -#if ENABLE_GCODE_VIEWER_STATISTICS - for (const TBuffer& buffer : m_buffers) { - m_statistics.paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path); - } - - auto update_segments_count = [&](EMoveType type, int64_t& count) { - unsigned int id = buffer_id(type); - const MultiIndexBuffer& buffers = indices[id]; - int64_t indices_count = 0; - for (const IndexBuffer& buffer : buffers) { - indices_count += buffer.size(); - } - const TBuffer& t_buffer = m_buffers[id]; - if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) - indices_count -= static_cast(12 * t_buffer.paths.size()); // remove the starting + ending caps = 4 triangles - - count += indices_count / t_buffer.indices_per_segment(); - }; - - update_segments_count(EMoveType::Travel, m_statistics.travel_segments_count); - update_segments_count(EMoveType::Wipe, m_statistics.wipe_segments_count); - update_segments_count(EMoveType::Extrude, m_statistics.extrude_segments_count); - - m_statistics.load_indices = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - smooth_vertices_time).count(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - log_memory_usage("Loaded G-code generated indices buffers ", vertices, indices); - - // dismiss indices data, no more needed - std::vector().swap(indices); - - // layers zs / roles / extruder ids -> extract from result - size_t last_travel_s_id = 0; - seams_count = 0; - m_extruder_ids.clear(); - for (size_t i = 0; i < m_moves_count; ++i) { - const GCodeProcessorResult::MoveVertex& move = gcode_result.moves[i]; - if (move.type == EMoveType::Seam) - ++seams_count; - - size_t move_id = i - seams_count; - - if (move.type == EMoveType::Extrude) { - // layers zs - const double* const last_z = m_layers.empty() ? nullptr : &m_layers.get_zs().back(); - const double z = static_cast(move.position.z()); - if (last_z == nullptr || z < *last_z - EPSILON || *last_z + EPSILON < z) - m_layers.append(z, { last_travel_s_id, move_id }); - else - m_layers.get_endpoints().back().last = move_id; - // extruder ids - m_extruder_ids.emplace_back(move.extruder_id); - // roles - if (i > 0) - m_roles.emplace_back(move.extrusion_role); - } - else if (move.type == EMoveType::Travel) { - if (move_id - last_travel_s_id > 1 && !m_layers.empty()) - m_layers.get_endpoints().back().last = move_id; - - last_travel_s_id = move_id; - } - } - - // roles -> remove duplicates - sort_remove_duplicates(m_roles); - m_roles.shrink_to_fit(); - - // extruder ids -> remove duplicates - sort_remove_duplicates(m_extruder_ids); - m_extruder_ids.shrink_to_fit(); - - std::vector plater_extruder; - for (auto mid : m_extruder_ids){ - int eid = mid; - plater_extruder.push_back(++eid); - } - m_plater_extruder = plater_extruder; - - // replace layers for spiral vase mode - if (!gcode_result.spiral_vase_layers.empty()) { - m_layers.reset(); - for (const auto& layer : gcode_result.spiral_vase_layers) { - m_layers.append(layer.first, { layer.second.first, layer.second.second }); - } - } - - // set layers z range - if (!m_layers.empty()) - m_layers_z_range = { 0, static_cast(m_layers.size() - 1) }; - - // change color of paths whose layer contains option points - if (!options_zs.empty()) { - TBuffer& extrude_buffer = m_buffers[buffer_id(EMoveType::Extrude)]; - for (Path& path : extrude_buffer.paths) { - const float z = path.sub_paths.front().first.position.z(); - if (std::find_if(options_zs.begin(), options_zs.end(), [z](float f) { return f - EPSILON <= z && z <= f + EPSILON; }) != options_zs.end()) - path.cp_color_id = 255 - path.cp_color_id; - } - } - -#if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.load_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - if (progress_dialog != nullptr) - progress_dialog->Destroy(); + ToolpathsObjExporter exporter(m_viewer); + exporter.export_to(filename); } void GCodeViewer::load_shells(const Print& print, bool initialized, bool force_previewing) @@ -3246,840 +1994,175 @@ void GCodeViewer::load_shells(const Print& print, bool initialized, bool force_p % m_shells.print_id % m_shells.print_modify_count % object_count %m_shells.volumes.volumes.size(); } -void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const -{ -#if ENABLE_GCODE_VIEWER_STATISTICS - auto start_time = std::chrono::high_resolution_clock::now(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": enter, m_buffers size %1%!")%m_buffers.size(); - auto extrusion_color = [this](const Path& path) { - ColorRGBA color; - switch (m_view_type) - { - case EViewType::FeatureType: { color = Extrusion_Role_Colors[static_cast(path.role)]; break; } - case EViewType::Height: { color = m_extrusions.ranges.height.get_color_at(path.height); break; } - case EViewType::Width: { color = m_extrusions.ranges.width.get_color_at(path.width); break; } - case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; } - case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; } - case EViewType::Temperature: { color = m_extrusions.ranges.temperature.get_color_at(path.temperature); break; } - case EViewType::LayerTime: { color = m_extrusions.ranges.layer_duration.get_color_at(path.layer_time); break; } - case EViewType::LayerTimeLog: { color = m_extrusions.ranges.layer_duration_log.get_color_at(path.layer_time); break; } - case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } - case EViewType::Tool: { color = m_tools.m_tool_colors[path.extruder_id]; break; } - case EViewType::Summary: - case EViewType::ColorPrint: { - if (path.cp_color_id >= static_cast(m_tools.m_tool_colors.size())) - color = ColorRGBA::GRAY(); - else { - color = m_tools.m_tool_colors[path.cp_color_id]; - color = adjust_color_for_rendering(color); - } - break; - } - case EViewType::FilamentId: { - float id = float(path.extruder_id)/256; - float role = float(path.role) / 256; - color = {id, role, id, 1.0f}; - break; - } - default: { color = ColorRGBA::WHITE(); break; } - } - - return color; - }; - - auto travel_color = [](const Path& path) { - return (path.delta_extruder < 0.0f) ? Travel_Colors[2] /* Retract */ : - ((path.delta_extruder > 0.0f) ? Travel_Colors[1] /* Extrude */ : - Travel_Colors[0] /* Move */); - }; - - auto is_in_layers_range = [this](const Path& path, size_t min_id, size_t max_id) { - auto in_layers_range = [this, min_id, max_id](size_t id) { - return m_layers.get_endpoints_at(min_id).first <= id && id <= m_layers.get_endpoints_at(max_id).last; - }; - - return in_layers_range(path.sub_paths.front().first.s_id) && in_layers_range(path.sub_paths.back().last.s_id); - }; - - //BBS - auto is_extruder_in_layer_range = [this](const Path& path, size_t extruder_id) { - return path.extruder_id == extruder_id; - }; - - - auto is_travel_in_layers_range = [this](size_t path_id, size_t min_id, size_t max_id) { - const TBuffer& buffer = m_buffers[buffer_id(EMoveType::Travel)]; - if (path_id >= buffer.paths.size()) - return false; - - Path path = buffer.paths[path_id]; - size_t first = path_id; - size_t last = path_id; - - // check adjacent paths - while (first > 0 && path.sub_paths.front().first.position.isApprox(buffer.paths[first - 1].sub_paths.back().last.position)) { - --first; - path.sub_paths.front().first = buffer.paths[first].sub_paths.front().first; - } - while (last < buffer.paths.size() - 1 && path.sub_paths.back().last.position.isApprox(buffer.paths[last + 1].sub_paths.front().first.position)) { - ++last; - path.sub_paths.back().last = buffer.paths[last].sub_paths.back().last; - } - - const size_t min_s_id = m_layers.get_endpoints_at(min_id).first; - const size_t max_s_id = m_layers.get_endpoints_at(max_id).last; - - return (min_s_id <= path.sub_paths.front().first.s_id && path.sub_paths.front().first.s_id <= max_s_id) || - (min_s_id <= path.sub_paths.back().last.s_id && path.sub_paths.back().last.s_id <= max_s_id); - }; - -#if ENABLE_GCODE_VIEWER_STATISTICS - Statistics* statistics = const_cast(&m_statistics); - statistics->render_paths_size = 0; - statistics->models_instances_size = 0; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - const bool top_layer_only = true; - - //BBS - SequentialView::Endpoints global_endpoints = { m_sequential_view.gcode_ids.size() , 0 }; - SequentialView::Endpoints top_layer_endpoints = global_endpoints; - SequentialView* sequential_view = const_cast(&m_sequential_view); - if (top_layer_only || !keep_sequential_current_first) sequential_view->current.first = 0; - //BBS - if (!keep_sequential_current_last) sequential_view->current.last = m_sequential_view.gcode_ids.size(); - - // first pass: collect visible paths and update sequential view data - std::vector> paths; - - for (size_t b = 0; b < m_buffers.size(); ++b) { - TBuffer& buffer = const_cast(m_buffers[b]); - // reset render paths - buffer.render_paths.clear(); - - if (!buffer.visible) - continue; - - if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel || - buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) { - for (size_t id : buffer.model.instances.s_ids) { - if (id < m_layers.get_endpoints_at(m_layers_z_range[0]).first || m_layers.get_endpoints_at(m_layers_z_range[1]).last < id) - continue; - - global_endpoints.first = std::min(global_endpoints.first, id); - global_endpoints.last = std::max(global_endpoints.last, id); - - if (top_layer_only) { - if (id < m_layers.get_endpoints_at(m_layers_z_range[1]).first || m_layers.get_endpoints_at(m_layers_z_range[1]).last < id) - continue; - - top_layer_endpoints.first = std::min(top_layer_endpoints.first, id); - top_layer_endpoints.last = std::max(top_layer_endpoints.last, id); - } - } - } - else { - for (size_t i = 0; i < buffer.paths.size(); ++i) { - const Path& path = buffer.paths[i]; - if (path.type == EMoveType::Travel) { - if (!is_travel_in_layers_range(i, m_layers_z_range[0], m_layers_z_range[1])) - continue; - } - else if (!is_in_layers_range(path, m_layers_z_range[0], m_layers_z_range[1])) - continue; - - if (top_layer_only) { - if (path.type == EMoveType::Travel) { - if (is_travel_in_layers_range(i, m_layers_z_range[1], m_layers_z_range[1])) { - top_layer_endpoints.first = std::min(top_layer_endpoints.first, path.sub_paths.front().first.s_id); - top_layer_endpoints.last = std::max(top_layer_endpoints.last, path.sub_paths.back().last.s_id); - } - } - else if (is_in_layers_range(path, m_layers_z_range[1], m_layers_z_range[1])) { - top_layer_endpoints.first = std::min(top_layer_endpoints.first, path.sub_paths.front().first.s_id); - top_layer_endpoints.last = std::max(top_layer_endpoints.last, path.sub_paths.back().last.s_id); - } - } - - if (path.type == EMoveType::Extrude && !is_visible(path)) - continue; - - if (m_view_type == EViewType::ColorPrint && !m_tools.m_tool_visibles[path.extruder_id]) - continue; - - // store valid path - for (size_t j = 0; j < path.sub_paths.size(); ++j) { - paths.push_back({ static_cast(b), path.sub_paths[j].first.b_id, static_cast(i), static_cast(j) }); - } - - global_endpoints.first = std::min(global_endpoints.first, path.sub_paths.front().first.s_id); - global_endpoints.last = std::max(global_endpoints.last, path.sub_paths.back().last.s_id); - } - } - } - - // update current sequential position - sequential_view->current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(sequential_view->current.first, global_endpoints.first, global_endpoints.last) : global_endpoints.first; - if (global_endpoints.last == 0) { -m_no_render_path = true; - sequential_view->current.last = global_endpoints.last; - } else { -m_no_render_path = false; - sequential_view->current.last = keep_sequential_current_last ? std::clamp(sequential_view->current.last, global_endpoints.first, global_endpoints.last) : global_endpoints.last; - } - - // get the world position from the vertex buffer - bool found = false; - for (const TBuffer& buffer : m_buffers) { - if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel || - buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) { - for (size_t i = 0; i < buffer.model.instances.s_ids.size(); ++i) { - if (buffer.model.instances.s_ids[i] == m_sequential_view.current.last) { - size_t offset = i * buffer.model.instances.instance_size_floats(); - sequential_view->current_position.x() = buffer.model.instances.buffer[offset + 0]; - sequential_view->current_position.y() = buffer.model.instances.buffer[offset + 1]; - sequential_view->current_position.z() = buffer.model.instances.buffer[offset + 2]; - sequential_view->current_offset = buffer.model.instances.offsets[i]; - found = true; - break; - } - } - } - else { - // searches the path containing the current position - for (const Path& path : buffer.paths) { - if (path.contains(m_sequential_view.current.last)) { - const int sub_path_id = path.get_id_of_sub_path_containing(m_sequential_view.current.last); - if (sub_path_id != -1) { - const Path::Sub_Path& sub_path = path.sub_paths[sub_path_id]; - unsigned int offset = static_cast(m_sequential_view.current.last - sub_path.first.s_id); - if (offset > 0) { - if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Line) { - for (size_t i = sub_path.first.s_id + 1; i < m_sequential_view.current.last + 1; i++) { - size_t move_id = m_ssid_to_moveid_map[i]; - const GCodeProcessorResult::MoveVertex& curr = m_gcode_result->moves[move_id]; - if (curr.is_arc_move()) { - offset += curr.interpolation_points.size(); - } - } - offset = 2 * offset - 1; - } - else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) { - unsigned int indices_count = buffer.indices_per_segment(); - // BBS: modify to support moves which has internal point - for (size_t i = sub_path.first.s_id + 1; i < m_sequential_view.current.last + 1; i++) { - size_t move_id = m_ssid_to_moveid_map[i]; - const GCodeProcessorResult::MoveVertex& curr = m_gcode_result->moves[move_id]; - if (curr.is_arc_move()) { - offset += curr.interpolation_points.size(); - } - } - offset = indices_count * (offset - 1) + (indices_count - 2); - if (sub_path_id == 0) - offset += 6; // add 2 triangles for starting cap - } - } - offset += static_cast(sub_path.first.i_id); - - // gets the vertex index from the index buffer on gpu - if (sub_path.first.b_id >= 0 && sub_path.first.b_id < buffer.indices.size()) { - const IBuffer &i_buffer = buffer.indices[sub_path.first.b_id]; - unsigned int index = 0; - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); - glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast(offset * sizeof(IBufferType)), - static_cast(sizeof(IBufferType)), static_cast(&index))); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - - // gets the position from the vertices buffer on gpu - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); - glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(index * buffer.vertices.vertex_size_bytes()), - static_cast(3 * sizeof(float)), static_cast(sequential_view->current_position.data()))); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - } - sequential_view->current_offset = Vec3f::Zero(); - found = true; - break; - } - } - } - } - - if (found) - break; - } - - // second pass: filter paths by sequential data and collect them by color - RenderPath* render_path = nullptr; - for (const auto& [tbuffer_id, ibuffer_id, path_id, sub_path_id] : paths) { - TBuffer& buffer = const_cast(m_buffers[tbuffer_id]); - const Path& path = buffer.paths[path_id]; - const Path::Sub_Path& sub_path = path.sub_paths[sub_path_id]; - if (m_sequential_view.current.last < sub_path.first.s_id || sub_path.last.s_id < m_sequential_view.current.first) - continue; - - ColorRGBA color; - switch (path.type) - { - case EMoveType::Tool_change: - case EMoveType::Color_change: - case EMoveType::Pause_Print: - case EMoveType::Custom_GCode: - case EMoveType::Retract: - case EMoveType::Unretract: - case EMoveType::Seam: { color = option_color(path.type); break; } - case EMoveType::Extrude: { - if (!top_layer_only || - m_sequential_view.current.last == global_endpoints.last || - is_in_layers_range(path, m_layers_z_range[1], m_layers_z_range[1])) - color = extrusion_color(path); - else - color = Neutral_Color; - - break; - } - case EMoveType::Travel: { - if (!top_layer_only || m_sequential_view.current.last == global_endpoints.last || is_travel_in_layers_range(path_id, m_layers_z_range[1], m_layers_z_range[1])) - color = (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool) ? extrusion_color(path) : travel_color(path); - else - color = Neutral_Color; - - break; - } - case EMoveType::Wipe: { color = Wipe_Color; break; } - default: { color = { 0.0f, 0.0f, 0.0f, 1.0f }; break; } - } - - RenderPath key{ tbuffer_id, color, static_cast(ibuffer_id), path_id }; - if (render_path == nullptr || !RenderPathPropertyEqual()(*render_path, key)) { - buffer.render_paths.emplace_back(key); - render_path = const_cast(&buffer.render_paths.back()); - } - - unsigned int delta_1st = 0; - if (sub_path.first.s_id < m_sequential_view.current.first && m_sequential_view.current.first <= sub_path.last.s_id) - delta_1st = static_cast(m_sequential_view.current.first - sub_path.first.s_id); - - unsigned int size_in_indices = 0; - switch (buffer.render_primitive_type) - { - case TBuffer::ERenderPrimitiveType::Line: - case TBuffer::ERenderPrimitiveType::Triangle: { - // BBS: modify to support moves which has internal point - size_t max_s_id = std::min(m_sequential_view.current.last, sub_path.last.s_id); - size_t min_s_id = std::max(m_sequential_view.current.first, sub_path.first.s_id); - unsigned int segments_count = max_s_id - min_s_id; - for (size_t i = min_s_id + 1; i < max_s_id + 1; i++) { - size_t move_id = m_ssid_to_moveid_map[i]; - const GCodeProcessorResult::MoveVertex& curr = m_gcode_result->moves[move_id]; - if (curr.is_arc_move()) { - segments_count += curr.interpolation_points.size(); - } - } - size_in_indices = buffer.indices_per_segment() * segments_count; - break; - } - default: { break; } - } - - if (size_in_indices == 0) - continue; - - if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) { - if (sub_path_id == 0 && delta_1st == 0) - size_in_indices += 6; // add 2 triangles for starting cap - if (sub_path_id == path.sub_paths.size() - 1 && path.sub_paths.back().last.s_id <= m_sequential_view.current.last) - size_in_indices += 6; // add 2 triangles for ending cap - if (delta_1st > 0) - size_in_indices -= 6; // remove 2 triangles for corner cap - } - - render_path->sizes.push_back(size_in_indices); - - if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) { - delta_1st *= buffer.indices_per_segment(); - if (delta_1st > 0) { - delta_1st += 6; // skip 2 triangles for corner cap - if (sub_path_id == 0) - delta_1st += 6; // skip 2 triangles for starting cap - } - } - - render_path->offsets.push_back(static_cast((sub_path.first.i_id + delta_1st) * sizeof(IBufferType))); - -#if 0 - // check sizes and offsets against index buffer size on gpu - GLint buffer_size; - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->indices[render_path->ibuffer_id].ibo)); - glsafe(::glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &buffer_size)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - if (render_path->offsets.back() + render_path->sizes.back() * sizeof(IBufferType) > buffer_size) - BOOST_LOG_TRIVIAL(error) << "GCodeViewer::refresh_render_paths: Invalid render path data"; -#endif - } - - // Removes empty render paths and sort. - for (size_t b = 0; b < m_buffers.size(); ++b) { - TBuffer* buffer = const_cast(&m_buffers[b]); - buffer->render_paths.erase(std::remove_if(buffer->render_paths.begin(), buffer->render_paths.end(), - [](const auto &path){ return path.sizes.empty() || path.offsets.empty(); }), - buffer->render_paths.end()); - } - - // second pass: for buffers using instanced and batched models, update the instances render ranges - for (size_t b = 0; b < m_buffers.size(); ++b) { - TBuffer& buffer = const_cast(m_buffers[b]); - if (buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::InstancedModel && - buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) - continue; - - buffer.model.instances.render_ranges.reset(); - - if (!buffer.visible || buffer.model.instances.s_ids.empty()) - continue; - - buffer.model.instances.render_ranges.ranges.push_back({ 0, 0, 0, buffer.model.color }); - bool has_second_range = top_layer_only && m_sequential_view.current.last != m_sequential_view.global.last; - if (has_second_range) - buffer.model.instances.render_ranges.ranges.push_back({ 0, 0, 0, Neutral_Color }); - - if (m_sequential_view.current.first <= buffer.model.instances.s_ids.back() && buffer.model.instances.s_ids.front() <= m_sequential_view.current.last) { - for (size_t id : buffer.model.instances.s_ids) { - if (has_second_range) { - if (id < m_sequential_view.endpoints.first) { - ++buffer.model.instances.render_ranges.ranges.front().offset; - if (id <= m_sequential_view.current.first) - ++buffer.model.instances.render_ranges.ranges.back().offset; - else - ++buffer.model.instances.render_ranges.ranges.back().count; - } - else if (id <= m_sequential_view.current.last) - ++buffer.model.instances.render_ranges.ranges.front().count; - else - break; - } - else { - if (id <= m_sequential_view.current.first) - ++buffer.model.instances.render_ranges.ranges.front().offset; - else if (id <= m_sequential_view.current.last) - ++buffer.model.instances.render_ranges.ranges.front().count; - else - break; - } - } - } - } - - // set sequential data to their final value - sequential_view->endpoints = top_layer_only ? top_layer_endpoints : global_endpoints; - sequential_view->current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(sequential_view->current.first, sequential_view->endpoints.first, sequential_view->endpoints.last) : sequential_view->endpoints.first; - sequential_view->global = global_endpoints; - - // updates sequential range caps - std::array* sequential_range_caps = const_cast*>(&m_sequential_range_caps); - (*sequential_range_caps)[0].reset(); - (*sequential_range_caps)[1].reset(); - - if (m_sequential_view.current.first != m_sequential_view.current.last) { - for (const auto& [tbuffer_id, ibuffer_id, path_id, sub_path_id] : paths) { - TBuffer& buffer = const_cast(m_buffers[tbuffer_id]); - if (buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Triangle) - continue; - - const Path& path = buffer.paths[path_id]; - const Path::Sub_Path& sub_path = path.sub_paths[sub_path_id]; - if (m_sequential_view.current.last <= sub_path.first.s_id || sub_path.last.s_id <= m_sequential_view.current.first) - continue; - - // update cap for first endpoint of current range - if (m_sequential_view.current.first > sub_path.first.s_id) { - SequentialRangeCap& cap = (*sequential_range_caps)[0]; - const IBuffer& i_buffer = buffer.indices[ibuffer_id]; - cap.buffer = &buffer; - cap.vbo = i_buffer.vbo; - - // calculate offset into the index buffer - unsigned int offset = sub_path.first.i_id; - offset += 6; // add 2 triangles for corner cap - offset += static_cast(m_sequential_view.current.first - sub_path.first.s_id) * buffer.indices_per_segment(); - if (sub_path_id == 0) - offset += 6; // add 2 triangles for starting cap - - // extract indices from index buffer - std::array indices{ 0, 0, 0, 0, 0, 0 }; - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); - glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 0) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[0]))); - glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 7) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[1]))); - glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 1) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[2]))); - glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 13) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[4]))); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - indices[3] = indices[0]; - indices[5] = indices[1]; - - // send indices to gpu - glsafe(::glGenBuffers(1, &cap.ibo)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cap.ibo)); - glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(IBufferType), indices.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - - // extract color from render path - size_t offset_bytes = offset * sizeof(IBufferType); - for (const RenderPath& render_path : buffer.render_paths) { - if (render_path.ibuffer_id == ibuffer_id) { - for (size_t j = 0; j < render_path.offsets.size(); ++j) { - if (render_path.contains(offset_bytes)) { - cap.color = render_path.color; - break; - } - } - } - } - } - - // update cap for last endpoint of current range - if (m_sequential_view.current.last < sub_path.last.s_id) { - SequentialRangeCap& cap = (*sequential_range_caps)[1]; - const IBuffer& i_buffer = buffer.indices[ibuffer_id]; - cap.buffer = &buffer; - cap.vbo = i_buffer.vbo; - - // calculate offset into the index buffer - unsigned int offset = sub_path.first.i_id; - offset += 6; // add 2 triangles for corner cap - offset += static_cast(m_sequential_view.current.last - 1 - sub_path.first.s_id) * buffer.indices_per_segment(); - if (sub_path_id == 0) - offset += 6; // add 2 triangles for starting cap - - // extract indices from index buffer - std::array indices{ 0, 0, 0, 0, 0, 0 }; - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); - glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 2) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[0]))); - glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 4) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[1]))); - glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 10) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[2]))); - glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 16) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[5]))); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - indices[3] = indices[0]; - indices[4] = indices[2]; - - // send indices to gpu - glsafe(::glGenBuffers(1, &cap.ibo)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cap.ibo)); - glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(IBufferType), indices.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - - // extract color from render path - size_t offset_bytes = offset * sizeof(IBufferType); - for (const RenderPath& render_path : buffer.render_paths) { - if (render_path.ibuffer_id == ibuffer_id) { - for (size_t j = 0; j < render_path.offsets.size(); ++j) { - if (render_path.contains(offset_bytes)) { - cap.color = render_path.color; - break; - } - } - } - } - } - - if ((*sequential_range_caps)[0].is_renderable() && (*sequential_range_caps)[1].is_renderable()) - break; - } - } - - //BBS - enable_moves_slider(!paths.empty()); - -#if ENABLE_GCODE_VIEWER_STATISTICS - for (const TBuffer& buffer : m_buffers) { - statistics->render_paths_size += SLIC3R_STDUNORDEREDSET_MEMSIZE(buffer.render_paths, RenderPath); - for (const RenderPath& path : buffer.render_paths) { - statistics->render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.sizes, unsigned int); - statistics->render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t); - } - statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances.buffer, float); - statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances.s_ids, size_t); - statistics->models_instances_size += SLIC3R_STDVEC_MEMSIZE(buffer.model.instances.render_ranges.ranges, InstanceVBuffer::Ranges::Range); - } - statistics->refresh_paths_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS -} - void GCodeViewer::render_toolpaths() { const Camera& camera = wxGetApp().plater()->get_camera(); - const double zoom = camera.get_zoom(); + const libvgcode::Mat4x4 converted_view_matrix = libvgcode::convert(static_cast(camera.get_view_matrix().matrix().cast())); + const libvgcode::Mat4x4 converted_projetion_matrix = libvgcode::convert(static_cast(camera.get_projection_matrix().matrix().cast())); +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + m_viewer.set_cog_marker_scale_factor(m_cog_marker_fixed_screen_size ? 10.0f * m_cog_marker_size * camera.get_inv_zoom() : m_cog_marker_size); + m_viewer.set_tool_marker_scale_factor(m_tool_marker_fixed_screen_size ? 10.0f * m_tool_marker_size * camera.get_inv_zoom() : m_tool_marker_size); +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + m_viewer.render(converted_view_matrix, converted_projetion_matrix); - auto render_as_lines = [ -#if ENABLE_GCODE_VIEWER_STATISTICS - this -#endif // ENABLE_GCODE_VIEWER_STATISTICS - ](std::vector::iterator it_path, std::vector::iterator it_end, GLShaderProgram& shader, int uniform_color) { - for (auto it = it_path; it != it_end && it_path->ibuffer_id == it->ibuffer_id; ++it) { - const RenderPath& path = *it; - // Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415. - assert(! path.sizes.empty()); - assert(! path.offsets.empty()); - shader.set_uniform(uniform_color, path.color); - glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_lines_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - }; +#if ENABLE_NEW_GCODE_VIEWER_DEBUG + if (is_legend_shown()) { + ImGuiWrapper& imgui = *wxGetApp().imgui(); + const Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); + imgui.set_next_window_pos(static_cast(cnv_size.get_width()), 0.0f, ImGuiCond_Always, 1.0f, 0.0f); + imgui.begin(std::string("LibVGCode Viewer Debug"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize); - auto render_as_triangles = [ -#if ENABLE_GCODE_VIEWER_STATISTICS - this -#endif // ENABLE_GCODE_VIEWER_STATISTICS - ](std::vector::iterator it_path, std::vector::iterator it_end, GLShaderProgram& shader, int uniform_color) { - for (auto it = it_path; it != it_end && it_path->ibuffer_id == it->ibuffer_id; ++it) { - const RenderPath& path = *it; - // Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415. - assert(! path.sizes.empty()); - assert(! path.offsets.empty()); - shader.set_uniform(uniform_color, path.color); - glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_triangles_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - }; + if (ImGui::BeginTable("Data", 2)) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "# vertices"); + ImGui::TableSetColumnIndex(1); + ImGuiWrapper::text(std::to_string(m_viewer.get_vertices_count())); - auto render_as_instanced_model = [ -#if ENABLE_GCODE_VIEWER_STATISTICS - this -#endif // ENABLE_GCODE_VIEWER_STATISTICS - ](TBuffer& buffer, GLShaderProgram & shader) { - for (auto& range : buffer.model.instances.render_ranges.ranges) { - if (range.vbo == 0 && range.count > 0) { - glsafe(::glGenBuffers(1, &range.vbo)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, range.vbo)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, range.count * buffer.model.instances.instance_size_bytes(), (const void*)&buffer.model.instances.buffer[range.offset * buffer.model.instances.instance_size_floats()], GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - } + ImGui::Separator(); - if (range.vbo > 0) { - buffer.model.model.set_color(range.color); - buffer.model.model.render_instanced(range.vbo, range.count); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_instanced_models_calls_count; - m_statistics.total_instances_gpu_size += static_cast(range.count * buffer.model.instances.instance_size_bytes()); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - } - }; + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "cpu memory"); + ImGui::TableSetColumnIndex(1); + ImGuiWrapper::text(format_memsize(m_viewer.get_used_cpu_memory())); -#if ENABLE_GCODE_VIEWER_STATISTICS - auto render_as_batched_model = [this](TBuffer& buffer, GLShaderProgram& shader, int position_id, int normal_id) { -#else - auto render_as_batched_model = [](TBuffer& buffer, GLShaderProgram& shader, int position_id, int normal_id) { -#endif // ENABLE_GCODE_VIEWER_STATISTICS + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "gpu memory"); + ImGui::TableSetColumnIndex(1); + ImGuiWrapper::text(format_memsize(m_viewer.get_used_gpu_memory())); - struct Range - { - unsigned int first; - unsigned int last; - bool intersects(const Range& other) const { return (other.last < first || other.first > last) ? false : true; } - }; - Range buffer_range = { 0, 0 }; - const size_t indices_per_instance = buffer.model.data.indices_count(); + ImGui::Separator(); - for (size_t j = 0; j < buffer.indices.size(); ++j) { - const IBuffer& i_buffer = buffer.indices[j]; - buffer_range.last = buffer_range.first + i_buffer.count / indices_per_instance; - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); - if (position_id != -1) { - glsafe(::glVertexAttribPointer(position_id, buffer.vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes())); - glsafe(::glEnableVertexAttribArray(position_id)); - } - const bool has_normals = buffer.vertices.normal_size_floats() > 0; - if (has_normals) { - if (normal_id != -1) { - glsafe(::glVertexAttribPointer(normal_id, buffer.vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); - glsafe(::glEnableVertexAttribArray(normal_id)); - } - } - - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); - - for (auto& range : buffer.model.instances.render_ranges.ranges) { - const Range range_range = { range.offset, range.offset + range.count }; - if (range_range.intersects(buffer_range)) { - shader.set_uniform("uniform_color", range.color); - const unsigned int offset = (range_range.first > buffer_range.first) ? range_range.first - buffer_range.first : 0; - const size_t offset_bytes = static_cast(offset) * indices_per_instance * sizeof(IBufferType); - const Range render_range = { std::max(range_range.first, buffer_range.first), std::min(range_range.last, buffer_range.last) }; - const size_t count = static_cast(render_range.last - render_range.first) * indices_per_instance; - if (count > 0) { - glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)count, GL_UNSIGNED_SHORT, (const void*)offset_bytes)); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_batched_models_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - } - } + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "layers range"); + ImGui::TableSetColumnIndex(1); + const libvgcode::Interval& layers_range = m_viewer.get_layers_view_range(); + ImGuiWrapper::text(std::to_string(layers_range[0]) + " - " + std::to_string(layers_range[1])); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - if (normal_id != -1) - glsafe(::glDisableVertexAttribArray(normal_id)); - if (position_id != -1) - glsafe(::glDisableVertexAttribArray(position_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "view range (enabled)"); + ImGui::TableSetColumnIndex(1); + const libvgcode::Interval& enabled_view_range = m_viewer.get_view_enabled_range(); + ImGuiWrapper::text(std::to_string(enabled_view_range[0]) + " - " + std::to_string(enabled_view_range[1]) + " | " + + std::to_string(m_viewer.get_vertex_at(enabled_view_range[0]).gcode_id) + " - " + + std::to_string(m_viewer.get_vertex_at(enabled_view_range[1]).gcode_id)); - buffer_range.first = buffer_range.last; + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "view range (visible)"); + ImGui::TableSetColumnIndex(1); + const libvgcode::Interval& visible_view_range = m_viewer.get_view_visible_range(); + ImGuiWrapper::text(std::to_string(visible_view_range[0]) + " - " + std::to_string(visible_view_range[1]) + " | " + + std::to_string(m_viewer.get_vertex_at(visible_view_range[0]).gcode_id) + " - " + + std::to_string(m_viewer.get_vertex_at(visible_view_range[1]).gcode_id)); + + auto add_range_property_row = [&imgui](const std::string& label, const std::array& range) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label); + ImGui::TableSetColumnIndex(1); + char buf[128]; + sprintf(buf, "%.3f - %.3f", range[0], range[1]); + ImGuiWrapper::text(buf); + }; + + add_range_property_row("height range", m_viewer.get_color_range(libvgcode::EViewType::Height).get_range()); + add_range_property_row("width range", m_viewer.get_color_range(libvgcode::EViewType::Width).get_range()); + add_range_property_row("speed range", m_viewer.get_color_range(libvgcode::EViewType::Speed).get_range()); + add_range_property_row("fan speed range", m_viewer.get_color_range(libvgcode::EViewType::FanSpeed).get_range()); + add_range_property_row("temperature range", m_viewer.get_color_range(libvgcode::EViewType::Temperature).get_range()); + add_range_property_row("volumetric rate range", m_viewer.get_color_range(libvgcode::EViewType::VolumetricFlowRate).get_range()); + add_range_property_row("layer time linear range", m_viewer.get_color_range(libvgcode::EViewType::LayerTimeLinear).get_range()); + add_range_property_row("layer time logarithmic range", m_viewer.get_color_range(libvgcode::EViewType::LayerTimeLogarithmic).get_range()); + + ImGui::EndTable(); } - }; - auto line_width = [](double zoom) { - return (zoom < 5.0) ? 1.0 : (1.0 + 5.0 * (zoom - 5.0) / (100.0 - 5.0)); - }; +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + ImGui::Separator(); - const unsigned char begin_id = buffer_id(EMoveType::Retract); - const unsigned char end_id = buffer_id(EMoveType::Count); + if (ImGui::BeginTable("Cog", 2)) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiPureWrap::text_colored(ImGuiPureWrap::COL_ORANGE_LIGHT, "Cog marker scale factor"); + ImGui::TableSetColumnIndex(1); + ImGuiPureWrap::text(std::to_string(get_cog_marker_scale_factor())); - for (unsigned char i = begin_id; i < end_id; ++i) { - TBuffer& buffer = m_buffers[i]; - if (!buffer.visible || !buffer.has_data()) - continue; - - GLShaderProgram* shader = wxGetApp().get_shader(buffer.shader.c_str()); - if (shader == nullptr) - continue; - - shader->start_using(); - - shader->set_uniform("view_model_matrix", camera.get_view_matrix()); - shader->set_uniform("projection_matrix", camera.get_projection_matrix()); - shader->set_uniform("view_normal_matrix", (Matrix3d)Matrix3d::Identity()); - - if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel) { - shader->set_uniform("emission_factor", 0.25f); - render_as_instanced_model(buffer, *shader); - shader->set_uniform("emission_factor", 0.0f); + ImGui::EndTable(); } - else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) { - shader->set_uniform("emission_factor", 0.25f); - const int position_id = shader->get_attrib_location("v_position"); - const int normal_id = shader->get_attrib_location("v_normal"); - render_as_batched_model(buffer, *shader, position_id, normal_id); - shader->set_uniform("emission_factor", 0.0f); - } - else { - const int position_id = shader->get_attrib_location("v_position"); - const int normal_id = shader->get_attrib_location("v_normal"); - const int uniform_color = shader->get_uniform_location("uniform_color"); - auto it_path = buffer.render_paths.begin(); - for (unsigned int ibuffer_id = 0; ibuffer_id < static_cast(buffer.indices.size()); ++ibuffer_id) { - const IBuffer& i_buffer = buffer.indices[ibuffer_id]; - // Skip all paths with ibuffer_id < ibuffer_id. - for (; it_path != buffer.render_paths.end() && it_path->ibuffer_id < ibuffer_id; ++it_path); - if (it_path == buffer.render_paths.end() || it_path->ibuffer_id > ibuffer_id) - // Not found. This shall not happen. - continue; + ImGui::Separator(); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); - if (position_id != -1) { - glsafe(::glVertexAttribPointer(position_id, buffer.vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes())); - glsafe(::glEnableVertexAttribArray(position_id)); - } - const bool has_normals = buffer.vertices.normal_size_floats() > 0; - if (has_normals) { - if (normal_id != -1) { - glsafe(::glVertexAttribPointer(normal_id, buffer.vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); - glsafe(::glEnableVertexAttribArray(normal_id)); - } - } + if (ImGui::BeginTable("Tool", 2)) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiPureWrap::text_colored(ImGuiPureWrap::COL_ORANGE_LIGHT, "Tool marker scale factor"); + ImGui::TableSetColumnIndex(1); + ImGuiPureWrap::text(std::to_string(m_viewer.get_tool_marker_scale_factor())); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiPureWrap::text_colored(ImGuiPureWrap::COL_ORANGE_LIGHT, "Tool marker z offset"); + ImGui::TableSetColumnIndex(1); + float tool_z_offset = m_viewer.get_tool_marker_offset_z(); + if (imgui.slider_float("##ToolZOffset", &tool_z_offset, 0.0f, 1.0f)) + m_viewer.set_tool_marker_offset_z(tool_z_offset); - // Render all elements with it_path->ibuffer_id == ibuffer_id, possible with varying colors. - switch (buffer.render_primitive_type) - { - case TBuffer::ERenderPrimitiveType::Line: { - glsafe(::glLineWidth(static_cast(line_width(zoom)))); - render_as_lines(it_path, buffer.render_paths.end(), *shader, uniform_color); - break; - } - case TBuffer::ERenderPrimitiveType::Triangle: { - render_as_triangles(it_path, buffer.render_paths.end(), *shader, uniform_color); - break; - } - default: { break; } - } - - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - - if (normal_id != -1) - glsafe(::glDisableVertexAttribArray(normal_id)); - if (position_id != -1) - glsafe(::glDisableVertexAttribArray(position_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiPureWrap::text_colored(ImGuiPureWrap::COL_ORANGE_LIGHT, "Tool marker color"); + ImGui::TableSetColumnIndex(1); + const libvgcode::Color& color = m_viewer.get_tool_marker_color(); + std::array c = { static_cast(color[0]) / 255.0f, static_cast(color[1]) / 255.0f, static_cast(color[2]) / 255.0f }; + if (ImGui::ColorPicker3("##ToolColor", c.data())) { + m_viewer.set_tool_marker_color({ static_cast(c[0] * 255.0f), + static_cast(c[1] * 255.0f), + static_cast(c[2] * 255.0f) }); } - } + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiPureWrap::text_colored(ImGuiPureWrap::COL_ORANGE_LIGHT, "Tool marker alpha"); + ImGui::TableSetColumnIndex(1); + float tool_alpha = m_viewer.get_tool_marker_alpha(); + if (imgui.slider_float("##ToolAlpha", &tool_alpha, 0.25f, 0.75f)) + m_viewer.set_tool_marker_alpha(tool_alpha); - shader->stop_using(); - } - -#if ENABLE_GCODE_VIEWER_STATISTICS - auto render_sequential_range_cap = [this, &camera] -#else - auto render_sequential_range_cap = [&camera] -#endif // ENABLE_GCODE_VIEWER_STATISTICS - (const SequentialRangeCap& cap) { - const TBuffer* buffer = cap.buffer; - GLShaderProgram* shader = wxGetApp().get_shader(buffer->shader.c_str()); - if (shader == nullptr) - return; - - shader->start_using(); - - shader->set_uniform("view_model_matrix", camera.get_view_matrix()); - shader->set_uniform("projection_matrix", camera.get_projection_matrix()); - shader->set_uniform("view_normal_matrix", (Matrix3d)Matrix3d::Identity()); - - const int position_id = shader->get_attrib_location("v_position"); - const int normal_id = shader->get_attrib_location("v_normal"); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, cap.vbo)); - if (position_id != -1) { - glsafe(::glVertexAttribPointer(position_id, buffer->vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer->vertices.vertex_size_bytes(), (const void*)buffer->vertices.position_offset_bytes())); - glsafe(::glEnableVertexAttribArray(position_id)); - } - const bool has_normals = buffer->vertices.normal_size_floats() > 0; - if (has_normals) { - if (normal_id != -1) { - glsafe(::glVertexAttribPointer(normal_id, buffer->vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer->vertices.vertex_size_bytes(), (const void*)buffer->vertices.normal_offset_bytes())); - glsafe(::glEnableVertexAttribArray(normal_id)); - } - } - - shader->set_uniform("uniform_color", cap.color); - - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cap.ibo)); - glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)cap.indices_count(), GL_UNSIGNED_SHORT, nullptr)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_triangles_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - if (normal_id != -1) - glsafe(::glDisableVertexAttribArray(normal_id)); - if (position_id != -1) - glsafe(::glDisableVertexAttribArray(position_id)); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - - shader->stop_using(); - }; - - for (unsigned int i = 0; i < 2; ++i) { - if (m_sequential_range_caps[i].is_renderable()) - render_sequential_range_cap(m_sequential_range_caps[i]); + ImGui::EndTable(); + } +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + + ImGui::Separator(); + if (ImGui::BeginTable("Radii", 2)) { + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "Travels radius"); + ImGui::TableSetColumnIndex(1); + float travels_radius = m_viewer.get_travels_radius(); + ImGui::SetNextItemWidth(200.0f); + if (imgui.slider_float("##TravelRadius", &travels_radius, 0.05f, 0.5f)) + m_viewer.set_travels_radius(travels_radius); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "Wipes radius"); + ImGui::TableSetColumnIndex(1); + float wipes_radius = m_viewer.get_wipes_radius(); + ImGui::SetNextItemWidth(200.0f); + if (imgui.slider_float("##WipesRadius", &wipes_radius, 0.05f, 0.5f)) + m_viewer.set_wipes_radius(wipes_radius); + + ImGui::EndTable(); + } + imgui.end(); } +#endif // ENABLE_NEW_GCODE_VIEWER_DEBUG } void GCodeViewer::render_shells(int canvas_width, int canvas_height) @@ -4136,7 +2219,7 @@ void GCodeViewer::render_all_plates_stats(const std::vector filament_colors; decode_colors(wxGetApp().plater()->get_extruder_colors_from_plater_config(gcode_result_list.back()), filament_colors); - for (int i = 0; i < filament_colors.size(); i++) { + for (int i = 0; i < filament_colors.size(); i++) { filament_colors[i] = adjust_color_for_rendering(filament_colors[i]); } @@ -4271,14 +2354,14 @@ void GCodeViewer::render_all_plates_stats(const std::vector(m_time_estimate_mode)]; + const PrintEstimatedStatistics::Mode& plate_time_mode = plate_print_statistics.modes[static_cast(m_viewer.get_time_mode())]; total_time_all_plates += plate_time_mode.time; - + Print *print; plate->get_print((PrintBase **) &print, nullptr, nullptr); total_cost_all_plates += print->print_statistics().total_cost; } - + for (auto it = model_volume_of_extruders_all_plates.begin(); it != model_volume_of_extruders_all_plates.end(); it++) { auto [model_used_filament_m, model_used_filament_g] = get_used_filament_from_volume(it->second, it->first); if (model_used_filament_m != 0.0 || model_used_filament_g != 0.0) @@ -4711,7 +2794,7 @@ void GCodeViewer::render_legend_color_arr_recommen(float window_padding) void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canvas_height, int right_margin) { - if (!m_legend_enabled) + if (!is_legend_shown()) return; const Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); @@ -4745,11 +2828,12 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv None }; - const PrintEstimatedStatistics::Mode& time_mode = m_print_statistics.modes[static_cast(m_time_estimate_mode)]; - //BBS - /*bool show_estimated_time = time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType || - (m_view_type == EViewType::ColorPrint && !time_mode.custom_gcode_times.empty()));*/ - bool show_estimated = time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType || m_view_type == EViewType::ColorPrint); + const PrintEstimatedStatistics::Mode& time_mode = m_print_statistics.modes[static_cast(m_viewer.get_time_mode())]; + const libvgcode::EViewType curr_view_type = m_viewer.get_view_type(); + const int curr_view_type_i = static_cast(curr_view_type); + bool show_estimated_time = time_mode.time > 0.0f && (curr_view_type == libvgcode::EViewType::FeatureType || + curr_view_type == libvgcode::EViewType::LayerTimeLinear || curr_view_type == libvgcode::EViewType::LayerTimeLogarithmic || + (curr_view_type == libvgcode::EViewType::ColorPrint && !time_mode.custom_gcode_times.empty())); const float icon_size = ImGui::GetTextLineHeight() * 0.7; //BBS GUI refactor @@ -4771,7 +2855,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv const ColorRGBA& color, const std::vector>& columns_offsets, bool checkbox = true, - float checkbox_pos = 0.f, // ORCA use calculated value for eye icon. Aligned to "Display" header or end of combo box + float checkbox_pos = 0.f, // ORCA use calculated value for eye icon. Aligned to "Display" header or end of combo box bool visible = true, std::function callback = nullptr) { @@ -4855,24 +2939,24 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv }; - auto append_range = [append_item](const Extrusions::Range& range, unsigned int decimals) { - auto append_range_item = [append_item](int i, float value, unsigned int decimals) { + auto append_range = [append_item](const libvgcode::ColorRange& range, unsigned int decimals) { + auto append_range_item = [append_item, &range](int i, float value, unsigned int decimals) { char buf[1024]; ::sprintf(buf, "%.*f", decimals, value); - append_item(EItemType::Rect, Range_Colors[i], { { buf , 0} }); + append_item(EItemType::Rect, libvgcode::convert(range.get_palette()[i]), { { buf , 0} }); }; - if (range.count == 1) + std::vector values = range.get_values(); + if (values.size() == 1) // single item use case - append_range_item(0, range.min, decimals); - else if (range.count == 2) { - append_range_item(static_cast(Range_Colors.size()) - 1, range.max, decimals); - append_range_item(0, range.min, decimals); + append_range_item(0, values.front(), decimals); + else if (values.size() == 2) { + append_range_item(static_cast(range.get_palette().size()) - 1, values.back(), decimals); + append_range_item(0, values.front(), decimals); } else { - const float step_size = range.step_size(); - for (int i = static_cast(Range_Colors.size()) - 1; i >= 0; --i) { - append_range_item(i, range.get_value_at_step(i), decimals); + for (int i = static_cast(range.get_palette().size()) - 1; i >= 0; --i) { + append_range_item(i, values[i], decimals); } } }; @@ -4931,8 +3015,9 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv if (item.type != ColorChange) continue; - const std::vector zs = m_layers.get_zs(); - auto lower_b = std::lower_bound(zs.begin(), zs.end(), item.print_z - epsilon()); + const std::vector zs = m_viewer.get_layers_zs(); + auto lower_b = std::lower_bound(zs.begin(), zs.end(), + static_cast(item.print_z - epsilon())); if (lower_b == zs.end()) continue; @@ -4971,14 +3056,14 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv return _u8L("from") + " " + std::string(buf1) + " " + _u8L("to") + " " + std::string(buf2) + " " + _u8L("mm"); }; - auto role_time_and_percent = [time_mode](ExtrusionRole role) { - auto it = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [role](const std::pair& item) { return role == item.first; }); - return (it != time_mode.roles_times.end()) ? std::make_pair(it->second, it->second / time_mode.time) : std::make_pair(0.0f, 0.0f); + auto role_time_and_percent = [this, time_mode](libvgcode::EGCodeExtrusionRole role) { + const float time = m_viewer.get_extrusion_role_estimated_time(role); + return std::make_pair(time, time / time_mode.time); }; - auto move_time_and_percent = [time_mode](EMoveType move_type) { - auto it = std::find_if(time_mode.moves_times.begin(), time_mode.moves_times.end(), [move_type](const std::pair& item) { return move_type == item.first; }); - return (it != time_mode.moves_times.end()) ? std::make_pair(it->second, it->second / time_mode.time) : std::make_pair(0.0f, 0.0f); + auto travel_time_and_percent = [this, time_mode]() { + const float time = m_viewer.get_travels_estimated_time(); + return std::make_pair(time, time / time_mode.time); }; auto used_filament_per_role = [this, imperial_units](ExtrusionRole role) { @@ -5044,10 +3129,13 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv m_view_type_sel = i; set_view_type(view_type_items[m_view_type_sel]); reset_visible(view_type_items[m_view_type_sel]); - // update buffers' render paths - refresh_render_paths(false, false); update_moves_slider(); + #if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + imgui.set_requires_extra_frame(); + #else wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); + wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); + #endif } if (is_selected) { ImGui::SetItemDefaultFocus(); @@ -5108,10 +3196,11 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv const PrintStatistics& ps = wxGetApp().plater()->get_partplate_list().get_current_fff_print().print_statistics(); double koef = imperial_units ? GizmoObjectManipulation::in_to_mm : 1000.0; double unit_conver = imperial_units ? GizmoObjectManipulation::oz_to_g : 1; - + std::vector used_filaments_m; + std::vector used_filaments_g; // used filament statistics - for (size_t extruder_id : m_extruder_ids) { + for (size_t extruder_id : m_viewer.get_used_extruders_ids()) { if (m_print_statistics.model_volumes_per_extruder.find(extruder_id) == m_print_statistics.model_volumes_per_extruder.end()) { model_used_filaments_m.push_back(0.0); model_used_filaments_g.push_back(0.0); @@ -5127,7 +3216,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv } } - for (size_t extruder_id : m_extruder_ids) { + for (size_t extruder_id : m_viewer.get_used_extruders_ids()) { if (m_print_statistics.wipe_tower_volumes_per_extruder.find(extruder_id) == m_print_statistics.wipe_tower_volumes_per_extruder.end()) { wipe_tower_used_filaments_m.push_back(0.0); wipe_tower_used_filaments_g.push_back(0.0); @@ -5143,7 +3232,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv } } - for (size_t extruder_id : m_extruder_ids) { + for (size_t extruder_id : m_viewer.get_used_extruders_ids()) { if (m_print_statistics.flush_per_filament.find(extruder_id) == m_print_statistics.flush_per_filament.end()) { flushed_filaments_m.push_back(0.0); flushed_filaments_g.push_back(0.0); @@ -5159,7 +3248,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv } } - for (size_t extruder_id : m_extruder_ids) { + for (size_t extruder_id : m_viewer.get_used_extruders_ids()) { if (m_print_statistics.support_volumes_per_extruder.find(extruder_id) == m_print_statistics.support_volumes_per_extruder.end()) { support_used_filaments_m.push_back(0.0); support_used_filaments_g.push_back(0.0); @@ -5179,16 +3268,17 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv // extrusion paths section -> title ImGui::Dummy({ window_padding, window_padding }); ImGui::SameLine(); - switch (m_view_type) + switch (curr_view_type) { - case EViewType::FeatureType: + case libvgcode::EViewType::FeatureType: { // calculate offsets to align time/percentage data char buffer[64]; - for (size_t i = 0; i < m_roles.size(); ++i) { - ExtrusionRole role = m_roles[i]; - if (role < erCount) { - labels.push_back(_u8L(ExtrusionEntity::role_to_string(role))); + const std::vector& roles = m_viewer.get_extrusion_roles(); + for (libvgcode::EGCodeExtrusionRole role : roles) { + assert(static_cast(role) < libvgcode::GCODE_EXTRUSION_ROLES_COUNT); + if (static_cast(role) < libvgcode::GCODE_EXTRUSION_ROLES_COUNT) { + labels.push_back(_u8L(ExtrusionEntity::role_to_string(convert(role)))); auto [time, percent] = role_time_and_percent(role); times.push_back((time > 0.0f) ? short_time(get_time_dhms(time)) : ""); if (percent == 0) // ORCA remove % symbol from rows @@ -5197,7 +3287,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv percent > 0.001 ? ::sprintf(buffer, "%.1f", percent * 100) : ::sprintf(buffer, "<0.1"); percents.push_back(buffer); - auto [model_used_filament_m, model_used_filament_g] = used_filament_per_role(role); + auto [model_used_filament_m, model_used_filament_g] = used_filament_per_role(convert(role)); ::sprintf(buffer, imperial_units ? "%.2fin" : "%.2fm", model_used_filament_m); // ORCA dont use spacing between value and unit used_filaments_length.push_back(buffer); ::sprintf(buffer, imperial_units ? "%.2foz" : "%.2fg", model_used_filament_g); // ORCA dont use spacing between value and unit @@ -5207,7 +3297,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv //BBS: get travel time and percent { - auto [time, percent] = move_time_and_percent(EMoveType::Travel); + auto [time, percent] = travel_time_and_percent(); travel_time = (time > 0.0f) ? short_time(get_time_dhms(time)) : ""; if (percent == 0) // ORCA remove % symbol from rows ::sprintf(buffer, "0"); @@ -5221,24 +3311,37 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv append_headers({{_u8L("Line Type"), offsets[0]}, {_u8L("Time"), offsets[1]}, {"%", offsets[2]}, {_u8L("Usage"), offsets[3]}, {_u8L("Display"), offsets[5]}}); break; } - case EViewType::Height: { imgui.title(_u8L("Layer Height (mm)")); break; } - case EViewType::Width: { imgui.title(_u8L("Line Width (mm)")); break; } - case EViewType::Feedrate: + case libvgcode::EViewType::Height: { imgui.title(_u8L("Layer Height (mm)")); break; } + case libvgcode::EViewType::Width: { imgui.title(_u8L("Line Width (mm)")); break; } + case libvgcode::EViewType::Speed: { imgui.title(_u8L("Speed (mm/s)")); break; } + case libvgcode::EViewType::ActualSpeed: + { + imgui.title(_u8L("Actual Speed (mm/s)")); + break; + } + case libvgcode::EViewType::FanSpeed: { imgui.title(_u8L("Fan Speed (%)")); break; } + case libvgcode::EViewType::Temperature: { imgui.title(_u8L("Temperature (°C)")); break; } + case libvgcode::EViewType::VolumetricFlowRate: + { imgui.title(_u8L("Volumetric flow rate (mm³/s)")); break; } + case libvgcode::EViewType::ActualVolumetricFlowRate: + { imgui.title(_u8L("Actual volumetric flow rate (mm³/s)")); break; } + case libvgcode::EViewType::LayerTimeLinear: + { imgui.title(_u8L("Layer Time")); break; } + case libvgcode::EViewType::LayerTimeLogarithmic: + { imgui.title(_u8L("Layer Time (log)")); break; } - case EViewType::FanSpeed: { imgui.title(_u8L("Fan Speed (%)")); break; } - case EViewType::Temperature: { imgui.title(_u8L("Temperature (°C)")); break; } - case EViewType::VolumetricRate: { imgui.title(_u8L("Volumetric flow rate (mm³/s)")); break; } - case EViewType::LayerTime: { imgui.title(_u8L("Layer Time")); break; } - case EViewType::LayerTimeLog: { imgui.title(_u8L("Layer Time (log)")); break; } - - case EViewType::Tool: + case libvgcode::EViewType::Tool: { // calculate used filaments data - for (size_t extruder_id : m_extruder_ids) { + const size_t extruders_count = get_extruders_count(); + used_filaments_m = std::vector(extruders_count, 0.0); + used_filaments_g = std::vector(extruders_count, 0.0); + const std::vector& used_extruders_ids = m_viewer.get_used_extruders_ids(); + for (uint8_t extruder_id : used_extruders_ids) { if (m_print_statistics.model_volumes_per_extruder.find(extruder_id) == m_print_statistics.model_volumes_per_extruder.end()) continue; double volume = m_print_statistics.model_volumes_per_extruder.at(extruder_id); @@ -5252,7 +3355,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv append_headers({ {_u8L("Filament"), offsets[0]}, {_u8L("Usage"), offsets[1]} }); break; } - case EViewType::ColorPrint: + case libvgcode::EViewType::ColorPrint: { std::vector total_filaments; char buffer[64]; @@ -5291,119 +3394,133 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv default: { break; } } - auto append_option_item = [this, append_item](EMoveType type, std::vector offsets) { - auto append_option_item_with_type = [this, offsets, append_item](EMoveType type, const ColorRGBA& color, const std::string& label, bool visible) { + auto append_option_item = [this, append_item](libvgcode::EOptionType type, std::vector offsets) { + auto append_option_item_with_type = [this, offsets, append_item](libvgcode::EOptionType type, const ColorRGBA& color, const std::string& label, bool visible) { append_item(EItemType::Rect, color, {{ label , offsets[0] }}, true, offsets.back()/*ORCA checkbox_pos*/, visible, [this, type, visible]() { - m_buffers[buffer_id(type)].visible = !m_buffers[buffer_id(type)].visible; - // update buffers' render paths - refresh_render_paths(false, false); + m_viewer.toggle_option_visibility(type); update_moves_slider(); - wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); }); }; - const bool visible = m_buffers[buffer_id(type)].visible; - if (type == EMoveType::Travel) { + const bool visible = m_viewer.is_option_visible(type); + if (type == libvgcode::EOptionType::Travels) { //BBS: only display travel time in FeatureType view - append_option_item_with_type(type, Travel_Colors[0], _u8L("Travel"), visible); + append_option_item_with_type(type, libvgcode::convert(m_viewer.get_option_color(libvgcode::EOptionType::Travels)), _u8L("Travel"), visible); } - else if (type == EMoveType::Seam) - append_option_item_with_type(type, Options_Colors[(int)EOptionsColors::Seams], _u8L("Seams"), visible); - else if (type == EMoveType::Retract) - append_option_item_with_type(type, Options_Colors[(int)EOptionsColors::Retractions], _u8L("Retract"), visible); - else if (type == EMoveType::Unretract) - append_option_item_with_type(type, Options_Colors[(int)EOptionsColors::Unretractions], _u8L("Unretract"), visible); - else if (type == EMoveType::Tool_change) - append_option_item_with_type(type, Options_Colors[(int)EOptionsColors::ToolChanges], _u8L("Filament Changes"), visible); - else if (type == EMoveType::Wipe) - append_option_item_with_type(type, Wipe_Color, _u8L("Wipe"), visible); + else if (type == libvgcode::EOptionType::Seams) + append_option_item_with_type(type, libvgcode::convert(m_viewer.get_option_color(libvgcode::EOptionType::Seams)), _u8L("Seams"), visible); + else if (type == libvgcode::EOptionType::Retractions) + append_option_item_with_type(type, libvgcode::convert(m_viewer.get_option_color(libvgcode::EOptionType::Retractions)), _u8L("Retract"), visible); + else if (type == libvgcode::EOptionType::Unretractions) + append_option_item_with_type(type, libvgcode::convert(m_viewer.get_option_color(libvgcode::EOptionType::Unretractions)), _u8L("Unretract"), visible); + else if (type == libvgcode::EOptionType::ToolChanges) + append_option_item_with_type(type, libvgcode::convert(m_viewer.get_option_color(libvgcode::EOptionType::ToolChanges)), _u8L("Filament Changes"), visible); + else if (type == libvgcode::EOptionType::Wipes) + append_option_item_with_type(type, libvgcode::convert(m_viewer.get_option_color(libvgcode::EOptionType::Wipes)), _u8L("Wipe"), visible); }; + const libvgcode::EViewType new_view_type = curr_view_type; + // extrusion paths section -> items - switch (m_view_type) + switch (new_view_type) { - case EViewType::FeatureType: + case libvgcode::EViewType::FeatureType: { - for (size_t i = 0; i < m_roles.size(); ++i) { - ExtrusionRole role = m_roles[i]; - if (role >= erCount) + auto roles = m_viewer.get_extrusion_roles(); + for (size_t i = 0; i < roles.size(); ++i) { + libvgcode::EGCodeExtrusionRole role = roles[i]; + if (role >= libvgcode::EGCodeExtrusionRole::COUNT) continue; - const bool visible = is_visible(role); + const bool visible = m_viewer.is_extrusion_role_visible(role); std::vector> columns_offsets; columns_offsets.push_back({ labels[i], offsets[0] }); columns_offsets.push_back({ times[i], offsets[1] }); columns_offsets.push_back({percents[i], offsets[2]}); columns_offsets.push_back({used_filaments_length[i], offsets[3]}); columns_offsets.push_back({used_filaments_weight[i], offsets[4]}); - append_item(EItemType::Rect, Extrusion_Role_Colors[static_cast(role)], columns_offsets, + append_item(EItemType::Rect, libvgcode::convert(m_viewer.get_extrusion_role_color(role)), columns_offsets, true, offsets.back(), visible, [this, role, visible]() { - m_extrusions.role_visibility_flags = visible ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); - // update buffers' render paths - refresh_render_paths(false, false); + m_viewer.toggle_extrusion_role_visibility(role); update_moves_slider(); - wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); }); } - for(auto item : options_items) { - if (item != EMoveType::Travel) { + auto options = m_viewer.get_options(); + for(auto item : options) { + if (item != libvgcode::EOptionType::Travels) { append_option_item(item, offsets); } else { //BBS: show travel time in FeatureType view - const bool visible = m_buffers[buffer_id(item)].visible; + const bool visible = m_viewer.is_option_visible(item); std::vector> columns_offsets; columns_offsets.push_back({ _u8L("Travel"), offsets[0] }); columns_offsets.push_back({ travel_time, offsets[1] }); columns_offsets.push_back({ travel_percent, offsets[2] }); - append_item(EItemType::Rect, Travel_Colors[0], columns_offsets, true, offsets.back()/*ORCA checkbox_pos*/, visible, [this, item, visible]() { - m_buffers[buffer_id(item)].visible = !m_buffers[buffer_id(item)].visible; - // update buffers' render paths - refresh_render_paths(false, false); + append_item(EItemType::Rect, libvgcode::convert(m_viewer.get_option_color(libvgcode::EOptionType::Travels)), columns_offsets, true, offsets.back()/*ORCA checkbox_pos*/, visible, [this, item, visible]() { + m_viewer.toggle_option_visibility(item); update_moves_slider(); - wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); }); } } break; } - case EViewType::Height: { append_range(m_extrusions.ranges.height, 2); break; } - case EViewType::Width: { append_range(m_extrusions.ranges.width, 2); break; } - case EViewType::Feedrate: { - append_range(m_extrusions.ranges.feedrate, 0); + case libvgcode::EViewType::Height: { append_range(m_viewer.get_color_range(libvgcode::EViewType::Height), 2); break; } + case libvgcode::EViewType::Width: { append_range(m_viewer.get_color_range(libvgcode::EViewType::Width), 2); break; } + case libvgcode::EViewType::Speed: { + append_range(m_viewer.get_color_range(libvgcode::EViewType::Speed), 0); ImGui::Spacing(); ImGui::Dummy({ window_padding, window_padding }); ImGui::SameLine(); offsets = calculate_offsets({ { _u8L("Options"), { _u8L("Travel")}}, { _u8L("Display"), {""}} }, icon_size); append_headers({ {_u8L("Options"), offsets[0] }, { _u8L("Display"), offsets[1]} }); - const bool travel_visible = m_buffers[buffer_id(EMoveType::Travel)].visible; + const bool travel_visible = m_viewer.is_option_visible(libvgcode::EOptionType::Travels); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 3.0f)); - append_item(EItemType::None, Travel_Colors[0], { {_u8L("travel"), offsets[0] }}, true, predictable_icon_pos/*ORCA checkbox_pos*/, travel_visible, [this, travel_visible]() { - m_buffers[buffer_id(EMoveType::Travel)].visible = !m_buffers[buffer_id(EMoveType::Travel)].visible; - // update buffers' render paths, and update m_tools.m_tool_colors and m_extrusions.ranges - refresh(*m_gcode_result, wxGetApp().plater()->get_extruder_colors_from_plater_config(m_gcode_result)); + append_item(EItemType::None, libvgcode::convert(m_viewer.get_option_color(libvgcode::EOptionType::Travels)), { {_u8L("travel"), offsets[0] }}, true, predictable_icon_pos/*ORCA checkbox_pos*/, travel_visible, [this, travel_visible]() { + m_viewer.toggle_option_visibility(libvgcode::EOptionType::Travels); + // refresh(*m_gcode_result, wxGetApp().plater()->get_extruder_colors_from_plater_config(m_gcode_result)); update_moves_slider(); - wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); }); ImGui::PopStyleVar(1); break; } - case EViewType::FanSpeed: { append_range(m_extrusions.ranges.fan_speed, 0); break; } - case EViewType::Temperature: { append_range(m_extrusions.ranges.temperature, 0); break; } - case EViewType::LayerTime: { append_range(m_extrusions.ranges.layer_duration, true); break; } - case EViewType::LayerTimeLog: { append_range(m_extrusions.ranges.layer_duration_log, true); break; } - case EViewType::VolumetricRate: { append_range(m_extrusions.ranges.volumetric_rate, 2); break; } - case EViewType::Tool: + case libvgcode::EViewType::ActualSpeed: { + append_range(m_viewer.get_color_range(libvgcode::EViewType::ActualSpeed), 0); + ImGui::Spacing(); + ImGui::Dummy({ window_padding, window_padding }); + ImGui::SameLine(); + offsets = calculate_offsets({ { _u8L("Options"), { _u8L("Travel")}}, { _u8L("Display"), {""}} }, icon_size); + append_headers({ {_u8L("Options"), offsets[0] }, { _u8L("Display"), offsets[1]} }); + const bool travel_visible = m_viewer.is_option_visible(libvgcode::EOptionType::Travels); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 3.0f)); + append_item(EItemType::None, libvgcode::convert(m_viewer.get_option_color(libvgcode::EOptionType::Travels)), { {_u8L("travel"), offsets[0] }}, true, predictable_icon_pos/*ORCA checkbox_pos*/, travel_visible, [this, travel_visible]() { + m_viewer.toggle_option_visibility(libvgcode::EOptionType::Travels); + // refresh(*m_gcode_result, wxGetApp().plater()->get_extruder_colors_from_plater_config(m_gcode_result)); + update_moves_slider(); + }); + ImGui::PopStyleVar(1); + break; + } + case libvgcode::EViewType::FanSpeed: { append_range(m_viewer.get_color_range(libvgcode::EViewType::FanSpeed), 0); break; } + case libvgcode::EViewType::Temperature: { append_range(m_viewer.get_color_range(libvgcode::EViewType::Temperature), 0); break; } + case libvgcode::EViewType::LayerTimeLinear: { append_range(m_viewer.get_color_range(libvgcode::EViewType::LayerTimeLinear), true); break; } + case libvgcode::EViewType::LayerTimeLogarithmic: { append_range(m_viewer.get_color_range(libvgcode::EViewType::LayerTimeLogarithmic), true); break; } + case libvgcode::EViewType::VolumetricFlowRate: { append_range(m_viewer.get_color_range(libvgcode::EViewType::VolumetricFlowRate), 2); break; } + case libvgcode::EViewType::ActualVolumetricFlowRate: { append_range(m_viewer.get_color_range(libvgcode::EViewType::ActualVolumetricFlowRate), 2); break; } + case libvgcode::EViewType::Tool: { // shows only extruders actually used char buf[64]; size_t i = 0; - for (unsigned char extruder_id : m_extruder_ids) { + const std::vector& used_extruders_ids = m_viewer.get_used_extruders_ids(); + for (uint8_t extruder_id : used_extruders_ids) { ::sprintf(buf, imperial_units ? "%.2f in %.2f g" : "%.2f m %.2f g", model_used_filaments_m[i], model_used_filaments_g[i]); - append_item(EItemType::Rect, m_tools.m_tool_colors[extruder_id], { { _u8L("Extruder") + " " + std::to_string(extruder_id + 1), offsets[0]}, {buf, offsets[1]} }); + append_item(EItemType::Rect, libvgcode::convert(m_viewer.get_tool_colors()[extruder_id]), { { _u8L("Extruder") + " " + std::to_string(extruder_id + 1), offsets[0]}, {buf, offsets[1]} }); + // append_item(EItemType::Rect, libvgcode::convert(m_viewer.get_tool_colors()[extruder_id]), _u8L("Extruder") + " " + std::to_string(extruder_id + 1), + // true, "", 0.0f, 0.0f, offsets, used_filaments_m[extruder_id], used_filaments_g[extruder_id]); i++; } break; } - case EViewType::Summary: + case libvgcode::EViewType::Summary: { char buf[64]; imgui.text(_u8L("Total") + ":"); @@ -5425,13 +3542,13 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv imgui.text(short_time(get_time_dhms(time_mode.time))); break; } - case EViewType::ColorPrint: - { + case libvgcode::EViewType::ColorPrint: { //BBS: replace model custom gcode with current plate custom gcode const std::vector& custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes : m_custom_gcode_per_print_z; size_t total_items = 1; // BBS: no ColorChange type, use ToolChange - //for (size_t extruder_id : m_extruder_ids) { + //const std::vector& used_extruders_ids = m_viewer.get_used_extruders_ids(); + //for (uint8_t extruder_id : used_extruders_ids) { // total_items += color_print_ranges(extruder_id, custom_gcode_per_print_z).size(); //} @@ -5443,8 +3560,9 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv // shows only extruders actually used size_t i = 0; - for (auto extruder_idx : m_extruder_ids) { - const bool filament_visible = m_tools.m_tool_visibles[extruder_idx]; + const std::vector& used_extruders_ids = m_viewer.get_used_extruders_ids(); + auto tool_colors = m_viewer.get_tool_colors(); + for (auto extruder_idx : used_extruders_ids) { if (i < model_used_filaments_m.size() && i < model_used_filaments_g.size()) { std::vector> columns_offsets; columns_offsets.push_back({ std::to_string(extruder_idx + 1), color_print_offsets[_u8L("Filament")]}); @@ -5485,23 +3603,17 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv } float checkbox_pos = std::max(predictable_icon_pos, color_print_offsets[_u8L("Display")]); // ORCA prefer predictable_icon_pos when header not reacing end - append_item(EItemType::Rect, m_tools.m_tool_colors[extruder_idx], columns_offsets, true, checkbox_pos/*ORCA*/, filament_visible, [this, extruder_idx]() { - m_tools.m_tool_visibles[extruder_idx] = !m_tools.m_tool_visibles[extruder_idx]; - // update buffers' render paths - refresh_render_paths(false, false); - update_moves_slider(); - wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); - }); + append_item(EItemType::Rect, libvgcode::convert(tool_colors[extruder_idx]), columns_offsets, false, checkbox_pos/*ORCA*/, true, [this, extruder_idx]() {}); } i++; } - + if (need_scrollable) ImGui::EndChild(); // Sum of all rows char buf[64]; - if (m_extruder_ids.size() > 1) { + if (used_extruders_ids.size() > 1) { // Separator ImGuiWindow* window = ImGui::GetCurrentWindow(); const ImRect separator(ImVec2(window->Pos.x + window_padding * 3, window->DC.CursorPos.y), ImVec2(window->Pos.x + window->Size.x - window_padding * 3, window->DC.CursorPos.y + 1.0f)); @@ -5535,7 +3647,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv (total_model_used_filament_g + total_support_used_filament_g + total_flushed_filament_g + total_wipe_tower_used_filament_g) / unit_conver); columns_offsets.push_back({ buf, color_print_offsets[_u8L("Total")] }); } - append_item(EItemType::None, m_tools.m_tool_colors[0], columns_offsets); + append_item(EItemType::None, libvgcode::convert(tool_colors[0]), columns_offsets); } //BBS display filament change times @@ -5560,7 +3672,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv } // partial estimated printing time section - if (m_view_type == EViewType::ColorPrint) { + if (new_view_type == libvgcode::EViewType::ColorPrint) { using Times = std::pair; using TimesList = std::vector>; @@ -5587,9 +3699,10 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv //BBS: replace model custom gcode with current plate custom gcode std::vector custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes : m_custom_gcode_per_print_z; - std::vector last_color(m_extruders_count); - for (size_t i = 0; i < m_extruders_count; ++i) { - last_color[i] = m_tools.m_tool_colors[i]; + const size_t extruders_count = get_extruders_count(); + std::vector last_color(extruders_count); + for (size_t i = 0; i < extruders_count; ++i) { + last_color[i] = libvgcode::convert(m_viewer.get_tool_colors()[i]); } int last_extruder_id = 1; int color_change_idx = 0; @@ -5735,12 +3848,13 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv } // travel paths section - if (m_buffers[buffer_id(EMoveType::Travel)].visible) { - switch (m_view_type) + if (m_viewer.is_option_visible(libvgcode::EOptionType::Travels)) { + switch (m_viewer.get_view_type()) { - case EViewType::Feedrate: - case EViewType::Tool: - case EViewType::ColorPrint: { + case libvgcode::EViewType::Speed: + case libvgcode::EViewType::ActualSpeed: + case libvgcode::EViewType::Tool: + case libvgcode::EViewType::ColorPrint: { break; } default: { @@ -5780,21 +3894,6 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv // } //} - auto any_option_available = [this]() { - auto available = [this](EMoveType type) { - const TBuffer& buffer = m_buffers[buffer_id(type)]; - return buffer.visible && buffer.has_data(); - }; - - return available(EMoveType::Color_change) || - available(EMoveType::Custom_GCode) || - available(EMoveType::Pause_Print) || - available(EMoveType::Retract) || - available(EMoveType::Tool_change) || - available(EMoveType::Unretract) || - available(EMoveType::Seam); - }; - //auto add_option = [this, append_item](EMoveType move_type, EOptionsColors color, const std::string& text) { // const TBuffer& buffer = m_buffers[buffer_id(move_type)]; // if (buffer.visible && buffer.has_data()) @@ -5831,7 +3930,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv has_settings |= has_filament_settings; //BBS: add only gcode mode bool show_settings = m_only_gcode_in_preview; //wxGetApp().is_gcode_viewer(); - show_settings &= (m_view_type == EViewType::FeatureType || m_view_type == EViewType::Tool); + show_settings &= (new_view_type == libvgcode::EViewType::FeatureType || new_view_type == libvgcode::EViewType::Tool); show_settings &= has_settings; if (show_settings) { auto calc_offset = [this]() { @@ -5841,7 +3940,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv if (!m_settings_ids.print.empty()) ret = std::max(ret, ImGui::CalcTextSize((_u8L("Print settings") + std::string(":")).c_str()).x); if (!m_settings_ids.filament.empty()) { - for (unsigned char i : m_extruder_ids) { + for (unsigned char i : m_viewer.get_used_extruders_ids()) { ret = std::max(ret, ImGui::CalcTextSize((_u8L("Filament") + " " + std::to_string(i + 1) + ":").c_str()).x); } } @@ -5866,10 +3965,10 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv imgui.text(m_settings_ids.print); } if (!m_settings_ids.filament.empty()) { - for (unsigned char i : m_extruder_ids) { + for (unsigned char i : m_viewer.get_used_extruders_ids()) { if (i < static_cast(m_settings_ids.filament.size()) && !m_settings_ids.filament[i].empty()) { std::string txt = _u8L("Filament"); - txt += (m_extruder_ids.size() == 1) ? ":" : " " + std::to_string(i + 1); + txt += (m_viewer.get_used_extruders_count() == 1) ? ":" : " " + std::to_string(i + 1); imgui.text(txt); ImGui::SameLine(offset); imgui.text(m_settings_ids.filament[i]); @@ -5904,7 +4003,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv ImGui::CalcTextSize(cgcode_unknown_str.c_str()).x)))) ); - + ImGui::Dummy(ImVec2(0.0f, ImGui::GetFontSize() * 0.1)); ImGui::Dummy({window_padding, window_padding}); ImGui::SameLine(); @@ -5927,12 +4026,12 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv } ImGui::SameLine(max_len); char buf[64]; - int layer = m_layers.get_l_at(custom_gcode.print_z); + int layer = m_viewer.get_layer_id_at(custom_gcode.print_z); ::sprintf(buf, "%d",layer ); imgui.text(buf); ImGui::SameLine(max_len * 1.5); - - std::vector layer_times = m_print_statistics.modes[static_cast(PrintEstimatedStatistics::ETimeMode::Normal)].layers_times; + + std::vector layer_times = m_viewer.get_layers_estimated_times(); float custom_gcode_time = 0; if (layer > 0) { @@ -5948,25 +4047,25 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv // total estimated printing time section ImGui::Spacing(); - std::string time_title = m_view_type == EViewType::FeatureType ? _u8L("Total Estimation") : _u8L("Time Estimation"); - auto can_show_mode_button = [this](PrintEstimatedStatistics::ETimeMode mode) { - bool show = false; - if (m_print_statistics.modes.size() > 1 && m_print_statistics.modes[static_cast(mode)].roles_times.size() > 0) { - for (size_t i = 0; i < m_print_statistics.modes.size(); ++i) { - if (i != static_cast(mode) && - m_print_statistics.modes[i].time > 0.0f && - short_time(get_time_dhms(m_print_statistics.modes[static_cast(mode)].time)) != short_time(get_time_dhms(m_print_statistics.modes[i].time))) { - show = true; - break; - } + std::string time_title = m_viewer.get_view_type() == libvgcode::EViewType::FeatureType ? _u8L("Total Estimation") : _u8L("Time Estimation"); + auto can_show_mode_button = [this](libvgcode::ETimeMode mode) { + std::vector time_strs; + for (size_t i = 0; i < m_print_statistics.modes.size(); ++i) { + if (m_print_statistics.modes[i].time > 0.0f) { + const std::string time_str = short_time(get_time_dhms(m_print_statistics.modes[i].time)); + const auto it = std::find(time_strs.begin(), time_strs.end(), time_str); + if (it == time_strs.end()) + time_strs.emplace_back(time_str); } } - return show; + return time_strs.size() > 1; }; - if (can_show_mode_button(m_time_estimate_mode)) { - switch (m_time_estimate_mode) + + const libvgcode::ETimeMode time_mode_id = m_viewer.get_time_mode(); + if (can_show_mode_button(time_mode_id)) { + switch (time_mode_id) { - case PrintEstimatedStatistics::ETimeMode::Normal: { time_title += " [" + _u8L("Normal mode") + "]"; break; } + case libvgcode::ETimeMode::Normal: { time_title += " [" + _u8L("Normal mode") + "]"; break; } default: { assert(false); break; } } } @@ -5980,11 +4079,11 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv std::string prepare_str = _u8L("Prepare time"); std::string print_str = _u8L("Model printing time"); std::string total_str = _u8L("Total time"); - float max_len = window_padding + 2 * ImGui::GetStyle().ItemSpacing.x; - if (time_mode.layers_times.empty()) + float max_len = window_padding + 2 * ImGui::GetStyle().ItemSpacing.x; + if (m_viewer.get_layers_estimated_times().empty()) max_len += ImGui::CalcTextSize(total_str.c_str()).x; else { - if (m_view_type == EViewType::FeatureType) + if (m_viewer.get_view_type() == libvgcode::EViewType::FeatureType) max_len += std::max(ImGui::CalcTextSize(cost_str.c_str()).x, std::max(ImGui::CalcTextSize(print_str.c_str()).x, std::max(std::max(ImGui::CalcTextSize(prepare_str.c_str()).x, ImGui::CalcTextSize(total_str.c_str()).x), @@ -5993,7 +4092,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv max_len += std::max(ImGui::CalcTextSize(print_str.c_str()).x, (std::max(ImGui::CalcTextSize(prepare_str.c_str()).x, ImGui::CalcTextSize(total_str.c_str()).x))); } - if (m_view_type == EViewType::FeatureType) { + if (m_viewer.get_view_type() == libvgcode::EViewType::FeatureType) { //BBS display filament cost ImGui::Dummy({ window_padding, window_padding }); ImGui::SameLine(); @@ -6026,10 +4125,6 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv ::sprintf(buf, "%.2f", ps.total_cost); imgui.text(buf); } - auto role_time = [time_mode](ExtrusionRole role) { - auto it = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [role](const std::pair& item) { return role == item.first; }); - return (it != time_mode.roles_times.end()) ? it->second : 0.0f; - }; //BBS: start gcode is mostly same with prepeare time if (time_mode.prepare_time != 0.0f) { ImGui::Dummy({ window_padding, window_padding }); @@ -6049,44 +4144,44 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv ImGui::SameLine(max_len); imgui.text(short_time(get_time_dhms(time_mode.time))); - auto show_mode_button = [this, &imgui, can_show_mode_button](const wxString& label, PrintEstimatedStatistics::ETimeMode mode) { + auto show_mode_button = [this, &imgui, can_show_mode_button](const std::string& label, libvgcode::ETimeMode mode) { if (can_show_mode_button(mode)) { if (imgui.button(label)) { - m_time_estimate_mode = mode; + m_viewer.set_time_mode(mode); #if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT imgui.set_requires_extra_frame(); #else wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); - wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); + wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); #endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT } } }; - switch (m_time_estimate_mode) { - case PrintEstimatedStatistics::ETimeMode::Normal: { - show_mode_button(_L("Switch to silent mode"), PrintEstimatedStatistics::ETimeMode::Stealth); + switch (time_mode_id) { + case libvgcode::ETimeMode::Normal: { + show_mode_button(_u8L("Show stealth mode"), libvgcode::ETimeMode::Stealth); break; } - case PrintEstimatedStatistics::ETimeMode::Stealth: { - show_mode_button(_L("Switch to normal mode"), PrintEstimatedStatistics::ETimeMode::Normal); + case libvgcode::ETimeMode::Stealth: { + show_mode_button(_u8L("Show normal mode"), libvgcode::ETimeMode::Normal); break; } default : { assert(false); break; } } - if (m_view_type == EViewType::ColorPrint) { + if (m_viewer.get_view_type() == libvgcode::EViewType::ColorPrint) { ImGui::Spacing(); ImGui::Dummy({ window_padding, window_padding }); ImGui::SameLine(); offsets = calculate_offsets({ { _u8L("Options"), { ""}}, { _u8L("Display"), {""}} }, icon_size); offsets[1] = std::max(predictable_icon_pos, color_print_offsets[_u8L("Display")]); // ORCA prefer predictable_icon_pos when header not reacing end append_headers({ {_u8L("Options"), offsets[0] }, { _u8L("Display"), offsets[1]} }); - for (auto item : options_items) + for (auto item : m_viewer.get_options()) append_option_item(item, offsets); } ImGui::Dummy({ window_padding, window_padding }); - if (m_nozzle_nums > 1 && (m_view_type == EViewType::Summary || m_view_type == EViewType::ColorPrint)) // ORCA show only on summary and filament tab + if (m_nozzle_nums > 1 && (m_viewer.get_view_type() == libvgcode::EViewType::Summary || m_viewer.get_view_type() == libvgcode::EViewType::ColorPrint)) // ORCA show only on summary and filament tab render_legend_color_arr_recommen(window_padding); legend_height = ImGui::GetCurrentWindow()->Size.y; @@ -6120,145 +4215,6 @@ void GCodeViewer::render_slider(int canvas_width, int canvas_height) { m_layers_slider->render(canvas_width, canvas_height); } -#if ENABLE_GCODE_VIEWER_STATISTICS -void GCodeViewer::render_statistics() -{ - static const float offset = 275.0f; - - ImGuiWrapper& imgui = *wxGetApp().imgui(); - - auto add_time = [&imgui](const std::string& label, int64_t time) { - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label); - ImGui::SameLine(offset); - imgui.text(std::to_string(time) + " ms (" + get_time_dhms(static_cast(time) * 0.001f) + ")"); - }; - - auto add_memory = [&imgui](const std::string& label, int64_t memory) { - auto format_string = [memory](const std::string& units, float value) { - return std::to_string(memory) + " bytes (" + - Slic3r::float_to_string_decimal_point(float(memory) * value, 3) - + " " + units + ")"; - }; - - static const float kb = 1024.0f; - static const float inv_kb = 1.0f / kb; - static const float mb = 1024.0f * kb; - static const float inv_mb = 1.0f / mb; - static const float gb = 1024.0f * mb; - static const float inv_gb = 1.0f / gb; - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label); - ImGui::SameLine(offset); - if (static_cast(memory) < mb) - imgui.text(format_string("KB", inv_kb)); - else if (static_cast(memory) < gb) - imgui.text(format_string("MB", inv_mb)); - else - imgui.text(format_string("GB", inv_gb)); - }; - - auto add_counter = [&imgui](const std::string& label, int64_t counter) { - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label); - ImGui::SameLine(offset); - imgui.text(std::to_string(counter)); - }; - - imgui.set_next_window_pos(0.5f * wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_width(), 0.0f, ImGuiCond_Once, 0.5f, 0.0f); - ImGui::SetNextWindowSizeConstraints({ 300.0f, 100.0f }, { 600.0f, 900.0f }); - imgui.begin(std::string("GCodeViewer Statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize); - ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow()); - - if (ImGui::CollapsingHeader("Time")) { - add_time(std::string("GCodeProcessor:"), m_statistics.results_time); - - ImGui::Separator(); - add_time(std::string("Load:"), m_statistics.load_time); - add_time(std::string(" Load vertices:"), m_statistics.load_vertices); - add_time(std::string(" Smooth vertices:"), m_statistics.smooth_vertices); - add_time(std::string(" Load indices:"), m_statistics.load_indices); - add_time(std::string("Refresh:"), m_statistics.refresh_time); - add_time(std::string("Refresh paths:"), m_statistics.refresh_paths_time); - } - - if (ImGui::CollapsingHeader("OpenGL calls")) { - add_counter(std::string("Multi GL_LINES:"), m_statistics.gl_multi_lines_calls_count); - add_counter(std::string("Multi GL_TRIANGLES:"), m_statistics.gl_multi_triangles_calls_count); - add_counter(std::string("GL_TRIANGLES:"), m_statistics.gl_triangles_calls_count); - ImGui::Separator(); - add_counter(std::string("Instanced models:"), m_statistics.gl_instanced_models_calls_count); - add_counter(std::string("Batched models:"), m_statistics.gl_batched_models_calls_count); - } - - if (ImGui::CollapsingHeader("CPU memory")) { - add_memory(std::string("GCodeProcessor results:"), m_statistics.results_size); - - ImGui::Separator(); - add_memory(std::string("Paths:"), m_statistics.paths_size); - add_memory(std::string("Render paths:"), m_statistics.render_paths_size); - add_memory(std::string("Models instances:"), m_statistics.models_instances_size); - } - - if (ImGui::CollapsingHeader("GPU memory")) { - add_memory(std::string("Vertices:"), m_statistics.total_vertices_gpu_size); - add_memory(std::string("Indices:"), m_statistics.total_indices_gpu_size); - add_memory(std::string("Instances:"), m_statistics.total_instances_gpu_size); - ImGui::Separator(); - add_memory(std::string("Max VBuffer:"), m_statistics.max_vbuffer_gpu_size); - add_memory(std::string("Max IBuffer:"), m_statistics.max_ibuffer_gpu_size); - } - - if (ImGui::CollapsingHeader("Other")) { - add_counter(std::string("Travel segments count:"), m_statistics.travel_segments_count); - add_counter(std::string("Wipe segments count:"), m_statistics.wipe_segments_count); - add_counter(std::string("Extrude segments count:"), m_statistics.extrude_segments_count); - add_counter(std::string("Instances count:"), m_statistics.instances_count); - add_counter(std::string("Batched count:"), m_statistics.batched_count); - ImGui::Separator(); - add_counter(std::string("VBuffers count:"), m_statistics.vbuffers_count); - add_counter(std::string("IBuffers count:"), m_statistics.ibuffers_count); - } - - imgui.end(); -} -#endif // ENABLE_GCODE_VIEWER_STATISTICS - -void GCodeViewer::log_memory_used(const std::string& label, int64_t additional) const -{ - if (Slic3r::get_logging_level() >= 5) { - int64_t paths_size = 0; - int64_t render_paths_size = 0; - for (const TBuffer& buffer : m_buffers) { - paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path); - render_paths_size += SLIC3R_STDUNORDEREDSET_MEMSIZE(buffer.render_paths, RenderPath); - for (const RenderPath& path : buffer.render_paths) { - render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.sizes, unsigned int); - render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t); - } - } - int64_t layers_size = SLIC3R_STDVEC_MEMSIZE(m_layers.get_zs(), double); - layers_size += SLIC3R_STDVEC_MEMSIZE(m_layers.get_endpoints(), Layers::Endpoints); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format("paths_size %1%, render_paths_size %2%,layers_size %3%, additional %4%\n") - %paths_size %render_paths_size %layers_size %additional; - BOOST_LOG_TRIVIAL(trace) << label - << "(" << format_memsize_MB(additional + paths_size + render_paths_size + layers_size) << ");" - << log_memory_info(); - } -} - -ColorRGBA GCodeViewer::option_color(EMoveType move_type) const -{ - switch (move_type) - { - case EMoveType::Tool_change: { return Options_Colors[static_cast(EOptionsColors::ToolChanges)]; } - case EMoveType::Color_change: { return Options_Colors[static_cast(EOptionsColors::ColorChanges)]; } - case EMoveType::Pause_Print: { return Options_Colors[static_cast(EOptionsColors::PausePrints)]; } - case EMoveType::Custom_GCode: { return Options_Colors[static_cast(EOptionsColors::CustomGCodes)]; } - case EMoveType::Retract: { return Options_Colors[static_cast(EOptionsColors::Retractions)]; } - case EMoveType::Unretract: { return Options_Colors[static_cast(EOptionsColors::Unretractions)]; } - case EMoveType::Seam: { return Options_Colors[static_cast(EOptionsColors::Seams)]; } - default: { return { 0.0f, 0.0f, 0.0f, 1.0f }; } - } -} - } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 7c86a37e1c..ba4f3702db 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -10,6 +10,10 @@ #include +#include "LibVGCode/LibVGCodeWrapper.hpp" +// needed for tech VGCODE_ENABLE_COG_AND_TOOL_MARKERS +#include + #include #include #include @@ -33,584 +37,44 @@ static const float SLIDER_RIGHT_MARGIN = 124.0f; static const float SLIDER_BOTTOM_MARGIN = 64.0f; class GCodeViewer { - using IBufferType = unsigned short; - using VertexBuffer = std::vector; - using MultiVertexBuffer = std::vector; - using IndexBuffer = std::vector; - using MultiIndexBuffer = std::vector; - using InstanceBuffer = std::vector; - using InstanceIdBuffer = std::vector; - using InstancesOffsets = std::vector; - - static const std::vector Extrusion_Role_Colors; - static const std::vector Options_Colors; - static const std::vector Travel_Colors; - static const std::vector Range_Colors; - static const ColorRGBA Wipe_Color; - static const ColorRGBA Neutral_Color; - - enum class EOptionsColors : unsigned char - { - Retractions, - Unretractions, - Seams, - ToolChanges, - ColorChanges, - PausePrints, - CustomGCodes - }; - - // vbo buffer containing vertices data used to render a specific toolpath type - struct VBuffer - { - enum class EFormat : unsigned char - { - // vertex format: 3 floats -> position.x|position.y|position.z - Position, - // vertex format: 4 floats -> position.x|position.y|position.z|normal.x - PositionNormal1, - // vertex format: 6 floats -> position.x|position.y|position.z|normal.x|normal.y|normal.z - PositionNormal3 - }; - - EFormat format{ EFormat::Position }; - // vbos id - std::vector vbos; - // sizes of the buffers, in bytes, used in export to obj - std::vector sizes; - // count of vertices, updated after data are sent to gpu - size_t count{ 0 }; - - size_t data_size_bytes() const { return count * vertex_size_bytes(); } - // We set 65536 as max count of vertices inside a vertex buffer to allow - // to use unsigned short in place of unsigned int for indices in the index buffer, to save memory - size_t max_size_bytes() const { return 65536 * vertex_size_bytes(); } - - size_t vertex_size_floats() const { return position_size_floats() + normal_size_floats(); } - size_t vertex_size_bytes() const { return vertex_size_floats() * sizeof(float); } - - size_t position_offset_floats() const { return 0; } - size_t position_offset_bytes() const { return position_offset_floats() * sizeof(float); } - - size_t position_size_floats() const { return 3; } - size_t position_size_bytes() const { return position_size_floats() * sizeof(float); } - - size_t normal_offset_floats() const { - assert(format == EFormat::PositionNormal1 || format == EFormat::PositionNormal3); - return position_size_floats(); - } - size_t normal_offset_bytes() const { return normal_offset_floats() * sizeof(float); } - - size_t normal_size_floats() const { - switch (format) - { - case EFormat::PositionNormal1: { return 1; } - case EFormat::PositionNormal3: { return 3; } - default: { return 0; } - } - } - size_t normal_size_bytes() const { return normal_size_floats() * sizeof(float); } - - void reset(); - }; - - // buffer containing instances data used to render a toolpaths using instanced or batched models - // instance record format: - // instanced models: 5 floats -> position.x|position.y|position.z|width|height (which are sent to the shader as -> vec3 (offset) + vec2 (scales) in GLModel::render_instanced()) - // batched models: 3 floats -> position.x|position.y|position.z - struct InstanceVBuffer - { - // ranges used to render only subparts of the intances - struct Ranges - { - struct Range - { - // offset in bytes of the 1st instance to render - unsigned int offset; - // count of instances to render - unsigned int count; - // vbo id - unsigned int vbo{ 0 }; - // Color to apply to the instances - ColorRGBA color; - }; - - std::vector ranges; - - void reset(); - }; - - enum class EFormat : unsigned char - { - InstancedModel, - BatchedModel - }; - - EFormat format; - - // cpu-side buffer containing all instances data - InstanceBuffer buffer; - // indices of the moves for all instances - std::vector s_ids; - // position offsets, used to show the correct value of the tool position - InstancesOffsets offsets; - Ranges render_ranges; - - size_t data_size_bytes() const { return s_ids.size() * instance_size_bytes(); } - - size_t instance_size_floats() const { - switch (format) - { - case EFormat::InstancedModel: { return 5; } - case EFormat::BatchedModel: { return 3; } - default: { return 0; } - } - } - size_t instance_size_bytes() const { return instance_size_floats() * sizeof(float); } - - void reset(); - }; - - // ibo buffer containing indices data (for lines/triangles) used to render a specific toolpath type - struct IBuffer - { - // id of the associated vertex buffer - unsigned int vbo{ 0 }; - // ibo id - unsigned int ibo{ 0 }; - // count of indices, updated after data are sent to gpu - size_t count{ 0 }; - - void reset(); - }; - - // Used to identify different toolpath sub-types inside a IBuffer - struct Path - { - struct Endpoint - { - // index of the buffer in the multibuffer vector - // the buffer type may change: - // it is the vertex buffer while extracting vertices data, - // the index buffer while extracting indices data - unsigned int b_id{ 0 }; - // index into the buffer - size_t i_id{ 0 }; - // move id - size_t s_id{ 0 }; - Vec3f position{ Vec3f::Zero() }; - }; - - struct Sub_Path - { - Endpoint first; - Endpoint last; - - bool contains(size_t s_id) const { - return first.s_id <= s_id && s_id <= last.s_id; - } - }; - - EMoveType type{ EMoveType::Noop }; - ExtrusionRole role{ erNone }; - float delta_extruder{ 0.0f }; - float height{ 0.0f }; - float width{ 0.0f }; - float feedrate{ 0.0f }; - float fan_speed{ 0.0f }; - float temperature{ 0.0f }; - float volumetric_rate{ 0.0f }; - float layer_time{ 0.0f }; - unsigned char extruder_id{ 0 }; - unsigned char cp_color_id{ 0 }; - std::vector sub_paths; - - bool matches(const GCodeProcessorResult::MoveVertex& move) const; - size_t vertices_count() const { - return sub_paths.empty() ? 0 : sub_paths.back().last.s_id - sub_paths.front().first.s_id + 1; - } - bool contains(size_t s_id) const { - return sub_paths.empty() ? false : sub_paths.front().first.s_id <= s_id && s_id <= sub_paths.back().last.s_id; - } - int get_id_of_sub_path_containing(size_t s_id) const { - if (sub_paths.empty()) - return -1; - else { - for (int i = 0; i < static_cast(sub_paths.size()); ++i) { - if (sub_paths[i].contains(s_id)) - return i; - } - return -1; - } - } - void add_sub_path(const GCodeProcessorResult::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id) { - Endpoint endpoint = { b_id, i_id, s_id, move.position }; - sub_paths.push_back({ endpoint , endpoint }); - } - }; - - // Used to batch the indices needed to render the paths - struct RenderPath - { - // Index of the parent tbuffer - unsigned char tbuffer_id; - // Render path property - ColorRGBA color; - // Index of the buffer in TBuffer::indices - unsigned int ibuffer_id; - // Render path content - // Index of the path in TBuffer::paths - unsigned int path_id; - std::vector sizes; - std::vector offsets; // use size_t because we need an unsigned integer whose size matches pointer's size (used in the call glMultiDrawElements()) - bool contains(size_t offset) const { - for (size_t i = 0; i < offsets.size(); ++i) { - if (offsets[i] <= offset && offset <= offsets[i] + static_cast(sizes[i] * sizeof(IBufferType))) - return true; - } - return false; - } - }; - struct RenderPathPropertyLower { - bool operator() (const RenderPath &l, const RenderPath &r) const { - if (l.tbuffer_id < r.tbuffer_id) - return true; - if (l.color < r.color) - return true; - else if (l.color > r.color) - return false; - return l.ibuffer_id < r.ibuffer_id; - } - }; - struct RenderPathPropertyEqual { - bool operator() (const RenderPath &l, const RenderPath &r) const { - return l.tbuffer_id == r.tbuffer_id && l.ibuffer_id == r.ibuffer_id && l.color == r.color; - } - }; - - // buffer containing data for rendering a specific toolpath type - struct TBuffer - { - enum class ERenderPrimitiveType : unsigned char - { - Line, - Triangle, - InstancedModel, - BatchedModel - }; - - ERenderPrimitiveType render_primitive_type; - - // buffers for point, line and triangle primitive types - VBuffer vertices; - std::vector indices; - - struct Model - { - GLModel model; - ColorRGBA color; - InstanceVBuffer instances; - GLModel::Geometry data; - - void reset(); - }; - - // contain the buffer for model primitive types - Model model; - - std::string shader; - std::vector paths; - std::vector render_paths; - bool visible{ false }; - - void reset(); - - // b_id index of buffer contained in this->indices - // i_id index of first index contained in this->indices[b_id] - // s_id index of first vertex contained in this->vertices - void add_path(const GCodeProcessorResult::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id); - - unsigned int max_vertices_per_segment() const { - switch (render_primitive_type) - { - case ERenderPrimitiveType::Line: { return 2; } - case ERenderPrimitiveType::Triangle: { return 8; } - default: { return 0; } - } - } - - size_t max_vertices_per_segment_size_floats() const { return vertices.vertex_size_floats() * static_cast(max_vertices_per_segment()); } - size_t max_vertices_per_segment_size_bytes() const { return max_vertices_per_segment_size_floats() * sizeof(float); } - unsigned int indices_per_segment() const { - switch (render_primitive_type) - { - case ERenderPrimitiveType::Line: { return 2; } - case ERenderPrimitiveType::Triangle: { return 30; } // 3 indices x 10 triangles - default: { return 0; } - } - } - size_t indices_per_segment_size_bytes() const { return static_cast(indices_per_segment() * sizeof(IBufferType)); } - unsigned int max_indices_per_segment() const { - switch (render_primitive_type) - { - case ERenderPrimitiveType::Line: { return 2; } - case ERenderPrimitiveType::Triangle: { return 36; } // 3 indices x 12 triangles - default: { return 0; } - } - } - size_t max_indices_per_segment_size_bytes() const { return max_indices_per_segment() * sizeof(IBufferType); } - - bool has_data() const { - switch (render_primitive_type) - { - case ERenderPrimitiveType::Line: - case ERenderPrimitiveType::Triangle: { - return !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0; - } - case ERenderPrimitiveType::InstancedModel: { return model.model.is_initialized() && !model.instances.buffer.empty(); } - case ERenderPrimitiveType::BatchedModel: { - return !model.data.vertices.empty() && !model.data.indices.empty() && - !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0; - } - default: { return false; } - } - } - }; - - - // helper to render extrusion paths - struct Extrusions - { - struct Range - { - float min; - float max; - unsigned int count; - bool log_scale; - - Range() { reset(); } - void update_from(const float value) { - if (value != max && value != min) - ++count; - min = std::min(min, value); - max = std::max(max, value); - } - void reset(bool log = false) { min = FLT_MAX; max = -FLT_MAX; count = 0; log_scale = log; } - - float step_size() const; - ColorRGBA get_color_at(float value) const; - float get_value_at_step(int step) const; - - }; - - struct Ranges - { - // Color mapping by layer height. - Range height; - // Color mapping by extrusion width. - Range width; - // Color mapping by feedrate. - Range feedrate; - // Color mapping by fan speed. - Range fan_speed; - // Color mapping by volumetric extrusion rate. - Range volumetric_rate; - // Color mapping by extrusion temperature. - Range temperature; - // Color mapping by layer time. - Range layer_duration; -Range layer_duration_log; - void reset() { - height.reset(); - width.reset(); - feedrate.reset(); - fan_speed.reset(); - volumetric_rate.reset(); - temperature.reset(); - layer_duration.reset(); - layer_duration_log.reset(true); - } - }; - - unsigned int role_visibility_flags{ 0 }; - Ranges ranges; - - void reset_role_visibility_flags() { - role_visibility_flags = 0; - for (unsigned int i = 0; i < erCount; ++i) { - role_visibility_flags |= 1 << i; - } - } - - void reset_ranges() { ranges.reset(); } - }; - - class Layers - { - public: - struct Endpoints - { - size_t first{ 0 }; - size_t last{ 0 }; - - bool operator == (const Endpoints& other) const { return first == other.first && last == other.last; } - bool operator != (const Endpoints& other) const { return !operator==(other); } - }; - - private: - std::vector m_zs; - std::vector m_endpoints; - - public: - void append(double z, Endpoints endpoints) { - m_zs.emplace_back(z); - m_endpoints.emplace_back(endpoints); - } - - void reset() { - m_zs = std::vector(); - m_endpoints = std::vector(); - } - - size_t size() const { return m_zs.size(); } - bool empty() const { return m_zs.empty(); } - const std::vector& get_zs() const { return m_zs; } - const std::vector& get_endpoints() const { return m_endpoints; } - std::vector& get_endpoints() { return m_endpoints; } - double get_z_at(unsigned int id) const { return (id < m_zs.size()) ? m_zs[id] : 0.0; } - Endpoints get_endpoints_at(unsigned int id) const { return (id < m_endpoints.size()) ? m_endpoints[id] : Endpoints(); } - int get_l_at(float z) const - { - auto iter = std::upper_bound(m_zs.begin(), m_zs.end(), z); - return std::distance(m_zs.begin(), iter); - } - - bool operator != (const Layers& other) const { - if (m_zs != other.m_zs) - return true; - if (m_endpoints != other.m_endpoints) - return true; - return false; - } - }; - - // used to render the toolpath caps of the current sequential range - // (i.e. when sliding on the horizontal slider) - struct SequentialRangeCap - { - TBuffer* buffer{ nullptr }; - unsigned int ibo{ 0 }; - unsigned int vbo{ 0 }; - ColorRGBA color; - - ~SequentialRangeCap(); - bool is_renderable() const { return buffer != nullptr; } - void reset(); - size_t indices_count() const { return 6; } - }; - -#if ENABLE_GCODE_VIEWER_STATISTICS - struct Statistics - { - // time - int64_t results_time{ 0 }; - int64_t load_time{ 0 }; - int64_t load_vertices{ 0 }; - int64_t smooth_vertices{ 0 }; - int64_t load_indices{ 0 }; - int64_t refresh_time{ 0 }; - int64_t refresh_paths_time{ 0 }; - // opengl calls - int64_t gl_multi_lines_calls_count{ 0 }; - int64_t gl_multi_triangles_calls_count{ 0 }; - int64_t gl_triangles_calls_count{ 0 }; - int64_t gl_instanced_models_calls_count{ 0 }; - int64_t gl_batched_models_calls_count{ 0 }; - // memory - int64_t results_size{ 0 }; - int64_t total_vertices_gpu_size{ 0 }; - int64_t total_indices_gpu_size{ 0 }; - int64_t total_instances_gpu_size{ 0 }; - int64_t max_vbuffer_gpu_size{ 0 }; - int64_t max_ibuffer_gpu_size{ 0 }; - int64_t paths_size{ 0 }; - int64_t render_paths_size{ 0 }; - int64_t models_instances_size{ 0 }; - // other - int64_t travel_segments_count{ 0 }; - int64_t wipe_segments_count{ 0 }; - int64_t extrude_segments_count{ 0 }; - int64_t instances_count{ 0 }; - int64_t batched_count{ 0 }; - int64_t vbuffers_count{ 0 }; - int64_t ibuffers_count{ 0 }; - - void reset_all() { - reset_times(); - reset_opengl(); - reset_sizes(); - reset_others(); - } - - void reset_times() { - results_time = 0; - load_time = 0; - load_vertices = 0; - smooth_vertices = 0; - load_indices = 0; - refresh_time = 0; - refresh_paths_time = 0; - } - - void reset_opengl() { - gl_multi_lines_calls_count = 0; - gl_multi_triangles_calls_count = 0; - gl_triangles_calls_count = 0; - gl_instanced_models_calls_count = 0; - gl_batched_models_calls_count = 0; - } - - void reset_sizes() { - results_size = 0; - total_vertices_gpu_size = 0; - total_indices_gpu_size = 0; - total_instances_gpu_size = 0; - max_vbuffer_gpu_size = 0; - max_ibuffer_gpu_size = 0; - paths_size = 0; - render_paths_size = 0; - models_instances_size = 0; - } - - void reset_others() { - travel_segments_count = 0; - wipe_segments_count = 0; - extrude_segments_count = 0; - instances_count = 0; - batched_count = 0; - vbuffers_count = 0; - ibuffers_count = 0; - } - }; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - public: enum class EViewType : unsigned char; struct SequentialView { +#if ENABLE_ACTUAL_SPEED_DEBUG + struct ActualSpeedImguiWidget + { + std::pair y_range = { 0.0f, 0.0f }; + std::vector> levels; + struct Item + { + float pos{ 0.0f }; + float speed{ 0.0f }; + bool internal{ false }; + }; + std::vector data; + int plot(const char* label, const std::array& frame_size = { 0.0f, 0.0f }); + }; +#endif // ENABLE_ACTUAL_SPEED_DEBUG + class Marker { GLModel m_model; Vec3f m_world_position; - Transform3f m_world_transform; // for seams, the position of the marker is on the last endpoint of the toolpath containing it // the offset is used to show the correct value of tool position in the "ToolPosition" window // see implementation of render() method Vec3f m_world_offset; - float m_z_offset{ 0.5f }; - GCodeProcessorResult::MoveVertex m_curr_move; + float m_z_offset{ 0.0f }; + // z offset of the model + float m_model_z_offset{ 0.5f }; bool m_visible{ true }; bool m_is_dark = false; + bool m_fixed_screen_size{ false }; + float m_scale_factor{ 1.0f }; +#if ENABLE_ACTUAL_SPEED_DEBUG + ActualSpeedImguiWidget m_actual_speed_imgui_widget; +#endif // ENABLE_ACTUAL_SPEED_DEBUG public: float m_scale = 1.0f; @@ -619,16 +83,28 @@ public: const BoundingBoxf3& get_bounding_box() const { return m_model.get_bounding_box(); } - void set_world_position(const Vec3f& position); + void set_world_position(const Vec3f& position) { m_world_position = position; } void set_world_offset(const Vec3f& offset) { m_world_offset = offset; } + void set_z_offset(float z_offset) { m_z_offset = z_offset; } + +#if ENABLE_ACTUAL_SPEED_DEBUG + void set_actual_speed_y_range(const std::pair& y_range) { + m_actual_speed_imgui_widget.y_range = y_range; + } + void set_actual_speed_levels(const std::vector>& levels) { + m_actual_speed_imgui_widget.levels = levels; + } + void set_actual_speed_data(const std::vector& data) { + m_actual_speed_imgui_widget.data = data; + } +#endif // ENABLE_ACTUAL_SPEED_DEBUG bool is_visible() const { return m_visible; } void set_visible(bool visible) { m_visible = visible; } - void render(int canvas_width, int canvas_height, const EViewType& view_type); + void render(int canvas_width, int canvas_height, const libvgcode::EViewType& view_type); + void render_position_window(const libvgcode::Viewer* viewer, int canvas_width, int canvas_height); void on_change_color_mode(bool is_dark) { m_is_dark = is_dark; } - - void update_curr_move(const GCodeProcessorResult::MoveVertex move); }; class GCodeWindow @@ -672,33 +148,12 @@ public: void stop_mapping_file(); }; - struct Endpoints - { - size_t first{ 0 }; - size_t last{ 0 }; - }; - - bool skip_invisible_moves{ false }; - Endpoints endpoints; - Endpoints current; - Endpoints last_current; - Endpoints global; - Vec3f current_position{ Vec3f::Zero() }; - Vec3f current_offset{ Vec3f::Zero() }; Marker marker; GCodeWindow gcode_window; - std::vector gcode_ids; float m_scale = 1.0; bool m_show_marker = false; - void render(const bool has_render_path, float legend_height, int canvas_width, int canvas_height, int right_margin, const EViewType& view_type); + void render(const bool has_render_path, float legend_height, const libvgcode::Viewer* viewer, uint32_t gcode_id, int canvas_width, int canvas_height, int right_margin, const libvgcode::EViewType& view_type); }; - - struct ETools - { - std::vector m_tool_colors; - std::vector m_tool_visibles; - }; - struct ExtruderFilament { std::string type; @@ -706,24 +161,6 @@ public: unsigned char filament_id; bool is_support_filament; }; - - enum class EViewType : unsigned char - { - Summary = 0, - FeatureType, - Height, - Width, - Feedrate, - FanSpeed, - Temperature, - VolumetricRate, - Tool, - ColorPrint, - FilamentId, - LayerTime, - LayerTimeLog, - Count - }; // helper to render shells struct Shells { @@ -744,19 +181,16 @@ private: std::vector m_plater_extruder; bool m_gl_data_initialized{ false }; unsigned int m_last_result_id{ 0 }; - size_t m_moves_count{ 0 }; //BBS: save m_gcode_result as well const GCodeProcessorResult* m_gcode_result; //BBS: add only gcode mode bool m_only_gcode_in_preview {false}; - std::vector m_ssid_to_moveid_map; //BBS: extruder dispensing filament std::vector m_left_extruder_filament; std::vector m_right_extruder_filament; size_t m_nozzle_nums; - std::vector m_buffers{ static_cast(EMoveType::Extrude) }; // bounding box of toolpaths BoundingBoxf3 m_paths_bounding_box; // bounding box of toolpaths + marker tools @@ -764,41 +198,38 @@ private: //BBS: add shell bounding box BoundingBoxf3 m_shell_bounding_box; float m_max_print_height{ 0.0f }; + float m_z_offset{ 0.0f }; - //BBS save m_tools_color and m_tools_visible - ETools m_tools; ConfigOptionMode m_user_mode; bool m_fold = {false}; - Layers m_layers; - std::array m_layers_z_range; - std::vector m_roles; size_t m_extruders_count; - std::vector m_extruder_ids; std::vector m_filament_diameters; std::vector m_filament_densities; - Extrusions m_extrusions; SequentialView m_sequential_view; IMSlider* m_moves_slider; IMSlider* m_layers_slider; +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + // whether or not to render the cog model with fixed screen size + bool m_cog_marker_fixed_screen_size{ true }; + float m_cog_marker_size{ 1.0f }; + bool m_tool_marker_fixed_screen_size{ false }; + float m_tool_marker_size{ 1.0f }; +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS /*BBS GUI refactor, store displayed items in color scheme combobox */ - std::vector view_type_items; + std::vector view_type_items; std::vector view_type_items_str; int m_view_type_sel = 0; - EViewType m_view_type{ EViewType::FeatureType }; std::vector options_items; + bool m_legend_visible{ true }; bool m_legend_enabled{ true }; + float m_legend_height; PrintEstimatedStatistics m_print_statistics; - PrintEstimatedStatistics::ETimeMode m_time_estimate_mode{ PrintEstimatedStatistics::ETimeMode::Normal }; -#if ENABLE_GCODE_VIEWER_STATISTICS - Statistics m_statistics; -#endif // ENABLE_GCODE_VIEWER_STATISTICS std::array m_detected_point_sizes = { 0.0f, 0.0f }; GCodeProcessorResult::SettingsIds m_settings_ids; - std::array m_sequential_range_caps; std::vector m_custom_gcode_per_print_z; @@ -806,6 +237,9 @@ private: mutable bool m_no_render_path { false }; bool m_is_dark = false; + libvgcode::Viewer m_viewer; + bool m_loaded_as_preview{ false }; + public: GCodeViewer(); ~GCodeViewer(); @@ -818,11 +252,10 @@ public: // extract rendering data from the given parameters //BBS: add only gcode mode - void load(const GCodeProcessorResult& gcode_result, const Print& print, const BuildVolume& build_volume, - const std::vector& exclude_bounding_box, ConfigOptionMode mode, bool only_gcode = false); - // recalculate ranges in dependence of what is visible and sets tool/print colors - void refresh(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors); - void refresh_render_paths(); + void load_as_gcode(const GCodeProcessorResult& gcode_result, const Print& print, const std::vector& str_tool_colors, + const std::vector& str_color_print_colors, const BuildVolume& build_volume, + const std::vector& exclude_bounding_box, ConfigOptionMode mode, bool only_gcode = false); + void load_as_preview(libvgcode::GCodeInputData&& data); void update_shells_color_by_extruder(const DynamicPrintConfig* config); void set_shell_transparency(float alpha = 0.15f); @@ -836,11 +269,11 @@ public: //BBS: GUI refactor: add canvas width and height void render(int canvas_width, int canvas_height, int right_margin); //BBS - void _render_calibration_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager); - void _render_calibration_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager); - void render_calibration_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager); + // void _render_calibration_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager); + // void _render_calibration_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager); + // void render_calibration_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager); + bool has_data() const { return !m_viewer.get_extrusion_roles().empty(); } - bool has_data() const { return !m_roles.empty(); } bool can_export_toolpaths() const; std::vector get_plater_extruder(); @@ -848,8 +281,15 @@ public: const BoundingBoxf3& get_paths_bounding_box() const { return m_paths_bounding_box; } const BoundingBoxf3& get_max_bounding_box() const { return m_max_bounding_box; } const BoundingBoxf3& get_shell_bounding_box() const { return m_shell_bounding_box; } - const std::vector& get_layers_zs() const { return m_layers.get_zs(); } - const std::array &get_layers_z_range() const { return m_layers_z_range; } + std::vector get_layers_zs() const { + const std::vector zs = m_viewer.get_layers_zs(); + std::vector ret; + std::transform(zs.begin(), zs.end(), std::back_inserter(ret), [](float z) { return static_cast(z); }); + return ret; + } + std::vector get_layers_times() const { return m_viewer.get_layers_estimated_times(); } + + const std::array &get_layers_z_range() const { return m_viewer.get_layers_view_range(); } const SequentialView& get_sequential_view() const { return m_sequential_view; } void update_sequential_view_current(unsigned int first, unsigned int last); @@ -860,56 +300,56 @@ public: void enable_moves_slider(bool enable) const; void update_moves_slider(bool set_to_max = false); void update_layers_slider_mode(); - void update_marker_curr_move(); + + const libvgcode::Interval& get_gcode_view_full_range() const { return m_viewer.get_view_full_range(); } + const libvgcode::Interval& get_gcode_view_enabled_range() const { return m_viewer.get_view_enabled_range(); } + const libvgcode::Interval& get_gcode_view_visible_range() const { return m_viewer.get_view_visible_range(); } + const libvgcode::PathVertex& get_gcode_vertex_at(size_t id) const { return m_viewer.get_vertex_at(id); } bool is_contained_in_bed() const { return m_contained_in_bed; } //BBS: add only gcode mode bool is_only_gcode_in_preview() const { return m_only_gcode_in_preview; } - EViewType get_view_type() const { return m_view_type; } - void set_view_type(EViewType type, bool reset_feature_type_visible = true) { - if (type == EViewType::Count) - type = EViewType::FeatureType; - m_view_type = (EViewType)type; - if (reset_feature_type_visible && type == EViewType::ColorPrint) { - reset_visible(EViewType::FeatureType); - } + void set_view_type(libvgcode::EViewType type) { + m_viewer.set_view_type(type); } - void reset_visible(EViewType type) { - if (type == EViewType::FeatureType) { - for (size_t i = 0; i < m_roles.size(); ++i) { - ExtrusionRole role = m_roles[i]; - m_extrusions.role_visibility_flags = m_extrusions.role_visibility_flags | (1 << role); + void reset_visible(libvgcode::EViewType type) { + if (type == libvgcode::EViewType::FeatureType) { + auto roles = m_viewer.get_extrusion_roles(); + for (size_t i = 0; i < roles.size(); ++i) { + auto role = roles[i]; + if (!m_viewer.is_extrusion_role_visible(role)) { + m_viewer.toggle_extrusion_role_visibility(role); + } } - } else if (type == EViewType::ColorPrint){ - for(auto item: m_tools.m_tool_visibles) item = true; } } - bool is_toolpath_move_type_visible(EMoveType type) const; - void set_toolpath_move_type_visible(EMoveType type, bool visible); - unsigned int get_toolpath_role_visibility_flags() const { return m_extrusions.role_visibility_flags; } - void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; } - unsigned int get_options_visibility_flags() const; - void set_options_visibility_from_flags(unsigned int flags); + libvgcode::EViewType get_view_type() const { return m_viewer.get_view_type(); } + void set_layers_z_range(const std::array& layers_z_range); - bool is_legend_enabled() const { return m_legend_enabled; } + bool is_legend_shown() const { return m_legend_visible && m_legend_enabled; } + void show_legend(bool show) { m_legend_visible = show; } void enable_legend(bool enable) { m_legend_enabled = enable; } float get_legend_height() { return m_legend_height; } void export_toolpaths_to_obj(const char* filename) const; - std::vector& get_custom_gcode_per_print_z() { return m_custom_gcode_per_print_z; } size_t get_extruders_count() { return m_extruders_count; } void push_combo_style(); void pop_combo_style(); + void invalidate_legend() { /*TODO: m_legend_resizer.reset();*/ } + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + float get_cog_marker_scale_factor() const { return m_viewer.get_cog_marker_scale_factor(); } + void set_cog_marker_scale_factor(float factor) { return m_viewer.set_cog_marker_scale_factor(factor); } +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + private: - void load_toolpaths(const GCodeProcessorResult& gcode_result, const BuildVolume& build_volume, const std::vector& exclude_bounding_box); //BBS: always load shell at preview //void load_shells(const Print& print); - void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const; void render_toolpaths(); void render_shells(int canvas_width, int canvas_height); @@ -917,16 +357,6 @@ private: void render_legend(float &legend_height, int canvas_width, int canvas_height, int right_margin); void render_legend_color_arr_recommen(float window_padding); void render_slider(int canvas_width, int canvas_height); - -#if ENABLE_GCODE_VIEWER_STATISTICS - void render_statistics(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - bool is_visible(ExtrusionRole role) const { - return role < erCount && (m_extrusions.role_visibility_flags & (1 << role)) != 0; - } - bool is_visible(const Path& path) const { return is_visible(path.role); } - void log_memory_used(const std::string& label, int64_t additional = 0) const; - ColorRGBA option_color(EMoveType move_type) const; }; } // namespace GUI diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ce859e1a7b..fe9b60ea93 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -97,9 +97,6 @@ void GLCanvas3D::load_render_colors() //static constexpr const float AXES_COLOR[3][3] = { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } }; -// Number of floats -static constexpr const size_t MAX_VERTEX_BUFFER_SIZE = 131072 * 6; // 3.15MB - namespace Slic3r { namespace GUI { @@ -173,8 +170,10 @@ void GLCanvas3D::LayersEditing::init() { glsafe(::glGenTextures(1, (GLuint*)&m_z_texture_id)); glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); - glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)); - glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)); + if (!OpenGLManager::get_gl_info().is_core_profile() || !OpenGLManager::get_gl_info().is_mesa()) { + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + } glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST)); glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1)); @@ -215,16 +214,6 @@ bool GLCanvas3D::LayersEditing::is_allowed() const return wxGetApp().get_shader("variable_layer_height") != nullptr && m_z_texture_id > 0; } -bool GLCanvas3D::LayersEditing::is_enabled() const -{ - return m_enabled; -} - -void GLCanvas3D::LayersEditing::set_enabled(bool enabled) -{ - m_enabled = is_allowed() && enabled; -} - float GLCanvas3D::LayersEditing::s_overlay_window_width; void GLCanvas3D::LayersEditing::show_tooltip_information(const GLCanvas3D& canvas, std::map captions_texts, float x, float y) @@ -578,11 +567,25 @@ void GLCanvas3D::LayersEditing::render_profile(const GLCanvas3D& canvas) m_profile.profile.init_from(std::move(init_data)); } - GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#if SLIC3R_OPENGL_ES + GLShaderProgram* shader = wxGetApp().get_shader("dashed_lines"); +#else + GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); +#endif // SLIC3R_OPENGL_ES if (shader != nullptr) { shader->start_using(); shader->set_uniform("view_model_matrix", Transform3d::Identity()); shader->set_uniform("projection_matrix", Transform3d::Identity()); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + const std::array& viewport = wxGetApp().plater()->get_camera().get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 0.25f); + shader->set_uniform("gap_size", 0.0f); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES m_profile.baseline.render(); m_profile.profile.render(); shader->stop_using(); @@ -746,24 +749,6 @@ const Point GLCanvas3D::Mouse::Drag::Invalid_2D_Point(INT_MAX, INT_MAX); const Vec3d GLCanvas3D::Mouse::Drag::Invalid_3D_Point(DBL_MAX, DBL_MAX, DBL_MAX); const int GLCanvas3D::Mouse::Drag::MoveThresholdPx = 5; -GLCanvas3D::Mouse::Drag::Drag() - : start_position_2D(Invalid_2D_Point) - , start_position_3D(Invalid_3D_Point) - , move_volume_idx(-1) - , move_requires_threshold(false) - , move_start_threshold_position_2D(Invalid_2D_Point) -{ -} - -GLCanvas3D::Mouse::Mouse() - : dragging(false) - , position(DBL_MAX, DBL_MAX) - , scene_position(DBL_MAX, DBL_MAX, DBL_MAX) - , ignore_left_up(false) - , ignore_right_up(false) -{ -} - void GLCanvas3D::Labels::render(const std::vector& sorted_instances) const { if (!m_enabled || !is_shown() || m_canvas.get_gizmos_manager().is_running()) @@ -1360,11 +1345,6 @@ void GLCanvas3D::on_change_color_mode(bool is_dark, bool reinit) { } } -void GLCanvas3D::set_as_dirty() -{ - m_dirty = true; -} - const float GLCanvas3D::get_scale() const { #if ENABLE_RETINA_GL @@ -1374,11 +1354,6 @@ const float GLCanvas3D::get_scale() const #endif } -unsigned int GLCanvas3D::get_volumes_count() const -{ - return (unsigned int)m_volumes.volumes.size(); -} - void GLCanvas3D::reset_volumes() { if (!m_initialized) @@ -1693,11 +1668,6 @@ void GLCanvas3D::set_config(const DynamicPrintConfig* config) m_layers_editing.set_shrinkage_compensation(fff_print()->shrinkage_compensation()); } -void GLCanvas3D::set_process(BackgroundSlicingProcess *process) -{ - m_process = process; -} - void GLCanvas3D::set_model(Model* model) { m_model = model; @@ -1791,16 +1761,6 @@ BoundingBoxf3 GLCanvas3D::plate_scene_bounding_box(int plate_idx) const return bb; } -bool GLCanvas3D::is_layers_editing_enabled() const -{ - return m_layers_editing.is_enabled(); -} - -bool GLCanvas3D::is_layers_editing_allowed() const -{ - return m_layers_editing.is_allowed(); -} - void GLCanvas3D::reset_layer_height_profile() { wxGetApp().plater()->take_snapshot("Variable layer height - Reset"); @@ -1825,52 +1785,12 @@ void GLCanvas3D::smooth_layer_height_profile(const HeightProfileSmoothingParams& m_dirty = true; } -bool GLCanvas3D::is_reload_delayed() const -{ - return m_reload_delayed; -} - void GLCanvas3D::enable_layers_editing(bool enable) { m_layers_editing.set_enabled(enable); set_as_dirty(); } -void GLCanvas3D::enable_legend_texture(bool enable) -{ - m_gcode_viewer.enable_legend(enable); -} - -void GLCanvas3D::enable_picking(bool enable) -{ - m_picking_enabled = enable; - - // Orca: invalidate hover state when dragging is toggled, otherwise if we turned off dragging - // while hovering above a volume, the hovering state won't update even if mouse has moved away. - // Fixes https://github.com/OrcaSlicer/OrcaSlicer/pull/9979#issuecomment-3065575889 - m_hover_volume_idxs.clear(); -} - -void GLCanvas3D::enable_moving(bool enable) -{ - m_moving_enabled = enable; -} - -void GLCanvas3D::enable_gizmos(bool enable) -{ - m_gizmos.set_enabled(enable); -} - -void GLCanvas3D::enable_selection(bool enable) -{ - m_selection.set_enabled(enable); -} - -void GLCanvas3D::enable_main_toolbar(bool enable) -{ - m_main_toolbar.set_enabled(enable); -} - void GLCanvas3D::reset_select_plate_toolbar_selection() { if (m_sel_plate_toolbar.m_all_plates_stats_item) m_sel_plate_toolbar.m_all_plates_stats_item->selected = false; @@ -1898,16 +1818,6 @@ void GLCanvas3D::enable_separator_toolbar(bool enable) m_separator_toolbar.set_enabled(enable); } -void GLCanvas3D::enable_dynamic_background(bool enable) -{ - m_dynamic_background_enabled = enable; -} - -void GLCanvas3D::allow_multisample(bool allow) -{ - m_multisample_allowed = allow; -} - void GLCanvas3D::zoom_to_bed() { BoundingBoxf3 box = m_bed.build_volume().bounding_volume(); @@ -2103,7 +2013,7 @@ void GLCanvas3D::render(bool only_init) _render_background(); //BBS add partplater rendering logic - bool only_current = false, only_body = false, no_partplate = false; + bool only_current = false, only_body = false, no_partplate = false; bool show_grid = true; GLGizmosManager::EType gizmo_type = m_gizmos.get_current_type(); if (!m_main_toolbar.is_enabled()) { @@ -2356,13 +2266,6 @@ void GLCanvas3D::render_thumbnail(ThumbnailData & thumbnail_d } } -void GLCanvas3D::render_calibration_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params) -{ - //load current plate gcode - m_gcode_viewer.render_calibration_thumbnail(thumbnail_data, w, h, thumbnail_params, - wxGetApp().plater()->get_partplate_list(), wxGetApp().get_opengl_manager()); -} - //BBS void GLCanvas3D::select_curr_plate_all() { @@ -2424,11 +2327,6 @@ void GLCanvas3D::set_selected_visible(bool visible) } } -void GLCanvas3D::delete_selected() -{ - m_selection.erase(); -} - void GLCanvas3D::ensure_on_bed(unsigned int object_idx, bool allow_negative_z) { //BBS if asseble view canvas @@ -2463,26 +2361,6 @@ void GLCanvas3D::ensure_on_bed(unsigned int object_idx, bool allow_negative_z) } -const std::vector& GLCanvas3D::get_gcode_layers_zs() const -{ - return m_gcode_viewer.get_layers_zs(); -} - -std::vector GLCanvas3D::get_volumes_print_zs(bool active_only) const -{ - return m_volumes.get_current_print_zs(active_only); -} - -void GLCanvas3D::set_gcode_options_visibility_from_flags(unsigned int flags) -{ - m_gcode_viewer.set_options_visibility_from_flags(flags); -} - -void GLCanvas3D::set_volumes_z_range(const std::array& range) -{ - m_volumes.set_range(range[0] - 1e-6, range[1] + 1e-6); -} - std::vector GLCanvas3D::load_object(const ModelObject& model_object, int obj_idx, std::vector instance_idxs) { if (instance_idxs.empty()) { @@ -3161,7 +3039,7 @@ void GLCanvas3D::set_shell_transparence(float alpha){ } //BBS: add only gcode mode -void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors, bool only_gcode) +void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors, const std::vector& str_color_print_colors, bool only_gcode) { PartPlateList& partplate_list = wxGetApp().plater()->get_partplate_list(); PartPlate* plate = partplate_list.get_curr_plate(); @@ -3170,8 +3048,13 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult& gcode_result, co //BBS: init is called in GLCanvas3D.render() //when load gcode directly, it is too late m_gcode_viewer.init(wxGetApp().get_mode(), wxGetApp().preset_bundle); - m_gcode_viewer.load(gcode_result, *this->fff_print(), wxGetApp().plater()->build_volume(), exclude_bounding_box, + m_gcode_viewer.enable_legend(true); + + + m_gcode_viewer.load_as_gcode(gcode_result, *this->fff_print(), str_tool_colors, str_color_print_colors, wxGetApp().plater()->build_volume(), exclude_bounding_box, wxGetApp().get_mode(), only_gcode); + m_gcode_layers_times_cache = m_gcode_viewer.get_layers_times(); + m_gcode_viewer.get_moves_slider()->SetHigherValue(m_gcode_viewer.get_moves_slider()->GetMaxValue()); if (wxGetApp().is_editor()) { @@ -3179,14 +3062,6 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult& gcode_result, co _update_slice_error_status(); } - m_gcode_viewer.refresh(gcode_result, str_tool_colors); - set_as_dirty(); - request_extra_frame(); -} - -void GLCanvas3D::refresh_gcode_preview_render_paths() -{ - m_gcode_viewer.refresh_render_paths(); set_as_dirty(); request_extra_frame(); } @@ -3204,26 +3079,6 @@ void GLCanvas3D::load_sla_preview() } } -/*void GLCanvas3D::load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values) -{ - const Print *print = this->fff_print(); - if (print == nullptr) - return; - - _set_current(); - - // Release OpenGL data before generating new data. - this->reset_volumes(); - - const BuildVolume &build_volume = m_bed.build_volume(); - _load_print_toolpaths(build_volume); - _load_wipe_tower_toolpaths(build_volume, str_tool_colors); - for (const PrintObject* object : print->objects()) - _load_print_object_toolpaths(*object, build_volume, str_tool_colors, color_print_values); - - _set_warning_notification_if_needed(EWarning::ToolpathOutside); -}*/ - void GLCanvas3D::bind_event_handlers() { if (m_canvas != nullptr) { @@ -3303,11 +3158,6 @@ void GLCanvas3D::unbind_event_handlers() } } -void GLCanvas3D::on_size(wxSizeEvent& evt) -{ - m_dirty = true; -} - void GLCanvas3D::on_idle(wxIdleEvent& evt) { if (!m_initialized) @@ -3779,9 +3629,8 @@ void GLCanvas3D::on_key(wxKeyEvent& evt) const int keyCode = evt.GetKeyCode(); auto imgui = wxGetApp().imgui(); - if (imgui->update_key_data(evt)) { + if (imgui->update_key_data(evt)) render(); - } else { if (!m_gizmos.on_key(evt)) { @@ -5522,20 +5371,6 @@ void GLCanvas3D::set_cursor(ECursorType type) } } -void GLCanvas3D::msw_rescale() -{ -} - -bool GLCanvas3D::has_toolpaths_to_export() const -{ - return m_gcode_viewer.can_export_toolpaths(); -} - -void GLCanvas3D::export_toolpaths_to_obj(const char* filename) const -{ - m_gcode_viewer.export_toolpaths_to_obj(filename); -} - void GLCanvas3D::mouse_up_cleanup() { m_moving = false; @@ -7815,14 +7650,12 @@ void GLCanvas3D::_render_gcode(int canvas_width, int canvas_height) } layers_slider->set_as_dirty(false); post_event(SimpleEvent(EVT_GLCANVAS_UPDATE)); - m_gcode_viewer.update_marker_curr_move(); } if (moves_slider->is_dirty()) { moves_slider->set_as_dirty(false); m_gcode_viewer.update_sequential_view_current((moves_slider->GetLowerValueD() - 1.0), static_cast(moves_slider->GetHigherValueD() - 1.0)); post_event(SimpleEvent(EVT_GLCANVAS_UPDATE)); - m_gcode_viewer.update_marker_curr_move(); } } @@ -7848,13 +7681,6 @@ void GLCanvas3D::_render_sequential_clearance() } } -#if ENABLE_RENDER_SELECTION_CENTER -void GLCanvas3D::_render_selection_center() -{ - m_selection.render_center(m_gizmos.is_dragging()); -} -#endif // ENABLE_RENDER_SELECTION_CENTER - void GLCanvas3D::_check_and_update_toolbar_icon_scale() { // Update collapse toolbar @@ -9217,7 +9043,10 @@ void GLCanvas3D::_render_camera_target() static const float half_length = 5.0f; glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glLineWidth(2.0f)); +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth(2.0f)); +#endif // !SLIC3R_OPENGL_ES const Vec3f& target = wxGetApp().plater()->get_camera().get_target().cast(); bool target_changed = !m_camera_target.target.isApprox(target.cast()); m_camera_target.target = target.cast(); @@ -9398,11 +9227,6 @@ void GLCanvas3D::_render_sla_slices() } } -void GLCanvas3D::_render_selection_sidebar_hints() -{ - m_selection.render_sidebar_hints(m_sidebar_field, m_gizmos.get_uniform_scaling()); -} - void GLCanvas3D::_update_volumes_hover_state() { for (GLVolume* v : m_volumes.volumes) { @@ -9526,564 +9350,6 @@ Vec3d GLCanvas3D::_mouse_to_bed_3d(const Point& mouse_pos) return mouse_ray(mouse_pos).intersect_plane(0.0); } -void GLCanvas3D::_start_timer() -{ - m_timer.Start(100, wxTIMER_CONTINUOUS); -} - -void GLCanvas3D::_stop_timer() -{ - m_timer.Stop(); -} - -void GLCanvas3D::_load_print_toolpaths(const BuildVolume &build_volume) -{ - const Print *print = this->fff_print(); - if (print == nullptr) - return; - - if (! print->is_step_done(psSkirtBrim)) - return; - - if (!print->has_skirt() && !print->has_brim()) - return; - - const ColorRGBA color = ColorRGBA::GREENISH(); - - // number of skirt layers - size_t total_layer_count = 0; - for (const PrintObject* print_object : print->objects()) { - total_layer_count = std::max(total_layer_count, print_object->total_layer_count()); - } - size_t skirt_height = print->has_infinite_skirt() ? total_layer_count : std::min(print->config().skirt_height.value, total_layer_count); - if (skirt_height == 0 && print->has_brim()) - skirt_height = 1; - - // Get first skirt_height layers. - //FIXME This code is fishy. It may not work for multiple objects with different layering due to variable layer height feature. - // This is not critical as this is just an initial preview. - const PrintObject* highest_object = *std::max_element(print->objects().begin(), print->objects().end(), [](auto l, auto r){ return l->layers().size() < r->layers().size(); }); - std::vector print_zs; - print_zs.reserve(skirt_height * 2); - for (size_t i = 0; i < std::min(skirt_height, highest_object->layers().size()); ++ i) - print_zs.emplace_back(float(highest_object->layers()[i]->print_z)); - // Only add skirt for the raft layers. - for (size_t i = 0; i < std::min(skirt_height, std::min(highest_object->slicing_parameters().raft_layers(), highest_object->support_layers().size())); ++ i) - print_zs.emplace_back(float(highest_object->support_layers()[i]->print_z)); - sort_remove_duplicates(print_zs); - skirt_height = std::min(skirt_height, print_zs.size()); - print_zs.erase(print_zs.begin() + skirt_height, print_zs.end()); - - GLVolume* volume = m_volumes.new_toolpath_volume(color); - GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; - for (size_t i = 0; i < skirt_height; ++ i) { - volume->print_zs.emplace_back(print_zs[i]); - volume->offsets.emplace_back(init_data.indices_count()); - //BBS: usage of m_brim are deleted - _3DScene::extrusionentity_to_verts(print->skirt(), print_zs[i], Point(0, 0), init_data); - // Ensure that no volume grows over the limits. If the volume is too large, allocate a new one. - if (init_data.vertices_size_bytes() > MAX_VERTEX_BUFFER_SIZE) { - volume->model.init_from(std::move(init_data)); - GLVolume &vol = *volume; - volume = m_volumes.new_toolpath_volume(vol.color); - } - } - volume->model.init_from(std::move(init_data)); - volume->is_outside = !contains(build_volume, volume->model); -} - -void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const BuildVolume& build_volume, const std::vector& str_tool_colors, const std::vector& color_print_values) -{ - std::vector tool_colors; - decode_colors(str_tool_colors, tool_colors); - - struct Ctxt - { - const PrintInstances *shifted_copies; - std::vector layers; - bool has_perimeters; - bool has_infill; - bool has_support; - const std::vector* tool_colors; - bool is_single_material_print; - int filaments_cnt; - const std::vector* color_print_values; - - static ColorRGBA color_perimeters() { return ColorRGBA::YELLOW(); } - static ColorRGBA color_infill() { return ColorRGBA::REDISH(); } - static ColorRGBA color_support() { return ColorRGBA::GREENISH(); } - static ColorRGBA color_pause_or_custom_code() { return ColorRGBA::GRAY(); } - - // For cloring by a tool, return a parsed color. - bool color_by_tool() const { return tool_colors != nullptr; } - size_t number_tools() const { return color_by_tool() ? tool_colors->size() : 0; } - const ColorRGBA& color_tool(size_t tool) const { return (*tool_colors)[tool]; } - - // For coloring by a color_print(M600), return a parsed color. - bool color_by_color_print() const { return color_print_values!=nullptr; } - const size_t color_print_color_idx_by_layer_idx(const size_t layer_idx) const { - const CustomGCode::Item value{layers[layer_idx]->print_z + EPSILON, CustomGCode::Custom, 0, ""}; - auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); - return (it - color_print_values->begin()) % number_tools(); - } - - const size_t color_print_color_idx_by_layer_idx_and_extruder(const size_t layer_idx, const int extruder) const - { - const coordf_t print_z = layers[layer_idx]->print_z; - - auto it = std::find_if(color_print_values->begin(), color_print_values->end(), - [print_z](const CustomGCode::Item& code) - { return fabs(code.print_z - print_z) < EPSILON; }); - if (it != color_print_values->end()) { - CustomGCode::Type type = it->type; - // pause print or custom Gcode - if (type == CustomGCode::PausePrint || - (type != CustomGCode::ColorChange && type != CustomGCode::ToolChange)) - return number_tools()-1; // last color item is a gray color for pause print or custom G-code - - // change tool (extruder) - if (type == CustomGCode::ToolChange) - return get_color_idx_for_tool_change(it, extruder); - // change color for current extruder - if (type == CustomGCode::ColorChange) { - int color_idx = get_color_idx_for_color_change(it, extruder); - if (color_idx >= 0) - return color_idx; - } - } - - const CustomGCode::Item value{print_z + EPSILON, CustomGCode::Custom, 0, ""}; - it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); - while (it != color_print_values->begin()) { - --it; - // change color for current extruder - if (it->type == CustomGCode::ColorChange) { - int color_idx = get_color_idx_for_color_change(it, extruder); - if (color_idx >= 0) - return color_idx; - } - // change tool (extruder) - if (it->type == CustomGCode::ToolChange) - return get_color_idx_for_tool_change(it, extruder); - } - - return std::min(filaments_cnt - 1, std::max(extruder - 1, 0));; - } - - private: - int get_m600_color_idx(std::vector::const_iterator it) const - { - int shift = 0; - while (it != color_print_values->begin()) { - --it; - if (it->type == CustomGCode::ColorChange) - shift++; - } - return filaments_cnt + shift; - } - - int get_color_idx_for_tool_change(std::vector::const_iterator it, const int extruder) const - { - const int current_extruder = it->extruder == 0 ? extruder : it->extruder; - if (number_tools() == size_t(filaments_cnt + 1)) // there is no one "M600" - return std::min(filaments_cnt - 1, std::max(current_extruder - 1, 0)); - - auto it_n = it; - while (it_n != color_print_values->begin()) { - --it_n; - if (it_n->type == CustomGCode::ColorChange && it_n->extruder == current_extruder) - return get_m600_color_idx(it_n); - } - - return std::min(filaments_cnt - 1, std::max(current_extruder - 1, 0)); - } - - int get_color_idx_for_color_change(std::vector::const_iterator it, const int extruder) const - { - if (filaments_cnt == 1) - return get_m600_color_idx(it); - - auto it_n = it; - bool is_tool_change = false; - while (it_n != color_print_values->begin()) { - --it_n; - if (it_n->type == CustomGCode::ToolChange) { - is_tool_change = true; - if (it_n->extruder == it->extruder || (it_n->extruder == 0 && it->extruder == extruder)) - return get_m600_color_idx(it); - break; - } - } - if (!is_tool_change && it->extruder == extruder) - return get_m600_color_idx(it); - - return -1; - } - - } ctxt; - - ctxt.has_perimeters = print_object.is_step_done(posPerimeters); - ctxt.has_infill = print_object.is_step_done(posInfill); - ctxt.has_support = print_object.is_step_done(posSupportMaterial); - ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors; - ctxt.color_print_values = color_print_values.empty() ? nullptr : &color_print_values; - ctxt.is_single_material_print = this->fff_print()->extruders().size()==1; - ctxt.filaments_cnt = wxGetApp().filaments_cnt(); - - ctxt.shifted_copies = &print_object.instances(); - - // order layers by print_z - { - size_t nlayers = 0; - if (ctxt.has_perimeters || ctxt.has_infill) - nlayers = print_object.layers().size(); - if (ctxt.has_support) - nlayers += print_object.support_layers().size(); - ctxt.layers.reserve(nlayers); - } - if (ctxt.has_perimeters || ctxt.has_infill) - for (const Layer *layer : print_object.layers()) - ctxt.layers.emplace_back(layer); - if (ctxt.has_support) - for (const Layer *layer : print_object.support_layers()) - ctxt.layers.emplace_back(layer); - std::sort(ctxt.layers.begin(), ctxt.layers.end(), [](const Layer *l1, const Layer *l2) { return l1->print_z < l2->print_z; }); - - // Maximum size of an allocation block: 32MB / sizeof(float) - BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start" << m_volumes.log_memory_info() << log_memory_info(); - - const bool is_selected_separate_extruder = m_selected_extruder > 0 && ctxt.color_by_color_print(); - - //FIXME Improve the heuristics for a grain size. - size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1)); - tbb::spin_mutex new_volume_mutex; - auto new_volume = [this, &new_volume_mutex](const ColorRGBA& color) { - // Allocate the volume before locking. - GLVolume *volume = new GLVolume(color); - volume->is_extrusion_path = true; - // to prevent sending data to gpu (in the main thread) while - // editing the model geometry - volume->model.disable_render(); - tbb::spin_mutex::scoped_lock lock; - // Lock by ROII, so if the emplace_back() fails, the lock will be released. - lock.acquire(new_volume_mutex); - m_volumes.volumes.emplace_back(volume); - lock.release(); - return volume; - }; - const size_t volumes_cnt_initial = m_volumes.volumes.size(); - tbb::parallel_for( - tbb::blocked_range(0, ctxt.layers.size(), grain_size), - [&ctxt, &new_volume, is_selected_separate_extruder, this](const tbb::blocked_range& range) { - GLVolumePtrs vols; - std::vector geometries; - auto select_geometry = [&ctxt, &geometries](size_t layer_idx, int extruder, int feature) -> GLModel::Geometry& { - return geometries[ctxt.color_by_color_print() ? - ctxt.color_print_color_idx_by_layer_idx_and_extruder(layer_idx, extruder) : - ctxt.color_by_tool() ? - std::min(ctxt.number_tools() - 1, std::max(extruder - 1, 0)) : - feature - ]; - }; - if (ctxt.color_by_color_print() || ctxt.color_by_tool()) { - for (size_t i = 0; i < ctxt.number_tools(); ++i) { - vols.emplace_back(new_volume(ctxt.color_tool(i))); - geometries.emplace_back(GLModel::Geometry()); - } - } - else { - vols = { new_volume(ctxt.color_perimeters()), new_volume(ctxt.color_infill()), new_volume(ctxt.color_support()) }; - geometries = { GLModel::Geometry(), GLModel::Geometry(), GLModel::Geometry() }; - } - - assert(vols.size() == geometries.size()); - for (GLModel::Geometry& g : geometries) { - g.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; - } - for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) { - const Layer *layer = ctxt.layers[idx_layer]; - - if (is_selected_separate_extruder) { - bool at_least_one_has_correct_extruder = false; - for (const LayerRegion* layerm : layer->regions()) { - if (layerm->slices.surfaces.empty()) - continue; - const PrintRegionConfig& cfg = layerm->region().config(); - if (cfg.wall_filament.value == m_selected_extruder || - cfg.sparse_infill_filament.value == m_selected_extruder || - cfg.solid_infill_filament.value == m_selected_extruder ) { - at_least_one_has_correct_extruder = true; - break; - } - } - if (!at_least_one_has_correct_extruder) - continue; - } - - for (size_t i = 0; i < vols.size(); ++i) { - GLVolume* vol = vols[i]; - if (vol->print_zs.empty() || vol->print_zs.back() != layer->print_z) { - vol->print_zs.emplace_back(layer->print_z); - vol->offsets.emplace_back(geometries[i].indices_count()); - } - } - - for (const PrintInstance &instance : *ctxt.shifted_copies) { - const Point © = instance.shift; - for (const LayerRegion *layerm : layer->regions()) { - if (is_selected_separate_extruder) - { - const PrintRegionConfig& cfg = layerm->region().config(); - if (cfg.wall_filament.value != m_selected_extruder || - cfg.sparse_infill_filament.value != m_selected_extruder || - cfg.solid_infill_filament.value != m_selected_extruder) - continue; - } - if (ctxt.has_perimeters) - _3DScene::extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy, - select_geometry(idx_layer, layerm->region().config().wall_filament.value, 0)); - if (ctxt.has_infill) { - for (const ExtrusionEntity *ee : layerm->fills.entities) { - // fill represents infill extrusions of a single island. - const auto *fill = dynamic_cast(ee); - if (! fill->entities.empty()) - _3DScene::extrusionentity_to_verts(*fill, float(layer->print_z), copy, - select_geometry(idx_layer, is_solid_infill(fill->entities.front()->role()) ? - layerm->region().config().solid_infill_filament : - layerm->region().config().sparse_infill_filament, 1)); - } - } - } - if (ctxt.has_support) { - const SupportLayer *support_layer = dynamic_cast(layer); - if (support_layer) { - for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities) - _3DScene::extrusionentity_to_verts(extrusion_entity, float(layer->print_z), copy, - select_geometry(idx_layer, (extrusion_entity->role() == erSupportMaterial || extrusion_entity->role() == erSupportTransition) ? - support_layer->object()->config().support_filament : - support_layer->object()->config().support_interface_filament, 2)); - } - } - } - // Ensure that no volume grows over the limits. If the volume is too large, allocate a new one. - for (size_t i = 0; i < vols.size(); ++i) { - GLVolume &vol = *vols[i]; - if (geometries[i].vertices_size_bytes() > MAX_VERTEX_BUFFER_SIZE) { - vol.model.init_from(std::move(geometries[i])); - vols[i] = new_volume(vol.color); - } - } - } - for (size_t i = 0; i < vols.size(); ++i) { - if (!geometries[i].is_empty()) - vols[i]->model.init_from(std::move(geometries[i])); - } - }); - - BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info(); - // Remove empty volumes from the newly added volumes. - { - for (auto ptr_it = m_volumes.volumes.begin() + volumes_cnt_initial; ptr_it != m_volumes.volumes.end(); ++ptr_it) - if ((*ptr_it)->empty()) { - delete *ptr_it; - *ptr_it = nullptr; - } - m_volumes.volumes.erase(std::remove(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(), nullptr), m_volumes.volumes.end()); - } - for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) { - GLVolume* v = m_volumes.volumes[i]; - v->is_outside = !contains(build_volume, v->model); - // We are done editinig the model, now it can be sent to gpu - v->model.enable_render(); - } - - BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info(); -} - -void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, const std::vector& str_tool_colors) -{ - const Print *print = this->fff_print(); - if (print == nullptr || print->wipe_tower_data().tool_changes.empty()) - return; - - if (!print->is_step_done(psWipeTower)) - return; - - std::vector tool_colors; - decode_colors(str_tool_colors, tool_colors); - - struct Ctxt - { - const Print *print; - const std::vector *tool_colors; - Vec2f wipe_tower_pos; - float wipe_tower_angle; - - static ColorRGBA color_support() { return ColorRGBA::GREENISH(); } - - // For cloring by a tool, return a parsed color. - bool color_by_tool() const { return tool_colors != nullptr; } - size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() : 0; } - const ColorRGBA& color_tool(size_t tool) const { return (*tool_colors)[tool]; } - int volume_idx(int tool, int feature) const { - return this->color_by_tool() ? std::min(this->number_tools() - 1, std::max(tool, 0)) : feature; - } - - const std::vector& tool_change(size_t idx) { - const auto &tool_changes = print->wipe_tower_data().tool_changes; - return priming.empty() ? - ((idx == tool_changes.size()) ? final : tool_changes[idx]) : - ((idx == 0) ? priming : (idx == tool_changes.size() + 1) ? final : tool_changes[idx - 1]); - } - std::vector priming; - std::vector final; - } ctxt; - - ctxt.print = print; - ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors; - if (print->wipe_tower_data().priming) - for (int i=0; i<(int)print->wipe_tower_data().priming.get()->size(); ++i) - ctxt.priming.emplace_back(print->wipe_tower_data().priming.get()->at(i)); - if (print->wipe_tower_data().final_purge) - ctxt.final.emplace_back(*print->wipe_tower_data().final_purge.get()); - - ctxt.wipe_tower_angle = ctxt.print->config().wipe_tower_rotation_angle.value/180.f * PI; - - // BBS: add partplate logic - int plate_idx = print->get_plate_index(); - Vec3d plate_origin = print->get_plate_origin(); - double wipe_tower_x = ctxt.print->config().wipe_tower_x.get_at(plate_idx) + plate_origin(0); - double wipe_tower_y = ctxt.print->config().wipe_tower_y.get_at(plate_idx) + plate_origin(1); - ctxt.wipe_tower_pos = Vec2f(wipe_tower_x, wipe_tower_y); - - BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - start" << m_volumes.log_memory_info() << log_memory_info(); - - //FIXME Improve the heuristics for a grain size. - size_t n_items = print->wipe_tower_data().tool_changes.size() + (ctxt.priming.empty() ? 0 : 1); - size_t grain_size = std::max(n_items / 128, size_t(1)); - tbb::spin_mutex new_volume_mutex; - auto new_volume = [this, &new_volume_mutex](const ColorRGBA& color) { - auto *volume = new GLVolume(color); - volume->is_extrusion_path = true; - // to prevent sending data to gpu (in the main thread) while - // editing the model geometry - volume->model.disable_render(); - tbb::spin_mutex::scoped_lock lock; - lock.acquire(new_volume_mutex); - m_volumes.volumes.emplace_back(volume); - lock.release(); - return volume; - }; - const size_t volumes_cnt_initial = m_volumes.volumes.size(); - std::vector volumes_per_thread(n_items); - tbb::parallel_for( - tbb::blocked_range(0, n_items, grain_size), - [&ctxt, &new_volume](const tbb::blocked_range& range) { - // Bounding box of this slab of a wipe tower. - GLVolumePtrs vols; - std::vector geometries; - if (ctxt.color_by_tool()) { - for (size_t i = 0; i < ctxt.number_tools(); ++i) { - vols.emplace_back(new_volume(ctxt.color_tool(i))); - geometries.emplace_back(GLModel::Geometry()); - } - } - else { - vols = { new_volume(ctxt.color_support()) }; - geometries = { GLModel::Geometry() }; - } - - assert(vols.size() == geometries.size()); - for (GLModel::Geometry& g : geometries) { - g.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; - } - for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++idx_layer) { - const std::vector &layer = ctxt.tool_change(idx_layer); - for (size_t i = 0; i < vols.size(); ++i) { - GLVolume &vol = *vols[i]; - if (vol.print_zs.empty() || vol.print_zs.back() != layer.front().print_z) { - vol.print_zs.emplace_back(layer.front().print_z); - vol.offsets.emplace_back(geometries[i].indices_count()); - } - } - for (const WipeTower::ToolChangeResult &extrusions : layer) { - for (size_t i = 1; i < extrusions.extrusions.size();) { - const WipeTower::Extrusion &e = extrusions.extrusions[i]; - if (e.width == 0.) { - ++i; - continue; - } - size_t j = i + 1; - if (ctxt.color_by_tool()) - for (; j < extrusions.extrusions.size() && extrusions.extrusions[j].tool == e.tool && extrusions.extrusions[j].width > 0.f; ++j); - else - for (; j < extrusions.extrusions.size() && extrusions.extrusions[j].width > 0.f; ++j); - size_t n_lines = j - i; - Lines lines; - std::vector widths; - std::vector heights; - lines.reserve(n_lines); - widths.reserve(n_lines); - heights.assign(n_lines, extrusions.layer_height); - WipeTower::Extrusion e_prev = extrusions.extrusions[i-1]; - - if (!extrusions.priming) { // wipe tower extrusions describe the wipe tower at the origin with no rotation - e_prev.pos = Eigen::Rotation2Df(ctxt.wipe_tower_angle) * e_prev.pos; - e_prev.pos += ctxt.wipe_tower_pos; - } - - for (; i < j; ++i) { - WipeTower::Extrusion e = extrusions.extrusions[i]; - assert(e.width > 0.f); - if (!extrusions.priming) { - e.pos = Eigen::Rotation2Df(ctxt.wipe_tower_angle) * e.pos; - e.pos += ctxt.wipe_tower_pos; - } - - lines.emplace_back(Point::new_scale(e_prev.pos.x(), e_prev.pos.y()), Point::new_scale(e.pos.x(), e.pos.y())); - widths.emplace_back(e.width); - - e_prev = e; - } - _3DScene::thick_lines_to_verts(lines, widths, heights, lines.front().a == lines.back().b, extrusions.print_z, - geometries[ctxt.volume_idx(e.tool, 0)]); - } - } - } - for (size_t i = 0; i < vols.size(); ++i) { - GLVolume &vol = *vols[i]; - if (geometries[i].vertices_size_bytes() > MAX_VERTEX_BUFFER_SIZE) { - vol.model.init_from(std::move(geometries[i])); - vols[i] = new_volume(vol.color); - } - } - for (size_t i = 0; i < vols.size(); ++i) { - if (!geometries[i].is_empty()) - vols[i]->model.init_from(std::move(geometries[i])); - } - }); - - BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info(); - // Remove empty volumes from the newly added volumes. - { - for (auto ptr_it = m_volumes.volumes.begin() + volumes_cnt_initial; ptr_it != m_volumes.volumes.end(); ++ptr_it) - if ((*ptr_it)->empty()) { - delete *ptr_it; - *ptr_it = nullptr; - } - m_volumes.volumes.erase(std::remove(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(), nullptr), m_volumes.volumes.end()); - } - for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) { - GLVolume* v = m_volumes.volumes[i]; - v->is_outside = !contains(build_volume, v->model); - // We are done editinig the model, now it can be sent to gpu - v->model.enable_render(); - } - - BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info(); -} - // While it looks like we can call // this->reload_scene(true, true) // the two functions are quite different: @@ -10138,11 +9404,6 @@ void GLCanvas3D::_load_sla_shells() update_volumes_colors_by_extruder(); } -void GLCanvas3D::_update_sla_shells_outside_state() -{ - check_volumes_outside_state(); -} - void GLCanvas3D::_set_warning_notification_if_needed(EWarning warning) { _set_current(); @@ -10693,13 +9954,13 @@ const SLAPrint* GLCanvas3D::sla_print() const return (m_process == nullptr) ? nullptr : m_process->sla_print(); } -void GLCanvas3D::WipeTowerInfo::apply_wipe_tower() const +void GLCanvas3D::WipeTowerInfo::apply_wipe_tower(Vec2d pos, double rot) const { // BBS: add partplate logic DynamicConfig& proj_cfg = wxGetApp().preset_bundle->project_config; Vec3d plate_origin = wxGetApp().plater()->get_partplate_list().get_plate(m_plate_idx)->get_origin(); - ConfigOptionFloat wipe_tower_x(m_pos(X) - plate_origin(0)); - ConfigOptionFloat wipe_tower_y(m_pos(Y) - plate_origin(1)); + ConfigOptionFloat wipe_tower_x(pos(X) - plate_origin(0)); + ConfigOptionFloat wipe_tower_y(pos(Y) - plate_origin(1)); ConfigOptionFloats* wipe_tower_x_opt = proj_cfg.option("wipe_tower_x", true); ConfigOptionFloats* wipe_tower_y_opt = proj_cfg.option("wipe_tower_y", true); @@ -10724,11 +9985,6 @@ void GLCanvas3D::GizmoHighlighterTimer::Notify() wxPostEvent((wxEvtHandler*)GetOwner(), GizmoHighlighterTimerEvent(EVT_GLCANVAS_GIZMO_HIGHLIGHTER_TIMER, *this)); } -void GLCanvas3D::ToolbarHighlighter::set_timer_owner(wxEvtHandler* owner, int timerid/* = wxID_ANY*/) -{ - m_timer.SetOwner(owner, timerid); -} - void GLCanvas3D::ToolbarHighlighter::init(GLToolbarItem* toolbar_item, GLCanvas3D* canvas) { if (m_timer.IsRunning()) @@ -10746,9 +10002,9 @@ void GLCanvas3D::ToolbarHighlighter::invalidate() { m_timer.Stop(); - if (m_toolbar_item) { + if (m_toolbar_item) m_toolbar_item->set_highlight(GLToolbarItem::EHighlightState::NotHighlighted); - } + m_toolbar_item = nullptr; m_blink_counter = 0; m_render_arrow = false; @@ -10773,11 +10029,6 @@ void GLCanvas3D::ToolbarHighlighter::blink() invalidate(); } -void GLCanvas3D::GizmoHighlighter::set_timer_owner(wxEvtHandler* owner, int timerid/* = wxID_ANY*/) -{ - m_timer.SetOwner(owner, timerid); -} - void GLCanvas3D::GizmoHighlighter::init(GLGizmosManager* manager, GLGizmosManager::EType gizmo, GLCanvas3D* canvas) { if (m_timer.IsRunning()) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 6931b305d6..17a388c731 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -286,8 +286,8 @@ class GLCanvas3D bool is_allowed() const; - bool is_enabled() const; - void set_enabled(bool enabled); + bool is_enabled() const { return m_enabled; } + void set_enabled(bool enabled) { m_enabled = is_allowed() && enabled; } void show_tooltip_information(const GLCanvas3D& canvas, std::map captions_texts, float x, float y); void render_variable_layer_height_dialog(const GLCanvas3D& canvas); @@ -327,25 +327,20 @@ class GLCanvas3D static const Vec3d Invalid_3D_Point; static const int MoveThresholdPx; - Point start_position_2D; - Vec3d start_position_3D; - int move_volume_idx; - bool move_requires_threshold; - Point move_start_threshold_position_2D; - - public: - Drag(); + Point start_position_2D{ Invalid_2D_Point }; + Vec3d start_position_3D{ Invalid_3D_Point }; + int move_volume_idx{ -1 }; + bool move_requires_threshold{ false }; + Point move_start_threshold_position_2D{ Invalid_2D_Point }; }; - bool dragging; - Vec2d position; - Vec3d scene_position; + bool dragging{ false }; + Vec2d position{ DBL_MAX, DBL_MAX }; + Vec3d scene_position{ DBL_MAX, DBL_MAX, DBL_MAX }; + bool ignore_left_up{ false }; Drag drag; - bool ignore_left_up; bool ignore_right_up; - Mouse(); - void set_start_position_2D_as_invalid() { drag.start_position_2D = Drag::Invalid_2D_Point; } void set_start_position_3D_as_invalid() { drag.start_position_3D = Drag::Invalid_3D_Point; } void set_move_start_threshold_position_2D_as_invalid() { drag.move_start_threshold_position_2D = Drag::Invalid_2D_Point; } @@ -638,6 +633,9 @@ private: int custom_height_count = 0; int assembly_view_count = 0; + // used to show layers times on the layers slider when pre-gcode view is active + std::vector m_gcode_layers_times_cache; + public: OrientSettings& get_orient_settings() { @@ -685,7 +683,7 @@ public: struct ToolbarHighlighter { - void set_timer_owner(wxEvtHandler* owner, int timerid = wxID_ANY); + void set_timer_owner(wxEvtHandler* owner, int timerid = wxID_ANY) { m_timer.SetOwner(owner, timerid); } void init(GLToolbarItem* toolbar_item, GLCanvas3D* canvas); void blink(); void invalidate(); @@ -700,7 +698,7 @@ public: struct GizmoHighlighter { - void set_timer_owner(wxEvtHandler* owner, int timerid = wxID_ANY); + void set_timer_owner(wxEvtHandler* owner, int timerid = wxID_ANY) { m_timer.SetOwner(owner, timerid); } void init(GLGizmosManager* manager, GLGizmosManager::EType gizmo, GLCanvas3D* canvas); void blink(); void invalidate(); @@ -764,22 +762,33 @@ public: void reset_explosion_ratio() { m_explosion_ratio = 1.0; } void on_change_color_mode(bool is_dark, bool reinit = true); const bool get_dark_mode_status() { return m_is_dark; } - void set_as_dirty(); + void set_as_dirty() { m_dirty = true; } void requires_check_outside_state() { m_requires_check_outside_state = true; } - unsigned int get_volumes_count() const; + unsigned int get_volumes_count() const { return (unsigned int)m_volumes.volumes.size(); } const GLVolumeCollection& get_volumes() const { return m_volumes; } void reset_volumes(); ModelInstanceEPrintVolumeState check_volumes_outside_state(ObjectFilamentResults* object_results = nullptr) const; + void check_volumes_outside_state(GLVolumeCollection& volumes) const { check_volumes_outside_state(volumes, nullptr, false); } bool is_all_plates_selected() { return m_sel_plate_toolbar.m_all_plates_stats_item && m_sel_plate_toolbar.m_all_plates_stats_item->selected; } const float get_scale() const; +private: + // returns true if all the volumes are completely contained in the print volume + // returns the containment state in the given out_state, if non-null + bool check_volumes_outside_state(GLVolumeCollection& volumes, ModelInstanceEPrintVolumeState* out_state, bool selection_only = true) const; + +public: //BBS GCodeViewer& get_gcode_viewer() { return m_gcode_viewer; } void init_gcode_viewer(ConfigOptionMode mode, Slic3r::PresetBundle* preset_bundle) { m_gcode_viewer.init(mode, preset_bundle); } void reset_gcode_toolpaths() { m_gcode_viewer.reset(); } const GCodeViewer::SequentialView& get_gcode_sequential_view() const { return m_gcode_viewer.get_sequential_view(); } void update_gcode_sequential_view_current(unsigned int first, unsigned int last) { m_gcode_viewer.update_sequential_view_current(first, last); } + const libvgcode::Interval& get_gcode_view_full_range() const { return m_gcode_viewer.get_gcode_view_full_range(); } + const libvgcode::Interval& get_gcode_view_enabled_range() const { return m_gcode_viewer.get_gcode_view_enabled_range(); } + const libvgcode::Interval& get_gcode_view_visible_range() const { return m_gcode_viewer.get_gcode_view_visible_range(); } + const libvgcode::PathVertex& get_gcode_vertex_at(size_t id) const { return m_gcode_viewer.get_gcode_vertex_at(id); } void toggle_selected_volume_visibility(bool selected_visible); void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); @@ -788,7 +797,7 @@ public: void update_instance_printable_state_for_objects(const std::vector& object_idxs); void set_config(const DynamicPrintConfig* config); - void set_process(BackgroundSlicingProcess* process); + void set_process(BackgroundSlicingProcess* process) { m_process = process; } void set_model(Model* model); const Model* get_model() const { return m_model; } @@ -832,22 +841,28 @@ public: BoundingBoxf3 scene_bounding_box() const; BoundingBoxf3 plate_scene_bounding_box(int plate_idx) const; - bool is_layers_editing_enabled() const; - bool is_layers_editing_allowed() const; + bool is_layers_editing_enabled() const { return m_layers_editing.is_enabled(); } + bool is_layers_editing_allowed() const { return m_layers_editing.is_allowed(); } void reset_layer_height_profile(); void adaptive_layer_height_profile(float quality_factor); void smooth_layer_height_profile(const HeightProfileSmoothingParams& smoothing_params); - bool is_reload_delayed() const; + bool is_reload_delayed() const { return m_reload_delayed; } void enable_layers_editing(bool enable); - void enable_legend_texture(bool enable); - void enable_picking(bool enable); - void enable_moving(bool enable); - void enable_gizmos(bool enable); - void enable_selection(bool enable); - void enable_main_toolbar(bool enable); + void enable_picking(bool enable) + { + m_picking_enabled = enable; + // Orca: invalidate hover state when dragging is toggled, otherwise if we turned off dragging + // while hovering above a volume, the hovering state won't update even if mouse has moved away. + // Fixes https://github.com/OrcaSlicer/OrcaSlicer/pull/9979#issuecomment-3065575889 + m_hover_volume_idxs.clear(); + } + void enable_moving(bool enable) { m_moving_enabled = enable; } + void enable_gizmos(bool enable) { m_gizmos.set_enabled(enable); } + void enable_selection(bool enable) { m_selection.set_enabled(enable); } + void enable_main_toolbar(bool enable) { m_main_toolbar.set_enabled(enable); } //BBS: GUI refactor: GLToolbar void _update_select_plate_toolbar_stats_item(bool force_selected = false); void reset_select_plate_toolbar_selection(); @@ -855,10 +870,10 @@ public: void enable_assemble_view_toolbar(bool enable); void enable_return_toolbar(bool enable); void enable_separator_toolbar(bool enable); - void enable_dynamic_background(bool enable); + void enable_dynamic_background(bool enable) { m_dynamic_background_enabled = enable; } void enable_labels(bool enable) { m_labels.enable(enable); } void enable_slope(bool enable) { m_slope.enable(enable); } - void allow_multisample(bool allow); + void allow_multisample(bool allow) { m_multisample_allowed = allow; } void zoom_to_bed(); void zoom_to_volumes(); @@ -963,9 +978,6 @@ public: bool for_picking = false, bool ban_light = false); - //BBS use gcoder viewer render calibration thumbnails - void render_calibration_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params); - //BBS void select_curr_plate_all(); void select_object_from_idx(std::vector& object_idxs); @@ -976,18 +988,14 @@ public: void deselect_all(); void exit_gizmo(); void set_selected_visible(bool visible); - void delete_selected(); + void delete_selected() { m_selection.erase(); } void ensure_on_bed(unsigned int object_idx, bool allow_negative_z); - bool is_gcode_legend_enabled() const { return m_gcode_viewer.is_legend_enabled(); } - GCodeViewer::EViewType get_gcode_view_type() const { return m_gcode_viewer.get_view_type(); } - const std::vector& get_gcode_layers_zs() const; - std::vector get_volumes_print_zs(bool active_only) const; - unsigned int get_gcode_options_visibility_flags() const { return m_gcode_viewer.get_options_visibility_flags(); } - void set_gcode_options_visibility_from_flags(unsigned int flags); - unsigned int get_toolpath_role_visibility_flags() const { return m_gcode_viewer.get_toolpath_role_visibility_flags(); } - void set_volumes_z_range(const std::array& range); - std::vector& get_custom_gcode_per_print_z() { return m_gcode_viewer.get_custom_gcode_per_print_z(); } + std::vector get_gcode_layers_zs() const { return m_gcode_viewer.get_layers_zs(); } + std::vector get_gcode_layers_times() const { return m_gcode_viewer.get_layers_times(); } + const std::vector& get_gcode_layers_times_cache() const { return m_gcode_layers_times_cache; } + void reset_gcode_layers_times_cache() { m_gcode_layers_times_cache.clear(); } + void set_volumes_z_range(const std::array& range) { m_volumes.set_range(range[0] - 1e-6, range[1] + 1e-6); } size_t get_gcode_extruders_count() { return m_gcode_viewer.get_extruders_count(); } std::vector load_object(const ModelObject& model_object, int obj_idx, std::vector instance_idxs); @@ -1003,16 +1011,16 @@ public: void set_shells_on_previewing(bool is_preview) { m_gcode_viewer.set_shells_on_preview(is_preview); } //BBS: add only gcode mode - void load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors, bool only_gcode); - void refresh_gcode_preview_render_paths(); - void set_gcode_view_preview_type(GCodeViewer::EViewType type) { return m_gcode_viewer.set_view_type(type); } - GCodeViewer::EViewType get_gcode_view_preview_type() const { return m_gcode_viewer.get_view_type(); } + void load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors, + const std::vector& str_color_print_colors, bool only_gcode); + void set_gcode_view_type(libvgcode::EViewType type) { return m_gcode_viewer.set_view_type(type); } + libvgcode::EViewType get_gcode_view_type() const { return m_gcode_viewer.get_view_type(); } + void load_sla_preview(); - //void load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values); void bind_event_handlers(); void unbind_event_handlers(); - void on_size(wxSizeEvent& evt); + void on_size(wxSizeEvent& evt) { m_dirty = true; } void on_idle(wxIdleEvent& evt); void on_char(wxKeyEvent& evt); void on_key(wxKeyEvent& evt); @@ -1079,7 +1087,8 @@ public: inline double rotation() const { return m_rotation; } inline const Vec2d bb_size() const { return m_bb.size(); } - void apply_wipe_tower() const; + void apply_wipe_tower() const { apply_wipe_tower(m_pos, m_rotation); } + void apply_wipe_tower(Vec2d pos, double rot) const; }; // BBS: add partplate logic @@ -1101,7 +1110,7 @@ public: Vec2f get_nearest_empty_cell(const Vec2f start_point, const Vec2f step = {10, 10}); void set_cursor(ECursorType type); - void msw_rescale(); + void msw_rescale() { m_gcode_viewer.invalidate_legend(); } void request_extra_frame() { m_extra_frame_requested = true; } @@ -1111,8 +1120,8 @@ public: void force_main_toolbar_left_action(int item_id) { m_main_toolbar.force_left_action(item_id, *this); } void force_main_toolbar_right_action(int item_id) { m_main_toolbar.force_right_action(item_id, *this); } - bool has_toolpaths_to_export() const; - void export_toolpaths_to_obj(const char* filename) const; + bool has_toolpaths_to_export() const { return m_gcode_viewer.can_export_toolpaths(); } + void export_toolpaths_to_obj(const char* filename) const { m_gcode_viewer.export_toolpaths_to_obj(filename); } void mouse_up_cleanup(); @@ -1234,7 +1243,7 @@ private: void _render_selection(); void _render_sequential_clearance(); #if ENABLE_RENDER_SELECTION_CENTER - void _render_selection_center(); + void _render_selection_center() { m_selection.render_center(m_gizmos.is_dragging()); } #endif // ENABLE_RENDER_SELECTION_CENTER void _check_and_update_toolbar_icon_scale(); void _render_overlays(); @@ -1260,7 +1269,7 @@ private: void _render_camera_target(); #endif // ENABLE_SHOW_CAMERA_TARGET void _render_sla_slices(); - void _render_selection_sidebar_hints(); + void _render_selection_sidebar_hints() { m_selection.render_sidebar_hints(m_sidebar_field, m_gizmos.get_uniform_scaling()); } //BBS: GUI refactor: adjust main toolbar position bool _render_orient_menu(float left, float right, float bottom, float top); bool _render_arrange_menu(float left, float right, float bottom, float top); @@ -1271,23 +1280,12 @@ private: // Convert the screen space coordinate to world coordinate on the bed. Vec3d _mouse_to_bed_3d(const Point& mouse_pos); - void _start_timer(); - void _stop_timer(); - - // Create 3D thick extrusion lines for a skirt and brim. - // Adds a new Slic3r::GUI::3DScene::Volume to volumes, updates collision with the build_volume. - void _load_print_toolpaths(const BuildVolume &build_volume); - // Create 3D thick extrusion lines for object forming extrusions. - // Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes, - // one for perimeters, one for infill and one for supports, updates collision with the build_volume. - void _load_print_object_toolpaths(const PrintObject& print_object, const BuildVolume &build_volume, - const std::vector& str_tool_colors, const std::vector& color_print_values); - // Create 3D thick extrusion lines for wipe tower extrusions, updates collision with the build_volume. - void _load_wipe_tower_toolpaths(const BuildVolume &build_volume, const std::vector& str_tool_colors); + void _start_timer() { m_timer.Start(100, wxTIMER_CONTINUOUS); } + void _stop_timer() { m_timer.Stop(); } // Load SLA objects and support structures for objects, for which the slaposSliceSupports step has been finished. - void _load_sla_shells(); - void _update_sla_shells_outside_state(); + void _load_sla_shells(); + void _update_sla_shells_outside_state() { check_volumes_outside_state(); } void _set_warning_notification_if_needed(EWarning warning); //BBS: add partplate print volume get function diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 76d2711266..507768ad64 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -551,6 +551,16 @@ void GLModel::reset() glsafe(::glDeleteBuffers(1, &m_render_data.vbo_id)); m_render_data.vbo_id = 0; } +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + if (m_render_data.vao_id > 0) { + glsafe(::glDeleteVertexArrays(1, &m_render_data.vao_id)); + m_render_data.vao_id = 0; + } +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES m_render_data.vertices_count = 0; m_render_data.indices_count = 0; @@ -619,6 +629,14 @@ void GLModel::render(const std::pair& range) const bool normal = Geometry::has_normal(data.format); const bool tex_coord = Geometry::has_tex_coord(data.format); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + glsafe(::glBindVertexArray(m_render_data.vao_id)); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES + // the following binding is needed to set the vertex attributes glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id)); int position_id = -1; @@ -661,6 +679,13 @@ void GLModel::render(const std::pair& range) glsafe(::glDisableVertexAttribArray(position_id)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + glsafe(::glBindVertexArray(0)); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES } void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instances_count) @@ -689,6 +714,14 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance return; } +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + glsafe(::glBindVertexArray(m_render_data.vao_id)); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, instances_vbo)); const size_t instance_stride = 5 * sizeof(float); glsafe(::glVertexAttribPointer(offset_id, 3, GL_FLOAT, GL_FALSE, instance_stride, (const void*)0)); @@ -735,6 +768,13 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance glsafe(::glDisableVertexAttribArray(offset_id)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + glsafe(::glBindVertexArray(0)); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES } bool GLModel::send_to_gpu() @@ -750,6 +790,15 @@ bool GLModel::send_to_gpu() return false; } +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + glsafe(::glGenVertexArrays(1, &m_render_data.vao_id)); + glsafe(::glBindVertexArray(m_render_data.vao_id)); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES + // vertices glsafe(::glGenBuffers(1, &m_render_data.vbo_id)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id)); @@ -790,6 +839,14 @@ bool GLModel::send_to_gpu() m_render_data.indices_count = indices_count; data.indices = std::vector(); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + glsafe(::glBindVertexArray(0)); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES + return true; } diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index c1d6c49e61..13729f5a9e 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -131,6 +131,7 @@ namespace GUI { struct RenderData { Geometry geometry; + unsigned int vao_id{ 0 }; unsigned int vbo_id{ 0 }; unsigned int ibo_id{ 0 }; size_t vertices_count{ 0 }; diff --git a/src/slic3r/GUI/GLSelectionRectangle.cpp b/src/slic3r/GUI/GLSelectionRectangle.cpp index 3cb9b82593..2f3ba3d49b 100644 --- a/src/slic3r/GUI/GLSelectionRectangle.cpp +++ b/src/slic3r/GUI/GLSelectionRectangle.cpp @@ -72,15 +72,26 @@ namespace GUI { const float top = -2.0f * (get_top() * cnv_inv_height - 0.5f); const float bottom = -2.0f * (get_bottom() * cnv_inv_height - 0.5f); - glsafe(::glLineWidth(1.5f)); +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth(1.5f)); +#endif // !SLIC3R_OPENGL_ES glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glPushAttrib(GL_ENABLE_BIT)); - glsafe(::glLineStipple(4, 0xAAAA)); - glsafe(::glEnable(GL_LINE_STIPPLE)); +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) { + glsafe(::glPushAttrib(GL_ENABLE_BIT)); + glsafe(::glLineStipple(4, 0xAAAA)); + glsafe(::glEnable(GL_LINE_STIPPLE)); + } +#endif // !SLIC3R_OPENGL_ES - GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#if SLIC3R_OPENGL_ES + GLShaderProgram* shader = wxGetApp().get_shader("dashed_lines"); +#else + GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); +#endif // SLIC3R_OPENGL_ES if (shader != nullptr) { shader->start_using(); @@ -90,34 +101,86 @@ namespace GUI { m_rectangle.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 }; - init_data.reserve_vertices(4); - init_data.reserve_indices(4); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P4 }; + init_data.reserve_vertices(5); + init_data.reserve_indices(8); +#if !SLIC3R_OPENGL_ES + } + else { + init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 }; + init_data.reserve_vertices(4); + init_data.reserve_indices(4); + } +#endif // !SLIC3R_OPENGL_ES // vertices - init_data.add_vertex(Vec2f(left, bottom)); - init_data.add_vertex(Vec2f(right, bottom)); - init_data.add_vertex(Vec2f(right, top)); - init_data.add_vertex(Vec2f(left, top)); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + const float width = right - left; + const float height = top - bottom; + float perimeter = 0.0f; - // indices - init_data.add_index(0); - init_data.add_index(1); - init_data.add_index(2); - init_data.add_index(3); + init_data.add_vertex(Vec4f(left, bottom, 0.0f, perimeter)); + perimeter += width; + init_data.add_vertex(Vec4f(right, bottom, 0.0f, perimeter)); + perimeter += height; + init_data.add_vertex(Vec4f(right, top, 0.0f, perimeter)); + perimeter += width; + init_data.add_vertex(Vec4f(left, top, 0.0f, perimeter)); + perimeter += height; + init_data.add_vertex(Vec4f(left, bottom, 0.0f, perimeter)); + + // indices + init_data.add_line(0, 1); + init_data.add_line(1, 2); + init_data.add_line(2, 3); + init_data.add_line(3, 4); +#if !SLIC3R_OPENGL_ES + } + else { + init_data.add_vertex(Vec2f(left, bottom)); + init_data.add_vertex(Vec2f(right, bottom)); + init_data.add_vertex(Vec2f(right, top)); + init_data.add_vertex(Vec2f(left, top)); + + // indices + init_data.add_index(0); + init_data.add_index(1); + init_data.add_index(2); + init_data.add_index(3); + } +#endif // !SLIC3R_OPENGL_ES m_rectangle.init_from(std::move(init_data)); } shader->set_uniform("view_model_matrix", Transform3d::Identity()); shader->set_uniform("projection_matrix", Transform3d::Identity()); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + const std::array& viewport = wxGetApp().plater()->get_camera().get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 0.25f); + shader->set_uniform("dash_size", 0.01f); + shader->set_uniform("gap_size", 0.0075f); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES m_rectangle.set_color(ColorRGBA::ORCA()); // ORCA: use orca color for selection rectangle m_rectangle.render(); shader->stop_using(); } - glsafe(::glPopAttrib()); +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glPopAttrib()); +#endif // !SLIC3R_OPENGL_ES } } // namespace GUI diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index d3215ab84c..2a0d5433cf 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -33,7 +33,13 @@ std::pair GLShadersManager::init() bool valid = true; +#if SLIC3R_OPENGL_ES + const std::string prefix = "ES/"; + // used to render wireframed triangles + valid &= append_shader("wireframe", { prefix + "wireframe.vs", prefix + "wireframe.fs" }); +#else const std::string prefix = GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 1) ? "140/" : "110/"; +#endif // SLIC3R_OPENGL_ES // imgui shader valid &= append_shader("imgui", { prefix + "imgui.vs", prefix + "imgui.fs" }); // basic shader, used to render all what was previously rendered using the immediate mode @@ -44,13 +50,21 @@ std::pair GLShadersManager::init() valid &= append_shader("flat_texture", { prefix + "flat_texture.vs", prefix + "flat_texture.fs" }); // used to render 3D scene background valid &= append_shader("background", { prefix + "background.vs", prefix + "background.fs" }); +#if SLIC3R_OPENGL_ES + // used to render dashed lines + valid &= append_shader("dashed_lines", { prefix + "dashed_lines.vs", prefix + "dashed_lines.fs" }); +#else + if (GUI::OpenGLManager::get_gl_info().is_core_profile()) + // used to render thick and/or dashed lines + valid &= append_shader("dashed_thick_lines", { prefix + "dashed_thick_lines.vs", prefix + "dashed_thick_lines.fs", prefix + "dashed_thick_lines.gs" }); +#endif // SLIC3R_OPENGL_ES // used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells, options in gcode preview valid &= append_shader("gouraud_light", { prefix + "gouraud_light.vs", prefix + "gouraud_light.fs" }); //used to render thumbnail valid &= append_shader("thumbnail", { prefix + "thumbnail.vs", prefix + "thumbnail.fs"}); // used to render printbed valid &= append_shader("printbed", { prefix + "printbed.vs", prefix + "printbed.fs" }); - valid &= append_shader("hotbed", {"110/hotbed.vs", "110/hotbed.fs"}); + valid &= append_shader("hotbed", {prefix + "hotbed.vs", prefix + "hotbed.fs"}); // used to render options in gcode preview if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) { valid &= append_shader("gouraud_light_instanced", { prefix + "gouraud_light_instanced.vs", prefix + "gouraud_light_instanced.fs" }); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index fda19112d4..01961271c6 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -2278,7 +2278,8 @@ std::string GUI_App::get_gl_info(bool for_github) wxGLContext* GUI_App::init_glcontext(wxGLCanvas& canvas) { - return m_opengl_mgr.init_glcontext(canvas); + return m_opengl_mgr.init_glcontext(canvas, init_params != nullptr ? init_params->opengl_version : std::make_pair(0, 0), + init_params != nullptr ? init_params->opengl_compatibility_profile : false, init_params != nullptr ? init_params->opengl_debug : false); } bool GUI_App::init_opengl() @@ -6567,7 +6568,7 @@ void GUI_App::open_preferences(size_t open_on_tab, const std::string& highlight_ #else if (dlg.seq_top_layer_only_changed()) #endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER - this->plater_->refresh_print(); + this->plater_->reload_print(); #ifdef _WIN32 if (is_editor()) { if (app_config->get("associate_3mf") == "true") diff --git a/src/slic3r/GUI/GUI_Init.cpp b/src/slic3r/GUI/GUI_Init.cpp index b86a1db081..8130fe90f5 100644 --- a/src/slic3r/GUI/GUI_Init.cpp +++ b/src/slic3r/GUI/GUI_Init.cpp @@ -23,6 +23,8 @@ namespace Slic3r { namespace GUI { +const std::vector> OpenGLVersions::core = { {3,2}, {3,3}, {4,0}, {4,1}, {4,2}, {4,3}, {4,4}, {4,5}, {4,6} }; + int GUI_Run(GUI_InitParams ¶ms) { #if __APPLE__ diff --git a/src/slic3r/GUI/GUI_Init.hpp b/src/slic3r/GUI/GUI_Init.hpp index 8b30b3ed19..0d987fa014 100644 --- a/src/slic3r/GUI/GUI_Init.hpp +++ b/src/slic3r/GUI/GUI_Init.hpp @@ -8,6 +8,11 @@ namespace Slic3r { namespace GUI { +struct OpenGLVersions +{ + static const std::vector> core; +}; + struct GUI_InitParams { int argc; @@ -20,6 +25,10 @@ struct GUI_InitParams DynamicPrintConfig extra_config; std::vector input_files; + std::pair opengl_version { 0, 0 }; + bool opengl_debug { false }; + bool opengl_compatibility_profile { false }; + //BBS: remove start_as_gcodeviewer logic //bool start_as_gcodeviewer; bool input_gcode { false }; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 1dcdbe350d..ea3ae5d21d 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -5,6 +5,9 @@ #include "GUI_Preview.hpp" #include "GUI_App.hpp" #include "GUI.hpp" +#if ENABLE_OPENGL_AUTO_AA_SAMPLES +#include "GUI_Init.hpp" +#endif // ENABLE_OPENGL_AUTO_AA_SAMPLES #include "I18N.hpp" #include "3DScene.hpp" #include "BackgroundSlicingProcess.hpp" @@ -55,6 +58,10 @@ bool View3D::init(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrintConfig if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */)) return false; +#if ENABLE_OPENGL_AUTO_AA_SAMPLES + const GUI_InitParams* const init_params = wxGetApp().init_params; + m_canvas_widget = OpenGLManager::create_wxglcanvas(*this, (init_params != nullptr) ? init_params->opengl_aa : false); +#else m_canvas_widget = OpenGLManager::create_wxglcanvas(*this); if (m_canvas_widget == nullptr) return false; @@ -254,6 +261,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Model* model) #endif // _WIN32 m_canvas_widget = OpenGLManager::create_wxglcanvas(*this); +#endif // ENABLE_OPENGL_AUTO_AA_SAMPLES if (m_canvas_widget == nullptr) return false; @@ -264,8 +272,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Model* model) m_canvas->set_model(model); m_canvas->set_process(m_process); m_canvas->set_type(GLCanvas3D::ECanvasType::CanvasPreview); - m_canvas->enable_legend_texture(true); - + m_canvas->get_gcode_viewer().enable_legend(true); //BBS: GUI refactor: GLToolbar if (wxGetApp().is_editor()) { m_canvas->enable_select_plate_toolbar(true); @@ -332,50 +339,16 @@ void Preview::load_print(bool keep_z_range, bool only_gcode) } //BBS: add only gcode mode -void Preview::reload_print(bool keep_volumes, bool only_gcode) +void Preview::reload_print(bool only_gcode) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" %1%: enter, keep_volumes %2%")%__LINE__ %keep_volumes; -#ifdef __linux__ - // We are getting mysterious crashes on Linux in gtk due to OpenGL context activation GH #1874 #1955. - // So we are applying a workaround here: a delayed release of OpenGL vertex buffers. - if (!IsShown()) - { - m_volumes_cleanup_required = !keep_volumes; - return; - } -#endif /* __linux__ */ - if ( -#ifdef __linux__ - m_volumes_cleanup_required || -#endif /* __linux__ */ - !keep_volumes) - { - m_canvas->reset_volumes(); - //BBS: add m_loaded_print logic - //m_loaded = false; - m_loaded_print = nullptr; -#ifdef __linux__ - m_volumes_cleanup_required = false; -#endif /* __linux__ */ - } + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" %1%: enter")%__LINE__; - load_print(false, only_gcode); - m_only_gcode = only_gcode; -} - -//BBS: add only gcode mode -void Preview::refresh_print() -{ - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" %1%: enter, current m_loaded_print %2%")%__LINE__ %m_loaded_print; //BBS: add m_loaded_print logic //m_loaded = false; m_loaded_print = nullptr; - if (!IsShown()) - return; - - load_print(true, m_only_gcode); - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" %1%: exit")%__LINE__; + load_print(false, only_gcode); + m_only_gcode = only_gcode; } //BBS: always load shell at preview @@ -396,7 +369,7 @@ void Preview::msw_rescale() get_canvas3d()->msw_rescale(); // rescale legend - refresh_print(); + reload_print(m_only_gcode); } void Preview::sys_color_changed() @@ -580,7 +553,7 @@ void Preview::update_layers_slider(const std::vector& layers_z, bool kee ticks_info_from_curr_plate = plater->model().get_curr_plate_custom_gcodes(); else { ticks_info_from_curr_plate.mode = CustomGCode::Mode::SingleExtruder; - ticks_info_from_curr_plate.gcodes = m_canvas->get_custom_gcode_per_print_z(); + ticks_info_from_curr_plate.gcodes = m_gcode_result->custom_gcode_per_print_z; } check_layers_slider_values(ticks_info_from_curr_plate.gcodes, layers_z); @@ -612,7 +585,7 @@ void Preview::update_layers_slider(const std::vector& layers_z, bool kee m_layers_slider->SetTicksValues(ticks_info_from_curr_plate); auto print_mode_stat = m_gcode_result->print_statistics.modes.front(); - m_layers_slider->SetLayersTimes(print_mode_stat.layers_times, print_mode_stat.time); + m_layers_slider->SetLayersTimes(m_canvas->get_gcode_layers_times_cache(), print_mode_stat.time); // Suggest the auto color change, if model looks like sign if (m_layers_slider->IsNewPrint()) { @@ -701,28 +674,17 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode) else if (directly_preview && !has_layers) keep_z_range = false; - GCodeViewer::EViewType gcode_view_type = m_canvas->get_gcode_view_preview_type(); - bool gcode_preview_data_valid = !m_gcode_result->moves.empty(); + libvgcode::EViewType gcode_view_type = m_canvas->get_gcode_view_type(); + const bool gcode_preview_data_valid = !m_gcode_result->moves.empty(); + const bool is_pregcode_preview = !gcode_preview_data_valid && wxGetApp().is_editor(); - // Collect colors per extruder. - std::vector colors; - std::vector color_print_values = {}; - // set color print values, if it si selected "ColorPrint" view type - if (gcode_view_type == GCodeViewer::EViewType::ColorPrint) { - colors = wxGetApp().plater()->get_colors_for_color_print(m_gcode_result); - - if (!gcode_preview_data_valid) { - if (wxGetApp().is_editor()) - //BBS - color_print_values = wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes; - else - color_print_values = m_canvas->get_custom_gcode_per_print_z(); - colors.push_back("#808080"); // gray color for pause print or custom G-code - } - } - else if (gcode_preview_data_valid || gcode_view_type == GCodeViewer::EViewType::Tool) { - colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(m_gcode_result); - color_print_values.clear(); + const std::vector tool_colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(m_gcode_result); + const std::vector& color_print_values = wxGetApp().is_editor() ? + wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes : m_gcode_result->custom_gcode_per_print_z; + std::vector color_print_colors; + if (!color_print_values.empty()) { + color_print_colors = wxGetApp().plater()->get_colors_for_color_print(m_gcode_result); + color_print_colors.push_back("#808080"); // gray color for pause print or custom G-code } std::vector zs; @@ -735,7 +697,9 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode) //BBS: add more log BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": will load gcode_preview from result, moves count %1%") % m_gcode_result->moves.size(); //BBS: add only gcode mode - m_canvas->load_gcode_preview(*m_gcode_result, colors, only_gcode); + m_canvas->load_gcode_preview(*m_gcode_result, tool_colors, color_print_colors, only_gcode); + // the view type may have been changed by the call m_canvas->load_gcode_preview() + gcode_view_type = m_canvas->get_gcode_view_type(); //BBS show sliders show_moves_sliders(); @@ -748,7 +712,7 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode) //m_loaded = true; m_loaded_print = print; } - else if (wxGetApp().is_editor()) { + else if (is_pregcode_preview) { // Load the initial preview based on slices, not the final G-code. //BBS: only display shell before slicing result out //m_canvas->load_preview(colors, color_print_values); @@ -764,7 +728,7 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode) std::vector gcodes = wxGetApp().is_editor() ? //BBS wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes : - m_canvas->get_custom_gcode_per_print_z(); + m_gcode_result->custom_gcode_per_print_z; const wxString choice = !gcodes.empty() ? _L("Multicolor Print") : (number_extruders > 1) ? _L("Filaments") : _L("Line Type"); @@ -775,7 +739,8 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode) //BBS show_layers_sliders(false); m_canvas_widget->Refresh(); - } else + } + else update_layers_slider(zs, keep_z_range); } } @@ -798,7 +763,12 @@ bool AssembleView::init(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrint if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */)) return false; +#if ENABLE_OPENGL_AUTO_AA_SAMPLES + const GUI_InitParams* const init_params = wxGetApp().init_params; + m_canvas_widget = OpenGLManager::create_wxglcanvas(*this, (init_params != nullptr) ? init_params->opengl_aa : false); +#else m_canvas_widget = OpenGLManager::create_wxglcanvas(*this); +#endif // ENABLE_OPENGL_AUTO_AA_SAMPLES if (m_canvas_widget == nullptr) return false; diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 0478cc9818..5469e32b71 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -92,12 +92,6 @@ class Preview : public wxPanel BackgroundSlicingProcess* m_process; GCodeProcessorResult* m_gcode_result; -#ifdef __linux__ - // We are getting mysterious crashes on Linux in gtk due to OpenGL context activation GH #1874 #1955. - // So we are applying a workaround here. - bool m_volumes_cleanup_required { false }; -#endif /* __linux__ */ - // Calling this function object forces Plater::schedule_background_process. std::function m_schedule_background_process; @@ -146,8 +140,7 @@ public: //BBS: add only gcode mode void load_print(bool keep_z_range = false, bool only_gcode = false); - void reload_print(bool keep_volumes = false, bool only_gcode = false); - void refresh_print(); + void reload_print(bool only_gcode = false); //BBS: always load shell at preview void load_shells(const Print& print, bool force_previewing = false); void reset_shells(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp index 602b622f45..8c6349f58f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp @@ -989,11 +989,19 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers() } glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glLineWidth(m_hover_id != -1 ? 2.0f : 1.5f)); - glLineStipple(1, 0x0FFF); - glEnable(GL_LINE_STIPPLE); + // ORCA: OpenGL Core Profile +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) { + glsafe(::glLineWidth(m_hover_id != -1 ? 2.0f : 1.5f)); + glLineStipple(1, 0x0FFF); + glEnable(GL_LINE_STIPPLE); + } +#endif // !SLIC3R_OPENGL_ES m_grabber_connection.render(); - glDisable(GL_LINE_STIPPLE); +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glDisable(GL_LINE_STIPPLE); +#endif // !SLIC3R_OPENGL_ES shader->stop_using(); } @@ -1147,10 +1155,18 @@ void GLGizmoAdvancedCut::render_cut_line() shader->set_uniform("view_model_matrix", camera.get_view_matrix()); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); - glEnable(GL_LINE_STIPPLE); - glLineStipple(1, 0x0FFF); + // ORCA: OpenGL Core Profile +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) { + glEnable(GL_LINE_STIPPLE); + glLineStipple(1, 0x0FFF); + } +#endif // !SLIC3R_OPENGL_ES m_cut_line.render(); - glDisable(GL_LINE_STIPPLE); +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glDisable(GL_LINE_STIPPLE); +#endif // !SLIC3R_OPENGL_ES shader->stop_using(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 1031110fa8..f72bf8bcc0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -231,7 +231,11 @@ void GLGizmoBase::render_cross_mark(const Vec3f &target, bool is_single) { const float half_length = 4.0f; - glsafe(::glLineWidth(2.0f)); + // ORCA: OpenGL Core Profile +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth(2.0f)); +#endif // !SLIC3R_OPENGL_ES auto render_line = [](const Vec3f& p1, const Vec3f& p2, const ColorRGBA& color) { GLModel::Geometry init_data; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 233e4d941b..eeeb3da285 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1184,24 +1184,30 @@ void GLGizmoMeasure::render_dimensioning() const Transform3d ss_to_ndc_matrix = TransformHelper::ndc_to_ss_matrix_inverse(viewport); -#if ENABLE_GL_CORE_PROFILE +#if !SLIC3R_OPENGL_ES if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES shader->stop_using(); - shader = wxGetApp().get_shader("dashed_thick_lines"); +#if SLIC3R_OPENGL_ES + shader = wxGetApp().get_shader("dashed_lines"); +#else + shader = wxGetApp().get_shader("dashed_thick_lines"); +#endif // SLIC3R_OPENGL_ES if (shader == nullptr) return; shader->start_using(); shader->set_uniform("projection_matrix", Transform3d::Identity()); - const std::array& viewport = camera.get_viewport(); shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); shader->set_uniform("width", 1.0f); shader->set_uniform("gap_size", 0.0f); +#if !SLIC3R_OPENGL_ES } else -#endif // ENABLE_GL_CORE_PROFILE - glsafe(::glLineWidth(2.0f)); + glsafe(::glLineWidth(2.0f)); +#endif // !SLIC3R_OPENGL_ES + // stem shader->set_uniform("view_model_matrix", overlap ? ss_to_ndc_matrix * Geometry::translation_transform(v1ss_3) * q12ss * Geometry::translation_transform(-2.0 * TRIANGLE_HEIGHT * Vec3d::UnitX()) * Geometry::scale_transform({ v12ss_len + 4.0 * TRIANGLE_HEIGHT, 1.0f, 1.0f }) : @@ -1209,8 +1215,9 @@ void GLGizmoMeasure::render_dimensioning() m_dimensioning.line.set_color(color); m_dimensioning.line.render(); -#if ENABLE_GL_CORE_PROFILE +#if !SLIC3R_OPENGL_ES if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES shader->stop_using(); shader = wxGetApp().get_shader("flat"); @@ -1218,10 +1225,11 @@ void GLGizmoMeasure::render_dimensioning() return; shader->start_using(); +#if !SLIC3R_OPENGL_ES } else -#endif // ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth(1.0f)); +#endif // !SLIC3R_OPENGL_ES // arrow 1 if (show_first_tri) { @@ -1441,11 +1449,16 @@ void GLGizmoMeasure::render_dimensioning() } const Camera& camera = wxGetApp().plater()->get_camera(); -#if ENABLE_GL_CORE_PROFILE +#if !SLIC3R_OPENGL_ES if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES shader->stop_using(); +#if SLIC3R_OPENGL_ES + shader = wxGetApp().get_shader("dashed_lines"); +#else shader = wxGetApp().get_shader("dashed_thick_lines"); +#endif // SLIC3R_OPENGL_ES if (shader == nullptr) return; @@ -1455,18 +1468,20 @@ void GLGizmoMeasure::render_dimensioning() shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); shader->set_uniform("width", 1.0f); shader->set_uniform("gap_size", 0.0f); +#if !SLIC3R_OPENGL_ES } else -#endif // ENABLE_GL_CORE_PROFILE - glsafe(::glLineWidth(2.0f)); + glsafe(::glLineWidth(2.0f)); +#endif // !SLIC3R_OPENGL_ES // arc shader->set_uniform("projection_matrix", camera.get_projection_matrix()); shader->set_uniform("view_model_matrix", camera.get_view_matrix() * Geometry::translation_transform(center)); m_dimensioning.arc.render(); -#if ENABLE_GL_CORE_PROFILE +#if !SLIC3R_OPENGL_ES if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES shader->stop_using(); shader = wxGetApp().get_shader("flat"); @@ -1474,10 +1489,11 @@ void GLGizmoMeasure::render_dimensioning() return; shader->start_using(); +#if !SLIC3R_OPENGL_ES } else -#endif // ENABLE_GL_CORE_PROFILE - glsafe(::glLineWidth(1.0f)); + glsafe(::glLineWidth(1.0f)); +#endif // !SLIC3R_OPENGL_ES // arrows auto render_arrow = [this, shader, &camera, &normal, ¢er, &e1_unit, draw_radius, step, resolution](unsigned int endpoint_id) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index 0c21a3ade6..d8bc90fdd6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -887,6 +887,16 @@ void GLMmSegmentationGizmo3DScene::release_geometry() { glsafe(::glDeleteBuffers(1, &triangle_indices_VBO_id)); triangle_indices_VBO_id = 0; } +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + if (this->vertices_VAO_id > 0) { + glsafe(::glDeleteVertexArrays(1, &this->vertices_VAO_id)); + this->vertices_VAO_id = 0; + } +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES this->clear(); } @@ -895,6 +905,13 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const { assert(triangle_indices_idx < this->triangle_indices_VBO_ids.size()); assert(this->triangle_patches.size() == this->triangle_indices_VBO_ids.size()); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + assert(this->vertices_VAO_id != 0); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES assert(this->vertices_VBO_id != 0); assert(this->triangle_indices_VBO_ids[triangle_indices_idx] != 0); @@ -902,6 +919,13 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const if (shader == nullptr) return; +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + glsafe(::glBindVertexArray(this->vertices_VAO_id)); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES // the following binding is needed to set the vertex attributes glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_VBO_id)); const GLint position_id = shader->get_attrib_location("v_position"); @@ -922,17 +946,48 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const glsafe(::glDisableVertexAttribArray(position_id)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + glsafe(::glBindVertexArray(0)); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES } void GLMmSegmentationGizmo3DScene::finalize_vertices() { +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + assert(this->vertices_VAO_id == 0); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES assert(this->vertices_VBO_id == 0); if (!this->vertices.empty()) { +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + glsafe(::glGenVertexArrays(1, &this->vertices_VAO_id)); + glsafe(::glBindVertexArray(this->vertices_VAO_id)); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES + glsafe(::glGenBuffers(1, &this->vertices_VBO_id)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_VBO_id)); glsafe(::glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(float), this->vertices.data(), GL_STATIC_DRAW)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); this->vertices.clear(); + +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + glsafe(::glBindVertexArray(0)); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp index 00017f2a93..2ab524e379 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp @@ -57,6 +57,7 @@ public: // IDs of the Vertex Array Objects, into which the geometry has been loaded. // Zero if the VBOs are not sent to GPU yet. + unsigned int vertices_VAO_id{ 0 }; unsigned int vertices_VBO_id{0}; std::vector triangle_indices_VBO_ids; }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index c82936650b..8a82f14e8e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -160,7 +160,11 @@ void GLGizmoMove3D::on_render() m_grabbers[i].color = AXES_COLOR[i]; m_grabbers[i].hover_color = AXES_HOVER_COLOR[i]; } - glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); + +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); +#endif // !SLIC3R_OPENGL_ES auto render_grabber_connection = [this, &zero](unsigned int id) { if (m_grabbers[id].enabled) { @@ -184,19 +188,41 @@ void GLGizmoMove3D::on_render() m_grabber_connections[id].model.init_from(std::move(init_data)); //} - glLineStipple(1, 0x0FFF); - glEnable(GL_LINE_STIPPLE); + // ORCA: OpenGL Core Profile +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) { + glLineStipple(1, 0x0FFF); + glEnable(GL_LINE_STIPPLE); + } +#endif // !SLIC3R_OPENGL_ES m_grabber_connections[id].model.render(); - glDisable(GL_LINE_STIPPLE); +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glDisable(GL_LINE_STIPPLE); +#endif // !SLIC3R_OPENGL_ES } }; - GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#if SLIC3R_OPENGL_ES + GLShaderProgram* shader = wxGetApp().get_shader("dashed_lines"); +#else + GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); +#endif // SLIC3R_OPENGL_ES if (shader != nullptr) { shader->start_using(); const Camera& camera = wxGetApp().plater()->get_camera(); shader->set_uniform("view_model_matrix", camera.get_view_matrix() * base_matrix); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + const std::array& viewport = camera.get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 0.25f); + shader->set_uniform("gap_size", 0.0f); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES // draw axes for (unsigned int i = 0; i < 3; ++i) { @@ -210,7 +236,11 @@ void GLGizmoMove3D::on_render() render_grabbers(box); if (m_object_manipulation->is_instance_coordinates()) { - shader = wxGetApp().get_shader("flat"); +#if SLIC3R_OPENGL_ES + GLShaderProgram* shader = wxGetApp().get_shader("dashed_lines"); +#else + GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); +#endif // SLIC3R_OPENGL_ES if (shader != nullptr) { shader->start_using(); const Camera& camera = wxGetApp().plater()->get_camera(); @@ -224,6 +254,16 @@ void GLGizmoMove3D::on_render() shader->set_uniform("view_model_matrix", camera.get_view_matrix() * cur_tran.get_matrix()); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif /// !SLIC3R_OPENGL_ES + const std::array& viewport = camera.get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 0.5f); + shader->set_uniform("gap_size", 0.0f); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES render_cross_mark(Vec3f::Zero(), true); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index 319f3a57cf..7d3f40bd12 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -181,14 +181,23 @@ void GLGizmoPainterBase::render_cursor_circle() const float cnv_inv_height = 1.0f / cnv_height; const Vec2d center = m_parent.get_local_mouse_position(); + const float zoom = float(wxGetApp().plater()->get_camera().get_zoom()); const float radius = m_cursor_radius * float(wxGetApp().plater()->get_camera().get_zoom()); - glsafe(::glLineWidth(1.5f)); +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth(1.5f)); +#endif // !SLIC3R_OPENGL_ES + glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glPushAttrib(GL_ENABLE_BIT)); - glsafe(::glLineStipple(4, 0xAAAA)); - glsafe(::glEnable(GL_LINE_STIPPLE)); +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) { + glsafe(::glPushAttrib(GL_ENABLE_BIT)); + glsafe(::glLineStipple(4, 0xAAAA)); + glsafe(::glEnable(GL_LINE_STIPPLE)); + } +#endif // !SLIC3R_OPENGL_ES if (!m_circle.is_initialized() || !m_old_center.isApprox(center) || std::abs(m_old_cursor_radius - radius) > EPSILON) { m_old_cursor_radius = radius; @@ -196,19 +205,49 @@ void GLGizmoPainterBase::render_cursor_circle() m_circle.reset(); GLModel::Geometry init_data; - static const unsigned int StepsCount = 32; - static const float StepSize = 2.0f * float(PI) / float(StepsCount); - init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 }; + unsigned int steps_count = 0; +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + steps_count = (unsigned int)(2 * (4 + int(252 * (zoom - 1.0f) / (250.0f - 1.0f)))); + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P2 }; +#if !SLIC3R_OPENGL_ES + } + else { + steps_count = 32; + init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 }; + } +#endif // !SLIC3R_OPENGL_ES + const float step_size = 2.0f * float(PI) / float(steps_count); init_data.color = { 0.0f, 1.0f, 0.3f, 1.0f }; - init_data.reserve_vertices(StepsCount); - init_data.reserve_indices(StepsCount); + init_data.reserve_vertices(steps_count); + init_data.reserve_indices(steps_count); // vertices + indices - for (unsigned int i = 0; i < StepsCount; ++i) { - const float angle = float(i * StepSize); - init_data.add_vertex(Vec2f(2.0f * ((center.x() + ::cos(angle) * radius) * cnv_inv_width - 0.5f), - -2.0f * ((center.y() + ::sin(angle) * radius) * cnv_inv_height - 0.5f))); - init_data.add_index(i); + for (unsigned int i = 0; i < steps_count; ++i) { +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + if (i % 2 != 0) continue; + + const float angle_i = float(i) * step_size; + const unsigned int j = (i + 1) % steps_count; + const float angle_j = float(j) * step_size; + const Vec2d v_i(::cos(angle_i), ::sin(angle_i)); + const Vec2d v_j(::cos(angle_j), ::sin(angle_j)); + init_data.add_vertex(Vec2f(v_i.x(), v_i.y())); + init_data.add_vertex(Vec2f(v_j.x(), v_j.y())); + const size_t vcount = init_data.vertices_count(); + init_data.add_line(vcount - 2, vcount - 1); +#if !SLIC3R_OPENGL_ES + } + else { + const float angle = float(i) * step_size; + init_data.add_vertex(Vec2f(2.0f * ((center.x() + ::cos(angle) * radius) * cnv_inv_width - 0.5f), + -2.0f * ((center.y() + ::sin(angle) * radius) * cnv_inv_height - 0.5f))); + init_data.add_index(i); + } +#endif // !SLIC3R_OPENGL_ES } m_circle.init_from(std::move(init_data)); @@ -223,16 +262,43 @@ void GLGizmoPainterBase::render_cursor_circle() m_circle.set_color(render_color); - GLShaderProgram* shader = GUI::wxGetApp().get_shader("flat"); +#if SLIC3R_OPENGL_ES + GLShaderProgram* shader = wxGetApp().get_shader("dashed_lines"); +#else + GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); +#endif // SLIC3R_OPENGL_ES if (shader != nullptr) { shader->start_using(); - shader->set_uniform("view_model_matrix", Transform3d::Identity()); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + const Transform3d view_model_matrix = Geometry::translation_transform(Vec3d(2.0f * (center.x() * cnv_inv_width - 0.5f), -2.0f * (center.y() * cnv_inv_height - 0.5f), 0.0)) * + Geometry::scale_transform(Vec3d(2.0f * radius * cnv_inv_width, 2.0f * radius * cnv_inv_height, 1.0f)); + shader->set_uniform("view_model_matrix", view_model_matrix); +#if !SLIC3R_OPENGL_ES + } + else + shader->set_uniform("view_model_matrix", Transform3d::Identity()); +#endif // !SLIC3R_OPENGL_ES shader->set_uniform("projection_matrix", Transform3d::Identity()); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + const std::array& viewport = wxGetApp().plater()->get_camera().get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 0.25f); + shader->set_uniform("gap_size", 0.0f); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES m_circle.render(); shader->stop_using(); } - glsafe(::glPopAttrib()); +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glPopAttrib()); +#endif // !SLIC3R_OPENGL_ES glsafe(::glEnable(GL_DEPTH_TEST)); } @@ -326,7 +392,11 @@ void GLGizmoPainterBase::render_cursor_height_range(const Transform3d& trafo) co shader->set_uniform("view_model_matrix", view_model_matrix); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); - glsafe(::glLineWidth(2.0f)); + // ORCA: OpenGL Core Profile +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth(2.0f)); +#endif // !SLIC3R_OPENGL_ES m_cut_contours[m_volumes_index].contours.render(); m_volumes_index++; } @@ -1528,6 +1598,13 @@ void TriangleSelectorPatch::render(int triangle_indices_idx, bool show_wireframe { assert(triangle_indices_idx < this->m_triangle_indices_VBO_ids.size()); assert(this->m_triangle_patches.size() == this->m_triangle_indices_VBO_ids.size()); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + assert(this->m_vertices_VAO_id != 0); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES //assert(this->m_vertices_VBO_id != 0); assert(this->m_triangle_patches.size() == this->m_vertices_VBO_ids.size()); assert(this->m_vertices_VBO_ids[triangle_indices_idx] != 0); @@ -1537,6 +1614,13 @@ void TriangleSelectorPatch::render(int triangle_indices_idx, bool show_wireframe if (shader == nullptr) return; +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + glsafe(::glBindVertexArray(this->m_vertices_VAO_id)); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES // the following binding is needed to set the vertex attributes glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->m_vertices_VBO_ids[triangle_indices_idx])); const GLint position_id = shader->get_attrib_location("v_position"); @@ -1580,6 +1664,16 @@ void TriangleSelectorPatch::release_geometry() glsafe(::glDeleteBuffers(1, &m_vertices_VBO_id)); m_vertices_VBO_id = 0; }*/ +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + if (this->m_vertices_VAO_id > 0) { + glsafe(::glDeleteVertexArrays(1, &this->m_vertices_VAO_id)); + this->m_vertices_VAO_id = 0; + } +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES for (auto& vertice_VBO_id : m_vertices_VBO_ids) { glsafe(::glDeleteBuffers(1, &vertice_VBO_id)); vertice_VBO_id = 0; @@ -1607,6 +1701,13 @@ void TriangleSelectorPatch::finalize_vertices() void TriangleSelectorPatch::finalize_triangle_indices() { +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + assert(this->m_vertices_VAO_id == 0); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES m_vertices_VBO_ids.resize(m_triangle_patches.size()); m_triangle_indices_VBO_ids.resize(m_triangle_patches.size()); m_triangle_indices_sizes.resize(m_triangle_patches.size()); @@ -1634,6 +1735,15 @@ void TriangleSelectorPatch::finalize_triangle_indices() triangle_indices.clear(); } } + +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + glsafe(::glGenVertexArrays(1, &this->m_vertices_VAO_id)); + glsafe(::glBindVertexArray(this->m_vertices_VAO_id)); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES } #ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp index 444f6609ff..5fc1a9e18f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -162,6 +162,7 @@ protected: // IDs of the Vertex Array Objects, into which the geometry has been loaded. // Zero if the VBOs are not sent to GPU yet. + unsigned int m_vertices_VAO_id{ 0 }; //unsigned int m_vertices_VBO_id{ 0 }; std::vector m_vertices_VBO_ids; std::vector m_triangle_indices_VBO_ids; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index dfdd788029..b51bd7d0e4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -149,8 +149,16 @@ void GLGizmoRotate::on_render() m_grabbers.front().matrix = local_transform(selection); - glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); - GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); +#endif // !SLIC3R_OPENGL_ES + +#if SLIC3R_OPENGL_ES + GLShaderProgram* shader = wxGetApp().get_shader("dashed_lines"); +#else + GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); +#endif // SLIC3R_OPENGL_ES if (shader != nullptr) { shader->start_using(); @@ -158,6 +166,16 @@ void GLGizmoRotate::on_render() const Transform3d view_model_matrix = camera.get_view_matrix() * m_grabbers.front().matrix; shader->set_uniform("view_model_matrix", view_model_matrix); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + const std::array& viewport = camera.get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 0.25f); + shader->set_uniform("gap_size", 0.0f); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES const bool radius_changed = std::abs(m_old_radius - m_radius) > EPSILON; m_old_radius = m_radius; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index 143d5b6669..edd8939804 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -293,12 +293,19 @@ void GLGizmoScale3D::on_render() update_grabbers_data(); - glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); +#endif // !SLIC3R_OPENGL_ES const float grabber_mean_size = (float)((m_bounding_box.size().x() + m_bounding_box.size().y() + m_bounding_box.size().z()) / 3.0); //draw connections - GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#if SLIC3R_OPENGL_ES + GLShaderProgram* shader = wxGetApp().get_shader("dashed_lines"); +#else + GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); +#endif // SLIC3R_OPENGL_ES if (shader != nullptr) { shader->start_using(); // BBS: when select multiple objects, uniform scale can be deselected, display the connection(4,5) @@ -306,6 +313,16 @@ void GLGizmoScale3D::on_render() const Camera& camera = wxGetApp().plater()->get_camera(); shader->set_uniform("view_model_matrix", camera.get_view_matrix() * m_grabbers_tran.get_matrix()); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + const std::array& viewport = camera.get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 0.25f); + shader->set_uniform("gap_size", 0.0f); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES if (m_grabbers[4].enabled && m_grabbers[5].enabled) render_grabbers_connection(4, 5, m_grabbers[4].color); render_grabbers_connection(6, 7, m_grabbers[2].color); @@ -373,10 +390,18 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int } m_grabber_connections[id].model.set_color(color); - glLineStipple(1, 0x0FFF); - glEnable(GL_LINE_STIPPLE); + // ORCA: OpenGL Core Profile +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) { + glLineStipple(1, 0x0FFF); + glEnable(GL_LINE_STIPPLE); + } +#endif // !SLIC3R_OPENGL_ES m_grabber_connections[id].model.render(); - glDisable(GL_LINE_STIPPLE); +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glDisable(GL_LINE_STIPPLE); +#endif // !SLIC3R_OPENGL_ES } //BBS: add input window for move diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp index 8a5e1f000f..ae8217d8d3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp @@ -643,7 +643,6 @@ void GLGizmoSimplify::on_render() const Transform3d trafo_matrix = selected_volume->world_matrix(); auto* gouraud_shader = wxGetApp().get_shader("gouraud_light"); - glsafe(::glPushAttrib(GL_DEPTH_TEST)); glsafe(::glEnable(GL_DEPTH_TEST)); gouraud_shader->start_using(); const Camera& camera = wxGetApp().plater()->get_camera(); @@ -657,20 +656,29 @@ void GLGizmoSimplify::on_render() gouraud_shader->stop_using(); if (m_show_wireframe) { - auto* contour_shader = wxGetApp().get_shader("mm_contour"); +#if SLIC3R_OPENGL_ES + auto* contour_shader = wxGetApp().get_shader("wireframe"); +#else + auto *contour_shader = wxGetApp().get_shader("mm_contour"); +#endif // SLIC3R_OPENGL_ES contour_shader->start_using(); contour_shader->set_uniform("offset", OpenGLManager::get_gl_info().is_mesa() ? 0.0005 : 0.00001); contour_shader->set_uniform("view_model_matrix", view_model_matrix); contour_shader->set_uniform("projection_matrix", camera.get_projection_matrix()); const ColorRGBA color = m_glmodel.get_color(); m_glmodel.set_color(ColorRGBA::WHITE()); - glsafe(::glLineWidth(1.0f)); +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth(1.0f)); glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); +#endif // !SLIC3R_OPENGL_ES //ScopeGuard offset_fill_guard([]() { glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); }); //glsafe(::glEnable(GL_POLYGON_OFFSET_FILL)); //glsafe(::glPolygonOffset(5.0, 5.0)); m_glmodel.render(); +#if !SLIC3R_OPENGL_ES glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); +#endif // !SLIC3R_OPENGL_ES m_glmodel.set_color(color); contour_shader->stop_using(); } diff --git a/src/slic3r/GUI/IMSlider.cpp b/src/slic3r/GUI/IMSlider.cpp index 78c2668fa7..3bfc26cd11 100644 --- a/src/slic3r/GUI/IMSlider.cpp +++ b/src/slic3r/GUI/IMSlider.cpp @@ -1468,6 +1468,8 @@ void IMSlider::on_mouse_wheel(wxMouseEvent& evt) { return; } + ImGuiWrapper& imgui = *wxGetApp().imgui(); + float wheel = 0.0f; wheel = evt.GetWheelRotation() > 0 ? 1.0f : -1.0f; if (wheel == 0.0f) @@ -1492,6 +1494,7 @@ void IMSlider::on_mouse_wheel(wxMouseEvent& evt) { const int new_pos = GetHigherValue() + wheel; SetHigherValue(new_pos); set_as_dirty(); + imgui.set_requires_extra_frame(); } } else { @@ -1509,6 +1512,7 @@ void IMSlider::on_mouse_wheel(wxMouseEvent& evt) { m_selection == ssLower ? SetLowerValue(new_pos) : SetHigherValue(new_pos); } set_as_dirty(); + imgui.set_requires_extra_frame(); } } } diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index f4a7adfd22..8bd2904c49 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -100,6 +100,9 @@ static const std::map font_icons = { {ImGui::CollapseBtn , "collapse_btn" }, {ImGui::RevertBtn , "revert_btn" }, + {ImGui::HorizontalHide , "horizontal_hide" }, + {ImGui::HorizontalShow , "horizontal_show" }, + {ImGui::CloseBlockNotifButton , "block_notification_close" }, {ImGui::CloseBlockNotifHoverButton , "block_notification_close_hover" }, @@ -3022,22 +3025,39 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) shader->start_using(); - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill. - GLint last_texture; glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture)); - GLint last_polygon_mode[2]; glsafe(::glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode)); - GLint last_viewport[4]; glsafe(::glGetIntegerv(GL_VIEWPORT, last_viewport)); - GLint last_scissor_box[4]; glsafe(::glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box)); - GLint last_texture_env_mode; glsafe(::glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &last_texture_env_mode)); - glsafe(::glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT)); + // Backup GL state + GLenum last_active_texture; glsafe(::glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture)); + GLuint last_program; glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_program)); + GLuint last_texture; glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&last_texture)); + GLuint last_array_buffer; glsafe(::glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer)); + GLuint last_vertex_array_object = 0; +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) +#endif // !SLIC3R_OPENGL_ES + glsafe(::glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object)); + GLint last_viewport[4]; glsafe(::glGetIntegerv(GL_VIEWPORT, last_viewport)); + GLint last_scissor_box[4]; glsafe(::glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box)); + GLenum last_blend_src_rgb; glsafe(::glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb)); + GLenum last_blend_dst_rgb; glsafe(::glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb)); + GLenum last_blend_src_alpha; glsafe(::glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha)); + GLenum last_blend_dst_alpha; glsafe(::glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha)); + GLenum last_blend_equation_rgb; glsafe(::glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb)); + GLenum last_blend_equation_alpha; glsafe(::glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha)); + GLboolean last_enable_blend = ::glIsEnabled(GL_BLEND); + GLboolean last_enable_cull_face = ::glIsEnabled(GL_CULL_FACE); + GLboolean last_enable_depth_test = ::glIsEnabled(GL_DEPTH_TEST); + GLboolean last_enable_stencil_test = ::glIsEnabled(GL_STENCIL_TEST); + GLboolean last_enable_scissor_test = ::glIsEnabled(GL_SCISSOR_TEST); + + // set new GL state + glsafe(::glActiveTexture(GL_TEXTURE0)); glsafe(::glEnable(GL_BLEND)); - glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + glsafe(::glBlendEquation(GL_FUNC_ADD)); + glsafe(::glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); glsafe(::glDisable(GL_CULL_FACE)); glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glDisable(GL_STENCIL_TEST)); glsafe(::glEnable(GL_SCISSOR_TEST)); - glsafe(::glEnable(GL_TEXTURE_2D)); - glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); - glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)); // Setup viewport, orthographic projection matrix // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. @@ -3069,6 +3089,16 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert); const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx); + GLuint vao_id = 0; +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + glsafe(::glGenVertexArrays(1, &vao_id)); + glsafe(::glBindVertexArray(vao_id)); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES + GLuint vbo_id; glsafe(::glGenBuffers(1, &vbo_id)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, vbo_id)); @@ -3128,14 +3158,31 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) glsafe(::glDeleteBuffers(1, &ibo_id)); glsafe(::glDeleteBuffers(1, &vbo_id)); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + if (vao_id > 0) + glsafe(::glDeleteVertexArrays(1, &vao_id)); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES } - // Restore modified state - glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_texture_env_mode)); - glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture)); - glsafe(::glPopAttrib()); - glsafe(::glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); - glsafe(::glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]))); + // Restore modified GL state + glsafe(::glBindTexture(GL_TEXTURE_2D, last_texture)); + glsafe(::glActiveTexture(last_active_texture)); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) +#endif // !SLIC3R_OPENGL_ES + glsafe(::glBindVertexArray(last_vertex_array_object)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer)); + glsafe(::glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha)); + glsafe(::glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha)); + if (last_enable_blend) glsafe(::glEnable(GL_BLEND)); else glsafe(::glDisable(GL_BLEND)); + if (last_enable_cull_face) glsafe(::glEnable(GL_CULL_FACE)); else glsafe(::glDisable(GL_CULL_FACE)); + if (last_enable_depth_test) glsafe(::glEnable(GL_DEPTH_TEST)); else glsafe(::glDisable(GL_DEPTH_TEST)); + if (last_enable_stencil_test) glsafe(::glEnable(GL_STENCIL_TEST)); else glsafe(::glDisable(GL_STENCIL_TEST)); + if (last_enable_scissor_test) glsafe(::glEnable(GL_SCISSOR_TEST)); else glsafe(::glDisable(GL_SCISSOR_TEST)); glsafe(::glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3])); glsafe(::glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3])); diff --git a/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp b/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp new file mode 100644 index 0000000000..b71d7cb3e9 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp @@ -0,0 +1,814 @@ +///|/ Copyright (c) Prusa Research 2020 - 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher +///|/ +#include +#include +#include +#include +#include +#include + +#include "libslic3r/libslic3r.h" +#include "LibVGCodeWrapper.hpp" +#include "libslic3r/Print.hpp" +#include "libslic3r/Color.hpp" +#include "libslic3r/CustomGCode.hpp" +#include "libslic3r/Exception.hpp" +#include "libslic3r/ExtrusionEntity.hpp" +#include "libslic3r/ExtrusionEntityCollection.hpp" +#include "libslic3r/GCode/WipeTower.hpp" +#include "libslic3r/Layer.hpp" +#include "libslic3r/Line.hpp" +#include "libslic3r/Polyline.hpp" +#include "libslic3r/PrintConfig.hpp" +#include "../../src/libvgcode/include/GCodeInputData.hpp" +#include "../../src/libvgcode/include/PathVertex.hpp" +#include "libvgcode/include/Types.hpp" + +namespace libvgcode { +class Viewer; + +Vec3 convert(const Slic3r::Vec3f& v) +{ + return { v.x(), v.y(), v.z() }; +} + +Slic3r::Vec3f convert(const Vec3& v) +{ + return { v[0], v[1], v[2] }; +} + +Mat4x4 convert(const Slic3r::Matrix4f& m) +{ + Mat4x4 ret; + std::memcpy(ret.data(), m.data(), 16 * sizeof(float)); + return ret; +} + +Slic3r::ColorRGBA convert(const Color& c) +{ + static const float inv_255 = 1.0f / 255.0f; + return { c[0] * inv_255, c[1] * inv_255, c[2] * inv_255, 1.0f }; +} + +Color convert(const Slic3r::ColorRGBA& c) +{ + return { static_cast(c.r() * 255.0f), static_cast(c.g() * 255.0f), static_cast(c.b() * 255.0f) }; +} + +Color convert(const std::string& color_str) +{ + Slic3r::ColorRGBA color_rgba; + return decode_color(color_str, color_rgba) ? convert(color_rgba) : DUMMY_COLOR; +} + +Slic3r::ExtrusionRole convert(EGCodeExtrusionRole role) +{ + switch (role) + { + case EGCodeExtrusionRole::None: { return Slic3r::ExtrusionRole::erNone; } + case EGCodeExtrusionRole::Perimeter: { return Slic3r::ExtrusionRole::erPerimeter; } + case EGCodeExtrusionRole::ExternalPerimeter: { return Slic3r::ExtrusionRole::erExternalPerimeter; } + case EGCodeExtrusionRole::OverhangPerimeter: { return Slic3r::ExtrusionRole::erOverhangPerimeter; } + case EGCodeExtrusionRole::InternalInfill: { return Slic3r::ExtrusionRole::erInternalInfill; } + case EGCodeExtrusionRole::SolidInfill: { return Slic3r::ExtrusionRole::erSolidInfill; } + case EGCodeExtrusionRole::TopSolidInfill: { return Slic3r::ExtrusionRole::erTopSolidInfill; } + case EGCodeExtrusionRole::Ironing: { return Slic3r::ExtrusionRole::erIroning; } + case EGCodeExtrusionRole::BridgeInfill: { return Slic3r::ExtrusionRole::erBridgeInfill; } + case EGCodeExtrusionRole::GapFill: { return Slic3r::ExtrusionRole::erGapFill; } + case EGCodeExtrusionRole::Skirt: { return Slic3r::ExtrusionRole::erSkirt; } + case EGCodeExtrusionRole::SupportMaterial: { return Slic3r::ExtrusionRole::erSupportMaterial; } + case EGCodeExtrusionRole::SupportMaterialInterface: { return Slic3r::ExtrusionRole::erSupportMaterialInterface; } + case EGCodeExtrusionRole::WipeTower: { return Slic3r::ExtrusionRole::erWipeTower; } + case EGCodeExtrusionRole::Custom: { return Slic3r::ExtrusionRole::erCustom; } + // ORCA + case EGCodeExtrusionRole::BottomSurface: { return Slic3r::ExtrusionRole::erBottomSurface; } + case EGCodeExtrusionRole::InternalBridgeInfill: { return Slic3r::ExtrusionRole::erInternalBridgeInfill; } + case EGCodeExtrusionRole::Brim: { return Slic3r::ExtrusionRole::erBrim; } + case EGCodeExtrusionRole::SupportTransition: { return Slic3r::ExtrusionRole::erSupportTransition; } + case EGCodeExtrusionRole::Mixed: { return Slic3r::ExtrusionRole::erMixed; } + default: { return Slic3r::ExtrusionRole::erNone; } + } +} + +EGCodeExtrusionRole convert(Slic3r::ExtrusionRole role) +{ + switch (role) + { + case Slic3r::ExtrusionRole::erNone: { return EGCodeExtrusionRole::None; } + case Slic3r::ExtrusionRole::erPerimeter: { return EGCodeExtrusionRole::Perimeter; } + case Slic3r::ExtrusionRole::erExternalPerimeter: { return EGCodeExtrusionRole::ExternalPerimeter; } + case Slic3r::ExtrusionRole::erOverhangPerimeter: { return EGCodeExtrusionRole::OverhangPerimeter; } + case Slic3r::ExtrusionRole::erInternalInfill: { return EGCodeExtrusionRole::InternalInfill; } + case Slic3r::ExtrusionRole::erSolidInfill: { return EGCodeExtrusionRole::SolidInfill; } + case Slic3r::ExtrusionRole::erTopSolidInfill: { return EGCodeExtrusionRole::TopSolidInfill; } + case Slic3r::ExtrusionRole::erIroning: { return EGCodeExtrusionRole::Ironing; } + case Slic3r::ExtrusionRole::erBridgeInfill: { return EGCodeExtrusionRole::BridgeInfill; } + case Slic3r::ExtrusionRole::erGapFill: { return EGCodeExtrusionRole::GapFill; } + case Slic3r::ExtrusionRole::erSkirt: { return EGCodeExtrusionRole::Skirt; } + case Slic3r::ExtrusionRole::erSupportMaterial: { return EGCodeExtrusionRole::SupportMaterial; } + case Slic3r::ExtrusionRole::erSupportMaterialInterface: { return EGCodeExtrusionRole::SupportMaterialInterface; } + case Slic3r::ExtrusionRole::erWipeTower: { return EGCodeExtrusionRole::WipeTower; } + case Slic3r::ExtrusionRole::erCustom: { return EGCodeExtrusionRole::Custom; } + // ORCA + case Slic3r::ExtrusionRole::erBottomSurface: { return EGCodeExtrusionRole::BottomSurface; } + case Slic3r::ExtrusionRole::erInternalBridgeInfill: { return EGCodeExtrusionRole::InternalBridgeInfill; } + case Slic3r::ExtrusionRole::erBrim: { return EGCodeExtrusionRole::Brim; } + case Slic3r::ExtrusionRole::erSupportTransition: { return EGCodeExtrusionRole::SupportTransition; } + case Slic3r::ExtrusionRole::erMixed: { return EGCodeExtrusionRole::Mixed; } + default: { return EGCodeExtrusionRole::None; } + } +} + +EMoveType convert(Slic3r::EMoveType type) +{ + switch (type) + { + case Slic3r::EMoveType::Noop: { return EMoveType::Noop; } + case Slic3r::EMoveType::Retract: { return EMoveType::Retract; } + case Slic3r::EMoveType::Unretract: { return EMoveType::Unretract; } + case Slic3r::EMoveType::Seam: { return EMoveType::Seam; } + case Slic3r::EMoveType::Tool_change: { return EMoveType::ToolChange; } + case Slic3r::EMoveType::Color_change: { return EMoveType::ColorChange; } + case Slic3r::EMoveType::Pause_Print: { return EMoveType::PausePrint; } + case Slic3r::EMoveType::Custom_GCode: { return EMoveType::CustomGCode; } + case Slic3r::EMoveType::Travel: { return EMoveType::Travel; } + case Slic3r::EMoveType::Wipe: { return EMoveType::Wipe; } + case Slic3r::EMoveType::Extrude: { return EMoveType::Extrude; } + default: { return EMoveType::COUNT; } + } +} + +// EOptionType convert(const Slic3r::GUI::Preview::OptionType& type) +// { +// switch (type) +// { +// case Slic3r::GUI::Preview::OptionType::Travel: { return EOptionType::Travels; } +// case Slic3r::GUI::Preview::OptionType::Wipe: { return EOptionType::Wipes; } +// case Slic3r::GUI::Preview::OptionType::Retractions: { return EOptionType::Retractions; } +// case Slic3r::GUI::Preview::OptionType::Unretractions: { return EOptionType::Unretractions; } +// case Slic3r::GUI::Preview::OptionType::Seams: { return EOptionType::Seams; } +// case Slic3r::GUI::Preview::OptionType::ToolChanges: { return EOptionType::ToolChanges; } +// case Slic3r::GUI::Preview::OptionType::ColorChanges: { return EOptionType::ColorChanges; } +// case Slic3r::GUI::Preview::OptionType::PausePrints: { return EOptionType::PausePrints; } +// case Slic3r::GUI::Preview::OptionType::CustomGCodes: { return EOptionType::CustomGCodes; } +// #if VGCODE_ENABLE_COG_AND_TOOL_MARKERS +// case Slic3r::GUI::Preview::OptionType::CenterOfGravity: { return EOptionType::CenterOfGravity; } +// case Slic3r::GUI::Preview::OptionType::ToolMarker: { return EOptionType::ToolMarker; } +// #else +// // case Slic3r::GUI::Preview::OptionType::CenterOfGravity: { return EOptionType::COUNT; } +// case Slic3r::GUI::Preview::OptionType::ToolMarker: { return EOptionType::COUNT; } +// #endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS +// default: { return EOptionType::COUNT; } +// } +// } + +ETimeMode convert(const Slic3r::PrintEstimatedStatistics::ETimeMode& mode) +{ + switch (mode) + { + case Slic3r::PrintEstimatedStatistics::ETimeMode::Normal: { return ETimeMode::Normal; } + case Slic3r::PrintEstimatedStatistics::ETimeMode::Stealth: { return ETimeMode::Stealth; } + default: { return ETimeMode::COUNT; } + } +} + +Slic3r::PrintEstimatedStatistics::ETimeMode convert(const ETimeMode& mode) +{ + switch (mode) + { + case ETimeMode::Normal: { return Slic3r::PrintEstimatedStatistics::ETimeMode::Normal; } + case ETimeMode::Stealth: { return Slic3r::PrintEstimatedStatistics::ETimeMode::Stealth; } + default: { return Slic3r::PrintEstimatedStatistics::ETimeMode::Count; } + } +} + +GCodeInputData convert(const Slic3r::GCodeProcessorResult& result, const std::vector& str_tool_colors, + const std::vector& str_color_print_colors, const Viewer& viewer) +{ + GCodeInputData ret; + + // collect tool colors + ret.tools_colors.reserve(str_tool_colors.size()); + for (const std::string& color : str_tool_colors) { + ret.tools_colors.emplace_back(convert(color)); + } + + // collect color print colors + const std::vector& str_colors = str_color_print_colors.empty() ? str_tool_colors : str_color_print_colors; + ret.color_print_colors.reserve(str_colors.size()); + for (const std::string& color : str_colors) { + ret.color_print_colors.emplace_back(convert(color)); + } + + const std::vector& moves = result.moves; + ret.vertices.reserve(2 * moves.size()); + for (size_t i = 1; i < moves.size(); ++i) { + const Slic3r::GCodeProcessorResult::MoveVertex& curr = moves[i]; + const Slic3r::GCodeProcessorResult::MoveVertex& prev = moves[i - 1]; + const EMoveType curr_type = convert(curr.type); + const EOptionType option_type = move_type_to_option(curr_type); + if (option_type == EOptionType::COUNT || option_type == EOptionType::Travels || option_type == EOptionType::Wipes) { + if (ret.vertices.empty() || prev.type != curr.type || prev.extrusion_role != curr.extrusion_role + // ORCA: Fix issue with flow rate changes being visualized incorrectly + || prev.mm3_per_mm != curr.mm3_per_mm) { + // to allow libvgcode to properly detect the start/end of a path we need to add a 'phantom' vertex + // equal to the current one with the exception of the position, which should match the previous move position, + // and the times, which are set to zero +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + const libvgcode::PathVertex vertex = { convert(prev.position), curr.height, curr.width, curr.feedrate, prev.actual_feedrate, + curr.mm3_per_mm, curr.fan_speed, curr.temperature, 0.0f, convert(curr.extrusion_role), curr_type, + static_cast(curr.gcode_id), static_cast(curr.layer_id), + static_cast(curr.extruder_id), static_cast(curr.cp_color_id), { 0.0f, 0.0f } }; +#else + const libvgcode::PathVertex vertex = { convert(prev.position), curr.height, curr.width, curr.feedrate, prev.actual_feedrate, + curr.mm3_per_mm, curr.fan_speed, curr.temperature, convert(curr.extrusion_role), curr_type, + static_cast(curr.gcode_id), static_cast(curr.layer_id), + static_cast(curr.extruder_id), static_cast(curr.cp_color_id), { 0.0f, 0.0f } }; +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + ret.vertices.emplace_back(vertex); + } + } + +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + const libvgcode::PathVertex vertex = { convert(curr.position), curr.height, curr.width, curr.feedrate, curr.actual_feedrate, + curr.mm3_per_mm, curr.fan_speed, curr.temperature, + result.filament_densities[curr.extruder_id] * curr.mm3_per_mm * (curr.position - prev.position).norm(), + convert(curr.extrusion_role), curr_type, static_cast(curr.gcode_id), static_cast(curr.layer_id), + static_cast(curr.extruder_id), static_cast(curr.cp_color_id), curr.time }; +#else + const libvgcode::PathVertex vertex = { convert(curr.position), curr.height, curr.width, curr.feedrate, curr.actual_feedrate, + curr.mm3_per_mm, curr.fan_speed, curr.temperature, convert(curr.extrusion_role), curr_type, + static_cast(curr.gcode_id), static_cast(curr.layer_id), + static_cast(curr.extruder_id), static_cast(curr.cp_color_id), curr.time }; +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + ret.vertices.emplace_back(vertex); + } + ret.vertices.shrink_to_fit(); + + ret.spiral_vase_mode = result.spiral_vase_mode; + + return ret; +} + +static void convert_lines_to_vertices(const Slic3r::Lines& lines, const std::vector& widths, const std::vector& heights, + float top_z, size_t layer_id, size_t extruder_id, size_t color_id, EGCodeExtrusionRole extrusion_role, bool closed, std::vector& vertices) +{ + if (lines.empty()) + return; + + // loop once more in case of closed loops + const size_t lines_end = closed ? (lines.size() + 1) : lines.size(); + for (size_t ii = 0; ii < lines_end; ++ii) { + const size_t i = (ii == lines.size()) ? 0 : ii; + const Slic3r::Line& line = lines[i]; + // first segment of the polyline + if (ii == 0) { + // add a dummy vertex at the start, to separate the current line from the others + const Slic3r::Vec2f a = unscale(line.a).cast(); +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + libvgcode::PathVertex vertex = { convert(Slic3r::Vec3f(a.x(), a.y(), top_z)), heights[i], widths[i], 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, extrusion_role, EMoveType::Noop, 0, static_cast(layer_id), + static_cast(extruder_id), static_cast(color_id), { 0.0f, 0.0f } }; +#else + libvgcode::PathVertex vertex = { convert(Slic3r::Vec3f(a.x(), a.y(), top_z)), heights[i], widths[i], 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, extrusion_role, EMoveType::Noop, 0, static_cast(layer_id), + static_cast(extruder_id), static_cast(color_id), { 0.0f, 0.0f } }; +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + vertices.emplace_back(vertex); + // add the starting vertex of the segment + vertex.type = EMoveType::Extrude; + vertices.emplace_back(vertex); + } + // add the ending vertex of the segment + const Slic3r::Vec2f b = unscale(line.b).cast(); +#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS + const libvgcode::PathVertex vertex = { convert(Slic3r::Vec3f(b.x(), b.y(), top_z)), heights[i], widths[i], 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, extrusion_role, EMoveType::Extrude, 0, static_cast(layer_id), + static_cast(extruder_id), static_cast(color_id), { 0.0f, 0.0f } }; +#else + const libvgcode::PathVertex vertex = { convert(Slic3r::Vec3f(b.x(), b.y(), top_z)), heights[i], widths[i], 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, extrusion_role, EMoveType::Extrude, 0, static_cast(layer_id), + static_cast(extruder_id), static_cast(color_id), { 0.0f, 0.0f } }; +#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS + vertices.emplace_back(vertex); + } +} + +static void convert_to_vertices(const Slic3r::ExtrusionPath& extrusion_path, float print_z, size_t layer_id, size_t extruder_id, size_t color_id, + EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, std::vector& vertices) +{ + Slic3r::Polyline polyline = extrusion_path.polyline; + polyline.remove_duplicate_points(); + polyline.translate(shift); + const Slic3r::Lines lines = polyline.lines(); + std::vector widths(lines.size(), extrusion_path.width); + std::vector heights(lines.size(), extrusion_path.height); + convert_lines_to_vertices(lines, widths, heights, print_z, layer_id, extruder_id, color_id, extrusion_role, false, vertices); +} + +static void convert_to_vertices(const Slic3r::ExtrusionMultiPath& extrusion_multi_path, float print_z, size_t layer_id, size_t extruder_id, + size_t color_id, EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, std::vector& vertices) +{ + Slic3r::Lines lines; + std::vector widths; + std::vector heights; + for (const Slic3r::ExtrusionPath& extrusion_path : extrusion_multi_path.paths) { + Slic3r::Polyline polyline = extrusion_path.polyline; + polyline.remove_duplicate_points(); + polyline.translate(shift); + const Slic3r::Lines lines_this = polyline.lines(); + append(lines, lines_this); + widths.insert(widths.end(), lines_this.size(), extrusion_path.width); + heights.insert(heights.end(), lines_this.size(), extrusion_path.height); + } + convert_lines_to_vertices(lines, widths, heights, print_z, layer_id, extruder_id, color_id, extrusion_role, false, vertices); +} + +static void convert_to_vertices(const Slic3r::ExtrusionLoop& extrusion_loop, float print_z, size_t layer_id, size_t extruder_id, size_t color_id, + EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, std::vector& vertices) +{ + Slic3r::Lines lines; + std::vector widths; + std::vector heights; + for (const Slic3r::ExtrusionPath& extrusion_path : extrusion_loop.paths) { + Slic3r::Polyline polyline = extrusion_path.polyline; + polyline.remove_duplicate_points(); + polyline.translate(shift); + const Slic3r::Lines lines_this = polyline.lines(); + append(lines, lines_this); + widths.insert(widths.end(), lines_this.size(), extrusion_path.width); + heights.insert(heights.end(), lines_this.size(), extrusion_path.height); + } + convert_lines_to_vertices(lines, widths, heights, print_z, layer_id, extruder_id, color_id, extrusion_role, true, vertices); +} + +// forward declaration +static void convert_to_vertices(const Slic3r::ExtrusionEntityCollection& extrusion_entity_collection, float print_z, size_t layer_id, + size_t extruder_id, size_t color_id, EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, std::vector& vertices); + +static void convert_to_vertices(const Slic3r::ExtrusionEntity& extrusion_entity, float print_z, size_t layer_id, size_t extruder_id, size_t color_id, + EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, std::vector& vertices) +{ + auto* extrusion_path = dynamic_cast(&extrusion_entity); + if (extrusion_path != nullptr) + convert_to_vertices(*extrusion_path, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, vertices); + else { + auto* extrusion_loop = dynamic_cast(&extrusion_entity); + if (extrusion_loop != nullptr) + convert_to_vertices(*extrusion_loop, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, vertices); + else { + auto* extrusion_multi_path = dynamic_cast(&extrusion_entity); + if (extrusion_multi_path != nullptr) + convert_to_vertices(*extrusion_multi_path, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, vertices); + else { + auto* extrusion_entity_collection = dynamic_cast(&extrusion_entity); + if (extrusion_entity_collection != nullptr) + convert_to_vertices(*extrusion_entity_collection, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, vertices); + else + throw Slic3r::RuntimeError("Found unexpected extrusion_entity type"); + } + } + } +} + +static void convert_to_vertices(const Slic3r::ExtrusionEntityCollection& extrusion_entity_collection, float print_z, size_t layer_id, + size_t extruder_id, size_t color_id, EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, std::vector& vertices) +{ + for (const Slic3r::ExtrusionEntity* extrusion_entity : extrusion_entity_collection.entities) { + if (extrusion_entity != nullptr) + convert_to_vertices(*extrusion_entity, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, vertices); + } +} + +struct VerticesData +{ + std::vector vertices; + std::vector layers_zs; +}; + +static void convert_brim_skirt_to_vertices(const Slic3r::Print& print, std::vector& vertices_data) +{ + vertices_data.emplace_back(VerticesData()); + VerticesData& data = vertices_data.back(); + + // number of skirt layers + size_t total_layer_count = 0; + for (const Slic3r::PrintObject* print_object : print.objects()) { + total_layer_count = std::max(total_layer_count, print_object->total_layer_count()); + } + size_t skirt_height = print.has_infinite_skirt() ? total_layer_count : std::min(print.config().skirt_height.value, total_layer_count); + if (skirt_height == 0 && print.has_brim()) + skirt_height = 1; + + // Get first skirt_height layers. + //FIXME This code is fishy. It may not work for multiple objects with different layering due to variable layer height feature. + // This is not critical as this is just an initial preview. + const Slic3r::PrintObject* highest_object = *std::max_element(print.objects().begin(), print.objects().end(), + [](auto l, auto r) { return l->layers().size() < r->layers().size(); }); + data.layers_zs.reserve(skirt_height * 2); + for (size_t i = 0; i < std::min(skirt_height, highest_object->layers().size()); ++i) { + data.layers_zs.emplace_back(float(highest_object->layers()[i]->print_z)); + } + // Only add skirt for the raft layers. + for (size_t i = 0; i < std::min(skirt_height, std::min(highest_object->slicing_parameters().raft_layers(), highest_object->support_layers().size())); ++i) { + data.layers_zs.emplace_back(float(highest_object->support_layers()[i]->print_z)); + } + Slic3r::sort_remove_duplicates(data.layers_zs); + skirt_height = std::min(skirt_height, data.layers_zs.size()); + data.layers_zs.erase(data.layers_zs.begin() + skirt_height, data.layers_zs.end()); + + for (size_t i = 0; i < skirt_height; ++i) { + // TODO - brim map? + // if (i == 0) + // convert_to_vertices(print.brim(), data.layers_zs[i], i, 0, 0, EGCodeExtrusionRole::Skirt, Slic3r::Point(0, 0), data.vertices); + convert_to_vertices(print.skirt(), data.layers_zs[i], i, 0, 0, EGCodeExtrusionRole::Skirt, Slic3r::Point(0, 0), data.vertices); + } +} + +class WipeTowerHelper +{ +public: + WipeTowerHelper(const Slic3r::Print& print) : m_print(print) { + const Slic3r::PrintConfig& config = m_print.config(); + const Slic3r::WipeTowerData& wipe_tower_data = m_print.wipe_tower_data(); + if (wipe_tower_data.priming && config.single_extruder_multi_material_priming) { + for (size_t i = 0; i < wipe_tower_data.priming.get()->size(); ++i) { + m_priming.emplace_back(wipe_tower_data.priming.get()->at(i)); + } + } + if (wipe_tower_data.final_purge) + m_final.emplace_back(*wipe_tower_data.final_purge.get()); + + m_angle = print.model().wipe_tower.rotation / 180.0f * PI; + // ORCA/BBS: plate index + m_position = print.model().wipe_tower.positions[print.get_plate_index()].cast(); + m_layers_count = wipe_tower_data.tool_changes.size() + (m_priming.empty() ? 0 : 1); + } + + const std::vector& tool_change(size_t idx) { + const auto& tool_changes = m_print.wipe_tower_data().tool_changes; + return m_priming.empty() ? + ((idx == tool_changes.size()) ? m_final : tool_changes[idx]) : + ((idx == 0) ? m_priming : (idx == tool_changes.size() + 1) ? m_final : tool_changes[idx - 1]); + } + + float get_angle() const { return m_angle; } + const Slic3r::Vec2f& get_position() const { return m_position; } + size_t get_layers_count() { return m_layers_count; } + +private: + const Slic3r::Print& m_print; + std::vector m_priming; + std::vector m_final; + Slic3r::Vec2f m_position{ Slic3r::Vec2f::Zero() }; + float m_angle{ 0.0f }; + size_t m_layers_count{ 0 }; +}; + +static void convert_wipe_tower_to_vertices(const Slic3r::Print& print, const std::vector& str_tool_colors, + std::vector& vertices_data) +{ + vertices_data.emplace_back(VerticesData()); + VerticesData& data = vertices_data.back(); + + WipeTowerHelper wipe_tower_helper(print); + const float angle = wipe_tower_helper.get_angle(); + const Slic3r::Vec2f& position = wipe_tower_helper.get_position(); + + for (size_t item = 0; item < wipe_tower_helper.get_layers_count(); ++item) { + const std::vector& layer = wipe_tower_helper.tool_change(item); + for (const Slic3r::WipeTower::ToolChangeResult& extrusions : layer) { + data.layers_zs.emplace_back(extrusions.print_z); + for (size_t i = 1; i < extrusions.extrusions.size(); /*no increment*/) { + const Slic3r::WipeTower::Extrusion& e = extrusions.extrusions[i]; + if (e.width == 0.0f) { + ++i; + continue; + } + size_t j = i + 1; + if (str_tool_colors.empty()) + for (; j < extrusions.extrusions.size() && extrusions.extrusions[j].width > 0.0f; ++j); + else + for (; j < extrusions.extrusions.size() && extrusions.extrusions[j].tool == e.tool && extrusions.extrusions[j].width > 0.0f; ++j); + + const size_t n_lines = j - i; + Slic3r::Lines lines; + std::vector widths; + std::vector heights; + lines.reserve(n_lines); + widths.reserve(n_lines); + heights.assign(n_lines, extrusions.layer_height); + Slic3r::WipeTower::Extrusion e_prev = extrusions.extrusions[i - 1]; + + if (!extrusions.priming) { // wipe tower extrusions describe the wipe tower at the origin with no rotation + e_prev.pos = Eigen::Rotation2Df(angle) * e_prev.pos; + e_prev.pos += position; + } + + for (; i < j; ++i) { + Slic3r::WipeTower::Extrusion ee = extrusions.extrusions[i]; + assert(ee.width > 0.0f); + if (!extrusions.priming) { + ee.pos = Eigen::Rotation2Df(angle) * ee.pos; + ee.pos += position; + } + lines.emplace_back(Slic3r::Point::new_scale(e_prev.pos.x(), e_prev.pos.y()), Slic3r::Point::new_scale(ee.pos.x(), ee.pos.y())); + widths.emplace_back(ee.width); + e_prev = ee; + } + + convert_lines_to_vertices(lines, widths, heights, extrusions.print_z, item, static_cast(e.tool), 0, + EGCodeExtrusionRole::WipeTower, lines.front().a == lines.back().b, data.vertices); + } + } + } + + Slic3r::sort_remove_duplicates(data.layers_zs); +} + +class ObjectHelper +{ +public: + ObjectHelper(const std::vector& color_print_values, size_t tool_colors_count, size_t color_print_colors_count, size_t extruders_count) + : m_color_print_values(color_print_values) + , m_tool_colors_count(tool_colors_count) + , m_color_print_colors_count(color_print_colors_count) + , m_extruders_count(extruders_count) { + } + + uint8_t color_id(float print_z, size_t extruder_id) const { + if (!m_color_print_values.empty()) + return color_print_color_id(double(print_z), extruder_id); + else { + if (m_tool_colors_count > 0) + return std::min(m_tool_colors_count - 1, static_cast(extruder_id)); + else + return 0; + } + } + +private: + const std::vector& m_color_print_values; + size_t m_tool_colors_count{ 0 }; + size_t m_color_print_colors_count{ 0 }; + size_t m_extruders_count{ 0 }; + + uint8_t color_print_color_id(double print_z, size_t extruder_id) const { + auto it = std::find_if(m_color_print_values.begin(), m_color_print_values.end(), + [print_z](const Slic3r::CustomGCode::Item& code) { + return std::fabs(code.print_z - print_z) < EPSILON; + }); + if (it != m_color_print_values.end()) { + Slic3r::CustomGCode::Type type = it->type; + // pause print or custom Gcode + if (type == Slic3r::CustomGCode::PausePrint || (type != Slic3r::CustomGCode::ColorChange && type != Slic3r::CustomGCode::Template)) + return static_cast(m_color_print_colors_count - 1); // last color item is a gray color for pause print or custom G-code + switch (it->type) { + // change color for current extruder + case Slic3r::CustomGCode::ColorChange: { + const int c = color_change_color_id(it, extruder_id); + if (c >= 0) + return static_cast(c); + break; + } + // change tool (extruder) + case Slic3r::CustomGCode::ToolChange: { return tool_change_color_id(it, extruder_id); } + default: { break; } + } + } + + const Slic3r::CustomGCode::Item value{ print_z + EPSILON, Slic3r::CustomGCode::Custom, 0, "" }; + it = std::lower_bound(m_color_print_values.begin(), m_color_print_values.end(), value); + while (it != m_color_print_values.begin()) { + --it; + switch (it->type) { + // change color for current extruder + case Slic3r::CustomGCode::ColorChange: { + const int c = color_change_color_id(it, extruder_id); + if (c >= 0) + return static_cast(c); + break; + } + // change tool (extruder) + case Slic3r::CustomGCode::ToolChange: { return tool_change_color_id(it, extruder_id); } + default: { break; } + } + } + + return std::min(m_extruders_count - 1, static_cast(extruder_id)); + } + + int color_change_color_id(std::vector::const_iterator it, size_t extruder_id) const { + if (m_extruders_count == 1) + return m600_color_id(it); + + auto it_n = it; + bool is_tool_change = false; + while (it_n != m_color_print_values.begin()) { + --it_n; + if (it_n->type == Slic3r::CustomGCode::ToolChange) { + is_tool_change = true; + if (it_n->extruder == it->extruder || (it_n->extruder == 0 && it->extruder == static_cast(extruder_id + 1))) + return m600_color_id(it); + break; + } + } + if (!is_tool_change && it->extruder == static_cast(extruder_id + 1)) + return m600_color_id(it); + + return -1; + } + + uint8_t tool_change_color_id(std::vector::const_iterator it, size_t extruder_id) const { + const int current_extruder = it->extruder == 0 ? static_cast(extruder_id + 1) : it->extruder; + if (m_tool_colors_count == m_extruders_count + 1) // there is no one "M600" + return std::min(m_extruders_count - 1, std::max(current_extruder - 1, 0)); + + auto it_n = it; + while (it_n != m_color_print_values.begin()) { + --it_n; + if (it_n->type == Slic3r::CustomGCode::ColorChange && it_n->extruder == current_extruder) + return m600_color_id(it_n); + } + + return std::min(m_extruders_count - 1, std::max(current_extruder - 1, 0)); + } + + int m600_color_id(std::vector::const_iterator it) const { + int shift = 0; + while (it != m_color_print_values.begin()) { + --it; + if (it->type == Slic3r::CustomGCode::ColorChange) + ++shift; + } + return static_cast(m_extruders_count) + shift; + } +}; + +static void convert_object_to_vertices(const Slic3r::PrintObject& object, const std::vector& str_tool_colors, + const std::vector& str_color_print_colors, const std::vector& color_print_values, + size_t extruders_count, VerticesData& data) +{ + const bool has_perimeters = object.is_step_done(Slic3r::posPerimeters); + const bool has_infill = object.is_step_done(Slic3r::posInfill); + const bool has_support = object.is_step_done(Slic3r::posSupportMaterial); + + // order layers by print_z + std::vector layers; + if (has_perimeters || has_infill) { + layers.reserve(layers.size() + object.layers().size()); + std::copy(object.layers().begin(), object.layers().end(), std::back_inserter(layers)); + } + if (has_support) { + layers.reserve(layers.size() + object.support_layers().size()); + std::copy(object.support_layers().begin(), object.support_layers().end(), std::back_inserter(layers)); + } + std::sort(layers.begin(), layers.end(), [](const Slic3r::Layer* l1, const Slic3r::Layer* l2) { return l1->print_z < l2->print_z; }); + + ObjectHelper object_helper(color_print_values, str_tool_colors.size(), str_color_print_colors.size(), extruders_count); + + data.layers_zs.reserve(layers.size()); + for (const Slic3r::Layer* layer : layers) { + data.layers_zs.emplace_back(static_cast(layer->print_z)); + } + + Slic3r::sort_remove_duplicates(data.layers_zs); + + for (const Slic3r::Layer* layer : layers) { + const size_t old_vertices_count = data.vertices.size(); + const float layer_z = static_cast(layer->print_z); + const auto it = std::find(data.layers_zs.begin(), data.layers_zs.end(), layer_z); + assert(it != data.layers_zs.end()); + const size_t layer_id = (it != data.layers_zs.end()) ? std::distance(data.layers_zs.begin(), it) : 0; + for (const Slic3r::PrintInstance& instance : object.instances()) { + const Slic3r::Point& copy = instance.shift; + for (const Slic3r::LayerRegion* layerm : layer->regions()) { + if (layerm->slices.empty()) + continue; + const Slic3r::PrintRegionConfig& cfg = layerm->region().config(); + if (has_perimeters) { + const size_t extruder_id = static_cast(std::max(cfg.wall_filament.value - 1, 0)); + convert_to_vertices(layerm->perimeters, layer_z, layer_id, extruder_id, + object_helper.color_id(layer_z, extruder_id), EGCodeExtrusionRole::ExternalPerimeter, + copy, data.vertices); + } + if (has_infill) { + for (const Slic3r::ExtrusionEntity* ee : layerm->fills) { + // fill represents infill extrusions of a single island. + const auto& fill = *dynamic_cast(ee); + if (!fill.entities.empty()) { + const bool is_solid_infill = Slic3r::is_solid_infill(fill.entities.front()->role()); + const size_t extruder_id = is_solid_infill ? + static_cast(std::max(cfg.solid_infill_filament.value - 1, 0)) : + static_cast(std::max(cfg.sparse_infill_filament.value - 1, 0)); + convert_to_vertices(fill, layer_z, layer_id, extruder_id, + object_helper.color_id(layer_z, extruder_id), + is_solid_infill ? EGCodeExtrusionRole::SolidInfill : EGCodeExtrusionRole::InternalInfill, + copy, data.vertices); + } + } + } + } + if (has_support) { + const Slic3r::SupportLayer* support_layer = dynamic_cast(layer); + if (support_layer == nullptr) + continue; + const Slic3r::PrintObjectConfig& cfg = support_layer->object()->config(); + for (const Slic3r::ExtrusionEntity* extrusion_entity : support_layer->support_fills.entities) { + const bool is_support_material = extrusion_entity->role() == Slic3r::ExtrusionRole::erSupportMaterial; + const size_t extruder_id = is_support_material ? + static_cast(std::max(cfg.support_filament.value - 1, 0)) : + static_cast(std::max(cfg.support_interface_filament.value - 1, 0)); + convert_to_vertices(*extrusion_entity, layer_z, layer_id, + extruder_id, object_helper.color_id(layer_z, extruder_id), + is_support_material ? EGCodeExtrusionRole::SupportMaterial : EGCodeExtrusionRole::SupportMaterialInterface, + copy, data.vertices); + } + } + } + // filter out empty layers + const size_t new_vertices_count = data.vertices.size(); + if (new_vertices_count == old_vertices_count) + data.layers_zs.erase(data.layers_zs.begin() + layer_id); + } +} + +static void convert_objects_to_vertices(const Slic3r::ConstPrintObjectPtrsAdaptor& objects, const std::vector& str_tool_colors, + const std::vector& str_color_print_colors, const std::vector& color_print_values, size_t extruders_count, + std::vector& data) +{ + // extract vertices and layers zs object by object + data.reserve(data.size() + objects.size()); + for (size_t i = 0; i < objects.size(); ++i) { + data.emplace_back(VerticesData()); + convert_object_to_vertices(*objects[i], str_tool_colors, str_color_print_colors, color_print_values, extruders_count, data.back()); + } +} + +// mapping from Slic3r::Print to libvgcode::GCodeInputData +GCodeInputData convert(const Slic3r::Print& print, const std::vector& str_tool_colors, + const std::vector& str_color_print_colors, const std::vector& color_print_values, + size_t extruders_count) +{ + GCodeInputData ret; + std::vector data; + if (print.is_step_done(Slic3r::psSkirtBrim) && (print.has_skirt() || print.has_brim())) + // extract vertices and layers zs from skirt/brim + convert_brim_skirt_to_vertices(print, data); + if (!print.wipe_tower_data().tool_changes.empty() && print.is_step_done(Slic3r::psWipeTower)) + // extract vertices and layers zs from wipe tower + convert_wipe_tower_to_vertices(print, str_tool_colors, data); + // extract vertices and layers zs from objects + convert_objects_to_vertices(print.objects(), str_tool_colors, str_color_print_colors, color_print_values, extruders_count, data); + + // collect layers zs + std::vector layers; + for (const VerticesData& d : data) { + layers.reserve(layers.size() + d.layers_zs.size()); + std::copy(d.layers_zs.begin(), d.layers_zs.end(), std::back_inserter(layers)); + } + Slic3r::sort_remove_duplicates(layers); + + // Now we need to copy the vertices into ret.vertices to be consumed by the preliminary G-code preview. + // We need to collect vertices in the first layer for all objects, push them into the output vector + // and then do the same for all the layers. The algorithm relies on the fact that the vertices from + // lower layers are always placed after vertices from the higher layer. + std::vector vert_indices(data.size(), 0); + for (size_t layer_id = 0; layer_id < layers.size(); ++layer_id) { + const float layer_z = layers[layer_id]; + for (size_t obj_idx = 0; obj_idx < data.size(); ++obj_idx) { + // d contains PathVertices for one object. Let's stuff everything below this layer_z into ret.vertices. + const size_t start_idx = vert_indices[obj_idx]; + size_t idx = start_idx; + while (idx < data[obj_idx].vertices.size() && data[obj_idx].vertices[idx].position[2] <= layer_z) + ++idx; + // We have found a vertex above current layer_z. Let's copy the vertices into the output + // and remember where to start when we process another layer. + ret.vertices.insert(ret.vertices.end(), + data[obj_idx].vertices.begin() + start_idx, + data[obj_idx].vertices.begin() + idx); + vert_indices[obj_idx] = idx; + } + } + + + // collect tool colors + ret.tools_colors.reserve(str_tool_colors.size()); + for (const std::string& color : str_tool_colors) { + ret.tools_colors.emplace_back(convert(color)); + } + + // collect color print colors + const std::vector& str_colors = str_color_print_colors.empty() ? str_tool_colors : str_color_print_colors; + ret.color_print_colors.reserve(str_colors.size()); + for (const std::string& color : str_colors) { + ret.color_print_colors.emplace_back(convert(color)); + } + + return ret; +} + +} // namespace libvgcode + diff --git a/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.hpp b/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.hpp new file mode 100644 index 0000000000..35b5bd7b44 --- /dev/null +++ b/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.hpp @@ -0,0 +1,83 @@ +///|/ Copyright (c) Prusa Research 2020 - 2023 Enrico Turri @enricoturri1966 +///|/ +///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher +///|/ +#ifndef slic3r_LibVGCodeWrapper_hpp_ +#define slic3r_LibVGCodeWrapper_hpp_ + +#include <../../src/libvgcode/include/Viewer.hpp> +#include <../../src/libvgcode/include/PathVertex.hpp> +#include <../../src/libvgcode/include/GCodeInputData.hpp> +#include <../../src/libvgcode/include/ColorRange.hpp> +#include +#include +#include +#include + +#include "../../src/libvgcode/include/Types.hpp" +#include "libslic3r/Color.hpp" +#include "libslic3r/GCode/GCodeProcessor.hpp" +#include "slic3r/GUI/GUI_Preview.hpp" +#include "libslic3r/ExtrusionEntity.hpp" +#include "libslic3r/Point.hpp" + + +namespace Slic3r { +class Print; + +namespace CustomGCode { +struct Item; +} // namespace CustomGCode +} // namespace Slic3r + +namespace libvgcode { +class Viewer; + +// mapping from Slic3r::Vec3f to libvgcode::Vec3 +extern Vec3 convert(const Slic3r::Vec3f& v); + +// mapping from libvgcode::Vec3 to Slic3r::Vec3f +extern Slic3r::Vec3f convert(const Vec3& v); + +// mapping from Slic3r::Matrix4f to libvgcode::Mat4x4 +extern Mat4x4 convert(const Slic3r::Matrix4f& m); + +// mapping from libvgcode::Color to Slic3r::ColorRGBA +extern Slic3r::ColorRGBA convert(const Color& c); + +// mapping from Slic3r::ColorRGBA to libvgcode::Color +extern Color convert(const Slic3r::ColorRGBA& c); + +// mapping from encoded color to libvgcode::Color +extern Color convert(const std::string& color_str); + +// mapping from libvgcode::EGCodeExtrusionRole to Slic3r::ExtrusionRole +extern Slic3r::ExtrusionRole convert(EGCodeExtrusionRole role); + +// mapping from Slic3r::ExtrusionRole to libvgcode::EGCodeExtrusionRole +extern EGCodeExtrusionRole convert(Slic3r::ExtrusionRole role); + +// mapping from Slic3r::EMoveType to libvgcode::EMoveType +extern EMoveType convert(Slic3r::EMoveType type); + +// mapping from Slic3r::GUI::Preview::OptionType to libvgcode::EOptionType +// extern EOptionType convert(const Slic3r::GUI::Preview::OptionType& type); + +// mapping from Slic3r::PrintEstimatedStatistics::ETimeMode to libvgcode::ETimeMode +extern ETimeMode convert(const Slic3r::PrintEstimatedStatistics::ETimeMode& mode); + +// mapping from libvgcode::ETimeMode to Slic3r::PrintEstimatedStatistics::ETimeMode +extern Slic3r::PrintEstimatedStatistics::ETimeMode convert(const ETimeMode& mode); + +// mapping from Slic3r::GCodeProcessorResult to libvgcode::GCodeInputData +extern GCodeInputData convert(const Slic3r::GCodeProcessorResult& result, const std::vector& str_tool_colors, + const std::vector& str_color_print_colors, const Viewer& viewer); + +// mapping from Slic3r::Print to libvgcode::GCodeInputData +extern GCodeInputData convert(const Slic3r::Print& print, const std::vector& str_tool_colors, + const std::vector& str_color_print_colors, const std::vector& color_print_values, + size_t extruders_count); + +} // namespace libvgcode + +#endif // slic3r_LibVGCodeWrapper_hpp_ diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index b6d1a7b7d8..ba98bfc470 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -2984,7 +2984,7 @@ void MainFrame::init_menubar_as_editor() #else if (dlg.seq_top_layer_only_changed()) #endif - plater()->refresh_print(); + plater()->reload_print(); }, "", nullptr, []() { return true; }, this, 1); //parent_menu->Insert(1, preference_item); diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index 8fe680e41f..3bbc8927b6 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -16,6 +16,8 @@ #include #include +#include "GUI_Init.hpp" + #ifdef __APPLE__ // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets #include @@ -114,6 +116,10 @@ void OpenGLManager::GLInfo::detect() const float* max_anisotropy = const_cast(&m_max_anisotropy); glsafe(::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy)); } + + if (!GLEW_ARB_compatibility) + *const_cast(&m_core_profile) = true; + *const_cast(&m_detected) = true; } @@ -182,6 +188,9 @@ std::string OpenGLManager::GLInfo::to_string(bool for_github) const out << h2_start << "OpenGL installation" << h2_end << line_end; out << b_start << "GL version: " << b_end << m_version << line_end; +#if !SLIC3R_OPENGL_ES + out << b_start << "Profile: " << b_end << (is_core_profile() ? "Core" : "Compatibility") << line_end; +#endif // !SLIC3R_OPENGL_ES out << b_start << "Vendor: " << b_end << m_vendor << line_end; out << b_start << "Renderer: " << b_end << m_renderer << line_end; out << b_start << "GLSL version: " << b_end << m_glsl_version << line_end; @@ -241,6 +250,7 @@ OpenGLManager::~OpenGLManager() bool OpenGLManager::init_gl(bool popup_error) { if (!m_gl_initialized) { + glewExperimental = true; GLenum result = glewInit(); if (result != GLEW_OK) { BOOST_LOG_TRIVIAL(error) << "Unable to init glew library"; @@ -268,11 +278,11 @@ bool OpenGLManager::init_gl(bool popup_error) bool valid_version = s_gl_info.is_version_greater_or_equal_to(2, 0); if (!valid_version) { - BOOST_LOG_TRIVIAL(error) << "Found opengl version <= 2.0"<< std::endl; + BOOST_LOG_TRIVIAL(error) << "Found opengl version <= 3.2"<< std::endl; // Complain about the OpenGL version. if (popup_error) { wxString message = from_u8((boost::format( - _utf8(L("The application cannot run normally because OpenGL version is lower than 2.0.\n")))).str()); + _utf8(L("The application cannot run normally because OpenGL version is lower than 3.2.\n")))).str()); message += "\n"; message += _L("Please upgrade your graphics card driver."); wxMessageBox(message, _L("Unsupported OpenGL version"), wxOK | wxICON_ERROR); @@ -316,10 +326,79 @@ bool OpenGLManager::init_gl(bool popup_error) return true; } -wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas) +wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas, const std::pair& required_opengl_version, bool enable_compatibility_profile, + bool enable_debug) { if (m_context == nullptr) { - m_context = new wxGLContext(&canvas); + // m_debug_enabled = enable_debug; + + const int gl_major = required_opengl_version.first; + const int gl_minor = required_opengl_version.second; + const bool supports_core_profile = + std::find(OpenGLVersions::core.begin(), OpenGLVersions::core.end(), std::make_pair(gl_major, gl_minor)) != OpenGLVersions::core.end(); + + if (gl_major == 0 && !enable_compatibility_profile) { + // search for highest supported core profile version + // disable wxWidgets logging to avoid showing the log dialog in case the following code fails generating a valid gl context + wxLogNull logNo; + for (auto v = OpenGLVersions::core.rbegin(); v != OpenGLVersions::core.rend(); ++v) { + wxGLContextAttrs attrs; + attrs.PlatformDefaults().MajorVersion(v->first).MinorVersion(v->second).CoreProfile().ForwardCompatible(); + // if (m_debug_enabled) + // attrs.DebugCtx(); + attrs.EndList(); + m_context = new wxGLContext(&canvas, nullptr, &attrs); + if (m_context->IsOK()) + break; + else { + delete m_context; + m_context = nullptr; + } + } + } + + if (m_context == nullptr) { + // search for requested compatibility profile version + if (enable_compatibility_profile) { + // disable wxWidgets logging to avoid showing the log dialog in case the following code fails generating a valid gl context + wxLogNull logNo; + wxGLContextAttrs attrs; + attrs.PlatformDefaults().CompatibilityProfile(); + // if (m_debug_enabled) + // attrs.DebugCtx(); + attrs.EndList(); + m_context = new wxGLContext(&canvas, nullptr, &attrs); + if (!m_context->IsOK()) { + delete m_context; + m_context = nullptr; + } + } + // search for requested core profile version + else if (supports_core_profile) { + // disable wxWidgets logging to avoid showing the log dialog in case the following code fails generating a valid gl context + wxLogNull logNo; + wxGLContextAttrs attrs; + attrs.PlatformDefaults().MajorVersion(gl_major).MinorVersion(gl_minor).CoreProfile().ForwardCompatible(); + // if (m_debug_enabled) + // attrs.DebugCtx(); + attrs.EndList(); + m_context = new wxGLContext(&canvas, nullptr, &attrs); + if (!m_context->IsOK()) { + delete m_context; + m_context = nullptr; + } + } + } + + if (m_context == nullptr) { + wxGLContextAttrs attrs; + attrs.PlatformDefaults(); + // if (m_debug_enabled) + // attrs.DebugCtx(); + attrs.EndList(); + // if no valid context was created use the default one + m_context = new wxGLContext(&canvas, nullptr, &attrs); + } #ifdef __APPLE__ // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp index 52d50a9578..030bd18ebd 100644 --- a/src/slic3r/GUI/OpenGLManager.hpp +++ b/src/slic3r/GUI/OpenGLManager.hpp @@ -24,8 +24,12 @@ public: class GLInfo { bool m_detected{ false }; + bool m_core_profile{ false }; int m_max_tex_size{ 0 }; float m_max_anisotropy{ 0.0f }; +#if ENABLE_OPENGL_AUTO_AA_SAMPLES + int m_samples{ 0 }; +#endif // ENABLE_OPENGL_AUTO_AA_SAMPLES std::string m_version; std::string m_glsl_version; @@ -40,6 +44,8 @@ public: const std::string& get_vendor() const; const std::string& get_renderer() const; + bool is_core_profile() const { return m_core_profile; } + bool is_mesa() const; int get_max_tex_size() const; @@ -93,7 +99,7 @@ public: ~OpenGLManager(); bool init_gl(bool popup_error = true); - wxGLContext* init_glcontext(wxGLCanvas& canvas); + wxGLContext* init_glcontext(wxGLCanvas& canvas, const std::pair& required_opengl_version, bool enable_compatibility_profile, bool enable_debug); GLShaderProgram* get_shader(const std::string& shader_name) { return m_shaders_manager.get_shader(shader_name); } GLShaderProgram* get_current_shader() { return m_shaders_manager.get_current_shader(); } diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 6ee0733abd..acb8240523 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -960,7 +960,30 @@ void PartPlate::render_exclude_area(bool force_default_color) { void PartPlate::render_grid(bool bottom) { //glsafe(::glEnable(GL_MULTISAMPLE)); // draw grid - glsafe(::glLineWidth(1.0f * m_scale_factor)); + + // ORCA: OpenGL Core Profile support + // FIXME: ideally, we'd use the same shader for both the thin and thick lines, but for some reason setting the uniforms has no effect + GLShaderProgram* shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) { + return; + } + + shader->start_using(); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + + const Camera& camera = wxGetApp().plater()->get_camera(); + const std::array& viewport = camera.get_viewport(); + const Transform3d& view_matrix = camera.get_view_matrix(); + const Transform3d& projection_matrix = camera.get_projection_matrix(); + + shader->set_uniform("view_model_matrix", view_matrix); + shader->set_uniform("projection_matrix", projection_matrix); + +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth(1.0f * m_scale_factor)); +#endif // !SLIC3R_OPENGL_ES ColorRGBA color; if (bottom) @@ -974,9 +997,37 @@ void PartPlate::render_grid(bool bottom) { m_gridlines.set_color(color); m_gridlines.render(); - glsafe(::glLineWidth(2.0f * m_scale_factor)); + shader->stop_using(); + + // ORCA: OpenGL Core Profile support +#if SLIC3R_OPENGL_ES + shader = wxGetApp().get_shader("dashed_lines"); +#else + shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); +#endif // SLIC3R_OPENGL_ES + if (shader == nullptr) { + return; + } + shader->start_using(); + + shader->set_uniform("view_model_matrix", view_matrix); + shader->set_uniform("projection_matrix", projection_matrix); + +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 0.25f); +#if !SLIC3R_OPENGL_ES + } else { + glsafe(::glLineWidth(2.0f * m_scale_factor)); + } +#endif // !SLIC3R_OPENGL_ES + m_gridlines_bolder.set_color(color); m_gridlines_bolder.render(); + + shader->stop_using(); } void PartPlate::render_height_limit(PartPlate::HeightLimitMode mode) @@ -984,20 +1035,32 @@ void PartPlate::render_height_limit(PartPlate::HeightLimitMode mode) if (m_print && m_print->config().print_sequence == PrintSequence::ByObject && mode != HEIGHT_LIMIT_NONE) { // draw lower limit - glsafe(::glLineWidth(3.0f * m_scale_factor)); + // ORCA: OpenGL Core Profile +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth(3.0f * m_scale_factor)); +#endif // !SLIC3R_OPENGL_ES m_height_limit_common.set_color(HEIGHT_LIMIT_BOTTOM_COLOR); m_height_limit_common.render(); if ((mode == HEIGHT_LIMIT_BOTTOM) || (mode == HEIGHT_LIMIT_BOTH)) { - glsafe(::glLineWidth(3.0f * m_scale_factor)); - m_height_limit_bottom.set_color(HEIGHT_LIMIT_BOTTOM_COLOR); + // ORCA: OpenGL Core Profile +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth(3.0f * m_scale_factor)); +#endif // !SLIC3R_OPENGL_ES + m_height_limit_bottom.set_color(HEIGHT_LIMIT_BOTTOM_COLOR); m_height_limit_bottom.render(); } // draw upper limit if ((mode == HEIGHT_LIMIT_TOP) || (mode == HEIGHT_LIMIT_BOTH)){ - glsafe(::glLineWidth(3.0f * m_scale_factor)); - m_height_limit_top.set_color(HEIGHT_LIMIT_TOP_COLOR); + // ORCA: OpenGL Core Profile +#if !SLIC3R_OPENGL_ES + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth(3.0f * m_scale_factor)); +#endif // !SLIC3R_OPENGL_ES + m_height_limit_top.set_color(HEIGHT_LIMIT_TOP_COLOR); m_height_limit_top.render(); } } @@ -3164,9 +3227,6 @@ void PartPlate::render(const Transform3d& view_matrix, const Transform3d& projec } } - if (show_grid) - render_grid(bottom); - render_height_limit(mode); glsafe(::glDisable(GL_BLEND)); @@ -3178,6 +3238,9 @@ void PartPlate::render(const Transform3d& view_matrix, const Transform3d& projec shader->stop_using(); } + if (show_grid) + render_grid(bottom); + if (!bottom && m_selected && !force_background_color) { if (m_partplate_list) render_logo(bottom, m_partplate_list->render_cali_logo && render_cali); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 059955a7cc..5b40d2feeb 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4543,8 +4543,6 @@ struct Plater::priv bool for_picking = false, bool ban_light = false); ThumbnailsList generate_thumbnails(const ThumbnailsParams& params, Camera::EType camera_type); - //BBS - void generate_calibration_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params); PlateBBoxData generate_first_layer_bbox(); void bring_instance_forward() const; @@ -8690,7 +8688,7 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice) else { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": single slice, reload print"); if (model_fits) - this->preview->reload_print(true); + this->preview->reload_print(); // TODO else this->update_fff_scene_only_shells(); } @@ -10147,11 +10145,6 @@ ThumbnailsList Plater::priv::generate_thumbnails(const ThumbnailsParams& params, return thumbnails; } -void Plater::priv::generate_calibration_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params) -{ - preview->get_canvas3d()->render_calibration_thumbnail(data, w, h, thumbnail_params); -} - PlateBBoxData Plater::priv::generate_first_layer_bbox() { PlateBBoxData bboxdata; @@ -13039,7 +13032,7 @@ void Plater::load_gcode(const wxString& filename) //current_result->reset(); //p->gcode_result.reset(); //reset_gcode_toolpaths(); - p->preview->reload_print(false, m_only_gcode); + p->preview->reload_print(m_only_gcode); wxGetApp().mainframe->select_tab(MainFrame::tpPreview); p->set_current_panel(p->preview, true); p->get_current_canvas3D()->render(); @@ -13089,7 +13082,7 @@ void Plater::load_gcode(const wxString& filename) current_print.set_gcode_file_ready(); // show results - p->preview->reload_print(false, m_only_gcode); + p->preview->reload_print(m_only_gcode); //BBS: zoom to bed 0 for gcode preview //p->preview->get_canvas3d()->zoom_to_gcode(); p->preview->get_canvas3d()->zoom_to_plate(0); @@ -13117,9 +13110,9 @@ void Plater::reload_gcode_from_disk() load_gcode(filename); } -void Plater::refresh_print() +void Plater::reload_print() { - p->preview->refresh_print(); + p->preview->reload_print(); } // BBS @@ -15360,7 +15353,7 @@ void Plater::reslice() if (clean_gcode_toolpaths) reset_gcode_toolpaths(); - p->preview->reload_print(!clean_gcode_toolpaths); + p->preview->reload_print(); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": finished, started slicing for plate %1%") % p->partplate_list.get_curr_plate_index(); @@ -15999,6 +15992,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config) p->sidebar->update_searcher(); p->reset_gcode_toolpaths(); p->view3D->get_canvas3d()->reset_sequential_print_clearance(); + p->preview->get_canvas3d()->reset_volumes(); //BBS: invalid all the slice results p->partplate_list.invalid_all_slice_result(); } @@ -16852,7 +16846,7 @@ int Plater::select_plate(int plate_index, bool need_slice) else { validate_current_plate(model_fits, validate_err); //just refresh_print - refresh_print(); + reload_print(); p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false, true); } } @@ -16878,7 +16872,7 @@ int Plater::select_plate(int plate_index, bool need_slice) //p->ready_to_slice = false; p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false); - refresh_print(); + reload_print(); } } } @@ -16918,7 +16912,7 @@ int Plater::select_plate(int plate_index, bool need_slice) else { //p->ready_to_slice = false; p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false); - refresh_print(); + reload_print(); } } else @@ -17280,7 +17274,7 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModi //p->ready_to_slice = false; p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false); - refresh_print(); + reload_print(); } } else diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 5f70657e5f..b53b3c2a90 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -326,7 +326,7 @@ public: void load_gcode(); void load_gcode(const wxString& filename); void reload_gcode_from_disk(); - void refresh_print(); + void reload_print(); // SoftFever void calib_pa(const Calib_Params& params); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 34063c1ca9..e9a43dbc97 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -2618,9 +2618,14 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, const Transform3d& glsafe(::glEnable(GL_DEPTH_TEST)); - glsafe(::glLineWidth(2.0f * m_scale_factor)); +#if SLIC3R_OPENGL_ES + GLShaderProgram* shader = wxGetApp().get_shader("dashed_lines"); +#else + if (!OpenGLManager::get_gl_info().is_core_profile()) + glsafe(::glLineWidth(2.0f * m_scale_factor)); - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); +#endif // SLIC3R_OPENGL_ES if (shader == nullptr) return; @@ -2628,6 +2633,16 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, const Transform3d& const Camera& camera = wxGetApp().plater()->get_camera(); shader->set_uniform("view_model_matrix", camera.get_view_matrix() * trafo); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#if !SLIC3R_OPENGL_ES + if (OpenGLManager::get_gl_info().is_core_profile()) { +#endif // !SLIC3R_OPENGL_ES + const std::array& viewport = camera.get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 1.5f); + shader->set_uniform("gap_size", 0.0f); +#if !SLIC3R_OPENGL_ES + } +#endif // !SLIC3R_OPENGL_ES m_box.set_color(to_rgba(color)); m_box.render(); shader->stop_using();