From 71fd4084c2864490bab2dc3d7e75ccf88423e237 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 25 Oct 2023 23:14:53 +0800 Subject: [PATCH] Tech ENABLE_LEGACY_OPENGL_REMOVAL - porting remaining changes (cherry picked from commit prusa3d/PrusaSlicer@2f572d3cf0f0926ad0041e3c95251439e340fe08 ) --- resources/shaders/background_attr.vs | 12 + resources/shaders/cali.fs | 8 - resources/shaders/cali.vs | 6 - resources/shaders/flat_attr.vs | 5 +- resources/shaders/flat_texture_attr.vs | 15 + resources/shaders/gouraud.fs | 1 - resources/shaders/gouraud.vs | 2 - resources/shaders/gouraud_attr.vs | 77 +++ resources/shaders/gouraud_light_attr.vs | 45 ++ .../shaders/gouraud_light_instanced_attr.vs | 50 ++ resources/shaders/mm_contour_attr.fs | 13 + resources/shaders/mm_contour_attr.vs | 11 + resources/shaders/mm_gouraud_attr.fs | 90 +++ resources/shaders/mm_gouraud_attr.vs | 35 + resources/shaders/options_110.fs | 8 - resources/shaders/options_110.vs | 22 - resources/shaders/options_120.fs | 22 - resources/shaders/options_120.vs | 22 - resources/shaders/printbed.fs | 8 +- resources/shaders/printbed.vs | 4 +- resources/shaders/printbed_attr.vs | 15 + resources/shaders/thumbnail_attr.vs | 51 ++ .../shaders/variable_layer_height_attr.vs | 60 ++ src/OrcaSlicer.cpp | 2 +- src/slic3r/GUI/3DBed.cpp | 71 +- src/slic3r/GUI/3DBed.hpp | 12 +- src/slic3r/GUI/3DScene.cpp | 138 ++-- src/slic3r/GUI/3DScene.hpp | 7 +- src/slic3r/GUI/Camera.hpp | 1 - src/slic3r/GUI/GCodeViewer.cpp | 370 +++++----- src/slic3r/GUI/GLCanvas3D.cpp | 448 ++++++------ src/slic3r/GUI/GLCanvas3D.hpp | 16 +- src/slic3r/GUI/GLModel.cpp | 637 +++++++----------- src/slic3r/GUI/GLModel.hpp | 46 +- src/slic3r/GUI/GLSelectionRectangle.cpp | 52 +- src/slic3r/GUI/GLSelectionRectangle.hpp | 12 +- src/slic3r/GUI/GLShader.cpp | 5 + src/slic3r/GUI/GLShader.hpp | 2 + src/slic3r/GUI/GLShadersManager.cpp | 43 +- src/slic3r/GUI/GLTexture.cpp | 10 +- src/slic3r/GUI/GLToolbar.cpp | 468 +++++++------ src/slic3r/GUI/GLToolbar.hpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp | 58 +- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 25 +- src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 1 + src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 14 +- src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp | 32 +- src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp | 37 +- .../GUI/Gizmos/GLGizmoMmuSegmentation.cpp | 14 +- src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 37 +- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp | 134 ++-- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp | 10 +- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 110 ++- src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp | 2 + src/slic3r/GUI/Gizmos/GLGizmoScale.cpp | 20 +- src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp | 14 +- src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp | 18 +- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 58 +- src/slic3r/GUI/Gizmos/GLGizmoText.cpp | 6 +- src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 13 +- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 153 ++--- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 4 +- src/slic3r/GUI/MeshUtils.cpp | 16 +- src/slic3r/GUI/PartPlate.cpp | 70 +- src/slic3r/GUI/PartPlate.hpp | 12 +- src/slic3r/GUI/Selection.cpp | 188 +++--- src/slic3r/GUI/Selection.hpp | 8 +- src/slic3r/Utils/CalibUtils.cpp | 2 +- 68 files changed, 2145 insertions(+), 1837 deletions(-) create mode 100644 resources/shaders/background_attr.vs delete mode 100644 resources/shaders/cali.fs delete mode 100644 resources/shaders/cali.vs create mode 100644 resources/shaders/flat_texture_attr.vs create mode 100644 resources/shaders/gouraud_attr.vs create mode 100644 resources/shaders/gouraud_light_attr.vs create mode 100644 resources/shaders/gouraud_light_instanced_attr.vs create mode 100644 resources/shaders/mm_contour_attr.fs create mode 100644 resources/shaders/mm_contour_attr.vs create mode 100644 resources/shaders/mm_gouraud_attr.fs create mode 100644 resources/shaders/mm_gouraud_attr.vs delete mode 100644 resources/shaders/options_110.fs delete mode 100644 resources/shaders/options_110.vs delete mode 100644 resources/shaders/options_120.fs delete mode 100644 resources/shaders/options_120.vs create mode 100644 resources/shaders/printbed_attr.vs create mode 100644 resources/shaders/thumbnail_attr.vs create mode 100644 resources/shaders/variable_layer_height_attr.vs diff --git a/resources/shaders/background_attr.vs b/resources/shaders/background_attr.vs new file mode 100644 index 0000000000..9b56ab43a2 --- /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/cali.fs b/resources/shaders/cali.fs deleted file mode 100644 index ab656998df..0000000000 --- a/resources/shaders/cali.fs +++ /dev/null @@ -1,8 +0,0 @@ -#version 110 - -uniform vec4 uniform_color; - -void main() -{ - gl_FragColor = uniform_color; -} diff --git a/resources/shaders/cali.vs b/resources/shaders/cali.vs deleted file mode 100644 index d0d3ee42a9..0000000000 --- a/resources/shaders/cali.vs +++ /dev/null @@ -1,6 +0,0 @@ -#version 110 - -void main() -{ - gl_Position = ftransform(); -} diff --git a/resources/shaders/flat_attr.vs b/resources/shaders/flat_attr.vs index 1b00886757..370eedb72d 100644 --- a/resources/shaders/flat_attr.vs +++ b/resources/shaders/flat_attr.vs @@ -2,9 +2,10 @@ attribute vec3 v_position; -uniform mat4 projection_view_model_matrix; +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; void main() { - gl_Position = projection_view_model_matrix * vec4(v_position, 1.0); + 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 0000000000..e59a99da35 --- /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 3f12a6e92c..4084efdbf1 100644 --- a/resources/shaders/gouraud.fs +++ b/resources/shaders/gouraud.fs @@ -48,7 +48,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 79d7a63c07..c8b3d7b335 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 0000000000..87e524c14a --- /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 0000000000..2e1b5fb429 --- /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 0000000000..7069feb65e --- /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 0000000000..14477a59e6 --- /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 0000000000..370eedb72d --- /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 0000000000..4ecf7bf70c --- /dev/null +++ b/resources/shaders/mm_gouraud_attr.fs @@ -0,0 +1,90 @@ +#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; +//BBS: add grey and orange +//const vec3 GREY = vec3(0.9, 0.9, 0.9); +const vec3 ORANGE = vec3(0.8, 0.4, 0.0); +const vec3 LightRed = vec3(0.78, 0.0, 0.0); +const vec3 LightBlue = vec3(0.73, 1.0, 1.0); +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; +varying vec4 world_pos; + +struct SlopeDetection +{ + bool actived; + float normal_z; + mat3 volume_world_normal_matrix; +}; +uniform SlopeDetection slope; + +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; + + vec3 transformed_normal = normalize(slope.volume_world_normal_matrix * triangle_normal); + + if (slope.actived) { + if(world_pos.z<0.1&&world_pos.z>-0.1) + { + color = LightBlue; + alpha = 1.0; + } + else if( transformed_normal.z < slope.normal_z - EPSILON) + { + color = color * 0.5 + LightRed * 0.5; + alpha = 1.0; + } + } + // 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 0000000000..d51c53b82b --- /dev/null +++ b/resources/shaders/mm_gouraud_attr.vs @@ -0,0 +1,35 @@ +#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; +varying vec4 world_pos; +struct SlopeDetection +{ + bool actived; + float normal_z; + mat3 volume_world_normal_matrix; +}; +uniform SlopeDetection slope; +void main() +{ + model_pos = vec4(v_position, 1.0); + // Point in homogenous coordinates. + 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 ab656998df..0000000000 --- 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 5f2ab23504..0000000000 --- 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 e9b61304f2..0000000000 --- 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 edb503fb2b..0000000000 --- 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 bef0751580..833dff08f4 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 3b3f8875d2..27addc7526 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 0000000000..e59a99da35 --- /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/thumbnail_attr.vs b/resources/shaders/thumbnail_attr.vs new file mode 100644 index 0000000000..a9a3c984b2 --- /dev/null +++ b/resources/shaders/thumbnail_attr.vs @@ -0,0 +1,51 @@ +#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; + +uniform mat4 volume_world_matrix; + +// x = tainted, y = specular; +varying vec2 intensity; +varying vec4 world_pos; + +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; + + // Point in homogenous coordinates. + world_pos = volume_world_matrix * gl_Vertex; + + 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 0000000000..40609bd0d9 --- /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/OrcaSlicer.cpp b/src/OrcaSlicer.cpp index c8ba1cdd31..9c99e6f686 100644 --- a/src/OrcaSlicer.cpp +++ b/src/OrcaSlicer.cpp @@ -2370,7 +2370,7 @@ int CLI::run(int argc, char **argv) } ThumbnailsParams thumbnail_params; - GLShaderProgram* shader = opengl_mgr.get_shader("thumbnail"); + GLShaderProgram* shader = opengl_mgr.get_shader("thumbnail_attr"); if (!shader) { BOOST_LOG_TRIVIAL(error) << boost::format("can not get shader for rendering thumbnail"); } diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 55a25c5141..7d3867b398 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -47,7 +47,7 @@ bool init_model_from_poly(GLModel &model, const ExPolygon &poly, float z) return false; 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); @@ -71,12 +71,8 @@ bool init_model_from_poly(GLModel &model, const ExPolygon &poly, float z) const Vec3f p = {v.x(), v.y(), 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); } model.init_from(std::move(init_data)); @@ -210,17 +206,19 @@ void Bed3D::load_render_colors() void Bed3D::Axes::render() { - auto render_axis = [this](const Transform3f& transform) { - glsafe(::glPushMatrix()); - glsafe(::glMultMatrixf(transform.data())); + 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()); m_arrow.render(); - glsafe(::glPopMatrix()); }; if (!m_arrow.is_initialized()) m_arrow.init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length)); - GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr"); if (shader == nullptr) return; @@ -231,15 +229,15 @@ void Bed3D::Axes::render() // x axis m_arrow.set_color(AXIS_X_COLOR); - render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }).cast()); + render_axis(shader, Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 })); // y axis m_arrow.set_color(AXIS_Y_COLOR); - render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }).cast()); + render_axis(shader, Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 })); // z axis m_arrow.set_color(AXIS_Z_COLOR); - render_axis(Geometry::assemble_transform(m_origin).cast()); + render_axis(shader, Geometry::assemble_transform(m_origin)); shader->stop_using(); @@ -362,17 +360,17 @@ void Bed3D::on_change_color_mode(bool is_dark) m_is_dark = is_dark; } -void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes) +void Bed3D::render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_axes) { - render_internal(canvas, bottom, scale_factor, show_axes); + render_internal(canvas, view_matrix, projection_matrix, bottom, scale_factor, show_axes); } -/*void Bed3D::render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_factor) +/*void Bed3D::render_for_picking(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor) { - render_internal(canvas, bottom, scale_factor, false, false, true); + render_internal(canvas, view_matrix, projection_matrix, bottom, scale_factor, false, false, true); }*/ -void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor, +void Bed3D::render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_axes) { m_scale_factor = scale_factor; @@ -386,9 +384,9 @@ void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor, switch (m_type) { - case Type::System: { render_system(canvas, bottom); break; } + case Type::System: { render_system(canvas, view_matrix, projection_matrix, bottom); break; } default: - case Type::Custom: { render_custom(canvas, bottom); break; } + case Type::Custom: { render_custom(canvas, view_matrix, projection_matrix, bottom); break; } } glsafe(::glDisable(GL_DEPTH_TEST)); @@ -464,10 +462,10 @@ void Bed3D::render_axes() m_axes.render(); } -void Bed3D::render_system(GLCanvas3D& canvas, bool bottom) +void Bed3D::render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom) { if (!bottom) - render_model(); + render_model(view_matrix, projection_matrix); /*if (show_texture) render_texture(bottom, canvas);*/ @@ -538,9 +536,12 @@ void Bed3D::render_system(GLCanvas3D& canvas, bool bottom) } if (m_triangles.get_vertices_count() > 0) { - GLShaderProgram* shader = wxGetApp().get_shader("printbed"); + GLShaderProgram* shader = wxGetApp().get_shader("printbed_attr"); if (shader != nullptr) { shader->start_using(); + 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()); shader->set_uniform("transparent_background", bottom); shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg")); @@ -658,7 +659,7 @@ void Bed3D::update_bed_triangles() const_cast(m_extended_bounding_box) = calc_extended_bounding_box(); } -void Bed3D::render_model() +void Bed3D::render_model(const Transform3d& view_matrix, const Transform3d& projection_matrix) { if (m_model_filename.empty()) return; @@ -670,20 +671,21 @@ void Bed3D::render_model() } if (!m_model.get_filename().empty()) { - GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr"); if (shader != nullptr) { shader->start_using(); shader->set_uniform("emission_factor", 0.0f); - glsafe(::glPushMatrix()); - glsafe(::glTranslated(m_model_offset.x(), m_model_offset.y(), m_model_offset.z())); + 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()); m_model.render(); - glsafe(::glPopMatrix()); shader->stop_using(); } } } -void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom) +void Bed3D::render_custom(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom) { if (m_model_filename.empty()) { render_default(bottom); @@ -691,7 +693,7 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom) } if (!bottom) - render_model(); + render_model(view_matrix, projection_matrix); /*if (show_texture) render_texture(bottom, canvas);*/ @@ -708,8 +710,9 @@ void Bed3D::render_default(bool bottom) if (shader != nullptr) { shader->start_using(); - const Transform3d matrix = wxGetApp().plater()->get_camera().get_projection_view_matrix(); - shader->set_uniform("projection_view_model_matrix", matrix); + 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()); glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glEnable(GL_BLEND)); diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index 661dee47b7..e72c6f8af6 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -146,8 +146,8 @@ public: bool contains(const Point& point) const; Point point_projection(const Point& point) const; - void render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes); - //void render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_factor); + void render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_axes); + //void render_for_picking(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor); void on_change_color_mode(bool is_dark); @@ -159,13 +159,13 @@ private: //BBS: with offset void update_bed_triangles(); static std::tuple detect_type(const Pointfs& shape); - void render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor, + void render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_axes); void render_axes(); - void render_system(GLCanvas3D& canvas, bool bottom); + void render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom); //void render_texture(bool bottom, GLCanvas3D& canvas); - void render_model(); - void render_custom(GLCanvas3D& canvas, bool bottom); + 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); void render_default(bool bottom); }; diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index ac533c3365..354dc76c71 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -6,6 +6,7 @@ #include "GUI_Colors.hpp" #include "Plater.hpp" #include "BitmapCache.hpp" +#include "Camera.hpp" #include "libslic3r/BuildVolume.hpp" #include "libslic3r/ExtrusionEntity.hpp" @@ -96,10 +97,14 @@ void GLVolume::SinkingContours::render() { update(); - glsafe(::glPushMatrix()); - glsafe(::glTranslated(m_shift.x(), m_shift.y(), m_shift.z())); + 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()); m_model.render(); - glsafe(::glPopMatrix()); } void GLVolume::SinkingContours::update() @@ -117,7 +122,7 @@ void GLVolume::SinkingContours::update() m_model.reset(); GUI::GLModel::Geometry init_data; - init_data.format = { GUI::GLModel::Geometry::EPrimitiveType::Triangles, GUI::GLModel::Geometry::EVertexLayout::P3, GUI::GLModel::Geometry::EIndexType::UINT }; + init_data.format = { GUI::GLModel::Geometry::EPrimitiveType::Triangles, GUI::GLModel::Geometry::EVertexLayout::P3 }; init_data.color = ColorRGBA::WHITE(); unsigned int vertices_counter = 0; MeshSlicingParams slicing_params; @@ -131,7 +136,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)); @@ -398,10 +403,17 @@ void GLVolume::render(bool with_outline) if (!is_active) return; + GLShaderProgram* shader = GUI::wxGetApp().get_current_shader(); + if (shader == nullptr) + return; + if (this->is_left_handed()) glFrontFace(GL_CW); glsafe(::glCullFace(GL_BACK)); - glsafe(::glPushMatrix()); + if (with_outline) { + // Error: not supported! + throw Slic3r::InvalidArgument("Render GLVolume with outline is not supported"); + } // BBS: add logic for mmu segmentation rendering auto render_body = [&]() { @@ -446,7 +458,6 @@ void GLVolume::render(bool with_outline) for (int index = 0; index < colors.size(); index++) colors[index].a(render_color.a()); } - glsafe(::glMultMatrixd(world_matrix().data())); for (int idx = 0; idx < mmuseg_models.size(); idx++) { GUI::GLModel &m = mmuseg_models[idx]; if (m.is_empty()) @@ -489,7 +500,6 @@ void GLVolume::render(bool with_outline) } } else { - glsafe(::glMultMatrixd(world_matrix().data())); if (tverts_range == std::make_pair(0, -1)) model.render(); else @@ -498,7 +508,6 @@ void GLVolume::render(bool with_outline) }; //BBS: add logic of outline rendering - GLShaderProgram* shader = GUI::wxGetApp().get_current_shader(); //BOOST_LOG_TRIVIAL(info) << boost::format(": %1%, with_outline %2%, shader %3%.")%__LINE__ %with_outline %shader; if (with_outline && shader != nullptr) { @@ -629,7 +638,6 @@ void GLVolume::render(bool with_outline) render_body(); //BOOST_LOG_TRIVIAL(info) << boost::format(": %1%, normal render.")%__LINE__; } - glsafe(::glPopMatrix()); if (this->is_left_handed()) glFrontFace(GL_CCW); } @@ -640,7 +648,6 @@ void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_obj if (this->is_left_handed()) glFrontFace(GL_CW); glsafe(::glCullFace(GL_BACK)); - glsafe(::glPushMatrix()); bool color_volume = false; ModelObject* model_object = nullptr; @@ -704,16 +711,12 @@ void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_obj else m.render(this->tverts_range); } - } - else { - glsafe(::glMultMatrixd(world_matrix().data())); + } else { if (tverts_range == std::make_pair(0, -1)) model.render(); else model.render(this->tverts_range); } - - glsafe(::glPopMatrix()); if (this->is_left_handed()) glFrontFace(GL_CCW); } @@ -997,8 +1000,8 @@ int GLVolumeCollection::get_selection_support_threshold_angle(bool &enable_suppo } //BBS: add outline drawing logic -void GLVolumeCollection::render( - GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d &view_matrix, std::function filter_func, bool with_outline) const +void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, const Transform3d& projection_matrix, + std::function filter_func, bool with_outline) const { GLVolumeWithIdAndZList to_render = volumes_to_render(volumes, type, view_matrix, filter_func); if (to_render.empty()) @@ -1008,8 +1011,9 @@ void GLVolumeCollection::render( if (shader == nullptr) return; - GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat"); - GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat"); + 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")); if (type == ERenderType::Transparent) { glsafe(::glEnable(GL_BLEND)); @@ -1049,9 +1053,6 @@ void GLVolumeCollection::render( } shader->start_using(); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - if (!volume.first->model.is_initialized()) shader->set_uniform("uniform_color", volume.first->render_color); shader->set_uniform("z_range", m_z_range, 2); @@ -1096,6 +1097,10 @@ void GLVolumeCollection::render( glcheck(); volume.first->model.set_color(volume.first->render_color); + 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()); //BBS: add outline related logic volume.first->render(with_outline && volume.first->selected); @@ -1106,9 +1111,6 @@ void GLVolumeCollection::render( glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); } if (m_show_sinking_contours) { @@ -1462,8 +1464,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. @@ -1513,13 +1515,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]); } } } @@ -1541,11 +1543,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]); } } } @@ -1582,36 +1584,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]); } } @@ -1751,13 +1753,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 { @@ -1776,11 +1778,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]); } } @@ -1819,30 +1821,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]); } } diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 5c01e22f9c..79e53320b4 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -446,11 +446,8 @@ public: int get_selection_support_threshold_angle(bool&) const; // Render the volumes by OpenGL. //BBS: add outline drawing logic - void render(ERenderType type, - bool disable_cullface, - const Transform3d & view_matrix, - std::function filter_func = std::function(), - bool with_outline = true) const; + void render(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, const Transform3d& projection_matrix, + std::function filter_func = std::function(), bool with_outline = true) const; // Clear the geometry void clear() { for (auto *v : volumes) delete v; volumes.clear(); } diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp index 4abaedecac..401365ad4e 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -92,7 +92,6 @@ public: const std::array& get_viewport() const { return m_viewport; } const Transform3d& get_view_matrix() const { return m_view_matrix; } const Transform3d& get_projection_matrix() const { return m_projection_matrix; } - Transform3d get_projection_view_matrix() const { return m_projection_matrix * m_view_matrix; } //BBS const Eigen::Quaterniond& get_view_rotation() const {return m_view_rotation; } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 675af85d22..c106ed01ec 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -307,7 +307,7 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he if (!m_visible) return; - GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr"); if (shader == nullptr) return; @@ -317,13 +317,14 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he shader->start_using(); shader->set_uniform("emission_factor", 0.0f); - glsafe(::glPushMatrix()); - glsafe(::glMultMatrixf(m_world_transform.data())); + 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()); m_model.render(); - glsafe(::glPopMatrix()); - shader->stop_using(); glsafe(::glDisable(GL_BLEND)); @@ -787,7 +788,7 @@ void GCodeViewer::init(ConfigOptionMode mode, PresetBundle* preset_bundle) case EMoveType::Seam: { // if (wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) { // buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::InstancedModel; -// buffer.shader = "gouraud_light_instanced"; +// buffer.shader = "gouraud_light_instanced_attr"; // buffer.model.model.init_from(diamond(16)); // buffer.model.color = option_color(type); // buffer.model.instances.format = InstanceVBuffer::EFormat::InstancedModel; @@ -798,7 +799,7 @@ void GCodeViewer::init(ConfigOptionMode mode, PresetBundle* preset_bundle) buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::BatchedModel; buffer.vertices.format = VBuffer::EFormat::PositionNormal3; - buffer.shader = "gouraud_light"; + buffer.shader = "gouraud_light_attr"; buffer.model.data = diamond(16); buffer.model.color = option_color(type); @@ -810,13 +811,13 @@ void GCodeViewer::init(ConfigOptionMode mode, PresetBundle* preset_bundle) case EMoveType::Extrude: { buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Triangle; buffer.vertices.format = VBuffer::EFormat::PositionNormal3; - buffer.shader = "gouraud_light"; + buffer.shader = "gouraud_light_attr"; break; } case EMoveType::Travel: { buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Line; - buffer.vertices.format = VBuffer::EFormat::PositionNormal3; - buffer.shader = "toolpaths_lines"; + buffer.vertices.format = VBuffer::EFormat::Position; + buffer.shader = "flat_attr"; break; } } @@ -1324,7 +1325,7 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai // Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415. assert(!path.sizes.empty()); assert(!path.offsets.empty()); - glsafe(::glUniform4fv(uniform_color, 1, static_cast(path.color.data()))); + shader.set_uniform(uniform_color, path.color); glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_triangles_calls_count; @@ -1359,7 +1360,7 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai #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) { + auto render_as_batched_model = [](TBuffer& buffer, GLShaderProgram& shader, int position_id, int normal_id) { #endif // ENABLE_GCODE_VIEWER_STATISTICS struct Range @@ -1375,12 +1376,16 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai 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)); - 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)); + if (position_id != -1) { + glsafe(::glVertexAttribPointer(position_id, buffer.vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes())); + glsafe(::glEnableVertexAttribArray(position_id)); + } bool has_normals = buffer.vertices.normal_size_floats() > 0; if (has_normals) { - glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); + if (normal_id != -1) { + glsafe(::glVertexAttribPointer(normal_id, buffer.vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); + glsafe(::glEnableVertexAttribArray(normal_id)); + } } glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); @@ -1403,11 +1408,11 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai } glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - - if (has_normals) - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + + if (normal_id != -1) + glsafe(::glDisableVertexAttribArray(normal_id)); + if (position_id != -1) + glsafe(::glDisableVertexAttribArray(position_id)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); buffer_range.first = buffer_range.last; @@ -1423,10 +1428,15 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai if (!buffer.visible || !buffer.has_data()) continue; - GLShaderProgram* shader = opengl_manager.get_shader("cali"); + GLShaderProgram* shader = opengl_manager.get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + int position_id = shader->get_attrib_location("v_position"); + int normal_id = shader->get_attrib_location("v_normal"); + if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel) { //shader->set_uniform("emission_factor", 0.25f); render_as_instanced_model(buffer, *shader); @@ -1434,7 +1444,7 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai } else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) { //shader->set_uniform("emission_factor", 0.25f); - render_as_batched_model(buffer, *shader); + render_as_batched_model(buffer, *shader, position_id, normal_id); //shader->set_uniform("emission_factor", 0.0f); } else { @@ -1452,12 +1462,16 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai continue; 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)); + if (position_id != -1) { + glsafe(::glVertexAttribPointer(position_id, buffer.vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes())); + glsafe(::glEnableVertexAttribArray(position_id)); + } bool has_normals = false;// buffer.vertices.normal_size_floats() > 0; if (has_normals) { - glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); + if (normal_id != -1) { + glsafe(::glVertexAttribPointer(normal_id, buffer.vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); + glsafe(::glEnableVertexAttribArray(normal_id)); + } } glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); @@ -1473,11 +1487,12 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai } glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + + if (normal_id != -1) + glsafe(::glDisableVertexAttribArray(normal_id)); + if (position_id != -1) + glsafe(::glDisableVertexAttribArray(position_id)); - if (has_normals) - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } } @@ -2032,15 +2047,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result, const // format data into the buffers to be rendered as lines auto add_vertices_as_line = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, VertexBuffer& vertices) { - auto add_vertex = [&vertices](const Vec3f& position, const Vec3f& normal) { + auto add_vertex = [&vertices](const Vec3f& position) { // add position vertices.push_back(position.x()); vertices.push_back(position.y()); vertices.push_back(position.z()); - // add normal - vertices.push_back(normal.x()); - vertices.push_back(normal.y()); - vertices.push_back(normal.z()); }; // x component of the normal to the current segment (the normal is parallel to the XY plane) //BBS: Has modified a lot for this function to support arc move @@ -2048,13 +2059,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result, const for (size_t i = 0; i < loop_num + 1; i++) { const Vec3f &previous = (i == 0? prev.position : curr.interpolation_points[i-1]); const Vec3f ¤t = (i == loop_num? curr.position : curr.interpolation_points[i]); - const Vec3f dir = (current - previous).normalized(); - Vec3f normal(dir.y(), -dir.x(), 0.0); - normal.normalize(); // add previous vertex - add_vertex(previous, normal); + add_vertex(previous); // add current vertex - add_vertex(current, normal); + add_vertex(current); } }; //BBS: modify a lot to support arc travel @@ -2325,7 +2333,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result, const auto add_indices_as_model_batch = [](const GLModel::Geometry& data, IndexBuffer& indices, IBufferType base_index) { const size_t indices_count = data.indices_count(); for (size_t i = 0; i < indices_count; ++i) { - indices.push_back(static_cast(data.extract_ushort_index(i) + base_index)); + indices.push_back(static_cast(data.extract_index(i) + base_index)); } }; @@ -3765,15 +3773,14 @@ m_no_render_path = false; 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 }; 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) { @@ -3793,7 +3800,7 @@ void GCodeViewer::render_toolpaths() #if ENABLE_GCODE_VIEWER_STATISTICS this #endif // ENABLE_GCODE_VIEWER_STATISTICS - ](std::vector::reverse_iterator it_path, std::vector::reverse_iterator it_end, GLShaderProgram& shader, int uniform_color) { + ](std::vector::iterator it_path, std::vector::iterator it_end, GLShaderProgram& shader, int uniform_color) { glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); glsafe(::glEnable(GL_POINT_SPRITE)); @@ -3802,7 +3809,7 @@ void GCodeViewer::render_toolpaths() // Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415. assert(! path.sizes.empty()); assert(! path.offsets.empty()); - glsafe(::glUniform4fv(uniform_color, 1, static_cast(path.color.data()))); + shader.set_uniform(uniform_color, path.color); glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_points_calls_count; @@ -3813,20 +3820,17 @@ void GCodeViewer::render_toolpaths() glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); }; - auto shader_init_as_lines = [light_intensity](GLShaderProgram &shader) { - shader.set_uniform("light_intensity", light_intensity); - }; auto render_as_lines = [ #if ENABLE_GCODE_VIEWER_STATISTICS this #endif // ENABLE_GCODE_VIEWER_STATISTICS - ](std::vector::reverse_iterator it_path, std::vector::reverse_iterator it_end, GLShaderProgram& shader, int uniform_color) { + ](std::vector::iterator it_path, std::vector::iterator it_end, GLShaderProgram& shader, int uniform_color) { for (auto it = it_path; it != it_end && it_path->ibuffer_id == it->ibuffer_id; ++it) { const RenderPath& path = *it; // Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415. assert(! path.sizes.empty()); assert(! path.offsets.empty()); - glsafe(::glUniform4fv(uniform_color, 1, static_cast(path.color.data()))); + shader.set_uniform(uniform_color, path.color); glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_lines_calls_count; @@ -3838,13 +3842,13 @@ void GCodeViewer::render_toolpaths() #if ENABLE_GCODE_VIEWER_STATISTICS this #endif // ENABLE_GCODE_VIEWER_STATISTICS - ](std::vector::reverse_iterator it_path, std::vector::reverse_iterator it_end, GLShaderProgram& shader, int uniform_color) { + ](std::vector::iterator it_path, std::vector::iterator it_end, GLShaderProgram& shader, int uniform_color) { for (auto it = it_path; it != it_end && it_path->ibuffer_id == it->ibuffer_id; ++it) { const RenderPath& path = *it; // Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415. assert(! path.sizes.empty()); assert(! path.offsets.empty()); - glsafe(::glUniform4fv(uniform_color, 1, static_cast(path.color.data()))); + shader.set_uniform(uniform_color, path.color); glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_triangles_calls_count; @@ -3877,9 +3881,9 @@ void GCodeViewer::render_toolpaths() }; #if ENABLE_GCODE_VIEWER_STATISTICS - auto render_as_batched_model = [this](TBuffer& buffer, GLShaderProgram& shader) { + 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) { + auto render_as_batched_model = [](TBuffer& buffer, GLShaderProgram& shader, int position_id, int normal_id) { #endif // ENABLE_GCODE_VIEWER_STATISTICS struct Range @@ -3889,30 +3893,34 @@ 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)); - 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 (position_id != -1) { + glsafe(::glVertexAttribPointer(position_id, buffer.vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes())); + glsafe(::glEnableVertexAttribArray(position_id)); + } + const bool has_normals = buffer.vertices.normal_size_floats() > 0; if (has_normals) { - glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); + if (normal_id != -1) { + glsafe(::glVertexAttribPointer(normal_id, buffer.vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); + glsafe(::glEnableVertexAttribArray(normal_id)); + } } glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); for (auto& range : buffer.model.instances.render_ranges.ranges) { - Range range_range = { range.offset, range.offset + range.count }; + 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 @@ -3924,10 +3932,10 @@ void GCodeViewer::render_toolpaths() glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - if (has_normals) - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + if (normal_id != -1) + glsafe(::glDisableVertexAttribArray(normal_id)); + if (position_id != -1) + glsafe(::glDisableVertexAttribArray(position_id)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); buffer_range.first = buffer_range.last; @@ -3938,9 +3946,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); - //BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":begin_id %1%, end_id %2% ")%(int)begin_id %(int)end_id; + 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]; @@ -3948,80 +3955,90 @@ 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.rbegin(); - //BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":buffer indices size %1%, render_path size %2% ")%buffer.indices.size() %buffer.render_paths.size(); - unsigned int indices_count = static_cast(buffer.indices.size()); - for (unsigned int index = 0; index < indices_count; ++index) { - unsigned int ibuffer_id = indices_count - index - 1; - const IBuffer& i_buffer = buffer.indices[ibuffer_id]; - // Skip all paths with ibuffer_id < ibuffer_id. - for (; it_path != buffer.render_paths.rend() && it_path->ibuffer_id > ibuffer_id; ++ it_path) ; - if (it_path == buffer.render_paths.rend() || 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)); - } + 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"); - // 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.rend(), *shader, uniform_color); - break; - } - case TBuffer::ERenderPrimitiveType::Line: { - glsafe(::glLineWidth(static_cast(line_width(zoom)))); - render_as_lines(it_path, buffer.render_paths.rend(), *shader, uniform_color); - break; - } - case TBuffer::ERenderPrimitiveType::Triangle: { - render_as_triangles(it_path, buffer.render_paths.rend(), *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); + render_as_batched_model(buffer, *shader, position_id, normal_id); + shader->set_uniform("emission_factor", 0.0f); + } + else { + if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Point) + shader_init_as_points(*shader); + 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 (position_id != -1) { + glsafe(::glVertexAttribPointer(position_id, buffer.vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes())); + glsafe(::glEnableVertexAttribArray(position_id)); + } + const bool has_normals = buffer.vertices.normal_size_floats() > 0; + if (has_normals) { + if (normal_id != -1) { + glsafe(::glVertexAttribPointer(normal_id, buffer.vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes())); + glsafe(::glEnableVertexAttribArray(normal_id)); + } + } + + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); + + // 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 (normal_id != -1) + glsafe(::glDisableVertexAttribArray(normal_id)); + if (position_id != -1) + glsafe(::glDisableVertexAttribArray(position_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + } + } + + shader->stop_using(); } #if ENABLE_GCODE_VIEWER_STATISTICS @@ -4030,37 +4047,55 @@ 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(); + + 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"); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, cap.vbo)); + if (position_id != -1) { + glsafe(::glVertexAttribPointer(position_id, buffer->vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer->vertices.vertex_size_bytes(), (const void*)buffer->vertices.position_offset_bytes())); + glsafe(::glEnableVertexAttribArray(position_id)); + } + const bool has_normals = buffer->vertices.normal_size_floats() > 0; + if (has_normals) { + if (normal_id != -1) { + glsafe(::glVertexAttribPointer(normal_id, buffer->vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer->vertices.vertex_size_bytes(), (const void*)buffer->vertices.normal_offset_bytes())); + glsafe(::glEnableVertexAttribArray(normal_id)); } + } - shader->set_uniform("uniform_color", cap.color); + 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; #endif // ENABLE_GCODE_VIEWER_STATISTICS - if (has_normals) - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); + if (normal_id != -1) + glsafe(::glDisableVertexAttribArray(normal_id)); + if (position_id != -1) + glsafe(::glDisableVertexAttribArray(position_id)); - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - shader->stop_using(); - } + shader->stop_using(); }; for (unsigned int i = 0; i < 2; ++i) { @@ -4076,7 +4111,7 @@ void GCodeViewer::render_shells() //if (!m_shells.visible || m_shells.volumes.empty()) return; - GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr"); if (shader == nullptr) return; @@ -4084,8 +4119,9 @@ void GCodeViewer::render_shells() // glsafe(::glDepthMask(GL_FALSE)); shader->start_using(); + const Camera& camera = wxGetApp().plater()->get_camera(); //BBS: reopen cul faces - m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix()); + m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, false, camera.get_view_matrix(), camera.get_projection_matrix()); shader->stop_using(); // glsafe(::glDepthMask(GL_TRUE)); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f66a59fb12..81db138871 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -14,22 +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/GLCanvas3D.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 "slic3r/GUI/BitmapCache.hpp" -#include "slic3r/Utils/MacDarkMode.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_Colors.hpp" @@ -38,6 +32,9 @@ #include "NotificationManager.hpp" #include "format.hpp" +#include "slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp" +#include "slic3r/Utils/UndoRedo.hpp" + #include #if ENABLE_RETINA_GL @@ -166,7 +163,7 @@ void GLCanvas3D::LayersEditing::select_object(const Model& model, int object_id) bool GLCanvas3D::LayersEditing::is_allowed() const { - return wxGetApp().get_shader("variable_layer_height") != nullptr && m_z_texture_id > 0; + return wxGetApp().get_shader("variable_layer_height_attr") != nullptr && m_z_texture_id > 0; } bool GLCanvas3D::LayersEditing::is_enabled() const @@ -220,9 +217,8 @@ void GLCanvas3D::LayersEditing::render_variable_layer_height_dialog(const GLCanv ImGuiWrapper& imgui = *wxGetApp().imgui(); const Size& cnv_size = canvas.get_canvas_size(); - float zoom = (float)wxGetApp().plater()->get_camera().get_zoom(); float left_pos = canvas.m_main_toolbar.get_item("layersediting")->render_left_pos; - const float x = 0.5 * cnv_size.get_width() + left_pos * zoom; + const float x = (1 + left_pos) * cnv_size.get_width() / 2; imgui.set_next_window_pos(x, canvas.m_main_toolbar.get_height(), ImGuiCond_Always, 0.0f, 0.0f); imgui.push_toolbar_style(canvas.get_scale()); @@ -322,12 +318,8 @@ void GLCanvas3D::LayersEditing::render_variable_layer_height_dialog(const GLCanv void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) { render_variable_layer_height_dialog(canvas); - const Rect& bar_rect = get_bar_rect_viewport(canvas); - m_profile.dirty = m_profile.old_bar_rect != bar_rect; - render_active_object_annotations(canvas, bar_rect); - render_profile(bar_rect); - m_profile.old_bar_rect = bar_rect; - m_profile.dirty = false; + render_active_object_annotations(canvas); + render_profile(canvas); } float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas) @@ -361,18 +353,9 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_screen(const GLCanvas3D& canvas) return { w - thickness_bar_width(canvas), 0.0f, w, h }; } -Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) -{ - const Size& cnv_size = canvas.get_canvas_size(); - float half_w = 0.5f * (float)cnv_size.get_width(); - float half_h = 0.5f * (float)cnv_size.get_height(); - 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 }; -} - bool GLCanvas3D::LayersEditing::is_initialized() const { - return wxGetApp().get_shader("variable_layer_height") != nullptr; + return wxGetApp().get_shader("variable_layer_height_attr") != nullptr; } std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) const @@ -401,12 +384,20 @@ std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) con return ret; } -void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) +void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas) { if (!m_enabled) return; - GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height"); + 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"); if (shader == nullptr) return; @@ -417,32 +408,36 @@ 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); + shader->set_uniform("view_model_matrix", Transform3d::Identity()); + shader->set_uniform("projection_matrix", Transform3d::Identity()); + shader->set_uniform("normal_matrix", (Matrix3d)Eigen::Matrix3d::Identity()); glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); // Render the color bar - if (!m_profile.background.is_initialized() || m_profile.dirty) { + if (!m_profile.background.is_initialized() || m_profile.old_canvas_width != cnv_width) { + m_profile.old_canvas_width = cnv_width; 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 - 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(); + 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; 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)); } @@ -454,73 +449,82 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 shader->stop_using(); } -void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect) +void GLCanvas3D::LayersEditing::render_profile(const GLCanvas3D& canvas) { if (!m_enabled) return; //FIXME show some kind of legend. + if (!m_slicing_parameters) return; + 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 = 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; + 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; // Baseline - if (!m_profile.baseline.is_initialized() || m_profile.dirty) { + if (!m_profile.baseline.is_initialized() || m_profile.old_layer_height_profile != m_layer_height_profile) { 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 - 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())); + 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)); // indices - init_data.add_ushort_line(0, 1); + init_data.add_line(0, 1); m_profile.baseline.init_from(std::move(init_data)); } - if (!m_profile.profile.is_initialized() || m_profile.dirty || m_profile.old_layer_height_profile != m_layer_height_profile) { + if (!m_profile.profile.is_initialized() || m_profile.old_layer_height_profile != m_layer_height_profile) { 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) { - 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); + 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))); + init_data.add_index(i / 2); } m_profile.profile.init_from(std::move(init_data)); } - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); + shader->set_uniform("view_model_matrix", Transform3d::Identity()); + shader->set_uniform("projection_matrix", Transform3d::Identity()); m_profile.baseline.render(); m_profile.profile.render(); shader->stop_using(); } } -void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D & canvas, const GLVolumeCollection & volumes)//render volume and layer height texture (has mapping relation with each other) +void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const GLVolumeCollection& volumes) { assert(this->is_allowed()); assert(this->last_object_id != -1); @@ -530,7 +534,7 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D & canvas, const if (current_shader != nullptr) current_shader->stop_using(); - GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height"); + GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height_attr"); if (shader == nullptr) return; @@ -544,6 +548,9 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D & canvas, const 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)); + const Camera& camera = wxGetApp().plater()->get_camera(); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + // Initialize the layer height texture mapping. const GLsizei w = (GLsizei)m_layers_texture.width; const GLsizei h = (GLsizei)m_layers_texture.height; @@ -562,6 +569,9 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D & canvas, const shader->set_uniform("volume_world_matrix", glvolume->world_matrix()); shader->set_uniform("object_max_z", 0.0f); + 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()); glvolume->render(); } @@ -883,7 +893,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons if (!polygons.empty()) { if (m_render_fill) { GLModel::Geometry fill_data; - fill_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::UINT }; + fill_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; fill_data.color = { 0.8f, 0.8f, 1.0f, 0.5f }; // vertices + indices @@ -897,7 +907,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); } } @@ -910,7 +920,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons //BBS: add the height limit compute logic if (!height_polygons.empty()) { GLModel::Geometry height_fill_data; - height_fill_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::UINT }; + height_fill_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 }; height_fill_data.color = {0.8f, 0.8f, 1.0f, 0.5f}; // vertices + indices @@ -923,7 +933,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons height_fill_data.add_vertex(point); ++vertices_counter; if (vertices_counter % 3 == 0) - height_fill_data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); + height_fill_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); } } @@ -936,12 +946,16 @@ void GLCanvas3D::SequentialPrintClearance::render() const ColorRGBA FILL_COLOR = { 0.7f, 0.7f, 1.0f, 0.5f }; const ColorRGBA NO_FILL_COLOR = { 0.75f, 0.75f, 0.75f, 0.75f }; - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader == nullptr) return; shader->start_using(); + 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()); + glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glDisable(GL_CULL_FACE)); glsafe(::glEnable(GL_BLEND)); @@ -1839,9 +1853,9 @@ void GLCanvas3D::render(bool only_init) _render_sla_slices(); _render_selection(); if (!no_partplate) - _render_bed(!camera.is_looking_downward(), show_axes); + _render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), show_axes); if (!no_partplate) //BBS: add outline logic - _render_platelist(!camera.is_looking_downward(), only_current, only_body, hover_id, true); + _render_platelist(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), only_current, only_body, hover_id, true); _render_objects(GLVolumeCollection::ERenderType::Transparent, !m_gizmos.is_running()); } /* preview render */ @@ -1849,8 +1863,8 @@ void GLCanvas3D::render(bool only_init) _render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running()); _render_sla_slices(); _render_selection(); - _render_bed(!camera.is_looking_downward(), show_axes); - _render_platelist(!camera.is_looking_downward(), only_current, true, hover_id); + _render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), show_axes); + _render_platelist(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), only_current, true, hover_id); // BBS: GUI refactor: add canvas size as parameters _render_gcode(cnv_size.get_width(), cnv_size.get_height()); } @@ -1858,7 +1872,7 @@ void GLCanvas3D::render(bool only_init) else if (m_canvas_type == ECanvasType::CanvasAssembleView) { //BBS: add outline logic _render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running()); - //_render_bed(!camera.is_looking_downward(), show_axes); + //_render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), show_axes); _render_plane(); //BBS: add outline logic insteadof selection under assemble view //_render_selection(); @@ -1992,7 +2006,7 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, const GLVolumeCollection& volumes, Camera::EType camera_type, bool use_top_view, bool for_picking) { - GLShaderProgram* shader = wxGetApp().get_shader("thumbnail"); + GLShaderProgram* shader = wxGetApp().get_shader("thumbnail_attr"); ModelObjectPtrs& model_objects = GUI::wxGetApp().model().objects; std::vector colors = ::get_extruders_colors(); switch (OpenGLManager::get_framebuffers_type()) @@ -5180,7 +5194,7 @@ bool GLCanvas3D::_render_orient_menu(float left, float right, float bottom, floa //original use center as {0.0}, and top is (canvas_h/2), bottom is (-canvas_h/2), also plus inv_camera //now change to left_up as {0,0}, and top is 0, bottom is canvas_h #if BBS_TOOLBAR_ON_TOP - const float x = left * float(wxGetApp().plater()->get_camera().get_zoom()) + 0.5f * canvas_w; + const float x = (1 + left) * canvas_w / 2; ImGuiWrapper::push_toolbar_style(get_scale()); imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f); #else @@ -5265,9 +5279,8 @@ bool GLCanvas3D::_render_arrange_menu(float left, float right, float bottom, flo //original use center as {0.0}, and top is (canvas_h/2), bottom is (-canvas_h/2), also plus inv_camera //now change to left_up as {0,0}, and top is 0, bottom is canvas_h #if BBS_TOOLBAR_ON_TOP - float zoom = (float)wxGetApp().plater()->get_camera().get_zoom(); float left_pos = m_main_toolbar.get_item("arrange")->render_left_pos; - const float x = 0.5 * canvas_w + left_pos * zoom; + const float x = (1 + left_pos) * canvas_w / 2; imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.0f, 0.0f); #else @@ -5536,19 +5549,15 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const } else { camera.zoom_to_box(volumes_box); - const Vec3d& target = camera.get_target(); - double distance = camera.get_distance(); camera.select_view("iso"); - camera.apply_view_matrix(); - - camera.apply_projection(plate_build_volume); } - camera.apply_view_matrix(); + const Transform3d &view_matrix = camera.get_view_matrix(); + camera.apply_projection(plate_build_volume); - //GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + //GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr"); if (!for_picking && (shader == nullptr)) { BOOST_LOG_TRIVIAL(info) << boost::format("render_thumbnail with no picking: shader is null, return directly"); return; @@ -5561,6 +5570,8 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); glsafe(::glEnable(GL_DEPTH_TEST)); + const Transform3d &projection_matrix = camera.get_projection_matrix(); + if (for_picking) { //if (OpenGLManager::can_multisample()) // This flag is often ignored by NVIDIA drivers if rendering into a screen buffer. @@ -5573,9 +5584,6 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const // do not cull backfaces to show broken geometry, if any glsafe(::glDisable(GL_CULL_FACE)); - //glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - //glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - for (GLVolume* vol : visible_volumes) { // Object picking mode. Render the object with a color encoding the object index. // we reserve color = (0,0,0) for occluders (as the printbed) @@ -5587,15 +5595,19 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const unsigned int g = (id & (0x000000FF << 8)) >> 8; unsigned int b = (id & (0x000000FF << 16)) >> 16; unsigned int a = 0xFF; - glsafe(::glColor4f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255, (GLfloat)a * INV_255)); + vol->model.set_color({(GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255, (GLfloat)a * INV_255}); /*curr_color[0] = (GLfloat)r * INV_255; curr_color[1] = (GLfloat)g * INV_255; curr_color[2] = (GLfloat)b * INV_255; curr_color[3] = (GLfloat)a * INV_255; shader->set_uniform("uniform_color", curr_color);*/ - bool is_active = vol->is_active; + const bool is_active = vol->is_active; vol->is_active = true; + 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()); vol->simple_render(nullptr, model_objects, extruder_colors); vol->is_active = is_active; } @@ -5627,8 +5639,12 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const shader->set_uniform("uniform_color", (vol->printable && !vol->is_outside) ? orange : gray); }*/ // 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; + 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()); vol->simple_render(shader, model_objects, extruder_colors); vol->is_active = is_active; } @@ -6404,7 +6420,8 @@ void GLCanvas3D::_picking_pass() //BBS: only render plate in view 3D if (m_canvas_type == ECanvasType::CanvasView3D) { - _render_plates_for_picking(); + const Camera &camera = wxGetApp().plater()->get_camera(); + _render_plates_for_picking(camera.get_view_matrix(), camera.get_projection_matrix()); } m_camera_clipping_plane = m_gizmos.get_clipping_plane(); @@ -6574,12 +6591,6 @@ void GLCanvas3D::_render_background() } } - glsafe(::glPushMatrix()); - glsafe(::glLoadIdentity()); - glsafe(::glMatrixMode(GL_PROJECTION)); - glsafe(::glPushMatrix()); - glsafe(::glLoadIdentity()); - // Draws a bottom to top gradient over the complete screen. glsafe(::glDisable(GL_DEPTH_TEST)); @@ -6591,7 +6602,7 @@ void GLCanvas3D::_render_background() 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); @@ -6602,30 +6613,25 @@ 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)); } - GLShaderProgram* shader = wxGetApp().get_shader("background"); + GLShaderProgram* shader = wxGetApp().get_shader("background_attr"); 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(); } glsafe(::glEnable(GL_DEPTH_TEST)); - - glsafe(::glPopMatrix()); - glsafe(::glMatrixMode(GL_MODELVIEW)); - glsafe(::glPopMatrix()); } -void GLCanvas3D::_render_bed(bool bottom, bool show_axes) +void GLCanvas3D::_render_bed(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_axes) { float scale_factor = 1.0; #if ENABLE_RETINA_GL @@ -6643,27 +6649,27 @@ void GLCanvas3D::_render_bed(bool bottom, bool show_axes) //bool show_texture = true; //BBS set axes mode m_bed.set_axes_mode(m_main_toolbar.is_enabled()); - m_bed.render(*this, bottom, scale_factor, show_axes); + m_bed.render(*this, view_matrix, projection_matrix, bottom, scale_factor, show_axes); } -void GLCanvas3D::_render_bed_for_picking(bool bottom) +void GLCanvas3D::_render_bed_for_picking(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom) { float scale_factor = 1.0; #if ENABLE_RETINA_GL scale_factor = m_retina_helper->get_scale_factor(); #endif // ENABLE_RETINA_GL - //m_bed.render_for_picking(*this, bottom, scale_factor); + //m_bed.render_for_picking(*this, view_matrix, projection_matrix, bottom, scale_factor); } -void GLCanvas3D::_render_platelist(bool bottom, bool only_current, bool only_body, int hover_id, bool render_cali) const +void GLCanvas3D::_render_platelist(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current, bool only_body, int hover_id, bool render_cali) { - wxGetApp().plater()->get_partplate_list().render(bottom, only_current, only_body, hover_id, render_cali); + wxGetApp().plater()->get_partplate_list().render(view_matrix, projection_matrix, bottom, only_current, only_body, hover_id, render_cali); } -void GLCanvas3D::_render_plates_for_picking() const +void GLCanvas3D::_render_plates_for_picking(const Transform3d &view_matrix, const Transform3d &projection_matrix) { - wxGetApp().plater()->get_partplate_list().render_for_picking_pass(); + wxGetApp().plater()->get_partplate_list().render_for_picking_pass(view_matrix, projection_matrix); } void GLCanvas3D::_render_plane() const @@ -6736,7 +6742,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with else m_volumes.set_show_sinking_contours(!m_gizmos.is_hiding_instances()); - GLShaderProgram* shader = wxGetApp().get_shader("gouraud"); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_attr"); ECanvasType canvas_type = this->m_canvas_type; if (shader != nullptr) { shader->start_using(); @@ -6751,10 +6757,11 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with { if (m_picking_enabled && 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; - 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); - }); + 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); + }); m_layers_editing.render_volumes(*this, m_volumes); } else { @@ -6766,7 +6773,8 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with }*/ //BBS:add assemble view related logic // do not cull backfaces to show broken geometry, if any - m_volumes.render(type, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this, canvas_type](const GLVolume& volume) { + const Camera& camera = wxGetApp().plater()->get_camera(); + m_volumes.render(type, m_picking_enabled, camera.get_view_matrix(), camera.get_projection_matrix(), [this, canvas_type](const GLVolume& volume) { if (canvas_type == ECanvasType::CanvasAssembleView) { return !volume.is_modifier && !volume.is_wipe_tower; } @@ -6798,8 +6806,9 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with else shader->set_uniform("show_wireframe", false); }*/ + const Camera& camera = wxGetApp().plater()->get_camera(); //BBS:add assemble view related logic - m_volumes.render(type, false, wxGetApp().plater()->get_camera().get_view_matrix(), [this, canvas_type](const GLVolume& volume) { + m_volumes.render(type, false, camera.get_view_matrix(), camera.get_projection_matrix(), [this, canvas_type](const GLVolume& volume) { if (canvas_type == ECanvasType::CanvasAssembleView) { return !volume.is_modifier; } @@ -7171,16 +7180,13 @@ void GLCanvas3D::_render_style_editor() void GLCanvas3D::_render_volumes_for_picking() const { - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader == nullptr) return; // do not cull backfaces to show broken geometry, if any glsafe(::glDisable(GL_CULL_FACE)); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - const Transform3d& view_matrix = wxGetApp().plater()->get_camera().get_view_matrix(); for (size_t type = 0; type < 2; ++ type) { GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, (type == 0) ? GLVolumeCollection::ERenderType::Opaque : GLVolumeCollection::ERenderType::Transparent, view_matrix); @@ -7194,14 +7200,14 @@ void GLCanvas3D::_render_volumes_for_picking() const //const unsigned int id = 1 + volume.second.first; volume.first->model.set_color(picking_decode(id)); shader->start_using(); + 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()); volume.first->render(); shader->stop_using(); } } - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glEnable(GL_CULL_FACE)); } @@ -7241,32 +7247,19 @@ 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(); + const float top = 0.5f * (float)cnv_size.get_height(); -#if BBS_TOOLBAR_ON_TOP GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar(); - float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; - float gizmo_width = m_gizmos.get_scaled_total_width(); - float assemble_width = m_assemble_view_toolbar.get_width(); - float separator_width = m_separator_toolbar.get_width(); - float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; - float left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + separator_width + gizmo_width + assemble_width - collapse_toolbar_width)) * inv_zoom; -#else - float gizmo_height = m_gizmos.get_scaled_total_height(); - float space_height = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale(); - float main_toolbar_height = (float)m_main_toolbar.get_height(); - float assemble_height = m_assemble_view_toolbar.get_height(); - float top = 0.5f * (main_toolbar_height + gizmo_height + assemble_height) * inv_zoom; - float left = (0.5f * (float)cnv_size.get_width() - m_main_toolbar.get_width()) * inv_zoom; - //BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": top %1%, main_toolbar_height %2%, space_height %3% gizmo_height %4%") % top % main_toolbar_height % space_height % gizmo_height; -#endif + const float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; + const float gizmo_width = m_gizmos.get_scaled_total_width(); + const float assemble_width = m_assemble_view_toolbar.get_width(); + const float separator_width = m_separator_toolbar.get_width(); + const float left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + separator_width + gizmo_width + assemble_width - collapse_toolbar_width)); 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); - } } //BBS: GUI refactor: GLToolbar adjust @@ -7591,28 +7584,16 @@ void GLCanvas3D::_render_assemble_view_toolbar() const if (!m_assemble_view_toolbar.is_enabled()) return; - Size cnv_size = get_canvas_size(); - float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); - -#if BBS_TOOLBAR_ON_TOP + const Size cnv_size = get_canvas_size(); GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar(); - float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; - float gizmo_width = m_gizmos.get_scaled_total_width(); - float assemble_width = m_assemble_view_toolbar.get_width(); - float separator_width = m_separator_toolbar.get_width(); - float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; - float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width - separator_width - collapse_toolbar_width)) * inv_zoom; - float left = main_toolbar_left + (m_main_toolbar.get_width() + gizmo_width) * inv_zoom; - //float left = 0.5f * (m_main_toolbar.get_width() + gizmo_width - m_assemble_view_toolbar.get_width() + collapse_toolbar_width) * inv_zoom; -#else - float gizmo_height = m_gizmos.get_scaled_total_height(); - //float space_height = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale(); - float main_toolbar_height = (float)m_main_toolbar.get_height(); - float assemble_height = (float)m_assemble_view_toolbar.get_height(); - float top = 0.5f * (assemble_height - main_toolbar_height - gizmo_height) * inv_zoom; - float left = (0.5f * (float)cnv_size.get_width() - m_assemble_view_toolbar.get_width()) * inv_zoom; - //BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": top %1%, main_toolbar_height %2%, space_height %3% gizmo_height %4%") % top % main_toolbar_height % space_height % gizmo_height; -#endif + const float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; + const float gizmo_width = m_gizmos.get_scaled_total_width(); + const float assemble_width = m_assemble_view_toolbar.get_width(); + const float separator_width = m_separator_toolbar.get_width(); + const float top = 0.5f * (float)cnv_size.get_height(); + const float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width + separator_width - collapse_toolbar_width)); + const float left = main_toolbar_left + (m_main_toolbar.get_width() + gizmo_width + separator_width); + m_assemble_view_toolbar.set_position(top, left); m_assemble_view_toolbar.render(*this); } @@ -7677,17 +7658,15 @@ void GLCanvas3D::_render_separator_toolbar_right() const if (!m_separator_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(); GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar(); - float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; - float gizmo_width = m_gizmos.get_scaled_total_width(); - float assemble_width = m_assemble_view_toolbar.get_width(); - float separator_width = m_separator_toolbar.get_width(); - float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; - float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width - collapse_toolbar_width)) * inv_zoom; - float left = main_toolbar_left + (m_main_toolbar.get_width() + gizmo_width) * inv_zoom; + const float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; + const float gizmo_width = m_gizmos.get_scaled_total_width(); + const float assemble_width = m_assemble_view_toolbar.get_width(); + const float separator_width = m_separator_toolbar.get_width(); + const float top = 0.5f * (float)cnv_size.get_height(); + const float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width + separator_width - collapse_toolbar_width)); + const float left = main_toolbar_left + (m_main_toolbar.get_width() + gizmo_width + separator_width / 2); m_separator_toolbar.set_position(top, left); m_separator_toolbar.render(*this,GLToolbarItem::SeparatorLine); @@ -7698,17 +7677,15 @@ void GLCanvas3D::_render_separator_toolbar_left() const if (!m_separator_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(); GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar(); - float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; - float gizmo_width = m_gizmos.get_scaled_total_width(); - float assemble_width = m_assemble_view_toolbar.get_width(); - float separator_width = m_separator_toolbar.get_width(); - float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; - float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width + separator_width - collapse_toolbar_width)) * inv_zoom; - float left = main_toolbar_left + (m_main_toolbar.get_width()) * inv_zoom; + const float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; + const float gizmo_width = m_gizmos.get_scaled_total_width(); + const float assemble_width = m_assemble_view_toolbar.get_width(); + const float separator_width = m_separator_toolbar.get_width(); + const float top = 0.5f * (float)cnv_size.get_height(); + const float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width + separator_width - collapse_toolbar_width)); + const float left = main_toolbar_left + (m_main_toolbar.get_width()); m_separator_toolbar.set_position(top, left); m_separator_toolbar.render(*this,GLToolbarItem::SeparatorLine); @@ -7718,12 +7695,10 @@ 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(); - - 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; - float left = -0.5f * (float)cnv_size.get_width() * inv_zoom; + const Size cnv_size = get_canvas_size(); + const float top = 0.5f * (float)cnv_size.get_height(); + //const float left = (0.5f * (float)cnv_size.get_width() - (float)collapse_toolbar.get_width() - band); + const float left = -0.5f * (float)cnv_size.get_width(); collapse_toolbar.set_position(top, left); collapse_toolbar.render(*this); @@ -8002,52 +7977,51 @@ void GLCanvas3D::_render_assemble_info() 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)); - const Vec3d& target = wxGetApp().plater()->get_camera().get_target(); - bool target_changed = !m_camera_target.target.isApprox(target); - m_camera_target.target = target; + 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_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)); } } - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); + 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()); for (int i = 0; i < 3; ++i) { m_camera_target.axis[i].render(); } @@ -8100,7 +8074,7 @@ void GLCanvas3D::_render_sla_slices() 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; @@ -8110,10 +8084,7 @@ void GLCanvas3D::_render_sla_slices() 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); + init_data.add_triangle(vertices_count - 3, vertices_count - 2, vertices_count - 1); } } @@ -8164,24 +8135,25 @@ void GLCanvas3D::_render_sla_slices() } } - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); for (const SLAPrintObject::Instance& inst : obj->instances()) { - 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)); + 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()); bottom_obj_triangles.render(); top_obj_triangles.render(); bottom_sup_triangles.render(); top_sup_triangles.render(); - glsafe(::glPopMatrix()); } shader->stop_using(); @@ -8371,7 +8343,7 @@ void GLCanvas3D::_load_print_toolpaths(const BuildVolume &build_volume) 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 }; for (size_t i = 0; i < skirt_height; ++ i) { volume->print_zs.emplace_back(print_zs[i]); volume->offsets.emplace_back(init_data.indices_count()); @@ -8594,7 +8566,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c 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 }; } for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) { const Layer *layer = ctxt.layers[idx_layer]; @@ -8793,7 +8765,7 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con 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 }; } for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++idx_layer) { const std::vector &layer = ctxt.tool_change(idx_layer); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index f9103c75cd..77ad673947 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -261,9 +261,8 @@ class GLCanvas3D GLModel baseline; GLModel profile; GLModel background; - Rect old_bar_rect; + float old_canvas_width{ 0.0f }; std::vector old_layer_height_profile; - bool dirty{ false }; }; Profile m_profile; @@ -294,7 +293,6 @@ 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); - static Rect get_bar_rect_viewport(const GLCanvas3D& canvas); static float get_overlay_window_width() { return LayersEditing::s_overlay_window_width; } float object_max_z() const { return m_object_max_z; } @@ -304,8 +302,8 @@ class GLCanvas3D private: bool is_initialized() const; void generate_layer_height_texture(); - void render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect); - void render_profile(const Rect& bar_rect); + void render_active_object_annotations(const GLCanvas3D& canvas); + void render_profile(const GLCanvas3D& canvas); void update_slicing_parameters(); static float thickness_bar_width(const GLCanvas3D& canvas); @@ -1117,11 +1115,11 @@ private: void _picking_pass(); void _rectangular_selection_picking_pass(); void _render_background(); - void _render_bed(bool bottom, bool show_axes); - void _render_bed_for_picking(bool bottom); + 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); //BBS: add part plate related logic - void _render_platelist(bool bottom, bool only_current, bool only_body = false, int hover_id = -1, bool render_cali = false) const; - void _render_plates_for_picking() const; + void _render_platelist(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current, bool only_body = false, int hover_id = -1, bool render_cali = false); + void _render_plates_for_picking(const Transform3d& view_matrix, const Transform3d& projection_matrix); //BBS: add outline drawing logic void _render_objects(GLVolumeCollection::ERenderType type, bool with_outline = true); //BBS: GUI refactor: add canvas size as parameters diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 1d2337bc60..94a431f1c8 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -52,16 +52,6 @@ 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); } } @@ -391,21 +302,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) @@ -491,7 +398,7 @@ void GLModel::init_from(const indexed_triangle_set& its) } 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()); @@ -505,10 +412,7 @@ void GLModel::init_from(const indexed_triangle_set& its) 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 @@ -531,7 +435,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) { @@ -550,7 +454,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); } } @@ -598,7 +502,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(); m_bounding_box = BoundingBoxf3(); m_filename = std::string(); } @@ -618,13 +522,14 @@ 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; } } } @@ -642,7 +547,6 @@ void GLModel::render(const std::pair& range) return; GLShaderProgram* shader = wxGetApp().get_current_shader(); - if (shader == nullptr) return; @@ -655,7 +559,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); @@ -664,74 +568,44 @@ void GLModel::render(const std::pair& range) glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id)); - bool use_attributes = boost::algorithm::iends_with(shader->get_name(), "_attr"); - int position_id = -1; int normal_id = -1; int tex_coord_id = -1; if (position) { - if (use_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)); + 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)); } } if (normal) { - if (use_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)); + 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)); } } if (tex_coord) { - if (use_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)); + 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)); } } 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 (use_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)); - } + 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)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } @@ -742,18 +616,18 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance return; GLShaderProgram* shader = wxGetApp().get_current_shader(); - if (shader == nullptr || !boost::algorithm::iends_with(shader->get_name(), "_instanced")) + if (shader == nullptr || !boost::algorithm::iends_with(shader->get_name(), "_instanced_attr")) 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; @@ -773,8 +647,8 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance 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); @@ -833,26 +707,36 @@ 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; } -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); -} - template inline bool all_vertices_inside(const GLModel::Geometry& geometry, Fn fn) { @@ -907,13 +791,12 @@ bool contains(const BuildVolume& volume, const GLModel& model, bool ignore_botto } } -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) { - resolution = std::max(4, resolution); - resolution = std::min(10922, resolution); // ensure no unsigned short overflow of indices + resolution = std::max(4, resolution); 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(6 * resolution + 2); data.reserve_indices(6 * resolution * 3); @@ -921,7 +804,7 @@ GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, fl 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); @@ -930,75 +813,74 @@ GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, fl const float total_height = tip_height + stem_height; // tip vertices/normals - 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 }); + 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); } 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) { - resolution = std::max(2, resolution); - resolution = std::min(8188, resolution); // ensure no unsigned short overflow of indices + resolution = std::max(2, resolution); 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(8 * (resolution + 1) + 30); data.reserve_indices((8 * resolution + 16) * 3); @@ -1012,146 +894,146 @@ GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float // 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); } return data; @@ -1160,7 +1042,7 @@ GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float GLModel::Geometry straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness) { 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(42); data.reserve_indices(72); @@ -1170,122 +1052,121 @@ GLModel::Geometry straight_arrow(float tip_width, float tip_height, float stem_w const float total_height = tip_height + stem_height; // 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); } return data; } -GLModel::Geometry diamond(unsigned short resolution) +GLModel::Geometry diamond(unsigned int resolution) { - resolution = std::max(4, resolution); - resolution = std::min(65534, resolution); // ensure no unsigned short overflow of indices + resolution = std::max(4, resolution); 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(resolution + 2); data.reserve_indices((2 * (resolution + 1)) * 3); const float step = 2.0f * float(PI) / float(resolution); // vertices - for (unsigned short i = 0; i < resolution; ++i) { - float ii = float(i) * step; + 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); return data; } diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index 79c615f31c..28485cd40e 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -46,23 +46,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 @@ -72,36 +74,29 @@ namespace GUI { 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); + 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; void remove_vertex(size_t id); 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); } @@ -121,9 +116,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); @@ -164,9 +157,10 @@ 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); } const Geometry& get_geometry() const { return m_render_data.geometry; } + void init_from(Geometry&& data); void init_from(const TriangleMesh& mesh); void init_from(const indexed_triangle_set& its); @@ -217,13 +211,13 @@ namespace GUI { // 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 @@ -234,7 +228,7 @@ 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); } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GLSelectionRectangle.cpp b/src/slic3r/GUI/GLSelectionRectangle.cpp index e06f087699..3f0e7cf66b 100644 --- a/src/slic3r/GUI/GLSelectionRectangle.cpp +++ b/src/slic3r/GUI/GLSelectionRectangle.cpp @@ -74,40 +74,28 @@ namespace GUI { if (!is_dragging()) return; - const Camera& camera = wxGetApp().plater()->get_camera(); - float inv_zoom = (float)camera.get_inv_zoom(); - - 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(); - if (cnv_half_width == 0.0f || cnv_half_height == 0.0f) + 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; - 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 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; + 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); glsafe(::glLineWidth(1.5f)); glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glPushMatrix()); - glsafe(::glLoadIdentity()); - // ensure that the rectangle is renderered inside the frustrum - glsafe(::glTranslated(0.0, 0.0, -(camera.get_near_z() + 0.5))); - // 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)); - glsafe(::glPushAttrib(GL_ENABLE_BIT)); glsafe(::glLineStipple(4, 0xAAAA)); glsafe(::glEnable(GL_LINE_STIPPLE)); - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); @@ -117,7 +105,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); @@ -128,23 +116,23 @@ 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(0.0f, 1.0f, 0.38f, 1.0f); - m_rectangle.set_color(color); + shader->set_uniform("view_model_matrix", Transform3d::Identity()); + shader->set_uniform("projection_matrix", Transform3d::Identity()); + + m_rectangle.set_color({0.0f, 1.0f, 0.38f, 1.0f}); m_rectangle.render(); shader->stop_using(); } glsafe(::glPopAttrib()); - - glsafe(::glPopMatrix()); } } // namespace GUI diff --git a/src/slic3r/GUI/GLSelectionRectangle.hpp b/src/slic3r/GUI/GLSelectionRectangle.hpp index ad0360e0cc..5ec56a60a0 100644 --- a/src/slic3r/GUI/GLSelectionRectangle.hpp +++ b/src/slic3r/GUI/GLSelectionRectangle.hpp @@ -36,12 +36,12 @@ 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 }; diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index 32b3d59601..174cfec590 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -296,6 +296,11 @@ void GLShaderProgram::set_uniform(int id, const Matrix3f& value) const glsafe(::glUniformMatrix3fv(id, 1, GL_FALSE, static_cast(value.data()))); } +void GLShaderProgram::set_uniform(int id, const Matrix3d& value) const +{ + set_uniform(id, (Matrix3f)value.cast()); +} + 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 975c12c24a..76697fa594 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -60,6 +60,7 @@ 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); } + void set_uniform(const char* name, const Matrix3d& value) const { set_uniform(get_uniform_location(name), value); } 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); } @@ -79,6 +80,7 @@ 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; + void set_uniform(int id, const Matrix3d& value) const; 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 c00599805c..2048b56105 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -34,25 +34,22 @@ std::pair GLShadersManager::init() bool valid = true; // basic shader, used to render all what was previously rendered using the immediate mode - valid &= append_shader("flat", { "flat.vs", "flat.fs" }); valid &= append_shader("flat_attr", { "flat_attr.vs", "flat.fs" }); // basic shader for textures, used to render textures - valid &= append_shader("flat_texture", { "flat_texture.vs", "flat_texture.fs" }); + valid &= append_shader("flat_texture_attr", { "flat_texture_attr.vs", "flat_texture.fs" }); // used to render 3D scene background - valid &= append_shader("background", { "background.vs", "background.fs" }); + valid &= append_shader("background_attr", { "background_attr.vs", "background.fs" }); // 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" }); + valid &= append_shader("gouraud_light_attr", { "gouraud_light_attr.vs", "gouraud_light.fs" }); //used to render thumbnail - valid &= append_shader("thumbnail", { "thumbnail.vs", "thumbnail.fs" }); - // used to render first layer for calibration - valid &= append_shader("cali", { "cali.vs", "cali.fs"}); + valid &= append_shader("thumbnail_attr", {"thumbnail_attr.vs", "thumbnail.fs"}); + valid &= append_shader("thumbnail", {"thumbnail.vs", "thumbnail.fs"}); // used to render printbed - valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" }); + valid &= append_shader("printbed_attr", { "printbed_attr.vs", "printbed.fs" }); // used to render options in gcode preview - if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) - valid &= append_shader("gouraud_light_instanced", { "gouraud_light_instanced.vs", "gouraud_light_instanced.fs" }); - // used to render extrusion and travel paths as lines in gcode preview - valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" }); + if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) { + valid &= append_shader("gouraud_light_instanced_attr", { "gouraud_light_instanced_attr.vs", "gouraud_light_instanced.fs" }); + } // used to render objects in 3d editor //if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 0)) { @@ -64,34 +61,26 @@ std::pair GLShadersManager::init() ); } else { - valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" } + valid &= append_shader("gouraud_attr", { "gouraud_attr.vs", "gouraud.fs" } #if ENABLE_ENVIRONMENT_MAP , { "ENABLE_ENVIRONMENT_MAP"sv } #endif // ENABLE_ENVIRONMENT_MAP ); } // used to render variable layers heights in 3d editor - valid &= append_shader("variable_layer_height", { "variable_layer_height.vs", "variable_layer_height.fs" }); + 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", { "mm_contour.vs", "mm_contour.fs" }); + valid &= append_shader("mm_contour_attr", { "mm_contour_attr.vs", "mm_contour_attr.fs" }); // 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 (platform_flavor() == PlatformFlavor::OSXOnArm && wxPlatformInfo::Get().GetOSMajorVersion() < 12) { - //if (GUI::wxGetApp().plater() && GUI::wxGetApp().plater()->is_wireframe_enabled()) - // valid &= append_shader("mm_gouraud", {"mm_gouraud_wireframe.vs", "mm_gouraud_wireframe.fs"}, {"FLIP_TRIANGLE_NORMALS"sv}); - //else - valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"}, {"FLIP_TRIANGLE_NORMALS"sv}); - } - else { - //if (GUI::wxGetApp().plater() && GUI::wxGetApp().plater()->is_wireframe_enabled()) - // valid &= append_shader("mm_gouraud", {"mm_gouraud_wireframe.vs", "mm_gouraud_wireframe.fs"}); - //else - valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"}); - } + 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" }); //BBS: add shader for outline valid &= append_shader("outline", { "outline.vs", "outline.fs" }); diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp index 69ed23e2ff..041653a6c4 100644 --- a/src/slic3r/GUI/GLTexture.cpp +++ b/src/slic3r/GUI/GLTexture.cpp @@ -663,7 +663,7 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right, glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id)); 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); @@ -674,15 +674,17 @@ 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)); - GLShaderProgram* shader = wxGetApp().get_shader("flat_texture"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_texture_attr"); if (shader != nullptr) { shader->start_using(); + shader->set_uniform("view_model_matrix", Transform3d::Identity()); + shader->set_uniform("projection_matrix", Transform3d::Identity()); model.render(); shader->stop_using(); } diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 6a78edd907..a10177ba9c 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -551,18 +551,16 @@ void GLToolbar::render(const GLCanvas3D& parent,GLToolbarItem::EType type) { default: case Layout::Horizontal: { render_horizontal(parent,type); 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 @@ -610,7 +608,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()) { @@ -757,16 +755,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); @@ -784,12 +778,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 @@ -804,8 +797,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 normal state item->set_state(GLToolbarItem::Normal); parent.render(); @@ -825,55 +817,51 @@ 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; } } } void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent) { - // NB: mouse_pos is already scaled appropriately + 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())); - float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); - float factor = m_layout.scale * inv_zoom; + 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; - Size cnv_size = parent.get_canvas_size(); - Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom); + const float separator_stride = separator_size + gap_size; + const float icon_stride = icons_size + gap_size; - float scaled_icons_size = m_layout.icons_size * factor; - float scaled_separator_size = m_layout.separator_size * factor; - float scaled_gap_size = m_layout.gap_size * factor; - float scaled_border = m_layout.border * factor; + float left = m_layout.left + border; + float top = m_layout.top - border; - float separator_stride = scaled_separator_size + scaled_gap_size; - float icon_stride = scaled_icons_size + scaled_gap_size; - - float left = m_layout.left + scaled_border; - float top = m_layout.top - scaled_border; - - for (GLToolbarItem* item : m_items) - { + for (GLToolbarItem* item : m_items) { if (!item->is_visible()) continue; if (item->is_separator()) left += separator_stride; - else - { - float right = left + scaled_icons_size; - float bottom = top - scaled_icons_size; + else { + float right = left + icons_size; + const float bottom = top - icons_size; //BBS: GUI refactor: GLToolbar if (item->is_action_with_text()) - right += scaled_icons_size * item->get_extra_size_ratio(); - GLToolbarItem::EState state = item->get_state(); - bool inside = (left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top); + right += icons_size * item->get_extra_size_ratio(); + + 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) - { + if (inside) { item->set_state(GLToolbarItem::Hover); parent.set_as_dirty(); } @@ -882,8 +870,7 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D } case GLToolbarItem::Hover: { - if (!inside) - { + if (!inside) { item->set_state(GLToolbarItem::Normal); parent.set_as_dirty(); } @@ -892,8 +879,7 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D } case GLToolbarItem::Pressed: { - if (inside) - { + if (inside) { item->set_state(GLToolbarItem::HoverPressed); parent.set_as_dirty(); } @@ -902,8 +888,7 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D } case GLToolbarItem::HoverPressed: { - if (!inside) - { + if (!inside) { item->set_state(GLToolbarItem::Pressed); parent.set_as_dirty(); } @@ -912,8 +897,7 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D } case GLToolbarItem::Disabled: { - if (inside) - { + if (inside) { item->set_state(GLToolbarItem::HoverDisabled); parent.set_as_dirty(); } @@ -922,8 +906,7 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D } case GLToolbarItem::HoverDisabled: { - if (!inside) - { + if (!inside) { item->set_state(GLToolbarItem::Disabled); parent.set_as_dirty(); } @@ -939,59 +922,55 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D left += icon_stride; //BBS: GUI refactor: GLToolbar if (item->is_action_with_text()) - left += scaled_icons_size * item->get_extra_size_ratio(); + left += icons_size * item->get_extra_size_ratio(); } } } void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& parent) { - // NB: mouse_pos is already scaled appropriately + 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())); - float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); - float factor = m_layout.scale * inv_zoom; + 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; - Size cnv_size = parent.get_canvas_size(); - Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom); + const float separator_stride = separator_size + gap_size; + const float icon_stride = icons_size + gap_size; - float scaled_icons_size = m_layout.icons_size * factor; - float scaled_separator_size = m_layout.separator_size * factor; - float scaled_gap_size = m_layout.gap_size * factor; - float scaled_border = m_layout.border * factor; - float separator_stride = scaled_separator_size + scaled_gap_size; - float icon_stride = scaled_icons_size + scaled_gap_size; + float left = m_layout.left + border; + float top = m_layout.top - border; - float left = m_layout.left + scaled_border; - float top = m_layout.top - scaled_border; - - for (GLToolbarItem* item : m_items) - { + for (GLToolbarItem* item : m_items) { if (!item->is_visible()) continue; if (item->is_separator()) top -= separator_stride; - else - { - float right = left + scaled_icons_size; - float bottom = top - scaled_icons_size; + else { + float right = left + icons_size; + const float bottom = top - icons_size; if (item->is_action_with_text_image()) - right += m_layout.text_size * factor; + right += m_layout.text_size * m_layout.scale; //BBS: GUI refactor: GLToolbar if (item->is_action_with_text()) - right += scaled_icons_size * item->get_extra_size_ratio(); + right += icons_size * item->get_extra_size_ratio(); GLToolbarItem::EState state = item->get_state(); - bool inside = (left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top); + 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) - { + if (inside) { item->set_state(GLToolbarItem::Hover); parent.set_as_dirty(); } @@ -1000,8 +979,7 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& } case GLToolbarItem::Hover: { - if (!inside) - { + if (!inside) { item->set_state(GLToolbarItem::Normal); parent.set_as_dirty(); } @@ -1010,8 +988,7 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& } case GLToolbarItem::Pressed: { - if (inside) - { + if (inside) { item->set_state(GLToolbarItem::HoverPressed); parent.set_as_dirty(); } @@ -1020,8 +997,7 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& } case GLToolbarItem::HoverPressed: { - if (!inside) - { + if (!inside) { item->set_state(GLToolbarItem::Pressed); parent.set_as_dirty(); } @@ -1030,8 +1006,7 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& } case GLToolbarItem::Disabled: { - if (inside) - { + if (inside) { item->set_state(GLToolbarItem::HoverDisabled); parent.set_as_dirty(); } @@ -1040,8 +1015,7 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& } case GLToolbarItem::HoverDisabled: { - if (!inside) - { + if (!inside) { item->set_state(GLToolbarItem::Disabled); parent.set_as_dirty(); } @@ -1083,77 +1057,78 @@ 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); } } } int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3D& parent) const { - // NB: mouse_pos is already scaled appropriately + 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())); - float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); - float factor = m_layout.scale * inv_zoom; + 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; - Size cnv_size = parent.get_canvas_size(); - Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom); + float left = m_layout.left + border; + const float top = m_layout.top - border; - float scaled_icons_size = m_layout.icons_size * factor; - float scaled_separator_size = m_layout.separator_size * factor; - float scaled_gap_size = m_layout.gap_size * factor; - float scaled_border = m_layout.border * factor; - - float left = m_layout.left + scaled_border; - float top = m_layout.top - scaled_border; - - - for (size_t id=0; idis_visible()) continue; - if (item->is_separator()) - { - float right = left + scaled_separator_size; - float bottom = top - scaled_icons_size; + 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(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top)) + 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 += scaled_gap_size; + right += gap_size; - if (id < m_items.size() - 1) - { + if (id < m_items.size() - 1) { // mouse inside the gap - if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top)) + 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 + scaled_icons_size; - float bottom = top - scaled_icons_size; + else { + float right = left + icons_size; + const float bottom = top - icons_size; //BBS: GUI refactor: GLToolbar if (item->is_action_with_text()) - right += scaled_icons_size * item->get_extra_size_ratio(); + right += icons_size * item->get_extra_size_ratio(); // mouse inside the icon - if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top)) + 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 += scaled_gap_size; + right += gap_size; - if (id < m_items.size() - 1) - { + if (id < m_items.size() - 1) { // mouse inside the gap - if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top)) + 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; } @@ -1166,73 +1141,75 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3 int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& parent) const { - // NB: mouse_pos is already scaled appropriately + 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())); - float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); - float factor = m_layout.scale * inv_zoom; + 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; - Size cnv_size = parent.get_canvas_size(); - Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom); + const float left = m_layout.left + border; + float top = m_layout.top - border; - float scaled_icons_size = m_layout.icons_size * factor; - float scaled_separator_size = m_layout.separator_size * factor; - float scaled_gap_size = m_layout.gap_size * factor; - float scaled_border = m_layout.border * factor; - - float left = m_layout.left + scaled_border; - float top = m_layout.top - scaled_border; - - for (size_t id=0; idis_visible()) continue; - if (item->is_separator()) - { - float right = left + scaled_icons_size; - float bottom = top - scaled_separator_size; + 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(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top)) + 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 -= scaled_gap_size; + bottom -= gap_size; - if (id < m_items.size() - 1) - { + if (id < m_items.size() - 1) { // mouse inside the gap - if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top)) + 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 - { - float right = left + scaled_icons_size; - float bottom = top - scaled_icons_size; + else { + float right = left + icons_size; + float bottom = top - icons_size; if (item->is_action_with_text_image()) - right += m_layout.text_size * factor; + right += m_layout.text_size * m_layout.scale; //BBS: GUI refactor: GLToolbar if (item->is_action_with_text()) - right += scaled_icons_size * item->get_extra_size_ratio(); + right += icons_size * item->get_extra_size_ratio(); // mouse inside the icon - if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top)) + 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 -= scaled_gap_size; + bottom -= gap_size; - if (id < m_items.size() - 1) - { + if (id < m_items.size() - 1) { // mouse inside the gap - if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top)) + 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; } @@ -1243,33 +1220,32 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& return -1; } -void GLToolbar::render_background(float left, float top, float right, float bottom, float border) const +void GLToolbar::render_background(float left, float top, float right, float bottom, float border_w, float border_h) 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)) - { - 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; + 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; - float internal_left = left + border; - float internal_right = right - border; - float internal_top = top - border; - float internal_bottom = bottom + border; + 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; - float left_uv = 0.0f; - float right_uv = 1.0f; - float top_uv = 1.0f; - float bottom_uv = 0.0f; + const float left_uv = 0.0f; + const float right_uv = 1.0f; + const float top_uv = 1.0f; + const float bottom_uv = 0.0f; - float internal_left_uv = (float)m_background_texture.metadata.left * inv_tex_width; - float internal_right_uv = 1.0f - (float)m_background_texture.metadata.right * inv_tex_width; - float internal_top_uv = 1.0f - (float)m_background_texture.metadata.top * inv_tex_height; - float internal_bottom_uv = (float)m_background_texture.metadata.bottom * inv_tex_height; + 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)) + 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 } }); @@ -1281,7 +1257,7 @@ void GLToolbar::render_background(float left, float top, float right, float bott 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)) + 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 } }); @@ -1302,7 +1278,7 @@ void GLToolbar::render_background(float left, float top, float right, float bott 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)) + 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 } }); @@ -1314,7 +1290,7 @@ void GLToolbar::render_background(float left, float top, float right, float bott 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)) + 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 } }); @@ -1389,41 +1365,48 @@ void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighte void GLToolbar::render_horizontal(const GLCanvas3D& parent,GLToolbarItem::EType type) { - float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); - float factor = inv_zoom * m_layout.scale; + 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(); - float scaled_icons_size = m_layout.icons_size * factor; - float scaled_separator_size = m_layout.separator_size * factor; - float scaled_gap_size = m_layout.gap_size * factor; - float scaled_border = m_layout.border * factor; - float scaled_width = get_width() * inv_zoom; - float scaled_height = get_height() * inv_zoom; + if (cnv_w == 0 || cnv_h == 0) + return; - float separator_stride = scaled_separator_size + scaled_gap_size; - float icon_stride = scaled_icons_size + scaled_gap_size; + const float inv_cnv_w = 1.0f / cnv_w; + const float inv_cnv_h = 1.0f / cnv_h; - float left = m_layout.left; - float top = m_layout.top; - float right = left + scaled_width; + 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; + float right = left + width; if (type == GLToolbarItem::SeparatorLine) - right = left + scaled_width * 0.5; - float bottom = top - scaled_height; + right = left + width * 0.5; + const float bottom = top - height; - render_background(left, top, right, bottom, scaled_border); + render_background(left, top, right, bottom, border_w, border_h); - left += scaled_border; - top -= scaled_border; + left += border_w; + top -= border_h; // renders icons - for (const GLToolbarItem* item : m_items) - { + for (const GLToolbarItem* item : m_items) { if (!item->is_visible()) continue; if (item->is_separator()) left += separator_stride; - else - { + else { //BBS GUI refactor item->render_left_pos = left; if (!item->is_action_with_text_image()) { @@ -1432,13 +1415,13 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent,GLToolbarItem::EType int tex_height = m_icons_texture.get_height(); if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0)) return; - item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale)); + item->render(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)); } //BBS: GUI refactor: GLToolbar if (item->is_action_with_text()) { - float scaled_text_size = item->get_extra_size_ratio() * scaled_icons_size; - item->render_text(left + scaled_icons_size, left + scaled_icons_size + scaled_text_size, top - scaled_icons_size, top); + float scaled_text_size = item->get_extra_size_ratio() * icons_size_x; + item->render_text(left + icons_size_x, left + icons_size_x + scaled_text_size, top - icons_size_y, top); left += scaled_text_size; } left += icon_stride; @@ -1448,28 +1431,37 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent,GLToolbarItem::EType void GLToolbar::render_vertical(const GLCanvas3D& parent) { - float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); - float factor = inv_zoom * m_layout.scale; + 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(); - float scaled_icons_size = m_layout.icons_size * factor; - float scaled_separator_size = m_layout.separator_size * factor; - float scaled_gap_size = m_layout.gap_size * factor; - float scaled_border = m_layout.border * factor; - float scaled_width = get_width() * inv_zoom; - float scaled_height = get_height() * inv_zoom; + if (cnv_w == 0 || cnv_h == 0) + return; - float separator_stride = scaled_separator_size + scaled_gap_size; - float icon_stride = scaled_icons_size + scaled_gap_size; + const float inv_cnv_w = 1.0f / cnv_w; + const float inv_cnv_h = 1.0f / cnv_h; - float left = m_layout.left; - float top = m_layout.top; - float right = left + scaled_width; - float bottom = top - scaled_height; + 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; - render_background(left, top, right, bottom, scaled_border); + const float separator_stride = separator_size + gap_size; + const float icon_stride = icons_size_y + gap_size; - left += scaled_border; - top -= scaled_border; + 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) { @@ -1482,10 +1474,10 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) unsigned int tex_id; int tex_width, tex_height; if (item->is_action_with_text_image()) { - float scaled_text_size = m_layout.text_size * factor; - float scaled_text_width = item->get_extra_size_ratio() * scaled_icons_size; - float scaled_text_border = 2.5 * factor; - float scaled_text_height = scaled_icons_size / 2.0f; + float scaled_text_size = m_layout.text_size * m_layout.scale * inv_cnv_w; + float scaled_text_width = item->get_extra_size_ratio() * icons_size_x; + float scaled_text_border = 2.5 * m_layout.scale * inv_cnv_h; + float scaled_text_height = icons_size_y / 2.0f; item->render_text(left, left + scaled_text_size, top - scaled_text_border - scaled_text_height, top - scaled_text_border); float image_left = left + scaled_text_size; @@ -1494,7 +1486,7 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) tex_height = item->m_data.image_texture.get_height(); if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0)) return; - item->render_image(tex_id, image_left, image_left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale)); + item->render_image(tex_id, image_left, image_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)); } else { tex_id = m_icons_texture.get_id(); @@ -1502,14 +1494,14 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) tex_height = m_icons_texture.get_height(); if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0)) return; - item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale)); + item->render(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)); //BBS: GUI refactor: GLToolbar } if (item->is_action_with_text()) { - float scaled_text_width = item->get_extra_size_ratio() * scaled_icons_size; - float scaled_text_height = scaled_icons_size; - item->render_text(left + scaled_icons_size, left + scaled_icons_size + scaled_text_width, top - scaled_text_height, top); + float scaled_text_width = item->get_extra_size_ratio() * icons_size_x; + float scaled_text_height = icons_size_y; + item->render_text(left + icons_size_x, left + icons_size_x + scaled_text_width, top - scaled_text_height, top); } top -= icon_stride; } diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 09da22d3cd..43f81b5abb 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -436,8 +436,8 @@ 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; - void render_background(float left, float top, float right, float bottom, float border) const; - void render_horizontal(const GLCanvas3D& parent,GLToolbarItem::EType type); + void render_background(float left, float top, float right, float bottom, float border_w, float border_h) const; + void render_horizontal(const GLCanvas3D &parent, GLToolbarItem::EType type); void render_vertical(const GLCanvas3D& parent); bool generate_icons_texture(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp index 9bae84b034..fc132f57bc 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp @@ -492,8 +492,6 @@ void GLGizmoAdvancedCut::on_render_for_picking() glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glPushMatrix()); - BoundingBoxf3 box = m_parent.get_selection().get_bounding_box(); #if ENABLE_FIXED_GRABBER float mean_size = (float)(GLGizmoBase::Grabber::FixedGrabberSize); @@ -502,17 +500,17 @@ void GLGizmoAdvancedCut::on_render_for_picking() #endif m_move_grabber.color = picking_color_component(0); - GLShaderProgram *shader = wxGetApp().get_shader("flat"); + GLShaderProgram *shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); - + 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()); m_move_grabber.render_for_picking(mean_size); shader->stop_using(); } - glsafe(::glPopMatrix()); - glsafe(::glEnable(GL_DEPTH_TEST)); auto inst_id = m_c->selection_info()->get_active_instance(); if (inst_id < 0) @@ -868,7 +866,7 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers() glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - GLShaderProgram *shader = wxGetApp().get_shader("flat"); + GLShaderProgram *shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); @@ -877,7 +875,7 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers() 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_vertices(6); @@ -888,11 +886,14 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers() } // 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)); } + 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()); m_plane.render(); glsafe(::glEnable(GL_CULL_FACE)); @@ -907,17 +908,17 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers() 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.vertices.reserve(2 * GLModel::Geometry::vertex_stride_floats(init_data.format)); - init_data.indices.reserve(2 * GLModel::Geometry::index_stride_bytes(init_data.format)); + init_data.reserve_vertices(2); + init_data.reserve_vertices(2); // vertices init_data.add_vertex((Vec3f)plane_center_rot.cast()); init_data.add_vertex((Vec3f)m_move_grabber.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)); } @@ -933,7 +934,7 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers() } { - GLShaderProgram *shader = wxGetApp().get_shader("gouraud_light"); + GLShaderProgram *shader = wxGetApp().get_shader("gouraud_light_attr"); if (shader == nullptr) return; shader->start_using(); @@ -960,13 +961,15 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers() cube.set_color(render_color); - glsafe(::glPushMatrix()); - glsafe(::glTranslated(m_move_grabber.center.x(), m_move_grabber.center.y(), m_move_grabber.center.z())); - glsafe(::glMultMatrixd(m_rotate_matrix.data())); - - glsafe(::glScaled(fullsize, fullsize, fullsize)); + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d view_model_matrix = camera.get_view_matrix() * Geometry::assemble_transform(m_move_grabber.center) * + m_rotate_matrix * + Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), 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()); cube.render(); - glsafe(::glPopMatrix()); shader->stop_using(); } @@ -1064,23 +1067,26 @@ void GLGizmoAdvancedCut::render_cut_line() void GLGizmoAdvancedCut::render_connector_model(GLModel &model, const ColorRGBA &color, Transform3d view_model_matrix, bool for_picking) { - glPushMatrix(); GLShaderProgram *shader = nullptr; if (for_picking) - shader = wxGetApp().get_shader("cali"); + shader = wxGetApp().get_shader("flat_attr"); else - shader = wxGetApp().get_shader("gouraud_light"); + shader = wxGetApp().get_shader("gouraud_light_attr"); if (shader) { shader->start_using(); - glsafe(::glMultMatrixd(view_model_matrix.data())); + const Camera& camera = wxGetApp().plater()->get_camera(); + view_model_matrix = camera.get_view_matrix() * view_model_matrix; + 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()); model.set_color(color); model.render(); shader->stop_using(); } - glPopMatrix(); } void GLGizmoAdvancedCut::clear_selection() diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 849470f381..5dc0cc38e7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -4,6 +4,7 @@ #include #include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/GUI_Colors.hpp" // TODO: Display tooltips quicker on Linux @@ -97,11 +98,15 @@ GLModel& GLGizmoBase::Grabber::get_cube() void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, bool picking) { + GLShaderProgram* shader = wxGetApp().get_current_shader(); + if (shader == nullptr) + return; + 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)); + its_translate(its, -0.5f * Vec3f::Ones()); m_cube.init_from(its); } @@ -115,14 +120,14 @@ void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, boo m_cube.set_color(render_color); - 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)); + 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()); m_cube.render(); - glsafe(::glPopMatrix()); } GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) @@ -257,7 +262,7 @@ void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const void GLGizmoBase::render_grabbers(float size) const { - GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr"); if (shader == nullptr) return; shader->start_using(); @@ -271,7 +276,7 @@ void GLGizmoBase::render_grabbers(float size) const void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const { - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index b2b8c4626e..4e8a6dc1d0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -68,6 +68,7 @@ protected: bool dragging{ false }; Vec3d center{ Vec3d::Zero() }; Vec3d angles{ Vec3d::Zero() }; + Transform3d matrix{ Transform3d::Identity() }; ColorRGBA color{GRABBER_NORMAL_COL}; ColorRGBA hover_color{GRABBER_HOVER_COL}; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 86aa18f894..c6a635ccd5 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -155,7 +155,7 @@ bool GLGizmoFdmSupports::on_key_down_select_tool_type(int keyCode) { void GLGizmoFdmSupports::render_triangles(const Selection& selection) const { ClippingPlaneDataWrapper clp_data = this->get_clipping_plane_data(); - auto* shader = wxGetApp().get_shader("mm_gouraud"); + auto* shader = wxGetApp().get_shader("mm_gouraud_attr"); if (!shader) return; shader->start_using(); @@ -177,8 +177,11 @@ void GLGizmoFdmSupports::render_triangles(const Selection& selection) const if (is_left_handed) glsafe(::glFrontFace(GL_CW)); - glsafe(::glPushMatrix()); - glsafe(::glMultMatrixd(trafo_matrix.data())); + 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()); float normal_z = -::cos(Geometry::deg2rad(m_highlight_by_angle_threshold_deg)); Matrix3f normal_matrix = static_cast(trafo_matrix.matrix().block(0, 0, 3, 3).inverse().transpose().cast()); @@ -188,9 +191,8 @@ void GLGizmoFdmSupports::render_triangles(const Selection& selection) const shader->set_uniform("slope.actived", m_parent.is_using_slope()); shader->set_uniform("slope.volume_world_normal_matrix", normal_matrix); shader->set_uniform("slope.normal_z", normal_z); - m_triangle_selectors[mesh_id]->render(m_imgui); + m_triangle_selectors[mesh_id]->render(m_imgui, trafo_matrix); - glsafe(::glPopMatrix()); if (is_left_handed) glsafe(::glFrontFace(GL_CCW)); } @@ -895,7 +897,7 @@ void GLGizmoFdmSupports::run_thread() goto _finished; } 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 }; for (const SupportLayer *support_layer : m_print_instance.print_object->support_layers()) { for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp index 71ce109794..c47e1225d8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp @@ -2,6 +2,7 @@ #include "GLGizmoFlatten.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" #include "libslic3r/Geometry/ConvexHull.hpp" @@ -63,7 +64,7 @@ void GLGizmoFlatten::on_render() { const Selection& selection = m_parent.get_selection(); - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader == nullptr) return; @@ -75,16 +76,18 @@ 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(); - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z())); - glsafe(::glMultMatrixd(m.data())); + 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()); if (this->is_plane_update_necessary()) update_planes(); for (int i = 0; i < (int)m_planes.size(); ++i) { m_planes[i].vbo.set_color(i == m_hover_id ? GLGizmoBase::FLATTEN_HOVER_COLOR : GLGizmoBase::FLATTEN_COLOR); m_planes[i].vbo.render(); } - glsafe(::glPopMatrix()); } glsafe(::glEnable(GL_CULL_FACE)); @@ -95,7 +98,7 @@ void GLGizmoFlatten::on_render() void GLGizmoFlatten::on_render_for_picking() { const Selection& selection = m_parent.get_selection(); - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader == nullptr) return; @@ -106,16 +109,18 @@ void GLGizmoFlatten::on_render_for_picking() 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(); - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z())); - glsafe(::glMultMatrixd(m.data())); + 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()); if (this->is_plane_update_necessary()) update_planes(); for (int i = 0; i < (int)m_planes.size(); ++i) { m_planes[i].vbo.set_color(picking_color_component(i)); m_planes[i].vbo.render(); } - glsafe(::glPopMatrix()); } glsafe(::glEnable(GL_CULL_FACE)); @@ -337,16 +342,13 @@ void GLGizmoFlatten::update_planes() // the vertices in order, so triangulation is trivial. for (auto& plane : m_planes) { 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)); // FIXME: vertices should really be local, they need not diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 113ea04992..59026be85e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -103,28 +103,30 @@ void GLGizmoHollow::on_render_for_picking() void GLGizmoHollow::render_points(const Selection& selection, bool picking) { - GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat") : wxGetApp().get_shader("gouraud_light"); + GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat_attr") : wxGetApp().get_shader("gouraud_light_attr"); if (shader == nullptr) return; - + shader->start_using(); ScopeGuard guard([shader]() { shader->stop_using(); }); 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 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(); - glsafe(::glPushMatrix()); - glsafe(::glTranslated(0.0, 0.0, m_c->selection_info()->get_sla_shift())); - glsafe(::glMultMatrixd(instance_matrix.data())); + 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); 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; @@ -147,9 +149,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) m_cylinder.set_color(render_color); // 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())); + const Transform3d hole_matrix = Geometry::assemble_transform(drain_hole.pos.cast()) * instance_scaling_matrix_inverse; if (vol->is_left_handed()) glFrontFace(GL_CW); @@ -157,18 +157,17 @@ 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); - 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)); + const Eigen::AngleAxisd aa(q); + 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()); m_cylinder.render(); if (vol->is_left_handed()) glFrontFace(GL_CCW); - glsafe(::glPopMatrix()); } - - glsafe(::glPopMatrix()); } 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 30bc71f8e6..e52267841e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -192,7 +192,7 @@ void GLGizmoMmuSegmentation::set_painter_gizmo_data(const Selection &selection) void GLGizmoMmuSegmentation::render_triangles(const Selection &selection) const { ClippingPlaneDataWrapper clp_data = this->get_clipping_plane_data(); - auto *shader = wxGetApp().get_shader("mm_gouraud"); + auto* shader = wxGetApp().get_shader("mm_gouraud_attr"); if (!shader) return; shader->start_using(); @@ -221,18 +221,20 @@ void GLGizmoMmuSegmentation::render_triangles(const Selection &selection) const 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)); - glsafe(::glPushMatrix()); - glsafe(::glMultMatrixd(trafo_matrix.data())); + 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()); shader->set_uniform("volume_world_matrix", trafo_matrix); shader->set_uniform("volume_mirrored", is_left_handed); - m_triangle_selectors[mesh_id]->render(m_imgui); + m_triangle_selectors[mesh_id]->render(m_imgui, trafo_matrix); - glsafe(::glPopMatrix()); if (is_left_handed) glsafe(::glFrontFace(GL_CCW)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 469dff42f6..ebdf6ec390 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -140,7 +140,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); @@ -150,7 +150,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)); //} @@ -162,11 +162,13 @@ void GLGizmoMove3D::on_render() } }; - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); - - // draw axes line + 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()); + // draw axes for (unsigned int i = 0; i < 3; ++i) { render_grabber_connection(i); @@ -240,12 +242,12 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box, bool picking) { #if ENABLE_FIXED_GRABBER - float mean_size = (float)(GLGizmoBase::Grabber::FixedGrabberSize); + const float mean_size = (float)(GLGizmoBase::Grabber::FixedGrabberSize); #else - 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); #endif - double size = 0.75 * GLGizmoBase::Grabber::FixedGrabberSize * GLGizmoBase::INV_ZOOM; + const double size = 0.75 * GLGizmoBase::Grabber::FixedGrabberSize * GLGizmoBase::INV_ZOOM; ColorRGBA color = m_grabbers[axis].color; if (!picking && m_hover_id != -1) { @@ -254,7 +256,7 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box } } - GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light"); + GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat_attr" : "gouraud_light_attr"); if (shader == nullptr) return; @@ -262,22 +264,21 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box shader->start_using(); shader->set_uniform("emission_factor", 0.1f); - glsafe(::glPushMatrix()); - glsafe(::glTranslated(m_grabbers[axis].center.x(), m_grabbers[axis].center.y(), m_grabbers[axis].center.z())); + 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) - glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); + view_model_matrix = view_model_matrix * Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitY()); else if (axis == Y) - glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); + 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(Vec3d::Zero(), Vec3d::Zero(), Vec3d(0.75 * size, 0.75 * size, 2.0 * size)); - //glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); - glsafe(::glScaled(0.75 * size, 0.75 * size, 2.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()); m_cone.render(); - glsafe(::glPopMatrix()); shader->stop_using(); } - - } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index fbc2f25ffa..7d83f38cce 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -75,7 +75,7 @@ GLGizmoPainterBase::ClippingPlaneDataWrapper GLGizmoPainterBase::get_clipping_pl void GLGizmoPainterBase::render_triangles(const Selection& selection) const { - auto* shader = wxGetApp().get_shader("gouraud"); + auto* shader = wxGetApp().get_shader("gouraud_attr"); if (! shader) return; shader->start_using(); @@ -105,8 +105,11 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection) const if (is_left_handed) glsafe(::glFrontFace(GL_CW)); - glsafe(::glPushMatrix()); - glsafe(::glMultMatrixd(trafo_matrix.data())); + 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()); // 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 +117,8 @@ 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); - m_triangle_selectors[mesh_id]->render(m_imgui); + m_triangle_selectors[mesh_id]->render(m_imgui, trafo_matrix); - glsafe(::glPopMatrix()); if (is_left_handed) glsafe(::glFrontFace(GL_CCW)); } @@ -165,43 +167,34 @@ void GLGizmoPainterBase::render_cursor() void GLGizmoPainterBase::render_cursor_circle() { - 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; - const Size cnv_size = m_parent.get_canvas_size(); - 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) + 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 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; + + 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()); glsafe(::glLineWidth(1.5f)); glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glPushMatrix()); - glsafe(::glLoadIdentity()); - // ensure that the circle is renderered inside the frustrum - glsafe(::glTranslated(0.0, 0.0, -(camera.get_near_z() + 0.5))); - // 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)); - glsafe(::glPushAttrib(GL_ENABLE_BIT)); glsafe(::glLineStipple(4, 0xAAAA)); glsafe(::glEnable(GL_LINE_STIPPLE)); - if (!m_circle.is_initialized() || !m_old_center.isApprox(center) || std::abs(m_old_cursor_radius - m_cursor_radius) > EPSILON) { + if (!m_circle.is_initialized() || !m_old_center.isApprox(center) || std::abs(m_old_cursor_radius - radius) > EPSILON) { + m_old_cursor_radius = radius; m_old_center = center; - m_old_cursor_radius = m_cursor_radius; 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); @@ -209,8 +202,9 @@ void GLGizmoPainterBase::render_cursor_circle() // vertices + indices for (unsigned short i = 0; i < StepsCount; ++i) { const float angle = float(i * StepSize); - 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); + init_data.add_vertex(Vec2f(2.0f * ((center.x() + ::cos(angle) * radius) * cnv_inv_width - 0.5f), + -2.0f * ((center.y() + ::sin(angle) * radius) * cnv_inv_height - 0.5f))); + init_data.add_index(i); } m_circle.init_from(std::move(init_data)); @@ -225,15 +219,16 @@ void GLGizmoPainterBase::render_cursor_circle() m_circle.set_color(render_color); - GLShaderProgram* shader = GUI::wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); + shader->set_uniform("view_model_matrix", Transform3d::Identity()); + shader->set_uniform("projection_matrix", Transform3d::Identity()); m_circle.render(); shader->stop_using(); } glsafe(::glPopAttrib()); - glsafe(::glPopMatrix()); glsafe(::glEnable(GL_DEPTH_TEST)); } @@ -245,20 +240,13 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const s_sphere->init_from(its_make_sphere(1.0, double(PI) / 12.0)); } - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); 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(); - 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)); - if (is_left_handed) glFrontFace(GL_CW); @@ -270,6 +258,14 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const render_color = this->get_cursor_sphere_right_button_color(); shader->start_using(); + 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()); + assert(s_sphere != nullptr); s_sphere->set_color(render_color); s_sphere->render(); @@ -277,13 +273,17 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const shader->stop_using(); if (is_left_handed) glFrontFace(GL_CCW); - - glsafe(::glPopMatrix()); } // BBS void GLGizmoPainterBase::render_cursor_height_range(const Transform3d& trafo) const { + GLShaderProgram *shader = wxGetApp().get_shader("flat_attr"); + if (shader == nullptr) + return; + + shader->start_using(); + const BoundingBoxf3 box = bounding_box(); Vec3d hit_world = trafo * Vec3d(m_rr.hit(0), m_rr.hit(1), m_rr.hit(2)); float max_z = (float)box.max.z(); @@ -309,14 +309,18 @@ void GLGizmoPainterBase::render_cursor_height_range(const Transform3d& trafo) co for (int i = 0; i < zs.size(); i++) { update_contours(vol_mesh, zs[i], max_z, min_z); - glsafe(::glPushMatrix()); - glsafe(::glTranslated(m_cut_contours.shift.x(), m_cut_contours.shift.y(), m_cut_contours.shift.z())); + const Camera& camera = wxGetApp().plater()->get_camera(); + Transform3d view_model_matrix = camera.get_view_matrix() * Geometry::assemble_transform(m_cut_contours.shift); + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); glsafe(::glLineWidth(2.0f)); m_cut_contours.contours.render(); - glsafe(::glPopMatrix()); } } + + shader->stop_using(); } BoundingBoxf3 GLGizmoPainterBase::bounding_box() const @@ -1056,7 +1060,7 @@ ColorRGBA TriangleSelectorGUI::get_seed_fill_color(const ColorRGBA& base_color) 1.f}; } -void TriangleSelectorGUI::render(ImGuiWrapper* imgui) +void TriangleSelectorGUI::render(ImGuiWrapper* imgui, const Transform3d& matrix) { if (m_update_render_data) { update_render_data(); @@ -1066,7 +1070,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) auto* shader = wxGetApp().get_current_shader(); if (! shader) return; - assert(shader->get_name() == "gouraud"); + assert(shader->get_name() == "gouraud_attr" || shader->get_name() == "mm_gouraud_attr"); 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), @@ -1084,7 +1088,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) iva.render(); } - render_paint_contour(); + render_paint_contour(matrix); #ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG if (imgui) @@ -1109,12 +1113,12 @@ 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 }; for (const Triangle &tr : m_triangles) { bool is_valid = tr.valid(); @@ -1140,7 +1144,7 @@ void TriangleSelectorGUI::update_render_data() 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); cnt += 3; } @@ -1164,7 +1168,7 @@ bool TrianglePatch::is_fragment() const float TriangleSelectorPatch::gap_area = TriangleSelectorPatch::GapAreaMin; -void TriangleSelectorPatch::render(ImGuiWrapper* imgui) +void TriangleSelectorPatch::render(ImGuiWrapper* imgui, const Transform3d& matrix) { if (m_update_render_data) { update_render_data(); @@ -1174,8 +1178,8 @@ void TriangleSelectorPatch::render(ImGuiWrapper* imgui) auto* shader = wxGetApp().get_current_shader(); if (!shader) return; - assert(shader->get_name() == "mm_gouraud"); - GLint position_id = -1; + assert(shader->get_name() == "gouraud_attr" || shader->get_name() == "mm_gouraud_attr"); + GLint position_id = -1; GLint barycentric_id = -1; if (wxGetApp().plater()->is_wireframe_enabled()) { position_id = shader->get_attrib_location("v_position"); @@ -1212,7 +1216,7 @@ void TriangleSelectorPatch::render(ImGuiWrapper* imgui) } } - render_paint_contour(); + render_paint_contour(matrix); } void TriangleSelectorPatch::update_triangles_per_type() @@ -1631,10 +1635,14 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui) if (curr_shader != nullptr) curr_shader->stop_using(); - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); + 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()); + ::glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); for (vtype i : {ORIGINAL, SPLIT, INVALID}) { GLModel& va = m_varrays[i]; @@ -1661,35 +1669,37 @@ void TriangleSelectorGUI::update_paint_contour() 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()); + init_data.color = ColorRGBA::WHITE(); // 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)); } -void TriangleSelectorGUI::render_paint_contour() +void TriangleSelectorGUI::render_paint_contour(const Transform3d& matrix) { auto* curr_shader = wxGetApp().get_current_shader(); if (curr_shader != nullptr) curr_shader->stop_using(); - auto* contour_shader = wxGetApp().get_shader("mm_contour"); + auto* contour_shader = wxGetApp().get_shader("mm_contour_attr"); if (contour_shader != nullptr) { contour_shader->start_using(); + 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()); + glsafe(::glDepthFunc(GL_LEQUAL)); m_paint_contour.render(); glsafe(::glDepthFunc(GL_LESS)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp index c4f2cb5e29..0582e7aa77 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -34,10 +34,8 @@ public: : TriangleSelector(mesh, edge_limit) {} virtual ~TriangleSelectorGUI() = default; - // Render current selection. Transformation matrices are supposed - // to be already set. - virtual void render(ImGuiWrapper *imgui); - void render() { this->render(nullptr); } + virtual void render(ImGuiWrapper* imgui, const Transform3d& matrix); + void render(const Transform3d& matrix) { this->render(nullptr, matrix); } void set_wireframe_needed(bool need_wireframe) { m_need_wireframe = need_wireframe; } bool get_wireframe_needed() { return m_need_wireframe; } @@ -79,7 +77,7 @@ protected: GLModel m_paint_contour; void update_paint_contour(); - void render_paint_contour(); + void render_paint_contour(const Transform3d& matrix); bool m_need_wireframe {false}; }; @@ -105,7 +103,7 @@ public: // Render current selection. Transformation matrices are supposed // to be already set. - void render(ImGuiWrapper* imgui) override; + void render(ImGuiWrapper* imgui, const Transform3d& matrix) override; // TriangleSelector.m_triangles => m_gizmo_scene.triangle_patches void update_triangles_per_type(); // m_gizmo_scene.triangle_patches => TriangleSelector.m_triangles diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index a660d87dcc..ab3196364e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -126,14 +126,19 @@ void GLGizmoRotate::on_render() glsafe(::glEnable(GL_DEPTH_TEST)); - glsafe(::glPushMatrix()); - transform_to_local(selection); + m_grabbers.front().matrix = local_transform(selection); glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); + 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()); + const bool radius_changed = std::abs(m_old_radius - m_radius) > EPSILON; m_old_radius = m_radius; @@ -152,6 +157,8 @@ void GLGizmoRotate::on_render() render_grabber_connection(color, radius_changed); shader->stop_using(); } + glsafe(::glPushMatrix()); + transform_to_local(selection); render_grabber(box); render_grabber_extension(box, false); @@ -165,15 +172,11 @@ void GLGizmoRotate::on_render_for_picking() glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glPushMatrix()); - - transform_to_local(selection); + m_grabbers.front().matrix = local_transform(selection); const BoundingBoxf3& box = selection.get_bounding_box(); render_grabbers_for_picking(box); render_grabber_extension(box, true); - - glsafe(::glPopMatrix()); } //BBS: add input window for move @@ -214,7 +217,7 @@ void GLGizmoRotate::render_circle(const ColorRGBA& color, bool 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); @@ -222,7 +225,7 @@ void GLGizmoRotate::render_circle(const ColorRGBA& color, bool radius_changed) for (unsigned short 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)); @@ -241,7 +244,7 @@ void GLGizmoRotate::render_scale(const ColorRGBA& color, bool 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); @@ -257,8 +260,8 @@ void GLGizmoRotate::render_scale(const ColorRGBA& color, bool radius_changed) 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); + init_data.add_index(i * 2); + init_data.add_index(i * 2 + 1); } m_scale.init_from(std::move(init_data)); @@ -278,7 +281,7 @@ void GLGizmoRotate::render_snap_radii(const ColorRGBA& color, bool radius_change 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); @@ -294,8 +297,8 @@ void GLGizmoRotate::render_snap_radii(const ColorRGBA& color, bool radius_change 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); + init_data.add_index(i * 2); + init_data.add_index(i * 2 + 1); } m_snap_radii.init_from(std::move(init_data)); @@ -311,7 +314,7 @@ void GLGizmoRotate::render_reference_radius(const ColorRGBA& color, bool radius_ 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); @@ -320,7 +323,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)); } @@ -341,7 +344,7 @@ void GLGizmoRotate::render_angle_arc(const ColorRGBA& color, bool radius_changed 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); @@ -349,7 +352,7 @@ void GLGizmoRotate::render_angle_arc(const ColorRGBA& color, bool radius_changed for (unsigned short 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)); @@ -367,7 +370,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); @@ -376,7 +379,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)); } @@ -401,36 +404,69 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick if (!picking && m_hover_id != -1) color = m_grabbers.front().hover_color; - GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light"); + GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat_attr" : "gouraud_light_attr"); if (shader == nullptr) return; m_cone.set_color(color); + shader->start_using(); shader->set_uniform("emission_factor", 0.1f); const Vec3d& center = m_grabbers.front().center; - 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, 1.5 * size)); - glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); + 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(1.5 * 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()); m_cone.render(); - glsafe(::glPopMatrix()); - 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, 1.5 * size)); - glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); + view_model_matrix = view_matrix * m_grabbers.front().matrix * + Geometry::assemble_transform(center, Vec3d(-0.5 * PI, 0.0, m_angle)) * + Geometry::assemble_transform(1.5 * 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()); m_cone.render(); - glsafe(::glPopMatrix()); shader->stop_using(); } +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; +} + 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 aa4a773b47..b3cb707808 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp @@ -85,6 +85,8 @@ private: void render_grabber(const BoundingBoxf3& box); void render_grabber_extension(const BoundingBoxf3& box, bool picking); + Transform3d local_transform(const Selection& selection) const; + 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 0db0b4ab4b..aa3abff9bc 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -2,6 +2,7 @@ #include "GLGizmoScale.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/Plater.hpp" #include @@ -185,11 +186,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(), m_box.min.z()); @@ -230,14 +231,17 @@ 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); //draw connections - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); // BBS: when select multiple objects, uniform scale can be deselected, display the connection(4,5) //if (single_instance || single_volume) { + 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()); if (m_grabbers[4].enabled && m_grabbers[5].enabled) render_grabbers_connection(4, 5, m_grabbers[4].color); render_grabbers_connection(6, 7, m_grabbers[2].color); @@ -279,7 +283,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); @@ -288,7 +292,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)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp index 04e32898d6..57019b951d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp @@ -98,7 +98,7 @@ bool GLGizmoSeam::on_key_down_select_tool_type(int keyCode) { void GLGizmoSeam::render_triangles(const Selection& selection) const { ClippingPlaneDataWrapper clp_data = this->get_clipping_plane_data(); - auto* shader = wxGetApp().get_shader("mm_gouraud"); + auto* shader = wxGetApp().get_shader("mm_gouraud_attr"); if (!shader) return; shader->start_using(); @@ -120,8 +120,11 @@ void GLGizmoSeam::render_triangles(const Selection& selection) const if (is_left_handed) glsafe(::glFrontFace(GL_CW)); - glsafe(::glPushMatrix()); - glsafe(::glMultMatrixd(trafo_matrix.data())); + 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()); float normal_z = -::cos(Geometry::deg2rad(m_highlight_by_angle_threshold_deg)); Matrix3f normal_matrix = static_cast(trafo_matrix.matrix().block(0, 0, 3, 3).inverse().transpose().cast()); @@ -129,11 +132,10 @@ void GLGizmoSeam::render_triangles(const Selection& selection) const shader->set_uniform("volume_world_matrix", trafo_matrix); shader->set_uniform("volume_mirrored", is_left_handed); shader->set_uniform("slope.actived", m_parent.is_using_slope()); - shader->set_uniform("slope.volume_world_normal_matrix", static_cast(trafo_matrix.matrix().block(0, 0, 3, 3).inverse().transpose().cast())); + shader->set_uniform("slope.volume_world_normal_matrix", normal_matrix); shader->set_uniform("slope.normal_z", normal_z); - m_triangle_selectors[mesh_id]->render(m_imgui); + m_triangle_selectors[mesh_id]->render(m_imgui, trafo_matrix); - glsafe(::glPopMatrix()); if (is_left_handed) glsafe(::glFrontFace(GL_CCW)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp index aca431750d..3beb4f0a98 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp @@ -641,19 +641,25 @@ void GLGizmoSimplify::on_render() return; const Transform3d trafo_matrix = selected_volume->world_matrix(); - glsafe(::glPushMatrix()); - glsafe(::glMultMatrixd(trafo_matrix.data())); - - auto *gouraud_shader = wxGetApp().get_shader("gouraud_light"); + auto* gouraud_shader = wxGetApp().get_shader("gouraud_light_attr"); glsafe(::glPushAttrib(GL_DEPTH_TEST)); glsafe(::glEnable(GL_DEPTH_TEST)); gouraud_shader->start_using(); + 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()); m_glmodel.render(); gouraud_shader->stop_using(); if (m_show_wireframe) { - auto* contour_shader = wxGetApp().get_shader("mm_contour"); + auto* contour_shader = wxGetApp().get_shader("mm_contour_attr"); contour_shader->start_using(); + contour_shader->set_uniform("view_model_matrix", view_model_matrix); + contour_shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + const ColorRGBA color = m_glmodel.get_color(); + m_glmodel.set_color(ColorRGBA::WHITE()); glsafe(::glLineWidth(1.0f)); glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); //ScopeGuard offset_fill_guard([]() { glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); }); @@ -661,11 +667,11 @@ void GLGizmoSimplify::on_render() //glsafe(::glPolygonOffset(5.0, 5.0)); m_glmodel.render(); glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); + m_glmodel.set_color(color); contour_shader->stop_using(); } glsafe(::glPopAttrib()); - glsafe(::glPopMatrix()); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index a981d15c72..820c676903 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -127,7 +127,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) if (! has_points && ! has_holes) return; - GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light"); + GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat_attr") : wxGetApp().get_shader("gouraud_light_attr"); if (shader == nullptr) return; @@ -136,12 +136,13 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) 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(); + const Transform3d instance_matrix = Geometry::assemble_transform(m_c->selection_info()->get_sla_shift() * Vec3d::UnitZ()) * vol->get_instance_transformation().get_matrix(); - glsafe(::glPushMatrix()); - glsafe(::glTranslated(0.0, 0.0, z_shift)); - glsafe(::glMultMatrixd(instance_matrix.data())); + 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); ColorRGBA render_color; for (size_t i = 0; i < cache_size; ++i) { @@ -179,9 +180,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) 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. - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(support_point.pos.x(), support_point.pos.y(), support_point.pos.z())); - glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data())); + const Transform3d support_matrix = Geometry::assemble_transform(support_point.pos.cast()) * instance_scaling_matrix_inverse; if (vol->is_left_handed()) glFrontFace(GL_CW); @@ -194,27 +193,29 @@ 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; - 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)); + 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()); m_cone.render(); - glsafe(::glPopMatrix()); } const double radius = (double)support_point.head_front_radius * RenderPointScale; - glsafe(::glScaled(radius, radius, radius)); + 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()); m_sphere.render(); if (vol->is_left_handed()) glFrontFace(GL_CCW); - - glsafe(::glPopMatrix()); } // Now render the drain holes: @@ -226,31 +227,26 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) if (is_mesh_point_clipped(drain_hole.pos.cast())) continue; - // 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())); + const Transform3d hole_matrix = Geometry::assemble_transform(drain_hole.pos.cast()) * instance_scaling_matrix_inverse; 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); - 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)); + 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()); m_cylinder.render(); if (vol->is_left_handed()) glFrontFace(GL_CCW); - glsafe(::glPopMatrix()); } } - - glsafe(::glPopMatrix()); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoText.cpp b/src/slic3r/GUI/Gizmos/GLGizmoText.cpp index facfa464ed..6d31534d4a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoText.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoText.cpp @@ -448,7 +448,7 @@ void GLGizmoText::on_render() ColorRGBA color = picking_color_component(0); m_grabbers[0].color = color; - GLShaderProgram *shader = wxGetApp().get_shader("gouraud_light"); + GLShaderProgram *shader = wxGetApp().get_shader("gouraud_light_attr"); if (shader != nullptr) { shader->start_using(); m_grabbers[0].render_for_picking(mean_size); @@ -500,14 +500,12 @@ void GLGizmoText::on_render_for_picking() ColorRGBA color = picking_color_component(0); m_grabbers[0].color = color; - GLShaderProgram *shader = wxGetApp().get_shader("flat"); + GLShaderProgram *shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { - glsafe(::glPushMatrix()); shader->start_using(); m_grabbers[0].render_for_picking(mean_size); shader->stop_using(); - glsafe(::glPopMatrix()); } } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index 3f65a188ef..5a7d4c0f50 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -214,15 +214,14 @@ 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()); - glsafe(::glPushMatrix()); glsafe(::glPushAttrib(GL_DEPTH_TEST)); glsafe(::glDisable(GL_DEPTH_TEST)); clipper->render_cut(mv->is_model_part() ? ColorRGBA(0.8f, 0.3f, 0.0f, 1.0f) : color_from_model_volume(*mv)); glsafe(::glPopAttrib()); - glsafe(::glPopMatrix()); ++clipper_id; } @@ -412,7 +411,7 @@ void ObjectClipper::render_cut() const 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; if (is_assem_cnv) { trafo.set_offset(trafo.get_offset() + offset_to_assembly * (GLVolume::explosion_ratio - 1.0) + vol_trafo.get_offset() * (GLVolume::explosion_ratio - 1.0)); @@ -427,10 +426,8 @@ void ObjectClipper::render_cut() const clipper->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), std::numeric_limits::max())); else clipper->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), -SINKING_Z_THRESHOLD)); - glsafe(::glPushMatrix()); // BBS clipper->render_cut({ 0.25f, 0.25f, 0.25f, 1.0f }); - glsafe(::glPopMatrix()); ++clipper_id; } @@ -557,7 +554,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())); @@ -576,9 +573,7 @@ void SupportsClipper::render_cut() const m_clipper->set_plane(*ocl->get_clipping_plane()); m_clipper->set_transformation(supports_trafo); - glsafe(::glPushMatrix()); m_clipper->render_cut({ 1.0f, 0.f, 0.37f, 1.0f }); - glsafe(::glPopMatrix()); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 1e500ff406..7f13c25c77 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -85,7 +85,9 @@ size_t GLGizmosManager::get_gizmo_idx_from_mouse(const Vec2d& mouse_pos) const float width = get_scaled_total_width(); #if BBS_TOOLBAR_ON_TOP //float space_width = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale();; - float top_x = std::max(m_parent.get_main_toolbar_width() + border, 0.5f * (cnv_w - width + m_parent.get_main_toolbar_width() + m_parent.get_collapse_toolbar_width() - m_parent.get_assemble_view_toolbar_width()) + border); + const float separator_width = m_parent.get_separator_toolbar_width(); + float top_x = std::max(0.0f, 0.5f * (cnv_w - (width + separator_width + m_parent.get_main_toolbar_width() - m_parent.get_collapse_toolbar_width() + m_parent.get_assemble_view_toolbar_width()))); + top_x += m_parent.get_main_toolbar_width() + separator_width / 2 + border; if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) top_x = 0.5f * cnv_w + 0.5f * (m_parent.get_assembly_paint_toolbar_width()); float top_y = 0; @@ -1277,37 +1279,37 @@ void GLGizmosManager::update_after_undo_redo(const UndoRedo::Snapshot& snapshot) dynamic_cast(m_gizmos[SlaSupports].get())->reslice_SLA_supports(true); } -void GLGizmosManager::render_background(float left, float top, float right, float bottom, float border) const +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) { //BBS: GUI refactor: remove the corners of gizmo - 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 inv_tex_width = 1.0f / tex_width; + const float inv_tex_height = 1.0f / tex_height; - 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; + 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; GLTexture::render_sub_texture(tex_id, left, right, bottom, 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 } }); /* - const float internal_left = left + border; - const float internal_right = right - border; - const float internal_top = top - border; - const float internal_bottom = bottom + border; + 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_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 @@ -1383,119 +1385,98 @@ void GLGizmosManager::render_arrow(const GLCanvas3D& parent, EType highlighted_t //when rendering, {0, 0} is at the center, {-0.5, 0.5} at the left-top void GLGizmosManager::do_render_overlay() const { - std::vector selectable_idxs = get_selectable_idxs(); + 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 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(); - float height = get_scaled_total_height(); - float width = get_scaled_total_width(); - float zoomed_border = m_layout.scaled_border() * inv_zoom; + if (cnv_w == 0 || cnv_h == 0) + return; - float zoomed_top_x; + 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; if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) { - zoomed_top_x = 0.5f * m_parent.get_assembly_paint_toolbar_width() * inv_zoom; + top_x = m_parent.get_assembly_paint_toolbar_width() * inv_cnv_w; } else { //BBS: GUI refactor: GLToolbar&&Gizmo adjust -#if BBS_TOOLBAR_ON_TOP float main_toolbar_width = (float)m_parent.get_main_toolbar_width(); float assemble_view_width = (float)m_parent.get_assemble_view_toolbar_width(); float collapse_width = (float)m_parent.get_collapse_toolbar_width(); + float separator_width = (float)m_parent.get_separator_toolbar_width(); //float space_width = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale(); //float zoomed_top_x = 0.5f *(cnv_w + main_toolbar_width - 2 * space_width - width) * inv_zoom; - float main_toolbar_left = std::max(-0.5f * cnv_w, -0.5f * (main_toolbar_width + get_scaled_total_width() + assemble_view_width - collapse_width)) * inv_zoom; + float main_toolbar_left = std::max(-0.5f * cnv_w, -0.5f * (main_toolbar_width + get_scaled_total_width() + assemble_view_width + separator_width - collapse_width)); //float zoomed_top_x = 0.5f *(main_toolbar_width + collapse_width - width - assemble_view_width) * inv_zoom; - zoomed_top_x = main_toolbar_left + (main_toolbar_width)*inv_zoom; + top_x = main_toolbar_left + main_toolbar_width + separator_width / 2; + top_x = top_x * inv_cnv_w * 2; } - float zoomed_top_y = 0.5f * cnv_h * inv_zoom; -#else - //float zoomed_top_x = (-0.5f * cnv_w) * inv_zoom; - //float zoomed_top_y = (0.5f * height) * inv_zoom; - float zoomed_top_x = (0.5f * cnv_w - width) * inv_zoom; - float main_toolbar_height = (float)m_parent.get_main_toolbar_height(); - float assemble_view_height = (float)m_parent.get_assemble_view_toolbar_height(); - //float space_height = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale(); - float zoomed_top_y = 0.5f * (height + assemble_view_height - main_toolbar_height) * inv_zoom; -#endif - //BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": zoomed_top_y %1%, space_height %2%, main_toolbar_height %3% zoomed_top_x %4%") % zoomed_top_y % space_height % main_toolbar_height % zoomed_top_x; + float top_y = 1.0f; - float zoomed_left = zoomed_top_x; - float zoomed_top = zoomed_top_y; - float zoomed_right = zoomed_left + width * inv_zoom; - float zoomed_bottom = zoomed_top - height * inv_zoom; + render_background(top_x, top_y, top_x + width, top_y - height, border_w, border_h); - render_background(zoomed_left, zoomed_top, zoomed_right, zoomed_bottom, zoomed_border); + top_x += border_w; + top_y -= border_h; - 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_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; //BBS: GUI refactor: GLToolbar&&Gizmo adjust - float zoomed_stride_x = m_layout.scaled_stride_x() * inv_zoom; + const float stride_x = 2.0f * m_layout.scaled_stride_x() * inv_cnv_w; - 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; bool is_render_current = false; - for (size_t idx : selectable_idxs) - { + 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; - - 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 } }); + 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) { //BBS: GUI refactor: GLToolbar&&Gizmo adjust //render_input_window uses a different coordination(imgui) //1. no need to scale by camera zoom, set {0,0} at left-up corner for imgui -#if BBS_TOOLBAR_ON_TOP //gizmo->render_input_window(width, 0.5f * cnv_h - zoomed_top_y * zoom, toolbar_top); - gizmo->render_input_window(0.5 * cnv_w + zoomed_top_x * zoom, height, cnv_h); + gizmo->render_input_window(0.5 * cnv_w + 0.5f * top_x * cnv_w, get_scaled_total_height(), cnv_h); is_render_current = true; -#else - float toolbar_top = cnv_h - wxGetApp().plater()->get_view_toolbar().get_height(); - //gizmo->render_input_window(width, 0.5f * cnv_h - zoomed_top_y * zoom, toolbar_top); - gizmo->render_input_window(cnv_w - width, 0.5f * cnv_h - zoomed_top_y * zoom, toolbar_top); -#endif } -#if BBS_TOOLBAR_ON_TOP - zoomed_top_x += zoomed_stride_x; -#else - zoomed_top_y -= zoomed_stride_y; -#endif + top_x += stride_x; } // BBS simplify gizmo is not a selected gizmo and need to render input window if (!is_render_current && m_current != Undefined) { - m_gizmos[m_current]->render_input_window(0.5 * cnv_w + zoomed_top_x * zoom, height, cnv_h); + m_gizmos[m_current]->render_input_window(0.5 * cnv_w + 0.5f * top_x * cnv_w, get_scaled_total_height(), cnv_h); } } @@ -1542,14 +1523,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() + "/images/"; 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 12c97e9ac4..d95c169386 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -325,11 +325,11 @@ public: bool get_uniform_scaling() const { return m_object_manipulation.get_uniform_scaling();} private: - void render_background(float left, float top, float right, float bottom, float border) const; + void render_background(float left, float top, float right, float bottom, float border_w, float border_h) const; void do_render_overlay() const; - bool generate_icons_texture() const; + bool generate_icons_texture(); void update_on_off_state(const Vec2d& mouse_pos); std::string update_hover_state(const Vec2d& mouse_pos); diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp index 3cdf5b6368..be30f4c732 100644 --- a/src/slic3r/GUI/MeshUtils.cpp +++ b/src/slic3r/GUI/MeshUtils.cpp @@ -8,6 +8,7 @@ #include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/Camera.hpp" +#include "slic3r/GUI/Plater.hpp" #include @@ -73,13 +74,19 @@ void MeshClipper::render_cut(const ColorRGBA& color) if (! m_triangles_valid) recalculate_triangles(); + 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(); - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); + 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()); m_model.set_color(color); m_model.render(); shader->stop_using(); @@ -205,7 +212,7 @@ void MeshClipper::recalculate_triangles() 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()); @@ -215,10 +222,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()) diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index d56b369f38..958fd6d50b 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -351,7 +351,7 @@ static bool init_model_from_lines(GLModel &model, const Lines &lines, float z) { GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::index_type(2 * lines.size()) }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(2 * lines.size()); init_data.reserve_indices(2 * lines.size()); @@ -359,10 +359,7 @@ static bool init_model_from_lines(GLModel &model, const Lines &lines, float z) init_data.add_vertex(Vec3f(unscale(l.a.x()), unscale(l.a.y()), z)); init_data.add_vertex(Vec3f(unscale(l.b.x()), unscale(l.b.y()), 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); } model.init_from(std::move(init_data)); @@ -374,7 +371,7 @@ static bool init_model_from_lines(GLModel &model, const Lines3 &lines) { GLModel::Geometry init_data; - init_data.format = {GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::index_type(2 * lines.size())}; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 }; init_data.reserve_vertices(2 * lines.size()); init_data.reserve_indices(2 * lines.size()); @@ -382,10 +379,7 @@ static bool init_model_from_lines(GLModel &model, const Lines3 &lines) init_data.add_vertex(Vec3f(unscale(l.a.x()), unscale(l.a.y()), unscale(l.a.z()))); init_data.add_vertex(Vec3f(unscale(l.b.x()), unscale(l.b.y()), unscale(l.b.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); } model.init_from(std::move(init_data)); @@ -583,9 +577,12 @@ void PartPlate::render_logo_texture(GLTexture &logo_texture, GLModel& logo_buffe } if (logo_buffer.is_initialized()) { - GLShaderProgram* shader = wxGetApp().get_shader("printbed"); + GLShaderProgram* shader = wxGetApp().get_shader("printbed_attr"); if (shader != nullptr) { shader->start_using(); + 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()); shader->set_uniform("transparent_background", 0); shader->set_uniform("svg_source", 0); @@ -852,9 +849,12 @@ void PartPlate::show_tooltip(const std::string tooltip) void PartPlate::render_icons(bool bottom, bool only_name, int hover_id) { - GLShaderProgram* shader = wxGetApp().get_shader("printbed"); + GLShaderProgram* shader = wxGetApp().get_shader("printbed_attr"); if (shader != nullptr) { shader->start_using(); + 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()); shader->set_uniform("transparent_background", bottom); //shader->set_uniform("svg_source", boost::algorithm::iends_with(m_partplate_list->m_del_texture.get_source(), ".svg")); shader->set_uniform("svg_source", 0); @@ -940,9 +940,12 @@ void PartPlate::render_icons(bool bottom, bool only_name, int hover_id) void PartPlate::render_only_numbers(bool bottom) { - GLShaderProgram* shader = wxGetApp().get_shader("printbed"); + GLShaderProgram* shader = wxGetApp().get_shader("printbed_attr"); if (shader != nullptr) { shader->start_using(); + 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()); shader->set_uniform("transparent_background", bottom); //shader->set_uniform("svg_source", boost::algorithm::iends_with(m_partplate_list->m_del_texture.get_source(), ".svg")); shader->set_uniform("svg_source", 0); @@ -968,14 +971,17 @@ void PartPlate::render_only_numbers(bool bottom) } } -void PartPlate::render_rectangle_for_picking(GLModel &buffer, const ColorRGBA render_color) +void PartPlate::render_rectangle_for_picking(const Transform3d &view_matrix, const Transform3d &projection_matrix, GLModel &buffer, const ColorRGBA render_color) { glsafe(::glDisable(GL_DEPTH_TEST)); - GLShaderProgram *shader = wxGetApp().get_shader("flat"); + GLShaderProgram *shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); + shader->set_uniform("view_model_matrix", view_matrix); + shader->set_uniform("projection_matrix", projection_matrix); + //glsafe(::glDepthMask(GL_FALSE)); buffer.set_color(render_color); buffer.render(); @@ -1203,36 +1209,36 @@ void PartPlate::render_right_arrow(const ColorRGBA render_color, bool use_lighti } */ -void PartPlate::on_render_for_picking() { +void PartPlate::on_render_for_picking(const Transform3d &view_matrix, const Transform3d &projection_matrix) { //glsafe(::glDisable(GL_DEPTH_TEST)); int hover_id = 0; ColorRGBA color = picking_color_component(hover_id); m_grabber_color = color; //render_grabber(m_grabber_color, false); - render_rectangle_for_picking(m_triangles, m_grabber_color); + render_rectangle_for_picking(view_matrix, projection_matrix, m_triangles, m_grabber_color); hover_id = 1; color = picking_color_component(hover_id); m_grabber_color = color; //render_left_arrow(m_grabber_color, false); - render_rectangle_for_picking(m_del_icon, m_grabber_color); + render_rectangle_for_picking(view_matrix, projection_matrix, m_del_icon, m_grabber_color); hover_id = 2; color = picking_color_component(hover_id); m_grabber_color = color; - render_rectangle_for_picking(m_orient_icon, m_grabber_color); + render_rectangle_for_picking(view_matrix, projection_matrix, m_orient_icon, m_grabber_color); hover_id = 3; color = picking_color_component(hover_id); m_grabber_color = color; - render_rectangle_for_picking(m_arrange_icon, m_grabber_color); + render_rectangle_for_picking(view_matrix, projection_matrix, m_arrange_icon, m_grabber_color); hover_id = 4; color = picking_color_component(hover_id); m_grabber_color = color; //render_right_arrow(m_grabber_color, false); - render_rectangle_for_picking(m_lock_icon, m_grabber_color); + render_rectangle_for_picking(view_matrix, projection_matrix, m_lock_icon, m_grabber_color); hover_id = 5; color = picking_color_component(hover_id); m_grabber_color = color; if (m_partplate_list->render_plate_settings) - render_rectangle_for_picking(m_plate_settings_icon, m_grabber_color); + render_rectangle_for_picking(view_matrix, projection_matrix, m_plate_settings_icon, m_grabber_color); } ColorRGBA PartPlate::picking_color_component(int idx) const @@ -2494,7 +2500,7 @@ bool PartPlate::intersects(const BoundingBoxf3& bb) const return print_volume.intersects(bb); } -void PartPlate::render(bool bottom, bool only_body, bool force_background_color, HeightLimitMode mode, int hover_id, bool render_cali) +void PartPlate::render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_body, bool force_background_color, HeightLimitMode mode, int hover_id, bool render_cali) { GLShaderProgram *shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { @@ -2503,8 +2509,8 @@ void PartPlate::render(bool bottom, bool only_body, bool force_background_color, glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - const Transform3d matrix = wxGetApp().plater()->get_camera().get_projection_view_matrix(); - shader->set_uniform("projection_view_model_matrix", matrix); + shader->set_uniform("view_model_matrix", view_matrix); + shader->set_uniform("projection_matrix", projection_matrix); if (!bottom) { // draw background @@ -4352,7 +4358,7 @@ void PartPlateList::postprocess_arrange_polygon(arrangement::ArrangePolygon& arr /*rendering related functions*/ //render -void PartPlateList::render(bool bottom, bool only_current, bool only_body, int hover_id, bool render_cali) +void PartPlateList::render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current, bool only_body, int hover_id, bool render_cali) { const std::lock_guard local_lock(m_plates_mutex); std::vector::iterator it = m_plate_list.begin(); @@ -4377,25 +4383,25 @@ void PartPlateList::render(bool bottom, bool only_current, bool only_body, int h if (current_index == m_current_plate) { PartPlate::HeightLimitMode height_mode = (only_current)?PartPlate::HEIGHT_LIMIT_NONE:m_height_limit_mode; if (plate_hover_index == current_index) - (*it)->render(bottom, only_body, false, height_mode, plate_hover_action, render_cali); + (*it)->render(view_matrix, projection_matrix, bottom, only_body, false, height_mode, plate_hover_action, render_cali); else - (*it)->render(bottom, only_body, false, height_mode, -1, render_cali); + (*it)->render(view_matrix, projection_matrix, bottom, only_body, false, height_mode, -1, render_cali); } else { if (plate_hover_index == current_index) - (*it)->render(bottom, only_body, false, PartPlate::HEIGHT_LIMIT_NONE, plate_hover_action, render_cali); + (*it)->render(view_matrix, projection_matrix, bottom, only_body, false, PartPlate::HEIGHT_LIMIT_NONE, plate_hover_action, render_cali); else - (*it)->render(bottom, only_body, false, PartPlate::HEIGHT_LIMIT_NONE, -1, render_cali); + (*it)->render(view_matrix, projection_matrix, bottom, only_body, false, PartPlate::HEIGHT_LIMIT_NONE, -1, render_cali); } } } -void PartPlateList::render_for_picking_pass() +void PartPlateList::render_for_picking_pass(const Transform3d &view_matrix, const Transform3d &projection_matrix) { const std::lock_guard local_lock(m_plates_mutex); std::vector::iterator it = m_plate_list.begin(); for (it = m_plate_list.begin(); it != m_plate_list.end(); it++) { - (*it)->render_for_picking(); + (*it)->render_for_picking(view_matrix, projection_matrix); } } diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index 9fcadf0598..b93e4f4dfa 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -181,8 +181,8 @@ private: void render_icons(bool bottom, bool only_name = false, int hover_id = -1); void render_only_numbers(bool bottom); void render_plate_name_texture(); - void render_rectangle_for_picking(GLModel &buffer, const ColorRGBA render_color); - void on_render_for_picking(); + void render_rectangle_for_picking(const Transform3d &view_matrix, const Transform3d &projection_matrix, GLModel &buffer, const ColorRGBA render_color); + void on_render_for_picking(const Transform3d &view_matrix, const Transform3d &projection_matrix); ColorRGBA picking_color_component(int idx) const; public: @@ -341,8 +341,8 @@ public: bool contains(const BoundingBoxf3& bb) const; bool intersects(const BoundingBoxf3& bb) const; - void render(bool bottom, bool only_body = false, bool force_background_color = false, HeightLimitMode mode = HEIGHT_LIMIT_NONE, int hover_id = -1, bool render_cali = false); - void render_for_picking() { on_render_for_picking(); } + void render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_body = false, bool force_background_color = false, HeightLimitMode mode = HEIGHT_LIMIT_NONE, int hover_id = -1, bool render_cali = false); + void render_for_picking(const Transform3d &view_matrix, const Transform3d &projection_matrix) { on_render_for_picking(view_matrix, projection_matrix); } void set_selected(); void set_unselected(); void set_hover_id(int id) { m_hover_id = id; } @@ -740,8 +740,8 @@ public: /*rendering related functions*/ void on_change_color_mode(bool is_dark) { m_is_dark = is_dark; } - void render(bool bottom, bool only_current = false, bool only_body = false, int hover_id = -1, bool render_cali = false); - void render_for_picking_pass(); + void render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current = false, bool only_body = false, int hover_id = -1, bool render_cali = false); + void render_for_picking_pass(const Transform3d& view_matrix, const Transform3d& projection_matrix); void set_render_option(bool bedtype_texture, bool plate_settings); void set_render_cali(bool value = true) { render_cali_logo = value; } BoundingBoxf3& get_bounding_box() { return m_bounding_box; } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index cff214537f..455616e3f2 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1570,22 +1570,26 @@ void Selection::render_center(bool gizmo_is_dragging) if (!m_valid || is_empty()) return; - const Vec3d center = gizmo_is_dragging ? m_cache.dragging_center : get_bounding_box().center(); - - glsafe(::glDisable(GL_DEPTH_TEST)); - - glsafe(::glPushMatrix()); - glsafe(::glTranslated(center.x(), center.y(), center.z())); - - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader == nullptr) return; shader->start_using(); - m_vbo_sphere.set_color(-1, ColorRGBA::WHITE()); + + const Vec3d center = gizmo_is_dragging ? m_cache.dragging_center : get_bounding_box().center(); + + glsafe(::glDisable(GL_DEPTH_TEST)); + + 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()); + + m_vbo_sphere.set_color(ColorRGBA::WHITE()); m_vbo_sphere.render(); + shader->stop_using(); - glsafe(::glPopMatrix()); } #endif // ENABLE_RENDER_SELECTION_CENTER @@ -1596,7 +1600,7 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, bool unif if (sidebar_field.empty()) return; - GLShaderProgram* shader = wxGetApp().get_shader(boost::starts_with(sidebar_field, "layer") ? "flat" : "gouraud_light"); + GLShaderProgram* shader = wxGetApp().get_shader(boost::starts_with(sidebar_field, "layer") ? "flat_attr" : "gouraud_light_attr"); if (shader == nullptr) return; @@ -1604,16 +1608,14 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, bool unif glsafe(::glEnable(GL_DEPTH_TEST)); - glsafe(::glPushMatrix()); + const Transform3d base_matrix = Geometry::assemble_transform(get_bounding_box().center()); + Transform3d orient_matrix = Transform3d::Identity(); if (!boost::starts_with(sidebar_field, "layer")) { - const Vec3d& center = get_bounding_box().center(); - + shader->set_uniform("emission_factor", 0.05f); // BBS if (is_single_full_instance()/* && !wxGetApp().obj_manipul()->get_world_coordinates()*/) { - glsafe(::glTranslated(center.x(), center.y(), center.z())); if (!boost::starts_with(sidebar_field, "position")) { - Transform3d orient_matrix = Transform3d::Identity(); 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")) { @@ -1621,51 +1623,45 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, bool unif 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())); } } - - glsafe(::glMultMatrixd(orient_matrix.data())); } - } else if (is_single_volume() || is_single_modifier()) { - 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); + } + else if (is_single_volume() || is_single_modifier()) { + orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); 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); - glsafe(::glMultMatrixd(orient_matrix.data())); - } else { - glsafe(::glTranslated(center(0), center(1), center(2))); - 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())); - } + } + else { + if (requires_local_axes()) + orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); } } if (!boost::starts_with(sidebar_field, "layer")) glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); if (boost::starts_with(sidebar_field, "position")) - render_sidebar_position_hints(sidebar_field); + 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); + 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")) //BBS: GUI refactor: add uniform_scale from gizmo - render_sidebar_scale_hints(sidebar_field, uniform_scale); + render_sidebar_scale_hints(sidebar_field, uniform_scale, *shader, base_matrix * orient_matrix); else if (boost::starts_with(sidebar_field, "layer")) - render_sidebar_layers_hints(sidebar_field); + render_sidebar_layers_hints(sidebar_field, *shader); - glsafe(::glPopMatrix()); 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::cut_to_clipboard() @@ -1681,8 +1677,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; @@ -1695,26 +1690,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); } } } @@ -2167,7 +2158,7 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, const ColorRGB& co 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); @@ -2230,7 +2221,7 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, const ColorRGB& co // indices for (unsigned short i = 0; i < 48; ++i) { - init_data.add_ushort_index(i); + init_data.add_index(i); } m_box.init_from(std::move(init_data)); @@ -2240,11 +2231,14 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, const ColorRGB& co glsafe(::glLineWidth(2.0f * m_scale_factor)); - GLShaderProgram* shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader == nullptr) return; shader->start_using(); + 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()); m_box.set_color(to_rgba(color)); m_box.render(); shader->stop_using(); @@ -2255,91 +2249,103 @@ static ColorRGBA get_color(Axis axis) return GLGizmoBase::AXES_COLOR[axis]; } -void Selection::render_sidebar_position_hints(const std::string& sidebar_field) +void Selection::render_sidebar_position_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix) { + 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()); + if (boost::ends_with(sidebar_field, "x")) { - glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); + 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()); m_arrow.set_color(get_color(X)); m_arrow.render(); } else if (boost::ends_with(sidebar_field, "y")) { + shader.set_uniform("view_model_matrix", view_matrix); + shader.set_uniform("normal_matrix", (Matrix3d)view_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); m_arrow.set_color(get_color(Y)); m_arrow.render(); } else if (boost::ends_with(sidebar_field, "z")) { - glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); + 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()); m_arrow.set_color(get_color(Z)); m_arrow.render(); } } -void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) +void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix) { - auto render_sidebar_rotation_hint = [this]() { + 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(); - glsafe(::glRotated(180.0, 0.0, 0.0, 1.0)); + 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()); + if (boost::ends_with(sidebar_field, "x")) { - glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); m_curved_arrow.set_color(get_color(X)); - render_sidebar_rotation_hint(); + render_sidebar_rotation_hint(shader, view_matrix * Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitY())); } else if (boost::ends_with(sidebar_field, "y")) { - glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); m_curved_arrow.set_color(get_color(Y)); - render_sidebar_rotation_hint(); + render_sidebar_rotation_hint(shader, view_matrix * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitX())); } else if (boost::ends_with(sidebar_field, "z")) { m_curved_arrow.set_color(get_color(Z)); - render_sidebar_rotation_hint(); + render_sidebar_rotation_hint(shader, view_matrix); } } //BBS: GUI refactor: add gizmo uniform_scale -void Selection::render_sidebar_scale_hints(const std::string& sidebar_field, bool gizmo_uniform_scale) +void Selection::render_sidebar_scale_hints(const std::string& sidebar_field, bool gizmo_uniform_scale, GLShaderProgram& shader, const Transform3d& matrix) { // BBS //bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling(); bool uniform_scale = requires_uniform_scale() || gizmo_uniform_scale; - auto render_sidebar_scale_hint = [this, uniform_scale](Axis axis) { + auto render_sidebar_scale_hint = [this, uniform_scale](Axis axis, GLShaderProgram& shader, const Transform3d& matrix) { m_arrow.set_color(uniform_scale ? UNIFORM_SCALE_COLOR : get_color(axis)); - GLShaderProgram* shader = wxGetApp().get_current_shader(); - if (shader != nullptr) - shader->set_uniform("emission_factor", 0.0f); - - glsafe(::glTranslated(0.0, 5.0, 0.0)); + 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()); m_arrow.render(); - glsafe(::glTranslated(0.0, -10.0, 0.0)); - glsafe(::glRotated(180.0, 0.0, 0.0, 1.0)); + 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()); m_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()); + if (boost::ends_with(sidebar_field, "x") || uniform_scale) { - glsafe(::glPushMatrix()); - glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); - render_sidebar_scale_hint(X); - glsafe(::glPopMatrix()); + render_sidebar_scale_hint(X, shader, view_matrix * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitZ())); } if (boost::ends_with(sidebar_field, "y") || uniform_scale) { - glsafe(::glPushMatrix()); - render_sidebar_scale_hint(Y); - glsafe(::glPopMatrix()); + render_sidebar_scale_hint(Y, shader, view_matrix); } if (boost::ends_with(sidebar_field, "z") || uniform_scale) { - glsafe(::glPushMatrix()); - glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); - render_sidebar_scale_hint(Z); - glsafe(::glPopMatrix()); + render_sidebar_scale_hint(Z, shader, view_matrix * Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitX())); } } -void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) +void Selection::render_sidebar_layers_hints(const std::string& sidebar_field, GLShaderProgram& shader) { static const float Margin = 10.0f; @@ -2388,7 +2394,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) 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); @@ -2399,8 +2405,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)); } @@ -2410,7 +2416,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); @@ -2421,12 +2427,16 @@ 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)); } + 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()); + 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); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 254f82a3cf..71c2cf6a1b 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -408,11 +408,11 @@ private: 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(); void render_bounding_box(const BoundingBoxf3& box, const ColorRGB& color); - void render_sidebar_position_hints(const std::string& sidebar_field); - void render_sidebar_rotation_hints(const std::string& sidebar_field); + 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); //BBS: GUI refactor: add uniform_scale from gizmo - void render_sidebar_scale_hints(const std::string& sidebar_field, bool gizmo_uniform_scale); - void render_sidebar_layers_hints(const std::string& sidebar_field); + void render_sidebar_scale_hints(const std::string& sidebar_field, bool gizmo_uniform_scale, GLShaderProgram& shader, const Transform3d& matrix); + void render_sidebar_layers_hints(const std::string& sidebar_field, GLShaderProgram& shader); public: enum SyncRotationType { diff --git a/src/slic3r/Utils/CalibUtils.cpp b/src/slic3r/Utils/CalibUtils.cpp index a496d1ff34..9530a4eb7d 100644 --- a/src/slic3r/Utils/CalibUtils.cpp +++ b/src/slic3r/Utils/CalibUtils.cpp @@ -917,7 +917,7 @@ void CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f ThumbnailData* thumbnail_data = &plate_data_list[0]->plate_thumbnail; unsigned int thumbnail_width = 512, thumbnail_height = 512; const ThumbnailsParams thumbnail_params = {{}, false, true, true, true, 0}; - GLShaderProgram* shader = wxGetApp().get_shader("thumbnail"); + GLShaderProgram* shader = wxGetApp().get_shader("thumbnail_attr"); for (unsigned int obj_idx = 0; obj_idx < (unsigned int)model->objects.size(); ++ obj_idx) { const ModelObject &model_object = *model->objects[obj_idx];