mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-05 14:51:06 +00:00
Faster Preview View (#15884)
Co-authored-by: Kris Austin <kris.austin@gmail.com>
This commit is contained in:
@@ -37,6 +37,8 @@ static constexpr float MAX_WIPES_RADIUS_MM = 1.0f;
|
||||
// Used for positions, displacements and so on.
|
||||
//
|
||||
using Vec3 = std::array<float, 3>;
|
||||
// ORCA: the per vertex data uploaded as GL_RGBA32F, see extract_pos_and_or_hwa().
|
||||
using Vec4 = std::array<float, 4>;
|
||||
|
||||
//
|
||||
// 4x4 square matrix with elements in column-major order:
|
||||
|
||||
@@ -80,6 +80,10 @@ public:
|
||||
// ORCA: section view. Cuts away where dot(plane, (x, y, z, 1)) < 0; { 0, 0, 0, 1 } keeps all.
|
||||
//
|
||||
void set_clipping_plane(const std::array<float, 4>& plane);
|
||||
//
|
||||
// ORCA: direction to the top light in eye space, shading the toolpaths and biasing their shadow lookup.
|
||||
//
|
||||
void set_light_top_dir(const Vec3& direction);
|
||||
|
||||
//
|
||||
// ************************************************************************
|
||||
|
||||
@@ -14,7 +14,7 @@ static const char* Segments_Vertex_Shader =
|
||||
"#version 150\n"
|
||||
"#define POINTY_CAPS\n"
|
||||
"#define FIX_TWISTING\n"
|
||||
"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n"
|
||||
"uniform vec3 light_top_dir;\n"
|
||||
"const float light_top_diffuse = 0.6 * 0.8;\n"
|
||||
// ORCA: the specular was 0.6 * 0.125, too faint to give the filament any sheen.
|
||||
"const float light_top_specular = 0.6 * 0.25;\n"
|
||||
@@ -31,13 +31,9 @@ static const char* Segments_Vertex_Shader =
|
||||
"uniform samplerBuffer height_width_angle_tex;\n"
|
||||
"uniform samplerBuffer color_tex;\n"
|
||||
"uniform usamplerBuffer segment_index_tex;\n"
|
||||
// ORCA: 0 during the shadow caster pass - the bias below shifts eye_position but not
|
||||
// world_position, so the caster would write a depth the receiver never looks up.
|
||||
"uniform float bias_scale;\n"
|
||||
// draw the instances last to first, top layers before the ones they hide, so that early depth
|
||||
// rejection discards most of the hidden fragments; set when the camera looks down on the print
|
||||
"uniform int reverse_order;\n"
|
||||
"uniform int instance_count;\n"
|
||||
// ORCA: draw last segment first, so looking down the top layers hide the rest from the fragment shader.
|
||||
"uniform bool reverse_order;\n"
|
||||
"uniform int instances_count;\n"
|
||||
// ORCA: section view
|
||||
"uniform vec4 clipping_plane;\n"
|
||||
"in int vertex_id;\n"
|
||||
@@ -53,13 +49,22 @@ static const char* Segments_Vertex_Shader =
|
||||
// ORCA: section view - the segment and the light on its cut face
|
||||
"flat out int segment_id;\n"
|
||||
"out vec3 cut_color_direct;\n"
|
||||
"vec3 decode_color(float color) {\n"
|
||||
// ORCA: the layers greyed or dimmed around the one the sliders show, see ViewerImpl::set_layer_colors().
|
||||
"uniform ivec2 lit_layers;\n"
|
||||
"uniform int grey_below_layer;\n"
|
||||
"uniform float dim_brightness;\n"
|
||||
"uniform int kept_vertex;\n"
|
||||
"vec3 decode_color(float color, int id, int layer) {\n"
|
||||
" int c = int(round(color));\n"
|
||||
" int r = (c >> 16) & 0xFF;\n"
|
||||
" int g = (c >> 8) & 0xFF;\n"
|
||||
" int b = (c >> 0) & 0xFF;\n"
|
||||
" vec3 rgb = vec3((c >> 16) & 0xFF, (c >> 8) & 0xFF, c & 0xFF);\n"
|
||||
" if (id != kept_vertex && layer != lit_layers.x && layer != lit_layers.y) {\n"
|
||||
" if (dim_brightness >= 0.0)\n"
|
||||
" rgb = floor(rgb * dim_brightness);\n"
|
||||
" else if (layer < grey_below_layer)\n"
|
||||
" rgb = vec3(64.0);\n"
|
||||
" }\n"
|
||||
" float f = 1.0 / 255.0f;\n"
|
||||
" return f * vec3(r, g, b);\n"
|
||||
" return f * rgb;\n"
|
||||
"}\n"
|
||||
"float direct_lighting(vec3 eye_position, vec3 eye_normal) {\n"
|
||||
" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n"
|
||||
@@ -68,7 +73,7 @@ static const char* Segments_Vertex_Shader =
|
||||
" return top_diffuse + front_diffuse + top_specular;\n"
|
||||
"}\n"
|
||||
"void main() {\n"
|
||||
" int instance = (reverse_order != 0) ? instance_count - 1 - gl_InstanceID : gl_InstanceID;\n"
|
||||
" int instance = reverse_order ? instances_count - 1 - gl_InstanceID : gl_InstanceID;\n"
|
||||
" int id_a = int(texelFetch(segment_index_tex, instance).r);\n"
|
||||
" int id_b = id_a + 1;\n"
|
||||
" vec3 pos_a = texelFetch(position_tex, id_a).xyz;\n"
|
||||
@@ -157,9 +162,9 @@ static const char* Segments_Vertex_Shader =
|
||||
" }\n"
|
||||
" vec3 eye_position = (view_matrix * vec4(pos, 1.0)).xyz;\n"
|
||||
" // ORCA: Apply bias to z-position to avoid z-fighting\n"
|
||||
" eye_position.z += bias * bias_scale;\n"
|
||||
" eye_position.z += bias;\n"
|
||||
" vec3 eye_normal = (view_matrix * vec4(normalize(pos - endpoint_pos), 0.0)).xyz;\n"
|
||||
" vec3 color_base = decode_color(texelFetch(color_tex, id).r);\n"
|
||||
" vec3 color_base = decode_color(texelFetch(color_tex, id).r, id, int(texelFetch(position_tex, id).w));\n"
|
||||
" color = color_base * (ambient + emission);\n"
|
||||
" color_direct = color_base * direct_lighting(eye_position, eye_normal);\n"
|
||||
" world_position = pos;\n"
|
||||
@@ -170,12 +175,60 @@ static const char* Segments_Vertex_Shader =
|
||||
" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
// ORCA: realistic view - shadow caster, one light facing ribbon per segment, not instanced as tiny instances are slow.
|
||||
static const char* Segments_Shadow_Caster_Vertex_Shader =
|
||||
"#version 150\n"
|
||||
"const vec3 UP = vec3(0, 0, 1);\n"
|
||||
"const int CORNERS[6] = int[](0, 1, 2, 0, 2, 3);\n"
|
||||
"uniform mat4 view_matrix;\n"
|
||||
"uniform mat4 projection_matrix;\n"
|
||||
"uniform samplerBuffer position_tex;\n"
|
||||
"uniform samplerBuffer height_width_angle_tex;\n"
|
||||
"uniform usamplerBuffer segment_index_tex;\n"
|
||||
"uniform bool reverse_order;\n"
|
||||
"uniform int instances_count;\n"
|
||||
"out vec3 world_position;\n"
|
||||
"void main() {\n"
|
||||
" int segment = gl_VertexID / 6;\n"
|
||||
" int corner = CORNERS[gl_VertexID - 6 * segment];\n"
|
||||
" int instance = reverse_order ? instances_count - 1 - segment : segment;\n"
|
||||
" int id_a = int(texelFetch(segment_index_tex, instance).r);\n"
|
||||
" int id = corner < 2 ? id_a : id_a + 1;\n"
|
||||
" vec3 pos_a = texelFetch(position_tex, id_a).xyz;\n"
|
||||
" vec3 pos_b = texelFetch(position_tex, id_a + 1).xyz;\n"
|
||||
" vec3 line = pos_b - pos_a;\n"
|
||||
" float line_len = length(line);\n"
|
||||
" vec3 line_dir = line_len < 1e-4 ? vec3(1.0, 0.0, 0.0) : line / line_len;\n"
|
||||
" vec3 line_right_dir = abs(dot(line_dir, UP)) > 0.9 ? normalize(cross(vec3(1, 0, 0), line_dir)) : normalize(cross(line_dir, UP));\n"
|
||||
" vec3 line_up_dir = normalize(cross(line_right_dir, line_dir));\n"
|
||||
" vec3 to_light = vec3(view_matrix[0][2], view_matrix[1][2], view_matrix[2][2]);\n"
|
||||
" vec3 side_dir = cross(to_light, line_dir);\n"
|
||||
" side_dir = dot(side_dir, side_dir) < 1e-8 ? line_right_dir : normalize(side_dir);\n"
|
||||
" vec2 height_width = texelFetch(height_width_angle_tex, id).xy;\n"
|
||||
" float half_extent = 0.5 * (height_width.y * abs(dot(line_right_dir, side_dir)) + height_width.x * abs(dot(line_up_dir, side_dir)));\n"
|
||||
" float along = (corner < 2 ? -0.5 : 0.5) * height_width.y;\n"
|
||||
" float side = (corner == 0 || corner == 3) ? -1.0 : 1.0;\n"
|
||||
" vec3 pos = (corner < 2 ? pos_a : pos_b) + along * line_dir + side * half_extent * side_dir;\n"
|
||||
" world_position = pos;\n"
|
||||
" gl_Position = projection_matrix * (view_matrix * vec4(pos, 1.0));\n"
|
||||
"}\n";
|
||||
|
||||
// ORCA: realistic view - the shadow caster writes depth only. What a section cuts away casts no shadow.
|
||||
static const char* Segments_Shadow_Caster_Fragment_Shader =
|
||||
"#version 150\n"
|
||||
"uniform vec4 clipping_plane;\n"
|
||||
"in vec3 world_position;\n"
|
||||
"void main() {\n"
|
||||
" if (dot(vec4(world_position, 1.0), clipping_plane) < 0.0)\n"
|
||||
" discard;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* Segments_Fragment_Shader =
|
||||
"#version 150\n"
|
||||
"// ORCA: realistic view - object-on-object and self shadows, read from the same depth map the\n"
|
||||
"// rest of the 3D scene samples. shadow_intensity == 0, the default, short-circuits the lookup,\n"
|
||||
"// so the toolpaths shade exactly as before whenever realistic view is off.\n"
|
||||
"const vec3 SHADOW_LIGHT_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);\n"
|
||||
"uniform vec3 light_top_dir;\n"
|
||||
"uniform sampler2D shadow_map;\n"
|
||||
"uniform mat4 shadow_light_vp;\n"
|
||||
"uniform float shadow_intensity;\n"
|
||||
@@ -212,7 +265,7 @@ static const char* Segments_Fragment_Shader =
|
||||
" return 1.0;\n"
|
||||
" // Slope-scaled bias, as in gouraud.fs. An extrusion is only a handful of shadow-map texels\n"
|
||||
" // wide, so grazing faces need the larger bias to keep self-shadow acne off the top surfaces.\n"
|
||||
" float NdotL = dot(normalize(normal), SHADOW_LIGHT_DIR);\n"
|
||||
" float NdotL = dot(normalize(normal), light_top_dir);\n"
|
||||
" float bias = mix(0.0004, 0.004, clamp(1.0 - NdotL, 0.0, 1.0));\n"
|
||||
" float sum = 0.0;\n"
|
||||
" for (int x = -2; x <= 2; ++x) {\n"
|
||||
@@ -289,13 +342,22 @@ static const char* Options_Vertex_Shader =
|
||||
"in vec3 in_normal;\n"
|
||||
"out vec3 color;\n"
|
||||
"out float clipping_plane_dot;\n"
|
||||
"vec3 decode_color(float color) {\n"
|
||||
// ORCA: as in Segments_Vertex_Shader.
|
||||
"uniform ivec2 lit_layers;\n"
|
||||
"uniform int grey_below_layer;\n"
|
||||
"uniform float dim_brightness;\n"
|
||||
"uniform int kept_vertex;\n"
|
||||
"vec3 decode_color(float color, int id, int layer) {\n"
|
||||
" int c = int(round(color));\n"
|
||||
" int r = (c >> 16) & 0xFF;\n"
|
||||
" int g = (c >> 8) & 0xFF;\n"
|
||||
" int b = (c >> 0) & 0xFF;\n"
|
||||
" vec3 rgb = vec3((c >> 16) & 0xFF, (c >> 8) & 0xFF, c & 0xFF);\n"
|
||||
" if (id != kept_vertex && layer != lit_layers.x && layer != lit_layers.y) {\n"
|
||||
" if (dim_brightness >= 0.0)\n"
|
||||
" rgb = floor(rgb * dim_brightness);\n"
|
||||
" else if (layer < grey_below_layer)\n"
|
||||
" rgb = vec3(64.0);\n"
|
||||
" }\n"
|
||||
" float f = 1.0 / 255.0f;\n"
|
||||
" return f * vec3(r, g, b);\n"
|
||||
" return f * rgb;\n"
|
||||
"}\n"
|
||||
"float lighting(vec3 eye_position, vec3 eye_normal) {\n"
|
||||
" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n"
|
||||
@@ -321,7 +383,7 @@ static const char* Options_Vertex_Shader =
|
||||
" // ORCA: Apply bias to z-position to avoid z-fighting\n"
|
||||
" eye_position.z += bias;\n"
|
||||
" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n"
|
||||
" vec3 color_base = decode_color(texelFetch(color_tex, id).r);\n"
|
||||
" vec3 color_base = decode_color(texelFetch(color_tex, id).r, id, int(texelFetch(position_tex, id).w));\n"
|
||||
" color = color_base * lighting(eye_position, eye_normal);\n"
|
||||
" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
@@ -15,7 +15,7 @@ static const char* Segments_Vertex_Shader_ES =
|
||||
"precision lowp usampler2D;\n"
|
||||
"#define POINTY_CAPS\n"
|
||||
"#define FIX_TWISTING\n"
|
||||
"const vec3 light_top_dir = vec3(-0.4574957, 0.4574957, 0.7624929);\n"
|
||||
"uniform vec3 light_top_dir;\n"
|
||||
"const float light_top_diffuse = 0.6 * 0.8;\n"
|
||||
// ORCA: the specular was 0.6 * 0.125, too faint to give the filament any sheen.
|
||||
"const float light_top_specular = 0.6 * 0.25;\n"
|
||||
@@ -32,6 +32,9 @@ static const char* Segments_Vertex_Shader_ES =
|
||||
"uniform sampler2D height_width_angle_tex;\n"
|
||||
"uniform sampler2D color_tex;\n"
|
||||
"uniform usampler2D segment_index_tex;\n"
|
||||
// ORCA: draw last segment first, so looking down the top layers hide the rest from the fragment shader.
|
||||
"uniform bool reverse_order;\n"
|
||||
"uniform int instances_count;\n"
|
||||
// ORCA: section view
|
||||
"uniform vec4 clipping_plane;\n"
|
||||
"in float vertex_id_float;\n"
|
||||
@@ -47,13 +50,22 @@ static const char* Segments_Vertex_Shader_ES =
|
||||
// ORCA: section view - the segment and the light on its cut face
|
||||
"flat out int segment_id;\n"
|
||||
"out vec3 cut_color_direct;\n"
|
||||
"vec3 decode_color(float color) {\n"
|
||||
// ORCA: the layers greyed or dimmed around the one the sliders show, see ViewerImpl::set_layer_colors().
|
||||
"uniform ivec2 lit_layers;\n"
|
||||
"uniform int grey_below_layer;\n"
|
||||
"uniform float dim_brightness;\n"
|
||||
"uniform int kept_vertex;\n"
|
||||
"vec3 decode_color(float color, int id, int layer) {\n"
|
||||
" int c = int(round(color));\n"
|
||||
" int r = (c >> 16) & 0xFF;\n"
|
||||
" int g = (c >> 8) & 0xFF;\n"
|
||||
" int b = (c >> 0) & 0xFF;\n"
|
||||
" vec3 rgb = vec3((c >> 16) & 0xFF, (c >> 8) & 0xFF, c & 0xFF);\n"
|
||||
" if (id != kept_vertex && layer != lit_layers.x && layer != lit_layers.y) {\n"
|
||||
" if (dim_brightness >= 0.0)\n"
|
||||
" rgb = floor(rgb * dim_brightness);\n"
|
||||
" else if (layer < grey_below_layer)\n"
|
||||
" rgb = vec3(64.0);\n"
|
||||
" }\n"
|
||||
" float f = 1.0 / 255.0f;\n"
|
||||
" return f * vec3(r, g, b);\n"
|
||||
" return f * rgb;\n"
|
||||
"}\n"
|
||||
"float direct_lighting(vec3 eye_position, vec3 eye_normal) {\n"
|
||||
" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n"
|
||||
@@ -71,7 +83,8 @@ static const char* Segments_Vertex_Shader_ES =
|
||||
"}\n"
|
||||
"void main() {\n"
|
||||
" int vertex_id = int(vertex_id_float);\n"
|
||||
" int id_a = int(texelFetch(segment_index_tex, tex_coord_u(segment_index_tex, gl_InstanceID), 0).r);\n"
|
||||
" int instance = reverse_order ? instances_count - 1 - gl_InstanceID : gl_InstanceID;\n"
|
||||
" int id_a = int(texelFetch(segment_index_tex, tex_coord_u(segment_index_tex, instance), 0).r);\n"
|
||||
" int id_b = id_a + 1;\n"
|
||||
" vec3 pos_a = texelFetch(position_tex, tex_coord(position_tex, id_a), 0).xyz;\n"
|
||||
" vec3 pos_b = texelFetch(position_tex, tex_coord(position_tex, id_b), 0).xyz;\n"
|
||||
@@ -156,7 +169,7 @@ static const char* Segments_Vertex_Shader_ES =
|
||||
" }\n"
|
||||
" vec3 eye_position = (view_matrix * vec4(pos, 1.0)).xyz;\n"
|
||||
" vec3 eye_normal = (view_matrix * vec4(normalize(pos - endpoint_pos), 0.0)).xyz;\n"
|
||||
" vec3 color_base = decode_color(texelFetch(color_tex, tex_coord(color_tex, id), 0).r);\n"
|
||||
" vec3 color_base = decode_color(texelFetch(color_tex, tex_coord(color_tex, id), 0).r, id, int(texelFetch(position_tex, tex_coord(position_tex, id), 0).w));\n"
|
||||
" color = color_base * (ambient + emission);\n"
|
||||
" color_direct = color_base * direct_lighting(eye_position, eye_normal);\n"
|
||||
" world_position = pos;\n"
|
||||
@@ -167,6 +180,64 @@ static const char* Segments_Vertex_Shader_ES =
|
||||
" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
// ORCA: realistic view - shadow caster, one light facing ribbon per segment, not instanced as tiny instances are slow.
|
||||
static const char* Segments_Shadow_Caster_Vertex_Shader_ES =
|
||||
"#version 300 es\n"
|
||||
"precision lowp usampler2D;\n"
|
||||
"const vec3 UP = vec3(0, 0, 1);\n"
|
||||
"const int CORNERS[6] = int[](0, 1, 2, 0, 2, 3);\n"
|
||||
"uniform mat4 view_matrix;\n"
|
||||
"uniform mat4 projection_matrix;\n"
|
||||
"uniform sampler2D position_tex;\n"
|
||||
"uniform sampler2D height_width_angle_tex;\n"
|
||||
"uniform usampler2D segment_index_tex;\n"
|
||||
"uniform bool reverse_order;\n"
|
||||
"uniform int instances_count;\n"
|
||||
"out vec3 world_position;\n"
|
||||
"ivec2 tex_coord(sampler2D sampler, int id) {\n"
|
||||
" ivec2 tex_size = textureSize(sampler, 0);\n"
|
||||
" return (tex_size.y == 1) ? ivec2(id, 0) : ivec2(id % tex_size.x, id / tex_size.x);\n"
|
||||
"}\n"
|
||||
"ivec2 tex_coord_u(usampler2D sampler, int id) {\n"
|
||||
" ivec2 tex_size = textureSize(sampler, 0);\n"
|
||||
" return (tex_size.y == 1) ? ivec2(id, 0) : ivec2(id % tex_size.x, id / tex_size.x);\n"
|
||||
"}\n"
|
||||
"void main() {\n"
|
||||
" int segment = gl_VertexID / 6;\n"
|
||||
" int corner = CORNERS[gl_VertexID - 6 * segment];\n"
|
||||
" int instance = reverse_order ? instances_count - 1 - segment : segment;\n"
|
||||
" int id_a = int(texelFetch(segment_index_tex, tex_coord_u(segment_index_tex, instance), 0).r);\n"
|
||||
" int id = corner < 2 ? id_a : id_a + 1;\n"
|
||||
" vec3 pos_a = texelFetch(position_tex, tex_coord(position_tex, id_a), 0).xyz;\n"
|
||||
" vec3 pos_b = texelFetch(position_tex, tex_coord(position_tex, id_a + 1), 0).xyz;\n"
|
||||
" vec3 line = pos_b - pos_a;\n"
|
||||
" float line_len = length(line);\n"
|
||||
" vec3 line_dir = line_len < 1e-4 ? vec3(1.0, 0.0, 0.0) : line / line_len;\n"
|
||||
" vec3 line_right_dir = abs(dot(line_dir, UP)) > 0.9 ? normalize(cross(vec3(1, 0, 0), line_dir)) : normalize(cross(line_dir, UP));\n"
|
||||
" vec3 line_up_dir = normalize(cross(line_right_dir, line_dir));\n"
|
||||
" vec3 to_light = vec3(view_matrix[0][2], view_matrix[1][2], view_matrix[2][2]);\n"
|
||||
" vec3 side_dir = cross(to_light, line_dir);\n"
|
||||
" side_dir = dot(side_dir, side_dir) < 1e-8 ? line_right_dir : normalize(side_dir);\n"
|
||||
" vec2 height_width = texelFetch(height_width_angle_tex, tex_coord(height_width_angle_tex, id), 0).xy;\n"
|
||||
" float half_extent = 0.5 * (height_width.y * abs(dot(line_right_dir, side_dir)) + height_width.x * abs(dot(line_up_dir, side_dir)));\n"
|
||||
" float along = (corner < 2 ? -0.5 : 0.5) * height_width.y;\n"
|
||||
" float side = (corner == 0 || corner == 3) ? -1.0 : 1.0;\n"
|
||||
" vec3 pos = (corner < 2 ? pos_a : pos_b) + along * line_dir + side * half_extent * side_dir;\n"
|
||||
" world_position = pos;\n"
|
||||
" gl_Position = projection_matrix * (view_matrix * vec4(pos, 1.0));\n"
|
||||
"}\n";
|
||||
|
||||
// ORCA: realistic view - the shadow caster writes depth only. What a section cuts away casts no shadow.
|
||||
static const char* Segments_Shadow_Caster_Fragment_Shader_ES =
|
||||
"#version 300 es\n"
|
||||
"precision highp float;\n"
|
||||
"uniform vec4 clipping_plane;\n"
|
||||
"in vec3 world_position;\n"
|
||||
"void main() {\n"
|
||||
" if (dot(vec4(world_position, 1.0), clipping_plane) < 0.0)\n"
|
||||
" discard;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* Segments_Fragment_Shader_ES =
|
||||
"#version 300 es\n"
|
||||
"precision highp float;\n"
|
||||
@@ -178,7 +249,7 @@ static const char* Segments_Fragment_Shader_ES =
|
||||
"// ORCA: realistic view - object-on-object and self shadows, read from the same depth map the\n"
|
||||
"// rest of the 3D scene samples. shadow_intensity == 0, the default, short-circuits the lookup,\n"
|
||||
"// so the toolpaths shade exactly as before whenever realistic view is off.\n"
|
||||
"const vec3 SHADOW_LIGHT_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);\n"
|
||||
"uniform vec3 light_top_dir;\n"
|
||||
"uniform sampler2D shadow_map;\n"
|
||||
"uniform mat4 shadow_light_vp;\n"
|
||||
"uniform float shadow_intensity;\n"
|
||||
@@ -215,7 +286,7 @@ static const char* Segments_Fragment_Shader_ES =
|
||||
" return 1.0;\n"
|
||||
" // Slope-scaled bias, as in gouraud.fs. An extrusion is only a handful of shadow-map texels\n"
|
||||
" // wide, so grazing faces need the larger bias to keep self-shadow acne off the top surfaces.\n"
|
||||
" float NdotL = dot(normalize(normal), SHADOW_LIGHT_DIR);\n"
|
||||
" float NdotL = dot(normalize(normal), light_top_dir);\n"
|
||||
" float bias = mix(0.0004, 0.004, clamp(1.0 - NdotL, 0.0, 1.0));\n"
|
||||
" float sum = 0.0;\n"
|
||||
" for (int x = -2; x <= 2; ++x) {\n"
|
||||
@@ -291,13 +362,22 @@ static const char* Options_Vertex_Shader_ES =
|
||||
"in vec3 in_normal;\n"
|
||||
"out vec3 color;\n"
|
||||
"out float clipping_plane_dot;\n"
|
||||
"vec3 decode_color(float color) {\n"
|
||||
// ORCA: the layers greyed or dimmed around the one the sliders show, see ViewerImpl::set_layer_colors().
|
||||
"uniform ivec2 lit_layers;\n"
|
||||
"uniform int grey_below_layer;\n"
|
||||
"uniform float dim_brightness;\n"
|
||||
"uniform int kept_vertex;\n"
|
||||
"vec3 decode_color(float color, int id, int layer) {\n"
|
||||
" int c = int(round(color));\n"
|
||||
" int r = (c >> 16) & 0xFF;\n"
|
||||
" int g = (c >> 8) & 0xFF;\n"
|
||||
" int b = (c >> 0) & 0xFF;\n"
|
||||
" vec3 rgb = vec3((c >> 16) & 0xFF, (c >> 8) & 0xFF, c & 0xFF);\n"
|
||||
" if (id != kept_vertex && layer != lit_layers.x && layer != lit_layers.y) {\n"
|
||||
" if (dim_brightness >= 0.0)\n"
|
||||
" rgb = floor(rgb * dim_brightness);\n"
|
||||
" else if (layer < grey_below_layer)\n"
|
||||
" rgb = vec3(64.0);\n"
|
||||
" }\n"
|
||||
" float f = 1.0 / 255.0f;\n"
|
||||
" return f * vec3(r, g, b);\n"
|
||||
" return f * rgb;\n"
|
||||
"}\n"
|
||||
"float lighting(vec3 eye_position, vec3 eye_normal) {\n"
|
||||
" float top_diffuse = light_top_diffuse * max(dot(eye_normal, light_top_dir), 0.0);\n"
|
||||
@@ -326,7 +406,7 @@ static const char* Options_Vertex_Shader_ES =
|
||||
" clipping_plane_dot = dot(vec4(offset, 1.0), clipping_plane);\n"
|
||||
" vec3 eye_position = (view_matrix * vec4(scale_matrix * in_position + offset, 1.0)).xyz;\n"
|
||||
" vec3 eye_normal = (view_matrix * vec4(in_normal, 0.0)).xyz;\n"
|
||||
" vec3 color_base = decode_color(texelFetch(color_tex, tex_coord(color_tex, id), 0).r);\n"
|
||||
" vec3 color_base = decode_color(texelFetch(color_tex, tex_coord(color_tex, id), 0).r, id, int(texelFetch(position_tex, tex_coord(position_tex, id), 0).w));\n"
|
||||
" color = color_base * lighting(eye_position, eye_normal);\n"
|
||||
" gl_Position = projection_matrix * vec4(eye_position, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
@@ -52,6 +52,11 @@ void Viewer::set_shadow_map(int texture_unit, const Mat4x4& light_view_projectio
|
||||
m_impl->set_shadow_map(texture_unit, light_view_projection, intensity, texel_size);
|
||||
}
|
||||
|
||||
void Viewer::set_light_top_dir(const Vec3& direction)
|
||||
{
|
||||
m_impl->set_light_top_dir(direction);
|
||||
}
|
||||
|
||||
void Viewer::set_tone(float exposure, float saturation)
|
||||
{
|
||||
m_impl->set_tone(exposure, saturation);
|
||||
|
||||
+159
-131
@@ -349,7 +349,7 @@ void ViewerImpl::TextureData::init(size_t vertices_count)
|
||||
m_tex_ids = std::vector<TexIds>(m_count);
|
||||
}
|
||||
|
||||
void ViewerImpl::TextureData::set_positions(const std::vector<Vec3>& positions)
|
||||
void ViewerImpl::TextureData::set_positions(const std::vector<Vec4>& positions)
|
||||
{
|
||||
if (m_count == 0)
|
||||
return;
|
||||
@@ -383,17 +383,17 @@ void ViewerImpl::TextureData::set_positions(const std::vector<Vec3>& positions)
|
||||
glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
|
||||
glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
|
||||
if (remaining >= tex_capacity) {
|
||||
glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, static_cast<GLsizei>(w), static_cast<GLsizei>(h), 0, GL_RGB, GL_FLOAT, &positions[offset]));
|
||||
glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, static_cast<GLsizei>(w), static_cast<GLsizei>(h), 0, GL_RGBA, GL_FLOAT, &positions[offset]));
|
||||
m_tex_ids[i].positions.second = w * h;
|
||||
}
|
||||
else {
|
||||
// the last row is only partially fitted with data, send it separately
|
||||
glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, static_cast<GLsizei>(w), static_cast<GLsizei>(h), 0, GL_RGB, GL_FLOAT, nullptr));
|
||||
glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, static_cast<GLsizei>(w), static_cast<GLsizei>(h - 1), GL_RGB, GL_FLOAT, &positions[offset]));
|
||||
glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, static_cast<GLsizei>(h - 1), static_cast<GLsizei>(remaining % w), 1, GL_RGB, GL_FLOAT, &positions[offset + w * (h - 1)]));
|
||||
glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, static_cast<GLsizei>(w), static_cast<GLsizei>(h), 0, GL_RGBA, GL_FLOAT, nullptr));
|
||||
glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, static_cast<GLsizei>(w), static_cast<GLsizei>(h - 1), GL_RGBA, GL_FLOAT, &positions[offset]));
|
||||
glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, static_cast<GLsizei>(h - 1), static_cast<GLsizei>(remaining % w), 1, GL_RGBA, GL_FLOAT, &positions[offset + w * (h - 1)]));
|
||||
m_tex_ids[i].positions.second = w * (h - 1) + remaining % w;
|
||||
}
|
||||
m_positions_size += m_tex_ids[i].positions.second * sizeof(Vec3);
|
||||
m_positions_size += m_tex_ids[i].positions.second * sizeof(Vec4);
|
||||
|
||||
remaining = (remaining > tex_capacity) ? remaining - tex_capacity: 0;
|
||||
}
|
||||
@@ -402,7 +402,7 @@ void ViewerImpl::TextureData::set_positions(const std::vector<Vec3>& positions)
|
||||
glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, curr_unpack_alignment));
|
||||
}
|
||||
|
||||
void ViewerImpl::TextureData::set_heights_widths_angles(const std::vector<Vec3>& heights_widths_angles)
|
||||
void ViewerImpl::TextureData::set_heights_widths_angles(const std::vector<Vec4>& heights_widths_angles)
|
||||
{
|
||||
if (m_count == 0)
|
||||
return;
|
||||
@@ -436,17 +436,17 @@ void ViewerImpl::TextureData::set_heights_widths_angles(const std::vector<Vec3>&
|
||||
glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
|
||||
glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
|
||||
if (remaining >= tex_capacity) {
|
||||
glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, static_cast<GLsizei>(w), static_cast<GLsizei>(h), 0, GL_RGB, GL_FLOAT, &heights_widths_angles[offset]));
|
||||
glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, static_cast<GLsizei>(w), static_cast<GLsizei>(h), 0, GL_RGBA, GL_FLOAT, &heights_widths_angles[offset]));
|
||||
m_tex_ids[i].heights_widths_angles.second = w * h;
|
||||
}
|
||||
else {
|
||||
// the last row is only partially fitted with data, send it separately
|
||||
glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, static_cast<GLsizei>(w), static_cast<GLsizei>(h), 0, GL_RGB, GL_FLOAT, nullptr));
|
||||
glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, static_cast<GLsizei>(w), static_cast<GLsizei>(h - 1), GL_RGB, GL_FLOAT, &heights_widths_angles[offset]));
|
||||
glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, static_cast<GLsizei>(h - 1), static_cast<GLsizei>(remaining % w), 1, GL_RGB, GL_FLOAT, &heights_widths_angles[offset + w * (h - 1)]));
|
||||
glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, static_cast<GLsizei>(w), static_cast<GLsizei>(h), 0, GL_RGBA, GL_FLOAT, nullptr));
|
||||
glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, static_cast<GLsizei>(w), static_cast<GLsizei>(h - 1), GL_RGBA, GL_FLOAT, &heights_widths_angles[offset]));
|
||||
glsafe(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, static_cast<GLsizei>(h - 1), static_cast<GLsizei>(remaining % w), 1, GL_RGBA, GL_FLOAT, &heights_widths_angles[offset + w * (h - 1)]));
|
||||
m_tex_ids[i].heights_widths_angles.second = w * (h - 1) + remaining % w;
|
||||
}
|
||||
m_height_width_angle_size += m_tex_ids[i].heights_widths_angles.second * sizeof(Vec3);
|
||||
m_height_width_angle_size += m_tex_ids[i].heights_widths_angles.second * sizeof(Vec4);
|
||||
|
||||
remaining = (remaining > tex_capacity) ? remaining - tex_capacity : 0;
|
||||
}
|
||||
@@ -732,6 +732,21 @@ ViewerImpl::ViewerImpl()
|
||||
reset_default_options_colors();
|
||||
}
|
||||
|
||||
void ViewerImpl::SegmentsUniforms::init(unsigned int shader_id)
|
||||
{
|
||||
view_matrix = glGetUniformLocation(shader_id, "view_matrix");
|
||||
projection_matrix = glGetUniformLocation(shader_id, "projection_matrix");
|
||||
camera_position = glGetUniformLocation(shader_id, "camera_position");
|
||||
positions_tex = glGetUniformLocation(shader_id, "position_tex");
|
||||
height_width_angle_tex = glGetUniformLocation(shader_id, "height_width_angle_tex");
|
||||
colors_tex = glGetUniformLocation(shader_id, "color_tex");
|
||||
segment_index_tex = glGetUniformLocation(shader_id, "segment_index_tex");
|
||||
reverse_order = glGetUniformLocation(shader_id, "reverse_order");
|
||||
instances_count = glGetUniformLocation(shader_id, "instances_count");
|
||||
// ORCA: section view
|
||||
clipping_plane = glGetUniformLocation(shader_id, "clipping_plane");
|
||||
}
|
||||
|
||||
void ViewerImpl::init(const std::string& opengl_context_version)
|
||||
{
|
||||
if (m_initialized)
|
||||
@@ -756,15 +771,7 @@ void ViewerImpl::init(const std::string& opengl_context_version)
|
||||
m_segments_shader_id = init_shader("segments", Segments_Vertex_Shader, Segments_Fragment_Shader);
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
|
||||
m_uni_segments_view_matrix_id = glGetUniformLocation(m_segments_shader_id, "view_matrix");
|
||||
m_uni_segments_projection_matrix_id = glGetUniformLocation(m_segments_shader_id, "projection_matrix");
|
||||
m_uni_segments_camera_position_id = glGetUniformLocation(m_segments_shader_id, "camera_position");
|
||||
m_uni_segments_positions_tex_id = glGetUniformLocation(m_segments_shader_id, "position_tex");
|
||||
m_uni_segments_height_width_angle_tex_id = glGetUniformLocation(m_segments_shader_id, "height_width_angle_tex");
|
||||
m_uni_segments_colors_tex_id = glGetUniformLocation(m_segments_shader_id, "color_tex");
|
||||
m_uni_segments_segment_index_tex_id = glGetUniformLocation(m_segments_shader_id, "segment_index_tex");
|
||||
m_uni_segments_reverse_order_id = glGetUniformLocation(m_segments_shader_id, "reverse_order");
|
||||
m_uni_segments_instance_count_id = glGetUniformLocation(m_segments_shader_id, "instance_count");
|
||||
m_uni_segments.init(m_segments_shader_id);
|
||||
// ORCA: realistic view
|
||||
m_uni_segments_shadow_map_id = glGetUniformLocation(m_segments_shader_id, "shadow_map");
|
||||
m_uni_segments_shadow_light_vp_id = glGetUniformLocation(m_segments_shader_id, "shadow_light_vp");
|
||||
@@ -772,17 +779,29 @@ void ViewerImpl::init(const std::string& opengl_context_version)
|
||||
m_uni_segments_shadow_map_texel_id = glGetUniformLocation(m_segments_shader_id, "shadow_map_texel");
|
||||
m_uni_segments_exposure_id = glGetUniformLocation(m_segments_shader_id, "exposure");
|
||||
m_uni_segments_saturation_id = glGetUniformLocation(m_segments_shader_id, "saturation");
|
||||
m_uni_segments_bias_scale_id = glGetUniformLocation(m_segments_shader_id, "bias_scale");
|
||||
// ORCA: section view
|
||||
m_uni_segments_clipping_plane_id = glGetUniformLocation(m_segments_shader_id, "clipping_plane");
|
||||
m_uni_segments_light_top_dir_id = glGetUniformLocation(m_segments_shader_id, "light_top_dir");
|
||||
m_uni_segments_layer_colors.init(m_segments_shader_id);
|
||||
glcheck();
|
||||
assert(m_uni_segments.view_matrix != -1 &&
|
||||
m_uni_segments.projection_matrix != -1 &&
|
||||
m_uni_segments.camera_position != -1 &&
|
||||
m_uni_segments.positions_tex != -1 &&
|
||||
m_uni_segments.height_width_angle_tex != -1 &&
|
||||
m_uni_segments.colors_tex != -1 &&
|
||||
m_uni_segments.segment_index_tex != -1 &&
|
||||
m_uni_segments.reverse_order != -1 &&
|
||||
m_uni_segments.instances_count != -1);
|
||||
|
||||
// ORCA: realistic view
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
m_segments_caster_shader_id = init_shader("segments_shadow_caster", Segments_Shadow_Caster_Vertex_Shader_ES, Segments_Shadow_Caster_Fragment_Shader_ES);
|
||||
#else
|
||||
m_segments_caster_shader_id = init_shader("segments_shadow_caster", Segments_Shadow_Caster_Vertex_Shader, Segments_Shadow_Caster_Fragment_Shader);
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
m_uni_segments_caster.init(m_segments_caster_shader_id);
|
||||
// The caster pulls its vertices from gl_VertexID, but a core profile needs a vertex array bound to draw.
|
||||
glsafe(glGenVertexArrays(1, &m_segments_caster_vao_id));
|
||||
glcheck();
|
||||
assert(m_uni_segments_view_matrix_id != -1 &&
|
||||
m_uni_segments_projection_matrix_id != -1 &&
|
||||
m_uni_segments_camera_position_id != -1 &&
|
||||
m_uni_segments_positions_tex_id != -1 &&
|
||||
m_uni_segments_height_width_angle_tex_id != -1 &&
|
||||
m_uni_segments_colors_tex_id != -1 &&
|
||||
m_uni_segments_segment_index_tex_id != -1);
|
||||
|
||||
m_segment_template.init();
|
||||
|
||||
@@ -801,6 +820,7 @@ void ViewerImpl::init(const std::string& opengl_context_version)
|
||||
m_uni_options_segment_index_tex_id = glGetUniformLocation(m_options_shader_id, "segment_index_tex");
|
||||
// ORCA: section view
|
||||
m_uni_options_clipping_plane_id = glGetUniformLocation(m_options_shader_id, "clipping_plane");
|
||||
m_uni_options_layer_colors.init(m_options_shader_id);
|
||||
glcheck();
|
||||
assert(m_uni_options_view_matrix_id != -1 &&
|
||||
m_uni_options_projection_matrix_id != -1 &&
|
||||
@@ -874,6 +894,14 @@ void ViewerImpl::shutdown()
|
||||
glsafe(glDeleteProgram(m_segments_shader_id));
|
||||
m_segments_shader_id = 0;
|
||||
}
|
||||
if (m_segments_caster_shader_id != 0) {
|
||||
glsafe(glDeleteProgram(m_segments_caster_shader_id));
|
||||
m_segments_caster_shader_id = 0;
|
||||
}
|
||||
if (m_segments_caster_vao_id != 0) {
|
||||
glsafe(glDeleteVertexArrays(1, &m_segments_caster_vao_id));
|
||||
m_segments_caster_vao_id = 0;
|
||||
}
|
||||
m_initialized = false;
|
||||
OpenGLWrapper::unload_opengl();
|
||||
}
|
||||
@@ -894,7 +922,7 @@ void ViewerImpl::reset()
|
||||
for (std::vector<float>& times : m_layer_start_times)
|
||||
std::vector<float>().swap(times);
|
||||
std::vector<uint32_t>().swap(m_layer_first_vertex);
|
||||
std::vector<float>().swap(m_colors_scratch);
|
||||
m_layers_in_vertex_order = false;
|
||||
m_valid_lines_bitset.clear();
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
m_cog_marker.reset();
|
||||
@@ -924,9 +952,8 @@ void ViewerImpl::reset()
|
||||
// On some graphic cards texture buffers using GL_RGB32F format do not work, see:
|
||||
// https://dev.prusa3d.com/browse/SPE-2411
|
||||
// https://github.com/prusa3d/PrusaSlicer/issues/12908
|
||||
// To let all drivers be happy, we use GL_RGBA32F format, so we need to add an extra (currently unused) float
|
||||
// To let all drivers be happy, we use GL_RGBA32F format, so we need to add an extra float
|
||||
// to position and heights_widths_angles vectors
|
||||
using Vec4 = std::array<float, 4>;
|
||||
|
||||
static void extract_pos_and_or_hwa(const std::vector<PathVertex>& vertices, float travels_radius, float wipes_radius, BitSet<>& valid_lines_bitset,
|
||||
std::vector<Vec4>* positions = nullptr, std::vector<Vec4>* heights_widths_angles = nullptr, bool update_bitset = false) {
|
||||
@@ -963,8 +990,8 @@ static void extract_pos_and_or_hwa(const std::vector<PathVertex>& vertices, floa
|
||||
}
|
||||
|
||||
if (positions != nullptr) {
|
||||
// the last component is a dummy float to comply with GL_RGBA32F format
|
||||
Vec4 position = { v.position[0], v.position[1], v.position[2], 0.0f };
|
||||
// ORCA: the last component, there to comply with GL_RGBA32F format, carries the layer the shaders grey and dim by
|
||||
Vec4 position = { v.position[0], v.position[1], v.position[2], static_cast<float>(v.layer_id) };
|
||||
if (move_type == EMoveType::Extrude)
|
||||
// push down extrusion vertices by half height to render them at the right z
|
||||
position[2] -= 0.5f * v.height;
|
||||
@@ -1080,6 +1107,8 @@ void ViewerImpl::load(GCodeInputData&& gcode_data)
|
||||
}
|
||||
for (size_t i = m_layer_first_vertex.size() - 1; i > 0; --i)
|
||||
m_layer_first_vertex[i - 1] = std::min(m_layer_first_vertex[i - 1], m_layer_first_vertex[i]);
|
||||
m_layers_in_vertex_order = std::is_sorted(m_vertices.begin(), m_vertices.end(),
|
||||
[](const PathVertex& a, const PathVertex& b) { return a.layer_id < b.layer_id; });
|
||||
|
||||
// the running time at each layer's first vertex, summed in vertex order so that
|
||||
// get_estimated_time_at() matches a full accumulation exactly
|
||||
@@ -1274,17 +1303,6 @@ static float encode_color(const Color& color) {
|
||||
return static_cast<float>(i_color);
|
||||
}
|
||||
|
||||
// ORCA: returns the encoded color scaled towards black by 'brightness', preserving its hue.
|
||||
// 1.0 = no change, 0.0 = black.
|
||||
static float encode_color_dimmed(const Color& color, float brightness) {
|
||||
const int r = static_cast<int>(color[0] * brightness);
|
||||
const int g = static_cast<int>(color[1] * brightness);
|
||||
const int b = static_cast<int>(color[2] * brightness);
|
||||
const int i_color = r << 16 | g << 8 | b;
|
||||
return static_cast<float>(i_color);
|
||||
}
|
||||
|
||||
|
||||
void ViewerImpl::update_colors_texture()
|
||||
{
|
||||
#if !defined(ENABLE_OPENGL_ES)
|
||||
@@ -1292,6 +1310,32 @@ void ViewerImpl::update_colors_texture()
|
||||
return;
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
|
||||
// ORCA: the colors of the vertices alone; the layers greyed or dimmed around the one the sliders
|
||||
// show are left to the shaders, see set_layer_colors(), so that a slider step uploads nothing.
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
if (!m_vertices_colors.empty())
|
||||
// update gpu buffer for colors
|
||||
m_texture_data.set_colors(m_vertices_colors);
|
||||
#else
|
||||
m_colors_tex_size = m_vertices_colors.size() * sizeof(float);
|
||||
|
||||
// update gpu buffer for colors
|
||||
glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_colors_buf_id));
|
||||
glsafe(glBufferData(GL_TEXTURE_BUFFER, m_vertices_colors.size() * sizeof(float), m_vertices_colors.data(), GL_STATIC_DRAW));
|
||||
glsafe(glBindBuffer(GL_TEXTURE_BUFFER, 0));
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
}
|
||||
|
||||
void ViewerImpl::LayerColorsUniforms::init(unsigned int shader_id)
|
||||
{
|
||||
lit_layers = glGetUniformLocation(shader_id, "lit_layers");
|
||||
grey_below_layer = glGetUniformLocation(shader_id, "grey_below_layer");
|
||||
dim_brightness = glGetUniformLocation(shader_id, "dim_brightness");
|
||||
kept_vertex = glGetUniformLocation(shader_id, "kept_vertex");
|
||||
}
|
||||
|
||||
void ViewerImpl::set_layer_colors(const LayerColorsUniforms& uni) const
|
||||
{
|
||||
const size_t top_layer_id = m_settings.top_layer_only_view_range ? m_layers.get_view_range()[1] : 0;
|
||||
const bool color_top_layer_only = m_view_range.get_full()[1] != m_view_range.get_visible()[1];
|
||||
|
||||
@@ -1310,43 +1354,15 @@ void ViewerImpl::update_colors_texture()
|
||||
const bool dim_previous_layers = m_settings.dim_previous_layers && m_settings.top_layer_only_view_range &&
|
||||
!m_layers.empty() && (inspecting_top_layer || inspecting_bottom_layer);
|
||||
|
||||
// Based on current settings and slider position, we might want to render some
|
||||
// vertices as dark grey (or darkened, see above). Use either that or the normal color (from the cache).
|
||||
// Reused across calls: this runs on every slider tick, and the allocation alone is
|
||||
// 4 bytes per vertex of the whole print each time.
|
||||
std::vector<float>& colors = m_colors_scratch;
|
||||
colors.resize(m_vertices_colors.size());
|
||||
assert(colors.size() == m_vertices.size() && m_vertices_colors.size() == m_vertices.size());
|
||||
for (size_t i=0; i<m_vertices.size(); ++i) {
|
||||
const PathVertex& v = m_vertices[i];
|
||||
const bool keep_spiral_seam = m_settings.spiral_vase_mode && i == m_view_range.get_enabled()[0];
|
||||
// ORCA: layers kept at full brightness by the dimming above are excluded from the greying below too
|
||||
const bool inspected_layer = dim_previous_layers &&
|
||||
((inspecting_top_layer && v.layer_id == layers_range[1]) ||
|
||||
(inspecting_bottom_layer && v.layer_id == layers_range[0]));
|
||||
if (dim_previous_layers && !inspected_layer && !keep_spiral_seam)
|
||||
colors[i] = encode_color_dimmed(get_vertex_color(v), m_settings.dim_previous_layers_brightness);
|
||||
else if (!inspected_layer && color_top_layer_only && v.layer_id < top_layer_id && !keep_spiral_seam)
|
||||
colors[i] = encode_color(DUMMY_COLOR);
|
||||
else
|
||||
colors[i] = m_vertices_colors[i];
|
||||
}
|
||||
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
if (!colors.empty())
|
||||
// update gpu buffer for colors
|
||||
m_texture_data.set_colors(colors);
|
||||
#else
|
||||
m_colors_tex_size = colors.size() * sizeof(float);
|
||||
|
||||
// update gpu buffer for colors
|
||||
glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_colors_buf_id));
|
||||
glsafe(glBufferData(GL_TEXTURE_BUFFER, colors.size() * sizeof(float), colors.data(), GL_STATIC_DRAW));
|
||||
glsafe(glBindBuffer(GL_TEXTURE_BUFFER, 0));
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
// Without dimming, the layers below the top one go dark grey while the moves slider is short of
|
||||
// the end. Neither touches the inspected layers, nor the first vertex of a spiral vase layer.
|
||||
glsafe(glUniform2i(uni.lit_layers, dim_previous_layers && inspecting_bottom_layer ? static_cast<int>(layers_range[0]) : -1,
|
||||
dim_previous_layers && inspecting_top_layer ? static_cast<int>(layers_range[1]) : -1));
|
||||
glsafe(glUniform1i(uni.grey_below_layer, color_top_layer_only ? static_cast<int>(top_layer_id) : 0));
|
||||
glsafe(glUniform1f(uni.dim_brightness, dim_previous_layers ? m_settings.dim_previous_layers_brightness : -1.0f));
|
||||
glsafe(glUniform1i(uni.kept_vertex, m_settings.spiral_vase_mode ? static_cast<int>(m_view_range.get_enabled()[0]) : -1));
|
||||
}
|
||||
|
||||
|
||||
void ViewerImpl::update_colors()
|
||||
{
|
||||
|
||||
@@ -1366,7 +1382,7 @@ void ViewerImpl::update_colors()
|
||||
|
||||
// Recalculate "normal" colors of all the vertices for current view settings.
|
||||
// If some part of the preview should be rendered in dark grey, it is taken
|
||||
// care of in update_colors_texture. That is to avoid the need to recalculate
|
||||
// care of in the shaders, see set_layer_colors(). That is to avoid the need to recalculate
|
||||
// the "normal" color on every slider move.
|
||||
for (size_t i = 0; i < m_vertices.size(); ++i)
|
||||
m_vertices_colors[i] = encode_color(get_vertex_color(m_vertices[i]));
|
||||
@@ -1453,8 +1469,6 @@ void ViewerImpl::set_layers_view_range(Interval::value_type min, Interval::value
|
||||
update_view_full_range();
|
||||
m_view_range.set_visible(m_view_range.get_enabled());
|
||||
m_settings.update_enabled_entities = true;
|
||||
//m_settings.update_colors = true;
|
||||
update_colors_texture();
|
||||
}
|
||||
|
||||
void ViewerImpl::toggle_top_layer_only_view_range()
|
||||
@@ -1463,8 +1477,6 @@ void ViewerImpl::toggle_top_layer_only_view_range()
|
||||
update_view_full_range();
|
||||
m_view_range.set_visible(m_view_range.get_enabled());
|
||||
m_settings.update_enabled_entities = true;
|
||||
//m_settings.update_colors = true;
|
||||
update_colors_texture();
|
||||
}
|
||||
|
||||
// ORCA: enable/disable darkening of the layers the layer slider is not scrubbed to
|
||||
@@ -1473,9 +1485,6 @@ void ViewerImpl::set_dim_previous_layers(bool value)
|
||||
if (m_settings.dim_previous_layers == value)
|
||||
return;
|
||||
m_settings.dim_previous_layers = value;
|
||||
// defer the actual color/texture rebuild to the next render(), when the GL context is current
|
||||
// (this may be toggled from the Preferences dialog, outside the canvas context)
|
||||
m_settings.update_colors = true;
|
||||
}
|
||||
|
||||
// ORCA: set how bright the darkened layers are rendered, 1.0 = unchanged, 0.0 = black
|
||||
@@ -1485,7 +1494,6 @@ void ViewerImpl::set_dim_previous_layers_brightness(float value)
|
||||
if (m_settings.dim_previous_layers_brightness == value)
|
||||
return;
|
||||
m_settings.dim_previous_layers_brightness = value;
|
||||
m_settings.update_colors = true;
|
||||
}
|
||||
|
||||
std::vector<ETimeMode> ViewerImpl::get_time_modes() const
|
||||
@@ -1593,8 +1601,6 @@ void ViewerImpl::set_view_visible_range(Interval::value_type min, Interval::valu
|
||||
update_view_full_range();
|
||||
m_view_range.set_visible(min, max);
|
||||
update_enabled_entities();
|
||||
//m_settings.update_colors = true;
|
||||
update_colors_texture();
|
||||
}
|
||||
|
||||
float ViewerImpl::get_estimated_time_at(size_t id) const
|
||||
@@ -1819,7 +1825,6 @@ size_t ViewerImpl::get_used_cpu_memory() const
|
||||
for (const std::vector<float>& times : m_layer_start_times)
|
||||
ret += STDVEC_MEMSIZE(times, float);
|
||||
ret += STDVEC_MEMSIZE(m_layer_first_vertex, uint32_t);
|
||||
ret += STDVEC_MEMSIZE(m_colors_scratch, float);
|
||||
ret += m_valid_lines_bitset.size_in_bytes_cpu();
|
||||
ret += m_height_range.size_in_bytes_cpu();
|
||||
ret += m_width_range.size_in_bytes_cpu();
|
||||
@@ -1912,6 +1917,11 @@ void ViewerImpl::update_view_full_range()
|
||||
}
|
||||
|
||||
auto last_it = first_it;
|
||||
// ORCA: skip straight to the layer above the range rather than walking there
|
||||
if (m_layers_in_vertex_order && layers_range[1] + 1 < m_layer_first_vertex.size())
|
||||
last_it = std::max(first_it, m_vertices.begin() + m_layer_first_vertex[layers_range[1] + 1]);
|
||||
else if (m_layers_in_vertex_order)
|
||||
last_it = m_vertices.end();
|
||||
while (last_it != m_vertices.end() && last_it->layer_id <= layers_range[1]) {
|
||||
++last_it;
|
||||
}
|
||||
@@ -1951,12 +1961,14 @@ void ViewerImpl::update_view_full_range()
|
||||
|
||||
if (m_settings.top_layer_only_view_range) {
|
||||
const Interval& full_range = m_view_range.get_full();
|
||||
auto top_first_it = m_vertices.begin() + full_range[0];
|
||||
bool shortened = false;
|
||||
while (top_first_it != m_vertices.end() && (top_first_it->layer_id < layers_range[1] || !is_visible(*top_first_it, m_settings))) {
|
||||
const auto range_first_it = m_vertices.begin() + full_range[0];
|
||||
auto top_first_it = range_first_it;
|
||||
// ORCA: skip straight to the top layer rather than walking there
|
||||
if (m_layers_in_vertex_order)
|
||||
top_first_it = std::max(top_first_it, m_vertices.begin() + m_layer_first_vertex[layers_range[1]]);
|
||||
while (top_first_it != m_vertices.end() && (top_first_it->layer_id < layers_range[1] || !is_visible(*top_first_it, m_settings)))
|
||||
++top_first_it;
|
||||
shortened = true;
|
||||
}
|
||||
const bool shortened = top_first_it != range_first_it;
|
||||
if (shortened)
|
||||
--top_first_it;
|
||||
|
||||
@@ -2038,7 +2050,7 @@ void ViewerImpl::update_color_ranges()
|
||||
void ViewerImpl::update_heights_widths()
|
||||
{
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
std::vector<Vec3> heights_widths_angles;
|
||||
std::vector<Vec4> heights_widths_angles;
|
||||
heights_widths_angles.reserve(m_vertices.size());
|
||||
extract_pos_and_or_hwa(m_vertices, m_travels_radius, m_wipes_radius, m_valid_lines_bitset, nullptr, &heights_widths_angles);
|
||||
m_texture_data.set_heights_widths_angles(heights_widths_angles);
|
||||
@@ -2070,7 +2082,10 @@ void ViewerImpl::update_heights_widths()
|
||||
|
||||
void ViewerImpl::render_segments(const Mat4x4& view_matrix, const Mat4x4& projection_matrix, const Vec3& camera_position)
|
||||
{
|
||||
if (m_segments_shader_id == 0)
|
||||
// ORCA: realistic view. The shadow caster pass draws depth only.
|
||||
const unsigned int shader_id = m_rendering_shadow_casters ? m_segments_caster_shader_id : m_segments_shader_id;
|
||||
const SegmentsUniforms& uni = m_rendering_shadow_casters ? m_uni_segments_caster : m_uni_segments;
|
||||
if (shader_id == 0)
|
||||
return;
|
||||
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
@@ -2087,42 +2102,54 @@ void ViewerImpl::render_segments(const Mat4x4& view_matrix, const Mat4x4& projec
|
||||
const bool curr_cull_face = glIsEnabled(GL_CULL_FACE);
|
||||
glcheck();
|
||||
|
||||
glsafe(glUseProgram(m_segments_shader_id));
|
||||
glsafe(glUseProgram(shader_id));
|
||||
|
||||
glsafe(glUniform1i(m_uni_segments_positions_tex_id, 0));
|
||||
glsafe(glUniform1i(m_uni_segments_height_width_angle_tex_id, 1));
|
||||
glsafe(glUniform1i(m_uni_segments_colors_tex_id, 2));
|
||||
glsafe(glUniform1i(m_uni_segments_segment_index_tex_id, 3));
|
||||
glsafe(glUniformMatrix4fv(m_uni_segments_view_matrix_id, 1, GL_FALSE, view_matrix.data()));
|
||||
glsafe(glUniformMatrix4fv(m_uni_segments_projection_matrix_id, 1, GL_FALSE, projection_matrix.data()));
|
||||
glsafe(glUniform3fv(m_uni_segments_camera_position_id, 1, camera_position.data()));
|
||||
// The segments come in print order, bottom layer first. Seen from above, that is back to front,
|
||||
// and every hidden fragment is shaded before the one that covers it. Drawing them last to first
|
||||
// lets the depth test reject the hidden ones instead. The camera looks down when the world's
|
||||
// up axis points towards it, which is the view matrix's (2, 2) entry being positive.
|
||||
const bool top_down = !m_rendering_shadow_casters && view_matrix[10] > 0.0f;
|
||||
glsafe(glUniform1i(m_uni_segments_reverse_order_id, top_down ? 1 : 0));
|
||||
#ifndef ENABLE_OPENGL_ES
|
||||
glsafe(glUniform1i(m_uni_segments_instance_count_id, static_cast<int>(m_enabled_segments_count)));
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
// ORCA: realistic view. The depth pass writes the map it would otherwise read, so it shades
|
||||
// with the lookup off.
|
||||
glsafe(glUniform1i(m_uni_segments_shadow_map_id, m_shadow_map_texture_unit));
|
||||
glsafe(glUniformMatrix4fv(m_uni_segments_shadow_light_vp_id, 1, GL_FALSE, m_shadow_light_vp.data()));
|
||||
glsafe(glUniform1f(m_uni_segments_shadow_intensity_id, m_rendering_shadow_casters ? 0.0f : m_shadow_intensity));
|
||||
glsafe(glUniform1f(m_uni_segments_shadow_map_texel_id, m_shadow_map_texel));
|
||||
glsafe(glUniform1f(m_uni_segments_exposure_id, m_exposure));
|
||||
glsafe(glUniform1f(m_uni_segments_saturation_id, m_saturation));
|
||||
glsafe(glUniform1f(m_uni_segments_bias_scale_id, m_rendering_shadow_casters ? 0.0f : 1.0f));
|
||||
glsafe(glUniform4fv(m_uni_segments_clipping_plane_id, 1, m_clipping_plane.data()));
|
||||
glsafe(glUniform1i(uni.positions_tex, 0));
|
||||
glsafe(glUniform1i(uni.height_width_angle_tex, 1));
|
||||
glsafe(glUniform1i(uni.colors_tex, 2));
|
||||
glsafe(glUniform1i(uni.segment_index_tex, 3));
|
||||
glsafe(glUniformMatrix4fv(uni.view_matrix, 1, GL_FALSE, view_matrix.data()));
|
||||
glsafe(glUniformMatrix4fv(uni.projection_matrix, 1, GL_FALSE, projection_matrix.data()));
|
||||
glsafe(glUniform3fv(uni.camera_position, 1, camera_position.data()));
|
||||
// ORCA: view_matrix(2,2) > 0 is looking down, where the last segments printed are the nearest.
|
||||
const bool reverse_order = view_matrix[10] > 0.0f;
|
||||
glsafe(glUniform1i(uni.reverse_order, reverse_order ? 1 : 0));
|
||||
glsafe(glUniform4fv(uni.clipping_plane, 1, m_clipping_plane.data()));
|
||||
if (!m_rendering_shadow_casters) {
|
||||
// ORCA: realistic view
|
||||
glsafe(glUniform1i(m_uni_segments_shadow_map_id, m_shadow_map_texture_unit));
|
||||
glsafe(glUniformMatrix4fv(m_uni_segments_shadow_light_vp_id, 1, GL_FALSE, m_shadow_light_vp.data()));
|
||||
glsafe(glUniform1f(m_uni_segments_shadow_intensity_id, m_shadow_intensity));
|
||||
glsafe(glUniform1f(m_uni_segments_shadow_map_texel_id, m_shadow_map_texel));
|
||||
glsafe(glUniform1f(m_uni_segments_exposure_id, m_exposure));
|
||||
glsafe(glUniform1f(m_uni_segments_saturation_id, m_saturation));
|
||||
glsafe(glUniform3fv(m_uni_segments_light_top_dir_id, 1, m_light_top_dir.data()));
|
||||
set_layer_colors(m_uni_segments_layer_colors);
|
||||
}
|
||||
|
||||
glsafe(glDisable(GL_CULL_FACE));
|
||||
|
||||
auto draw = [this, &uni](size_t count) {
|
||||
glsafe(glUniform1i(uni.instances_count, static_cast<int>(count)));
|
||||
if (!m_rendering_shadow_casters) {
|
||||
m_segment_template.render(count);
|
||||
return;
|
||||
}
|
||||
// ORCA: realistic view. 6 vertices per caster ribbon.
|
||||
int curr_vertex_array = 0;
|
||||
glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array));
|
||||
glsafe(glBindVertexArray(m_segments_caster_vao_id));
|
||||
glsafe(glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(6 * count)));
|
||||
glsafe(glBindVertexArray(curr_vertex_array));
|
||||
};
|
||||
|
||||
#ifdef ENABLE_OPENGL_ES
|
||||
int curr_bound_texture = 0;
|
||||
glsafe(glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_bound_texture));
|
||||
|
||||
for (size_t i = 0; i < m_texture_data.get_count(); ++i) {
|
||||
const size_t tex_count = m_texture_data.get_count();
|
||||
for (size_t n = 0; n < tex_count; ++n) {
|
||||
const size_t i = reverse_order ? tex_count - 1 - n : n;
|
||||
const auto [id, count] = m_texture_data.get_enabled_segments_tex_id(i);
|
||||
if (count == 0)
|
||||
continue;
|
||||
@@ -2134,7 +2161,7 @@ void ViewerImpl::render_segments(const Mat4x4& view_matrix, const Mat4x4& projec
|
||||
glsafe(glBindTexture(GL_TEXTURE_2D, m_texture_data.get_colors_tex_id(i).first));
|
||||
glsafe(glActiveTexture(GL_TEXTURE3));
|
||||
glsafe(glBindTexture(GL_TEXTURE_2D, id));
|
||||
m_segment_template.render(count);
|
||||
draw(count);
|
||||
}
|
||||
#else
|
||||
std::array<int, 4> curr_bound_texture = { 0, 0, 0, 0 };
|
||||
@@ -2157,7 +2184,7 @@ void ViewerImpl::render_segments(const Mat4x4& view_matrix, const Mat4x4& projec
|
||||
glsafe(glBindTexture(GL_TEXTURE_BUFFER, m_enabled_segments_tex_id));
|
||||
glsafe(glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, m_enabled_segments_buf_id));
|
||||
|
||||
m_segment_template.render(m_enabled_segments_count);
|
||||
draw(m_enabled_segments_count);
|
||||
#endif // ENABLE_OPENGL_ES
|
||||
|
||||
if (curr_cull_face)
|
||||
@@ -2203,6 +2230,7 @@ void ViewerImpl::render_options(const Mat4x4& view_matrix, const Mat4x4& project
|
||||
glsafe(glUniformMatrix4fv(m_uni_options_view_matrix_id, 1, GL_FALSE, view_matrix.data()));
|
||||
glsafe(glUniformMatrix4fv(m_uni_options_projection_matrix_id, 1, GL_FALSE, projection_matrix.data()));
|
||||
glsafe(glUniform4fv(m_uni_options_clipping_plane_id, 1, m_clipping_plane.data()));
|
||||
set_layer_colors(m_uni_options_layer_colors);
|
||||
|
||||
glsafe(glEnable(GL_CULL_FACE));
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ public:
|
||||
void set_tone(float exposure, float saturation);
|
||||
// ORCA: section view, see Viewer::set_clipping_plane()
|
||||
void set_clipping_plane(const std::array<float, 4>& plane) { m_clipping_plane = plane; }
|
||||
void set_light_top_dir(const Vec3& direction) { m_light_top_dir = direction; }
|
||||
|
||||
EViewType get_view_type() const { return m_settings.view_type; }
|
||||
void set_view_type(EViewType type);
|
||||
@@ -264,9 +265,10 @@ private:
|
||||
//
|
||||
std::vector<uint32_t> m_layer_first_vertex;
|
||||
//
|
||||
// Scratch buffer for update_colors_texture(), kept alive across slider steps
|
||||
// ORCA: whether the layer ids never decrease along the vertices, so that each layer's vertices
|
||||
// follow m_layer_first_vertex. Not so for a print by object, whose layers start over per object.
|
||||
//
|
||||
std::vector<float> m_colors_scratch;
|
||||
bool m_layers_in_vertex_order{ false };
|
||||
//
|
||||
// Detected travel moves times
|
||||
//
|
||||
@@ -349,6 +351,9 @@ private:
|
||||
// OpenGL shaders ids
|
||||
//
|
||||
unsigned int m_segments_shader_id{ 0 };
|
||||
// ORCA: realistic view. Depth-only ribbons for the shadow caster pass, and the empty vertex array they draw with.
|
||||
unsigned int m_segments_caster_shader_id{ 0 };
|
||||
unsigned int m_segments_caster_vao_id{ 0 };
|
||||
unsigned int m_options_shader_id{ 0 };
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
unsigned int m_cog_marker_shader_id{ 0 };
|
||||
@@ -357,25 +362,44 @@ private:
|
||||
//
|
||||
// Caches for OpenGL uniforms id for segments shader
|
||||
//
|
||||
int m_uni_segments_view_matrix_id{ -1 };
|
||||
int m_uni_segments_projection_matrix_id{ -1 };
|
||||
int m_uni_segments_camera_position_id{ -1 };
|
||||
int m_uni_segments_positions_tex_id{ -1 };
|
||||
int m_uni_segments_height_width_angle_tex_id{ -1 };
|
||||
int m_uni_segments_colors_tex_id{ -1 };
|
||||
int m_uni_segments_segment_index_tex_id{ -1 };
|
||||
int m_uni_segments_reverse_order_id{ -1 };
|
||||
int m_uni_segments_instance_count_id{ -1 };
|
||||
// ORCA: the ones the shaded and the shadow caster programs share.
|
||||
struct SegmentsUniforms
|
||||
{
|
||||
int view_matrix{ -1 };
|
||||
int projection_matrix{ -1 };
|
||||
int camera_position{ -1 };
|
||||
int positions_tex{ -1 };
|
||||
int height_width_angle_tex{ -1 };
|
||||
int colors_tex{ -1 };
|
||||
int segment_index_tex{ -1 };
|
||||
int reverse_order{ -1 };
|
||||
int instances_count{ -1 };
|
||||
int clipping_plane{ -1 };
|
||||
|
||||
void init(unsigned int shader_id);
|
||||
};
|
||||
SegmentsUniforms m_uni_segments;
|
||||
SegmentsUniforms m_uni_segments_caster;
|
||||
int m_uni_segments_shadow_map_id{ -1 };
|
||||
int m_uni_segments_shadow_light_vp_id{ -1 };
|
||||
int m_uni_segments_shadow_intensity_id{ -1 };
|
||||
int m_uni_segments_shadow_map_texel_id{ -1 };
|
||||
int m_uni_segments_exposure_id{ -1 };
|
||||
int m_uni_segments_saturation_id{ -1 };
|
||||
int m_uni_segments_bias_scale_id{ -1 };
|
||||
int m_uni_segments_clipping_plane_id{ -1 };
|
||||
int m_uni_segments_light_top_dir_id{ -1 };
|
||||
// ORCA: the layers greyed or dimmed around the one the sliders show, in the segments and options shaders.
|
||||
struct LayerColorsUniforms
|
||||
{
|
||||
int lit_layers{ -1 };
|
||||
int grey_below_layer{ -1 };
|
||||
int dim_brightness{ -1 };
|
||||
int kept_vertex{ -1 };
|
||||
|
||||
void init(unsigned int shader_id);
|
||||
};
|
||||
LayerColorsUniforms m_uni_segments_layer_colors;
|
||||
//
|
||||
// Caches for OpenGL uniforms id for options shader
|
||||
// Caches for OpenGL uniforms id for options shader
|
||||
//
|
||||
int m_uni_options_view_matrix_id{ -1 };
|
||||
int m_uni_options_projection_matrix_id{ -1 };
|
||||
@@ -384,6 +408,7 @@ private:
|
||||
int m_uni_options_colors_tex_id{ -1 };
|
||||
int m_uni_options_segment_index_tex_id{ -1 };
|
||||
int m_uni_options_clipping_plane_id{ -1 };
|
||||
LayerColorsUniforms m_uni_options_layer_colors;
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
//
|
||||
// Caches for OpenGL uniforms id for cog marker shader
|
||||
@@ -407,8 +432,8 @@ private:
|
||||
{
|
||||
public:
|
||||
void init(size_t vertices_count);
|
||||
void set_positions(const std::vector<Vec3>& positions);
|
||||
void set_heights_widths_angles(const std::vector<Vec3>& heights_widths_angles);
|
||||
void set_positions(const std::vector<Vec4>& positions);
|
||||
void set_heights_widths_angles(const std::vector<Vec4>& heights_widths_angles);
|
||||
void set_colors(const std::vector<float>& colors);
|
||||
void set_enabled_segments(const std::vector<uint32_t>& enabled_segments);
|
||||
void set_enabled_options(const std::vector<uint32_t>& enabled_options);
|
||||
@@ -516,8 +541,7 @@ private:
|
||||
|
||||
//
|
||||
// ORCA: realistic view. Shadow map state set by set_shadow_map(), consumed by the segments
|
||||
// shader. m_rendering_shadow_casters forces the intensity to 0 for the depth pass, which
|
||||
// must not sample the very map it is writing.
|
||||
// shader. m_rendering_shadow_casters switches render_segments() to the depth-only program.
|
||||
//
|
||||
// Defaults past the four texture units render_segments() binds itself, so the sampler never
|
||||
// aliases one of the buffer textures before the owner of the map has said where it lives.
|
||||
@@ -533,6 +557,8 @@ private:
|
||||
//
|
||||
float m_exposure{ 1.0f };
|
||||
float m_saturation{ 1.0f };
|
||||
// ORCA: the light the segments shader shades with, in eye space.
|
||||
Vec3 m_light_top_dir{ -0.4574957f, 0.4574957f, 0.7624929f };
|
||||
|
||||
// ORCA: section view
|
||||
std::array<float, 4> m_clipping_plane{ 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
@@ -543,6 +569,8 @@ private:
|
||||
void update_heights_widths();
|
||||
void render_segments(const Mat4x4& view_matrix, const Mat4x4& projection_matrix, const Vec3& camera_position);
|
||||
void render_options(const Mat4x4& view_matrix, const Mat4x4& projection_matrix);
|
||||
// ORCA: the program using uni must be current.
|
||||
void set_layer_colors(const LayerColorsUniforms& uni) const;
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
void render_cog_marker(const Mat4x4& view_matrix, const Mat4x4& projection_matrix);
|
||||
void render_tool_marker(const Mat4x4& view_matrix, const Mat4x4& projection_matrix);
|
||||
|
||||
Reference in New Issue
Block a user