diff --git a/resources/icons/toolbar_arrow_2.svg b/resources/icons/toolbar_arrow_2.svg new file mode 100644 index 000000000..5ff1cfa2b --- /dev/null +++ b/resources/icons/toolbar_arrow_2.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/shaders/background_attr.vs b/resources/shaders/background_attr.vs new file mode 100644 index 000000000..9b56ab43a --- /dev/null +++ b/resources/shaders/background_attr.vs @@ -0,0 +1,12 @@ +#version 110 + +attribute vec3 v_position; +attribute vec2 v_tex_coord; + +varying vec2 tex_coord; + +void main() +{ + tex_coord = v_tex_coord; + gl_Position = vec4(v_position, 1.0); +} diff --git a/resources/shaders/flat_attr.vs b/resources/shaders/flat_attr.vs new file mode 100644 index 000000000..370eedb72 --- /dev/null +++ b/resources/shaders/flat_attr.vs @@ -0,0 +1,11 @@ +#version 110 + +attribute vec3 v_position; + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; + +void main() +{ + gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); +} diff --git a/resources/shaders/flat_texture_attr.vs b/resources/shaders/flat_texture_attr.vs new file mode 100644 index 000000000..e59a99da3 --- /dev/null +++ b/resources/shaders/flat_texture_attr.vs @@ -0,0 +1,15 @@ +#version 110 + +attribute vec3 v_position; +attribute vec2 v_tex_coord; + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; + +varying vec2 tex_coord; + +void main() +{ + tex_coord = v_tex_coord; + gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); +} diff --git a/resources/shaders/gouraud.fs b/resources/shaders/gouraud.fs index b9e860d10..511faf4c0 100644 --- a/resources/shaders/gouraud.fs +++ b/resources/shaders/gouraud.fs @@ -40,7 +40,6 @@ varying vec2 intensity; uniform PrintVolumeDetection print_volume; -varying vec4 model_pos; varying vec4 world_pos; varying float world_normal_z; varying vec3 eye_normal; diff --git a/resources/shaders/gouraud.vs b/resources/shaders/gouraud.vs index 79d7a63c0..c8b3d7b33 100644 --- a/resources/shaders/gouraud.vs +++ b/resources/shaders/gouraud.vs @@ -38,7 +38,6 @@ varying vec2 intensity; varying vec3 clipping_planes_dots; -varying vec4 model_pos; varying vec4 world_pos; varying float world_normal_z; varying vec3 eye_normal; @@ -60,7 +59,6 @@ void main() NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; - model_pos = gl_Vertex; // Point in homogenous coordinates. world_pos = volume_world_matrix * gl_Vertex; diff --git a/resources/shaders/gouraud_attr.vs b/resources/shaders/gouraud_attr.vs new file mode 100644 index 000000000..87e524c14 --- /dev/null +++ b/resources/shaders/gouraud_attr.vs @@ -0,0 +1,77 @@ +#version 110 + +#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 LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION) +//#define LIGHT_FRONT_SHININESS 5.0 + +#define INTENSITY_AMBIENT 0.3 + +const vec3 ZERO = vec3(0.0, 0.0, 0.0); + +struct SlopeDetection +{ + bool actived; + float normal_z; + mat3 volume_world_normal_matrix; +}; + +attribute vec3 v_position; +attribute vec3 v_normal; + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat3 normal_matrix; +uniform mat4 volume_world_matrix; +uniform SlopeDetection slope; + +// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane. +uniform vec2 z_range; +// Clipping plane - general orientation. Used by the SLA gizmo. +uniform vec4 clipping_plane; + +// x = diffuse, y = specular; +varying vec2 intensity; + +varying vec3 clipping_planes_dots; + +varying vec4 world_pos; +varying float world_normal_z; +varying vec3 eye_normal; + +void main() +{ + // First transform the normal into camera space and normalize the result. + eye_normal = normalize(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(eye_normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + 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, eye_normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + // Point in homogenous coordinates. + world_pos = volume_world_matrix * vec4(v_position, 1.0); + + // z component of normal vector in world coordinate used for slope shading + world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * v_normal)).z : 0.0; + + gl_Position = projection_matrix * position; + // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded. + clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); +} diff --git a/resources/shaders/gouraud_light_attr.vs b/resources/shaders/gouraud_light_attr.vs new file mode 100644 index 000000000..2e1b5fb42 --- /dev/null +++ b/resources/shaders/gouraud_light_attr.vs @@ -0,0 +1,45 @@ +#version 110 + +#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 + +attribute vec3 v_position; +attribute vec3 v_normal; + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat3 normal_matrix; + +// x = tainted, y = specular; +varying vec2 intensity; + +void main() +{ + // First transform the normal into camera space and normalize the result. + vec3 normal = normalize(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; + 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/gouraud_light_instanced_attr.vs b/resources/shaders/gouraud_light_instanced_attr.vs new file mode 100644 index 000000000..7069feb65 --- /dev/null +++ b/resources/shaders/gouraud_light_instanced_attr.vs @@ -0,0 +1,50 @@ +#version 110 + +#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 + +// vertex attributes +attribute vec3 v_position; +attribute vec3 v_normal; +// instance attributes +attribute vec3 i_offset; +attribute vec2 i_scales; + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat3 normal_matrix; + +// x = tainted, y = specular; +varying vec2 intensity; + +void main() +{ + // First transform the normal into camera space and normalize the result. + vec3 eye_normal = normalize(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(eye_normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + vec4 world_position = vec4(v_position * vec3(vec2(1.5 * i_scales.x), 1.5 * i_scales.y) + i_offset - vec3(0.0, 0.0, 0.5 * i_scales.y), 1.0); + vec4 eye_position = view_model_matrix * world_position; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position.xyz), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + gl_Position = projection_matrix * eye_position; +} diff --git a/resources/shaders/mm_contour_attr.fs b/resources/shaders/mm_contour_attr.fs new file mode 100644 index 000000000..14477a59e --- /dev/null +++ b/resources/shaders/mm_contour_attr.fs @@ -0,0 +1,13 @@ +#version 110 + +const float EPSILON = 0.0001; + +uniform vec4 uniform_color; + +void main() +{ + gl_FragColor = uniform_color; + // Values inside depth buffer for fragments of the contour of a selected area are offset + // by small epsilon to solve z-fighting between painted triangles and contour lines. + gl_FragDepth = gl_FragCoord.z - EPSILON; +} diff --git a/resources/shaders/mm_contour_attr.vs b/resources/shaders/mm_contour_attr.vs new file mode 100644 index 000000000..370eedb72 --- /dev/null +++ b/resources/shaders/mm_contour_attr.vs @@ -0,0 +1,11 @@ +#version 110 + +attribute vec3 v_position; + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; + +void main() +{ + gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); +} diff --git a/resources/shaders/mm_gouraud_attr.fs b/resources/shaders/mm_gouraud_attr.fs new file mode 100644 index 000000000..78181e1d7 --- /dev/null +++ b/resources/shaders/mm_gouraud_attr.fs @@ -0,0 +1,63 @@ +#version 110 + +#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 + +const vec3 ZERO = vec3(0.0, 0.0, 0.0); +const float EPSILON = 0.0001; + +uniform vec4 uniform_color; + +uniform bool volume_mirrored; + +uniform mat4 view_model_matrix; +uniform mat3 normal_matrix; + +varying vec3 clipping_planes_dots; +varying vec4 model_pos; + +void main() +{ + if (any(lessThan(clipping_planes_dots, ZERO))) + discard; + vec3 color = uniform_color.rgb; + float alpha = uniform_color.a; + + vec3 triangle_normal = normalize(cross(dFdx(model_pos.xyz), dFdy(model_pos.xyz))); +#ifdef FLIP_TRIANGLE_NORMALS + triangle_normal = -triangle_normal; +#endif + + if (volume_mirrored) + triangle_normal = -triangle_normal; + + // First transform the normal into camera space and normalize the result. + vec3 eye_normal = normalize(normal_matrix * triangle_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(eye_normal, LIGHT_TOP_DIR), 0.0); + + // x = diffuse, y = specular; + vec2 intensity = vec2(0.0); + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + vec3 position = (view_model_matrix * model_pos).xyz; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha); +} diff --git a/resources/shaders/mm_gouraud_attr.vs b/resources/shaders/mm_gouraud_attr.vs new file mode 100644 index 000000000..76101b767 --- /dev/null +++ b/resources/shaders/mm_gouraud_attr.vs @@ -0,0 +1,28 @@ +#version 110 + +const vec3 ZERO = vec3(0.0, 0.0, 0.0); + +attribute vec3 v_position; + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; + +uniform mat4 volume_world_matrix; +// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane. +uniform vec2 z_range; +// Clipping plane - general orientation. Used by the SLA gizmo. +uniform vec4 clipping_plane; + +varying vec3 clipping_planes_dots; +varying vec4 model_pos; + +void main() +{ + model_pos = vec4(v_position, 1.0); + // Point in homogenous coordinates. + vec4 world_pos = volume_world_matrix * model_pos; + + gl_Position = projection_matrix * view_model_matrix * model_pos; + // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded. + clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); +} diff --git a/resources/shaders/options_110.fs b/resources/shaders/options_110.fs deleted file mode 100644 index ab656998d..000000000 --- a/resources/shaders/options_110.fs +++ /dev/null @@ -1,8 +0,0 @@ -#version 110 - -uniform vec4 uniform_color; - -void main() -{ - gl_FragColor = uniform_color; -} diff --git a/resources/shaders/options_110.vs b/resources/shaders/options_110.vs deleted file mode 100644 index 5f2ab2350..000000000 --- a/resources/shaders/options_110.vs +++ /dev/null @@ -1,22 +0,0 @@ -#version 110 - -uniform bool use_fixed_screen_size; -uniform float zoom; -uniform float point_size; -uniform float near_plane_height; - -float fixed_screen_size() -{ - return point_size; -} - -float fixed_world_size() -{ - return (gl_Position.w == 1.0) ? zoom * near_plane_height * point_size : near_plane_height * point_size / gl_Position.w; -} - -void main() -{ - gl_Position = ftransform(); - gl_PointSize = use_fixed_screen_size ? fixed_screen_size() : fixed_world_size(); -} diff --git a/resources/shaders/options_120.fs b/resources/shaders/options_120.fs deleted file mode 100644 index e9b61304f..000000000 --- a/resources/shaders/options_120.fs +++ /dev/null @@ -1,22 +0,0 @@ -// version 120 is needed for gl_PointCoord -#version 120 - -uniform vec4 uniform_color; -uniform float percent_outline_radius; -uniform float percent_center_radius; - -vec4 calc_color(float radius, vec4 color) -{ - return ((radius < percent_center_radius) || (radius > 1.0 - percent_outline_radius)) ? - vec4(0.5 * color.rgb, color.a) : color; -} - -void main() -{ - vec2 pos = (gl_PointCoord - 0.5) * 2.0; - float radius = length(pos); - if (radius > 1.0) - discard; - - gl_FragColor = calc_color(radius, uniform_color); -} diff --git a/resources/shaders/options_120.vs b/resources/shaders/options_120.vs deleted file mode 100644 index edb503fb2..000000000 --- a/resources/shaders/options_120.vs +++ /dev/null @@ -1,22 +0,0 @@ -#version 120 - -uniform bool use_fixed_screen_size; -uniform float zoom; -uniform float point_size; -uniform float near_plane_height; - -float fixed_screen_size() -{ - return point_size; -} - -float fixed_world_size() -{ - return (gl_Position.w == 1.0) ? zoom * near_plane_height * point_size : near_plane_height * point_size / gl_Position.w; -} - -void main() -{ - gl_Position = ftransform(); - gl_PointSize = use_fixed_screen_size ? fixed_screen_size() : fixed_world_size(); -} diff --git a/resources/shaders/printbed.fs b/resources/shaders/printbed.fs index bef075158..833dff08f 100644 --- a/resources/shaders/printbed.fs +++ b/resources/shaders/printbed.fs @@ -7,15 +7,15 @@ uniform sampler2D texture; uniform bool transparent_background; uniform bool svg_source; -varying vec2 tex_coords; +varying vec2 tex_coord; vec4 svg_color() { // takes foreground from texture - vec4 fore_color = texture2D(texture, tex_coords); + vec4 fore_color = texture2D(texture, tex_coord); // calculates radial gradient - vec3 back_color = vec3(mix(back_color_light, back_color_dark, smoothstep(0.0, 0.5, length(abs(tex_coords.xy) - vec2(0.5))))); + vec3 back_color = vec3(mix(back_color_light, back_color_dark, smoothstep(0.0, 0.5, length(abs(tex_coord.xy) - vec2(0.5))))); // blends foreground with background return vec4(mix(back_color, fore_color.rgb, fore_color.a), transparent_background ? fore_color.a : 1.0); @@ -24,7 +24,7 @@ vec4 svg_color() vec4 non_svg_color() { // takes foreground from texture - vec4 color = texture2D(texture, tex_coords); + vec4 color = texture2D(texture, tex_coord); return vec4(color.rgb, transparent_background ? color.a * 0.25 : color.a); } diff --git a/resources/shaders/printbed.vs b/resources/shaders/printbed.vs index 3b3f8875d..27addc752 100644 --- a/resources/shaders/printbed.vs +++ b/resources/shaders/printbed.vs @@ -1,9 +1,9 @@ #version 110 -varying vec2 tex_coords; +varying vec2 tex_coord; void main() { gl_Position = ftransform(); - tex_coords = gl_MultiTexCoord0.xy; + tex_coord = gl_MultiTexCoord0.xy; } diff --git a/resources/shaders/printbed_attr.vs b/resources/shaders/printbed_attr.vs new file mode 100644 index 000000000..e59a99da3 --- /dev/null +++ b/resources/shaders/printbed_attr.vs @@ -0,0 +1,15 @@ +#version 110 + +attribute vec3 v_position; +attribute vec2 v_tex_coord; + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; + +varying vec2 tex_coord; + +void main() +{ + tex_coord = v_tex_coord; + gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); +} diff --git a/resources/shaders/toolpaths_cog_attr.vs b/resources/shaders/toolpaths_cog_attr.vs new file mode 100644 index 000000000..5951238b7 --- /dev/null +++ b/resources/shaders/toolpaths_cog_attr.vs @@ -0,0 +1,47 @@ +#version 110 + +#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 + +attribute vec3 v_position; +attribute vec3 v_normal; + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat3 normal_matrix; + +// x = tainted, y = specular; +varying vec2 intensity; +varying vec3 world_position; + +void main() +{ + // First transform the normal into camera space and normalize the result. + vec3 normal = normalize(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; + 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; + + world_position = v_position; + gl_Position = projection_matrix * position; +} diff --git a/resources/shaders/variable_layer_height_attr.vs b/resources/shaders/variable_layer_height_attr.vs new file mode 100644 index 000000000..40609bd0d --- /dev/null +++ b/resources/shaders/variable_layer_height_attr.vs @@ -0,0 +1,60 @@ +#version 110 + +#define INTENSITY_CORRECTION 0.6 + +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 + +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) +//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION) +//#define LIGHT_FRONT_SHININESS 5.0 + +#define INTENSITY_AMBIENT 0.3 + +attribute vec3 v_position; +attribute vec3 v_normal; +attribute vec2 v_tex_coord; + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat3 normal_matrix; +uniform mat4 volume_world_matrix; +uniform float object_max_z; + +// x = tainted, y = specular; +varying vec2 intensity; + +varying float object_z; + +void main() +{ + // ===================================================== + // NOTE: + // when object_max_z > 0.0 we are rendering the overlay + // when object_max_z == 0.0 we are rendering the volumes + // ===================================================== + + // First transform the normal into camera space and normalize the result. + vec3 normal = (object_max_z > 0.0) ? vec3(0.0, 0.0, 1.0) : normalize(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; + 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) + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + // Scaled to widths of the Z texture. + object_z = (object_max_z > 0.0) ? object_max_z * v_tex_coord.y : (volume_world_matrix * vec4(v_position, 1.0)).z; + + gl_Position = projection_matrix * position; +} diff --git a/src/libslic3r/BuildVolume.hpp b/src/libslic3r/BuildVolume.hpp index be8d224c3..b4ac118ec 100644 --- a/src/libslic3r/BuildVolume.hpp +++ b/src/libslic3r/BuildVolume.hpp @@ -95,10 +95,10 @@ public: bool all_paths_inside_vertices_and_normals_interleaved(const std::vector& paths, const Eigen::AlignedBox& bbox, bool ignore_bottom = true) const; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL const std::pair, std::vector>& top_bottom_convex_hull_decomposition_scene() const { return m_top_bottom_convex_hull_decomposition_scene; } const std::pair, std::vector>& top_bottom_convex_hull_decomposition_bed() const { return m_top_bottom_convex_hull_decomposition_bed; } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL private: // Source definition of the print bed geometry (PrintConfig::bed_shape) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 8e7fba126..f8f9f80e2 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -66,10 +66,10 @@ #define ENABLE_OBJECT_MANIPULATOR_FOCUS (1 && ENABLE_2_5_0_ALPHA1) // Enable removal of wipe tower magic object_id equal to 1000 #define ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL (1 && ENABLE_2_5_0_ALPHA1) -// Enable removal of old OpenGL render calls -#define ENABLE_GLBEGIN_GLEND_REMOVAL (1 && ENABLE_2_5_0_ALPHA1) -// Enable replace GLIndexedVertexArray with GLModel -#define ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL (1 && ENABLE_GLBEGIN_GLEND_REMOVAL) +// Enable removal of legacy OpenGL calls +#define ENABLE_LEGACY_OPENGL_REMOVAL (1 && ENABLE_2_5_0_ALPHA1) +// Enable using vertex attributes and matrices in shaders +#define ENABLE_GL_SHADERS_ATTRIBUTES (1 && ENABLE_LEGACY_OPENGL_REMOVAL) // Enable show non-manifold edges #define ENABLE_SHOW_NON_MANIFOLD_EDGES (1 && ENABLE_2_5_0_ALPHA1) // Enable rework of Reload from disk command diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 4ed054fb9..177c508ad 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -11,6 +11,10 @@ #include "GUI_App.hpp" #include "GLCanvas3D.hpp" +#if ENABLE_GL_SHADERS_ATTRIBUTES +#include "Plater.hpp" +#include "Camera.hpp" +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #include @@ -27,7 +31,7 @@ static const Slic3r::ColorRGBA DEFAULT_TRANSPARENT_GRID_COLOR = { 0.9f, 0.9f, 0 namespace Slic3r { namespace GUI { -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL bool GeometryBuffer::set_from_triangles(const std::vector &triangles, float z) { if (triangles.empty()) { @@ -96,7 +100,7 @@ const float* GeometryBuffer::get_vertices_data() const { return (m_vertices.size() > 0) ? (const float*)m_vertices.data() : nullptr; } -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL const float Bed3D::Axes::DefaultStemRadius = 0.5f; const float Bed3D::Axes::DefaultStemLength = 25.0f; @@ -105,17 +109,32 @@ const float Bed3D::Axes::DefaultTipLength = 5.0f; void Bed3D::Axes::render() { +#if ENABLE_GL_SHADERS_ATTRIBUTES + auto render_axis = [this](GLShaderProgram* shader, const Transform3d& transform) { + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d matrix = camera.get_view_matrix() * transform; + shader->set_uniform("view_model_matrix", matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else auto render_axis = [this](const Transform3f& transform) { glsafe(::glPushMatrix()); glsafe(::glMultMatrixf(transform.data())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_arrow.render(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES }; if (!m_arrow.is_initialized()) m_arrow.init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; @@ -125,28 +144,40 @@ void Bed3D::Axes::render() shader->set_uniform("emission_factor", 0.0f); // x axis -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_arrow.set_color(ColorRGBA::X()); #else m_arrow.set_color(-1, ColorRGBA::X()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + render_axis(shader, Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 })); +#else render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }).cast()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES // y axis -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_arrow.set_color(ColorRGBA::Y()); #else m_arrow.set_color(-1, ColorRGBA::Y()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + render_axis(shader, Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 })); +#else render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }).cast()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES // z axis -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_arrow.set_color(ColorRGBA::Z()); #else m_arrow.set_color(-1, ColorRGBA::Z()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + render_axis(shader, Geometry::assemble_transform(m_origin)); +#else render_axis(Geometry::assemble_transform(m_origin).cast()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES shader->stop_using(); @@ -200,7 +231,7 @@ bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, c m_model_filename = model_filename; m_extended_bounding_box = this->calc_extended_bounding_box(); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_contour = ExPolygon(Polygon::new_scale(bed_shape)); m_polygon = offset(m_contour.contour, (float)m_contour.contour.bounding_box().radius() * 1.7f, jtRound, scale_(0.5)).front(); @@ -217,7 +248,7 @@ bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, c m_polygon = offset(poly.contour, (float)bed_bbox.radius() * 1.7f, jtRound, scale_(0.5)).front(); this->release_VBOs(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL m_texture.reset(); m_model.reset(); @@ -239,6 +270,17 @@ Point Bed3D::point_projection(const Point& point) const return m_polygon.point_projection(point); } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void Bed3D::render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_axes, bool show_texture) +{ + render_internal(canvas, view_matrix, projection_matrix, bottom, scale_factor, show_axes, show_texture, false); +} + +void Bed3D::render_for_picking(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor) +{ + render_internal(canvas, view_matrix, projection_matrix, bottom, scale_factor, false, false, true); +} +#else void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes, bool show_texture) { render_internal(canvas, bottom, scale_factor, show_axes, show_texture, false); @@ -248,9 +290,15 @@ void Bed3D::render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_fact { render_internal(canvas, bottom, scale_factor, false, false, true); } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if ENABLE_GL_SHADERS_ATTRIBUTES +void Bed3D::render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, + bool show_axes, bool show_texture, bool picking) +#else void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes, bool show_texture, bool picking) +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { m_scale_factor = scale_factor; @@ -259,17 +307,23 @@ void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor, glsafe(::glEnable(GL_DEPTH_TEST)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_model.set_color(picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR); #else m_model.set_color(-1, picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL switch (m_type) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + case Type::System: { render_system(canvas, view_matrix, projection_matrix, bottom, show_texture); break; } + default: + case Type::Custom: { render_custom(canvas, view_matrix, projection_matrix, bottom, show_texture, picking); break; } +#else case Type::System: { render_system(canvas, bottom, show_texture); break; } default: case Type::Custom: { render_custom(canvas, bottom, show_texture, picking); break; } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } glsafe(::glDisable(GL_DEPTH_TEST)); @@ -298,7 +352,7 @@ BoundingBoxf3 Bed3D::calc_extended_bounding_box() const return out; } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void Bed3D::init_triangles() { if (m_triangles.is_initialized()) @@ -312,7 +366,7 @@ void Bed3D::init_triangles() return; GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3T2, GLModel::Geometry::index_type(triangles.size()) }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3T2 }; init_data.reserve_vertices(triangles.size()); init_data.reserve_indices(triangles.size() / 3); @@ -336,12 +390,8 @@ void Bed3D::init_triangles() const Vec3f p = { v.x(), v.y(), GROUND_Z }; init_data.add_vertex(p, (Vec2f)(v - min).cwiseProduct(inv_size).eval()); ++vertices_counter; - if (vertices_counter % 3 == 0) { - if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT) - init_data.add_ushort_triangle((unsigned short)vertices_counter - 3, (unsigned short)vertices_counter - 2, (unsigned short)vertices_counter - 1); - else - init_data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); - } + if (vertices_counter % 3 == 0) + init_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); } m_triangles.init_from(std::move(init_data)); @@ -380,18 +430,15 @@ void Bed3D::init_gridlines() std::copy(contour_lines.begin(), contour_lines.end(), std::back_inserter(gridlines)); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::index_type(2 * gridlines.size()) }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(2 * gridlines.size()); init_data.reserve_indices(2 * gridlines.size()); - for (const Line& l : gridlines) { + for (const Slic3r::Line& l : gridlines) { init_data.add_vertex(Vec3f(unscale(l.a.x()), unscale(l.a.y()), GROUND_Z)); init_data.add_vertex(Vec3f(unscale(l.b.x()), unscale(l.b.y()), GROUND_Z)); const unsigned int vertices_counter = (unsigned int)init_data.vertices_count(); - if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT) - init_data.add_ushort_line((unsigned short)vertices_counter - 2, (unsigned short)vertices_counter - 1); - else - init_data.add_uint_line(vertices_counter - 2, vertices_counter - 1); + init_data.add_line(vertices_counter - 2, vertices_counter - 1); } m_gridlines.init_from(std::move(init_data)); @@ -429,7 +476,7 @@ void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox) if (!m_gridlines.set_from_lines(gridlines, GROUND_Z)) BOOST_LOG_TRIVIAL(error) << "Unable to create bed grid lines\n"; } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // Try to match the print bed shape with the shape of an active profile. If such a match exists, // return the print bed model. @@ -461,6 +508,16 @@ void Bed3D::render_axes() m_axes.render(); } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void Bed3D::render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture) +{ + if (!bottom) + render_model(view_matrix, projection_matrix); + + if (show_texture) + render_texture(bottom, canvas); +} +#else void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture) { if (!bottom) @@ -469,6 +526,7 @@ void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture) if (show_texture) render_texture(bottom, canvas); } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) { @@ -531,12 +589,21 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) canvas.request_extra_frame(); } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL init_triangles(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("printbed_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("printbed"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES shader->set_uniform("transparent_background", bottom); shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg")); @@ -627,20 +694,24 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) shader->stop_using(); } } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void Bed3D::render_model(const Transform3d& view_matrix, const Transform3d& projection_matrix) +#else void Bed3D::render_model() +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { if (m_model_filename.empty()) return; if (m_model.get_filename() != m_model_filename && m_model.init_from_file(m_model_filename)) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_model.set_color(DEFAULT_MODEL_COLOR); #else m_model.set_color(-1, DEFAULT_MODEL_COLOR); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad m_model_offset = to_3d(m_build_volume.bounding_volume2d().center(), -0.03); @@ -650,20 +721,37 @@ void Bed3D::render_model() } if (!m_model.get_filename().empty()) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); shader->set_uniform("emission_factor", 0.0f); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d matrix = view_matrix * Geometry::assemble_transform(m_model_offset); + shader->set_uniform("view_model_matrix", matrix); + shader->set_uniform("projection_matrix", projection_matrix); + shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else glsafe(::glPushMatrix()); glsafe(::glTranslated(m_model_offset.x(), m_model_offset.y(), m_model_offset.z())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_model.render(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES shader->stop_using(); } } } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void Bed3D::render_custom(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture, bool picking) +#else void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking) +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { if (m_texture_filename.empty() && m_model_filename.empty()) { render_default(bottom, picking); @@ -671,7 +759,11 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bo } if (!bottom) +#if ENABLE_GL_SHADERS_ATTRIBUTES + render_model(view_matrix, projection_matrix); +#else render_model(); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (show_texture) render_texture(bottom, canvas); @@ -681,14 +773,24 @@ void Bed3D::render_default(bool bottom, bool picking) { m_texture.reset(); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL init_gridlines(); init_triangles(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); @@ -747,10 +849,10 @@ void Bed3D::render_default(bool bottom, bool picking) glsafe(::glDisable(GL_BLEND)); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL void Bed3D::release_VBOs() { if (m_vbo_id > 0) { @@ -758,7 +860,7 @@ void Bed3D::release_VBOs() m_vbo_id = 0; } } -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL } // GUI } // Slic3r diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index 350ae48f6..de4fa99cf 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -6,9 +6,9 @@ #include "GLModel.hpp" #include "libslic3r/BuildVolume.hpp" -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #include "libslic3r/ExPolygon.hpp" -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #include #include @@ -18,7 +18,7 @@ namespace GUI { class GLCanvas3D; -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL class GeometryBuffer { struct Vertex @@ -40,7 +40,7 @@ public: size_t get_tex_coords_offset() const { return (size_t)(3 * sizeof(float)); } unsigned int get_vertices_count() const { return (unsigned int)m_vertices.size(); } }; -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL class Bed3D { @@ -84,38 +84,38 @@ private: std::string m_model_filename; // Print volume bounding box exteded with axes and model. BoundingBoxf3 m_extended_bounding_box; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // Print bed polygon ExPolygon m_contour; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // Slightly expanded print bed polygon, for collision detection. Polygon m_polygon; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel m_triangles; GLModel m_gridlines; #else GeometryBuffer m_triangles; GeometryBuffer m_gridlines; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL GLTexture m_texture; // temporary texture shown until the main texture has still no levels compressed GLTexture m_temp_texture; GLModel m_model; Vec3d m_model_offset{ Vec3d::Zero() }; -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL unsigned int m_vbo_id{ 0 }; -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL Axes m_axes; float m_scale_factor{ 1.0f }; public: Bed3D() = default; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL ~Bed3D() = default; #else ~Bed3D() { release_VBOs(); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // Update print bed model from configuration. // Return true if the bed shape changed, so the calee will update the UI. @@ -139,31 +139,50 @@ public: bool contains(const Point& point) const; Point point_projection(const Point& point) const; +#if ENABLE_GL_SHADERS_ATTRIBUTES + void render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_axes, bool show_texture); + void render_for_picking(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor); +#else void render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes, bool show_texture); void render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_factor); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES private: // Calculate an extended bounding box from axes and current model for visualization purposes. BoundingBoxf3 calc_extended_bounding_box() const; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void init_triangles(); void init_gridlines(); #else void calc_triangles(const ExPolygon& poly); void calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL static std::tuple detect_type(const Pointfs& shape); +#if ENABLE_GL_SHADERS_ATTRIBUTES + void render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, + bool show_axes, bool show_texture, bool picking); +#else void render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes, bool show_texture, bool picking); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES void render_axes(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + void render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture); +#else void render_system(GLCanvas3D& canvas, bool bottom, bool show_texture); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES void render_texture(bool bottom, GLCanvas3D& canvas); +#if ENABLE_GL_SHADERS_ATTRIBUTES + void render_model(const Transform3d& view_matrix, const Transform3d& projection_matrix); + void render_custom(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture, bool picking); +#else void render_model(); void render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES void render_default(bool bottom, bool picking); -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL void release_VBOs(); -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL }; } // GUI diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 2405f39bc..0e7c551d5 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1,18 +1,21 @@ #include -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_SMOOTH_NORMALS #include #include #include #endif // ENABLE_SMOOTH_NORMALS -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL #include "3DScene.hpp" #include "GLShader.hpp" #include "GUI_App.hpp" #include "Plater.hpp" #include "BitmapCache.hpp" +#if ENABLE_GL_SHADERS_ATTRIBUTES +#include "Camera.hpp" +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #include "libslic3r/BuildVolume.hpp" #include "libslic3r/ExtrusionEntity.hpp" @@ -71,7 +74,7 @@ void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char namespace Slic3r { -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_SMOOTH_NORMALS static void smooth_normals_corner(TriangleMesh& mesh, std::vector& normals) { @@ -290,7 +293,7 @@ void GLIndexedVertexArray::render( glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL const float GLVolume::SinkingContours::HalfWidth = 0.25f; @@ -298,10 +301,22 @@ void GLVolume::SinkingContours::render() { update(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = GUI::wxGetApp().get_current_shader(); + if (shader == nullptr) + return; + + const GUI::Camera& camera = GUI::wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix() * Geometry::assemble_transform(m_shift)); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#else glsafe(::glPushMatrix()); glsafe(::glTranslated(m_shift.x(), m_shift.y(), m_shift.z())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_model.render(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } void GLVolume::SinkingContours::update() @@ -319,16 +334,16 @@ void GLVolume::SinkingContours::update() m_model.reset(); GUI::GLModel::Geometry init_data; -#if ENABLE_GLBEGIN_GLEND_REMOVAL - init_data.format = { GUI::GLModel::Geometry::EPrimitiveType::Triangles, GUI::GLModel::Geometry::EVertexLayout::P3, GUI::GLModel::Geometry::EIndexType::UINT }; +#if ENABLE_LEGACY_OPENGL_REMOVAL + init_data.format = { GUI::GLModel::Geometry::EPrimitiveType::Triangles, GUI::GLModel::Geometry::EVertexLayout::P3 }; init_data.color = ColorRGBA::WHITE(); unsigned int vertices_counter = 0; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL MeshSlicingParams slicing_params; slicing_params.trafo = m_parent.world_matrix(); const Polygons polygons = union_(slice_mesh(mesh.its, 0.0f, slicing_params)); for (const ExPolygon& expoly : diff_ex(expand(polygons, float(scale_(HalfWidth))), shrink(polygons, float(scale_(HalfWidth))))) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL const std::vector triangulation = triangulate_expolygon_3d(expoly); init_data.reserve_vertices(init_data.vertices_count() + triangulation.size()); init_data.reserve_indices(init_data.indices_count() + triangulation.size()); @@ -336,7 +351,7 @@ void GLVolume::SinkingContours::update() init_data.add_vertex((Vec3f)(v.cast() + 0.015f * Vec3f::UnitZ())); // add a small positive z to avoid z-fighting ++vertices_counter; if (vertices_counter % 3 == 0) - init_data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); + init_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); } } m_model.init_from(std::move(init_data)); @@ -360,7 +375,7 @@ void GLVolume::SinkingContours::update() init_data.entities.emplace_back(entity); } m_model.init_from(init_data); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } else m_shift = box.center() - m_old_box.center(); @@ -375,15 +390,27 @@ void GLVolume::NonManifoldEdges::render() update(); glsafe(::glLineWidth(2.0f)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = GUI::wxGetApp().get_current_shader(); + if (shader == nullptr) + return; + + const GUI::Camera& camera = GUI::wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix() * m_parent.world_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#else glsafe(::glPushMatrix()); glsafe(::glMultMatrixd(m_parent.world_matrix().data())); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if ENABLE_LEGACY_OPENGL_REMOVAL m_model.set_color(complementary(m_parent.render_color)); #else m_model.set_color(-1, complementary(m_parent.render_color)); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL m_model.render(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } void GLVolume::NonManifoldEdges::update() @@ -403,8 +430,8 @@ void GLVolume::NonManifoldEdges::update() const std::vector> edges = its_get_open_edges(mesh.its); if (!edges.empty()) { GUI::GLModel::Geometry init_data; -#if ENABLE_GLBEGIN_GLEND_REMOVAL - init_data.format = { GUI::GLModel::Geometry::EPrimitiveType::Lines, GUI::GLModel::Geometry::EVertexLayout::P3, GUI::GLModel::Geometry::index_type(2 * edges.size()) }; +#if ENABLE_LEGACY_OPENGL_REMOVAL + init_data.format = { GUI::GLModel::Geometry::EPrimitiveType::Lines, GUI::GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(2 * edges.size()); init_data.reserve_indices(2 * edges.size()); @@ -414,10 +441,7 @@ void GLVolume::NonManifoldEdges::update() init_data.add_vertex((Vec3f)mesh.its.vertices[edge.first].cast()); init_data.add_vertex((Vec3f)mesh.its.vertices[edge.second].cast()); vertices_count += 2; - if (init_data.format.index_type == GUI::GLModel::Geometry::EIndexType::USHORT) - init_data.add_ushort_line((unsigned short)vertices_count - 2, (unsigned short)vertices_count - 1); - else - init_data.add_uint_line(vertices_count - 2, vertices_count - 1); + init_data.add_line(vertices_count - 2, vertices_count - 1); } m_model.init_from(std::move(init_data)); #else @@ -438,7 +462,7 @@ void GLVolume::NonManifoldEdges::update() init_data.entities.emplace_back(entity); m_model.init_from(init_data); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } } } @@ -487,9 +511,9 @@ GLVolume::GLVolume(float r, float g, float b, float a) , force_neutral_color(false) , force_sinking_contours(false) , tverts_range(0, size_t(-1)) -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL , qverts_range(0, size_t(-1)) -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL { color = { r, g, b, a }; set_render_color(color); @@ -605,7 +629,7 @@ const BoundingBoxf3& GLVolume::transformed_non_sinking_bounding_box() const return *m_transformed_non_sinking_bounding_box; } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void GLVolume::set_range(double min_z, double max_z) { this->tverts_range.first = 0; @@ -671,29 +695,40 @@ void GLVolume::set_range(double min_z, double max_z) } } } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL void GLVolume::render() { if (!is_active) return; +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = GUI::wxGetApp().get_current_shader(); + if (shader == nullptr) + return; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + if (this->is_left_handed()) glFrontFace(GL_CW); glsafe(::glCullFace(GL_BACK)); - glsafe(::glPushMatrix()); - glsafe(::glMultMatrixd(world_matrix().data())); +#if !ENABLE_GL_SHADERS_ATTRIBUTES + glsafe(::glPushMatrix()); + glsafe(::glMultMatrixd(world_matrix().data())); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (tverts_range == std::make_pair(0, -1)) model.render(); else model.render(this->tverts_range); #else this->indexed_vertex_array.render(this->tverts_range, this->qverts_range); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL + +#if !ENABLE_GL_SHADERS_ATTRIBUTES + glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES - glsafe(::glPopMatrix()); if (this->is_left_handed()) glFrontFace(GL_CCW); } @@ -726,7 +761,7 @@ void GLVolume::render_non_manifold_edges() } #endif // ENABLE_SHOW_NON_MANIFOLD_EDGES -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL std::vector GLVolumeCollection::load_object( const ModelObject* model_object, int obj_idx, @@ -737,20 +772,20 @@ std::vector GLVolumeCollection::load_object( int obj_idx, const std::vector &instance_idxs, bool opengl_initialized) -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { std::vector volumes_idx; for (int volume_idx = 0; volume_idx < int(model_object->volumes.size()); ++volume_idx) for (int instance_idx : instance_idxs) -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL volumes_idx.emplace_back(this->GLVolumeCollection::load_object_volume(model_object, obj_idx, volume_idx, instance_idx)); #else volumes_idx.emplace_back(this->GLVolumeCollection::load_object_volume(model_object, obj_idx, volume_idx, instance_idx, opengl_initialized)); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL return volumes_idx; } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL int GLVolumeCollection::load_object_volume( const ModelObject* model_object, int obj_idx, @@ -763,7 +798,7 @@ int GLVolumeCollection::load_object_volume( int volume_idx, int instance_idx, bool opengl_initialized) -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { const ModelVolume *model_volume = model_object->volumes[volume_idx]; const int extruder_id = model_volume->extruder_id(); @@ -772,7 +807,7 @@ int GLVolumeCollection::load_object_volume( this->volumes.emplace_back(new GLVolume()); GLVolume& v = *this->volumes.back(); v.set_color(color_from_model_volume(*model_volume)); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_SMOOTH_NORMALS v.model.init_from(mesh, true); #else @@ -785,7 +820,7 @@ int GLVolumeCollection::load_object_volume( v.indexed_vertex_array.load_mesh(mesh); #endif // ENABLE_SMOOTH_NORMALS v.indexed_vertex_array.finalize_geometry(opengl_initialized); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL v.composite_id = GLVolume::CompositeID(obj_idx, volume_idx, instance_idx); if (model_volume->is_model_part()) { // GLVolume will reference a convex hull from model_volume! @@ -804,7 +839,7 @@ int GLVolumeCollection::load_object_volume( // Load SLA auxiliary GLVolumes (for support trees or pad). // This function produces volumes for multiple instances in a single shot, // as some object specific mesh conversions may be expensive. -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void GLVolumeCollection::load_object_auxiliary( const SLAPrintObject* print_object, int obj_idx, @@ -823,7 +858,7 @@ void GLVolumeCollection::load_object_auxiliary( // Timestamp of the last change of the milestone size_t timestamp, bool opengl_initialized) -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { assert(print_object->is_step_done(milestone)); Transform3d mesh_trafo_inv = print_object->trafo().inverse(); @@ -836,7 +871,7 @@ void GLVolumeCollection::load_object_auxiliary( const ModelInstance& model_instance = *print_object->model_object()->instances[instance_idx.first]; this->volumes.emplace_back(new GLVolume((milestone == slaposPad) ? GLVolume::SLA_PAD_COLOR : GLVolume::SLA_SUPPORT_COLOR)); GLVolume& v = *this->volumes.back(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_SMOOTH_NORMALS v.model.init_from(mesh, true); #else @@ -850,7 +885,7 @@ void GLVolumeCollection::load_object_auxiliary( v.indexed_vertex_array.load_mesh(mesh); #endif // ENABLE_SMOOTH_NORMALS v.indexed_vertex_array.finalize_geometry(opengl_initialized); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL v.composite_id = GLVolume::CompositeID(obj_idx, -int(milestone), (int)instance_idx.first); v.geometry_id = std::pair(timestamp, model_instance.id().id); // Create a copy of the convex hull mesh for each instance. Use a move operator on the last instance. @@ -866,7 +901,7 @@ void GLVolumeCollection::load_object_auxiliary( } } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL int GLVolumeCollection::load_wipe_tower_preview( float pos_x, float pos_y, float width, float depth, float height, @@ -886,7 +921,7 @@ int GLVolumeCollection::load_wipe_tower_preview( int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized) #endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { if (depth < 0.01f) return int(this->volumes.size() - 1); @@ -943,16 +978,16 @@ int GLVolumeCollection::load_wipe_tower_preview( volumes.emplace_back(new GLVolume(color)); GLVolume& v = *volumes.back(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL v.model.init_from(mesh); v.model.set_color(color); #else v.indexed_vertex_array.load_mesh(mesh); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL v.set_convex_hull(mesh.convex_hull_3d()); -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL v.indexed_vertex_array.finalize_geometry(opengl_initialized); -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0)); v.set_volume_rotation(Vec3d(0., 0., (M_PI / 180.) * rotation_angle)); #if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL @@ -967,7 +1002,7 @@ int GLVolumeCollection::load_wipe_tower_preview( return int(volumes.size() - 1); } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLVolume* GLVolumeCollection::new_toolpath_volume(const ColorRGBA& rgba) { GLVolume* out = new_nontoolpath_volume(rgba); @@ -999,7 +1034,7 @@ GLVolume* GLVolumeCollection::new_nontoolpath_volume(const ColorRGBA& rgba, size this->volumes.emplace_back(out); return out; } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function filter_func) { @@ -1034,7 +1069,12 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo return list; } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, const Transform3d& projection_matrix, + std::function filter_func) const +#else void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func) const +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { GLVolumeWithIdAndZList to_render = volumes_to_render(volumes, type, view_matrix, filter_func); if (to_render.empty()) @@ -1044,10 +1084,16 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab if (shader == nullptr) return; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat_attr"); + GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat_attr"); + assert(boost::algorithm::iends_with(shader->get_name(), "_attr")); +#else GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat"); GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat"); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_GL_SHADERS_ATTRIBUTES +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (type == ERenderType::Transparent) { glsafe(::glEnable(GL_BLEND)); @@ -1062,36 +1108,34 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab volume.first->set_render_color(true); // render sinking contours of non-hovered volumes -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); if (sink_shader != nullptr) { sink_shader->start_using(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (m_show_sinking_contours) { if (volume.first->is_sinking() && !volume.first->is_below_printbed() && volume.first->hover == GLVolume::HS_None && !volume.first->force_sinking_contours) { -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL volume.first->render_sinking_contours(); -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL shader->start_using(); -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL } } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL sink_shader->stop_using(); } shader->start_using(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); +#if !ENABLE_GL_SHADERS_ATTRIBUTES + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL - if (!volume.first->model.is_initialized()) -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL - shader->set_uniform("uniform_color", volume.first->render_color); shader->set_uniform("z_range", m_z_range, 2); shader->set_uniform("clipping_plane", m_clipping_plane, 4); shader->set_uniform("print_volume.type", static_cast(m_print_volume.type)); @@ -1111,9 +1155,15 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab #endif // ENABLE_ENVIRONMENT_MAP glcheck(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL volume.first->model.set_color(volume.first->render_color); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d matrix = view_matrix * volume.first->world_matrix(); + shader->set_uniform("view_model_matrix", matrix); + shader->set_uniform("projection_matrix", projection_matrix); + shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES volume.first->render(); #if ENABLE_ENVIRONMENT_MAP @@ -1124,54 +1174,56 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } if (m_show_sinking_contours) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); if (sink_shader != nullptr) { sink_shader->start_using(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL for (GLVolumeWithIdAndZ& volume : to_render) { // render sinking contours of hovered/displaced volumes if (volume.first->is_sinking() && !volume.first->is_below_printbed() && (volume.first->hover != GLVolume::HS_None || volume.first->force_sinking_contours)) { -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glDepthFunc(GL_ALWAYS)); volume.first->render_sinking_contours(); glsafe(::glDepthFunc(GL_LESS)); -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL shader->start_using(); -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL } } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL sink_shader->start_using(); } shader->start_using(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } #if ENABLE_SHOW_NON_MANIFOLD_EDGES -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); if (edges_shader != nullptr) { edges_shader->start_using(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (m_show_non_manifold_edges && GUI::wxGetApp().app_config->get("non_manifold_edges") == "1") { for (GLVolumeWithIdAndZ& volume : to_render) { volume.first->render_non_manifold_edges(); } } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL edges_shader->stop_using(); } shader->start_using(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #endif // ENABLE_SHOW_NON_MANIFOLD_EDGES if (disable_cullface) @@ -1349,7 +1401,7 @@ std::string GLVolumeCollection::log_memory_info() const return " (GLVolumeCollection RAM: " + format_memsize_MB(this->cpu_memory_used()) + " GPU: " + format_memsize_MB(this->gpu_memory_used()) + " Both: " + format_memsize_MB(this->gpu_memory_used()) + ")"; } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL static void thick_lines_to_geometry( const Lines& lines, const std::vector& widths, @@ -1425,8 +1477,8 @@ static void thick_lines_to_geometry( if (!is_first && bottom_z_different) { // Found a change of the layer thickness -> Add a cap at the end of the previous segment. - geometry.add_uint_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]); - geometry.add_uint_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]); + geometry.add_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]); + geometry.add_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]); } // Share top / bottom vertices if possible. @@ -1476,13 +1528,13 @@ static void thick_lines_to_geometry( geometry.add_vertex(Vec3f(a2.x(), a2.y(), middle_z), Vec3f(-xy_right_normal.x(), -xy_right_normal.y(), 0.0f)); if (cross2(v_prev, v) > 0.0) { // Right turn. Fill in the right turn wedge. - geometry.add_uint_triangle(idx_prev[Right], idx_a[Right], idx_prev[Top]); - geometry.add_uint_triangle(idx_prev[Right], idx_prev[Bottom], idx_a[Right]); + geometry.add_triangle(idx_prev[Right], idx_a[Right], idx_prev[Top]); + geometry.add_triangle(idx_prev[Right], idx_prev[Bottom], idx_a[Right]); } else { // Left turn. Fill in the left turn wedge. - geometry.add_uint_triangle(idx_prev[Left], idx_prev[Top], idx_a[Left]); - geometry.add_uint_triangle(idx_prev[Left], idx_a[Left], idx_prev[Bottom]); + geometry.add_triangle(idx_prev[Left], idx_prev[Top], idx_a[Left]); + geometry.add_triangle(idx_prev[Left], idx_a[Left], idx_prev[Bottom]); } } } @@ -1504,11 +1556,11 @@ static void thick_lines_to_geometry( // Replace the left / right vertex indices to point to the start of the loop. const size_t indices_count = geometry.indices_count(); for (size_t u = indices_count - 24; u < indices_count; ++u) { - const unsigned int id = geometry.extract_uint_index(u); + const unsigned int id = geometry.extract_index(u); if (id == (unsigned int)idx_prev[Left]) - geometry.set_uint_index(u, (unsigned int)idx_initial[Left]); + geometry.set_index(u, (unsigned int)idx_initial[Left]); else if (id == (unsigned int)idx_prev[Right]) - geometry.set_uint_index(u, (unsigned int)idx_initial[Right]); + geometry.set_index(u, (unsigned int)idx_initial[Right]); } } } @@ -1545,36 +1597,36 @@ static void thick_lines_to_geometry( if (bottom_z_different && (closed || (!is_first && !is_last))) { // Found a change of the layer thickness -> Add a cap at the beginning of this segment. - geometry.add_uint_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]); - geometry.add_uint_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]); + geometry.add_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]); + geometry.add_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]); } if (!closed) { // Terminate open paths with caps. if (is_first) { - geometry.add_uint_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]); - geometry.add_uint_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]); + geometry.add_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]); + geometry.add_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]); } // We don't use 'else' because both cases are true if we have only one line. if (is_last) { - geometry.add_uint_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]); - geometry.add_uint_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]); + geometry.add_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]); + geometry.add_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]); } } // Add quads for a straight hollow tube-like segment. // bottom-right face - geometry.add_uint_triangle(idx_a[Bottom], idx_b[Bottom], idx_b[Right]); - geometry.add_uint_triangle(idx_a[Bottom], idx_b[Right], idx_a[Right]); + geometry.add_triangle(idx_a[Bottom], idx_b[Bottom], idx_b[Right]); + geometry.add_triangle(idx_a[Bottom], idx_b[Right], idx_a[Right]); // top-right face - geometry.add_uint_triangle(idx_a[Right], idx_b[Right], idx_b[Top]); - geometry.add_uint_triangle(idx_a[Right], idx_b[Top], idx_a[Top]); + geometry.add_triangle(idx_a[Right], idx_b[Right], idx_b[Top]); + geometry.add_triangle(idx_a[Right], idx_b[Top], idx_a[Top]); // top-left face - geometry.add_uint_triangle(idx_a[Top], idx_b[Top], idx_b[Left]); - geometry.add_uint_triangle(idx_a[Top], idx_b[Left], idx_a[Left]); + geometry.add_triangle(idx_a[Top], idx_b[Top], idx_b[Left]); + geometry.add_triangle(idx_a[Top], idx_b[Left], idx_a[Left]); // bottom-left face - geometry.add_uint_triangle(idx_a[Left], idx_b[Left], idx_b[Bottom]); - geometry.add_uint_triangle(idx_a[Left], idx_b[Bottom], idx_a[Bottom]); + geometry.add_triangle(idx_a[Left], idx_b[Left], idx_b[Bottom]); + geometry.add_triangle(idx_a[Left], idx_b[Bottom], idx_a[Bottom]); } } @@ -1714,13 +1766,13 @@ static void thick_lines_to_geometry( if (is_right_turn) { // Right turn. Fill in the right turn wedge. - geometry.add_uint_triangle(idx_prev[Right], idx_a[Right], idx_prev[Top]); - geometry.add_uint_triangle(idx_prev[Right], idx_prev[Bottom], idx_a[Right]); + geometry.add_triangle(idx_prev[Right], idx_a[Right], idx_prev[Top]); + geometry.add_triangle(idx_prev[Right], idx_prev[Bottom], idx_a[Right]); } else { // Left turn. Fill in the left turn wedge. - geometry.add_uint_triangle(idx_prev[Left], idx_prev[Top], idx_a[Left]); - geometry.add_uint_triangle(idx_prev[Left], idx_a[Left], idx_prev[Bottom]); + geometry.add_triangle(idx_prev[Left], idx_prev[Top], idx_a[Left]); + geometry.add_triangle(idx_prev[Left], idx_a[Left], idx_prev[Bottom]); } } else { @@ -1739,11 +1791,11 @@ static void thick_lines_to_geometry( // Replace the left / right vertex indices to point to the start of the loop. const size_t indices_count = geometry.indices_count(); for (size_t u = indices_count - 24; u < indices_count; ++u) { - const unsigned int id = geometry.extract_uint_index(u); + const unsigned int id = geometry.extract_index(u); if (id == (unsigned int)idx_prev[Left]) - geometry.set_uint_index(u, (unsigned int)idx_initial[Left]); + geometry.set_index(u, (unsigned int)idx_initial[Left]); else if (id == (unsigned int)idx_prev[Right]) - geometry.set_uint_index(u, (unsigned int)idx_initial[Right]); + geometry.set_index(u, (unsigned int)idx_initial[Right]); } } @@ -1782,30 +1834,30 @@ static void thick_lines_to_geometry( if (!closed) { // Terminate open paths with caps. if (i == 0) { - geometry.add_uint_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]); - geometry.add_uint_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]); + geometry.add_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]); + geometry.add_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]); } // We don't use 'else' because both cases are true if we have only one line. if (i + 1 == lines.size()) { - geometry.add_uint_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]); - geometry.add_uint_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]); + geometry.add_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]); + geometry.add_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]); } } // Add quads for a straight hollow tube-like segment. // bottom-right face - geometry.add_uint_triangle(idx_a[Bottom], idx_b[Bottom], idx_b[Right]); - geometry.add_uint_triangle(idx_a[Bottom], idx_b[Right], idx_a[Right]); + geometry.add_triangle(idx_a[Bottom], idx_b[Bottom], idx_b[Right]); + geometry.add_triangle(idx_a[Bottom], idx_b[Right], idx_a[Right]); // top-right face - geometry.add_uint_triangle(idx_a[Right], idx_b[Right], idx_b[Top]); - geometry.add_uint_triangle(idx_a[Right], idx_b[Top], idx_a[Top]); + geometry.add_triangle(idx_a[Right], idx_b[Right], idx_b[Top]); + geometry.add_triangle(idx_a[Right], idx_b[Top], idx_a[Top]); // top-left face - geometry.add_uint_triangle(idx_a[Top], idx_b[Top], idx_b[Left]); - geometry.add_uint_triangle(idx_a[Top], idx_b[Left], idx_a[Left]); + geometry.add_triangle(idx_a[Top], idx_b[Top], idx_b[Left]); + geometry.add_triangle(idx_a[Top], idx_b[Left], idx_a[Left]); // bottom-left face - geometry.add_uint_triangle(idx_a[Left], idx_b[Left], idx_b[Bottom]); - geometry.add_uint_triangle(idx_a[Left], idx_b[Bottom], idx_a[Bottom]); + geometry.add_triangle(idx_a[Left], idx_b[Left], idx_b[Bottom]); + geometry.add_triangle(idx_a[Left], idx_b[Bottom], idx_a[Bottom]); } } #else @@ -2318,9 +2370,9 @@ static void point_to_indexed_vertex_array(const Vec3crd& point, volume.push_triangle(idxs[3], idxs[1], idxs[4]); volume.push_triangle(idxs[0], idxs[3], idxs[4]); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void _3DScene::thick_lines_to_verts( const Lines& lines, const std::vector& widths, @@ -2383,10 +2435,10 @@ void _3DScene::extrusionentity_to_verts(const ExtrusionPath &extrusion_path, flo { extrusionentity_to_verts(extrusion_path.polyline, extrusion_path.width, extrusion_path.height, print_z, volume); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // Fill in the qverts and tverts with quads and triangles for the extrusion_path. -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void _3DScene::extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry) { Polyline polyline = extrusion_path.polyline; @@ -2408,10 +2460,10 @@ void _3DScene::extrusionentity_to_verts(const ExtrusionPath &extrusion_path, flo std::vector heights(lines.size(), extrusion_path.height); thick_lines_to_verts(lines, widths, heights, false, print_z, volume); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // Fill in the qverts and tverts with quads and triangles for the extrusion_loop. -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void _3DScene::extrusionentity_to_verts(const ExtrusionLoop& extrusion_loop, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry) { Lines lines; @@ -2445,10 +2497,10 @@ void _3DScene::extrusionentity_to_verts(const ExtrusionLoop &extrusion_loop, flo } thick_lines_to_verts(lines, widths, heights, true, print_z, volume); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // Fill in the qverts and tverts with quads and triangles for the extrusion_multi_path. -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void _3DScene::extrusionentity_to_verts(const ExtrusionMultiPath& extrusion_multi_path, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry) { Lines lines; @@ -2482,9 +2534,9 @@ void _3DScene::extrusionentity_to_verts(const ExtrusionMultiPath &extrusion_mult } thick_lines_to_verts(lines, widths, heights, false, print_z, volume); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void _3DScene::extrusionentity_to_verts(const ExtrusionEntityCollection& extrusion_entity_collection, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry) { for (const ExtrusionEntity* extrusion_entity : extrusion_entity_collection.entities) @@ -2496,9 +2548,9 @@ void _3DScene::extrusionentity_to_verts(const ExtrusionEntityCollection &extrusi for (const ExtrusionEntity *extrusion_entity : extrusion_entity_collection.entities) extrusionentity_to_verts(extrusion_entity, print_z, copy, volume); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void _3DScene::extrusionentity_to_verts(const ExtrusionEntity* extrusion_entity, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry) { if (extrusion_entity != nullptr) { @@ -2563,6 +2615,6 @@ void _3DScene::point3_to_verts(const Vec3crd& point, double width, double height { thick_point_to_verts(point, width, height, volume); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } // namespace Slic3r diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index ed2aa804e..950d447f0 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -46,7 +46,7 @@ enum ModelInstanceEPrintVolumeState : unsigned char; // Return appropriate color based on the ModelVolume. extern ColorRGBA color_from_model_volume(const ModelVolume& model_volume); -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL // A container for interleaved arrays of 3D vertices and normals, // possibly indexed by triangles and / or quads. class GLIndexedVertexArray { @@ -247,7 +247,7 @@ public: private: BoundingBox m_bounding_box; }; -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL class GLVolume { public: @@ -390,17 +390,17 @@ public: // Is mouse or rectangle selection over this object to select/deselect it ? EHoverState hover; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GUI::GLModel model; #else // Interleaved triangles & normals with indexed triangles & quads. GLIndexedVertexArray indexed_vertex_array; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // Ranges of triangle and quad indices to be rendered. std::pair tverts_range; -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL std::pair qverts_range; -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL // If the qverts or tverts contain thick extrusions, then offsets keeps pointers of the starts // of the extrusions per layer. @@ -410,7 +410,7 @@ public: // Bounding box of this volume, in unscaled coordinates. BoundingBoxf3 bounding_box() const { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL return this->model.get_bounding_box(); #else BoundingBoxf3 out; @@ -420,7 +420,7 @@ public: out.defined = true; } return out; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } void set_color(const ColorRGBA& rgba) { color = rgba; } @@ -510,20 +510,20 @@ public: // convex hull const TriangleMesh* convex_hull() const { return m_convex_hull.get(); } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL bool empty() const { return this->model.is_empty(); } #else bool empty() const { return this->indexed_vertex_array.empty(); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL void set_range(double low, double high); void render(); -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL void finalize_geometry(bool opengl_initialized) { this->indexed_vertex_array.finalize_geometry(opengl_initialized); } void release_geometry() { this->indexed_vertex_array.release_geometry(); } -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL void set_bounding_boxes_as_dirty() { m_transformed_bounding_box.reset(); @@ -543,7 +543,7 @@ public: // Return an estimate of the memory consumed by this class. size_t cpu_memory_used() const { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL return sizeof(*this) + this->model.cpu_memory_used() + this->print_zs.capacity() * sizeof(coordf_t) + this->offsets.capacity() * sizeof(size_t); } @@ -555,7 +555,7 @@ public: } // Return an estimate of the memory held by GPU vertex buffers. size_t gpu_memory_used() const { return this->indexed_vertex_array.gpu_memory_used(); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL size_t total_memory_used() const { return this->cpu_memory_used() + this->gpu_memory_used(); } }; @@ -615,7 +615,7 @@ public: GLVolumeCollection() { set_default_slope_normal_z(); } ~GLVolumeCollection() { clear(); } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL std::vector load_object( const ModelObject* model_object, int obj_idx, @@ -676,20 +676,25 @@ public: int load_wipe_tower_preview( int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized); #endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLVolume* new_toolpath_volume(const ColorRGBA& rgba); GLVolume* new_nontoolpath_volume(const ColorRGBA& rgba); #else GLVolume* new_toolpath_volume(const ColorRGBA& rgba, size_t reserve_vbo_floats = 0); GLVolume* new_nontoolpath_volume(const ColorRGBA& rgba, size_t reserve_vbo_floats = 0); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // Render the volumes by OpenGL. +#if ENABLE_GL_SHADERS_ATTRIBUTES + void render(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, const Transform3d& projection_matrix, + std::function filter_func = std::function()) const; +#else void render(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func = std::function()) const; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL // Finalize the initialization of the geometry & indices, // upload the geometry and indices to OpenGL VBO objects // and shrink the allocated data, possibly relasing it if it has been loaded into the VBOs. @@ -697,7 +702,7 @@ public: // Release the geometry data assigned to the volumes. // If OpenGL VBOs were allocated, an OpenGL context has to be active to release them. void release_geometry() { for (auto *v : volumes) v->release_geometry(); } -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL // Clear the geometry void clear() { for (auto *v : volumes) delete v; volumes.clear(); } @@ -747,7 +752,7 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo struct _3DScene { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL static void thick_lines_to_verts(const Lines& lines, const std::vector& widths, const std::vector& heights, bool closed, double top_z, GUI::GLModel::Geometry& geometry); static void thick_lines_to_verts(const Lines3& lines, const std::vector& widths, const std::vector& heights, bool closed, GUI::GLModel::Geometry& geometry); static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry); @@ -767,7 +772,7 @@ struct _3DScene static void extrusionentity_to_verts(const ExtrusionEntity* extrusion_entity, float print_z, const Point& copy, GLVolume& volume); static void polyline3_to_verts(const Polyline3& polyline, double width, double height, GLVolume& volume); static void point3_to_verts(const Vec3crd& point, double width, double height, GLVolume& volume); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL }; } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index cfe6fe418..0c3dd6560 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -184,7 +184,11 @@ void GCodeViewer::COG::render() init(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("toolpaths_cog_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("toolpaths_cog"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; @@ -192,6 +196,18 @@ void GCodeViewer::COG::render() glsafe(::glDisable(GL_DEPTH_TEST)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + Transform3d matrix = camera.get_view_matrix() * Geometry::assemble_transform(cog()); + if (m_fixed_size) { + const double inv_zoom = wxGetApp().plater()->get_camera().get_inv_zoom(); + matrix = matrix * Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), inv_zoom * Vec3d::Ones()); + } + shader->set_uniform("view_model_matrix", matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); + m_model.render(); +#else glsafe(::glPushMatrix()); const Vec3d position = cog(); glsafe(::glTranslated(position.x(), position.y(), position.z())); @@ -200,8 +216,8 @@ void GCodeViewer::COG::render() glsafe(::glScaled(inv_zoom, inv_zoom, inv_zoom)); } m_model.render(); - glsafe(::glPopMatrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES shader->stop_using(); @@ -297,11 +313,11 @@ void GCodeViewer::SequentialRangeCap::reset() { void GCodeViewer::SequentialView::Marker::init() { m_model.init_from(stilized_arrow(16, 2.0f, 4.0f, 1.0f, 8.0f)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_model.set_color({ 1.0f, 1.0f, 1.0f, 0.5f }); #else m_model.set_color(-1, { 1.0f, 1.0f, 1.0f, 0.5f }); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } void GCodeViewer::SequentialView::Marker::set_world_position(const Vec3f& position) @@ -315,7 +331,11 @@ void GCodeViewer::SequentialView::Marker::render() if (!m_visible) return; +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; @@ -324,13 +344,22 @@ void GCodeViewer::SequentialView::Marker::render() shader->start_using(); shader->set_uniform("emission_factor", 0.0f); - +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d matrix = camera.get_view_matrix() * m_world_transform.cast(); + shader->set_uniform("view_model_matrix", matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else glsafe(::glPushMatrix()); glsafe(::glMultMatrixf(m_world_transform.data())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_model.render(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES shader->stop_using(); @@ -663,7 +692,11 @@ void GCodeViewer::init() #if !DISABLE_GCODEVIEWER_INSTANCED_MODELS if (wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) { buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::InstancedModel; +#if ENABLE_GL_SHADERS_ATTRIBUTES + buffer.shader = "gouraud_light_instanced_attr"; +#else buffer.shader = "gouraud_light_instanced"; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES buffer.model.model.init_from(diamond(16)); buffer.model.color = option_color(type); buffer.model.instances.format = InstanceVBuffer::EFormat::InstancedModel; @@ -672,7 +705,11 @@ void GCodeViewer::init() #endif // !DISABLE_GCODEVIEWER_INSTANCED_MODELS buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::BatchedModel; buffer.vertices.format = VBuffer::EFormat::PositionNormal3; +#if ENABLE_GL_SHADERS_ATTRIBUTES + buffer.shader = "gouraud_light_attr"; +#else buffer.shader = "gouraud_light"; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES buffer.model.data = diamond(16); buffer.model.color = option_color(type); @@ -686,13 +723,22 @@ void GCodeViewer::init() case EMoveType::Extrude: { buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Triangle; buffer.vertices.format = VBuffer::EFormat::PositionNormal3; +#if ENABLE_GL_SHADERS_ATTRIBUTES + buffer.shader = "gouraud_light_attr"; +#else buffer.shader = "gouraud_light"; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES break; } case EMoveType::Travel: { buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Line; +#if ENABLE_GL_SHADERS_ATTRIBUTES + buffer.vertices.format = VBuffer::EFormat::Position; + buffer.shader = "flat_attr"; +#else buffer.vertices.format = VBuffer::EFormat::PositionNormal3; buffer.shader = "toolpaths_lines"; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES break; } } @@ -711,11 +757,11 @@ void GCodeViewer::init() m_gl_data_initialized = true; } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& print) #else void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& print, bool initialized) -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { // avoid processing if called with the same gcode_result #if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC @@ -754,11 +800,11 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr m_filament_densities = gcode_result.filament_densities; if (wxGetApp().is_editor()) -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL load_shells(print); #else load_shells(print, initialized); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL else { Pointfs bed_shape; std::string texture; @@ -1278,11 +1324,21 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) // 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) { +#if !ENABLE_GL_SHADERS_ATTRIBUTES // x component of the normal to the current segment (the normal is parallel to the XY plane) const Vec3f dir = (curr.position - prev.position).normalized(); Vec3f normal(dir.y(), -dir.x(), 0.0); normal.normalize(); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES +#if ENABLE_GL_SHADERS_ATTRIBUTES + auto add_vertex = [&vertices](const GCodeProcessorResult::MoveVertex& vertex) { + // add position + vertices.push_back(vertex.position.x()); + vertices.push_back(vertex.position.y()); + vertices.push_back(vertex.position.z()); + }; +#else auto add_vertex = [&vertices, &normal](const GCodeProcessorResult::MoveVertex& vertex) { // add position vertices.push_back(vertex.position.x()); @@ -1293,6 +1349,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) vertices.push_back(normal.y()); vertices.push_back(normal.z()); }; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES // add previous vertex add_vertex(prev); @@ -1571,7 +1628,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) 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(); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // append vertices const size_t vertices_count = data.vertices_count(); for (size_t i = 0; i < vertices_count; ++i) { @@ -1604,7 +1661,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) vertices.push_back(static_cast(normal.z())); } } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // append instance position instances.push_back(curr.position.x()); @@ -1615,10 +1672,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) }; auto add_indices_as_model_batch = [](const GLModel::Geometry& data, IndexBuffer& indices, IBufferType base_index) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL const size_t indices_count = data.indices_count(); for (size_t i = 0; i < indices_count; ++i) { - indices.push_back(static_cast(data.extract_ushort_index(i) + base_index)); + indices.push_back(static_cast(data.extract_index(i) + base_index)); } #else for (const auto& entity : data.entities) { @@ -1626,7 +1683,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) indices.push_back(static_cast(entity.indices[i] + base_index)); } } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL }; #if ENABLE_GCODE_VIEWER_STATISTICS @@ -2297,11 +2354,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) progress_dialog->Destroy(); } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void GCodeViewer::load_shells(const Print& print) #else void GCodeViewer::load_shells(const Print& print, bool initialized) -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { if (print.objects().empty()) // no shells, return @@ -2318,11 +2375,11 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) } size_t current_volumes_count = m_shells.volumes.volumes.size(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_shells.volumes.load_object(model_obj, object_id, instance_ids); #else m_shells.volumes.load_object(model_obj, object_id, instance_ids, initialized); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // adjust shells' z if raft is present const SlicingParameters& slicing_parameters = obj->slicing_parameters(); @@ -2346,7 +2403,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) const float depth = print.wipe_tower_data(extruders_count).depth; const float brim_width = print.wipe_tower_data(extruders_count).brim_width; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle, !print.is_step_done(psWipeTower), brim_width); @@ -2362,7 +2419,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) m_shells.volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle, !print.is_step_done(psWipeTower), brim_width, initialized); #endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } } @@ -2912,15 +2969,17 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool void GCodeViewer::render_toolpaths() { #if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS - float point_size = 20.0f; + const float point_size = 20.0f; #else - float point_size = 0.8f; + const float point_size = 0.8f; #endif // ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS - std::array light_intensity = { 0.25f, 0.70f, 0.75f, 0.75f }; +#if !ENABLE_GL_SHADERS_ATTRIBUTES + const std::array light_intensity = { 0.25f, 0.70f, 0.75f, 0.75f }; +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES const Camera& camera = wxGetApp().plater()->get_camera(); - double zoom = camera.get_zoom(); + const double zoom = camera.get_zoom(); const std::array& viewport = camera.get_viewport(); - float near_plane_height = camera.get_type() == Camera::EType::Perspective ? static_cast(viewport[3]) / (2.0f * static_cast(2.0 * std::tan(0.5 * Geometry::deg2rad(camera.get_fov())))) : + const float near_plane_height = camera.get_type() == Camera::EType::Perspective ? static_cast(viewport[3]) / (2.0f * static_cast(2.0 * std::tan(0.5 * Geometry::deg2rad(camera.get_fov())))) : static_cast(viewport[3]) * 0.0005; auto shader_init_as_points = [zoom, point_size, near_plane_height](GLShaderProgram& shader) { @@ -2960,9 +3019,11 @@ void GCodeViewer::render_toolpaths() glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); }; - auto shader_init_as_lines = [light_intensity](GLShaderProgram &shader) { +#if !ENABLE_GL_SHADERS_ATTRIBUTES + auto shader_init_as_lines = [light_intensity](GLShaderProgram &shader) { shader.set_uniform("light_intensity", light_intensity); }; +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES auto render_as_lines = [ #if ENABLE_GCODE_VIEWER_STATISTICS this @@ -3013,11 +3074,11 @@ void GCodeViewer::render_toolpaths() } if (range.vbo > 0) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL buffer.model.model.set_color(range.color); #else buffer.model.model.set_color(-1, range.color); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL buffer.model.model.render_instanced(range.vbo, range.count); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_instanced_models_calls_count; @@ -3027,11 +3088,19 @@ void GCodeViewer::render_toolpaths() } }; +#if ENABLE_GL_SHADERS_ATTRIBUTES +#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 +#else #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) { #endif // ENABLE_GCODE_VIEWER_STATISTICS +#endif // ENABLE_GL_SHADERS_ATTRIBUTES struct Range { @@ -3040,30 +3109,44 @@ void GCodeViewer::render_toolpaths() 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(); + const 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 ENABLE_GL_SHADERS_ATTRIBUTES + 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)); + } +#else glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes())); glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - bool has_normals = buffer.vertices.normal_size_floats() > 0; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + const bool has_normals = buffer.vertices.normal_size_floats() > 0; if (has_normals) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + 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)); + } +#else glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } 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 }; + const 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; + 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 @@ -3075,10 +3158,17 @@ void GCodeViewer::render_toolpaths() glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (normal_id != -1) + glsafe(::glDisableVertexAttribArray(normal_id)); + if (position_id != -1) + glsafe(::glDisableVertexAttribArray(position_id)); +#else if (has_normals) glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); buffer_range.first = buffer_range.last; @@ -3089,8 +3179,8 @@ void GCodeViewer::render_toolpaths() return (zoom < 5.0) ? 1.0 : (1.0 + 5.0 * (zoom - 5.0) / (100.0 - 5.0)); }; - unsigned char begin_id = buffer_id(EMoveType::Retract); - unsigned char end_id = buffer_id(EMoveType::Count); + const unsigned char begin_id = buffer_id(EMoveType::Retract); + const unsigned char end_id = buffer_id(EMoveType::Count); for (unsigned char i = begin_id; i < end_id; ++i) { TBuffer& buffer = m_buffers[i]; @@ -3098,77 +3188,121 @@ void GCodeViewer::render_toolpaths() continue; GLShaderProgram* shader = wxGetApp().get_shader(buffer.shader.c_str()); - if (shader != nullptr) { - shader->start_using(); + if (shader == nullptr) + continue; - 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); - shader->set_uniform("emission_factor", 0.0f); - } - else { - switch (buffer.render_primitive_type) { - case TBuffer::ERenderPrimitiveType::Point: shader_init_as_points(*shader); break; - case TBuffer::ERenderPrimitiveType::Line: shader_init_as_lines(*shader); break; - default: break; - } - 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; + shader->start_using(); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); - glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes())); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - bool has_normals = buffer.vertices.normal_size_floats() > 0; - if (has_normals) { - glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - } +#if ENABLE_GL_SHADERS_ATTRIBUTES + int position_id = -1; + int normal_id = -1; + const Transform3d& view_matrix = camera.get_view_matrix(); + shader->set_uniform("view_model_matrix", view_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->set_uniform("normal_matrix", (Matrix3d)view_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); + position_id = shader->get_attrib_location("v_position"); + normal_id = shader->get_attrib_location("v_normal"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES - // Render all elements with it_path->ibuffer_id == ibuffer_id, possible with varying colors. - switch (buffer.render_primitive_type) - { - case TBuffer::ERenderPrimitiveType::Point: { - render_as_points(it_path, buffer.render_paths.end(), *shader, uniform_color); - break; - } - 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 (has_normals) - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - } - } - - shader->stop_using(); + 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); +#if ENABLE_GL_SHADERS_ATTRIBUTES + render_as_batched_model(buffer, *shader, position_id, normal_id); +#else + render_as_batched_model(buffer, *shader); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + shader->set_uniform("emission_factor", 0.0f); + } + else { +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Point) + shader_init_as_points(*shader); +#else + switch (buffer.render_primitive_type) { + case TBuffer::ERenderPrimitiveType::Point: shader_init_as_points(*shader); break; + case TBuffer::ERenderPrimitiveType::Line: shader_init_as_lines(*shader); break; + default: break; + } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + 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; + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + 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)); + } +#else + glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes())); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + const bool has_normals = buffer.vertices.normal_size_floats() > 0; + if (has_normals) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + 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)); + } +#else + glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + } + + 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::Point: { + render_as_points(it_path, buffer.render_paths.end(), *shader, uniform_color); + break; + } + 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 ENABLE_GL_SHADERS_ATTRIBUTES + if (normal_id != -1) + glsafe(::glDisableVertexAttribArray(normal_id)); + if (position_id != -1) + glsafe(::glDisableVertexAttribArray(position_id)); +#else + if (has_normals) + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); + + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + } + } + + shader->stop_using(); } #if ENABLE_GCODE_VIEWER_STATISTICS @@ -3177,37 +3311,74 @@ void GCodeViewer::render_toolpaths() auto render_sequential_range_cap = [] #endif // ENABLE_GCODE_VIEWER_STATISTICS (const SequentialRangeCap& cap) { - GLShaderProgram* shader = wxGetApp().get_shader(cap.buffer->shader.c_str()); - if (shader != nullptr) { - shader->start_using(); + const TBuffer* buffer = cap.buffer; + GLShaderProgram* shader = wxGetApp().get_shader(buffer->shader.c_str()); + if (shader == nullptr) + return; - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, cap.vbo)); - glsafe(::glVertexPointer(cap.buffer->vertices.position_size_floats(), GL_FLOAT, cap.buffer->vertices.vertex_size_bytes(), (const void*)cap.buffer->vertices.position_offset_bytes())); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - bool has_normals = cap.buffer->vertices.normal_size_floats() > 0; - if (has_normals) { - glsafe(::glNormalPointer(GL_FLOAT, cap.buffer->vertices.vertex_size_bytes(), (const void*)cap.buffer->vertices.normal_offset_bytes())); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); + shader->start_using(); + +#if ENABLE_GL_SHADERS_ATTRIBUTES + int position_id = -1; + int normal_id = -1; + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d& view_matrix = camera.get_view_matrix(); + shader->set_uniform("view_model_matrix", view_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->set_uniform("normal_matrix", (Matrix3d)view_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); + + position_id = shader->get_attrib_location("v_position"); + normal_id = shader->get_attrib_location("v_normal"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, cap.vbo)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + 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)); + } +#else + glsafe(::glVertexPointer(buffer->vertices.position_size_floats(), GL_FLOAT, buffer->vertices.vertex_size_bytes(), (const void*)buffer->vertices.position_offset_bytes())); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + const bool has_normals = buffer->vertices.normal_size_floats() > 0; + if (has_normals) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + 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)); } +#else + glsafe(::glNormalPointer(GL_FLOAT, buffer->vertices.vertex_size_bytes(), (const void*)buffer->vertices.normal_offset_bytes())); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + } - shader->set_uniform("uniform_color", cap.color); + 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)); + 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; + ++m_statistics.gl_triangles_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS - if (has_normals) - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (normal_id != -1) + glsafe(::glDisableVertexAttribArray(normal_id)); + if (position_id != -1) + glsafe(::glDisableVertexAttribArray(position_id)); +#else + if (has_normals) + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES - shader->stop_using(); - } + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + + shader->stop_using(); }; for (unsigned int i = 0; i < 2; ++i) { @@ -3221,11 +3392,15 @@ void GCodeViewer::render_shells() if (!m_shells.visible || m_shells.volumes.empty()) return; +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL // when the background processing is enabled, it may happen that the shells data have been loaded // before opengl has been initialized for the preview canvas. // when this happens, the volumes' data have not been sent to gpu yet. @@ -3233,12 +3408,17 @@ void GCodeViewer::render_shells() if (!v->indexed_vertex_array.has_VBOs()) v->finalize_geometry(true); } -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL // glsafe(::glDepthMask(GL_FALSE)); shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, true, camera.get_view_matrix(), camera.get_projection_matrix()); +#else m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, true, wxGetApp().plater()->get_camera().get_view_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES shader->stop_using(); // glsafe(::glDepthMask(GL_TRUE)); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index bdb3ed983..438fc55fd 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -365,11 +365,11 @@ class GCodeViewer } case ERenderPrimitiveType::InstancedModel: { return model.model.is_initialized() && !model.instances.buffer.empty(); } case ERenderPrimitiveType::BatchedModel: { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL return !model.data.vertices.empty() && !model.data.indices.empty() && #else return model.data.vertices_count() > 0 && model.data.indices_count() && -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0; } default: { return false; } @@ -421,11 +421,11 @@ class GCodeViewer const float radius = m_fixed_size ? 10.0f : 1.0f; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_model.init_from(smooth_sphere(32, radius)); #else m_model.init_from(its_make_sphere(radius, PI / 32.0)); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } }; #endif // ENABLE_SHOW_TOOLPATHS_COG @@ -823,11 +823,11 @@ public: void init(); // extract rendering data from the given parameters -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void load(const GCodeProcessorResult& gcode_result, const Print& print); #else void load(const GCodeProcessorResult& gcode_result, const Print& print, bool initialized); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // 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); #if ENABLE_PREVIEW_LAYOUT @@ -887,11 +887,11 @@ public: private: void load_toolpaths(const GCodeProcessorResult& gcode_result); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void load_shells(const Print& print); #else void load_shells(const Print& print, bool initialized); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #if !ENABLE_PREVIEW_LAYOUT void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const; #endif // !ENABLE_PREVIEW_LAYOUT diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 1aca38371..4a42e11c1 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -14,19 +14,16 @@ #include "libslic3r/Technologies.hpp" #include "libslic3r/Tesselate.hpp" #include "libslic3r/PresetBundle.hpp" -#include "slic3r/GUI/3DBed.hpp" -#include "slic3r/GUI/3DScene.hpp" -#include "slic3r/GUI/BackgroundSlicingProcess.hpp" -#include "slic3r/GUI/GLShader.hpp" -#include "slic3r/GUI/GUI.hpp" -#include "slic3r/GUI/Tab.hpp" -#include "slic3r/GUI/GUI_Preview.hpp" -#include "slic3r/GUI/OpenGLManager.hpp" -#include "slic3r/GUI/Plater.hpp" -#include "slic3r/GUI/MainFrame.hpp" -#include "slic3r/Utils/UndoRedo.hpp" -#include "slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp" - +#include "3DBed.hpp" +#include "3DScene.hpp" +#include "BackgroundSlicingProcess.hpp" +#include "GLShader.hpp" +#include "GUI.hpp" +#include "Tab.hpp" +#include "GUI_Preview.hpp" +#include "OpenGLManager.hpp" +#include "Plater.hpp" +#include "MainFrame.hpp" #include "GUI_App.hpp" #include "GUI_ObjectList.hpp" #include "GUI_ObjectManipulation.hpp" @@ -35,6 +32,9 @@ #include "NotificationManager.hpp" #include "format.hpp" +#include "slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp" +#include "slic3r/Utils/UndoRedo.hpp" + #if ENABLE_RETINA_GL #include "slic3r/Utils/RetinaHelper.hpp" #endif @@ -72,7 +72,7 @@ static constexpr const float TRACKBALLSIZE = 0.8f; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL static const Slic3r::ColorRGBA DEFAULT_BG_DARK_COLOR = { 0.478f, 0.478f, 0.478f, 1.0f }; static const Slic3r::ColorRGBA DEFAULT_BG_LIGHT_COLOR = { 0.753f, 0.753f, 0.753f, 1.0f }; static const Slic3r::ColorRGBA ERROR_BG_DARK_COLOR = { 0.478f, 0.192f, 0.039f, 1.0f }; @@ -82,16 +82,16 @@ static const Slic3r::ColorRGB DEFAULT_BG_DARK_COLOR = { 0.478f, 0.478f, 0.478f static const Slic3r::ColorRGB DEFAULT_BG_LIGHT_COLOR = { 0.753f, 0.753f, 0.753f }; static const Slic3r::ColorRGB ERROR_BG_DARK_COLOR = { 0.478f, 0.192f, 0.039f }; static const Slic3r::ColorRGB ERROR_BG_LIGHT_COLOR = { 0.753f, 0.192f, 0.039f }; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // Number of floats static constexpr const size_t MAX_VERTEX_BUFFER_SIZE = 131072 * 6; // 3.15MB // Reserve size in number of floats. -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL static constexpr const size_t VERTEX_BUFFER_RESERVE_SIZE = 131072 * 2; // 1.05MB // Reserve size in number of floats, maximum sum of all preallocated buffers. //static constexpr const size_t VERTEX_BUFFER_RESERVE_SIZE_SUM_MAX = 1024 * 1024 * 128 / 4; // 128MB -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL namespace Slic3r { namespace GUI { @@ -161,7 +161,11 @@ void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id) bool GLCanvas3D::LayersEditing::is_allowed() const { +#if ENABLE_GL_SHADERS_ATTRIBUTES + return wxGetApp().get_shader("variable_layer_height_attr") != nullptr && m_z_texture_id > 0; +#else return wxGetApp().get_shader("variable_layer_height") != nullptr && m_z_texture_id > 0; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } bool GLCanvas3D::LayersEditing::is_enabled() const @@ -263,24 +267,29 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) GLCanvas3D::LayersEditing::s_overlay_window_width = ImGui::GetWindowSize().x /*+ (float)m_layers_texture.width/4*/; imgui.end(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + render_active_object_annotations(canvas); + render_profile(canvas); +#else const Rect& bar_rect = get_bar_rect_viewport(canvas); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_profile.dirty = m_profile.old_bar_rect != bar_rect; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL render_active_object_annotations(canvas, bar_rect); render_profile(bar_rect); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_profile.old_bar_rect = bar_rect; m_profile.dirty = false; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas) { const Vec2d mouse_pos = canvas.get_local_mouse_position(); const Rect& rect = get_bar_rect_screen(canvas); - float x = (float)mouse_pos(0); - float y = (float)mouse_pos(1); + float x = (float)mouse_pos.x(); + float y = (float)mouse_pos.y(); float t = rect.get_top(); float b = rect.get_bottom(); @@ -306,6 +315,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_screen(const GLCanvas3D& canvas) return { w - thickness_bar_width(canvas), 0.0f, w, h }; } +#if !ENABLE_GL_SHADERS_ATTRIBUTES Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) { const Size& cnv_size = canvas.get_canvas_size(); @@ -314,10 +324,15 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); return { (half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom }; } +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES bool GLCanvas3D::LayersEditing::is_initialized() const { +#if ENABLE_GL_SHADERS_ATTRIBUTES + return wxGetApp().get_shader("variable_layer_height_attr") != nullptr; +#else return wxGetApp().get_shader("variable_layer_height") != nullptr; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) const @@ -346,9 +361,25 @@ std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) con return ret; } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas) +#else void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Size cnv_size = canvas.get_canvas_size(); + const float cnv_width = (float)cnv_size.get_width(); + const float cnv_height = (float)cnv_size.get_height(); + if (cnv_width == 0.0f || cnv_height == 0.0f) + return; + + const float cnv_inv_width = 1.0f / cnv_width; + + GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; @@ -359,33 +390,50 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 shader->set_uniform("z_cursor", m_object_max_z * this->get_cursor_z_relative(canvas)); shader->set_uniform("z_cursor_band_width", band_width); shader->set_uniform("object_max_z", m_object_max_z); +#if ENABLE_GL_SHADERS_ATTRIBUTES + shader->set_uniform("view_model_matrix", Transform3d::Identity()); + shader->set_uniform("projection_matrix", Transform3d::Identity()); + shader->set_uniform("normal_matrix", (Matrix3d)Eigen::Matrix3d::Identity()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); // Render the color bar -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (!m_profile.background.is_initialized() || m_profile.old_canvas_width != cnv_width) { + m_profile.old_canvas_width = cnv_width; +#else if (!m_profile.background.is_initialized() || m_profile.dirty) { +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_profile.background.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2 }; init_data.reserve_vertices(4); init_data.reserve_indices(6); // vertices +#if ENABLE_GL_SHADERS_ATTRIBUTES + const float l = 1.0f - 2.0f * THICKNESS_BAR_WIDTH * cnv_inv_width; + const float r = 1.0f; + const float t = 1.0f; + const float b = -1.0f; +#else const float l = bar_rect.get_left(); const float r = bar_rect.get_right(); const float t = bar_rect.get_top(); const float b = bar_rect.get_bottom(); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES init_data.add_vertex(Vec2f(l, b), Vec2f(0.0f, 0.0f)); init_data.add_vertex(Vec2f(r, b), Vec2f(1.0f, 0.0f)); init_data.add_vertex(Vec2f(r, t), Vec2f(1.0f, 1.0f)); init_data.add_vertex(Vec2f(l, t), Vec2f(0.0f, 1.0f)); // indices - init_data.add_ushort_triangle(0, 1, 2); - init_data.add_ushort_triangle(2, 3, 0); + init_data.add_triangle(0, 1, 2); + init_data.add_triangle(2, 3, 0); m_profile.background.init_from(std::move(init_data)); } @@ -404,72 +452,115 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 ::glTexCoord2f(1.0f, 1.0f); ::glVertex2f(r, t); ::glTexCoord2f(0.0f, 1.0f); ::glVertex2f(l, t); glsafe(::glEnd()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); shader->stop_using(); } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void GLCanvas3D::LayersEditing::render_profile(const GLCanvas3D& canvas) +#else void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect) +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { //FIXME show some kind of legend. if (!m_slicing_parameters) return; +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Size cnv_size = canvas.get_canvas_size(); + const float cnv_width = (float)cnv_size.get_width(); + const float cnv_height = (float)cnv_size.get_height(); + if (cnv_width == 0.0f || cnv_height == 0.0f) + return; + + // Make the vertical bar a bit wider so the layer height curve does not touch the edge of the bar region. + const float scale_x = THICKNESS_BAR_WIDTH / float(1.12 * m_slicing_parameters->max_layer_height); + const float scale_y = cnv_height / m_object_max_z; + + const float cnv_inv_width = 1.0f / cnv_width; + const float cnv_inv_height = 1.0f / cnv_height; +#else // Make the vertical bar a bit wider so the layer height curve does not touch the edge of the bar region. const float scale_x = bar_rect.get_width() / float(1.12 * m_slicing_parameters->max_layer_height); const float scale_y = bar_rect.get_height() / m_object_max_z; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // Baseline +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (!m_profile.baseline.is_initialized() || m_profile.old_layer_height_profile != m_layer_height_profile) { +#else if (!m_profile.baseline.is_initialized() || m_profile.dirty) { +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_profile.baseline.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P2 }; init_data.color = ColorRGBA::BLACK(); init_data.reserve_vertices(2); init_data.reserve_indices(2); // vertices +#if ENABLE_GL_SHADERS_ATTRIBUTES + const float axis_x = 2.0f * ((cnv_width - THICKNESS_BAR_WIDTH + float(m_slicing_parameters->layer_height) * scale_x) * cnv_inv_width - 0.5f); + init_data.add_vertex(Vec2f(axis_x, -1.0f)); + init_data.add_vertex(Vec2f(axis_x, 1.0f)); +#else const float x = bar_rect.get_left() + float(m_slicing_parameters->layer_height) * scale_x; init_data.add_vertex(Vec2f(x, bar_rect.get_bottom())); init_data.add_vertex(Vec2f(x, bar_rect.get_top())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES // indices - init_data.add_ushort_line(0, 1); + init_data.add_line(0, 1); m_profile.baseline.init_from(std::move(init_data)); } +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (!m_profile.profile.is_initialized() || m_profile.old_layer_height_profile != m_layer_height_profile) { +#else if (!m_profile.profile.is_initialized() || m_profile.dirty || m_profile.old_layer_height_profile != m_layer_height_profile) { +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_profile.old_layer_height_profile = m_layer_height_profile; m_profile.profile.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::index_type(m_layer_height_profile.size() / 2) }; + init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P2 }; init_data.color = ColorRGBA::BLUE(); init_data.reserve_vertices(m_layer_height_profile.size() / 2); init_data.reserve_indices(m_layer_height_profile.size() / 2); // vertices + indices for (unsigned int i = 0; i < (unsigned int)m_layer_height_profile.size(); i += 2) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + init_data.add_vertex(Vec2f(2.0f * ((cnv_width - THICKNESS_BAR_WIDTH + float(m_layer_height_profile[i + 1]) * scale_x) * cnv_inv_width - 0.5f), + 2.0f * (float(m_layer_height_profile[i]) * scale_y * cnv_inv_height - 0.5))); +#else init_data.add_vertex(Vec2f(bar_rect.get_left() + float(m_layer_height_profile[i + 1]) * scale_x, bar_rect.get_bottom() + float(m_layer_height_profile[i]) * scale_y)); - if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT) - init_data.add_ushort_index((unsigned short)i / 2); - else - init_data.add_uint_index(i / 2); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + init_data.add_index(i / 2); } m_profile.profile.init_from(std::move(init_data)); } +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + shader->set_uniform("view_model_matrix", Transform3d::Identity()); + shader->set_uniform("projection_matrix", Transform3d::Identity()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_profile.baseline.render(); m_profile.profile.render(); shader->stop_using(); @@ -490,7 +581,7 @@ void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect) for (unsigned int i = 0; i < m_layer_height_profile.size(); i += 2) ::glVertex2f(bar_rect.get_left() + (float)m_layer_height_profile[i + 1] * scale_x, bar_rect.get_bottom() + (float)m_layer_height_profile[i] * scale_y); glsafe(::glEnd()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const GLVolumeCollection& volumes) @@ -503,7 +594,11 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G if (current_shader != nullptr) current_shader->stop_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; @@ -517,6 +612,11 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G shader->set_uniform("z_cursor", float(m_object_max_z) * float(this->get_cursor_z_relative(canvas))); shader->set_uniform("z_cursor_band_width", float(this->band_width)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + // Initialize the layer height texture mapping. const GLsizei w = (GLsizei)m_layers_texture.width; const GLsizei h = (GLsizei)m_layers_texture.height; @@ -535,6 +635,12 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G shader->set_uniform("volume_world_matrix", glvolume->world_matrix()); shader->set_uniform("object_max_z", 0.0f); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d view_model_matrix = camera.get_view_matrix() * glvolume->world_matrix(); + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + glvolume->render(); } // Revert back to the previous shader. @@ -882,18 +988,18 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons if (polygons.empty()) return; -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL size_t triangles_count = 0; for (const Polygon& poly : polygons) { triangles_count += poly.points.size() - 2; } const size_t vertices_count = 3 * triangles_count; -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL if (m_render_fill) { GLModel::Geometry fill_data; -#if ENABLE_GLBEGIN_GLEND_REMOVAL - fill_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::UINT }; +#if ENABLE_LEGACY_OPENGL_REMOVAL + fill_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; fill_data.color = { 0.3333f, 0.0f, 0.0f, 0.5f }; // vertices + indices @@ -907,7 +1013,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons fill_data.add_vertex((Vec3f)(v.cast() + 0.0125f * Vec3f::UnitZ())); // add a small positive z to avoid z-fighting ++vertices_counter; if (vertices_counter % 3 == 0) - fill_data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); + fill_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); } } @@ -937,10 +1043,10 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons fill_data.entities.emplace_back(entity); m_fill.init_from(fill_data); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_perimeter.init_from(polygons, 0.025f); // add a small positive z to avoid z-fighting #else GLModel::Geometry perimeter_data; @@ -960,7 +1066,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons } m_perimeter.init_from(perimeter_data); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } void GLCanvas3D::SequentialPrintClearance::render() @@ -968,26 +1074,36 @@ void GLCanvas3D::SequentialPrintClearance::render() const ColorRGBA FILL_COLOR = { 1.0f, 0.0f, 0.0f, 0.5f }; const ColorRGBA NO_FILL_COLOR = { 1.0f, 1.0f, 1.0f, 0.75f }; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #else GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (shader == nullptr) return; shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glDisable(GL_CULL_FACE)); glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_perimeter.set_color(m_render_fill ? FILL_COLOR : NO_FILL_COLOR); #else m_perimeter.set_color(-1, m_render_fill ? FILL_COLOR : NO_FILL_COLOR); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL m_perimeter.render(); m_fill.render(); @@ -1156,7 +1272,7 @@ bool GLCanvas3D::init() glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL // Set antialiasing / multisampling glsafe(::glDisable(GL_LINE_SMOOTH)); glsafe(::glDisable(GL_POLYGON_SMOOTH)); @@ -1186,7 +1302,7 @@ bool GLCanvas3D::init() // A handy trick -- have surface material mirror the color. glsafe(::glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)); glsafe(::glEnable(GL_COLOR_MATERIAL)); -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL if (m_multisample_allowed) glsafe(::glEnable(GL_MULTISAMPLE)); @@ -1194,11 +1310,11 @@ bool GLCanvas3D::init() if (m_main_toolbar.is_enabled()) m_layers_editing.init(); -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL // on linux the gl context is not valid until the canvas is not shown on screen // we defer the geometry finalization of volumes until the first call to render() m_volumes.finalize_geometry(true); -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL if (m_gizmos.is_enabled() && !m_gizmos.init()) std::cout << "Unable to initialize gizmos: please, check that all the required textures are available" << std::endl; @@ -1596,7 +1712,11 @@ void GLCanvas3D::render() _render_gcode(); _render_sla_slices(); _render_selection(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + _render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), true); +#else _render_bed(!camera.is_looking_downward(), true); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES _render_objects(GLVolumeCollection::ERenderType::Transparent); _render_sequential_clearance(); @@ -1803,11 +1923,11 @@ std::vector GLCanvas3D::load_object(const ModelObject& model_object, int ob instance_idxs.emplace_back(i); } } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL return m_volumes.load_object(&model_object, obj_idx, instance_idxs); #else return m_volumes.load_object(&model_object, obj_idx, instance_idxs, m_initialized); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } std::vector GLCanvas3D::load_object(const Model& model, int obj_idx) @@ -2032,11 +2152,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re // Note the index of the loaded volume, so that we can reload the main model GLVolume with the hollowed mesh // later in this function. it->volume_idx = m_volumes.volumes.size(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_volumes.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx); #else m_volumes.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, m_initialized); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL m_volumes.volumes.back()->geometry_id = key.geometry_id; update_object_list = true; } else { @@ -2093,48 +2213,48 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re GLVolume &volume = *m_volumes.volumes[it->volume_idx]; if (! volume.offsets.empty() && state.step[istep].timestamp != volume.offsets.front()) { // The backend either produced a new hollowed mesh, or it invalidated the one that the front end has seen. -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL volume.model.reset(); #else volume.indexed_vertex_array.release_geometry(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (state.step[istep].state == PrintStateBase::DONE) { TriangleMesh mesh = print_object->get_mesh(slaposDrillHoles); assert(! mesh.empty()); mesh.transform(sla_print->sla_trafo(*m_model->objects[volume.object_idx()]).inverse()); #if ENABLE_SMOOTH_NORMALS -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL volume.model.init_from(mesh, true); #else volume.indexed_vertex_array.load_mesh(mesh, true); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #else -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL volume.model.init_from(mesh); #else volume.indexed_vertex_array.load_mesh(mesh); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #endif // ENABLE_SMOOTH_NORMALS } else { // Reload the original volume. #if ENABLE_SMOOTH_NORMALS -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL volume.model.init_from(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh(), true); #else volume.indexed_vertex_array.load_mesh(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh(), true); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #else -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL volume.model.init_from(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh()); #else volume.indexed_vertex_array.load_mesh(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh()); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #endif // ENABLE_SMOOTH_NORMALS } -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL volume.finalize_geometry(true); -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL } //FIXME it is an ugly hack to write the timestamp into the "offsets" field to not have to add another member variable // to the GLVolume. We should refactor GLVolume significantly, so that the GLVolume will not contain member variables @@ -2164,11 +2284,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re for (size_t istep = 0; istep < sla_steps.size(); ++istep) if (!instances[istep].empty()) -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], state.step[istep].timestamp); #else m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], state.step[istep].timestamp, m_initialized); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } // Shift-up all volumes of the object so that it has the right elevation with respect to the print bed @@ -2198,7 +2318,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re float depth = print->wipe_tower_data(extruders_count).depth; float brim_width = print->wipe_tower_data(extruders_count).brim_width; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), @@ -2218,7 +2338,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re 1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), brim_width, m_initialized); #endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (volume_idx_wipe_tower_old != -1) map_glvolume_old_to_new[volume_idx_wipe_tower_old] = volume_idx_wipe_tower_new; } @@ -2278,7 +2398,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re m_dirty = true; } -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL static void reserve_new_volume_finalize_old_volume(GLVolume& vol_new, GLVolume& vol_old, bool gl_initialized, size_t prealloc_size = VERTEX_BUFFER_RESERVE_SIZE) { // Assign the large pre-allocated buffers to the new GLVolume. @@ -2293,15 +2413,15 @@ static void reserve_new_volume_finalize_old_volume(GLVolume& vol_new, GLVolume& // Finalize the old geometry, possibly move data to the graphics card. vol_old.finalize_geometry(gl_initialized); } -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors) { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_gcode_viewer.load(gcode_result, *this->fff_print()); #else m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (wxGetApp().is_editor()) { m_gcode_viewer.update_shells_color_by_extruder(m_config); @@ -4143,8 +4263,12 @@ bool GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) ImGuiWrapper* imgui = wxGetApp().imgui(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + imgui->set_next_window_pos(pos_x, m_undoredo_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f); +#else const float x = pos_x * (float)wxGetApp().plater()->get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width(); imgui->set_next_window_pos(x, m_undoredo_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES std::string title = is_undo ? L("Undo History") : L("Redo History"); imgui->begin(_(title), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); @@ -4183,8 +4307,12 @@ bool GLCanvas3D::_render_search_list(float pos_x) bool action_taken = false; ImGuiWrapper* imgui = wxGetApp().imgui(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + imgui->set_next_window_pos(pos_x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f); +#else const float x = /*pos_x * (float)wxGetApp().plater()->get_camera().get_zoom() + */0.5f * (float)get_canvas_size().get_width(); imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES std::string title = L("Search"); imgui->begin(_(title), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); @@ -4237,9 +4365,13 @@ bool GLCanvas3D::_render_arrange_menu(float pos_x) { ImGuiWrapper *imgui = wxGetApp().imgui(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + imgui->set_next_window_pos(pos_x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f); +#else auto canvas_w = float(get_canvas_size().get_width()); const float x = pos_x * float(wxGetApp().plater()->get_camera().get_zoom()) + 0.5f * canvas_w; imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES imgui->begin(_L("Arrange options"), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); @@ -4364,6 +4496,10 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const camera.zoom_to_box(volumes_box); camera.apply_view_matrix(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d& view_matrix = camera.get_view_matrix(); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + double near_z = -1.0; double far_z = -1.0; @@ -4371,14 +4507,22 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const // extends the near and far z of the frustrum to avoid the bed being clipped // box in eye space - BoundingBoxf3 t_bed_box = m_bed.extended_bounding_box().transformed(camera.get_view_matrix()); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const BoundingBoxf3 t_bed_box = m_bed.extended_bounding_box().transformed(view_matrix); +#else + const BoundingBoxf3 t_bed_box = m_bed.extended_bounding_box().transformed(camera.get_view_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES near_z = -t_bed_box.max.z(); far_z = -t_bed_box.min.z(); } camera.apply_projection(volumes_box, near_z, far_z); +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; @@ -4391,15 +4535,25 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const shader->start_using(); shader->set_uniform("emission_factor", 0.0f); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d& projection_matrix = camera.get_projection_matrix(); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + for (GLVolume* vol : visible_volumes) { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL vol->model.set_color((vol->printable && !vol->is_outside) ? (current_printer_technology() == ptSLA ? vol->color : ColorRGBA::ORANGE()) : ColorRGBA::GRAY()); #else shader->set_uniform("uniform_color", (vol->printable && !vol->is_outside) ? (current_printer_technology() == ptSLA ? vol->color : ColorRGBA::ORANGE()) : ColorRGBA::GRAY()); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // the volume may have been deactivated by an active gizmo - bool is_active = vol->is_active; + const bool is_active = vol->is_active; vol->is_active = true; +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d matrix = view_matrix * vol->world_matrix(); + shader->set_uniform("view_model_matrix", matrix); + shader->set_uniform("projection_matrix", projection_matrix); + shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES vol->render(); vol->is_active = is_active; } @@ -4409,7 +4563,11 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const glsafe(::glDisable(GL_DEPTH_TEST)); if (thumbnail_params.show_bed) +#if ENABLE_GL_SHADERS_ATTRIBUTES + _render_bed(view_matrix, projection_matrix, !camera.is_looking_downward(), false); +#else _render_bed(!camera.is_looking_downward(), false); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES // restore background color if (thumbnail_params.transparent_background) @@ -4670,13 +4828,15 @@ bool GLCanvas3D::_init_main_toolbar() background_data.right = 16; background_data.bottom = 16; - if (!m_main_toolbar.init(background_data)) - { + if (!m_main_toolbar.init(background_data)) { // unable to init the toolbar texture, disable it m_main_toolbar.set_enabled(false); return true; } // init arrow +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (!m_main_toolbar.init_arrow("toolbar_arrow_2.svg")) +#else BackgroundTexture::Metadata arrow_data; arrow_data.filename = "toolbar_arrow.svg"; arrow_data.left = 0; @@ -4684,14 +4844,16 @@ bool GLCanvas3D::_init_main_toolbar() arrow_data.right = 0; arrow_data.bottom = 0; if (!m_main_toolbar.init_arrow(arrow_data)) - { +#endif // ENABLE_GL_SHADERS_ATTRIBUTES BOOST_LOG_TRIVIAL(error) << "Main toolbar failed to load arrow texture."; - } + // m_gizmos is created at constructor, thus we can init arrow here. +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (!m_gizmos.init_arrow("toolbar_arrow_2.svg")) +#else if (!m_gizmos.init_arrow(arrow_data)) - { +#endif // ENABLE_GL_SHADERS_ATTRIBUTES BOOST_LOG_TRIVIAL(error) << "Gizmos manager failed to load arrow texture."; - } // m_main_toolbar.set_layout_type(GLToolbar::Layout::Vertical); m_main_toolbar.set_layout_type(GLToolbar::Layout::Horizontal); @@ -4738,9 +4900,7 @@ bool GLCanvas3D::_init_main_toolbar() item.right.toggable = true; item.right.render_callback = [this](float left, float right, float, float) { if (m_canvas != nullptr) - { _render_arrange_menu(0.5f * (left + right)); - } }; if (!m_main_toolbar.add_item(item)) return false; @@ -4843,8 +5003,7 @@ bool GLCanvas3D::_init_main_toolbar() item.sprite_id = 11; item.left.toggable = true; item.left.render_callback = [this](float left, float right, float, float) { - if (m_canvas != nullptr) - { + if (m_canvas != nullptr) { if (_render_search_list(0.5f * (left + right))) _deactivate_search_toolbar_item(); } @@ -4891,14 +5050,16 @@ bool GLCanvas3D::_init_undoredo_toolbar() background_data.right = 16; background_data.bottom = 16; - if (!m_undoredo_toolbar.init(background_data)) - { + if (!m_undoredo_toolbar.init(background_data)) { // unable to init the toolbar texture, disable it m_undoredo_toolbar.set_enabled(false); return true; } // init arrow +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (!m_undoredo_toolbar.init_arrow("toolbar_arrow_2.svg")) +#else BackgroundTexture::Metadata arrow_data; arrow_data.filename = "toolbar_arrow.svg"; arrow_data.left = 0; @@ -4906,9 +5067,8 @@ bool GLCanvas3D::_init_undoredo_toolbar() arrow_data.right = 0; arrow_data.bottom = 0; if (!m_undoredo_toolbar.init_arrow(arrow_data)) - { +#endif // ENABLE_GL_SHADERS_ATTRIBUTES BOOST_LOG_TRIVIAL(error) << "Undo/Redo toolbar failed to load arrow texture."; - } // m_undoredo_toolbar.set_layout_type(GLToolbar::Layout::Vertical); m_undoredo_toolbar.set_layout_type(GLToolbar::Layout::Horizontal); @@ -4928,8 +5088,7 @@ bool GLCanvas3D::_init_undoredo_toolbar() item.right.toggable = true; item.right.action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; }; item.right.render_callback = [this](float left, float right, float, float) { - if (m_canvas != nullptr) - { + if (m_canvas != nullptr) { if (_render_undo_redo_stack(true, 0.5f * (left + right))) _deactivate_undo_redo_toolbar_items(); } @@ -4948,8 +5107,7 @@ bool GLCanvas3D::_init_undoredo_toolbar() new_additional_tooltip = (boost::format(_utf8(L("Next Undo action: %1%"))) % action).str(); } - if (new_additional_tooltip != curr_additional_tooltip) - { + if (new_additional_tooltip != curr_additional_tooltip) { m_undoredo_toolbar.set_additional_tooltip(id, new_additional_tooltip); set_tooltip(""); } @@ -4966,8 +5124,7 @@ bool GLCanvas3D::_init_undoredo_toolbar() item.left.action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_REDO)); }; item.right.action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; }; item.right.render_callback = [this](float left, float right, float, float) { - if (m_canvas != nullptr) - { + if (m_canvas != nullptr) { if (_render_undo_redo_stack(false, 0.5f * (left + right))) _deactivate_undo_redo_toolbar_items(); } @@ -4986,8 +5143,7 @@ bool GLCanvas3D::_init_undoredo_toolbar() new_additional_tooltip = (boost::format(_utf8(L("Next Redo action: %1%"))) % action).str(); } - if (new_additional_tooltip != curr_additional_tooltip) - { + if (new_additional_tooltip != curr_additional_tooltip) { m_undoredo_toolbar.set_additional_tooltip(id, new_additional_tooltip); set_tooltip(""); } @@ -5131,7 +5287,12 @@ void GLCanvas3D::_picking_pass() if (m_camera_clipping_plane.is_active()) ::glDisable(GL_CLIP_PLANE0); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + _render_bed_for_picking(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward()); +#else _render_bed_for_picking(!wxGetApp().plater()->get_camera().is_looking_downward()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_gizmos.render_current_gizmo_for_picking_pass(); @@ -5187,7 +5348,12 @@ void GLCanvas3D::_rectangular_selection_picking_pass() glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); _render_volumes_for_picking(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + _render_bed_for_picking(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward()); +#else _render_bed_for_picking(!wxGetApp().plater()->get_camera().is_looking_downward()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (m_multisample_allowed) glsafe(::glEnable(GL_MULTISAMPLE)); @@ -5260,23 +5426,25 @@ void GLCanvas3D::_render_background() use_error_color &= m_gcode_viewer.has_data() && !m_gcode_viewer.is_contained_in_bed(); } +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPushMatrix()); glsafe(::glLoadIdentity()); glsafe(::glMatrixMode(GL_PROJECTION)); glsafe(::glPushMatrix()); glsafe(::glLoadIdentity()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES // Draws a bottom to top gradient over the complete screen. glsafe(::glDisable(GL_DEPTH_TEST)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL const ColorRGBA bottom_color = use_error_color ? ERROR_BG_DARK_COLOR : DEFAULT_BG_DARK_COLOR; if (!m_background.is_initialized()) { m_background.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2 }; init_data.reserve_vertices(4); init_data.reserve_indices(6); @@ -5287,18 +5455,21 @@ void GLCanvas3D::_render_background() init_data.add_vertex(Vec2f(-1.0f, 1.0f), Vec2f(0.0f, 1.0f)); // indices - init_data.add_ushort_triangle(0, 1, 2); - init_data.add_ushort_triangle(2, 3, 0); + init_data.add_triangle(0, 1, 2); + init_data.add_triangle(2, 3, 0); m_background.init_from(std::move(init_data)); } +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("background_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("background"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); shader->set_uniform("top_color", use_error_color ? ERROR_BG_LIGHT_COLOR : DEFAULT_BG_LIGHT_COLOR); shader->set_uniform("bottom_color", bottom_color); - m_background.render(); shader->stop_using(); } @@ -5312,16 +5483,22 @@ void GLCanvas3D::_render_background() ::glVertex2f(1.0f, 1.0f); ::glVertex2f(-1.0f, 1.0f); glsafe(::glEnd()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glEnable(GL_DEPTH_TEST)); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); glsafe(::glMatrixMode(GL_MODELVIEW)); glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void GLCanvas3D::_render_bed(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_axes) +#else void GLCanvas3D::_render_bed(bool bottom, bool show_axes) +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { float scale_factor = 1.0; #if ENABLE_RETINA_GL @@ -5335,17 +5512,29 @@ void GLCanvas3D::_render_bed(bool bottom, bool show_axes) && m_gizmos.get_current_type() != GLGizmosManager::Seam && m_gizmos.get_current_type() != GLGizmosManager::MmuSegmentation); +#if ENABLE_GL_SHADERS_ATTRIBUTES + m_bed.render(*this, view_matrix, projection_matrix, bottom, scale_factor, show_axes, show_texture); +#else m_bed.render(*this, bottom, scale_factor, show_axes, show_texture); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void GLCanvas3D::_render_bed_for_picking(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom) +#else void GLCanvas3D::_render_bed_for_picking(bool bottom) +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { float scale_factor = 1.0; #if ENABLE_RETINA_GL scale_factor = m_retina_helper->get_scale_factor(); #endif // ENABLE_RETINA_GL +#if ENABLE_GL_SHADERS_ATTRIBUTES + m_bed.render_for_picking(*this, view_matrix, projection_matrix, bottom, scale_factor); +#else m_bed.render_for_picking(*this, bottom, scale_factor); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type) @@ -5402,7 +5591,11 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type) m_volumes.set_show_non_manifold_edges(!m_gizmos.is_hiding_instances() && m_gizmos.get_current_type() != GLGizmosManager::Simplify); #endif // ENABLE_SHOW_NON_MANIFOLD_EDGES +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("gouraud"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); @@ -5413,18 +5606,33 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type) { if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) { int object_id = m_layers_editing.last_object_id; +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + m_volumes.render(type, false, camera.get_view_matrix(), camera.get_projection_matrix(), [object_id](const GLVolume& volume) { + // Which volume to paint without the layer height profile shader? + return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id); + }); +#else m_volumes.render(type, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) { // Which volume to paint without the layer height profile shader? return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id); }); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES // Let LayersEditing handle rendering of the active object using the layer height profile shader. m_layers_editing.render_volumes(*this, m_volumes); } else { // do not cull backfaces to show broken geometry, if any +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + m_volumes.render(type, m_picking_enabled, camera.get_view_matrix(), camera.get_projection_matrix(), [this](const GLVolume& volume) { + return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); + }); +#else m_volumes.render(type, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this](const GLVolume& volume) { return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); }); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } // In case a painting gizmo is open, it should render the painted triangles @@ -5443,7 +5651,12 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type) } case GLVolumeCollection::ERenderType::Transparent: { +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + m_volumes.render(type, false, camera.get_view_matrix(), camera.get_projection_matrix()); +#else m_volumes.render(type, false, wxGetApp().plater()->get_camera().get_view_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES break; } } @@ -5602,17 +5815,23 @@ void GLCanvas3D::_render_overlays() void GLCanvas3D::_render_volumes_for_picking() const { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // do not cull backfaces to show broken geometry, if any glsafe(::glDisable(GL_CULL_FACE)); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES const Transform3d& view_matrix = wxGetApp().plater()->get_camera().get_view_matrix(); for (size_t type = 0; type < 2; ++ type) { @@ -5623,21 +5842,28 @@ void GLCanvas3D::_render_volumes_for_picking() const // we reserve color = (0,0,0) for occluders (as the printbed) // so we shift volumes' id by 1 to get the proper color const unsigned int id = 1 + volume.second.first; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL volume.first->model.set_color(picking_decode(id)); shader->start_using(); #else glsafe(::glColor4fv(picking_decode(id).data())); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix() * volume.first->world_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES volume.first->render(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } } +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glEnable(GL_CULL_FACE)); } @@ -5663,9 +5889,7 @@ void GLCanvas3D::_render_gizmos_overlay() m_gizmos.render_overlay(); if (m_gizmo_highlighter.m_render_arrow) - { m_gizmos.render_arrow(*this, m_gizmo_highlighter.m_gizmo_type); - } } void GLCanvas3D::_render_main_toolbar() @@ -5673,20 +5897,26 @@ void GLCanvas3D::_render_main_toolbar() if (!m_main_toolbar.is_enabled()) return; - Size cnv_size = get_canvas_size(); - float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); + const Size cnv_size = get_canvas_size(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const float top = 0.5f * (float)cnv_size.get_height(); +#else + const float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); + const float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES - float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar(); - float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; - float left = -0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width) * inv_zoom; + const float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; +#if ENABLE_GL_SHADERS_ATTRIBUTES + const float left = -0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width); +#else + const float left = -0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width) * inv_zoom; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_main_toolbar.set_position(top, left); m_main_toolbar.render(*this); if (m_toolbar_highlighter.m_render_arrow) - { m_main_toolbar.render_arrow(*this, m_toolbar_highlighter.m_toolbar_item); - } } void GLCanvas3D::_render_undoredo_toolbar() @@ -5694,33 +5924,43 @@ void GLCanvas3D::_render_undoredo_toolbar() if (!m_undoredo_toolbar.is_enabled()) return; - Size cnv_size = get_canvas_size(); + const Size cnv_size = get_canvas_size(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const float top = 0.5f * (float)cnv_size.get_height(); +#else float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); - float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; + const float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar(); - float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; - float left = (m_main_toolbar.get_width() - 0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width)) * inv_zoom; + const float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; +#if ENABLE_GL_SHADERS_ATTRIBUTES + const float left = m_main_toolbar.get_width() - 0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width); +#else + const float left = (m_main_toolbar.get_width() - 0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width)) * inv_zoom; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_undoredo_toolbar.set_position(top, left); m_undoredo_toolbar.render(*this); if (m_toolbar_highlighter.m_render_arrow) - { m_undoredo_toolbar.render_arrow(*this, m_toolbar_highlighter.m_toolbar_item); - } } void GLCanvas3D::_render_collapse_toolbar() const { GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar(); - Size cnv_size = get_canvas_size(); - float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); + const Size cnv_size = get_canvas_size(); + const float band = m_layers_editing.is_enabled() ? (wxGetApp().imgui()->get_style_scaling() * LayersEditing::THICKNESS_BAR_WIDTH) : 0.0; +#if ENABLE_GL_SHADERS_ATTRIBUTES + const float top = 0.5f * (float)cnv_size.get_height(); + const float left = 0.5f * (float)cnv_size.get_width() - collapse_toolbar.get_width() - band; +#else + const float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); - float band = m_layers_editing.is_enabled() ? (wxGetApp().imgui()->get_style_scaling() * LayersEditing::THICKNESS_BAR_WIDTH) : 0.0; - - float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; - float left = (0.5f * (float)cnv_size.get_width() - (float)collapse_toolbar.get_width() - band) * inv_zoom; + const float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; + const float left = (0.5f * (float)cnv_size.get_width() - (float)collapse_toolbar.get_width() - band) * inv_zoom; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES collapse_toolbar.set_position(top, left); collapse_toolbar.render(*this); @@ -5743,12 +5983,18 @@ void GLCanvas3D::_render_view_toolbar() const view_toolbar.set_icons_size(size); #endif // ENABLE_RETINA_GL - Size cnv_size = get_canvas_size(); + const Size cnv_size = get_canvas_size(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + // places the toolbar on the bottom-left corner of the 3d scene + float top = -0.5f * (float)cnv_size.get_height() + view_toolbar.get_height(); + float left = -0.5f * (float)cnv_size.get_width(); +#else float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); // places the toolbar on the bottom-left corner of the 3d scene float top = (-0.5f * (float)cnv_size.get_height() + view_toolbar.get_height()) * inv_zoom; float left = -0.5f * (float)cnv_size.get_width() * inv_zoom; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES view_toolbar.set_position(top, left); view_toolbar.render(*this); } @@ -5756,54 +6002,59 @@ void GLCanvas3D::_render_view_toolbar() const #if ENABLE_SHOW_CAMERA_TARGET void GLCanvas3D::_render_camera_target() { - static const double half_length = 5.0; + static const float half_length = 5.0f; glsafe(::glDisable(GL_DEPTH_TEST)); glsafe(::glLineWidth(2.0f)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL - const Vec3d& target = wxGetApp().plater()->get_camera().get_target(); - bool target_changed = !m_camera_target.target.isApprox(target); - m_camera_target.target = target; +#if ENABLE_LEGACY_OPENGL_REMOVAL + 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(); for (int i = 0; i < 3; ++i) { if (!m_camera_target.axis[i].is_initialized() || target_changed) { m_camera_target.axis[i].reset(); - GLModel::InitializationData init_data; - GLModel::InitializationData::Entity entity; - entity.type = GLModel::PrimitiveType::Lines; - entity.positions.reserve(2); + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT }; + init_data.color = (i == X) ? ColorRGBA::X() : ((i == Y) ? ColorRGBA::Y() : ColorRGBA::Z()); + init_data.reserve_vertices(2); + init_data.reserve_indices(2); + + // vertices if (i == X) { - entity.positions.emplace_back(target.x() - half_length, target.y(), target.z()); - entity.positions.emplace_back(target.x() + half_length, target.y(), target.z()); + init_data.add_vertex(Vec3f(target.x() - half_length, target.y(), target.z())); + init_data.add_vertex(Vec3f(target.x() + half_length, target.y(), target.z())); } else if (i == Y) { - entity.positions.emplace_back(target.x(), target.y() - half_length, target.z()); - entity.positions.emplace_back(target.x(), target.y() + half_length, target.z()); + init_data.add_vertex(Vec3f(target.x(), target.y() - half_length, target.z())); + init_data.add_vertex(Vec3f(target.x(), target.y() + half_length, target.z())); } else { - entity.positions.emplace_back(target.x(), target.y(), target.z() - half_length); - entity.positions.emplace_back(target.x(), target.y(), target.z() + half_length); - } - entity.normals.reserve(2); - for (size_t j = 0; j < 2; ++j) { - entity.normals.emplace_back(Vec3f::UnitZ()); + init_data.add_vertex(Vec3f(target.x(), target.y(), target.z() - half_length)); + init_data.add_vertex(Vec3f(target.x(), target.y(), target.z() + half_length)); } - entity.indices.reserve(2); - entity.indices.emplace_back(0); - entity.indices.emplace_back(1); + // indices + init_data.add_ushort_line(0, 1); - init_data.entities.emplace_back(entity); - m_camera_target.axis[i].init_from(init_data); - m_camera_target.axis[i].set_color(-1, (i == X) ? ColorRGBA::X() : (i == Y) ? ColorRGBA::Y() : ColorRGBA::Z()); + m_camera_target.axis[i].init_from(std::move(init_data)); } } +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES for (int i = 0; i < 3; ++i) { m_camera_target.axis[i].render(); } @@ -5825,7 +6076,7 @@ void GLCanvas3D::_render_camera_target() ::glVertex3d(target.x(), target.y(), target.z() - half_length); ::glVertex3d(target.x(), target.y(), target.z() + half_length); glsafe(::glEnd()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } #endif // ENABLE_SHOW_CAMERA_TARGET @@ -5848,40 +6099,40 @@ void GLCanvas3D::_render_sla_slices() if (!obj->is_step_done(slaposSliceSupports)) continue; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL SlaCap::ObjectIdToModelsMap::iterator it_caps_bottom = m_sla_caps[0].triangles.find(i); SlaCap::ObjectIdToModelsMap::iterator it_caps_top = m_sla_caps[1].triangles.find(i); #else SlaCap::ObjectIdToTrianglesMap::iterator it_caps_bottom = m_sla_caps[0].triangles.find(i); SlaCap::ObjectIdToTrianglesMap::iterator it_caps_top = m_sla_caps[1].triangles.find(i); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { if (it_caps_bottom == m_sla_caps[0].triangles.end()) it_caps_bottom = m_sla_caps[0].triangles.emplace(i, SlaCap::Triangles()).first; if (!m_sla_caps[0].matches(clip_min_z)) { m_sla_caps[0].z = clip_min_z; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL it_caps_bottom->second.object.reset(); it_caps_bottom->second.supports.reset(); #else it_caps_bottom->second.object.clear(); it_caps_bottom->second.supports.clear(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } if (it_caps_top == m_sla_caps[1].triangles.end()) it_caps_top = m_sla_caps[1].triangles.emplace(i, SlaCap::Triangles()).first; if (!m_sla_caps[1].matches(clip_max_z)) { m_sla_caps[1].z = clip_max_z; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL it_caps_top->second.object.reset(); it_caps_top->second.supports.reset(); #else it_caps_top->second.object.clear(); it_caps_top->second.supports.clear(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel& bottom_obj_triangles = it_caps_bottom->second.object; GLModel& bottom_sup_triangles = it_caps_bottom->second.supports; GLModel& top_obj_triangles = it_caps_top->second.object; @@ -5891,12 +6142,12 @@ void GLCanvas3D::_render_sla_slices() Pointf3s &bottom_sup_triangles = it_caps_bottom->second.supports; Pointf3s &top_obj_triangles = it_caps_top->second.object; Pointf3s &top_sup_triangles = it_caps_top->second.supports; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL auto init_model = [](GLModel& model, const Pointf3s& triangles, const ColorRGBA& color) { GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::index_type(triangles.size()) }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(triangles.size()); init_data.reserve_indices(triangles.size() / 3); init_data.color = color; @@ -5905,12 +6156,8 @@ void GLCanvas3D::_render_sla_slices() for (const Vec3d& v : triangles) { init_data.add_vertex((Vec3f)v.cast()); ++vertices_count; - if (vertices_count % 3 == 0) { - if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT) - init_data.add_ushort_triangle((unsigned short)vertices_count - 3, (unsigned short)vertices_count - 2, (unsigned short)vertices_count - 1); - else - init_data.add_uint_triangle(vertices_count - 3, vertices_count - 2, vertices_count - 1); - } + if (vertices_count % 3 == 0) + init_data.add_triangle(vertices_count - 3, vertices_count - 2, vertices_count - 1); } if (!init_data.is_empty()) @@ -5922,7 +6169,7 @@ void GLCanvas3D::_render_sla_slices() #else if ((bottom_obj_triangles.empty() || bottom_sup_triangles.empty() || top_obj_triangles.empty() || top_sup_triangles.empty()) && !obj->get_slice_index().empty()) { -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL double layer_height = print->default_object_config().layer_height.value; double initial_layer_height = print->material_config().initial_layer_height.value; bool left_handed = obj->is_left_handed(); @@ -5942,7 +6189,7 @@ void GLCanvas3D::_render_sla_slices() if (slice_low.is_valid()) { const ExPolygons& obj_bottom = slice_low.get_slice(soModel); const ExPolygons& sup_bottom = slice_low.get_slice(soSupport); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // calculate model bottom cap if (!bottom_obj_triangles.is_initialized() && !obj_bottom.empty()) init_model(bottom_obj_triangles, triangulate_expolygons_3d(obj_bottom, clip_min_z - plane_shift_z, !left_handed), { 1.0f, 0.37f, 0.0f, 1.0f }); @@ -5956,13 +6203,13 @@ void GLCanvas3D::_render_sla_slices() // calculate support bottom cap if (bottom_sup_triangles.empty() && !sup_bottom.empty()) bottom_sup_triangles = triangulate_expolygons_3d(sup_bottom, clip_min_z - plane_shift_z, !left_handed); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } if (slice_high.is_valid()) { const ExPolygons& obj_top = slice_high.get_slice(soModel); const ExPolygons& sup_top = slice_high.get_slice(soSupport); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // calculate model top cap if (!top_obj_triangles.is_initialized() && !obj_top.empty()) init_model(top_obj_triangles, triangulate_expolygons_3d(obj_top, clip_max_z + plane_shift_z, left_handed), { 1.0f, 0.37f, 0.0f, 1.0f }); @@ -5976,29 +6223,46 @@ void GLCanvas3D::_render_sla_slices() // calculate support top cap if (top_sup_triangles.empty() && !sup_top.empty()) top_sup_triangles = triangulate_expolygons_3d(sup_top, clip_max_z + plane_shift_z, left_handed); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); for (const SLAPrintObject::Instance& inst : obj->instances()) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d view_model_matrix = camera.get_view_matrix() * + Geometry::assemble_transform(Vec3d(unscale(inst.shift.x()), unscale(inst.shift.y()), 0.0), + inst.rotation * Vec3d::UnitZ(), Vec3d::Ones(), + obj->is_left_handed() ? Vec3d(-1.0f, 1.0f, 1.0f) : Vec3d::Ones()); + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#else glsafe(::glPushMatrix()); glsafe(::glTranslated(unscale(inst.shift.x()), unscale(inst.shift.y()), 0.0)); glsafe(::glRotatef(Geometry::rad2deg(inst.rotation), 0.0f, 0.0f, 1.0f)); if (obj->is_left_handed()) // The polygons are mirrored by X. glsafe(::glScalef(-1.0f, 1.0f, 1.0f)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES bottom_obj_triangles.render(); top_obj_triangles.render(); bottom_sup_triangles.render(); top_sup_triangles.render(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } shader->stop_using(); @@ -6035,7 +6299,7 @@ void GLCanvas3D::_render_sla_slices() glsafe(::glPopMatrix()); } } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } } @@ -6219,16 +6483,16 @@ void GLCanvas3D::_load_print_toolpaths(const BuildVolume &build_volume) skirt_height = std::min(skirt_height, print_zs.size()); print_zs.erase(print_zs.begin() + skirt_height, print_zs.end()); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLVolume* volume = m_volumes.new_toolpath_volume(color); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; #else GLVolume *volume = m_volumes.new_toolpath_volume(color, VERTEX_BUFFER_RESERVE_SIZE); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL for (size_t i = 0; i < skirt_height; ++ i) { volume->print_zs.emplace_back(print_zs[i]); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL volume->offsets.emplace_back(init_data.indices_count()); if (i == 0) _3DScene::extrusionentity_to_verts(print->brim(), print_zs[i], Point(0, 0), init_data); @@ -6239,28 +6503,28 @@ void GLCanvas3D::_load_print_toolpaths(const BuildVolume &build_volume) if (i == 0) _3DScene::extrusionentity_to_verts(print->brim(), print_zs[i], Point(0, 0), *volume); _3DScene::extrusionentity_to_verts(print->skirt(), print_zs[i], Point(0, 0), *volume); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // Ensure that no volume grows over the limits. If the volume is too large, allocate a new one. -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (init_data.vertices_size_bytes() > MAX_VERTEX_BUFFER_SIZE) { volume->model.init_from(std::move(init_data)); #else if (volume->indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) { -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL GLVolume &vol = *volume; volume = m_volumes.new_toolpath_volume(vol.color); -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL reserve_new_volume_finalize_old_volume(*volume, vol, m_initialized); -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL } } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL volume->model.init_from(std::move(init_data)); volume->is_outside = !contains(build_volume, volume->model); #else volume->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(volume->indexed_vertex_array.vertices_and_normals_interleaved, volume->indexed_vertex_array.bounding_box()); volume->indexed_vertex_array.finalize_geometry(m_initialized); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } 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) @@ -6432,11 +6696,11 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c // Allocate the volume before locking. GLVolume *volume = new GLVolume(color); volume->is_extrusion_path = true; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // to prevent sending data to gpu (in the main thread) while // editing the model geometry volume->model.disable_render(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL 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); @@ -6449,7 +6713,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c tbb::blocked_range(0, ctxt.layers.size(), grain_size), [&ctxt, &new_volume, is_selected_separate_extruder, this](const tbb::blocked_range& range) { GLVolumePtrs vols; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL 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() ? @@ -6468,32 +6732,32 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c feature ]; }; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL 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))); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL geometries.emplace_back(GLModel::Geometry()); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } } else { vols = { new_volume(ctxt.color_perimeters()), new_volume(ctxt.color_infill()), new_volume(ctxt.color_support()) }; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL geometries = { GLModel::Geometry(), GLModel::Geometry(), GLModel::Geometry() }; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL assert(vols.size() == geometries.size()); for (GLModel::Geometry& g : geometries) { - g.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT }; + g.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; } #else for (GLVolume *vol : vols) // Reserving number of vertices (3x position + 3x color) vol->indexed_vertex_array.reserve(VERTEX_BUFFER_RESERVE_SIZE / 6); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) { const Layer *layer = ctxt.layers[idx_layer]; @@ -6514,7 +6778,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c continue; } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL 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) { @@ -6529,7 +6793,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c vol->offsets.emplace_back(vol->indexed_vertex_array.quad_indices.size()); vol->offsets.emplace_back(vol->indexed_vertex_array.triangle_indices.size()); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL for (const PrintInstance &instance : *ctxt.shifted_copies) { const Point © = instance.shift; @@ -6542,19 +6806,19 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c continue; } if (ctxt.has_perimeters) -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL _3DScene::extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy, select_geometry(idx_layer, layerm->region().config().perimeter_extruder.value, 0)); #else _3DScene::extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy, volume(idx_layer, layerm->region().config().perimeter_extruder.value, 0)); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL 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()) -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL _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_extruder : @@ -6566,7 +6830,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c layerm->region().config().solid_infill_extruder : layerm->region().config().infill_extruder, 1)); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } } } @@ -6574,7 +6838,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c const SupportLayer *support_layer = dynamic_cast(layer); if (support_layer) { for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities) -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL _3DScene::extrusionentity_to_verts(extrusion_entity, float(layer->print_z), copy, select_geometry(idx_layer, (extrusion_entity->role() == erSupportMaterial) ? support_layer->object()->config().support_material_extruder : @@ -6586,28 +6850,28 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c support_layer->object()->config().support_material_extruder : support_layer->object()->config().support_material_interface_extruder, 2)); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } } } // 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 ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (geometries[i].vertices_size_bytes() > MAX_VERTEX_BUFFER_SIZE) { vol.model.init_from(std::move(geometries[i])); #else if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) { -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL vols[i] = new_volume(vol.color); -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL reserve_new_volume_finalize_old_volume(*vols[i], vol, false); -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL } } } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL for (size_t i = 0; i < vols.size(); ++i) { if (!geometries[i].is_empty()) vols[i]->model.init_from(std::move(geometries[i])); @@ -6617,7 +6881,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c // Ideally one would call vol->indexed_vertex_array.finalize() here to move the buffers to the OpenGL driver, // but this code runs in parallel and the OpenGL driver is not thread safe. vol->indexed_vertex_array.shrink_to_fit(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL }); BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info(); @@ -6632,14 +6896,14 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c } for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) { GLVolume* v = m_volumes.volumes[i]; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL 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(); #else v->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(v->indexed_vertex_array.vertices_and_normals_interleaved, v->indexed_vertex_array.bounding_box()); v->indexed_vertex_array.finalize_geometry(m_initialized); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info(); @@ -6704,11 +6968,11 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con auto new_volume = [this, &new_volume_mutex](const ColorRGBA& color) { auto *volume = new GLVolume(color); volume->is_extrusion_path = true; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // to prevent sending data to gpu (in the main thread) while // editing the model geometry volume->model.disable_render(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL tbb::spin_mutex::scoped_lock lock; lock.acquire(new_volume_mutex); m_volumes.volumes.emplace_back(volume); @@ -6722,46 +6986,46 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con [&ctxt, &new_volume](const tbb::blocked_range& range) { // Bounding box of this slab of a wipe tower. GLVolumePtrs vols; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL std::vector geometries; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (ctxt.color_by_tool()) { for (size_t i = 0; i < ctxt.number_tools(); ++i) { vols.emplace_back(new_volume(ctxt.color_tool(i))); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL geometries.emplace_back(GLModel::Geometry()); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } } else { vols = { new_volume(ctxt.color_support()) }; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL geometries = { GLModel::Geometry() }; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL assert(vols.size() == geometries.size()); for (GLModel::Geometry& g : geometries) { - g.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT }; + g.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; } #else for (GLVolume *volume : vols) // Reserving number of vertices (3x position + 3x color) volume->indexed_vertex_array.reserve(VERTEX_BUFFER_RESERVE_SIZE / 6); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL 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); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL vol.offsets.emplace_back(geometries[i].indices_count()); #else vol.offsets.emplace_back(vol.indexed_vertex_array.quad_indices.size()); vol.offsets.emplace_back(vol.indexed_vertex_array.triangle_indices.size()); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } } for (const WipeTower::ToolChangeResult &extrusions : layer) { @@ -6804,32 +7068,32 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con e_prev = e; } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL _3DScene::thick_lines_to_verts(lines, widths, heights, lines.front().a == lines.back().b, extrusions.print_z, geometries[ctxt.volume_idx(e.tool, 0)]); #else _3DScene::thick_lines_to_verts(lines, widths, heights, lines.front().a == lines.back().b, extrusions.print_z, *vols[ctxt.volume_idx(e.tool, 0)]); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } } } for (size_t i = 0; i < vols.size(); ++i) { GLVolume &vol = *vols[i]; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (geometries[i].vertices_size_bytes() > MAX_VERTEX_BUFFER_SIZE) { vol.model.init_from(std::move(geometries[i])); #else if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) { -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL vols[i] = new_volume(vol.color); -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL reserve_new_volume_finalize_old_volume(*vols[i], vol, false); -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL } } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL for (size_t i = 0; i < vols.size(); ++i) { if (!geometries[i].is_empty()) vols[i]->model.init_from(std::move(geometries[i])); @@ -6837,7 +7101,7 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con #else for (GLVolume *vol : vols) vol->indexed_vertex_array.shrink_to_fit(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL }); BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info(); @@ -6852,14 +7116,14 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con } for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) { GLVolume* v = m_volumes.volumes[i]; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL 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(); #else v->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(v->indexed_vertex_array.vertices_and_normals_interleaved, v->indexed_vertex_array.bounding_box()); v->indexed_vertex_array.finalize_geometry(m_initialized); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info(); @@ -6883,21 +7147,21 @@ void GLCanvas3D::_load_sla_shells() m_volumes.volumes.emplace_back(new GLVolume(color)); GLVolume& v = *m_volumes.volumes.back(); #if ENABLE_SMOOTH_NORMALS -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL v.model.init_from(mesh, true); #else v.indexed_vertex_array.load_mesh(mesh, true); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #else -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL v.model.init_from(mesh); #else v.indexed_vertex_array.load_mesh(mesh); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #endif // ENABLE_SMOOTH_NORMALS -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL v.indexed_vertex_array.finalize_geometry(m_initialized); -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL v.shader_outside_printer_detection_enabled = outside_printer_detection_enabled; v.composite_id.volume_id = volume_id; v.set_instance_offset(unscale(instance.shift.x(), instance.shift.y(), 0.0)); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 48fef5611..09659faea 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -239,18 +239,24 @@ class GLCanvas3D int last_object_id{ -1 }; float last_z{ 0.0f }; LayerHeightEditActionType last_action{ LAYER_HEIGHT_EDIT_ACTION_INCREASE }; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL struct Profile { GLModel baseline; GLModel profile; GLModel background; +#if ENABLE_GL_SHADERS_ATTRIBUTES + float old_canvas_width{ 0.0f }; +#else Rect old_bar_rect; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES std::vector old_layer_height_profile; +#if !ENABLE_GL_SHADERS_ATTRIBUTES bool dirty{ false }; +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES }; Profile m_profile; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL LayersEditing() = default; ~LayersEditing(); @@ -277,7 +283,9 @@ class GLCanvas3D static float get_cursor_z_relative(const GLCanvas3D& canvas); static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y); static Rect get_bar_rect_screen(const GLCanvas3D& canvas); +#if !ENABLE_GL_SHADERS_ATTRIBUTES static Rect get_bar_rect_viewport(const GLCanvas3D& canvas); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES static float get_overlay_window_width() { return LayersEditing::s_overlay_window_width; } float object_max_z() const { return m_object_max_z; } @@ -287,8 +295,13 @@ class GLCanvas3D private: bool is_initialized() const; void generate_layer_height_texture(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + void render_active_object_annotations(const GLCanvas3D& canvas); + void render_profile(const GLCanvas3D& canvas); +#else void render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect); void render_profile(const Rect& bar_rect); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES void update_slicing_parameters(); static float thickness_bar_width(const GLCanvas3D &canvas); @@ -335,7 +348,7 @@ class GLCanvas3D struct SlaCap { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL struct Triangles { GLModel object; @@ -353,7 +366,7 @@ class GLCanvas3D typedef std::map ObjectIdToTrianglesMap; double z; ObjectIdToTrianglesMap triangles; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL SlaCap() { reset(); } void reset() { z = DBL_MAX; triangles.clear(); } @@ -620,7 +633,7 @@ private: } m_gizmo_highlighter; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_SHOW_CAMERA_TARGET struct CameraTarget { @@ -631,7 +644,7 @@ private: CameraTarget m_camera_target; #endif // ENABLE_SHOW_CAMERA_TARGET GLModel m_background; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL public: explicit GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed); @@ -940,8 +953,13 @@ private: void _picking_pass(); void _rectangular_selection_picking_pass(); void _render_background(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + void _render_bed(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_axes); + void _render_bed_for_picking(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom); +#else void _render_bed(bool bottom, bool show_axes); void _render_bed_for_picking(bool bottom); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES void _render_objects(GLVolumeCollection::ERenderType type); void _render_gcode(); #if ENABLE_SHOW_TOOLPATHS_COG diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index f0eac9a24..af650875b 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -8,28 +8,28 @@ #include "libslic3r/TriangleMesh.hpp" #include "libslic3r/Model.hpp" #include "libslic3r/Polygon.hpp" -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #include "libslic3r/BuildVolume.hpp" #include "libslic3r/Geometry/ConvexHull.hpp" -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #include #include -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_SMOOTH_NORMALS #include #include #include #endif // ENABLE_SMOOTH_NORMALS -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #include namespace Slic3r { namespace GUI { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_SMOOTH_NORMALS static void smooth_normals_corner(const TriangleMesh& mesh, std::vector& normals) { @@ -56,19 +56,9 @@ static void smooth_normals_corner(const TriangleMesh& mesh, std::vector::iterator it = vertices.begin() + id * stride; + const size_t stride = vertex_stride_floats(format); + std::vector::const_iterator it = vertices.begin() + id * stride; vertices.erase(it, it + stride); } } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL size_t GLModel::Geometry::vertex_stride_floats(const Format& format) { @@ -402,21 +311,17 @@ size_t GLModel::Geometry::tex_coord_offset_floats(const Format& format) }; } -size_t GLModel::Geometry::index_stride_bytes(const Format& format) +size_t GLModel::Geometry::index_stride_bytes(const Geometry& data) { - switch (format.index_type) + switch (data.index_type) { case EIndexType::UINT: { return sizeof(unsigned int); } case EIndexType::USHORT: { return sizeof(unsigned short); } + case EIndexType::UBYTE: { return sizeof(unsigned char); } default: { assert(false); return 0; } }; } -GLModel::Geometry::EIndexType GLModel::Geometry::index_type(size_t vertices_count) -{ - return (vertices_count < 65536) ? EIndexType::USHORT : EIndexType::UINT; -} - bool GLModel::Geometry::has_position(const Format& format) { switch (format.vertex_layout) @@ -473,15 +378,15 @@ size_t GLModel::Geometry::indices_count() const } return ret; } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void GLModel::init_from(Geometry&& data) #else void GLModel::init_from(const Geometry& data) -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (is_initialized()) { // call reset() if you want to reuse this model assert(false); @@ -541,10 +446,10 @@ void GLModel::init_from(const Geometry& data) send_to_gpu(rdata, vertices, indices); m_render_data.emplace_back(rdata); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_SMOOTH_NORMALS void GLModel::init_from(const TriangleMesh& mesh, bool smooth_normals) { @@ -601,9 +506,9 @@ void GLModel::init_from(const TriangleMesh& mesh) void GLModel::init_from(const indexed_triangle_set& its) #else void GLModel::init_from(const indexed_triangle_set& its, const BoundingBoxf3 &bbox) -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (is_initialized()) { // call reset() if you want to reuse this model assert(false); @@ -616,7 +521,7 @@ void GLModel::init_from(const indexed_triangle_set& its, const BoundingBoxf3 &bb } Geometry& data = m_render_data.geometry; - data.format = { Geometry::EPrimitiveType::Triangles, Geometry::EVertexLayout::P3N3, GLModel::Geometry::index_type(3 * its.indices.size()) }; + data.format = { Geometry::EPrimitiveType::Triangles, Geometry::EVertexLayout::P3N3 }; data.reserve_vertices(3 * its.indices.size()); data.reserve_indices(3 * its.indices.size()); @@ -630,10 +535,7 @@ void GLModel::init_from(const indexed_triangle_set& its, const BoundingBoxf3 &bb data.add_vertex(vertex[j], n); } vertices_counter += 3; - if (data.format.index_type == GLModel::Geometry::EIndexType::USHORT) - data.add_ushort_triangle((unsigned short)vertices_counter - 3, (unsigned short)vertices_counter - 2, (unsigned short)vertices_counter - 1); - else - data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); + data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); } // update bounding box @@ -670,19 +572,19 @@ void GLModel::init_from(const indexed_triangle_set& its, const BoundingBoxf3 &bb send_to_gpu(data, vertices, indices); m_render_data.emplace_back(data); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL void GLModel::init_from(const indexed_triangle_set& its) { init_from(its, bounding_box(its)); } -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL void GLModel::init_from(const Polygons& polygons, float z) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (is_initialized()) { // call reset() if you want to reuse this model assert(false); @@ -695,7 +597,7 @@ void GLModel::init_from(const Polygons& polygons, float z) } Geometry& data = m_render_data.geometry; - data.format = { Geometry::EPrimitiveType::Lines, Geometry::EVertexLayout::P3, Geometry::EIndexType::UINT }; + data.format = { Geometry::EPrimitiveType::Lines, Geometry::EVertexLayout::P3 }; size_t segments_count = 0; for (const Polygon& polygon : polygons) { @@ -714,7 +616,7 @@ void GLModel::init_from(const Polygons& polygons, float z) data.add_vertex(Vec3f(unscale(p0.x()), unscale(p0.y()), z)); data.add_vertex(Vec3f(unscale(p1.x()), unscale(p1.y()), z)); vertices_counter += 2; - data.add_uint_line(vertices_counter - 2, vertices_counter - 1); + data.add_line(vertices_counter - 2, vertices_counter - 1); } } @@ -746,7 +648,7 @@ void GLModel::init_from(const Polygons& polygons, float z) append_polygon(polygon, z, init_data); } init_from(init_data); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } bool GLModel::init_from_file(const std::string& filename) @@ -765,19 +667,19 @@ bool GLModel::init_from_file(const std::string& filename) return false; } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL init_from(model.mesh()); #else const TriangleMesh& mesh = model.mesh(); init_from(mesh.its, mesh.bounding_box()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL m_filename = filename; return true; } -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL void GLModel::set_color(int entity_id, const ColorRGBA& color) { for (size_t i = 0; i < m_render_data.size(); ++i) { @@ -791,11 +693,11 @@ ColorRGBA GLModel::get_color(size_t entity_id) const if (entity_id < 0 || entity_id >= m_render_data.size()) return ColorRGBA{}; return m_render_data[entity_id].color; } -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL void GLModel::reset() { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // release gpu memory if (m_render_data.ibo_id > 0) { glsafe(::glDeleteBuffers(1, &m_render_data.ibo_id)); @@ -809,7 +711,7 @@ void GLModel::reset() m_render_data.vertices_count = 0; m_render_data.indices_count = 0; m_render_data.geometry.vertices = std::vector(); - m_render_data.geometry.indices = std::vector(); + m_render_data.geometry.indices = std::vector(); #else for (RenderData& data : m_render_data) { // release gpu memory @@ -820,12 +722,12 @@ void GLModel::reset() } m_render_data.clear(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL m_bounding_box = BoundingBoxf3(); m_filename = std::string(); } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL static GLenum get_primitive_mode(const GLModel::Geometry::Format& format) { switch (format.type) @@ -841,76 +743,27 @@ static GLenum get_primitive_mode(const GLModel::Geometry::Format& format) } } -static GLenum get_index_type(const GLModel::Geometry::Format& format) +static GLenum get_index_type(const GLModel::Geometry& data) { - switch (format.index_type) + switch (data.index_type) { default: case GLModel::Geometry::EIndexType::UINT: { return GL_UNSIGNED_INT; } case GLModel::Geometry::EIndexType::USHORT: { return GL_UNSIGNED_SHORT; } + case GLModel::Geometry::EIndexType::UBYTE: { return GL_UNSIGNED_BYTE; } } } void GLModel::render() #else void GLModel::render() const -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL render(std::make_pair(0, indices_count())); #else GLShaderProgram* shader = wxGetApp().get_current_shader(); -#if ENABLE_GLBEGIN_GLEND_REMOVAL - if (shader == nullptr) - return; - - // sends data to gpu if not done yet - if (m_render_data.vbo_id == 0 || m_render_data.ibo_id == 0) { - if (m_render_data.geometry.vertices_count() > 0 && m_render_data.geometry.indices_count() > 0 && !send_to_gpu()) - return; - } - - const Geometry& data = m_render_data.geometry; - - const GLenum mode = get_primitive_mode(data.format); - const GLenum index_type = get_index_type(data.format); - - const size_t vertex_stride_bytes = Geometry::vertex_stride_bytes(data.format); - const bool position = Geometry::has_position(data.format); - const bool normal = Geometry::has_normal(data.format); - const bool tex_coord = Geometry::has_tex_coord(data.format); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id)); - - if (position) { - glsafe(::glVertexPointer(Geometry::position_stride_floats(data.format), GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::position_offset_bytes(data.format))); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - } - if (normal) { - glsafe(::glNormalPointer(GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::normal_offset_bytes(data.format))); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - } - if (tex_coord) { - glsafe(::glTexCoordPointer(Geometry::tex_coord_stride_floats(data.format), GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::tex_coord_offset_bytes(data.format))); - glsafe(::glEnableClientState(GL_TEXTURE_COORD_ARRAY)); - } - - shader->set_uniform("uniform_color", data.color); - - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_render_data.ibo_id)); - glsafe(::glDrawElements(mode, indices_count(), index_type, nullptr)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - - if (tex_coord) - glsafe(::glDisableClientState(GL_TEXTURE_COORD_ARRAY)); - if (normal) - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - if (position) - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); -#else for (const RenderData& data : m_render_data) { if (data.vbo_id == 0 || data.ibo_id == 0) continue; @@ -946,11 +799,10 @@ void GLModel::render() const glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void GLModel::render(const std::pair& range) { if (m_render_disabled) @@ -960,7 +812,6 @@ void GLModel::render(const std::pair& range) return; GLShaderProgram* shader = wxGetApp().get_current_shader(); - if (shader == nullptr) return; @@ -973,7 +824,7 @@ void GLModel::render(const std::pair& range) const Geometry& data = m_render_data.geometry; const GLenum mode = get_primitive_mode(data.format); - const GLenum index_type = get_index_type(data.format); + const GLenum index_type = get_index_type(data); const size_t vertex_stride_bytes = Geometry::vertex_stride_bytes(data.format); const bool position = Geometry::has_position(data.format); @@ -982,59 +833,102 @@ void GLModel::render(const std::pair& range) glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + int position_id = -1; + int normal_id = -1; + int tex_coord_id = -1; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + if (position) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + position_id = shader->get_attrib_location("v_position"); + if (position_id != -1) { + glsafe(::glVertexAttribPointer(position_id, Geometry::position_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::position_offset_bytes(data.format))); + glsafe(::glEnableVertexAttribArray(position_id)); + } +#else glsafe(::glVertexPointer(Geometry::position_stride_floats(data.format), GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::position_offset_bytes(data.format))); glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } if (normal) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + normal_id = shader->get_attrib_location("v_normal"); + if (normal_id != -1) { + glsafe(::glVertexAttribPointer(normal_id, Geometry::normal_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::normal_offset_bytes(data.format))); + glsafe(::glEnableVertexAttribArray(normal_id)); + } +#else glsafe(::glNormalPointer(GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::normal_offset_bytes(data.format))); glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } if (tex_coord) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + tex_coord_id = shader->get_attrib_location("v_tex_coord"); + if (tex_coord_id != -1) { + glsafe(::glVertexAttribPointer(tex_coord_id, Geometry::tex_coord_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::tex_coord_offset_bytes(data.format))); + glsafe(::glEnableVertexAttribArray(tex_coord_id)); + } +#else glsafe(::glTexCoordPointer(Geometry::tex_coord_stride_floats(data.format), GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::tex_coord_offset_bytes(data.format))); glsafe(::glEnableClientState(GL_TEXTURE_COORD_ARRAY)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } shader->set_uniform("uniform_color", data.color); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_render_data.ibo_id)); - glsafe(::glDrawElements(mode, range.second - range.first, index_type, (const void*)(range.first * Geometry::index_stride_bytes(data.format)))); + glsafe(::glDrawElements(mode, range.second - range.first, index_type, (const void*)(range.first * Geometry::index_stride_bytes(data)))); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (tex_coord_id != -1) + glsafe(::glDisableVertexAttribArray(tex_coord_id)); + if (normal_id != -1) + glsafe(::glDisableVertexAttribArray(normal_id)); + if (position_id != -1) + glsafe(::glDisableVertexAttribArray(position_id)); +#else if (tex_coord) glsafe(::glDisableClientState(GL_TEXTURE_COORD_ARRAY)); if (normal) glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); if (position) glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instances_count) #else void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instances_count) const -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { if (instances_vbo == 0) return; GLShaderProgram* shader = wxGetApp().get_current_shader(); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (shader == nullptr || !boost::algorithm::iends_with(shader->get_name(), "_instanced_attr")) +#else if (shader == nullptr || !boost::algorithm::iends_with(shader->get_name(), "_instanced")) +#endif // ENABLE_GL_SHADERS_ATTRIBUTES return; // vertex attributes - GLint position_id = shader->get_attrib_location("v_position"); - GLint normal_id = shader->get_attrib_location("v_normal"); + const GLint position_id = shader->get_attrib_location("v_position"); + const GLint normal_id = shader->get_attrib_location("v_normal"); if (position_id == -1 || normal_id == -1) return; // instance attributes - GLint offset_id = shader->get_attrib_location("i_offset"); - GLint scales_id = shader->get_attrib_location("i_scales"); + const GLint offset_id = shader->get_attrib_location("i_offset"); + const GLint scales_id = shader->get_attrib_location("i_scales"); if (offset_id == -1 || scales_id == -1) return; @@ -1054,10 +948,10 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance GLint offset_id = (shader != nullptr) ? shader->get_attrib_location("i_offset") : -1; GLint scales_id = (shader != nullptr) ? shader->get_attrib_location("i_scales") : -1; assert(offset_id != -1 && scales_id != -1); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glBindBuffer(GL_ARRAY_BUFFER, instances_vbo)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glVertexAttribPointer(offset_id, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (GLvoid*)0)); glsafe(::glEnableVertexAttribArray(offset_id)); glsafe(::glVertexAttribDivisor(offset_id, 1)); @@ -1076,13 +970,13 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance glsafe(::glEnableVertexAttribArray(scales_id)); glsafe(::glVertexAttribDivisor(scales_id, 1)); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL const Geometry& data = m_render_data.geometry; - GLenum mode = get_primitive_mode(data.format); - GLenum index_type = get_index_type(data.format); + const GLenum mode = get_primitive_mode(data.format); + const GLenum index_type = get_index_type(data); shader->set_uniform("uniform_color", data.color); @@ -1157,12 +1051,12 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance glsafe(::glDisableVertexAttribArray(scales_id)); if (offset_id != -1) glsafe(::glDisableVertexAttribArray(offset_id)); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL bool GLModel::send_to_gpu() { if (m_render_data.vbo_id > 0 || m_render_data.ibo_id > 0) { @@ -1187,10 +1081,32 @@ bool GLModel::send_to_gpu() // indices glsafe(::glGenBuffers(1, &m_render_data.ibo_id)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_render_data.ibo_id)); - glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.indices_size_bytes(), data.indices.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + if (m_render_data.vertices_count <= 256) { + // convert indices to unsigned char to save gpu memory + std::vector reduced_indices(data.indices.size()); + for (size_t i = 0; i < data.indices.size(); ++i) { + reduced_indices[i] = (unsigned char)data.indices[i]; + } + data.index_type = Geometry::EIndexType::UBYTE; + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, reduced_indices.size() * sizeof(unsigned char), reduced_indices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } + else if (m_render_data.vertices_count <= 65536) { + // convert indices to unsigned short to save gpu memory + std::vector reduced_indices(data.indices.size()); + for (size_t i = 0; i < data.indices.size(); ++i) { + reduced_indices[i] = (unsigned short)data.indices[i]; + } + data.index_type = Geometry::EIndexType::USHORT; + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, reduced_indices.size() * sizeof(unsigned short), reduced_indices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } + else { + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.indices_size_bytes(), data.indices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } m_render_data.indices_count = indices_count(); - data.indices = std::vector(); + data.indices = std::vector(); return true; } @@ -1212,23 +1128,9 @@ void GLModel::send_to_gpu(RenderData& data, const std::vector& vertices, glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GLBEGIN_GLEND_REMOVAL -static void append_vertex(GLModel::Geometry& data, const Vec3f& position, const Vec3f& normal) -{ - data.add_vertex(position, normal); -} - -static void append_triangle(GLModel::Geometry& data, unsigned short v1, unsigned short v2, unsigned short v3) -{ - data.add_ushort_index(v1); - data.add_ushort_index(v2); - data.add_ushort_index(v3); -} -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL - -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL template inline bool all_vertices_inside(const GLModel::Geometry& geometry, Fn fn) { @@ -1282,11 +1184,11 @@ bool contains(const BuildVolume& volume, const GLModel& model, bool ignore_botto return true; } } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL -GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, float tip_height, float stem_radius, float stem_height) +GLModel::Geometry stilized_arrow(unsigned int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height) { -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL auto append_vertex = [](GLModel::Geometry::Entity& entity, const Vec3f& position, const Vec3f& normal) { entity.positions.emplace_back(position); entity.normals.emplace_back(normal); @@ -1296,28 +1198,25 @@ GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, fl entity.indices.emplace_back(v2); entity.indices.emplace_back(v3); }; -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL - resolution = std::max(4, resolution); -#if ENABLE_GLBEGIN_GLEND_REMOVAL - resolution = std::min(10922, resolution); // ensure no unsigned short overflow of indices -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL + resolution = std::max(4, resolution); GLModel::Geometry data; -#if ENABLE_GLBEGIN_GLEND_REMOVAL - data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT }; +#if ENABLE_LEGACY_OPENGL_REMOVAL + data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; data.reserve_vertices(6 * resolution + 2); data.reserve_indices(6 * resolution * 3); #else GLModel::Geometry::Entity entity; entity.type = GLModel::EPrimitiveType::Triangles; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL const float angle_step = 2.0f * float(PI) / float(resolution); std::vector cosines(resolution); std::vector sines(resolution); - for (unsigned short i = 0; i < resolution; ++i) { + for (unsigned int i = 0; i < resolution; ++i) { const float angle = angle_step * float(i); cosines[i] = ::cos(angle); sines[i] = -::sin(angle); @@ -1326,64 +1225,64 @@ GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, fl const float total_height = tip_height + stem_height; // tip vertices/normals -#if ENABLE_GLBEGIN_GLEND_REMOVAL - append_vertex(data, { 0.0f, 0.0f, total_height }, Vec3f::UnitZ()); - for (unsigned short i = 0; i < resolution; ++i) { - append_vertex(data, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f }); +#if ENABLE_LEGACY_OPENGL_REMOVAL + data.add_vertex(Vec3f(0.0f, 0.0f, total_height), (Vec3f)Vec3f::UnitZ()); + for (unsigned int i = 0; i < resolution; ++i) { + data.add_vertex(Vec3f(tip_radius * sines[i], tip_radius * cosines[i], stem_height), Vec3f(sines[i], cosines[i], 0.0f)); } // tip triangles - for (unsigned short i = 0; i < resolution; ++i) { - const unsigned short v3 = (i < resolution - 1) ? i + 2 : 1; - append_triangle(data, 0, i + 1, v3); + for (unsigned int i = 0; i < resolution; ++i) { + const unsigned int v3 = (i < resolution - 1) ? i + 2 : 1; + data.add_triangle(0, i + 1, v3); } // tip cap outer perimeter vertices - for (unsigned short i = 0; i < resolution; ++i) { - append_vertex(data, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, -Vec3f::UnitZ()); + for (unsigned int i = 0; i < resolution; ++i) { + data.add_vertex(Vec3f(tip_radius * sines[i], tip_radius * cosines[i], stem_height), (Vec3f)(-Vec3f::UnitZ())); } // tip cap inner perimeter vertices - for (unsigned short i = 0; i < resolution; ++i) { - append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, -Vec3f::UnitZ()); + for (unsigned int i = 0; i < resolution; ++i) { + data.add_vertex(Vec3f(stem_radius * sines[i], stem_radius * cosines[i], stem_height), (Vec3f)(-Vec3f::UnitZ())); } // tip cap triangles - for (unsigned short i = 0; i < resolution; ++i) { - const unsigned short v2 = (i < resolution - 1) ? i + resolution + 2 : resolution + 1; - const unsigned short v3 = (i < resolution - 1) ? i + 2 * resolution + 2 : 2 * resolution + 1; - append_triangle(data, i + resolution + 1, v3, v2); - append_triangle(data, i + resolution + 1, i + 2 * resolution + 1, v3); + for (unsigned int i = 0; i < resolution; ++i) { + const unsigned int v2 = (i < resolution - 1) ? i + resolution + 2 : resolution + 1; + const unsigned int v3 = (i < resolution - 1) ? i + 2 * resolution + 2 : 2 * resolution + 1; + data.add_triangle(i + resolution + 1, v3, v2); + data.add_triangle(i + resolution + 1, i + 2 * resolution + 1, v3); } // stem bottom vertices - for (unsigned short i = 0; i < resolution; ++i) { - append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f }); + for (unsigned int i = 0; i < resolution; ++i) { + data.add_vertex(Vec3f(stem_radius * sines[i], stem_radius * cosines[i], stem_height), Vec3f(sines[i], cosines[i], 0.0f)); } // stem top vertices - for (unsigned short i = 0; i < resolution; ++i) { - append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, { sines[i], cosines[i], 0.0f }); + for (unsigned int i = 0; i < resolution; ++i) { + data.add_vertex(Vec3f(stem_radius * sines[i], stem_radius * cosines[i], 0.0f), Vec3f(sines[i], cosines[i], 0.0f)); } // stem triangles - for (unsigned short i = 0; i < resolution; ++i) { - const unsigned short v2 = (i < resolution - 1) ? i + 3 * resolution + 2 : 3 * resolution + 1; - const unsigned short v3 = (i < resolution - 1) ? i + 4 * resolution + 2 : 4 * resolution + 1; - append_triangle(data, i + 3 * resolution + 1, v3, v2); - append_triangle(data, i + 3 * resolution + 1, i + 4 * resolution + 1, v3); + for (unsigned int i = 0; i < resolution; ++i) { + const unsigned int v2 = (i < resolution - 1) ? i + 3 * resolution + 2 : 3 * resolution + 1; + const unsigned int v3 = (i < resolution - 1) ? i + 4 * resolution + 2 : 4 * resolution + 1; + data.add_triangle(i + 3 * resolution + 1, v3, v2); + data.add_triangle(i + 3 * resolution + 1, i + 4 * resolution + 1, v3); } // stem cap vertices - append_vertex(data, Vec3f::Zero(), -Vec3f::UnitZ()); - for (unsigned short i = 0; i < resolution; ++i) { - append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, -Vec3f::UnitZ()); + data.add_vertex((Vec3f)Vec3f::Zero(), (Vec3f)(-Vec3f::UnitZ())); + for (unsigned int i = 0; i < resolution; ++i) { + data.add_vertex(Vec3f(stem_radius * sines[i], stem_radius * cosines[i], 0.0f), (Vec3f)(-Vec3f::UnitZ())); } // stem cap triangles - for (unsigned short i = 0; i < resolution; ++i) { - const unsigned short v3 = (i < resolution - 1) ? i + 5 * resolution + 3 : 5 * resolution + 2; - append_triangle(data, 5 * resolution + 1, v3, i + 5 * resolution + 2); + for (unsigned int i = 0; i < resolution; ++i) { + const unsigned int v3 = (i < resolution - 1) ? i + 5 * resolution + 3 : 5 * resolution + 2; + data.add_triangle(5 * resolution + 1, v3, i + 5 * resolution + 2); } #else append_vertex(entity, { 0.0f, 0.0f, total_height }, Vec3f::UnitZ()); @@ -1446,14 +1345,14 @@ GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, fl } data.entities.emplace_back(entity); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL return data; } -GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness) +GLModel::Geometry circular_arrow(unsigned int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness) { -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL auto append_vertex = [](GLModel::Geometry::Entity& entity, const Vec3f& position, const Vec3f& normal) { entity.positions.emplace_back(position); entity.normals.emplace_back(normal); @@ -1463,22 +1362,19 @@ GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float entity.indices.emplace_back(v2); entity.indices.emplace_back(v3); }; -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL - resolution = std::max(2, resolution); -#if ENABLE_GLBEGIN_GLEND_REMOVAL - resolution = std::min(8188, resolution); // ensure no unsigned short overflow of indices -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL + resolution = std::max(2, resolution); GLModel::Geometry data; -#if ENABLE_GLBEGIN_GLEND_REMOVAL - data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT }; +#if ENABLE_LEGACY_OPENGL_REMOVAL + data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; data.reserve_vertices(8 * (resolution + 1) + 30); data.reserve_indices((8 * resolution + 16) * 3); #else GLModel::Geometry::Entity entity; entity.type = GLModel::EPrimitiveType::Triangles; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL const float half_thickness = 0.5f * thickness; const float half_stem_width = 0.5f * stem_width; @@ -1488,149 +1384,149 @@ GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float const float inner_radius = radius - half_stem_width; const float step_angle = 0.5f * float(PI) / float(resolution); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // tip // top face vertices - append_vertex(data, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitZ()); - append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitZ()); - append_vertex(data, { -tip_height, radius, half_thickness }, Vec3f::UnitZ()); - append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, Vec3f::UnitZ()); - append_vertex(data, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitZ()); + data.add_vertex(Vec3f(0.0f, outer_radius, half_thickness), (Vec3f)Vec3f::UnitZ()); + data.add_vertex(Vec3f(0.0f, radius + half_tip_width, half_thickness), (Vec3f)Vec3f::UnitZ()); + data.add_vertex(Vec3f(-tip_height, radius, half_thickness), (Vec3f)Vec3f::UnitZ()); + data.add_vertex(Vec3f(0.0f, radius - half_tip_width, half_thickness), (Vec3f)Vec3f::UnitZ()); + data.add_vertex(Vec3f(0.0f, inner_radius, half_thickness), (Vec3f)Vec3f::UnitZ()); // top face triangles - append_triangle(data, 0, 1, 2); - append_triangle(data, 0, 2, 4); - append_triangle(data, 4, 2, 3); + data.add_triangle(0, 1, 2); + data.add_triangle(0, 2, 4); + data.add_triangle(4, 2, 3); // bottom face vertices - append_vertex(data, { 0.0f, outer_radius, -half_thickness }, -Vec3f::UnitZ()); - append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, -Vec3f::UnitZ()); - append_vertex(data, { -tip_height, radius, -half_thickness }, -Vec3f::UnitZ()); - append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, -Vec3f::UnitZ()); - append_vertex(data, { 0.0f, inner_radius, -half_thickness }, -Vec3f::UnitZ()); + data.add_vertex(Vec3f(0.0f, outer_radius, -half_thickness), (Vec3f)(-Vec3f::UnitZ())); + data.add_vertex(Vec3f(0.0f, radius + half_tip_width, -half_thickness), (Vec3f)(-Vec3f::UnitZ())); + data.add_vertex(Vec3f(-tip_height, radius, -half_thickness), (Vec3f)(-Vec3f::UnitZ())); + data.add_vertex(Vec3f(0.0f, radius - half_tip_width, -half_thickness), (Vec3f)(-Vec3f::UnitZ())); + data.add_vertex(Vec3f(0.0f, inner_radius, -half_thickness), (Vec3f)(-Vec3f::UnitZ())); // bottom face triangles - append_triangle(data, 5, 7, 6); - append_triangle(data, 5, 9, 7); - append_triangle(data, 9, 8, 7); + data.add_triangle(5, 7, 6); + data.add_triangle(5, 9, 7); + data.add_triangle(9, 8, 7); // side faces vertices - append_vertex(data, { 0.0f, outer_radius, -half_thickness }, Vec3f::UnitX()); - append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, Vec3f::UnitX()); - append_vertex(data, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitX()); - append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitX()); + data.add_vertex(Vec3f(0.0f, outer_radius, -half_thickness), (Vec3f)Vec3f::UnitX()); + data.add_vertex(Vec3f(0.0f, radius + half_tip_width, -half_thickness), (Vec3f)Vec3f::UnitX()); + data.add_vertex(Vec3f(0.0f, outer_radius, half_thickness), (Vec3f)Vec3f::UnitX()); + data.add_vertex(Vec3f(0.0f, radius + half_tip_width, half_thickness), (Vec3f)Vec3f::UnitX()); Vec3f normal(-half_tip_width, tip_height, 0.0f); normal.normalize(); - append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, normal); - append_vertex(data, { -tip_height, radius, -half_thickness }, normal); - append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, normal); - append_vertex(data, { -tip_height, radius, half_thickness }, normal); + data.add_vertex(Vec3f(0.0f, radius + half_tip_width, -half_thickness), normal); + data.add_vertex(Vec3f(-tip_height, radius, -half_thickness), normal); + data.add_vertex(Vec3f(0.0f, radius + half_tip_width, half_thickness), normal); + data.add_vertex(Vec3f(-tip_height, radius, half_thickness), normal); normal = { -half_tip_width, -tip_height, 0.0f }; normal.normalize(); - append_vertex(data, { -tip_height, radius, -half_thickness }, normal); - append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, normal); - append_vertex(data, { -tip_height, radius, half_thickness }, normal); - append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, normal); + data.add_vertex(Vec3f(-tip_height, radius, -half_thickness), normal); + data.add_vertex(Vec3f(0.0f, radius - half_tip_width, -half_thickness), normal); + data.add_vertex(Vec3f(-tip_height, radius, half_thickness), normal); + data.add_vertex(Vec3f(0.0f, radius - half_tip_width, half_thickness), normal); - append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, Vec3f::UnitX()); - append_vertex(data, { 0.0f, inner_radius, -half_thickness }, Vec3f::UnitX()); - append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, Vec3f::UnitX()); - append_vertex(data, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitX()); + data.add_vertex(Vec3f(0.0f, radius - half_tip_width, -half_thickness), (Vec3f)Vec3f::UnitX()); + data.add_vertex(Vec3f(0.0f, inner_radius, -half_thickness), (Vec3f)Vec3f::UnitX()); + data.add_vertex(Vec3f(0.0f, radius - half_tip_width, half_thickness), (Vec3f)Vec3f::UnitX()); + data.add_vertex(Vec3f(0.0f, inner_radius, half_thickness), (Vec3f)Vec3f::UnitX()); // side face triangles - for (unsigned short i = 0; i < 4; ++i) { - const unsigned short ii = i * 4; - append_triangle(data, 10 + ii, 11 + ii, 13 + ii); - append_triangle(data, 10 + ii, 13 + ii, 12 + ii); + for (unsigned int i = 0; i < 4; ++i) { + const unsigned int ii = i * 4; + data.add_triangle(10 + ii, 11 + ii, 13 + ii); + data.add_triangle(10 + ii, 13 + ii, 12 + ii); } // stem // top face vertices - for (unsigned short i = 0; i <= resolution; ++i) { + for (unsigned int i = 0; i <= resolution; ++i) { const float angle = float(i) * step_angle; - append_vertex(data, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ()); + data.add_vertex(Vec3f(inner_radius * ::sin(angle), inner_radius * ::cos(angle), half_thickness), (Vec3f)Vec3f::UnitZ()); } - for (unsigned short i = 0; i <= resolution; ++i) { + for (unsigned int i = 0; i <= resolution; ++i) { const float angle = float(i) * step_angle; - append_vertex(data, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ()); + data.add_vertex(Vec3f(outer_radius * ::sin(angle), outer_radius * ::cos(angle), half_thickness), (Vec3f)Vec3f::UnitZ()); } // top face triangles - for (unsigned short i = 0; i < resolution; ++i) { - append_triangle(data, 26 + i, 27 + i, 27 + resolution + i); - append_triangle(data, 27 + i, 28 + resolution + i, 27 + resolution + i); + for (unsigned int i = 0; i < resolution; ++i) { + data.add_triangle(26 + i, 27 + i, 27 + resolution + i); + data.add_triangle(27 + i, 28 + resolution + i, 27 + resolution + i); } // bottom face vertices - for (unsigned short i = 0; i <= resolution; ++i) { + for (unsigned int i = 0; i <= resolution; ++i) { const float angle = float(i) * step_angle; - append_vertex(data, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ()); + data.add_vertex(Vec3f(inner_radius * ::sin(angle), inner_radius * ::cos(angle), -half_thickness), (Vec3f)(-Vec3f::UnitZ())); } - for (unsigned short i = 0; i <= resolution; ++i) { + for (unsigned int i = 0; i <= resolution; ++i) { const float angle = float(i) * step_angle; - append_vertex(data, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ()); + data.add_vertex(Vec3f(outer_radius * ::sin(angle), outer_radius * ::cos(angle), -half_thickness), (Vec3f)(-Vec3f::UnitZ())); } // bottom face triangles - for (unsigned short i = 0; i < resolution; ++i) { - append_triangle(data, 28 + 2 * resolution + i, 29 + 3 * resolution + i, 29 + 2 * resolution + i); - append_triangle(data, 29 + 2 * resolution + i, 29 + 3 * resolution + i, 30 + 3 * resolution + i); + for (unsigned int i = 0; i < resolution; ++i) { + data.add_triangle(28 + 2 * resolution + i, 29 + 3 * resolution + i, 29 + 2 * resolution + i); + data.add_triangle(29 + 2 * resolution + i, 29 + 3 * resolution + i, 30 + 3 * resolution + i); } // side faces vertices and triangles - for (unsigned short i = 0; i <= resolution; ++i) { + for (unsigned int i = 0; i <= resolution; ++i) { const float angle = float(i) * step_angle; const float c = ::cos(angle); const float s = ::sin(angle); - append_vertex(data, { inner_radius * s, inner_radius * c, -half_thickness }, { -s, -c, 0.0f }); + data.add_vertex(Vec3f(inner_radius * s, inner_radius * c, -half_thickness), Vec3f(-s, -c, 0.0f)); } - for (unsigned short i = 0; i <= resolution; ++i) { + for (unsigned int i = 0; i <= resolution; ++i) { const float angle = float(i) * step_angle; const float c = ::cos(angle); const float s = ::sin(angle); - append_vertex(data, { inner_radius * s, inner_radius * c, half_thickness }, { -s, -c, 0.0f }); + data.add_vertex(Vec3f(inner_radius * s, inner_radius * c, half_thickness), Vec3f(-s, -c, 0.0f)); } - unsigned short first_id = 26 + 4 * (resolution + 1); - for (unsigned short i = 0; i < resolution; ++i) { - const unsigned short ii = first_id + i; - append_triangle(data, ii, ii + 1, ii + resolution + 2); - append_triangle(data, ii, ii + resolution + 2, ii + resolution + 1); + unsigned int first_id = 26 + 4 * (resolution + 1); + for (unsigned int i = 0; i < resolution; ++i) { + const unsigned int ii = first_id + i; + data.add_triangle(ii, ii + 1, ii + resolution + 2); + data.add_triangle(ii, ii + resolution + 2, ii + resolution + 1); } - append_vertex(data, { inner_radius, 0.0f, -half_thickness }, -Vec3f::UnitY()); - append_vertex(data, { outer_radius, 0.0f, -half_thickness }, -Vec3f::UnitY()); - append_vertex(data, { inner_radius, 0.0f, half_thickness }, -Vec3f::UnitY()); - append_vertex(data, { outer_radius, 0.0f, half_thickness }, -Vec3f::UnitY()); + data.add_vertex(Vec3f(inner_radius, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitY())); + data.add_vertex(Vec3f(outer_radius, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitY())); + data.add_vertex(Vec3f(inner_radius, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitY())); + data.add_vertex(Vec3f(outer_radius, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitY())); first_id = 26 + 6 * (resolution + 1); - append_triangle(data, first_id, first_id + 1, first_id + 3); - append_triangle(data, first_id, first_id + 3, first_id + 2); + data.add_triangle(first_id, first_id + 1, first_id + 3); + data.add_triangle(first_id, first_id + 3, first_id + 2); - for (short i = resolution; i >= 0; --i) { + for (int i = resolution; i >= 0; --i) { const float angle = float(i) * step_angle; const float c = ::cos(angle); const float s = ::sin(angle); - append_vertex(data, { outer_radius * s, outer_radius * c, -half_thickness }, { s, c, 0.0f }); + data.add_vertex(Vec3f(outer_radius * s, outer_radius * c, -half_thickness), Vec3f(s, c, 0.0f)); } - for (short i = resolution; i >= 0; --i) { + for (int i = resolution; i >= 0; --i) { const float angle = float(i) * step_angle; const float c = ::cos(angle); const float s = ::sin(angle); - append_vertex(data, { outer_radius * s, outer_radius * c, +half_thickness }, { s, c, 0.0f }); + data.add_vertex(Vec3f(outer_radius * s, outer_radius * c, +half_thickness), Vec3f(s, c, 0.0f)); } first_id = 30 + 6 * (resolution + 1); - for (unsigned short i = 0; i < resolution; ++i) { - const unsigned short ii = first_id + i; - append_triangle(data, ii, ii + 1, ii + resolution + 2); - append_triangle(data, ii, ii + resolution + 2, ii + resolution + 1); + for (unsigned int i = 0; i < resolution; ++i) { + const unsigned int ii = first_id + i; + data.add_triangle(ii, ii + 1, ii + resolution + 2); + data.add_triangle(ii, ii + resolution + 2, ii + resolution + 1); } #else // tip @@ -1778,14 +1674,14 @@ GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float } data.entities.emplace_back(entity); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL return data; } GLModel::Geometry straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness) { -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL auto append_vertex = [](GLModel::Geometry::Entity& entity, const Vec3f& position, const Vec3f& normal) { entity.positions.emplace_back(position); entity.normals.emplace_back(normal); @@ -1795,101 +1691,101 @@ GLModel::Geometry straight_arrow(float tip_width, float tip_height, float stem_w entity.indices.emplace_back(v2); entity.indices.emplace_back(v3); }; -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL GLModel::Geometry data; -#if ENABLE_GLBEGIN_GLEND_REMOVAL - data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT }; +#if ENABLE_LEGACY_OPENGL_REMOVAL + data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; data.reserve_vertices(42); data.reserve_indices(72); #else GLModel::Geometry::Entity entity; entity.type = GLModel::EPrimitiveType::Triangles; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL const float half_thickness = 0.5f * thickness; const float half_stem_width = 0.5f * stem_width; const float half_tip_width = 0.5f * tip_width; const float total_height = tip_height + stem_height; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // top face vertices - append_vertex(data, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ()); - append_vertex(data, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ()); - append_vertex(data, { half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ()); - append_vertex(data, { 0.0, total_height, half_thickness }, Vec3f::UnitZ()); - append_vertex(data, { -half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ()); - append_vertex(data, { -half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ()); - append_vertex(data, { -half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ()); + data.add_vertex(Vec3f(half_stem_width, 0.0f, half_thickness), (Vec3f)Vec3f::UnitZ()); + data.add_vertex(Vec3f(half_stem_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitZ()); + data.add_vertex(Vec3f(half_tip_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitZ()); + data.add_vertex(Vec3f(0.0f, total_height, half_thickness), (Vec3f)Vec3f::UnitZ()); + data.add_vertex(Vec3f(-half_tip_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitZ()); + data.add_vertex(Vec3f(-half_stem_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitZ()); + data.add_vertex(Vec3f(-half_stem_width, 0.0f, half_thickness), (Vec3f)Vec3f::UnitZ()); // top face triangles - append_triangle(data, 0, 1, 6); - append_triangle(data, 6, 1, 5); - append_triangle(data, 4, 5, 3); - append_triangle(data, 5, 1, 3); - append_triangle(data, 1, 2, 3); + data.add_triangle(0, 1, 6); + data.add_triangle(6, 1, 5); + data.add_triangle(4, 5, 3); + data.add_triangle(5, 1, 3); + data.add_triangle(1, 2, 3); // bottom face vertices - append_vertex(data, { half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitZ()); - append_vertex(data, { half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); - append_vertex(data, { half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); - append_vertex(data, { 0.0, total_height, -half_thickness }, -Vec3f::UnitZ()); - append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); - append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); - append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitZ()); + data.add_vertex(Vec3f(half_stem_width, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitZ())); + data.add_vertex(Vec3f(half_stem_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitZ())); + data.add_vertex(Vec3f(half_tip_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitZ())); + data.add_vertex(Vec3f(0.0f, total_height, -half_thickness), (Vec3f)(-Vec3f::UnitZ())); + data.add_vertex(Vec3f(-half_tip_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitZ())); + data.add_vertex(Vec3f(-half_stem_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitZ())); + data.add_vertex(Vec3f(-half_stem_width, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitZ())); // bottom face triangles - append_triangle(data, 7, 13, 8); - append_triangle(data, 13, 12, 8); - append_triangle(data, 12, 11, 10); - append_triangle(data, 8, 12, 10); - append_triangle(data, 9, 8, 10); + data.add_triangle(7, 13, 8); + data.add_triangle(13, 12, 8); + data.add_triangle(12, 11, 10); + data.add_triangle(8, 12, 10); + data.add_triangle(9, 8, 10); // side faces vertices - append_vertex(data, { half_stem_width, 0.0, -half_thickness }, Vec3f::UnitX()); - append_vertex(data, { half_stem_width, stem_height, -half_thickness }, Vec3f::UnitX()); - append_vertex(data, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitX()); - append_vertex(data, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitX()); + data.add_vertex(Vec3f(half_stem_width, 0.0f, -half_thickness), (Vec3f)Vec3f::UnitX()); + data.add_vertex(Vec3f(half_stem_width, stem_height, -half_thickness), (Vec3f)Vec3f::UnitX()); + data.add_vertex(Vec3f(half_stem_width, 0.0f, half_thickness), (Vec3f)Vec3f::UnitX()); + data.add_vertex(Vec3f(half_stem_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitX()); - append_vertex(data, { half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitY()); - append_vertex(data, { half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitY()); - append_vertex(data, { half_stem_width, stem_height, half_thickness }, -Vec3f::UnitY()); - append_vertex(data, { half_tip_width, stem_height, half_thickness }, -Vec3f::UnitY()); + data.add_vertex(Vec3f(half_stem_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitY())); + data.add_vertex(Vec3f(half_tip_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitY())); + data.add_vertex(Vec3f(half_stem_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitY())); + data.add_vertex(Vec3f(half_tip_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitY())); Vec3f normal(tip_height, half_tip_width, 0.0f); normal.normalize(); - append_vertex(data, { half_tip_width, stem_height, -half_thickness }, normal); - append_vertex(data, { 0.0, total_height, -half_thickness }, normal); - append_vertex(data, { half_tip_width, stem_height, half_thickness }, normal); - append_vertex(data, { 0.0, total_height, half_thickness }, normal); + data.add_vertex(Vec3f(half_tip_width, stem_height, -half_thickness), normal); + data.add_vertex(Vec3f(0.0f, total_height, -half_thickness), normal); + data.add_vertex(Vec3f(half_tip_width, stem_height, half_thickness), normal); + data.add_vertex(Vec3f(0.0f, total_height, half_thickness), normal); normal = { -tip_height, half_tip_width, 0.0f }; normal.normalize(); - append_vertex(data, { 0.0, total_height, -half_thickness }, normal); - append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, normal); - append_vertex(data, { 0.0, total_height, half_thickness }, normal); - append_vertex(data, { -half_tip_width, stem_height, half_thickness }, normal); + data.add_vertex(Vec3f(0.0f, total_height, -half_thickness), normal); + data.add_vertex(Vec3f(-half_tip_width, stem_height, -half_thickness), normal); + data.add_vertex(Vec3f(0.0f, total_height, half_thickness), normal); + data.add_vertex(Vec3f(-half_tip_width, stem_height, half_thickness), normal); - append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitY()); - append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitY()); - append_vertex(data, { -half_tip_width, stem_height, half_thickness }, -Vec3f::UnitY()); - append_vertex(data, { -half_stem_width, stem_height, half_thickness }, -Vec3f::UnitY()); + data.add_vertex(Vec3f(-half_tip_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitY())); + data.add_vertex(Vec3f(-half_stem_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitY())); + data.add_vertex(Vec3f(-half_tip_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitY())); + data.add_vertex(Vec3f(-half_stem_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitY())); - append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitX()); - append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitX()); - append_vertex(data, { -half_stem_width, stem_height, half_thickness }, -Vec3f::UnitX()); - append_vertex(data, { -half_stem_width, 0.0, half_thickness }, -Vec3f::UnitX()); + data.add_vertex(Vec3f(-half_stem_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitX())); + data.add_vertex(Vec3f(-half_stem_width, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitX())); + data.add_vertex(Vec3f(-half_stem_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitX())); + data.add_vertex(Vec3f(-half_stem_width, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitX())); - append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitY()); - append_vertex(data, { half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitY()); - append_vertex(data, { -half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY()); - append_vertex(data, { half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY()); + data.add_vertex(Vec3f(-half_stem_width, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitY())); + data.add_vertex(Vec3f(half_stem_width, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitY())); + data.add_vertex(Vec3f(-half_stem_width, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitY())); + data.add_vertex(Vec3f(half_stem_width, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitY())); // side face triangles - for (unsigned short i = 0; i < 7; ++i) { - const unsigned short ii = i * 4; - append_triangle(data, 14 + ii, 15 + ii, 17 + ii); - append_triangle(data, 14 + ii, 17 + ii, 16 + ii); + for (unsigned int i = 0; i < 7; ++i) { + const unsigned int ii = i * 4; + data.add_triangle(14 + ii, 15 + ii, 17 + ii); + data.add_triangle(14 + ii, 17 + ii, 16 + ii); } #else // top face vertices @@ -1972,54 +1868,51 @@ GLModel::Geometry straight_arrow(float tip_width, float tip_height, float stem_w } data.entities.emplace_back(entity); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL return data; } -GLModel::Geometry diamond(unsigned short resolution) +GLModel::Geometry diamond(unsigned int resolution) { - resolution = std::max(4, resolution); -#if ENABLE_GLBEGIN_GLEND_REMOVAL - resolution = std::min(65534, resolution); // ensure no unsigned short overflow of indices -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL + resolution = std::max(4, resolution); GLModel::Geometry data; -#if ENABLE_GLBEGIN_GLEND_REMOVAL - data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT }; +#if ENABLE_LEGACY_OPENGL_REMOVAL + data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; data.reserve_vertices(resolution + 2); data.reserve_indices((2 * (resolution + 1)) * 3); #else GLModel::Geometry::Entity entity; entity.type = GLModel::EPrimitiveType::Triangles; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL const float step = 2.0f * float(PI) / float(resolution); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // vertices - for (unsigned short i = 0; i < resolution; ++i) { + for (unsigned int i = 0; i < resolution; ++i) { const float ii = float(i) * step; const Vec3f p = { 0.5f * ::cos(ii), 0.5f * ::sin(ii), 0.0f }; - append_vertex(data, p, p.normalized()); + data.add_vertex(p, (Vec3f)p.normalized()); } Vec3f p = { 0.0f, 0.0f, 0.5f }; - append_vertex(data, p, p.normalized()); + data.add_vertex(p, (Vec3f)p.normalized()); p = { 0.0f, 0.0f, -0.5f }; - append_vertex(data, p, p.normalized()); + data.add_vertex(p, (Vec3f)p.normalized()); // triangles // top - for (unsigned short i = 0; i < resolution; ++i) { - append_triangle(data, i + 0, i + 1, resolution); + for (unsigned int i = 0; i < resolution; ++i) { + data.add_triangle(i + 0, i + 1, resolution); } - append_triangle(data, resolution - 1, 0, resolution); + data.add_triangle(resolution - 1, 0, resolution); // bottom - for (unsigned short i = 0; i < resolution; ++i) { - append_triangle(data, i + 0, resolution + 1, i + 1); + for (unsigned int i = 0; i < resolution; ++i) { + data.add_triangle(i + 0, resolution + 1, i + 1); } - append_triangle(data, resolution - 1, resolution + 1, 0); + data.add_triangle(resolution - 1, resolution + 1, 0); #else // positions for (int i = 0; i < resolution; ++i) { @@ -2056,31 +1949,30 @@ GLModel::Geometry diamond(unsigned short resolution) entity.indices.push_back(0); data.entities.emplace_back(entity); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL return data; } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_SHOW_TOOLPATHS_COG -GLModel::Geometry smooth_sphere(unsigned short resolution, float radius) +GLModel::Geometry smooth_sphere(unsigned int resolution, float radius) { - resolution = std::max(4, resolution); - resolution = std::min(256, resolution); // ensure no unsigned short overflow of indices + resolution = std::max(4, resolution); - const unsigned short sectorCount = /*2 **/ resolution; - const unsigned short stackCount = resolution; + const unsigned int sectorCount = resolution; + const unsigned int stackCount = resolution; const float sectorStep = float(2.0 * M_PI / sectorCount); const float stackStep = float(M_PI / stackCount); GLModel::Geometry data; - data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT }; + data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; data.reserve_vertices((stackCount - 1) * sectorCount + 2); data.reserve_indices((2 * (stackCount - 1) * sectorCount) * 3); // vertices - for (unsigned short i = 0; i <= stackCount; ++i) { + for (unsigned int i = 0; i <= stackCount; ++i) { // from pi/2 to -pi/2 const double stackAngle = 0.5 * M_PI - stackStep * i; const double xy = double(radius) * ::cos(stackAngle); @@ -2090,7 +1982,7 @@ GLModel::Geometry smooth_sphere(unsigned short resolution, float radius) data.add_vertex(v, (Vec3f)v.normalized()); } else { - for (unsigned short j = 0; j < sectorCount; ++j) { + for (unsigned int j = 0; j < sectorCount; ++j) { // from 0 to 2pi const double sectorAngle = sectorStep * j; const Vec3f v(float(xy * std::cos(sectorAngle)), float(xy * std::sin(sectorAngle)), float(z)); @@ -2100,24 +1992,24 @@ GLModel::Geometry smooth_sphere(unsigned short resolution, float radius) } // triangles - for (unsigned short i = 0; i < stackCount; ++i) { + for (unsigned int i = 0; i < stackCount; ++i) { // Beginning of current stack. - unsigned short k1 = (i == 0) ? 0 : (1 + (i - 1) * sectorCount); - const unsigned short k1_first = k1; + unsigned int k1 = (i == 0) ? 0 : (1 + (i - 1) * sectorCount); + const unsigned int k1_first = k1; // Beginning of next stack. - unsigned short k2 = (i == 0) ? 1 : (k1 + sectorCount); - const unsigned short k2_first = k2; - for (unsigned short j = 0; j < sectorCount; ++j) { + unsigned int k2 = (i == 0) ? 1 : (k1 + sectorCount); + const unsigned int k2_first = k2; + for (unsigned int j = 0; j < sectorCount; ++j) { // 2 triangles per sector excluding first and last stacks - unsigned short k1_next = k1; - unsigned short k2_next = k2; + unsigned int k1_next = k1; + unsigned int k2_next = k2; if (i != 0) { k1_next = (j + 1 == sectorCount) ? k1_first : (k1 + 1); - data.add_ushort_triangle(k1, k2, k1_next); + data.add_triangle(k1, k2, k1_next); } if (i + 1 != stackCount) { k2_next = (j + 1 == sectorCount) ? k2_first : (k2 + 1); - data.add_ushort_triangle(k1_next, k2, k2_next); + data.add_triangle(k1_next, k2, k2_next); } k1 = k1_next; k2 = k2_next; @@ -2127,7 +2019,7 @@ GLModel::Geometry smooth_sphere(unsigned short resolution, float radius) return data; } #endif // ENABLE_SHOW_TOOLPATHS_COG -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index 3b268dab7..e18d04678 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -14,16 +14,16 @@ namespace Slic3r { class TriangleMesh; class Polygon; using Polygons = std::vector; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL class BuildVolume; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL namespace GUI { class GLModel { public: -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL enum class EPrimitiveType : unsigned char { Triangles, @@ -40,11 +40,11 @@ namespace GUI { size_t indices_count{ 0 }; ColorRGBA color; }; -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL struct Geometry { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL enum class EPrimitiveType : unsigned char { Points, @@ -68,23 +68,25 @@ namespace GUI { enum class EIndexType : unsigned char { UINT, // unsigned int - USHORT // unsigned short + USHORT, // unsigned short + UBYTE // unsigned byte }; struct Format { EPrimitiveType type{ EPrimitiveType::Triangles }; EVertexLayout vertex_layout{ EVertexLayout::P3N3 }; - EIndexType index_type{ EIndexType::UINT }; }; Format format; std::vector vertices; - std::vector indices; + std::vector indices; + EIndexType index_type{ EIndexType::UINT }; ColorRGBA color{ ColorRGBA::BLACK() }; - void reserve_vertices(size_t vertices_count); - void reserve_indices(size_t indices_count); + void reserve_vertices(size_t vertices_count) { vertices.reserve(vertices_count * vertex_stride_floats(format)); } + void reserve_indices(size_t indices_count) { indices.reserve(indices_count * index_stride_bytes(*this)); } + void add_vertex(const Vec2f& position); // EVertexLayout::P2 void add_vertex(const Vec2f& position, const Vec2f& tex_coord); // EVertexLayout::P2T2 @@ -92,42 +94,31 @@ namespace GUI { void add_vertex(const Vec3f& position, const Vec2f& tex_coord); // EVertexLayout::P3T2 void add_vertex(const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3 -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL void set_vertex(size_t id, const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3 - void set_ushort_index(size_t id, unsigned short index); - void set_uint_index(size_t id, unsigned int index); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + void set_index(size_t id, unsigned int index); - void add_ushort_index(unsigned short id); - void add_uint_index(unsigned int id); - - void add_ushort_line(unsigned short id1, unsigned short id2); - void add_uint_line(unsigned int id1, unsigned int id2); - - void add_ushort_triangle(unsigned short id1, unsigned short id2, unsigned short id3); - void add_uint_triangle(unsigned int id1, unsigned int id2, unsigned int id3); + void add_index(unsigned int id); + void add_line(unsigned int id1, unsigned int id2); + void add_triangle(unsigned int id1, unsigned int id2, unsigned int id3); Vec2f extract_position_2(size_t id) const; Vec3f extract_position_3(size_t id) const; Vec3f extract_normal_3(size_t id) const; Vec2f extract_tex_coord_2(size_t id) const; - unsigned int extract_uint_index(size_t id) const; - unsigned short extract_ushort_index(size_t id) const; + unsigned int extract_index(size_t id) const; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL void remove_vertex(size_t id); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL bool is_empty() const { return vertices_count() == 0 || indices_count() == 0; } size_t vertices_count() const { return vertices.size() / vertex_stride_floats(format); } - size_t indices_count() const { return indices.size() / index_stride_bytes(format); } + size_t indices_count() const { return indices.size(); } size_t vertices_size_floats() const { return vertices.size(); } size_t vertices_size_bytes() const { return vertices_size_floats() * sizeof(float); } - size_t indices_size_bytes() const { return indices.size(); } + size_t indices_size_bytes() const { return indices.size() * index_stride_bytes(*this); } static size_t vertex_stride_floats(const Format& format); static size_t vertex_stride_bytes(const Format& format) { return vertex_stride_floats(format) * sizeof(float); } @@ -147,9 +138,7 @@ namespace GUI { static size_t tex_coord_offset_floats(const Format& format); static size_t tex_coord_offset_bytes(const Format& format) { return tex_coord_offset_floats(format) * sizeof(float); } - static size_t index_stride_bytes(const Format& format); - - static EIndexType index_type(size_t vertices_count); + static size_t index_stride_bytes(const Geometry& data); static bool has_position(const Format& format); static bool has_normal(const Format& format); @@ -172,10 +161,10 @@ namespace GUI { size_t indices_count() const; size_t indices_size_bytes() const { return indices_count() * sizeof(unsigned int); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL }; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL struct RenderData { Geometry geometry; @@ -184,16 +173,12 @@ namespace GUI { size_t vertices_count{ 0 }; size_t indices_count{ 0 }; }; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL private: -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL RenderData m_render_data; -#else - std::vector m_render_data; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL // By default the vertex and index buffers data are sent to gpu at the first call to render() method. // If you need to initialize a model from outside the main thread, so that a call to render() may happen // before the initialization is complete, use the methods: @@ -202,7 +187,9 @@ namespace GUI { // enable_render() // to keep the data on cpu side until needed. bool m_render_disabled{ false }; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#else + std::vector m_render_data; +#endif // ENABLE_LEGACY_OPENGL_REMOVAL BoundingBoxf3 m_bounding_box; std::string m_filename; @@ -210,7 +197,7 @@ namespace GUI { GLModel() = default; virtual ~GLModel() { reset(); } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL size_t vertices_count() const { return m_render_data.vertices_count > 0 ? m_render_data.vertices_count : m_render_data.geometry.vertices_count(); } size_t indices_count() const { return m_render_data.indices_count > 0 ? @@ -219,11 +206,9 @@ namespace GUI { size_t vertices_size_floats() const { return vertices_count() * Geometry::vertex_stride_floats(m_render_data.geometry.format); } size_t vertices_size_bytes() const { return vertices_size_floats() * sizeof(float); } - size_t indices_size_bytes() const { return indices_count() * Geometry::index_stride_bytes(m_render_data.geometry.format); } + size_t indices_size_bytes() const { return indices_count() * Geometry::index_stride_bytes(m_render_data.geometry); } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL const Geometry& get_geometry() const { return m_render_data.geometry; } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL void init_from(Geometry&& data); #if ENABLE_SMOOTH_NORMALS @@ -234,43 +219,39 @@ namespace GUI { #else void init_from(const Geometry& data); void init_from(const indexed_triangle_set& its, const BoundingBoxf3& bbox); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL void init_from(const indexed_triangle_set& its); void init_from(const Polygons& polygons, float z); bool init_from_file(const std::string& filename); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void set_color(const ColorRGBA& color) { m_render_data.geometry.color = color; } const ColorRGBA& get_color() const { return m_render_data.geometry.color; } #else // if entity_id == -1 set the color of all entities void set_color(int entity_id, const ColorRGBA& color); ColorRGBA get_color(size_t entity_id = 0U) const; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL void reset(); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void render(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL void render(const std::pair& range); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL void render_instanced(unsigned int instances_vbo, unsigned int instances_count); bool is_initialized() const { return vertices_count() > 0 && indices_count() > 0; } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL bool is_empty() const { return m_render_data.geometry.is_empty(); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL #else void render() const; void render_instanced(unsigned int instances_vbo, unsigned int instances_count) const; bool is_initialized() const { return !m_render_data.empty(); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; } const std::string& get_filename() const { return m_filename; } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL bool is_render_disabled() const { return m_render_disabled; } void enable_render() { m_render_disabled = false; } void disable_render() { m_render_disabled = true; } @@ -291,31 +272,31 @@ namespace GUI { ret += indices_size_bytes(); return ret; } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL private: -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL bool send_to_gpu(); #else void send_to_gpu(RenderData& data, const std::vector& vertices, const std::vector& indices); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL }; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL bool contains(const BuildVolume& volume, const GLModel& model, bool ignore_bottom = true); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution // the origin of the arrow is in the center of the stem cap // the arrow has its axis of symmetry along the Z axis and is pointing upward // used to render bed axes and sequential marker - GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, float tip_height, float stem_radius, float stem_height); + GLModel::Geometry stilized_arrow(unsigned int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height); // create an arrow whose stem is a quarter of circle, with the given dimensions and resolution // the origin of the arrow is in the center of the circle // the arrow is contained in the 1st quadrant of the XY plane and is pointing counterclockwise // used to render sidebar hints for rotations - GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness); + GLModel::Geometry circular_arrow(unsigned int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness); // create an arrow with the given dimensions // the origin of the arrow is in the center of the stem cap @@ -326,15 +307,15 @@ namespace GUI { // create a diamond with the given resolution // the origin of the diamond is in its center // the diamond is contained into a box with size [1, 1, 1] - GLModel::Geometry diamond(unsigned short resolution); + GLModel::Geometry diamond(unsigned int resolution); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_SHOW_TOOLPATHS_COG // create a sphere with the given resolution and smooth normals // the origin of the sphere is in its center - GLModel::Geometry smooth_sphere(unsigned short resolution, float radius); + GLModel::Geometry smooth_sphere(unsigned int resolution, float radius); #endif // ENABLE_SHOW_TOOLPATHS_COG -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GLSelectionRectangle.cpp b/src/slic3r/GUI/GLSelectionRectangle.cpp index 8cf3247cb..2563939cf 100644 --- a/src/slic3r/GUI/GLSelectionRectangle.cpp +++ b/src/slic3r/GUI/GLSelectionRectangle.cpp @@ -74,34 +74,49 @@ namespace GUI { if (!is_dragging()) return; - const Camera& camera = wxGetApp().plater()->get_camera(); - float inv_zoom = (float)camera.get_inv_zoom(); + const Size cnv_size = canvas.get_canvas_size(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const float cnv_width = (float)cnv_size.get_width(); + const float cnv_height = (float)cnv_size.get_height(); + if (cnv_width == 0.0f || cnv_height == 0.0f) + return; - Size cnv_size = canvas.get_canvas_size(); - float cnv_half_width = 0.5f * (float)cnv_size.get_width(); - float cnv_half_height = 0.5f * (float)cnv_size.get_height(); + const float cnv_inv_width = 1.0f / cnv_width; + const float cnv_inv_height = 1.0f / cnv_height; + const float left = 2.0f * (get_left() * cnv_inv_width - 0.5f); + const float right = 2.0f * (get_right() * cnv_inv_width - 0.5f); + const float top = -2.0f * (get_top() * cnv_inv_height - 0.5f); + const float bottom = -2.0f * (get_bottom() * cnv_inv_height - 0.5f); +#else + const Camera& camera = wxGetApp().plater()->get_camera(); + const float inv_zoom = (float)camera.get_inv_zoom(); + + const float cnv_half_width = 0.5f * (float)cnv_size.get_width(); + const float cnv_half_height = 0.5f * (float)cnv_size.get_height(); if (cnv_half_width == 0.0f || cnv_half_height == 0.0f) return; - Vec2d start(m_start_corner(0) - cnv_half_width, cnv_half_height - m_start_corner(1)); - Vec2d end(m_end_corner(0) - cnv_half_width, cnv_half_height - m_end_corner(1)); + const Vec2d start(m_start_corner.x() - cnv_half_width, cnv_half_height - m_start_corner.y()); + const Vec2d end(m_end_corner.x() - cnv_half_width, cnv_half_height - m_end_corner.y()); + + const float left = (float)std::min(start.x(), end.x()) * inv_zoom; + const float top = (float)std::max(start.y(), end.y()) * inv_zoom; + const float right = (float)std::max(start.x(), end.x()) * inv_zoom; + const float bottom = (float)std::min(start.y(), end.y()) * inv_zoom; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES - const float left = (float)std::min(start(0), end(0)) * inv_zoom; - const float top = (float)std::max(start(1), end(1)) * inv_zoom; - const float right = (float)std::max(start(0), end(0)) * inv_zoom; - const float bottom = (float)std::min(start(1), end(1)) * inv_zoom; - glsafe(::glLineWidth(1.5f)); -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL float color[3]; color[0] = (m_state == Select) ? 0.3f : 1.0f; color[1] = (m_state == Select) ? 1.0f : 0.3f; color[2] = 0.3f; glsafe(::glColor3fv(color)); -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glDisable(GL_DEPTH_TEST)); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPushMatrix()); glsafe(::glLoadIdentity()); // ensure that the rectangle is renderered inside the frustrum @@ -109,13 +124,18 @@ namespace GUI { // ensure that the overlay fits the frustrum near z plane const double gui_scale = camera.get_gui_scale(); glsafe(::glScaled(gui_scale, gui_scale, 1.0)); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPushAttrib(GL_ENABLE_BIT)); glsafe(::glLineStipple(4, 0xAAAA)); glsafe(::glEnable(GL_LINE_STIPPLE)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); @@ -125,7 +145,7 @@ namespace GUI { m_rectangle.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 }; init_data.reserve_vertices(4); init_data.reserve_indices(4); @@ -136,19 +156,20 @@ namespace GUI { init_data.add_vertex(Vec2f(left, top)); // indices - init_data.add_ushort_index(0); - init_data.add_ushort_index(1); - init_data.add_ushort_index(2); - init_data.add_ushort_index(3); + init_data.add_index(0); + init_data.add_index(1); + init_data.add_index(2); + init_data.add_index(3); m_rectangle.init_from(std::move(init_data)); } - const ColorRGBA color( - (m_state == Select) ? 0.3f : 1.0f, - (m_state == Select) ? 1.0f : 0.3f, - 0.3f, 1.0f); - m_rectangle.set_color(color); +#if ENABLE_GL_SHADERS_ATTRIBUTES + shader->set_uniform("view_model_matrix", Transform3d::Identity()); + shader->set_uniform("projection_matrix", Transform3d::Identity()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + + m_rectangle.set_color(ColorRGBA((m_state == Select) ? 0.3f : 1.0f, (m_state == Select) ? 1.0f : 0.3f, 0.3f, 1.0f)); m_rectangle.render(); shader->stop_using(); } @@ -159,11 +180,13 @@ namespace GUI { ::glVertex2f((GLfloat)right, (GLfloat)top); ::glVertex2f((GLfloat)left, (GLfloat)top); glsafe(::glEnd()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glPopAttrib()); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } } // namespace GUI diff --git a/src/slic3r/GUI/GLSelectionRectangle.hpp b/src/slic3r/GUI/GLSelectionRectangle.hpp index ae0b7a097..71e663240 100644 --- a/src/slic3r/GUI/GLSelectionRectangle.hpp +++ b/src/slic3r/GUI/GLSelectionRectangle.hpp @@ -2,9 +2,9 @@ #define slic3r_GLSelectionRectangle_hpp_ #include "libslic3r/Point.hpp" -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #include "GLModel.hpp" -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL namespace Slic3r { namespace GUI { @@ -38,22 +38,22 @@ public: bool is_dragging() const { return m_state != Off; } EState get_state() const { return m_state; } - float get_width() const { return std::abs(m_start_corner(0) - m_end_corner(0)); } - float get_height() const { return std::abs(m_start_corner(1) - m_end_corner(1)); } - float get_left() const { return std::min(m_start_corner(0), m_end_corner(0)); } - float get_right() const { return std::max(m_start_corner(0), m_end_corner(0)); } - float get_top() const { return std::max(m_start_corner(1), m_end_corner(1)); } - float get_bottom() const { return std::min(m_start_corner(1), m_end_corner(1)); } + float get_width() const { return std::abs(m_start_corner.x() - m_end_corner.x()); } + float get_height() const { return std::abs(m_start_corner.y() - m_end_corner.y()); } + float get_left() const { return std::min(m_start_corner.x(), m_end_corner.x()); } + float get_right() const { return std::max(m_start_corner.x(), m_end_corner.x()); } + float get_top() const { return std::max(m_start_corner.y(), m_end_corner.y()); } + float get_bottom() const { return std::min(m_start_corner.y(), m_end_corner.y()); } private: EState m_state{ Off }; Vec2d m_start_corner{ Vec2d::Zero() }; Vec2d m_end_corner{ Vec2d::Zero() }; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel m_rectangle; Vec2d m_old_start_corner{ Vec2d::Zero() }; Vec2d m_old_end_corner{ Vec2d::Zero() }; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL }; diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index 32b3d5960..7e5704e87 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -296,6 +296,13 @@ void GLShaderProgram::set_uniform(int id, const Matrix3f& value) const glsafe(::glUniformMatrix3fv(id, 1, GL_FALSE, static_cast(value.data()))); } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void GLShaderProgram::set_uniform(int id, const Matrix3d& value) const +{ + set_uniform(id, (Matrix3f)value.cast()); +} +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + void GLShaderProgram::set_uniform(int id, const Vec3f& value) const { if (id >= 0) diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index 06a5c00e5..a867a62bd 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -61,6 +61,9 @@ public: void set_uniform(const char* name, const Transform3f& value) const { set_uniform(get_uniform_location(name), value); } void set_uniform(const char* name, const Transform3d& value) const { set_uniform(get_uniform_location(name), value); } void set_uniform(const char* name, const Matrix3f& value) const { set_uniform(get_uniform_location(name), value); } +#if ENABLE_GL_SHADERS_ATTRIBUTES + void set_uniform(const char* name, const Matrix3d& value) const { set_uniform(get_uniform_location(name), value); } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES void set_uniform(const char* name, const Vec3f& value) const { set_uniform(get_uniform_location(name), value); } void set_uniform(const char* name, const Vec3d& value) const { set_uniform(get_uniform_location(name), value); } void set_uniform(const char* name, const ColorRGB& value) const { set_uniform(get_uniform_location(name), value); } @@ -80,6 +83,9 @@ public: void set_uniform(int id, const Transform3f& value) const; void set_uniform(int id, const Transform3d& value) const; void set_uniform(int id, const Matrix3f& value) const; +#if ENABLE_GL_SHADERS_ATTRIBUTES + void set_uniform(int id, const Matrix3d& value) const; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES void set_uniform(int id, const Vec3f& value) const; void set_uniform(int id, const Vec3d& value) const; void set_uniform(int id, const ColorRGB& value) const; diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 33ac9b6bc..75b6824a7 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -33,47 +33,91 @@ std::pair GLShadersManager::init() bool valid = true; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + // basic shader, used to render all what was previously rendered using the immediate mode + valid &= append_shader("flat_attr", { "flat_attr.vs", "flat.fs" }); + // basic shader for textures, used to render textures + valid &= append_shader("flat_texture_attr", { "flat_texture_attr.vs", "flat_texture.fs" }); + // used to render 3D scene background + valid &= append_shader("background_attr", { "background_attr.vs", "background.fs" }); +#else // basic shader, used to render all what was previously rendered using the immediate mode valid &= append_shader("flat", { "flat.vs", "flat.fs" }); // basic shader for textures, used to render textures valid &= append_shader("flat_texture", { "flat_texture.vs", "flat_texture.fs" }); // used to render 3D scene background valid &= append_shader("background", { "background.vs", "background.fs" }); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_GL_SHADERS_ATTRIBUTES +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_SHOW_TOOLPATHS_COG // used to render toolpaths center of gravity +#if ENABLE_GL_SHADERS_ATTRIBUTES + valid &= append_shader("toolpaths_cog_attr", { "toolpaths_cog_attr.vs", "toolpaths_cog.fs" }); +#else valid &= append_shader("toolpaths_cog", { "toolpaths_cog.vs", "toolpaths_cog.fs" }); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #endif // ENABLE_SHOW_TOOLPATHS_COG +#if ENABLE_GL_SHADERS_ATTRIBUTES + // 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_attr", { "gouraud_light_attr.vs", "gouraud_light.fs" }); + // used to render printbed + valid &= append_shader("printbed_attr", { "printbed_attr.vs", "printbed.fs" }); +#else // 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", { "gouraud_light.vs", "gouraud_light.fs" }); // used to render printbed valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" }); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES // used to render options in gcode preview - if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) + if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + valid &= append_shader("gouraud_light_instanced_attr", { "gouraud_light_instanced_attr.vs", "gouraud_light_instanced.fs" }); +#else valid &= append_shader("gouraud_light_instanced", { "gouraud_light_instanced.vs", "gouraud_light_instanced.fs" }); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + } +#if ENABLE_GL_SHADERS_ATTRIBUTES + // used to render objects in 3d editor + valid &= append_shader("gouraud_attr", { "gouraud_attr.vs", "gouraud.fs" } +#else // used to render extrusion and travel paths as lines in gcode preview valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" }); // used to render objects in 3d editor valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #if ENABLE_ENVIRONMENT_MAP , { "ENABLE_ENVIRONMENT_MAP"sv } #endif // ENABLE_ENVIRONMENT_MAP ); +#if ENABLE_GL_SHADERS_ATTRIBUTES + // used to render variable layers heights in 3d editor + valid &= append_shader("variable_layer_height_attr", { "variable_layer_height_attr.vs", "variable_layer_height.fs" }); + // used to render highlight contour around selected triangles inside the multi-material gizmo + valid &= append_shader("mm_contour_attr", { "mm_contour_attr.vs", "mm_contour_attr.fs" }); +#else // used to render variable layers heights in 3d editor valid &= append_shader("variable_layer_height", { "variable_layer_height.vs", "variable_layer_height.fs" }); // used to render highlight contour around selected triangles inside the multi-material gizmo valid &= append_shader("mm_contour", { "mm_contour.vs", "mm_contour.fs" }); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES // Used to render painted triangles inside the multi-material gizmo. Triangle normals are computed inside fragment shader. // For Apple's on Arm CPU computed triangle normals inside fragment shader using dFdx and dFdy has the opposite direction. // Because of this, objects had darker colors inside the multi-material gizmo. // Based on https://stackoverflow.com/a/66206648, the similar behavior was also spotted on some other devices with Arm CPU. // Since macOS 12 (Monterey), this issue with the opposite direction on Apple's Arm CPU seems to be fixed, and computed // triangle normals inside fragment shader have the right direction. +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (platform_flavor() == PlatformFlavor::OSXOnArm && wxPlatformInfo::Get().GetOSMajorVersion() < 12) + valid &= append_shader("mm_gouraud_attr", { "mm_gouraud_attr.vs", "mm_gouraud_attr.fs" }, { "FLIP_TRIANGLE_NORMALS"sv }); + else + valid &= append_shader("mm_gouraud_attr", { "mm_gouraud_attr.vs", "mm_gouraud_attr.fs" }); +#else if (platform_flavor() == PlatformFlavor::OSXOnArm && wxPlatformInfo::Get().GetOSMajorVersion() < 12) valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"}, {"FLIP_TRIANGLE_NORMALS"sv}); else valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"}); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES return { valid, error }; } diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp index 340bb78c3..064ca1a18 100644 --- a/src/slic3r/GUI/GLTexture.cpp +++ b/src/slic3r/GUI/GLTexture.cpp @@ -3,10 +3,10 @@ #include "3DScene.hpp" #include "OpenGLManager.hpp" -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #include "GUI_App.hpp" #include "GLModel.hpp" -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #include @@ -339,9 +339,9 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right, glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2 }; init_data.reserve_vertices(4); init_data.reserve_indices(6); @@ -352,15 +352,23 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right, init_data.add_vertex(Vec2f(left, top), Vec2f(uvs.left_top.u, uvs.left_top.v)); // indices - init_data.add_ushort_triangle(0, 1, 2); - init_data.add_ushort_triangle(2, 3, 0); + init_data.add_triangle(0, 1, 2); + init_data.add_triangle(2, 3, 0); GLModel model; model.init_from(std::move(init_data)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_texture_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat_texture"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + shader->set_uniform("view_model_matrix", Transform3d::Identity()); + shader->set_uniform("projection_matrix", Transform3d::Identity()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES model.render(); shader->stop_using(); } @@ -371,7 +379,7 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right, ::glTexCoord2f(uvs.right_top.u, uvs.right_top.v); ::glVertex2f(right, top); ::glTexCoord2f(uvs.left_top.u, uvs.left_top.v); ::glVertex2f(left, top); glsafe(::glEnd()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 86827442d..78fbc084f 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -85,26 +85,29 @@ bool GLToolbarItem::update_enabled_state() return ret; } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void GLToolbarItem::render(const GLCanvas3D& parent, unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const +#else void GLToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { - auto uvs = [this](unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) -> GLTexture::Quad_UVs - { - assert((tex_width != 0) && (tex_height != 0)); + auto uvs = [this](unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) -> GLTexture::Quad_UVs { + assert(tex_width != 0 && tex_height != 0); GLTexture::Quad_UVs ret; // tiles in the texture are spaced by 1 pixel - float icon_size_px = (float)(tex_width - 1) / ((float)Num_States + (float)Num_Rendered_Highlight_States); - char render_state = (m_highlight_state == NotHighlighted ? m_state : Num_States + m_highlight_state); - float inv_tex_width = 1.0f / (float)tex_width; - float inv_tex_height = 1.0f / (float)tex_height; + const float icon_size_px = (float)(tex_width - 1) / ((float)Num_States + (float)Num_Rendered_Highlight_States); + const char render_state = (m_highlight_state == NotHighlighted ? m_state : Num_States + m_highlight_state); + const float inv_tex_width = 1.0f / (float)tex_width; + const float inv_tex_height = 1.0f / (float)tex_height; // tiles in the texture are spaced by 1 pixel - float u_offset = 1.0f * inv_tex_width; - float v_offset = 1.0f * inv_tex_height; - float du = icon_size_px * inv_tex_width; - float dv = icon_size_px * inv_tex_height; - float left = u_offset + (float)render_state * du; - float right = left + du - u_offset; - float top = v_offset + (float)m_data.sprite_id * dv; - float bottom = top + dv - v_offset; + const float u_offset = 1.0f * inv_tex_width; + const float v_offset = 1.0f * inv_tex_height; + const float du = icon_size_px * inv_tex_width; + const float dv = icon_size_px * inv_tex_height; + const float left = u_offset + (float)render_state * du; + const float right = left + du - u_offset; + const float top = v_offset + (float)m_data.sprite_id * dv; + const float bottom = top + dv - v_offset; ret.left_top = { left, top }; ret.left_bottom = { left, bottom }; ret.right_bottom = { right, bottom }; @@ -114,12 +117,26 @@ void GLToolbarItem::render(unsigned int tex_id, float left, float right, float b GLTexture::render_sub_texture(tex_id, left, right, bottom, top, uvs(tex_width, tex_height, icon_size)); - if (is_pressed()) - { - if ((m_last_action_type == Left) && m_data.left.can_render()) + if (is_pressed()) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Size cnv_size = parent.get_canvas_size(); + const float cnv_w = (float)cnv_size.get_width(); + const float cnv_h = (float)cnv_size.get_height(); + + const float out_left = (0.5f * left + 0.5f) * cnv_w; + const float out_right = (0.5f * right + 0.5f) * cnv_w; + const float out_top = (0.5f * top + 0.5f) * cnv_h; + const float out_bottom = (0.5f * bottom + 0.5f) * cnv_h; + if (m_last_action_type == Left && m_data.left.can_render()) + m_data.left.render_callback(out_left, out_right, out_bottom, out_top); + else if (m_last_action_type == Right && m_data.right.can_render()) + m_data.right.render_callback(out_left, out_right, out_bottom, out_top); +#else + if (m_last_action_type == Left && m_data.left.can_render()) m_data.left.render_callback(left, right, bottom, top); - else if ((m_last_action_type == Right) && m_data.right.can_render()) + else if (m_last_action_type == Right && m_data.right.can_render()) m_data.right.render_callback(left, right, bottom, top); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } } @@ -185,6 +202,16 @@ bool GLToolbar::init(const BackgroundTexture::Metadata& background_texture) return res; } +#if ENABLE_GL_SHADERS_ATTRIBUTES +bool GLToolbar::init_arrow(const std::string& filename) +{ + if (m_arrow_texture.get_id() != 0) + return true; + + const std::string path = resources_dir() + "/icons/"; + return (!filename.empty()) ? m_arrow_texture.load_from_svg_file(path + filename, false, false, false, 512) : false; +} +#else bool GLToolbar::init_arrow(const BackgroundTexture::Metadata& arrow_texture) { if (m_arrow_texture.texture.get_id() != 0) @@ -193,14 +220,15 @@ bool GLToolbar::init_arrow(const BackgroundTexture::Metadata& arrow_texture) std::string path = resources_dir() + "/icons/"; bool res = false; - if (!arrow_texture.filename.empty()) { + if (!arrow_texture.filename.empty()) res = m_arrow_texture.texture.load_from_svg_file(path + arrow_texture.filename, false, false, false, 1000); - } + if (res) m_arrow_texture.metadata = arrow_texture; return res; } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES GLToolbar::Layout::EType GLToolbar::get_layout_type() const { @@ -434,18 +462,16 @@ void GLToolbar::render(const GLCanvas3D& parent) { default: case Layout::Horizontal: { render_horizontal(parent); break; } - case Layout::Vertical: { render_vertical(parent); break; } + case Layout::Vertical: { render_vertical(parent); break; } } } - - bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent) { if (!m_enabled) return false; - Vec2d mouse_pos((double)evt.GetX(), (double)evt.GetY()); + const Vec2d mouse_pos((double)evt.GetX(), (double)evt.GetY()); bool processed = false; // mouse anywhere @@ -493,7 +519,7 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent) return false; } - int item_id = contains_mouse(mouse_pos, parent); + const int item_id = contains_mouse(mouse_pos, parent); if (item_id != -1) { // mouse inside toolbar if (evt.LeftDown() || evt.LeftDClick()) { @@ -601,16 +627,12 @@ int GLToolbar::get_visible_items_cnt() const void GLToolbar::do_action(GLToolbarItem::EActionType type, int item_id, GLCanvas3D& parent, bool check_hover) { - if ((m_pressed_toggable_id == -1) || (m_pressed_toggable_id == item_id)) - { - if ((0 <= item_id) && (item_id < (int)m_items.size())) - { + if (m_pressed_toggable_id == -1 || m_pressed_toggable_id == item_id) { + if (0 <= item_id && item_id < (int)m_items.size()) { GLToolbarItem* item = m_items[item_id]; - if ((item != nullptr) && !item->is_separator() && !item->is_disabled() && (!check_hover || item->is_hovered())) - { - if (((type == GLToolbarItem::Right) && item->is_right_toggable()) || - ((type == GLToolbarItem::Left) && item->is_left_toggable())) - { + if (item != nullptr && !item->is_separator() && !item->is_disabled() && (!check_hover || item->is_hovered())) { + if ((type == GLToolbarItem::Right && item->is_right_toggable()) || + (type == GLToolbarItem::Left && item->is_left_toggable())) { GLToolbarItem::EState state = item->get_state(); if (state == GLToolbarItem::Hover) item->set_state(GLToolbarItem::HoverPressed); @@ -628,12 +650,11 @@ void GLToolbar::do_action(GLToolbarItem::EActionType type, int item_id, GLCanvas switch (type) { default: - case GLToolbarItem::Left: { item->do_left_action(); break; } + case GLToolbarItem::Left: { item->do_left_action(); break; } case GLToolbarItem::Right: { item->do_right_action(); break; } } } - else - { + else { if (m_type == Radio) select_item(item->get_name()); else @@ -648,8 +669,7 @@ void GLToolbar::do_action(GLToolbarItem::EActionType type, int item_id, GLCanvas case GLToolbarItem::Right: { item->do_right_action(); break; } } - if ((m_type == Normal) && (item->get_state() != GLToolbarItem::Disabled)) - { + if (m_type == Normal && item->get_state() != GLToolbarItem::Disabled) { // the item may get disabled during the action, if not, set it back to hover state item->set_state(GLToolbarItem::Hover); parent.render(); @@ -669,10 +689,209 @@ void GLToolbar::update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent) { default: case Layout::Horizontal: { update_hover_state_horizontal(mouse_pos, parent); break; } - case Layout::Vertical: { update_hover_state_vertical(mouse_pos, parent); break; } + case Layout::Vertical: { update_hover_state_vertical(mouse_pos, parent); break; } } } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent) +{ + const Size cnv_size = parent.get_canvas_size(); + const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y())); + + const float icons_size = m_layout.icons_size * m_layout.scale; + const float separator_size = m_layout.separator_size * m_layout.scale; + const float gap_size = m_layout.gap_size * m_layout.scale; + const float border = m_layout.border * m_layout.scale; + + const float separator_stride = separator_size + gap_size; + const float icon_stride = icons_size + gap_size; + + float left = m_layout.left + border; + float top = m_layout.top - border; + + for (GLToolbarItem* item : m_items) { + if (!item->is_visible()) + continue; + + if (item->is_separator()) + left += separator_stride; + else { + const float right = left + icons_size; + const float bottom = top - icons_size; + + const GLToolbarItem::EState state = item->get_state(); + bool inside = (left <= (float)scaled_mouse_pos.x()) && + ((float)scaled_mouse_pos.x() <= right) && + (bottom <= (float)scaled_mouse_pos.y()) && + ((float)scaled_mouse_pos.y() <= top); + + switch (state) + { + case GLToolbarItem::Normal: + { + if (inside) { + item->set_state(GLToolbarItem::Hover); + parent.set_as_dirty(); + } + + break; + } + case GLToolbarItem::Hover: + { + if (!inside) { + item->set_state(GLToolbarItem::Normal); + parent.set_as_dirty(); + } + + break; + } + case GLToolbarItem::Pressed: + { + if (inside) { + item->set_state(GLToolbarItem::HoverPressed); + parent.set_as_dirty(); + } + + break; + } + case GLToolbarItem::HoverPressed: + { + if (!inside) { + item->set_state(GLToolbarItem::Pressed); + parent.set_as_dirty(); + } + + break; + } + case GLToolbarItem::Disabled: + { + if (inside) { + item->set_state(GLToolbarItem::HoverDisabled); + parent.set_as_dirty(); + } + + break; + } + case GLToolbarItem::HoverDisabled: + { + if (!inside) { + item->set_state(GLToolbarItem::Disabled); + parent.set_as_dirty(); + } + + break; + } + default: + { + break; + } + } + + left += icon_stride; + } + } +} + +void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& parent) +{ + const Size cnv_size = parent.get_canvas_size(); + const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y())); + + const float icons_size = m_layout.icons_size * m_layout.scale; + const float separator_size = m_layout.separator_size * m_layout.scale; + const float gap_size = m_layout.gap_size * m_layout.scale; + const float border = m_layout.border * m_layout.scale; + + const float separator_stride = separator_size + gap_size; + const float icon_stride = icons_size + gap_size; + + float left = m_layout.left + border; + float top = m_layout.top - border; + + for (GLToolbarItem* item : m_items) { + if (!item->is_visible()) + continue; + + if (item->is_separator()) + top -= separator_stride; + else { + const float right = left + icons_size; + const float bottom = top - icons_size; + + GLToolbarItem::EState state = item->get_state(); + const bool inside = (left <= (float)scaled_mouse_pos.x()) && + ((float)scaled_mouse_pos.x() <= right) && + (bottom <= (float)scaled_mouse_pos.y()) && + ((float)scaled_mouse_pos.y() <= top); + + switch (state) + { + case GLToolbarItem::Normal: + { + if (inside) { + item->set_state(GLToolbarItem::Hover); + parent.set_as_dirty(); + } + + break; + } + case GLToolbarItem::Hover: + { + if (!inside) { + item->set_state(GLToolbarItem::Normal); + parent.set_as_dirty(); + } + + break; + } + case GLToolbarItem::Pressed: + { + if (inside) { + item->set_state(GLToolbarItem::HoverPressed); + parent.set_as_dirty(); + } + + break; + } + case GLToolbarItem::HoverPressed: + { + if (!inside) { + item->set_state(GLToolbarItem::Pressed); + parent.set_as_dirty(); + } + + break; + } + case GLToolbarItem::Disabled: + { + if (inside) { + item->set_state(GLToolbarItem::HoverDisabled); + parent.set_as_dirty(); + } + + break; + } + case GLToolbarItem::HoverDisabled: + { + if (!inside) { + item->set_state(GLToolbarItem::Disabled); + parent.set_as_dirty(); + } + + break; + } + default: + { + break; + } + } + + top -= icon_stride; + } + } +} +#else void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent) { // NB: mouse_pos is already scaled appropriately @@ -889,18 +1108,16 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& } } } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES GLToolbarItem* GLToolbar::get_item(const std::string& item_name) { if (!m_enabled) return nullptr; - for (GLToolbarItem* item : m_items) - { - if (item->get_name() == item_name) - { + for (GLToolbarItem* item : m_items) { + if (item->get_name() == item_name) return item; - } } return nullptr; } @@ -914,10 +1131,159 @@ int GLToolbar::contains_mouse(const Vec2d& mouse_pos, const GLCanvas3D& parent) { default: case Layout::Horizontal: { return contains_mouse_horizontal(mouse_pos, parent); } - case Layout::Vertical: { return contains_mouse_vertical(mouse_pos, parent); } + case Layout::Vertical: { return contains_mouse_vertical(mouse_pos, parent); } } } +#if ENABLE_GL_SHADERS_ATTRIBUTES +int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3D& parent) const +{ + const Size cnv_size = parent.get_canvas_size(); + const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y())); + + const float icons_size = m_layout.icons_size * m_layout.scale; + const float separator_size = m_layout.separator_size * m_layout.scale; + const float gap_size = m_layout.gap_size * m_layout.scale; + const float border = m_layout.border * m_layout.scale; + + float left = m_layout.left + border; + const float top = m_layout.top - border; + + for (size_t id = 0; id < m_items.size(); ++id) { + GLToolbarItem* item = m_items[id]; + + if (!item->is_visible()) + continue; + + if (item->is_separator()) { + float right = left + separator_size; + const float bottom = top - icons_size; + + // mouse inside the separator + if (left <= (float)scaled_mouse_pos.x() && + (float)scaled_mouse_pos.x() <= right && + bottom <= (float)scaled_mouse_pos.y() && + (float)scaled_mouse_pos.y() <= top) + return id; + + left = right; + right += gap_size; + + if (id < m_items.size() - 1) { + // mouse inside the gap + if (left <= (float)scaled_mouse_pos.x() && + (float)scaled_mouse_pos.x() <= right && + bottom <= (float)scaled_mouse_pos.y() && + (float)scaled_mouse_pos.y() <= top) + return -2; + } + + left = right; + } + else { + float right = left + icons_size; + const float bottom = top - icons_size; + + // mouse inside the icon + if (left <= (float)scaled_mouse_pos.x() && + (float)scaled_mouse_pos.x() <= right && + bottom <= (float)scaled_mouse_pos.y() && + (float)scaled_mouse_pos.y() <= top) + return id; + + left = right; + right += gap_size; + + if (id < m_items.size() - 1) { + // mouse inside the gap + if (left <= (float)scaled_mouse_pos.x() && + (float)scaled_mouse_pos.x() <= right && + bottom <= (float)scaled_mouse_pos.y() && + (float)scaled_mouse_pos.y() <= top) + return -2; + } + + left = right; + } + } + + return -1; +} + +int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& parent) const +{ + const Size cnv_size = parent.get_canvas_size(); + const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y())); + + const float icons_size = m_layout.icons_size * m_layout.scale; + const float separator_size = m_layout.separator_size * m_layout.scale; + const float gap_size = m_layout.gap_size * m_layout.scale; + const float border = m_layout.border * m_layout.scale; + + const float left = m_layout.left + border; + float top = m_layout.top - border; + + for (size_t id = 0; id < m_items.size(); ++id) { + GLToolbarItem* item = m_items[id]; + + if (!item->is_visible()) + continue; + + if (item->is_separator()) { + const float right = left + icons_size; + float bottom = top - separator_size; + + // mouse inside the separator + if (left <= (float)scaled_mouse_pos.x() && + (float)scaled_mouse_pos.x() <= right && + bottom <= (float)scaled_mouse_pos.y() && + (float)scaled_mouse_pos.y() <= top) + return id; + + top = bottom; + bottom -= gap_size; + + if (id < m_items.size() - 1) { + // mouse inside the gap + if (left <= (float)scaled_mouse_pos.x() && + (float)scaled_mouse_pos.x() <= right && + bottom <= (float)scaled_mouse_pos.y() && + (float)scaled_mouse_pos.y() <= top) + return -2; + } + + top = bottom; + } + else { + const float right = left + icons_size; + float bottom = top - icons_size; + + // mouse inside the icon + if (left <= (float)scaled_mouse_pos.x() && + (float)scaled_mouse_pos.x() <= right && + bottom <= (float)scaled_mouse_pos.y() && + (float)scaled_mouse_pos.y() <= top) + return id; + + top = bottom; + bottom -= gap_size; + + if (id < m_items.size() - 1) { + // mouse inside the gap + if (left <= (float)scaled_mouse_pos.x() && + (float)scaled_mouse_pos.x() <= right && + bottom <= (float)scaled_mouse_pos.y() && + (float)scaled_mouse_pos.y() <= top) + return -2; + } + + top = bottom; + } + } + + return -1; +} +#else int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3D& parent) const { // NB: mouse_pos is already scaled appropriately @@ -1062,14 +1428,92 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& return -1; } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if ENABLE_GL_SHADERS_ATTRIBUTES +void GLToolbar::render_background(float left, float top, float right, float bottom, float border_w, float border_h) const +{ + const unsigned int tex_id = m_background_texture.texture.get_id(); + const float tex_width = (float)m_background_texture.texture.get_width(); + const float tex_height = (float)m_background_texture.texture.get_height(); + if (tex_id != 0 && tex_width > 0.0f && tex_height > 0.0f) { + const float inv_tex_width = 1.0f / tex_width; + const float inv_tex_height = 1.0f / tex_height; + + const float internal_left = left + border_w; + const float internal_right = right - border_w; + const float internal_top = top - border_h; + const float internal_bottom = bottom + border_w; + + const float left_uv = 0.0f; + const float right_uv = 1.0f; + const float top_uv = 1.0f; + const float bottom_uv = 0.0f; + + const float internal_left_uv = (float)m_background_texture.metadata.left * inv_tex_width; + const float internal_right_uv = 1.0f - (float)m_background_texture.metadata.right * inv_tex_width; + const float internal_top_uv = 1.0f - (float)m_background_texture.metadata.top * inv_tex_height; + const float internal_bottom_uv = (float)m_background_texture.metadata.bottom * inv_tex_height; + + // top-left corner + if (m_layout.horizontal_orientation == Layout::HO_Left || m_layout.vertical_orientation == Layout::VO_Top) + GLTexture::render_sub_texture(tex_id, left, internal_left, internal_top, top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + else + GLTexture::render_sub_texture(tex_id, left, internal_left, internal_top, top, { { left_uv, internal_top_uv }, { internal_left_uv, internal_top_uv }, { internal_left_uv, top_uv }, { left_uv, top_uv } }); + + // top edge + if (m_layout.vertical_orientation == Layout::VO_Top) + GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_top, top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + else + GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_top, top, { { internal_left_uv, internal_top_uv }, { internal_right_uv, internal_top_uv }, { internal_right_uv, top_uv }, { internal_left_uv, top_uv } }); + + // top-right corner + if (m_layout.horizontal_orientation == Layout::HO_Right || m_layout.vertical_orientation == Layout::VO_Top) + GLTexture::render_sub_texture(tex_id, internal_right, right, internal_top, top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + else + GLTexture::render_sub_texture(tex_id, internal_right, right, internal_top, top, { { internal_right_uv, internal_top_uv }, { right_uv, internal_top_uv }, { right_uv, top_uv }, { internal_right_uv, top_uv } }); + + // center-left edge + if (m_layout.horizontal_orientation == Layout::HO_Left) + GLTexture::render_sub_texture(tex_id, left, internal_left, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + else + GLTexture::render_sub_texture(tex_id, left, internal_left, internal_bottom, internal_top, { { left_uv, internal_bottom_uv }, { internal_left_uv, internal_bottom_uv }, { internal_left_uv, internal_top_uv }, { left_uv, internal_top_uv } }); + + // center + GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + + // center-right edge + if (m_layout.horizontal_orientation == Layout::HO_Right) + GLTexture::render_sub_texture(tex_id, internal_right, right, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + else + GLTexture::render_sub_texture(tex_id, internal_right, right, internal_bottom, internal_top, { { internal_right_uv, internal_bottom_uv }, { right_uv, internal_bottom_uv }, { right_uv, internal_top_uv }, { internal_right_uv, internal_top_uv } }); + + // bottom-left corner + if (m_layout.horizontal_orientation == Layout::HO_Left || m_layout.vertical_orientation == Layout::VO_Bottom) + GLTexture::render_sub_texture(tex_id, left, internal_left, bottom, internal_bottom, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + else + GLTexture::render_sub_texture(tex_id, left, internal_left, bottom, internal_bottom, { { left_uv, bottom_uv }, { internal_left_uv, bottom_uv }, { internal_left_uv, internal_bottom_uv }, { left_uv, internal_bottom_uv } }); + + // bottom edge + if (m_layout.vertical_orientation == Layout::VO_Bottom) + GLTexture::render_sub_texture(tex_id, internal_left, internal_right, bottom, internal_bottom, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + else + GLTexture::render_sub_texture(tex_id, internal_left, internal_right, bottom, internal_bottom, { { internal_left_uv, bottom_uv }, { internal_right_uv, bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_left_uv, internal_bottom_uv } }); + + // bottom-right corner + if (m_layout.horizontal_orientation == Layout::HO_Right || m_layout.vertical_orientation == Layout::VO_Bottom) + GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + else + GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_right_uv, bottom_uv }, { right_uv, bottom_uv }, { right_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv } }); + } +} +#else void GLToolbar::render_background(float left, float top, float right, float bottom, float border) const { unsigned int tex_id = m_background_texture.texture.get_id(); float tex_width = (float)m_background_texture.texture.get_width(); float tex_height = (float)m_background_texture.texture.get_height(); - if ((tex_id != 0) && (tex_width > 0) && (tex_height > 0)) - { + if (tex_id != 0 && tex_width > 0 && tex_height > 0) { float inv_tex_width = (tex_width != 0.0f) ? 1.0f / tex_width : 0.0f; float inv_tex_height = (tex_height != 0.0f) ? 1.0f / tex_height : 0.0f; @@ -1140,7 +1584,78 @@ void GLToolbar::render_background(float left, float top, float right, float bott GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_right_uv, bottom_uv }, { right_uv, bottom_uv }, { right_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv } }); } } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if ENABLE_GL_SHADERS_ATTRIBUTES +void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighted_item) +{ + // arrow texture not initialized + if (m_arrow_texture.get_id() == 0) + return; + + const Size cnv_size = parent.get_canvas_size(); + const float cnv_w = (float)cnv_size.get_width(); + const float cnv_h = (float)cnv_size.get_height(); + + if (cnv_w == 0 || cnv_h == 0) + return; + + const float inv_cnv_w = 1.0f / cnv_w; + const float inv_cnv_h = 1.0f / cnv_h; + + const float icons_size_x = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_w; + const float icons_size_y = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_h; + const float separator_size = 2.0f * m_layout.separator_size * m_layout.scale * inv_cnv_w; + const float gap_size = 2.0f * m_layout.gap_size * m_layout.scale * inv_cnv_w; + const float border_x = 2.0f * m_layout.border * m_layout.scale * inv_cnv_w; + const float border_y = 2.0f * m_layout.border * m_layout.scale * inv_cnv_h; + + const float separator_stride = separator_size + gap_size; + const float icon_stride = icons_size_x + gap_size; + + float left = 2.0f * m_layout.left * inv_cnv_w + border_x; + float top = 2.0f * m_layout.top * inv_cnv_h - 2.0f * border_y - icons_size_y; + + bool found = false; + for (const GLToolbarItem* item : m_items) { + if (!item->is_visible()) + continue; + + if (item->is_separator()) + left += separator_stride; + else { + if (item->get_name() == highlighted_item->get_name()) { + found = true; + break; + } + left += icon_stride; + } + } + if (!found) + return; + + const float right = left + icons_size_x; + + const unsigned int tex_id = m_arrow_texture.get_id(); + // arrow width and height + const float arr_tex_width = (float)m_arrow_texture.get_width(); + const float arr_tex_height = (float)m_arrow_texture.get_height(); + if (tex_id != 0 && arr_tex_width > 0.0f && arr_tex_height > 0.0f) { + const float arrow_size_x = 2.0f * m_layout.scale * arr_tex_width * inv_cnv_w; + const float arrow_size_y = 2.0f * m_layout.scale * arr_tex_height * inv_cnv_h; + + const float left_uv = 0.0f; + const float right_uv = 1.0f; + const float top_uv = 1.0f; + const float bottom_uv = 0.0f; + + top -= border_y; + const float bottom = top - arrow_size_y * icons_size_x / arrow_size_x; + + GLTexture::render_sub_texture(tex_id, left, right, bottom, top, { { left_uv, top_uv }, { right_uv, top_uv }, { right_uv, bottom_uv }, { left_uv, bottom_uv } }); + } +} +#else void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighted_item) { // arrow texture not initialized @@ -1206,7 +1721,119 @@ void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighte GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_bottom, internal_top, { { internal_left_uv, internal_top_uv }, { internal_right_uv, internal_top_uv }, { internal_right_uv, internal_bottom_uv }, { internal_left_uv, internal_bottom_uv } }); } } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if ENABLE_GL_SHADERS_ATTRIBUTES +void GLToolbar::render_horizontal(const GLCanvas3D& parent) +{ + const Size cnv_size = parent.get_canvas_size(); + const float cnv_w = (float)cnv_size.get_width(); + const float cnv_h = (float)cnv_size.get_height(); + + if (cnv_w == 0 || cnv_h == 0) + return; + + const unsigned int tex_id = m_icons_texture.get_id(); + const int tex_width = m_icons_texture.get_width(); + const int tex_height = m_icons_texture.get_height(); + + if (tex_id == 0 || tex_width <= 0 || tex_height <= 0) + return; + + const float inv_cnv_w = 1.0f / cnv_w; + const float inv_cnv_h = 1.0f / cnv_h; + + const float icons_size_x = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_w; + const float icons_size_y = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_h; + const float separator_size = 2.0f * m_layout.separator_size * m_layout.scale * inv_cnv_w; + const float gap_size = 2.0f * m_layout.gap_size * m_layout.scale * inv_cnv_w; + const float border_w = 2.0f * m_layout.border * m_layout.scale * inv_cnv_w; + const float border_h = 2.0f * m_layout.border * m_layout.scale * inv_cnv_h; + const float width = 2.0f * get_width() * inv_cnv_w; + const float height = 2.0f * get_height() * inv_cnv_h; + + const float separator_stride = separator_size + gap_size; + const float icon_stride = icons_size_x + gap_size; + + float left = 2.0f * m_layout.left * inv_cnv_w; + float top = 2.0f * m_layout.top * inv_cnv_h; + const float right = left + width; + const float bottom = top - height; + + render_background(left, top, right, bottom, border_w, border_h); + + left += border_w; + top -= border_h; + + // renders icons + for (const GLToolbarItem* item : m_items) { + if (!item->is_visible()) + continue; + + if (item->is_separator()) + left += separator_stride; + else { + item->render(parent, tex_id, left, left + icons_size_x, top - icons_size_y, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale)); + left += icon_stride; + } + } +} + +void GLToolbar::render_vertical(const GLCanvas3D& parent) +{ + const Size cnv_size = parent.get_canvas_size(); + const float cnv_w = (float)cnv_size.get_width(); + const float cnv_h = (float)cnv_size.get_height(); + + if (cnv_w == 0 || cnv_h == 0) + return; + + const unsigned int tex_id = m_icons_texture.get_id(); + const int tex_width = m_icons_texture.get_width(); + const int tex_height = m_icons_texture.get_height(); + + if (tex_id == 0 || tex_width <= 0 || tex_height <= 0) + return; + + const float inv_cnv_w = 1.0f / cnv_w; + const float inv_cnv_h = 1.0f / cnv_h; + + const float icons_size_x = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_w; + const float icons_size_y = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_h; + const float separator_size = 2.0f * m_layout.separator_size * m_layout.scale * inv_cnv_h; + const float gap_size = 2.0f * m_layout.gap_size * m_layout.scale * inv_cnv_h; + const float border_w = 2.0f * m_layout.border * m_layout.scale * inv_cnv_w; + const float border_h = 2.0f * m_layout.border * m_layout.scale * inv_cnv_h; + const float width = 2.0f * get_width() * inv_cnv_w; + const float height = 2.0f * get_height() * inv_cnv_h; + + const float separator_stride = separator_size + gap_size; + const float icon_stride = icons_size_y + gap_size; + + float left = 2.0f * m_layout.left * inv_cnv_w; + float top = 2.0f * m_layout.top * inv_cnv_h; + const float right = left + width; + const float bottom = top - height; + + render_background(left, top, right, bottom, border_w, border_h); + + left += border_w; + top -= border_h; + + // renders icons + for (const GLToolbarItem* item : m_items) { + if (!item->is_visible()) + continue; + + if (item->is_separator()) + top -= separator_stride; + else { + item->render(parent, tex_id, left, left + icons_size_x, top - icons_size_y, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale)); + top -= icon_stride; + } + } +} +#else void GLToolbar::render_horizontal(const GLCanvas3D& parent) { unsigned int tex_id = m_icons_texture.get_id(); @@ -1300,6 +1927,7 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) } } } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES bool GLToolbar::generate_icons_texture() { diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 5740db3e6..bd3204d63 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -153,7 +153,12 @@ public: // returns true if the state changes bool update_enabled_state(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + void render(const GLCanvas3D& parent, unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const; +#else void render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + private: void set_visible(bool visible) { m_data.visible = visible; } @@ -246,7 +251,11 @@ private: GLTexture m_icons_texture; bool m_icons_texture_dirty; BackgroundTexture m_background_texture; +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLTexture m_arrow_texture; +#else BackgroundTexture m_arrow_texture; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES Layout m_layout; ItemsList m_items; @@ -273,7 +282,11 @@ public: bool init(const BackgroundTexture::Metadata& background_texture); +#if ENABLE_GL_SHADERS_ATTRIBUTES + bool init_arrow(const std::string& filename); +#else bool init_arrow(const BackgroundTexture::Metadata& arrow_texture); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES Layout::EType get_layout_type() const; void set_layout_type(Layout::EType type); @@ -344,7 +357,11 @@ private: int contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3D& parent) const; int contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& parent) const; +#if ENABLE_GL_SHADERS_ATTRIBUTES + void render_background(float left, float top, float right, float bottom, float border_w, float border_h) const; +#else void render_background(float left, float top, float right, float bottom, float border) const; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES void render_horizontal(const GLCanvas3D& parent); void render_vertical(const GLCanvas3D& parent); diff --git a/src/slic3r/GUI/GalleryDialog.cpp b/src/slic3r/GUI/GalleryDialog.cpp index 0bc741c96..975b807dc 100644 --- a/src/slic3r/GUI/GalleryDialog.cpp +++ b/src/slic3r/GUI/GalleryDialog.cpp @@ -275,12 +275,12 @@ static void generate_thumbnail_from_model(const std::string& filename) GLVolumeCollection volumes; volumes.volumes.push_back(new GLVolume()); GLVolume* volume = volumes.volumes.back(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL volume->model.init_from(model.mesh()); #else volume->indexed_vertex_array.load_mesh(model.mesh()); volume->indexed_vertex_array.finalize_geometry(true); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL volume->set_instance_transformation(model.objects[0]->instances[0]->get_transformation()); volume->set_volume_transformation(model.objects[0]->volumes[0]->get_transformation()); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 82702f212..83aed4289 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -4,8 +4,10 @@ #include #include "slic3r/GUI/GUI_App.hpp" - #include "slic3r/GUI/GUI_ObjectManipulation.hpp" +#if ENABLE_GL_SHADERS_ATTRIBUTES +#include "slic3r/GUI/Plater.hpp" +#endif // ENABLE_GL_SHADERS_ATTRIBUTES // TODO: Display tooltips quicker on Linux @@ -33,34 +35,52 @@ float GLGizmoBase::Grabber::get_dragging_half_size(float size) const void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, bool picking) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_current_shader(); + if (shader == nullptr) + return; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + if (!m_cube.is_initialized()) { // This cannot be done in constructor, OpenGL is not yet // initialized at that point (on Linux at least). indexed_triangle_set its = its_make_cube(1., 1., 1.); - its_translate(its, Vec3f(-0.5, -0.5, -0.5)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL + its_translate(its, -0.5f * Vec3f::Ones()); +#if ENABLE_LEGACY_OPENGL_REMOVAL m_cube.init_from(its); #else m_cube.init_from(its, BoundingBoxf3{ { -0.5, -0.5, -0.5 }, { 0.5, 0.5, 0.5 } }); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } const float fullsize = 2.0f * (dragging ? get_dragging_half_size(size) : get_half_size(size)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_cube.set_color(render_color); #else m_cube.set_color(-1, render_color); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d view_model_matrix = camera.get_view_matrix() * matrix * Geometry::assemble_transform(center, angles, fullsize * Vec3d::Ones()); + const Transform3d& projection_matrix = camera.get_projection_matrix(); + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("projection_matrix", projection_matrix); + shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else glsafe(::glPushMatrix()); glsafe(::glTranslated(center.x(), center.y(), center.z())); glsafe(::glRotated(Geometry::rad2deg(angles.z()), 0.0, 0.0, 1.0)); glsafe(::glRotated(Geometry::rad2deg(angles.y()), 0.0, 1.0, 0.0)); glsafe(::glRotated(Geometry::rad2deg(angles.x()), 1.0, 0.0, 0.0)); glsafe(::glScaled(fullsize, fullsize, fullsize)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_cube.render(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) @@ -114,7 +134,11 @@ void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const void GLGizmoBase::render_grabbers(float size) const { +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; shader->start_using(); @@ -128,11 +152,15 @@ void GLGizmoBase::render_grabbers(float size) const void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL const float mean_size = float((box.size().x() + box.size().y() + box.size().z()) / 3.0); for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i) { @@ -141,10 +169,10 @@ void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const m_grabbers[i].render_for_picking(mean_size); } } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } // help function to process grabbers diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 6f62382e1..145320462 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -49,6 +49,9 @@ protected: bool dragging{ false }; Vec3d center{ Vec3d::Zero() }; Vec3d angles{ Vec3d::Zero() }; +#if ENABLE_GL_SHADERS_ATTRIBUTES + Transform3d matrix{ Transform3d::Identity() }; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES ColorRGBA color{ ColorRGBA::WHITE() }; Grabber() = default; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 095f1e7a5..5c9b08a93 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -106,23 +106,27 @@ void GLGizmoCut::on_render() glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); - Vec3d diff = plane_center - m_old_center; + const Vec3d diff = plane_center - m_old_center; // Z changed when move with cut plane // X and Y changed when move with cutted object bool is_changed = std::abs(diff.x()) > EPSILON || - std::abs(diff.y()) > EPSILON || - std::abs(diff.z()) > EPSILON; + std::abs(diff.y()) > EPSILON || + std::abs(diff.z()) > EPSILON; m_old_center = plane_center; if (!m_plane.is_initialized() || is_changed) { m_plane.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; init_data.color = { 0.8f, 0.8f, 0.8f, 0.5f }; init_data.reserve_vertices(4); init_data.reserve_indices(6); @@ -134,12 +138,18 @@ void GLGizmoCut::on_render() init_data.add_vertex(Vec3f(min_x, max_y, plane_center.z())); // indices - init_data.add_ushort_triangle(0, 1, 2); - init_data.add_ushort_triangle(2, 3, 0); + init_data.add_triangle(0, 1, 2); + init_data.add_triangle(2, 3, 0); m_plane.init_from(std::move(init_data)); } +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + m_plane.render(); #else // Draw the cutting plane @@ -150,7 +160,7 @@ void GLGizmoCut::on_render() ::glVertex3f(max_x, max_y, plane_center.z()); ::glVertex3f(min_x, max_y, plane_center.z()); glsafe(::glEnd()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glEnable(GL_CULL_FACE)); glsafe(::glDisable(GL_BLEND)); @@ -162,12 +172,12 @@ void GLGizmoCut::on_render() glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); glsafe(::glLineWidth(m_hover_id != -1 ? 2.0f : 1.5f)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (!m_grabber_connection.is_initialized() || is_changed) { m_grabber_connection.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; init_data.color = ColorRGBA::YELLOW(); init_data.reserve_vertices(2); init_data.reserve_indices(2); @@ -177,7 +187,7 @@ void GLGizmoCut::on_render() init_data.add_vertex((Vec3f)m_grabbers[0].center.cast()); // indices - init_data.add_ushort_line(0, 1); + init_data.add_line(0, 1); m_grabber_connection.init_from(std::move(init_data)); } @@ -187,7 +197,11 @@ void GLGizmoCut::on_render() shader->stop_using(); } +#if ENABLE_GL_SHADERS_ATTRIBUTES + shader = wxGetApp().get_shader("gouraud_light_attr"); +#else shader = wxGetApp().get_shader("gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #else glsafe(::glColor3f(1.0, 1.0, 0.0)); ::glBegin(GL_LINES); @@ -196,7 +210,7 @@ void GLGizmoCut::on_render() glsafe(::glEnd()); GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (shader != nullptr) { shader->start_using(); shader->set_uniform("emission_factor", 0.1f); @@ -207,20 +221,32 @@ void GLGizmoCut::on_render() shader->stop_using(); } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + shader = wxGetApp().get_shader("flat_attr"); +#else shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()* Geometry::assemble_transform(m_cut_contours.shift)); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#else glsafe(::glPushMatrix()); glsafe(::glTranslated(m_cut_contours.shift.x(), m_cut_contours.shift.y(), m_cut_contours.shift.z())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glLineWidth(2.0f)); m_cut_contours.contours.render(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES +#if ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } void GLGizmoCut::on_render_for_picking() @@ -383,11 +409,11 @@ void GLGizmoCut::update_contours() const Polygons polys = slice_mesh(m_cut_contours.mesh.its, m_cut_z, slicing_params); if (!polys.empty()) { m_cut_contours.contours.init_from(polys, static_cast(m_cut_z)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_cut_contours.contours.set_color(ColorRGBA::WHITE()); #else m_cut_contours.contours.set_color(-1, { 1.0f, 1.0f, 1.0f, 1.0f }); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } } else if (box.center() != m_cut_contours.position) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index feb23bf45..d81b53e5f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -23,11 +23,11 @@ class GLGizmoCut : public GLGizmoBase bool m_keep_upper{ true }; bool m_keep_lower{ true }; bool m_rotate_lower{ false }; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel m_plane; GLModel m_grabber_connection; Vec3d m_old_center; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL struct CutContours { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp index e0a583f0b..48c81bc5a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp @@ -1,9 +1,13 @@ // Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro. #include "GLGizmoFlatten.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #include "slic3r/GUI/GUI_App.hpp" -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES +#include "slic3r/GUI/Plater.hpp" +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + #include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" #include "libslic3r/Geometry/ConvexHull.hpp" @@ -100,13 +104,17 @@ void GLGizmoFlatten::on_render() { const Selection& selection = m_parent.get_selection(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; shader->start_using(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); @@ -115,70 +123,96 @@ void GLGizmoFlatten::on_render() if (selection.is_single_full_instance()) { const Transform3d& m = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d view_model_matrix = camera.get_view_matrix() * + Geometry::assemble_transform(selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z() * Vec3d::UnitZ()) * m; + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#else glsafe(::glPushMatrix()); glsafe(::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z())); glsafe(::glMultMatrixd(m.data())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (this->is_plane_update_necessary()) update_planes(); for (int i = 0; i < (int)m_planes.size(); ++i) { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_planes[i].vbo.set_color(i == m_hover_id ? DEFAULT_HOVER_PLANE_COLOR : DEFAULT_PLANE_COLOR); m_planes[i].vbo.render(); #else glsafe(::glColor4fv(i == m_hover_id ? DEFAULT_HOVER_PLANE_COLOR.data() : DEFAULT_PLANE_COLOR.data())); if (m_planes[i].vbo.has_VBOs()) m_planes[i].vbo.render(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } glsafe(::glEnable(GL_CULL_FACE)); glsafe(::glDisable(GL_BLEND)); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } void GLGizmoFlatten::on_render_for_picking() { const Selection& selection = m_parent.get_selection(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; shader->start_using(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glDisable(GL_DEPTH_TEST)); glsafe(::glDisable(GL_BLEND)); if (selection.is_single_full_instance() && !wxGetKeyState(WXK_CONTROL)) { const Transform3d& m = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d view_model_matrix = camera.get_view_matrix() * + Geometry::assemble_transform(selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z() * Vec3d::UnitZ()) * m; + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#else glsafe(::glPushMatrix()); glsafe(::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z())); glsafe(::glMultMatrixd(m.data())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (this->is_plane_update_necessary()) update_planes(); for (int i = 0; i < (int)m_planes.size(); ++i) { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_planes[i].vbo.set_color(picking_color_component(i)); #else glsafe(::glColor4fv(picking_color_component(i).data())); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL m_planes[i].vbo.render(); } +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } glsafe(::glEnable(GL_CULL_FACE)); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object) @@ -393,18 +427,15 @@ void GLGizmoFlatten::update_planes() // And finally create respective VBOs. The polygon is convex with // the vertices in order, so triangulation is trivial. for (auto& plane : m_planes) { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::TriangleFan, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::index_type(plane.vertices.size()) }; + init_data.format = { GLModel::Geometry::EPrimitiveType::TriangleFan, GLModel::Geometry::EVertexLayout::P3N3 }; init_data.reserve_vertices(plane.vertices.size()); init_data.reserve_indices(plane.vertices.size()); // vertices + indices for (size_t i = 0; i < plane.vertices.size(); ++i) { init_data.add_vertex((Vec3f)plane.vertices[i].cast(), (Vec3f)plane.normal.cast()); - if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT) - init_data.add_ushort_index((unsigned short)i); - else - init_data.add_uint_index((unsigned int)i); + init_data.add_index((unsigned int)i); } plane.vbo.init_from(std::move(init_data)); #else @@ -414,7 +445,7 @@ void GLGizmoFlatten::update_planes() for (size_t i=1; i vertices; // should be in fact local in update_planes() -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel vbo; #else GLIndexedVertexArray vbo; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL Vec3d normal; float area; }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index bc0056fa6..45af12b4d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -103,11 +103,15 @@ void GLGizmoHollow::on_render_for_picking() void GLGizmoHollow::render_points(const Selection& selection, bool picking) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat_attr") : wxGetApp().get_shader("gouraud_light_attr"); +#else GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat") : wxGetApp().get_shader("gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; - + shader->start_using(); ScopeGuard guard([shader]() { shader->stop_using(); }); #else @@ -115,23 +119,34 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) if (shader) shader->start_using(); ScopeGuard guard([shader]() { if (shader) shader->stop_using(); }); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin()); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse(); + const Transform3d instance_matrix = Geometry::assemble_transform(m_c->selection_info()->get_sla_shift() * Vec3d::UnitZ()) * vol->get_instance_transformation().get_matrix(); + + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d& view_matrix = camera.get_view_matrix(); + const Transform3d& projection_matrix = camera.get_projection_matrix(); + + shader->set_uniform("projection_matrix", projection_matrix); +#else const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse(); const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix(); glsafe(::glPushMatrix()); glsafe(::glTranslated(0.0, 0.0, m_c->selection_info()->get_sla_shift())); glsafe(::glMultMatrixd(instance_matrix.data())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES ColorRGBA render_color; const sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes; - size_t cache_size = drain_holes.size(); + const size_t cache_size = drain_holes.size(); for (size_t i = 0; i < cache_size; ++i) { const sla::DrainHole& drain_hole = drain_holes[i]; - const bool& point_selected = m_selected[i]; + const bool point_selected = m_selected[i]; if (is_mesh_point_clipped(drain_hole.pos.cast())) continue; @@ -151,16 +166,20 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) render_color = point_selected ? ColorRGBA(1.0f, 0.3f, 0.3f, 0.5f) : ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f); } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_cylinder.set_color(render_color); #else const_cast(&m_cylinder)->set_color(-1, render_color); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d hole_matrix = Geometry::assemble_transform(drain_hole.pos.cast()) * instance_scaling_matrix_inverse; +#else glsafe(::glPushMatrix()); glsafe(::glTranslatef(drain_hole.pos.x(), drain_hole.pos.y(), drain_hole.pos.z())); glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (vol->is_left_handed()) glFrontFace(GL_CW); @@ -168,18 +187,31 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) // Matrices set, we can render the point mark now. Eigen::Quaterniond q; q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * (-drain_hole.normal).cast()); - Eigen::AngleAxisd aa(q); + const Eigen::AngleAxisd aa(q); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d view_model_matrix = view_matrix * instance_matrix * hole_matrix * Transform3d(aa.toRotationMatrix()) * + Geometry::assemble_transform(-drain_hole.height * Vec3d::UnitZ(), Vec3d::Zero(), Vec3d(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength)); + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis().x(), aa.axis().y(), aa.axis().z())); glsafe(::glTranslated(0., 0., -drain_hole.height)); glsafe(::glScaled(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_cylinder.render(); if (vol->is_left_handed()) glFrontFace(GL_CCW); - glsafe(::glPopMatrix()); + +#if !ENABLE_GL_SHADERS_ATTRIBUTES + glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } - glsafe(::glPopMatrix()); +#if !ENABLE_GL_SHADERS_ATTRIBUTES + glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } bool GLGizmoHollow::is_mesh_point_clipped(const Vec3d& point) const diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index 24e90fceb..13c8a71c6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -170,7 +170,11 @@ void GLGizmoMmuSegmentation::data_changed() void GLGizmoMmuSegmentation::render_triangles(const Selection &selection) const { ClippingPlaneDataWrapper clp_data = this->get_clipping_plane_data(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + auto* shader = wxGetApp().get_shader("mm_gouraud_attr"); +#else auto *shader = wxGetApp().get_shader("mm_gouraud"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (!shader) return; shader->start_using(); @@ -188,18 +192,32 @@ void GLGizmoMmuSegmentation::render_triangles(const Selection &selection) const const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); - bool is_left_handed = trafo_matrix.matrix().determinant() < 0.; + const bool is_left_handed = trafo_matrix.matrix().determinant() < 0.0; if (is_left_handed) glsafe(::glFrontFace(GL_CW)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d matrix = camera.get_view_matrix() * trafo_matrix; + shader->set_uniform("view_model_matrix", matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else glsafe(::glPushMatrix()); glsafe(::glMultMatrixd(trafo_matrix.data())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES shader->set_uniform("volume_world_matrix", trafo_matrix); shader->set_uniform("volume_mirrored", is_left_handed); +#if ENABLE_GL_SHADERS_ATTRIBUTES + m_triangle_selectors[mesh_id]->render(m_imgui, trafo_matrix); +#else m_triangle_selectors[mesh_id]->render(m_imgui); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES if (is_left_handed) glsafe(::glFrontFace(GL_CCW)); } @@ -568,7 +586,11 @@ ColorRGBA GLGizmoMmuSegmentation::get_cursor_sphere_right_button_color() const return color; } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void TriangleSelectorMmGui::render(ImGuiWrapper* imgui, const Transform3d& matrix) +#else void TriangleSelectorMmGui::render(ImGuiWrapper *imgui) +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { if (m_update_render_data) update_render_data(); @@ -576,7 +598,11 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui) auto *shader = wxGetApp().get_current_shader(); if (!shader) return; +#if ENABLE_GL_SHADERS_ATTRIBUTES + assert(shader->get_name() == "mm_gouraud_attr"); +#else assert(shader->get_name() == "mm_gouraud"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES for (size_t color_idx = 0; color_idx < m_gizmo_scene.triangle_indices.size(); ++color_idx) if (m_gizmo_scene.has_VBOs(color_idx)) { @@ -588,8 +614,12 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui) m_gizmo_scene.render(color_idx); } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + render_paint_contour(matrix); +#else render_paint_contour(); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #else if (m_paint_contour.has_VBO()) { ScopeGuard guard_mm_gouraud([shader]() { shader->start_using(); }); @@ -604,7 +634,7 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui) contour_shader->stop_using(); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL m_update_render_data = false; } @@ -639,7 +669,7 @@ void TriangleSelectorMmGui::update_render_data() m_gizmo_scene.finalize_triangle_indices(); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL update_paint_contour(); #else m_paint_contour.release_geometry(); @@ -660,7 +690,7 @@ void TriangleSelectorMmGui::update_render_data() m_paint_contour.contour_indices_size = m_paint_contour.contour_indices.size(); m_paint_contour.finalize_geometry(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } wxString GLGizmoMmuSegmentation::handle_snapshot_action_name(bool shift_down, GLGizmoPainterBase::Button button_down) const diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp index 6f357bb6f..5d2397337 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp @@ -66,9 +66,13 @@ public: : TriangleSelectorGUI(mesh), m_colors(colors), m_default_volume_color(default_volume_color), m_gizmo_scene(2 * (colors.size() + 1)) {} ~TriangleSelectorMmGui() override = default; +#if ENABLE_GL_SHADERS_ATTRIBUTES + void render(ImGuiWrapper* imgui, const Transform3d& matrix) override; +#else // Render current selection. Transformation matrices are supposed // to be already set. void render(ImGuiWrapper* imgui) override; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES private: void update_render_data(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index c90c721cd..18acf6e9b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -2,6 +2,9 @@ #include "GLGizmoMove.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GUI_App.hpp" +#if ENABLE_GL_SHADERS_ATTRIBUTES +#include "slic3r/GUI/Plater.hpp" +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #include @@ -121,7 +124,7 @@ void GLGizmoMove3D::on_render() glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL auto render_grabber_connection = [this, ¢er](unsigned int id) { if (m_grabbers[id].enabled) { if (!m_grabber_connections[id].model.is_initialized() || !m_grabber_connections[id].old_center.isApprox(center)) { @@ -129,7 +132,7 @@ void GLGizmoMove3D::on_render() m_grabber_connections[id].model.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; init_data.color = AXES_COLOR[id]; init_data.reserve_vertices(2); init_data.reserve_indices(2); @@ -139,7 +142,7 @@ void GLGizmoMove3D::on_render() init_data.add_vertex((Vec3f)m_grabbers[id].center.cast()); // indices - init_data.add_ushort_line(0, 1); + init_data.add_line(0, 1); m_grabber_connections[id].model.init_from(std::move(init_data)); } @@ -147,18 +150,28 @@ void GLGizmoMove3D::on_render() m_grabber_connections[id].model.render(); } }; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (m_hover_id == -1) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL + +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES // draw axes for (unsigned int i = 0; i < 3; ++i) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL render_grabber_connection(i); #else if (m_grabbers[i].enabled) { @@ -168,13 +181,13 @@ void GLGizmoMove3D::on_render() ::glVertex3dv(m_grabbers[i].center.data()); glsafe(::glEnd()); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // draw grabbers render_grabbers(box); @@ -185,15 +198,30 @@ void GLGizmoMove3D::on_render() } else { // draw axis -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); + +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + render_grabber_connection(m_hover_id); shader->stop_using(); } +#if ENABLE_GL_SHADERS_ATTRIBUTES + shader = wxGetApp().get_shader("gouraud_light_attr"); +#else shader = wxGetApp().get_shader("gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #else glsafe(::glColor4fv(AXES_COLOR[m_hover_id].data())); ::glBegin(GL_LINES); @@ -202,12 +230,12 @@ void GLGizmoMove3D::on_render() glsafe(::glEnd()); GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (shader != nullptr) { shader->start_using(); shader->set_uniform("emission_factor", 0.1f); // draw grabber - float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0); + const float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0); m_grabbers[m_hover_id].render(true, mean_size); shader->stop_using(); } @@ -254,18 +282,22 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box, bool picking) { - float mean_size = float((box.size().x() + box.size().y() + box.size().z()) / 3.0); - double size = m_dragging ? double(m_grabbers[axis].get_dragging_half_size(mean_size)) : double(m_grabbers[axis].get_half_size(mean_size)); + const float mean_size = float((box.size().x() + box.size().y() + box.size().z()) / 3.0); + const double size = m_dragging ? double(m_grabbers[axis].get_dragging_half_size(mean_size)) : double(m_grabbers[axis].get_half_size(mean_size)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat_attr" : "gouraud_light_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #else GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (shader == nullptr) return; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_cone.set_color((!picking && m_hover_id != -1) ? complementary(m_grabbers[axis].color) : m_grabbers[axis].color); shader->start_using(); shader->set_uniform("emission_factor", 0.1f); @@ -275,8 +307,21 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box shader->start_using(); shader->set_uniform("emission_factor", 0.1f); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + Transform3d view_model_matrix = camera.get_view_matrix() * Geometry::assemble_transform(m_grabbers[axis].center); + if (axis == X) + view_model_matrix = view_model_matrix * Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitY()); + else if (axis == Y) + view_model_matrix = view_model_matrix * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitX()); + view_model_matrix = view_model_matrix * Geometry::assemble_transform(2.0 * size * Vec3d::UnitZ(), Vec3d::Zero(), Vec3d(0.75 * size, 0.75 * size, 3.0 * size)); + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else glsafe(::glPushMatrix()); glsafe(::glTranslated(m_grabbers[axis].center.x(), m_grabbers[axis].center.y(), m_grabbers[axis].center.z())); if (axis == X) @@ -286,12 +331,15 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_cone.render(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL if (! picking) -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp index 7c7ee0486..92729c199 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp @@ -18,14 +18,14 @@ class GLGizmoMove3D : public GLGizmoBase Vec3d m_starting_box_bottom_center{ Vec3d::Zero() }; GLModel m_cone; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL struct GrabberConnection { GLModel model; Vec3d old_center{ Vec3d::Zero() }; }; std::array m_grabber_connections; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL public: GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index 768bdec25..03d60440a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -18,11 +18,11 @@ namespace Slic3r::GUI { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL std::shared_ptr GLGizmoPainterBase::s_sphere = nullptr; #else std::shared_ptr GLGizmoPainterBase::s_sphere = nullptr; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) @@ -31,13 +31,13 @@ GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& ic GLGizmoPainterBase::~GLGizmoPainterBase() { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (s_sphere != nullptr) s_sphere.reset(); #else if (s_sphere != nullptr && s_sphere->has_VBOs()) s_sphere->release_geometry(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } void GLGizmoPainterBase::data_changed() @@ -80,7 +80,11 @@ GLGizmoPainterBase::ClippingPlaneDataWrapper GLGizmoPainterBase::get_clipping_pl void GLGizmoPainterBase::render_triangles(const Selection& selection) const { +#if ENABLE_GL_SHADERS_ATTRIBUTES + auto* shader = wxGetApp().get_shader("gouraud_attr"); +#else auto* shader = wxGetApp().get_shader("gouraud"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (! shader) return; shader->start_using(); @@ -105,8 +109,16 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection) const if (is_left_handed) glsafe(::glFrontFace(GL_CW)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d matrix = camera.get_view_matrix() * trafo_matrix; + shader->set_uniform("view_model_matrix", matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else glsafe(::glPushMatrix()); glsafe(::glMultMatrixd(trafo_matrix.data())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES // For printers with multiple extruders, it is necessary to pass trafo_matrix // to the shader input variable print_box.volume_world_matrix before @@ -114,9 +126,13 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection) const // wrong transformation matrix is used for "Clipping of view". shader->set_uniform("volume_world_matrix", trafo_matrix); +#if ENABLE_GL_SHADERS_ATTRIBUTES + m_triangle_selectors[mesh_id]->render(m_imgui, trafo_matrix); +#else m_triangle_selectors[mesh_id]->render(m_imgui); glsafe(::glPopMatrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (is_left_handed) glsafe(::glFrontFace(GL_CCW)); } @@ -151,11 +167,25 @@ void GLGizmoPainterBase::render_cursor() void GLGizmoPainterBase::render_cursor_circle() { +#if !ENABLE_GL_SHADERS_ATTRIBUTES const Camera &camera = wxGetApp().plater()->get_camera(); const float zoom = float(camera.get_zoom()); const float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES - const Size cnv_size = m_parent.get_canvas_size(); + const Size cnv_size = m_parent.get_canvas_size(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const float cnv_width = float(cnv_size.get_width()); + const float cnv_height = float(cnv_size.get_height()); + if (cnv_width == 0.0f || cnv_height == 0.0f) + return; + + const float cnv_inv_width = 1.0f / cnv_width; + const float cnv_inv_height = 1.0f / cnv_height; + + const Vec2d center = m_parent.get_local_mouse_position(); + const float radius = m_cursor_radius * float(wxGetApp().plater()->get_camera().get_zoom()); +#else const float cnv_half_width = 0.5f * float(cnv_size.get_width()); const float cnv_half_height = 0.5f * float(cnv_size.get_height()); if (cnv_half_width == 0.0f || cnv_half_height == 0.0f) @@ -163,14 +193,16 @@ void GLGizmoPainterBase::render_cursor_circle() const Vec2d mouse_pos(m_parent.get_local_mouse_position().x(), m_parent.get_local_mouse_position().y()); Vec2d center(mouse_pos.x() - cnv_half_width, cnv_half_height - mouse_pos.y()); center = center * inv_zoom; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glLineWidth(1.5f)); -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL static const std::array color = { 0.f, 1.f, 0.3f }; glsafe(::glColor3fv(color.data())); -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glDisable(GL_DEPTH_TEST)); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPushMatrix()); glsafe(::glLoadIdentity()); // ensure that the circle is renderered inside the frustrum @@ -178,38 +210,57 @@ void GLGizmoPainterBase::render_cursor_circle() // ensure that the overlay fits the frustrum near z plane const double gui_scale = camera.get_gui_scale(); glsafe(::glScaled(gui_scale, gui_scale, 1.0)); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPushAttrib(GL_ENABLE_BIT)); glsafe(::glLineStipple(4, 0xAAAA)); glsafe(::glEnable(GL_LINE_STIPPLE)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (!m_circle.is_initialized() || !m_old_center.isApprox(center) || std::abs(m_old_cursor_radius - radius) > EPSILON) { + m_old_cursor_radius = radius; +#else if (!m_circle.is_initialized() || !m_old_center.isApprox(center) || std::abs(m_old_cursor_radius - m_cursor_radius) > EPSILON) { - m_old_center = center; m_old_cursor_radius = m_cursor_radius; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + m_old_center = center; 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, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 }; init_data.color = { 0.0f, 1.0f, 0.3f, 1.0f }; init_data.reserve_vertices(StepsCount); init_data.reserve_indices(StepsCount); // vertices + indices - for (unsigned short i = 0; i < StepsCount; ++i) { - const float angle = float(i * StepSize); + for (unsigned int i = 0; i < StepsCount; ++i) { + const float angle = float(i) * StepSize; +#if ENABLE_GL_SHADERS_ATTRIBUTES + 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))); +#else init_data.add_vertex(Vec2f(center.x() + ::cos(angle) * m_cursor_radius, center.y() + ::sin(angle) * m_cursor_radius)); - init_data.add_ushort_index(i); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + init_data.add_index(i); } m_circle.init_from(std::move(init_data)); } +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = GUI::wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + shader->set_uniform("view_model_matrix", Transform3d::Identity()); + shader->set_uniform("projection_matrix", Transform3d::Identity()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_circle.render(); shader->stop_using(); } @@ -218,10 +269,12 @@ void GLGizmoPainterBase::render_cursor_circle() for (double angle=0; angle<2*M_PI; angle+=M_PI/20.) ::glVertex2f(GLfloat(center.x()+m_cursor_radius*cos(angle)), GLfloat(center.y()+m_cursor_radius*sin(angle))); glsafe(::glEnd()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glPopAttrib()); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glEnable(GL_DEPTH_TEST)); } @@ -229,29 +282,35 @@ void GLGizmoPainterBase::render_cursor_circle() void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const { if (s_sphere == nullptr) { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL s_sphere = std::make_shared(); s_sphere->init_from(its_make_sphere(1.0, double(PI) / 12.0)); #else s_sphere = std::make_shared(); s_sphere->load_its_flat_shading(its_make_sphere(1.0, double(PI) / 12.0)); s_sphere->finalize_geometry(true); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; const Transform3d complete_scaling_matrix_inverse = Geometry::Transformation(trafo).get_matrix(true, true, false, true).inverse(); const bool is_left_handed = Geometry::Transformation(trafo).is_left_handed(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPushMatrix()); glsafe(::glMultMatrixd(trafo.data())); // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. glsafe(::glTranslatef(m_rr.hit.x(), m_rr.hit.y(), m_rr.hit.z())); glsafe(::glMultMatrixd(complete_scaling_matrix_inverse.data())); glsafe(::glScaled(m_cursor_radius, m_cursor_radius, m_cursor_radius)); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES if (is_left_handed) glFrontFace(GL_CW); @@ -261,26 +320,38 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const render_color = this->get_cursor_sphere_left_button_color(); else if (m_button_down == Button::Right) render_color = this->get_cursor_sphere_right_button_color(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + Transform3d view_model_matrix = camera.get_view_matrix() * trafo * + Geometry::assemble_transform(m_rr.hit.cast()) * complete_scaling_matrix_inverse * + Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), m_cursor_radius * Vec3d::Ones()); + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + assert(s_sphere != nullptr); s_sphere->set_color(render_color); #else glsafe(::glColor4fv(render_color.data())); assert(s_sphere != nullptr); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL s_sphere->render(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (is_left_handed) glFrontFace(GL_CCW); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } @@ -839,7 +910,11 @@ ColorRGBA TriangleSelectorGUI::get_seed_fill_color(const ColorRGBA& base_color) return saturate(base_color, 0.75f); } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void TriangleSelectorGUI::render(ImGuiWrapper* imgui, const Transform3d& matrix) +#else void TriangleSelectorGUI::render(ImGuiWrapper* imgui) +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { static const ColorRGBA enforcers_color = { 0.47f, 0.47f, 1.0f, 1.0f }; static const ColorRGBA blockers_color = { 1.0f, 0.44f, 0.44f, 1.0f }; @@ -852,12 +927,16 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) auto* shader = wxGetApp().get_current_shader(); if (! shader) return; +#if ENABLE_GL_SHADERS_ATTRIBUTES + assert(shader->get_name() == "gouraud_attr"); +#else assert(shader->get_name() == "gouraud"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES ScopeGuard guard([shader]() { if (shader) shader->set_uniform("offset_depth_buffer", false);}); shader->set_uniform("offset_depth_buffer", true); for (auto iva : {std::make_pair(&m_iva_enforcers, enforcers_color), std::make_pair(&m_iva_blockers, blockers_color)}) { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL iva.first->set_color(iva.second); iva.first->render(); #else @@ -865,10 +944,10 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) shader->set_uniform("uniform_color", iva.second); iva.first->render(); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL for (auto& iva : m_iva_seed_fills) { size_t color_idx = &iva - &m_iva_seed_fills.front(); const ColorRGBA& color = TriangleSelectorGUI::get_seed_fill_color(color_idx == 1 ? enforcers_color : @@ -887,10 +966,14 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) shader->set_uniform("uniform_color", color); iva.render(); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + render_paint_contour(matrix); +#else render_paint_contour(); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #else if (m_paint_contour.has_VBO()) { ScopeGuard guard_gouraud([shader]() { shader->start_using(); }); @@ -905,7 +988,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) contour_shader->stop_using(); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG if (imgui) @@ -921,7 +1004,7 @@ void TriangleSelectorGUI::update_render_data() int blc_cnt = 0; std::vector seed_fill_cnt(m_iva_seed_fills.size(), 0); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL for (auto* iva : { &m_iva_enforcers, &m_iva_blockers }) { iva->reset(); } @@ -931,26 +1014,26 @@ void TriangleSelectorGUI::update_render_data() } GLModel::Geometry iva_enforcers_data; - iva_enforcers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT }; + iva_enforcers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; GLModel::Geometry iva_blockers_data; - iva_blockers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT }; + iva_blockers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; std::array iva_seed_fills_data; for (auto& data : iva_seed_fills_data) - data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT }; + data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; #else for (auto *iva : {&m_iva_enforcers, &m_iva_blockers}) iva->release_geometry(); for (auto &iva : m_iva_seed_fills) iva.release_geometry(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL for (const Triangle &tr : m_triangles) { if (!tr.valid() || tr.is_split() || (tr.get_state() == EnforcerBlockerType::NONE && !tr.is_selected_by_seed_fill())) continue; int tr_state = int(tr.get_state()); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel::Geometry &iva = tr.is_selected_by_seed_fill() ? iva_seed_fills_data[tr_state] : tr.get_state() == EnforcerBlockerType::ENFORCER ? iva_enforcers_data : iva_blockers_data; @@ -958,7 +1041,7 @@ void TriangleSelectorGUI::update_render_data() GLIndexedVertexArray &iva = tr.is_selected_by_seed_fill() ? m_iva_seed_fills[tr_state] : tr.get_state() == EnforcerBlockerType::ENFORCER ? m_iva_enforcers : m_iva_blockers; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL int &cnt = tr.is_selected_by_seed_fill() ? seed_fill_cnt[tr_state] : tr.get_state() == EnforcerBlockerType::ENFORCER ? enf_cnt : blc_cnt; @@ -968,21 +1051,21 @@ void TriangleSelectorGUI::update_render_data() //FIXME the normal may likely be pulled from m_triangle_selectors, but it may not be worth the effort // or the current implementation may be more cache friendly. const Vec3f n = (v1 - v0).cross(v2 - v1).normalized(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL iva.add_vertex(v0, n); iva.add_vertex(v1, n); iva.add_vertex(v2, n); - iva.add_uint_triangle((unsigned int)cnt, (unsigned int)cnt + 1, (unsigned int)cnt + 2); + iva.add_triangle((unsigned int)cnt, (unsigned int)cnt + 1, (unsigned int)cnt + 2); #else iva.push_geometry(v0, n); iva.push_geometry(v1, n); iva.push_geometry(v2, n); iva.push_triangle(cnt, cnt + 1, cnt + 2); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL cnt += 3; } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (!iva_enforcers_data.is_empty()) m_iva_enforcers.init_from(std::move(iva_enforcers_data)); if (!iva_blockers_data.is_empty()) @@ -991,17 +1074,15 @@ void TriangleSelectorGUI::update_render_data() if (!iva_seed_fills_data[i].is_empty()) m_iva_seed_fills[i].init_from(std::move(iva_seed_fills_data[i])); } + + update_paint_contour(); #else for (auto *iva : {&m_iva_enforcers, &m_iva_blockers}) iva->finalize_geometry(true); for (auto &iva : m_iva_seed_fills) iva.finalize_geometry(true); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL -#if ENABLE_GLBEGIN_GLEND_REMOVAL - update_paint_contour(); -#else m_paint_contour.release_geometry(); std::vector contour_edges = this->get_seed_fill_contour(); m_paint_contour.contour_vertices.reserve(contour_edges.size() * 6); @@ -1020,10 +1101,10 @@ void TriangleSelectorGUI::update_render_data() m_paint_contour.contour_indices_size = m_paint_contour.contour_indices.size(); m_paint_contour.finalize_geometry(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL void GLPaintContour::render() const { assert(this->m_contour_VBO_id != 0); @@ -1081,7 +1162,7 @@ void GLPaintContour::release_geometry() } this->clear(); } -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL #ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui) @@ -1118,60 +1199,60 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui) INVALID }; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL for (auto& va : m_varrays) va.reset(); #else for (auto& va : m_varrays) va.release_geometry(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL std::array cnts; ::glScalef(1.01f, 1.01f, 1.01f); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL std::array varrays_data; for (auto& data : varrays_data) data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT }; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL for (int tr_id=0; tr_idadd_vertex(m_vertices[tr.verts_idxs[i]].v, Vec3f(0.0f, 0.0f, 1.0f)); } @@ -1185,11 +1266,11 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui) va->push_triangle(*cnt, *cnt + 1, *cnt + 2); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL *cnt += 3; } -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL for (int i = 0; i < 3; ++i) { if (!varrays_data[i].is_empty()) m_varrays[i].init_from(std::move(varrays_data[i])); @@ -1200,21 +1281,31 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui) // // for (auto& iva : m_iva_seed_fills) // iva.finalize_geometry(true); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLShaderProgram* curr_shader = wxGetApp().get_current_shader(); if (curr_shader != nullptr) curr_shader->stop_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES +#endif // ENABLE_LEGACY_OPENGL_REMOVAL ::glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); for (vtype i : {ORIGINAL, SPLIT, INVALID}) { -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel& va = m_varrays[i]; switch (i) { case ORIGINAL: va.set_color({ 0.0f, 0.0f, 1.0f, 1.0f }); break; @@ -1233,56 +1324,71 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui) } va.render(); } -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } ::glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); } if (curr_shader != nullptr) curr_shader->start_using(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } #endif // PRUSASLICER_TRIANGLE_SELECTOR_DEBUG -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void TriangleSelectorGUI::update_paint_contour() { m_paint_contour.reset(); GLModel::Geometry init_data; const std::vector contour_edges = this->get_seed_fill_contour(); - init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::index_type(2 * contour_edges.size()) }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(2 * contour_edges.size()); init_data.reserve_indices(2 * contour_edges.size()); +#if ENABLE_GL_SHADERS_ATTRIBUTES + init_data.color = ColorRGBA::WHITE(); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES +// // vertices + indices unsigned int vertices_count = 0; for (const Vec2i& edge : contour_edges) { init_data.add_vertex(m_vertices[edge(0)].v); init_data.add_vertex(m_vertices[edge(1)].v); vertices_count += 2; - if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT) - init_data.add_ushort_line((unsigned short)vertices_count - 2, (unsigned short)vertices_count - 1); - else - init_data.add_uint_line(vertices_count - 2, vertices_count - 1); + init_data.add_line(vertices_count - 2, vertices_count - 1); } if (!init_data.is_empty()) m_paint_contour.init_from(std::move(init_data)); } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void TriangleSelectorGUI::render_paint_contour(const Transform3d& matrix) +#else void TriangleSelectorGUI::render_paint_contour() +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { auto* curr_shader = wxGetApp().get_current_shader(); if (curr_shader != nullptr) curr_shader->stop_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + auto* contour_shader = wxGetApp().get_shader("mm_contour_attr"); +#else auto* contour_shader = wxGetApp().get_shader("mm_contour"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (contour_shader != nullptr) { contour_shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + contour_shader->set_uniform("view_model_matrix", camera.get_view_matrix() * matrix); + contour_shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + glsafe(::glDepthFunc(GL_LEQUAL)); m_paint_contour.render(); glsafe(::glDepthFunc(GL_LESS)); @@ -1293,6 +1399,6 @@ void TriangleSelectorGUI::render_paint_contour() if (curr_shader != nullptr) curr_shader->start_using(); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp index 7949e2657..64f531793 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -3,11 +3,11 @@ #include "GLGizmoBase.hpp" -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #include "slic3r/GUI/GLModel.hpp" #else #include "slic3r/GUI/3DScene.hpp" -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #include "libslic3r/ObjectID.hpp" #include "libslic3r/TriangleSelector.hpp" @@ -33,7 +33,7 @@ enum class PainterGizmoType { MMU_SEGMENTATION }; -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL class GLPaintContour { public: @@ -69,7 +69,7 @@ public: GLuint m_contour_VBO_id{0}; GLuint m_contour_EBO_id{0}; }; -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL class TriangleSelectorGUI : public TriangleSelector { public: @@ -77,10 +77,15 @@ public: : TriangleSelector(mesh) {} virtual ~TriangleSelectorGUI() = default; +#if ENABLE_GL_SHADERS_ATTRIBUTES + virtual void render(ImGuiWrapper* imgui, const Transform3d& matrix); + void render(const Transform3d& matrix) { this->render(nullptr, matrix); } +#else // Render current selection. Transformation matrices are supposed // to be already set. virtual void render(ImGuiWrapper *imgui); void render() { this->render(nullptr); } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES void request_update_render_data() { m_update_render_data = true; } @@ -98,7 +103,7 @@ protected: private: void update_render_data(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel m_iva_enforcers; GLModel m_iva_blockers; std::array m_iva_seed_fills; @@ -110,17 +115,21 @@ private: GLIndexedVertexArray m_iva_blockers; std::array m_iva_seed_fills; std::array m_varrays; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL protected: -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel m_paint_contour; void update_paint_contour(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + void render_paint_contour(const Transform3d& matrix); +#else void render_paint_contour(); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #else GLPaintContour m_paint_contour; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL }; @@ -203,11 +212,11 @@ protected: bool m_paint_on_overhangs_only = false; float m_highlight_by_angle_threshold_deg = 0.f; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel m_circle; Vec2d m_old_center{ Vec2d::Zero() }; float m_old_cursor_radius{ 0.0f }; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL static constexpr float SmartFillAngleMin = 0.0f; static constexpr float SmartFillAngleMax = 90.f; @@ -241,11 +250,11 @@ private: const Camera& camera, const std::vector& trafo_matrices) const; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL static std::shared_ptr s_sphere; #else static std::shared_ptr s_sphere; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL bool m_internal_stack_active = false; bool m_schedule_update = false; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index a09ac8057..33866c64f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -163,15 +163,31 @@ void GLGizmoRotate::on_render() glsafe(::glEnable(GL_DEPTH_TEST)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + m_grabbers.front().matrix = local_transform(selection); +#else glsafe(::glPushMatrix()); transform_to_local(selection); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + 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()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + const bool radius_changed = std::abs(m_old_radius - m_radius) > EPSILON; m_old_radius = m_radius; @@ -205,7 +221,12 @@ void GLGizmoRotate::on_render() if (m_hover_id != -1) render_angle(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL + +#if ENABLE_GL_SHADERS_ATTRIBUTES + glsafe(::glPushMatrix()); + transform_to_local(selection); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES render_grabber(box); render_grabber_extension(box, false); @@ -219,15 +240,20 @@ void GLGizmoRotate::on_render_for_picking() glsafe(::glDisable(GL_DEPTH_TEST)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + m_grabbers.front().matrix = local_transform(selection); +#else glsafe(::glPushMatrix()); - transform_to_local(selection); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES const BoundingBoxf3& box = selection.get_bounding_box(); render_grabbers_for_picking(box); render_grabber_extension(box, true); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } void GLGizmoRotate3D::on_render_input_window(float x, float y, float bottom_limit) @@ -260,26 +286,26 @@ void GLGizmoRotate3D::load_rotoptimize_state() } } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void GLGizmoRotate::render_circle(const ColorRGBA& color, bool radius_changed) #else void GLGizmoRotate::render_circle() const -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (!m_circle.is_initialized() || radius_changed) { m_circle.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(ScaleStepsCount); init_data.reserve_indices(ScaleStepsCount); // vertices + indices - for (unsigned short i = 0; i < ScaleStepsCount; ++i) { + for (unsigned int i = 0; i < ScaleStepsCount; ++i) { const float angle = float(i * ScaleStepRad); init_data.add_vertex(Vec3f(::cos(angle) * m_radius, ::sin(angle) * m_radius, 0.0f)); - init_data.add_ushort_index(i); + init_data.add_index(i); } m_circle.init_from(std::move(init_data)); @@ -297,29 +323,29 @@ void GLGizmoRotate::render_circle() const ::glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z); } glsafe(::glEnd()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void GLGizmoRotate::render_scale(const ColorRGBA& color, bool radius_changed) #else void GLGizmoRotate::render_scale() const -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { const float out_radius_long = m_snap_fine_out_radius; const float out_radius_short = m_radius * (1.0f + 0.5f * ScaleLongTooth); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (!m_scale.is_initialized() || radius_changed) { m_scale.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(2 * ScaleStepsCount); init_data.reserve_indices(2 * ScaleStepsCount); // vertices + indices - for (unsigned short i = 0; i < ScaleStepsCount; ++i) { + for (unsigned int i = 0; i < ScaleStepsCount; ++i) { const float angle = float(i * ScaleStepRad); const float cosa = ::cos(angle); const float sina = ::sin(angle); @@ -328,10 +354,12 @@ void GLGizmoRotate::render_scale() const const float out_x = (i % ScaleLongEvery == 0) ? cosa * out_radius_long : cosa * out_radius_short; const float out_y = (i % ScaleLongEvery == 0) ? sina * out_radius_long : sina * out_radius_short; + // vertices init_data.add_vertex(Vec3f(in_x, in_y, 0.0f)); init_data.add_vertex(Vec3f(out_x, out_y, 0.0f)); - init_data.add_ushort_index(i * 2); - init_data.add_ushort_index(i * 2 + 1); + + // indices + init_data.add_line(i * 2, i * 2 + 1); } m_scale.init_from(std::move(init_data)); @@ -355,30 +383,30 @@ void GLGizmoRotate::render_scale() const ::glVertex3f((GLfloat)out_x, (GLfloat)out_y, (GLfloat)out_z); } glsafe(::glEnd()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void GLGizmoRotate::render_snap_radii(const ColorRGBA& color, bool radius_changed) #else void GLGizmoRotate::render_snap_radii() const -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { const float step = 2.0f * float(PI) / float(SnapRegionsCount); const float in_radius = m_radius / 3.0f; const float out_radius = 2.0f * in_radius; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (!m_snap_radii.is_initialized() || radius_changed) { m_snap_radii.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(2 * ScaleStepsCount); init_data.reserve_indices(2 * ScaleStepsCount); // vertices + indices - for (unsigned short i = 0; i < ScaleStepsCount; ++i) { + for (unsigned int i = 0; i < ScaleStepsCount; ++i) { const float angle = float(i * step); const float cosa = ::cos(angle); const float sina = ::sin(angle); @@ -387,10 +415,12 @@ void GLGizmoRotate::render_snap_radii() const const float out_x = cosa * out_radius; const float out_y = sina * out_radius; + // vertices init_data.add_vertex(Vec3f(in_x, in_y, 0.0f)); init_data.add_vertex(Vec3f(out_x, out_y, 0.0f)); - init_data.add_ushort_index(i * 2); - init_data.add_ushort_index(i * 2 + 1); + + // indices + init_data.add_line(i * 2, i * 2 + 1); } m_snap_radii.init_from(std::move(init_data)); @@ -414,17 +444,17 @@ void GLGizmoRotate::render_snap_radii() const ::glVertex3f((GLfloat)out_x, (GLfloat)out_y, (GLfloat)out_z); } glsafe(::glEnd()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void GLGizmoRotate::render_reference_radius(const ColorRGBA& color, bool radius_changed) { if (!m_reference_radius.is_initialized() || radius_changed) { m_reference_radius.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(2); init_data.reserve_indices(2); @@ -433,7 +463,7 @@ void GLGizmoRotate::render_reference_radius(const ColorRGBA& color, bool radius_ init_data.add_vertex(Vec3f(m_radius * (1.0f + GrabberOffset), 0.0f, 0.0f)); // indices - init_data.add_ushort_line(0, 1); + init_data.add_line(0, 1); m_reference_radius.init_from(std::move(init_data)); } @@ -449,18 +479,18 @@ void GLGizmoRotate::render_reference_radius() const ::glVertex3f((GLfloat)(m_radius * (1.0f + GrabberOffset)), 0.0f, 0.0f); glsafe(::glEnd()); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void GLGizmoRotate::render_angle_arc(const ColorRGBA& color, bool radius_changed) #else void GLGizmoRotate::render_angle() const -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { const float step_angle = float(m_angle) / float(AngleResolution); const float ex_radius = m_radius * (1.0f + GrabberOffset); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL const bool angle_changed = std::abs(m_old_angle - m_angle) > EPSILON; m_old_angle = m_angle; @@ -468,15 +498,15 @@ void GLGizmoRotate::render_angle() const m_angle_arc.reset(); if (m_angle > 0.0f) { GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(1 + AngleResolution); init_data.reserve_indices(1 + AngleResolution); // vertices + indices - for (unsigned short i = 0; i <= AngleResolution; ++i) { + for (unsigned int i = 0; i <= AngleResolution; ++i) { const float angle = float(i) * step_angle; init_data.add_vertex(Vec3f(::cos(angle) * ex_radius, ::sin(angle) * ex_radius, 0.0f)); - init_data.add_ushort_index(i); + init_data.add_index(i); } m_angle_arc.init_from(std::move(init_data)); @@ -495,10 +525,10 @@ void GLGizmoRotate::render_angle() const ::glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z); } glsafe(::glEnd()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void GLGizmoRotate::render_grabber_connection(const ColorRGBA& color, bool radius_changed) { if (!m_grabber_connection.model.is_initialized() || radius_changed || !m_grabber_connection.old_center.isApprox(m_grabbers.front().center)) { @@ -506,7 +536,7 @@ void GLGizmoRotate::render_grabber_connection(const ColorRGBA& color, bool radiu m_grabber_connection.old_center = m_grabbers.front().center; GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(2); init_data.reserve_indices(2); @@ -515,7 +545,7 @@ void GLGizmoRotate::render_grabber_connection(const ColorRGBA& color, bool radiu init_data.add_vertex((Vec3f)m_grabbers.front().center.cast()); // indices - init_data.add_ushort_line(0, 1); + init_data.add_line(0, 1); m_grabber_connection.model.init_from(std::move(init_data)); } @@ -523,11 +553,11 @@ void GLGizmoRotate::render_grabber_connection(const ColorRGBA& color, bool radiu m_grabber_connection.model.set_color(color); m_grabber_connection.model.render(); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL void GLGizmoRotate::render_grabber(const BoundingBoxf3& box) { -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL const double grabber_radius = double(m_radius) * (1.0 + double(GrabberOffset)); m_grabbers[0].center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0); m_grabbers[0].angles.z() = m_angle; @@ -538,7 +568,7 @@ void GLGizmoRotate::render_grabber(const BoundingBoxf3& box) ::glVertex3f(0.0f, 0.0f, 0.0f); ::glVertex3dv(m_grabbers[0].center.data()); glsafe(::glEnd()); -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL m_grabbers.front().color = m_highlight_color; render_grabbers(box); @@ -549,8 +579,12 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick const float mean_size = float((box.size().x() + box.size().y() + box.size().z()) / 3.0); const double size = m_dragging ? double(m_grabbers.front().get_dragging_half_size(mean_size)) : double(m_grabbers.front().get_half_size(mean_size)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat_attr" : "gouraud_light_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; @@ -568,17 +602,38 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick shader->start_using(); shader->set_uniform("emission_factor", 0.1f); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL const Vec3d& center = m_grabbers.front().center; +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d& view_matrix = camera.get_view_matrix(); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + + Transform3d view_model_matrix = view_matrix * m_grabbers.front().matrix * + Geometry::assemble_transform(center, Vec3d(0.5 * PI, 0.0, m_angle)) * + Geometry::assemble_transform(2.0 * size * Vec3d::UnitZ(), Vec3d::Zero(), Vec3d(0.75 * size, 0.75 * size, 3.0 * size)); + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else glsafe(::glPushMatrix()); glsafe(::glTranslated(center.x(), center.y(), center.z())); glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_cone.render(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + view_model_matrix = view_matrix * m_grabbers.front().matrix * + Geometry::assemble_transform(center, Vec3d(-0.5 * PI, 0.0, m_angle)) * + Geometry::assemble_transform(2.0 * size * Vec3d::UnitZ(), Vec3d::Zero(), Vec3d(0.75 * size, 0.75 * size, 3.0 * size)); + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else glsafe(::glPopMatrix()); glsafe(::glPushMatrix()); glsafe(::glTranslated(center.x(), center.y(), center.z())); @@ -586,15 +641,50 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_cone.render(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL if (! picking) -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); } +#if ENABLE_GL_SHADERS_ATTRIBUTES +Transform3d GLGizmoRotate::local_transform(const Selection& selection) const +{ + Transform3d ret; + + switch (m_axis) + { + case X: + { + ret = Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, 0.5 * PI, 0.0)) * Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, 0.0, -0.5 * PI)); + break; + } + case Y: + { + ret = Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, 0.0, -0.5 * PI)) * Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, -0.5 * PI, 0.0)); + break; + } + default: + case Z: + { + ret = Transform3d::Identity(); + break; + } + } + + if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes()) + ret = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(true, false, true, true) * ret; + + return Geometry::assemble_transform(m_center) * ret; +} +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + void GLGizmoRotate::transform_to_local(const Selection& selection) const { glsafe(::glTranslated(m_center.x(), m_center.y(), m_center.z())); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp index d0474df0e..c31b1f6f0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp @@ -36,7 +36,7 @@ private: float m_snap_fine_out_radius{ 0.0f }; GLModel m_cone; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel m_circle; GLModel m_scale; GLModel m_snap_radii; @@ -51,7 +51,7 @@ private: float m_old_radius{ 0.0f }; float m_old_hover_radius{ 0.0f }; float m_old_angle{ 0.0f }; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL ColorRGBA m_drag_color; ColorRGBA m_highlight_color; @@ -89,7 +89,7 @@ protected: void on_render_for_picking() override; private: -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void render_circle(const ColorRGBA& color, bool radius_changed); void render_scale(const ColorRGBA& color, bool radius_changed); void render_snap_radii(const ColorRGBA& color, bool radius_changed); @@ -102,10 +102,14 @@ private: void render_snap_radii() const; void render_reference_radius() const; void render_angle() const; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL void render_grabber(const BoundingBoxf3& box); void render_grabber_extension(const BoundingBoxf3& box, bool picking); +#if ENABLE_GL_SHADERS_ATTRIBUTES + Transform3d local_transform(const Selection& selection) const; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + void transform_to_local(const Selection& selection) const; // returns the intersection of the mouse ray with the plane perpendicular to the gizmo axis, in local coordinate Vec3d mouse_position_in_local_plane(const Linef3& mouse_ray, const Selection& selection) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index f7565a483..373a2396d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -2,6 +2,9 @@ #include "GLGizmoScale.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GUI_App.hpp" +#if ENABLE_GL_SHADERS_ATTRIBUTES +#include "slic3r/GUI/Plater.hpp" +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #include @@ -22,7 +25,7 @@ GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filen , m_drag_color(DEFAULT_DRAG_COLOR) , m_highlight_color(DEFAULT_HIGHLIGHT_COLOR) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_grabber_connections[0].grabber_indices = { 0, 1 }; m_grabber_connections[1].grabber_indices = { 2, 3 }; m_grabber_connections[2].grabber_indices = { 4, 5 }; @@ -30,7 +33,7 @@ GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filen m_grabber_connections[4].grabber_indices = { 7, 8 }; m_grabber_connections[5].grabber_indices = { 8, 9 }; m_grabber_connections[6].grabber_indices = { 9, 6 }; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } std::string GLGizmoScale3D::get_tooltip() const @@ -215,11 +218,11 @@ void GLGizmoScale3D::on_render() m_box = selection.get_bounding_box(); const Vec3d& center = m_box.center(); - Vec3d offset_x = offsets_transform * Vec3d((double)Offset, 0.0, 0.0); - Vec3d offset_y = offsets_transform * Vec3d(0.0, (double)Offset, 0.0); - Vec3d offset_z = offsets_transform * Vec3d(0.0, 0.0, (double)Offset); + const Vec3d offset_x = offsets_transform * Vec3d((double)Offset, 0.0, 0.0); + const Vec3d offset_y = offsets_transform * Vec3d(0.0, (double)Offset, 0.0); + const Vec3d offset_z = offsets_transform * Vec3d(0.0, 0.0, (double)Offset); - bool ctrl_down = (m_dragging && m_starting.ctrl_down) || (!m_dragging && wxGetKeyState(WXK_CONTROL)); + const bool ctrl_down = (m_dragging && m_starting.ctrl_down) || (!m_dragging && wxGetKeyState(WXK_CONTROL)); // x axis m_grabbers[0].center = m_transform * Vec3d(m_box.min.x(), center.y(), center.z()) - offset_x; @@ -257,14 +260,23 @@ void GLGizmoScale3D::on_render() const BoundingBoxf3& selection_box = selection.get_bounding_box(); - float grabber_mean_size = (float)((selection_box.size().x() + selection_box.size().y() + selection_box.size().z()) / 3.0); + const float grabber_mean_size = (float)((selection_box.size().x() + selection_box.size().y() + selection_box.size().z()) / 3.0); if (m_hover_id == -1) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // draw connections +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (m_grabbers[0].enabled && m_grabbers[1].enabled) render_grabbers_connection(0, 1, m_grabbers[0].color); if (m_grabbers[2].enabled && m_grabbers[3].enabled) @@ -296,23 +308,36 @@ void GLGizmoScale3D::on_render() render_grabbers_connection(7, 8); render_grabbers_connection(8, 9); render_grabbers_connection(9, 6); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL // draw grabbers render_grabbers(grabber_mean_size); } else if (m_hover_id == 0 || m_hover_id == 1) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // draw connections +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES render_grabbers_connection(0, 1, m_grabbers[0].color); shader->stop_using(); } // draw grabbers +#if ENABLE_GL_SHADERS_ATTRIBUTES + shader = wxGetApp().get_shader("gouraud_light_attr"); +#else shader = wxGetApp().get_shader("gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #else // draw connection glsafe(::glColor4fv(m_grabbers[0].color.data())); @@ -320,7 +345,7 @@ void GLGizmoScale3D::on_render() // draw grabbers GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (shader != nullptr) { shader->start_using(); shader->set_uniform("emission_factor", 0.1f); @@ -330,17 +355,30 @@ void GLGizmoScale3D::on_render() } } else if (m_hover_id == 2 || m_hover_id == 3) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // draw connections +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES render_grabbers_connection(2, 3, m_grabbers[2].color); shader->stop_using(); } // draw grabbers +#if ENABLE_GL_SHADERS_ATTRIBUTES + shader = wxGetApp().get_shader("gouraud_light_attr"); +#else shader = wxGetApp().get_shader("gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #else // draw connection glsafe(::glColor4fv(m_grabbers[2].color.data())); @@ -348,7 +386,7 @@ void GLGizmoScale3D::on_render() // draw grabbers GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (shader != nullptr) { shader->start_using(); shader->set_uniform("emission_factor", 0.1f); @@ -358,17 +396,30 @@ void GLGizmoScale3D::on_render() } } else if (m_hover_id == 4 || m_hover_id == 5) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // draw connections +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES render_grabbers_connection(4, 5, m_grabbers[4].color); shader->stop_using(); } // draw grabbers +#if ENABLE_GL_SHADERS_ATTRIBUTES + shader = wxGetApp().get_shader("gouraud_light_attr"); +#else shader = wxGetApp().get_shader("gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #else // draw connection glsafe(::glColor4fv(m_grabbers[4].color.data())); @@ -376,7 +427,7 @@ void GLGizmoScale3D::on_render() // draw grabbers GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (shader != nullptr) { shader->start_using(); shader->set_uniform("emission_factor", 0.1f); @@ -386,11 +437,20 @@ void GLGizmoScale3D::on_render() } } else if (m_hover_id >= 6) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // draw connections +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES render_grabbers_connection(6, 7, m_drag_color); render_grabbers_connection(7, 8, m_drag_color); render_grabbers_connection(8, 9, m_drag_color); @@ -399,7 +459,11 @@ void GLGizmoScale3D::on_render() } // draw grabbers +#if ENABLE_GL_SHADERS_ATTRIBUTES + shader = wxGetApp().get_shader("gouraud_light_attr"); +#else shader = wxGetApp().get_shader("gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #else // draw connection glsafe(::glColor4fv(m_drag_color.data())); @@ -410,7 +474,7 @@ void GLGizmoScale3D::on_render() // draw grabbers GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL if (shader != nullptr) { shader->start_using(); shader->set_uniform("emission_factor", 0.1f); @@ -428,7 +492,7 @@ void GLGizmoScale3D::on_render_for_picking() render_grabbers_for_picking(m_parent.get_selection().get_bounding_box()); } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int id_2, const ColorRGBA& color) { auto grabber_connection = [this](unsigned int id_1, unsigned int id_2) { @@ -451,7 +515,7 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int m_grabber_connections[id].model.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(2); init_data.reserve_indices(2); @@ -460,7 +524,7 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int init_data.add_vertex((Vec3f)m_grabbers[id_2].center.cast()); // indices - init_data.add_ushort_line(0, 1); + init_data.add_line(0, 1); m_grabber_connections[id].model.init_from(std::move(init_data)); } @@ -479,7 +543,7 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int glsafe(::glEnd()); } } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp index e0a49cdbf..f4efe052a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp @@ -33,7 +33,7 @@ class GLGizmoScale3D : public GLGizmoBase double m_snap_step{ 0.05 }; StartingData m_starting; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL struct GrabberConnection { GLModel model; @@ -42,7 +42,7 @@ class GLGizmoScale3D : public GLGizmoBase Vec3d old_v2{ Vec3d::Zero() }; }; std::array m_grabber_connections; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL ColorRGBA m_base_color; ColorRGBA m_drag_color; @@ -77,11 +77,11 @@ protected: virtual void on_render_for_picking() override; private: -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void render_grabbers_connection(unsigned int id_1, unsigned int id_2, const ColorRGBA& color); #else void render_grabbers_connection(unsigned int id_1, unsigned int id_2) const; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL void do_scale_along_axis(Axis axis, const UpdateData& data); void do_scale_uniform(const UpdateData& data); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp index 1b4c751d4..1a383187c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp @@ -651,7 +651,7 @@ void GLGizmoSimplify::init_model() } assert(volume != nullptr); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL // set actual triangle count m_triangle_count += volume->mesh().its.indices.size(); #else @@ -659,17 +659,17 @@ void GLGizmoSimplify::init_model() // set actual triangle count m_triangle_count += its.indices.size(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL assert(m_glmodels.find(id) == m_glmodels.end()); GLModel &glmodel = m_glmodels[id]; // create new glmodel -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL glmodel.init_from(volume->mesh()); glmodel.set_color(selected_volume->color); #else glmodel.init_from(its); glmodel.set_color(-1,selected_volume->color); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL m_parent.toggle_model_objects_visibility(false, info->model_object(), info->get_active_instance(), @@ -698,11 +698,11 @@ void GLGizmoSimplify::update_model(const State::Data &data) // when not reset it keeps old shape glmodel.reset(); glmodel.init_from(its); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL glmodel.set_color(color); #else glmodel.set_color(-1, color); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL m_triangle_count += its.indices.size(); } @@ -737,27 +737,53 @@ void GLGizmoSimplify::on_render() GLModel &glmodel = it->second; const Transform3d trafo_matrix = selected_volume->world_matrix(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + auto* gouraud_shader = wxGetApp().get_shader("gouraud_light_attr"); +#else glsafe(::glPushMatrix()); glsafe(::glMultMatrixd(trafo_matrix.data())); auto *gouraud_shader = wxGetApp().get_shader("gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPushAttrib(GL_DEPTH_TEST)); glsafe(::glEnable(GL_DEPTH_TEST)); gouraud_shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d view_model_matrix = camera.get_view_matrix() * trafo_matrix; + gouraud_shader->set_uniform("view_model_matrix", view_model_matrix); + gouraud_shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + gouraud_shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES glmodel.render(); gouraud_shader->stop_using(); if (m_show_wireframe) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + auto* contour_shader = wxGetApp().get_shader("mm_contour_attr"); +#else auto *contour_shader = wxGetApp().get_shader("mm_contour"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES contour_shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + contour_shader->set_uniform("view_model_matrix", view_model_matrix); + contour_shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + const ColorRGBA color = glmodel.get_color(); + glmodel.set_color(ColorRGBA::WHITE()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glLineWidth(1.0f)); glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); glmodel.render(); glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + glmodel.set_color(color); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES contour_shader->stop_using(); } glsafe(::glPopAttrib()); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 3cdc4e33a..4253c1a92 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -129,8 +129,12 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) if (! has_points && ! has_holes) return; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat_attr") : wxGetApp().get_shader("gouraud_light_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; @@ -144,16 +148,26 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) if (shader != nullptr) shader->stop_using(); }); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin()); const Transform3d instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse(); - const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix(); - const float z_shift = m_c->selection_info()->get_sla_shift(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d instance_matrix = Geometry::assemble_transform(m_c->selection_info()->get_sla_shift() * Vec3d::UnitZ()) * vol->get_instance_transformation().get_matrix(); + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d& view_matrix = camera.get_view_matrix(); + const Transform3d& projection_matrix = camera.get_projection_matrix(); + + shader->set_uniform("projection_matrix", projection_matrix); +#else + const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix(); + + const float z_shift = m_c->selection_info()->get_sla_shift(); glsafe(::glPushMatrix()); glsafe(::glTranslated(0.0, 0.0, z_shift)); glsafe(::glMultMatrixd(instance_matrix.data())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES ColorRGBA render_color; for (size_t i = 0; i < cache_size; ++i) { @@ -185,7 +199,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) } } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_cone.set_color(render_color); m_sphere.set_color(render_color); if (!picking) @@ -193,13 +207,17 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) m_cone.set_color(-1, render_color); m_sphere.set_color(-1, render_color); if (shader && !picking) -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL shader->set_uniform("emission_factor", 0.5f); // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d support_matrix = Geometry::assemble_transform(support_point.pos.cast()) * instance_scaling_matrix_inverse; +#else glsafe(::glPushMatrix()); glsafe(::glTranslatef(support_point.pos.x(), support_point.pos.y(), support_point.pos.z())); glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (vol->is_left_handed()) glFrontFace(GL_CW); @@ -212,68 +230,108 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) m_c->raycaster()->raycaster()->get_closest_point(m_editing_cache[i].support_point.pos, &m_editing_cache[i].normal); Eigen::Quaterniond q; - q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast()); + q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast()); const Eigen::AngleAxisd aa(q); - glsafe(::glPushMatrix()); - glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis().x(), aa.axis().y(), aa.axis().z())); const double cone_radius = 0.25; // mm const double cone_height = 0.75; +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d view_model_matrix = view_matrix * instance_matrix * support_matrix * Transform3d(aa.toRotationMatrix()) * + Geometry::assemble_transform((cone_height + support_point.head_front_radius * RenderPointScale) * Vec3d::UnitZ(), + Vec3d(PI, 0.0, 0.0), Vec3d(cone_radius, cone_radius, cone_height)); + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else + glsafe(::glPushMatrix()); + glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis().x(), aa.axis().y(), aa.axis().z())); glsafe(::glTranslatef(0.f, 0.f, cone_height + support_point.head_front_radius * RenderPointScale)); glsafe(::glRotated(180., 1., 0., 0.)); glsafe(::glScaled(cone_radius, cone_radius, cone_height)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_cone.render(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } const double radius = (double)support_point.head_front_radius * RenderPointScale; +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d view_model_matrix = view_matrix * instance_matrix * support_matrix * + Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), radius * Vec3d::Ones()); + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else + glsafe(::glPushMatrix()); glsafe(::glScaled(radius, radius, radius)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_sphere.render(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES + glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES if (vol->is_left_handed()) glFrontFace(GL_CCW); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } // Now render the drain holes: if (has_holes && ! picking) { render_color = { 0.7f, 0.7f, 0.7f, 0.7f }; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_cylinder.set_color(render_color); #else m_cylinder.set_color(-1, render_color); if (shader != nullptr) -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL shader->set_uniform("emission_factor", 0.5f); for (const sla::DrainHole& drain_hole : m_c->selection_info()->model_object()->sla_drain_holes) { if (is_mesh_point_clipped(drain_hole.pos.cast())) continue; +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d hole_matrix = Geometry::assemble_transform(drain_hole.pos.cast()) * instance_scaling_matrix_inverse; +#else // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. glsafe(::glPushMatrix()); glsafe(::glTranslatef(drain_hole.pos.x(), drain_hole.pos.y(), drain_hole.pos.z())); glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (vol->is_left_handed()) glFrontFace(GL_CW); // Matrices set, we can render the point mark now. - Eigen::Quaterniond q; - q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * (-drain_hole.normal).cast()); + q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * (-drain_hole.normal).cast()); const Eigen::AngleAxisd aa(q); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d view_model_matrix = view_matrix * instance_matrix * hole_matrix * Transform3d(aa.toRotationMatrix()) * + Geometry::assemble_transform(-drain_hole.height * Vec3d::UnitZ(), Vec3d::Zero(), Vec3d(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength)); + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis().x(), aa.axis().y(), aa.axis().z())); glsafe(::glTranslated(0., 0., -drain_hole.height)); glsafe(::glScaled(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_cylinder.render(); if (vol->is_left_handed()) glFrontFace(GL_CCW); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } } +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index 1e49ebc8c..0d6ec1eb0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -209,27 +209,32 @@ void InstancesHider::render_cut() const ClippingPlane clp = *get_pool()->object_clipper()->get_clipping_plane(); clp.set_normal(-clp.get_normal()); clipper->set_limiting_plane(clp); - } else + } + else clipper->set_limiting_plane(ClippingPlane::ClipsNothing()); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPushMatrix()); -#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES +#if !ENABLE_LEGACY_OPENGL_REMOVAL if (mv->is_model_part()) glsafe(::glColor3f(0.8f, 0.3f, 0.0f)); else { const ColorRGBA color = color_from_model_volume(*mv); glsafe(::glColor4fv(color.data())); } -#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glPushAttrib(GL_DEPTH_TEST)); glsafe(::glDisable(GL_DEPTH_TEST)); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL clipper->render_cut(mv->is_model_part() ? ColorRGBA(0.8f, 0.3f, 0.0f, 1.0f) : color_from_model_volume(*mv)); #else clipper->render_cut(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glPopAttrib()); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES ++clipper_id; } @@ -410,11 +415,11 @@ void ObjectClipper::render_cut() const return; const SelectionInfo* sel_info = get_pool()->selection_info(); const ModelObject* mo = sel_info->model_object(); - Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation(); + const Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation(); size_t clipper_id = 0; for (const ModelVolume* mv : mo->volumes) { - Geometry::Transformation vol_trafo = mv->get_transformation(); + const Geometry::Transformation vol_trafo = mv->get_transformation(); Geometry::Transformation trafo = inst_trafo * vol_trafo; trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift())); @@ -422,14 +427,18 @@ void ObjectClipper::render_cut() const clipper->set_plane(*m_clp); clipper->set_transformation(trafo); clipper->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), -SINKING_Z_THRESHOLD)); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPushMatrix()); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES +#if ENABLE_LEGACY_OPENGL_REMOVAL clipper->render_cut({ 1.0f, 0.37f, 0.0f, 1.0f }); #else glsafe(::glColor3f(1.0f, 0.37f, 0.0f)); clipper->render_cut(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES ++clipper_id; } @@ -520,7 +529,7 @@ void SupportsClipper::render_cut() const const SelectionInfo* sel_info = get_pool()->selection_info(); const ModelObject* mo = sel_info->model_object(); - Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation(); + const Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation(); //Geometry::Transformation vol_trafo = mo->volumes.front()->get_transformation(); Geometry::Transformation trafo = inst_trafo;// * vol_trafo; trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift())); @@ -539,14 +548,18 @@ void SupportsClipper::render_cut() const m_clipper->set_plane(*ocl->get_clipping_plane()); m_clipper->set_transformation(supports_trafo); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPushMatrix()); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES +#if ENABLE_LEGACY_OPENGL_REMOVAL m_clipper->render_cut({ 1.0f, 0.f, 0.37f, 1.0f }); #else glsafe(::glColor3f(1.0f, 0.f, 0.37f)); m_clipper->render_cut(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index fba02963f..21b55ea69 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -124,7 +124,17 @@ bool GLGizmosManager::init() return true; } -bool GLGizmosManager::init_arrow(const BackgroundTexture::Metadata& arrow_texture) +#if ENABLE_GL_SHADERS_ATTRIBUTES +bool GLGizmosManager::init_arrow(const std::string& filename) +{ + if (m_arrow_texture.get_id() != 0) + return true; + + const std::string path = resources_dir() + "/icons/"; + return (!filename.empty()) ? m_arrow_texture.load_from_svg_file(path + filename, false, false, false, 512) : false; +} +#else +bool GLGizmosManager::init_arrow(const BackgroundTexture::Metadata & arrow_texture) { if (m_arrow_texture.texture.get_id() != 0) return true; @@ -139,6 +149,7 @@ bool GLGizmosManager::init_arrow(const BackgroundTexture::Metadata& arrow_textur return res; } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES void GLGizmosManager::set_overlay_icon_size(float size) { @@ -329,7 +340,7 @@ void GLGizmosManager::render_current_gizmo_for_picking_pass() const m_gizmos[m_current]->render_for_picking(); } -void GLGizmosManager::render_overlay() const +void GLGizmosManager::render_overlay() { if (!m_enabled) return; @@ -665,6 +676,60 @@ void GLGizmosManager::update_after_undo_redo(const UndoRedo::Snapshot& snapshot) dynamic_cast(m_gizmos[SlaSupports].get())->reslice_SLA_supports(true); } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void GLGizmosManager::render_background(float left, float top, float right, float bottom, float border_w, float border_h) const +{ + const unsigned int tex_id = m_background_texture.texture.get_id(); + const float tex_width = float(m_background_texture.texture.get_width()); + const float tex_height = float(m_background_texture.texture.get_height()); + if (tex_id != 0 && tex_width > 0 && tex_height > 0) { + const float inv_tex_width = (tex_width != 0.0f) ? 1.0f / tex_width : 0.0f; + const float inv_tex_height = (tex_height != 0.0f) ? 1.0f / tex_height : 0.0f; + + const float internal_left = left + border_w; + const float internal_right = right - border_w; + const float internal_top = top - border_h; + const float internal_bottom = bottom + border_h; + + // float left_uv = 0.0f; + const float right_uv = 1.0f; + const float top_uv = 1.0f; + const float bottom_uv = 0.0f; + + const float internal_left_uv = float(m_background_texture.metadata.left) * inv_tex_width; + const float internal_right_uv = 1.0f - float(m_background_texture.metadata.right) * inv_tex_width; + const float internal_top_uv = 1.0f - float(m_background_texture.metadata.top) * inv_tex_height; + const float internal_bottom_uv = float(m_background_texture.metadata.bottom) * inv_tex_height; + + // top-left corner + GLTexture::render_sub_texture(tex_id, left, internal_left, internal_top, top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + + // top edge + GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_top, top, { { internal_left_uv, internal_top_uv }, { internal_right_uv, internal_top_uv }, { internal_right_uv, top_uv }, { internal_left_uv, top_uv } }); + + // top-right corner + GLTexture::render_sub_texture(tex_id, internal_right, right, internal_top, top, { { internal_right_uv, internal_top_uv }, { right_uv, internal_top_uv }, { right_uv, top_uv }, { internal_right_uv, top_uv } }); + + // center-left edge + GLTexture::render_sub_texture(tex_id, left, internal_left, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + + // center + GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + + // center-right edge + GLTexture::render_sub_texture(tex_id, internal_right, right, internal_bottom, internal_top, { { internal_right_uv, internal_bottom_uv }, { right_uv, internal_bottom_uv }, { right_uv, internal_top_uv }, { internal_right_uv, internal_top_uv } }); + + // bottom-left corner + GLTexture::render_sub_texture(tex_id, left, internal_left, bottom, internal_bottom, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + + // bottom edge + GLTexture::render_sub_texture(tex_id, internal_left, internal_right, bottom, internal_bottom, { { internal_left_uv, bottom_uv }, { internal_right_uv, bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_left_uv, internal_bottom_uv } }); + + // bottom-right corner + GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_right_uv, bottom_uv }, { right_uv, bottom_uv }, { right_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv } }); + } +} +#else void GLGizmosManager::render_background(float left, float top, float right, float bottom, float border) const { const unsigned int tex_id = m_background_texture.texture.get_id(); @@ -717,7 +782,56 @@ void GLGizmosManager::render_background(float left, float top, float right, floa GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_right_uv, bottom_uv }, { right_uv, bottom_uv }, { right_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv } }); } } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if ENABLE_GL_SHADERS_ATTRIBUTES +void GLGizmosManager::render_arrow(const GLCanvas3D& parent, EType highlighted_type) const +{ + const std::vector selectable_idxs = get_selectable_idxs(); + if (selectable_idxs.empty()) + return; + + const Size cnv_size = m_parent.get_canvas_size(); + const float cnv_w = (float)cnv_size.get_width(); + const float cnv_h = (float)cnv_size.get_height(); + + if (cnv_w == 0 || cnv_h == 0) + return; + + const float inv_cnv_w = 1.0f / cnv_w; + const float inv_cnv_h = 1.0f / cnv_h; + + const float top_x = -1.0f; + float top_y = get_scaled_total_height() * inv_cnv_h; + + const float icons_size_x = 2.0f * m_layout.scaled_icons_size() * inv_cnv_w; + const float icons_size_y = 2.0f * m_layout.scaled_icons_size() * inv_cnv_h; + const float stride_y = 2.0f * m_layout.scaled_stride_y() * inv_cnv_h; + + for (size_t idx : selectable_idxs) { + if (idx == highlighted_type) { + const int tex_width = m_arrow_texture.get_width(); + const int tex_height = m_arrow_texture.get_height(); + const unsigned int tex_id = m_arrow_texture.get_id(); + + const float arrow_size_x = 2.0f * m_layout.scale * float(tex_height) * inv_cnv_w; + const float arrow_size_y = 2.0f * m_layout.scale * float(tex_width) * inv_cnv_h; + + const float left_uv = 0.0f; + const float right_uv = 1.0f; + const float top_uv = 1.0f; + const float bottom_uv = 0.0f; + + const float left = top_x + icons_size_x + 6.0f * m_layout.scaled_border() * inv_cnv_w; + const float right = left + arrow_size_x * icons_size_y / arrow_size_y; + + GLTexture::render_sub_texture(tex_id, left, right, top_y, top_y + icons_size_y, { { left_uv, bottom_uv }, { left_uv, top_uv }, { right_uv, top_uv }, { right_uv, bottom_uv } }); + break; + } + top_y -= stride_y; + } +} +#else void GLGizmosManager::render_arrow(const GLCanvas3D& parent, EType highlighted_type) const { std::vector selectable_idxs = get_selectable_idxs(); @@ -756,21 +870,95 @@ void GLGizmosManager::render_arrow(const GLCanvas3D& parent, EType highlighted_t zoomed_top_y -= zoomed_stride_y; } } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if ENABLE_GL_SHADERS_ATTRIBUTES +void GLGizmosManager::do_render_overlay() const +{ + const std::vector selectable_idxs = get_selectable_idxs(); + if (selectable_idxs.empty()) + return; + + const Size cnv_size = m_parent.get_canvas_size(); + const float cnv_w = (float)cnv_size.get_width(); + const float cnv_h = (float)cnv_size.get_height(); + + if (cnv_w == 0 || cnv_h == 0) + return; + + const float inv_cnv_w = 1.0f / cnv_w; + const float inv_cnv_h = 1.0f / cnv_h; + + const float height = 2.0f * get_scaled_total_height() * inv_cnv_h; + const float width = 2.0f * get_scaled_total_width() * inv_cnv_w; + const float border_h = 2.0f * m_layout.scaled_border() * inv_cnv_h; + const float border_w = 2.0f * m_layout.scaled_border() * inv_cnv_w; + + float top_x = -1.0f; + float top_y = 0.5f * height; + + render_background(top_x, top_y, top_x + width, top_y - height, border_w, border_h); + + top_x += border_w; + top_y -= border_h; + + const float icons_size_x = 2.0f * m_layout.scaled_icons_size() * inv_cnv_w; + const float icons_size_y = 2.0f * m_layout.scaled_icons_size() * inv_cnv_h; + const float stride_y = 2.0f * m_layout.scaled_stride_y() * inv_cnv_h; + + const unsigned int icons_texture_id = m_icons_texture.get_id(); + const int tex_width = m_icons_texture.get_width(); + const int tex_height = m_icons_texture.get_height(); + + if (icons_texture_id == 0 || tex_width <= 1 || tex_height <= 1) + return; + + const float du = (float)(tex_width - 1) / (6.0f * (float)tex_width); // 6 is the number of possible states if the icons + const float dv = (float)(tex_height - 1) / (float)(m_gizmos.size() * tex_height); + + // tiles in the texture are spaced by 1 pixel + const float u_offset = 1.0f / (float)tex_width; + const float v_offset = 1.0f / (float)tex_height; + + float current_y = FLT_MAX; + for (size_t idx : selectable_idxs) { + GLGizmoBase* gizmo = m_gizmos[idx].get(); + const unsigned int sprite_id = gizmo->get_sprite_id(); + // higlighted state needs to be decided first so its highlighting in every other state + const int icon_idx = (m_highlight.first == idx ? (m_highlight.second ? 4 : 5) : (m_current == idx) ? 2 : ((m_hover == idx) ? 1 : (gizmo->is_activable() ? 0 : 3))); + + const float u_left = u_offset + icon_idx * du; + const float u_right = u_left + du - u_offset; + const float v_top = v_offset + sprite_id * dv; + const float v_bottom = v_top + dv - v_offset; + + GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + icons_size_x, top_y - icons_size_y, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } }); + if (idx == m_current || current_y == FLT_MAX) { + // The FLT_MAX trick is here so that even non-selectable but activable + // gizmos are passed some meaningful value. + current_y = 0.5f * cnv_h - 0.5f * top_y * cnv_h; + } + top_y -= stride_y; + } + + if (m_current != Undefined) + m_gizmos[m_current]->render_input_window(get_scaled_total_width(), current_y, cnv_h - wxGetApp().plater()->get_view_toolbar().get_height()); +} +#else void GLGizmosManager::do_render_overlay() const { std::vector selectable_idxs = get_selectable_idxs(); if (selectable_idxs.empty()) return; - float cnv_w = (float)m_parent.get_canvas_size().get_width(); - float cnv_h = (float)m_parent.get_canvas_size().get_height(); - float zoom = (float)wxGetApp().plater()->get_camera().get_zoom(); - float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); + const float cnv_w = (float)m_parent.get_canvas_size().get_width(); + const float cnv_h = (float)m_parent.get_canvas_size().get_height(); + const float zoom = (float)wxGetApp().plater()->get_camera().get_zoom(); + const float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); - float height = get_scaled_total_height(); - float width = get_scaled_total_width(); - float zoomed_border = m_layout.scaled_border() * inv_zoom; + const float height = get_scaled_total_height(); + const float width = get_scaled_total_width(); + const float zoomed_border = m_layout.scaled_border() * inv_zoom; float zoomed_top_x = (-0.5f * cnv_w) * inv_zoom; float zoomed_top_y = (0.5f * height) * inv_zoom; @@ -785,36 +973,35 @@ void GLGizmosManager::do_render_overlay() const zoomed_top_x += zoomed_border; zoomed_top_y -= zoomed_border; - float icons_size = m_layout.scaled_icons_size(); - float zoomed_icons_size = icons_size * inv_zoom; - float zoomed_stride_y = m_layout.scaled_stride_y() * inv_zoom; + const float icons_size = m_layout.scaled_icons_size(); + const float zoomed_icons_size = icons_size * inv_zoom; + const float zoomed_stride_y = m_layout.scaled_stride_y() * inv_zoom; - unsigned int icons_texture_id = m_icons_texture.get_id(); - int tex_width = m_icons_texture.get_width(); - int tex_height = m_icons_texture.get_height(); + const unsigned int icons_texture_id = m_icons_texture.get_id(); + const int tex_width = m_icons_texture.get_width(); + const int tex_height = m_icons_texture.get_height(); - if ((icons_texture_id == 0) || (tex_width <= 1) || (tex_height <= 1)) + if (icons_texture_id == 0 || tex_width <= 1 || tex_height <= 1) return; - float du = (float)(tex_width - 1) / (6.0f * (float)tex_width); // 6 is the number of possible states if the icons - float dv = (float)(tex_height - 1) / (float)(m_gizmos.size() * tex_height); + const float du = (float)(tex_width - 1) / (6.0f * (float)tex_width); // 6 is the number of possible states if the icons + const float dv = (float)(tex_height - 1) / (float)(m_gizmos.size() * tex_height); // tiles in the texture are spaced by 1 pixel - float u_offset = 1.0f / (float)tex_width; - float v_offset = 1.0f / (float)tex_height; + const float u_offset = 1.0f / (float)tex_width; + const float v_offset = 1.0f / (float)tex_height; - float current_y = FLT_MAX; - for (size_t idx : selectable_idxs) - { + float current_y = FLT_MAX; + for (size_t idx : selectable_idxs) { GLGizmoBase* gizmo = m_gizmos[idx].get(); - unsigned int sprite_id = gizmo->get_sprite_id(); + const unsigned int sprite_id = gizmo->get_sprite_id(); // higlighted state needs to be decided first so its highlighting in every other state - int icon_idx = (m_highlight.first == idx ? (m_highlight.second ? 4 : 5) : (m_current == idx) ? 2 : ((m_hover == idx) ? 1 : (gizmo->is_activable()? 0 : 3))); + const int icon_idx = (m_highlight.first == idx ? (m_highlight.second ? 4 : 5) : (m_current == idx) ? 2 : ((m_hover == idx) ? 1 : (gizmo->is_activable()? 0 : 3))); - float v_top = v_offset + sprite_id * dv; - float u_left = u_offset + icon_idx * du; - float v_bottom = v_top + dv - v_offset; - float u_right = u_left + du - u_offset; + const float u_left = u_offset + icon_idx * du; + const float u_right = u_left + du - u_offset; + const float v_top = v_offset + sprite_id * dv; + const float v_bottom = v_top + dv - v_offset; GLTexture::render_sub_texture(icons_texture_id, zoomed_top_x, zoomed_top_x + zoomed_icons_size, zoomed_top_y - zoomed_icons_size, zoomed_top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } }); if (idx == m_current || current_y == FLT_MAX) { @@ -826,10 +1013,11 @@ void GLGizmosManager::do_render_overlay() const } if (m_current != Undefined) { - float toolbar_top = cnv_h - wxGetApp().plater()->get_view_toolbar().get_height(); + const float toolbar_top = cnv_h - wxGetApp().plater()->get_view_toolbar().get_height(); m_gizmos[m_current]->render_input_window(width, current_y, toolbar_top); } } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES float GLGizmosManager::get_scaled_total_height() const { @@ -859,14 +1047,12 @@ GLGizmosManager::EType GLGizmosManager::get_gizmo_from_name(const std::string& g return GLGizmosManager::EType::Undefined; } -bool GLGizmosManager::generate_icons_texture() const +bool GLGizmosManager::generate_icons_texture() { std::string path = resources_dir() + "/icons/"; std::vector filenames; - for (size_t idx=0; idxget_icon_filename(); if (!icon_filename.empty()) filenames.push_back(path + icon_filename); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index b8dfdec78..187afd889 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -34,7 +34,7 @@ public: Rect() = default; Rect(float left, float top, float right, float bottom) : m_left(left) , m_top(top) , m_right(right) , m_bottom(bottom) {} -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL bool operator == (const Rect& other) const { if (std::abs(m_left - other.m_left) > EPSILON) return false; if (std::abs(m_top - other.m_top) > EPSILON) return false; @@ -43,7 +43,7 @@ public: return true; } bool operator != (const Rect& other) const { return !operator==(other); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL float get_left() const { return m_left; } void set_left(float left) { m_left = left; } @@ -102,10 +102,14 @@ private: GLCanvas3D& m_parent; bool m_enabled; std::vector> m_gizmos; - mutable GLTexture m_icons_texture; - mutable bool m_icons_texture_dirty; + GLTexture m_icons_texture; + bool m_icons_texture_dirty; BackgroundTexture m_background_texture; +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLTexture m_arrow_texture; +#else BackgroundTexture m_arrow_texture; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES Layout m_layout; EType m_current; EType m_hover; @@ -133,7 +137,11 @@ public: bool init(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + bool init_arrow(const std::string& filename); +#else bool init_arrow(const BackgroundTexture::Metadata& arrow_texture); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES template void load(Archive& ar) @@ -208,7 +216,7 @@ public: void render_current_gizmo_for_picking_pass() const; void render_painter_gizmo(); - void render_overlay() const; + void render_overlay(); void render_arrow(const GLCanvas3D& parent, EType highlighted_type) const; @@ -234,14 +242,18 @@ private: bool alt_down = false, bool control_down = false); +#if ENABLE_GL_SHADERS_ATTRIBUTES + void render_background(float left, float top, float right, float bottom, float border_w, float border_h) const; +#else void render_background(float left, float top, float right, float bottom, float border) const; - +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + void do_render_overlay() const; float get_scaled_total_height() const; float get_scaled_total_width() const; - bool generate_icons_texture() const; + bool generate_icons_texture(); void update_hover_state(const EType &type); bool grabber_contains_mouse() const; diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp index 3787abb2f..e7e9ba2fb 100644 --- a/src/slic3r/GUI/MeshUtils.cpp +++ b/src/slic3r/GUI/MeshUtils.cpp @@ -6,10 +6,13 @@ #include "libslic3r/ClipperUtils.hpp" #include "libslic3r/Model.hpp" -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #include "slic3r/GUI/GUI_App.hpp" -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #include "slic3r/GUI/Camera.hpp" +#if ENABLE_GL_SHADERS_ATTRIBUTES +#include "slic3r/GUI/Plater.hpp" +#endif // ENABLE_GL_SHADERS_ATTRIBUTES #include @@ -67,25 +70,35 @@ void MeshClipper::set_transformation(const Geometry::Transformation& trafo) } } - - -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void MeshClipper::render_cut(const ColorRGBA& color) #else void MeshClipper::render_cut() -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL { if (! m_triangles_valid) recalculate_triangles(); -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL + if (m_model.vertices_count() == 0 || m_model.indices_count() == 0) + return; + GLShaderProgram* curr_shader = wxGetApp().get_current_shader(); if (curr_shader != nullptr) curr_shader->stop_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_model.set_color(color); m_model.render(); shader->stop_using(); @@ -96,7 +109,7 @@ void MeshClipper::render_cut() #else if (m_vertex_array.has_VBOs()) m_vertex_array.render(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } @@ -185,11 +198,11 @@ void MeshClipper::recalculate_triangles() tr.pretranslate(0.001 * m_plane.get_normal().normalized()); // to avoid z-fighting -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_model.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::index_type(m_triangles2d.size()) }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 }; init_data.reserve_vertices(m_triangles2d.size()); init_data.reserve_indices(m_triangles2d.size()); @@ -199,10 +212,7 @@ void MeshClipper::recalculate_triangles() init_data.add_vertex((Vec3f)(tr * Vec3d((*(it + 1)).x(), (*(it + 1)).y(), height_mesh)).cast(), (Vec3f)up.cast()); init_data.add_vertex((Vec3f)(tr * Vec3d((*(it + 2)).x(), (*(it + 2)).y(), height_mesh)).cast(), (Vec3f)up.cast()); const size_t idx = it - m_triangles2d.cbegin(); - if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT) - init_data.add_ushort_triangle((unsigned short)idx, (unsigned short)idx + 1, (unsigned short)idx + 2); - else - init_data.add_uint_triangle((unsigned int)idx, (unsigned int)idx + 1, (unsigned int)idx + 2); + init_data.add_triangle((unsigned int)idx, (unsigned int)idx + 1, (unsigned int)idx + 2); } if (!init_data.is_empty()) @@ -217,7 +227,7 @@ void MeshClipper::recalculate_triangles() m_vertex_array.push_triangle(idx, idx+1, idx+2); } m_vertex_array.finalize_geometry(true); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL m_triangles_valid = true; } diff --git a/src/slic3r/GUI/MeshUtils.hpp b/src/slic3r/GUI/MeshUtils.hpp index cc961ee8f..3298d3876 100644 --- a/src/slic3r/GUI/MeshUtils.hpp +++ b/src/slic3r/GUI/MeshUtils.hpp @@ -7,11 +7,11 @@ #include "libslic3r/SLA/IndexedMesh.hpp" #include "admesh/stl.h" -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #include "slic3r/GUI/GLModel.hpp" #else #include "slic3r/GUI/3DScene.hpp" -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #include @@ -98,11 +98,11 @@ public: // Render the triangulated cut. Transformation matrices should // be set in world coords. -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void render_cut(const ColorRGBA& color); #else void render_cut(); -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL private: void recalculate_triangles(); @@ -113,11 +113,11 @@ private: ClippingPlane m_plane; ClippingPlane m_limiting_plane = ClippingPlane::ClipsNothing(); std::vector m_triangles2d; -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel m_model; #else GLIndexedVertexArray m_vertex_array; -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL bool m_triangles_valid = false; }; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 585616c11..68a052341 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1260,11 +1260,11 @@ void Selection::render(float scale_factor) m_scale_factor = scale_factor; // render cumulative bounding box of selected volumes -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL render_bounding_box(get_bounding_box(), ColorRGB::WHITE()); #else render_selected_volumes(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL render_synchronized_volumes(); } @@ -1274,33 +1274,47 @@ void Selection::render_center(bool gizmo_is_dragging) if (!m_valid || is_empty()) return; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; shader->start_using(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL const Vec3d center = gizmo_is_dragging ? m_cache.dragging_center : get_bounding_box().center(); glsafe(::glDisable(GL_DEPTH_TEST)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + Transform3d view_model_matrix = camera.get_view_matrix() * Geometry::assemble_transform(center); + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#else glsafe(::glPushMatrix()); glsafe(::glTranslated(center.x(), center.y(), center.z())); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL m_vbo_sphere.set_color(ColorRGBA::WHITE()); #else m_vbo_sphere.set_color(-1, ColorRGBA::WHITE()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL m_vbo_sphere.render(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } #endif // ENABLE_RENDER_SELECTION_CENTER @@ -1309,8 +1323,12 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) if (sidebar_field.empty()) return; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader(boost::starts_with(sidebar_field, "layer") ? "flat_attr" : "gouraud_light_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader(boost::starts_with(sidebar_field, "layer") ? "flat" : "gouraud_light"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; @@ -1326,19 +1344,31 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) shader->start_using(); glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glEnable(GL_DEPTH_TEST)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d base_matrix = Geometry::assemble_transform(get_bounding_box().center()); + Transform3d orient_matrix = Transform3d::Identity(); +#else glsafe(::glPushMatrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (!boost::starts_with(sidebar_field, "layer")) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + shader->set_uniform("emission_factor", 0.05f); +#else const Vec3d& center = get_bounding_box().center(); - +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (is_single_full_instance() && !wxGetApp().obj_manipul()->get_world_coordinates()) { +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glTranslated(center.x(), center.y(), center.z())); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES if (!boost::starts_with(sidebar_field, "position")) { +#if !ENABLE_GL_SHADERS_ATTRIBUTES Transform3d orient_matrix = Transform3d::Identity(); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES if (boost::starts_with(sidebar_field, "scale")) orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); else if (boost::starts_with(sidebar_field, "rotation")) { @@ -1346,36 +1376,60 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); else if (boost::ends_with(sidebar_field, "y")) { const Vec3d& rotation = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation(); - if (rotation(0) == 0.0) + if (rotation.x() == 0.0) orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); else - orient_matrix.rotate(Eigen::AngleAxisd(rotation(2), Vec3d::UnitZ())); + orient_matrix.rotate(Eigen::AngleAxisd(rotation.z(), Vec3d::UnitZ())); } } - +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glMultMatrixd(orient_matrix.data())); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES } - } else if (is_single_volume() || is_single_modifier()) { + } + else if (is_single_volume() || is_single_modifier()) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); +#else glsafe(::glTranslated(center.x(), center.y(), center.z())); Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (!boost::starts_with(sidebar_field, "position")) orient_matrix = orient_matrix * (*m_volumes)[*m_list.begin()]->get_volume_transformation().get_matrix(true, false, true, true); +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glMultMatrixd(orient_matrix.data())); - } else { - glsafe(::glTranslated(center(0), center(1), center(2))); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES + } + else { +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (requires_local_axes()) + orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); +#else + glsafe(::glTranslated(center.x(), center.y(), center.z())); if (requires_local_axes()) { const Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); glsafe(::glMultMatrixd(orient_matrix.data())); } +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (!boost::starts_with(sidebar_field, "layer")) glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + if (boost::starts_with(sidebar_field, "position")) + render_sidebar_position_hints(sidebar_field, *shader, base_matrix * orient_matrix); + else if (boost::starts_with(sidebar_field, "rotation")) + render_sidebar_rotation_hints(sidebar_field, *shader, base_matrix * orient_matrix); + else if (boost::starts_with(sidebar_field, "scale") || boost::starts_with(sidebar_field, "size")) + render_sidebar_scale_hints(sidebar_field, *shader, base_matrix * orient_matrix); + else if (boost::starts_with(sidebar_field, "layer")) + render_sidebar_layers_hints(sidebar_field, *shader); +#else if (boost::starts_with(sidebar_field, "position")) render_sidebar_position_hints(sidebar_field); else if (boost::starts_with(sidebar_field, "rotation")) @@ -1386,16 +1440,17 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) render_sidebar_layers_hints(sidebar_field); glsafe(::glPopMatrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL if (!boost::starts_with(sidebar_field, "layer")) -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); } bool Selection::requires_local_axes() const { - return (m_mode == Volume) && is_from_single_instance(); + return m_mode == Volume && is_from_single_instance(); } void Selection::copy_to_clipboard() @@ -1405,8 +1460,7 @@ void Selection::copy_to_clipboard() m_clipboard.reset(); - for (const ObjectIdxsToInstanceIdxsMap::value_type& object : m_cache.content) - { + for (const ObjectIdxsToInstanceIdxsMap::value_type& object : m_cache.content) { ModelObject* src_object = m_model->objects[object.first]; ModelObject* dst_object = m_clipboard.add_object(); dst_object->name = src_object->name; @@ -1419,26 +1473,22 @@ void Selection::copy_to_clipboard() dst_object->layer_height_profile.assign(src_object->layer_height_profile); dst_object->origin_translation = src_object->origin_translation; - for (int i : object.second) - { + for (int i : object.second) { dst_object->add_instance(*src_object->instances[i]); } - for (unsigned int i : m_list) - { + for (unsigned int i : m_list) { // Copy the ModelVolumes only for the selected GLVolumes of the 1st selected instance. const GLVolume* volume = (*m_volumes)[i]; - if ((volume->object_idx() == object.first) && (volume->instance_idx() == *object.second.begin())) - { + if (volume->object_idx() == object.first && volume->instance_idx() == *object.second.begin()) { int volume_idx = volume->volume_idx(); - if ((0 <= volume_idx) && (volume_idx < (int)src_object->volumes.size())) - { + if (0 <= volume_idx && volume_idx < (int)src_object->volumes.size()) { ModelVolume* src_volume = src_object->volumes[volume_idx]; ModelVolume* dst_volume = dst_object->add_volume(*src_volume); dst_volume->set_new_unique_id(); - } else { - assert(false); } + else + assert(false); } } } @@ -1831,22 +1881,22 @@ void Selection::do_remove_object(unsigned int object_idx) } } -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL void Selection::render_selected_volumes() const { float color[3] = { 1.0f, 1.0f, 1.0f }; render_bounding_box(get_bounding_box(), color); } -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL void Selection::render_synchronized_volumes() { if (m_mode == Instance) return; -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL float color[3] = { 1.0f, 1.0f, 0.0f }; -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL for (unsigned int i : m_list) { const GLVolume& volume = *(*m_volumes)[i]; @@ -1860,16 +1910,16 @@ void Selection::render_synchronized_volumes() if (v.object_idx() != object_idx || v.volume_idx() != volume_idx) continue; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL render_bounding_box(v.transformed_convex_hull_bounding_box(), ColorRGB::YELLOW()); #else render_bounding_box(v.transformed_convex_hull_bounding_box(), color); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } } } -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void Selection::render_bounding_box(const BoundingBoxf3& box, const ColorRGB& color) { #else @@ -1885,9 +1935,9 @@ void Selection::render_bounding_box(const BoundingBoxf3 & box, float* color) con glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glColor3fv(color)); glsafe(::glLineWidth(2.0f * m_scale_factor)); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL const BoundingBoxf3& curr_box = m_box.get_bounding_box(); if (!m_box.is_initialized() || !is_approx(box.min, curr_box.min) || !is_approx(box.max, curr_box.max)) { m_box.reset(); @@ -1897,7 +1947,7 @@ void Selection::render_bounding_box(const BoundingBoxf3 & box, float* color) con const Vec3f size = 0.2f * box.size().cast(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(48); init_data.reserve_indices(48); @@ -1959,8 +2009,8 @@ void Selection::render_bounding_box(const BoundingBoxf3 & box, float* color) con init_data.add_vertex(Vec3f(b_min.x(), b_max.y(), b_max.z() - size.z())); // indices - for (unsigned short i = 0; i < 48; ++i) { - init_data.add_ushort_index(i); + for (unsigned int i = 0; i < 48; ++i) { + init_data.add_index(i); } m_box.init_from(std::move(init_data)); @@ -1970,11 +2020,20 @@ void Selection::render_bounding_box(const BoundingBoxf3 & box, float* color) con glsafe(::glLineWidth(2.0f * m_scale_factor)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; shader->start_using(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_box.set_color(to_rgba(color)); m_box.render(); shader->stop_using(); @@ -2014,7 +2073,7 @@ void Selection::render_bounding_box(const BoundingBoxf3 & box, float* color) con ::glVertex3f(b_min(0), b_max(1), b_max(2)); ::glVertex3f(b_min(0), b_max(1), b_max(2) - size(2)); glsafe(::glEnd()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } static ColorRGBA get_color(Axis axis) @@ -2022,20 +2081,46 @@ static ColorRGBA get_color(Axis axis) return AXES_COLOR[axis]; } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void Selection::render_sidebar_position_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix) +#else void Selection::render_sidebar_position_hints(const std::string& sidebar_field) +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d view_matrix = camera.get_view_matrix() * matrix; + shader.set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + if (boost::ends_with(sidebar_field, "x")) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d view_model_matrix = view_matrix * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitZ()); + shader.set_uniform("view_model_matrix", view_model_matrix); + shader.set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_arrow.set_color(get_color(X)); m_arrow.render(); } else if (boost::ends_with(sidebar_field, "y")) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + shader.set_uniform("view_model_matrix", view_matrix); + shader.set_uniform("normal_matrix", (Matrix3d)view_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_arrow.set_color(get_color(Y)); m_arrow.render(); } else if (boost::ends_with(sidebar_field, "z")) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Transform3d view_model_matrix = view_matrix * Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitX()); + shader.set_uniform("view_model_matrix", view_model_matrix); + shader.set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_arrow.set_color(get_color(Z)); m_arrow.render(); } @@ -2054,31 +2139,68 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) m_arrow.set_color(-1, get_color(Z)); m_arrow.render(); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix) +#else void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + auto render_sidebar_rotation_hint = [this](GLShaderProgram& shader, const Transform3d& matrix) { + Transform3d view_model_matrix = matrix; + shader.set_uniform("view_model_matrix", view_model_matrix); + shader.set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); + m_curved_arrow.render(); + view_model_matrix = matrix * Geometry::assemble_transform(Vec3d::Zero(), PI * Vec3d::UnitZ()); + shader.set_uniform("view_model_matrix", view_model_matrix); + shader.set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); + m_curved_arrow.render(); + }; + + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d view_matrix = camera.get_view_matrix() * matrix; + shader.set_uniform("projection_matrix", camera.get_projection_matrix()); +#else auto render_sidebar_rotation_hint = [this]() { m_curved_arrow.render(); glsafe(::glRotated(180.0, 0.0, 0.0, 1.0)); m_curved_arrow.render(); }; +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (boost::ends_with(sidebar_field, "x")) { +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES m_curved_arrow.set_color(get_color(X)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + render_sidebar_rotation_hint(shader, view_matrix * Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitY())); +#else render_sidebar_rotation_hint(); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } else if (boost::ends_with(sidebar_field, "y")) { +#if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES m_curved_arrow.set_color(get_color(Y)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + render_sidebar_rotation_hint(shader, view_matrix * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitX())); +#else render_sidebar_rotation_hint(); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } else if (boost::ends_with(sidebar_field, "z")) { m_curved_arrow.set_color(get_color(Z)); +#if ENABLE_GL_SHADERS_ATTRIBUTES + render_sidebar_rotation_hint(shader, view_matrix); +#else render_sidebar_rotation_hint(); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } #else auto render_sidebar_rotation_hint = [this]() { @@ -2101,53 +2223,96 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) m_curved_arrow.set_color(-1, get_color(Z)); render_sidebar_rotation_hint(); } -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void Selection::render_sidebar_scale_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix) +#else void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { - bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling(); + const bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + auto render_sidebar_scale_hint = [this, uniform_scale](Axis axis, GLShaderProgram& shader, const Transform3d& matrix) { +#else auto render_sidebar_scale_hint = [this, uniform_scale](Axis axis) { -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if ENABLE_LEGACY_OPENGL_REMOVAL m_arrow.set_color(uniform_scale ? UNIFORM_SCALE_COLOR : get_color(axis)); #else m_arrow.set_color(-1, uniform_scale ? UNIFORM_SCALE_COLOR : get_color(axis)); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL + +#if ENABLE_GL_SHADERS_ATTRIBUTES + Transform3d view_model_matrix = matrix * Geometry::assemble_transform(5.0 * Vec3d::UnitY()); + shader.set_uniform("view_model_matrix", view_model_matrix); + shader.set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else GLShaderProgram* shader = wxGetApp().get_current_shader(); if (shader != nullptr) shader->set_uniform("emission_factor", 0.0f); glsafe(::glTranslated(0.0, 5.0, 0.0)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_arrow.render(); +#if ENABLE_GL_SHADERS_ATTRIBUTES + view_model_matrix = matrix * Geometry::assemble_transform(-5.0 * Vec3d::UnitY(), PI * Vec3d::UnitZ()); + shader.set_uniform("view_model_matrix", view_model_matrix); + shader.set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else glsafe(::glTranslated(0.0, -10.0, 0.0)); glsafe(::glRotated(180.0, 0.0, 0.0, 1.0)); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES m_arrow.render(); }; +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d view_matrix = camera.get_view_matrix() * matrix; + shader.set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + if (boost::ends_with(sidebar_field, "x") || uniform_scale) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + render_sidebar_scale_hint(X, shader, view_matrix * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitZ())); +#else glsafe(::glPushMatrix()); glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); render_sidebar_scale_hint(X); glsafe(::glPopMatrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } if (boost::ends_with(sidebar_field, "y") || uniform_scale) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + render_sidebar_scale_hint(Y, shader, view_matrix); +#else glsafe(::glPushMatrix()); render_sidebar_scale_hint(Y); glsafe(::glPopMatrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } if (boost::ends_with(sidebar_field, "z") || uniform_scale) { +#if ENABLE_GL_SHADERS_ATTRIBUTES + render_sidebar_scale_hint(Z, shader, view_matrix * Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitX())); +#else glsafe(::glPushMatrix()); glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); render_sidebar_scale_hint(Z); glsafe(::glPopMatrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES } } +#if ENABLE_GL_SHADERS_ATTRIBUTES +void Selection::render_sidebar_layers_hints(const std::string& sidebar_field, GLShaderProgram& shader) +#else void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) +#endif // ENABLE_GL_SHADERS_ATTRIBUTES { static const float Margin = 10.0f; @@ -2178,35 +2343,35 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) const BoundingBoxf3& box = get_bounding_box(); -#if !ENABLE_GLBEGIN_GLEND_REMOVAL +#if !ENABLE_LEGACY_OPENGL_REMOVAL const float min_x = float(box.min.x()) - Margin; const float max_x = float(box.max.x()) + Margin; const float min_y = float(box.min.y()) - Margin; const float max_y = float(box.max.y()) + Margin; -#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // !ENABLE_LEGACY_OPENGL_REMOVAL // view dependend order of rendering to keep correct transparency const bool camera_on_top = wxGetApp().plater()->get_camera().is_looking_downward(); const float z1 = camera_on_top ? min_z : max_z; const float z2 = camera_on_top ? max_z : min_z; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL const Vec3f p1 = { float(box.min.x()) - Margin, float(box.min.y()) - Margin, z1 }; const Vec3f p2 = { float(box.max.x()) + Margin, float(box.max.y()) + Margin, z2 }; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glDisable(GL_CULL_FACE)); glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL if (!m_planes.models[0].is_initialized() || !is_approx(m_planes.check_points[0], p1)) { m_planes.check_points[0] = p1; m_planes.models[0].reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(4); init_data.reserve_indices(6); @@ -2217,8 +2382,8 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) init_data.add_vertex(Vec3f(p1.x(), p2.y(), z1)); // indices - init_data.add_ushort_triangle(0, 1, 2); - init_data.add_ushort_triangle(2, 3, 0); + init_data.add_triangle(0, 1, 2); + init_data.add_triangle(2, 3, 0); m_planes.models[0].init_from(std::move(init_data)); } @@ -2228,7 +2393,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) m_planes.models[1].reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(4); init_data.reserve_indices(6); @@ -2239,12 +2404,18 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) init_data.add_vertex(Vec3f(p1.x(), p2.y(), z2)); // indices - init_data.add_ushort_triangle(0, 1, 2); - init_data.add_ushort_triangle(2, 3, 0); + init_data.add_triangle(0, 1, 2); + init_data.add_triangle(2, 3, 0); m_planes.models[1].init_from(std::move(init_data)); } +#if ENABLE_GL_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + shader.set_uniform("view_model_matrix", camera.get_view_matrix()); + shader.set_uniform("projection_matrix", camera.get_projection_matrix()); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES + m_planes.models[0].set_color((camera_on_top && type == 1) || (!camera_on_top && type == 2) ? SOLID_PLANE_COLOR : TRANSPARENT_PLANE_COLOR); m_planes.models[0].render(); m_planes.models[1].set_color((camera_on_top && type == 2) || (!camera_on_top && type == 1) ? SOLID_PLANE_COLOR : TRANSPARENT_PLANE_COLOR); @@ -2265,7 +2436,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) ::glVertex3f(max_x, max_y, z2); ::glVertex3f(min_x, max_y, z2); glsafe(::glEnd()); -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glEnable(GL_CULL_FACE)); glsafe(::glDisable(GL_BLEND)); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index f9e18b036..c9e55cf82 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -218,7 +218,7 @@ private: GLModel m_arrow; GLModel m_curved_arrow; -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL GLModel m_box; struct Planes { @@ -226,7 +226,7 @@ private: std::array models; }; Planes m_planes; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL float m_scale_factor; @@ -370,16 +370,23 @@ private: void do_remove_object(unsigned int object_idx); void set_bounding_boxes_dirty() { m_bounding_box.reset(); m_unscaled_instance_bounding_box.reset(); m_scaled_instance_bounding_box.reset(); } void render_synchronized_volumes(); -#if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL void render_bounding_box(const BoundingBoxf3& box, const ColorRGB& color); #else void render_selected_volumes() const; void render_bounding_box(const BoundingBoxf3& box, float* color) const; -#endif // ENABLE_GLBEGIN_GLEND_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + void render_sidebar_position_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix); + void render_sidebar_rotation_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix); + void render_sidebar_scale_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix); + void render_sidebar_layers_hints(const std::string& sidebar_field, GLShaderProgram& shader); +#else void render_sidebar_position_hints(const std::string& sidebar_field); void render_sidebar_rotation_hints(const std::string& sidebar_field); void render_sidebar_scale_hints(const std::string& sidebar_field); void render_sidebar_layers_hints(const std::string& sidebar_field); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES public: enum SyncRotationType { diff --git a/src/slic3r/Utils/UndoRedo.cpp b/src/slic3r/Utils/UndoRedo.cpp index 533c544a8..8fe20d012 100644 --- a/src/slic3r/Utils/UndoRedo.cpp +++ b/src/slic3r/Utils/UndoRedo.cpp @@ -21,9 +21,9 @@ #include #include -#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#if ENABLE_LEGACY_OPENGL_REMOVAL #include "slic3r/GUI/3DScene.hpp" -#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#endif // ENABLE_LEGACY_OPENGL_REMOVAL #include