NEW: cherry-pick rendering-stuff to github branch

jira: no-jira

Change-Id: If615d572b2021e707cc9ff037fefeabf46dacfa4
This commit is contained in:
jun.zhang 2024-12-10 19:30:08 +08:00 committed by lane.wei
parent 3366b13fd6
commit 9f060f9135
145 changed files with 5755 additions and 2664 deletions

View File

@ -1,7 +1,5 @@
#version 110
uniform vec4 uniform_color;
void main()
{
gl_FragColor = uniform_color;

View File

@ -0,0 +1,8 @@
#version 110
attribute vec3 v_position;
void main()
{
gl_Position = vec4(v_position, 1.0);
}

View File

@ -4,9 +4,15 @@ uniform mat4 view_matrix;
uniform mat4 projection_matrix;
attribute vec3 v_position;
attribute vec2 v_undefine;
attribute mat4 instanceMatrix;
// per instance data
// in mat4 instanceMatrix;
attribute vec4 i_data0;
attribute vec4 i_data1;
attribute vec4 i_data2;
attribute vec4 i_data3;
// end per instance data
void main()
{
gl_Position = projection_matrix * view_matrix * instanceMatrix * vec4(v_position, 1.0);
mat4 model_matrix = mat4(i_data0, i_data1, i_data2, i_data3);
gl_Position = projection_matrix * view_matrix * model_matrix * vec4(v_position, 1.0);
}

View File

@ -0,0 +1,10 @@
#version 110
uniform sampler2D u_texture;
varying vec2 v_texcoord;
void main()
{
gl_FragColor = texture2D(u_texture, v_texcoord);
}

View File

@ -0,0 +1,16 @@
#version 110
attribute vec3 v_position;
attribute vec2 v_tex_coord;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 u_uvTransformMatrix;
varying vec2 v_texcoord;
void main()
{
v_texcoord = (u_uvTransformMatrix * vec3(v_tex_coord, 1.0)).xy;
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
}

View File

@ -0,0 +1,78 @@
#version 110
uniform vec4 u_viewport_size;
uniform sampler2D u_sampler;
varying vec2 tex_coords;
// thanks https://github.com/mattdesl/glsl-fxaa
#ifndef FXAA_REDUCE_MIN
#define FXAA_REDUCE_MIN (1.0/ 128.0)
#endif
#ifndef FXAA_REDUCE_MUL
#define FXAA_REDUCE_MUL (1.0 / 8.0)
#endif
#ifndef FXAA_SPAN_MAX
#define FXAA_SPAN_MAX 8.0
#endif
vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 inv_resolution,
vec2 v_rgbNW, vec2 v_rgbNE,
vec2 v_rgbSW, vec2 v_rgbSE,
vec2 v_rgbM) {
vec4 color;
vec2 inverseVP = inv_resolution;
vec3 rgbNW = texture2D(tex, v_rgbNW).xyz;
vec3 rgbNE = texture2D(tex, v_rgbNE).xyz;
vec3 rgbSW = texture2D(tex, v_rgbSW).xyz;
vec3 rgbSE = texture2D(tex, v_rgbSE).xyz;
vec4 texColor = texture2D(tex, v_rgbM);
vec3 rgbM = texColor.xyz;
vec3 luma = vec3(0.299, 0.587, 0.114);
float lumaNW = dot(rgbNW, luma);
float lumaNE = dot(rgbNE, luma);
float lumaSW = dot(rgbSW, luma);
float lumaSE = dot(rgbSE, luma);
float lumaM = dot(rgbM, luma);
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
vec2 dir;
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
(0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
dir * rcpDirMin)) * inverseVP;
vec3 rgbA = 0.5 * (
texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +
texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);
vec3 rgbB = rgbA * 0.5 + 0.25 * (
texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz +
texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz);
float lumaB = dot(rgbB, luma);
if ((lumaB < lumaMin) || (lumaB > lumaMax))
color = vec4(rgbA, texColor.a);
else
color = vec4(rgbB, texColor.a);
return color;
}
void main()
{
vec2 fragCoord = tex_coords * u_viewport_size.xy;
vec2 add = u_viewport_size.zw;
vec2 rgbNW = tex_coords+vec2(-add.x, -add.y);
vec2 rgbNE = tex_coords+vec2( add.x, -add.y);
vec2 rgbSW = tex_coords+vec2(-add.x, add.y);
vec2 rgbSE = tex_coords+vec2( add.x, add.y);
vec2 rgbM = tex_coords;
gl_FragColor = fxaa(u_sampler, fragCoord, u_viewport_size.zw, rgbNW, rgbNE, rgbSW, rgbSE, rgbM);
}

View File

@ -0,0 +1,12 @@
#version 110
attribute vec3 v_position;
attribute vec2 v_tex_coord;
varying vec2 tex_coords;
void main()
{
tex_coords = v_tex_coord;
gl_Position = vec4(v_position, 1.0);
}

View File

@ -0,0 +1,35 @@
#version 110
uniform sampler2D u_sampler;
uniform mat3 u_convolution_matrix;
uniform vec2 u_viewport_size;
varying vec2 tex_coords;
vec4 sample(float offsetX, float offsetY)
{
return texture2D(u_sampler, vec2(tex_coords.x + offsetX, tex_coords.y + offsetY));
}
void main()
{
vec4 pixels[9];
float deltaWidth = 1.0 / u_viewport_size.x;
float deltaHeight = 1.0 / u_viewport_size.y;
pixels[0] = sample(-deltaWidth, deltaHeight );
pixels[1] = sample(0.0, deltaHeight );
pixels[2] = sample(deltaWidth, deltaHeight );
pixels[3] = sample(-deltaWidth, 0.0);
pixels[4] = sample(0.0, 0.0);
pixels[5] = sample(deltaWidth, 0.0);
pixels[6] = sample(-deltaWidth, -deltaHeight);
pixels[7] = sample(0.0, -deltaHeight);
pixels[8] = sample(deltaWidth, -deltaHeight);
vec4 accumulator = vec4(0.0);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; ++j)
{
accumulator += pixels[3 * i + j] * u_convolution_matrix[i][j];
}
}
gl_FragColor = accumulator;
}

View File

@ -0,0 +1,12 @@
#version 110
attribute vec3 v_position;
attribute vec2 v_tex_coord;
varying vec2 tex_coords;
void main()
{
tex_coords = v_tex_coord;
gl_Position = vec4(v_position, 1.0);
}

View File

@ -49,7 +49,6 @@ varying vec2 intensity;
uniform PrintVolumeDetection print_volume;
uniform vec3 extruder_printable_heights;
varying vec4 model_pos;
varying vec4 world_pos;
varying float world_normal_z;
varying vec3 eye_normal;

View File

@ -27,6 +27,13 @@ struct SlopeDetection
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;
@ -48,15 +55,15 @@ varying vec3 eye_normal;
void main()
{
// First transform the normal into camera space and normalize the result.
eye_normal = normalize(gl_NormalMatrix * gl_Normal);
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;
vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
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);
@ -66,14 +73,13 @@ void main()
NdotL = max(dot(eye_normal, LIGHT_BACK_DIR), 0.0);
intensity.x += NdotL * LIGHT_BACK_DIFFUSE;
}
model_pos = gl_Vertex;
// Point in homogenous coordinates.
world_pos = volume_world_matrix * gl_Vertex;
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 * gl_Normal)).z : 0.0;
world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * v_normal)).z : 0.0;
gl_Position = ftransform();
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);
}

View File

@ -14,30 +14,32 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define INTENSITY_AMBIENT 0.3
uniform mat4 volume_world_matrix;
attribute vec3 v_position;
attribute vec3 v_normal;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
// x = tainted, y = specular;
varying vec2 intensity;
varying vec4 world_pos;
void main()
{
// First transform the normal into camera space and normalize the result.
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
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;
vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
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 = ftransform();
gl_Position = projection_matrix * position;
}

View File

@ -2,6 +2,7 @@
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
const vec3 WHITE = vec3(1.0, 1.0, 1.0);
const float ONE_OVER_EPSILON = 1e4;
struct PrintVolumeDetection
{
// 0 = rectangle, 1 = circle, 2 = custom, 3 = invalid
@ -31,13 +32,20 @@ void main()
if (print_volume.type == 0) {// rectangle
pv_check_min = world_pos.xyz - vec3(print_volume.xy_data.x, print_volume.xy_data.y, print_volume.z_data.x);
pv_check_max = world_pos.xyz - vec3(print_volume.xy_data.z, print_volume.xy_data.w, print_volume.z_data.y);
pv_check_min = pv_check_min * ONE_OVER_EPSILON;
pv_check_max = pv_check_max * ONE_OVER_EPSILON;
color = (any(lessThan(pv_check_min, vec3(1.0))) || any(greaterThan(pv_check_max, vec3(1.0)))) ? mix(color, WHITE, 0.3333) : color;
}
else if (print_volume.type == 1) {// circle
float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy);
pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x);
pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y);
pv_check_min = pv_check_min * ONE_OVER_EPSILON;
pv_check_max = pv_check_max * ONE_OVER_EPSILON;
color = (any(lessThan(pv_check_min, vec3(1.0))) || any(greaterThan(pv_check_max, vec3(1.0)))) ? mix(color, WHITE, 0.3333) : color;
}
color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, WHITE, 0.3333) : color;
//gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
gl_FragColor = vec4(vec3(intensity.y) + color * (intensity.x + emission_factor), alpha);
}

View File

@ -1,7 +1,10 @@
#version 110
uniform sampler2D Texture;
varying vec2 Frag_UV;
varying vec4 color;
void main()
{
gl_FragColor = color * texture2D(Texture, Frag_UV.st);

View File

@ -1,10 +1,14 @@
#version 110
uniform mat4 ProjMtx;
attribute vec2 Position;
attribute vec2 UV;
attribute vec4 Color;
varying vec2 Frag_UV;
varying vec4 color;
void main()
{
Frag_UV = UV;

View File

@ -0,0 +1,10 @@
#version 110
uniform sampler2D u_sampler;
varying vec2 tex_coords;
void main()
{
gl_FragColor = texture2D(u_sampler, tex_coords);
}

View File

@ -0,0 +1,12 @@
#version 110
attribute vec3 v_position;
attribute vec2 v_tex_coord;
varying vec2 tex_coords;
void main()
{
tex_coords = v_tex_coord;
gl_Position = vec4(v_position, 1.0);
}

View File

@ -0,0 +1,11 @@
#version 110
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
attribute vec3 v_position;
void main()
{
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
}

View File

@ -24,7 +24,7 @@ const vec3 LightBlue = vec3(0.73, 1.0, 1.0);
uniform vec4 uniform_color;
varying vec3 clipping_planes_dots;
varying vec4 model_pos;
varying vec3 model_pos;
varying vec4 world_pos;
uniform bool volume_mirrored;
@ -57,6 +57,8 @@ vec3 getWireframeColor(vec3 fill) {
return (brightness > 0.75) ? vec3(0.11, 0.165, 0.208) : vec3(0.988, 0.988, 0.988);
}
uniform bool show_wireframe;
uniform mat4 view_model_matrix;
uniform mat3 normal_matrix;
void main()
{
@ -86,7 +88,7 @@ void main()
}
// First transform the normal into camera space and normalize the result.
vec3 eye_normal = normalize(gl_NormalMatrix * triangle_normal);
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.
@ -95,7 +97,7 @@ void main()
// x = diffuse, y = specular;
vec2 intensity = vec2(0.0, 0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec3 position = (gl_ModelViewMatrix * model_pos).xyz;
vec3 position = (view_model_matrix * vec4(model_pos, 1.0)).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).

View File

@ -2,17 +2,19 @@
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
//attribute vec3 v_position;
//attribute vec3 v_barycentric;
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;
attribute vec3 v_position;
attribute vec3 v_color;
varying vec3 clipping_planes_dots;
varying vec4 model_pos;
varying vec3 model_pos;
varying vec4 world_pos;
varying vec3 barycentric_coordinates;
@ -25,12 +27,12 @@ struct SlopeDetection
uniform SlopeDetection slope;
void main()
{
model_pos = gl_Vertex;
model_pos = v_position;
//model_pos = vec4(v_position, 1.0);
// Point in homogenous coordinates.
world_pos = volume_world_matrix * model_pos;
world_pos = volume_world_matrix * vec4(model_pos, 1.0);
gl_Position = ftransform();
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
//gl_Position = gl_ModelViewProjectionMatrix * vec4(v_position, 1.0);
// 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);
@ -38,5 +40,5 @@ void main()
//compute the Barycentric Coordinates
//int vertexMod3 = gl_VertexID % 3;
//barycentric_coordinates = vec3(float(vertexMod3 == 0), float(vertexMod3 == 1), float(vertexMod3 == 2));
barycentric_coordinates = gl_Color.xyz;//v_barycentric
barycentric_coordinates = v_color.xyz;
}

View File

@ -3,7 +3,7 @@
const vec3 back_color_dark = vec3(0.235, 0.235, 0.235);
const vec3 back_color_light = vec3(0.365, 0.365, 0.365);
uniform sampler2D texture;
uniform sampler2D u_sampler;
uniform bool transparent_background;
uniform bool svg_source;
@ -11,8 +11,8 @@ varying vec2 tex_coord;
vec4 svg_color(vec2 uv)
{
// takes foreground from texture
vec4 fore_color = texture2D(texture, uv);
// takes foreground from u_sampler
vec4 fore_color = texture2D(u_sampler, uv);
// calculates radial gradient
vec3 back_color = vec3(mix(back_color_light, back_color_dark, smoothstep(0.0, 0.5, length(abs(uv) - vec2(0.5)))));
@ -23,8 +23,8 @@ vec4 svg_color(vec2 uv)
vec4 non_svg_color(vec2 uv)
{
// takes foreground from texture
vec4 color = texture2D(texture, uv);
// takes foreground from u_sampler
vec4 color = texture2D(u_sampler, uv);
return vec4(color.rgb, transparent_background ? color.a * 0.25 : color.a);
}

View File

@ -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
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 * vec4(v_position, 1.0);
gl_Position = projection_matrix * position;
}

View File

@ -0,0 +1,16 @@
#version 110
attribute vec3 v_position;
attribute vec3 v_normal;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
varying vec3 eye_normal;
void main()
{
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
eye_normal = normal_matrix * v_normal;
}

View File

@ -14,6 +14,14 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#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;
@ -25,15 +33,15 @@ varying float object_z;
void main()
{
// First transform the normal into camera space and normalize the result.
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
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;
vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
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);
@ -43,10 +51,10 @@ void main()
// Scaled to widths of the Z texture.
if (object_max_z > 0.0)
// when rendering the overlay
object_z = object_max_z * gl_MultiTexCoord0.y;
object_z = object_max_z * v_tex_coord.y;
else
// when rendering the volumes
object_z = (volume_world_matrix * gl_Vertex).z;
object_z = (volume_world_matrix * vec4(v_position, 1.0)).z;
gl_Position = ftransform();
gl_Position = projection_matrix * position;
}

View File

@ -0,0 +1,8 @@
#version 140
uniform vec4 uniform_color;
out vec4 frag_color;
void main()
{
frag_color = uniform_color;
}

View File

@ -0,0 +1,8 @@
#version 140
in vec3 v_position;
void main()
{
gl_Position = vec4(v_position, 1.0);
}

View File

@ -0,0 +1,9 @@
#version 140
uniform vec4 uniform_color;
out vec4 frag_color;
void main()
{
frag_color = uniform_color;
}

View File

@ -0,0 +1,11 @@
#version 140
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
in vec3 v_position;
void main()
{
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
}

View File

@ -0,0 +1,19 @@
#version 140
uniform mat4 view_matrix;
uniform mat4 projection_matrix;
in vec3 v_position;
// per instance data
// in mat4 instanceMatrix;
in vec4 i_data0;
in vec4 i_data1;
in vec4 i_data2;
in vec4 i_data3;
// end per instance data
void main()
{
mat4 model_matrix = mat4(i_data0, i_data1, i_data2, i_data3);
gl_Position = projection_matrix * view_matrix * model_matrix* vec4(v_position, 1.0);
}

View File

@ -0,0 +1,12 @@
#version 140
uniform sampler2D u_texture;
in vec2 v_texcoord;
out vec4 frag_color;
void main()
{
frag_color = texture(u_texture, v_texcoord);
}

View File

@ -0,0 +1,16 @@
#version 140
in vec3 v_position;
in vec2 v_tex_coord;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 u_uvTransformMatrix;
out vec2 v_texcoord;
void main()
{
v_texcoord = (u_uvTransformMatrix * vec3(v_tex_coord, 1.0)).xy;
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
}

View File

@ -0,0 +1,79 @@
#version 140
uniform vec4 u_viewport_size;
uniform sampler2D u_sampler;
in vec2 tex_coords;
out vec4 frag_color;
// thanks https://github.com/mattdesl/glsl-fxaa
#ifndef FXAA_REDUCE_MIN
#define FXAA_REDUCE_MIN (1.0/ 128.0)
#endif
#ifndef FXAA_REDUCE_MUL
#define FXAA_REDUCE_MUL (1.0 / 8.0)
#endif
#ifndef FXAA_SPAN_MAX
#define FXAA_SPAN_MAX 8.0
#endif
vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 inv_resolution,
vec2 v_rgbNW, vec2 v_rgbNE,
vec2 v_rgbSW, vec2 v_rgbSE,
vec2 v_rgbM) {
vec4 color;
vec2 inverseVP = inv_resolution;
vec3 rgbNW = texture(tex, v_rgbNW).xyz;
vec3 rgbNE = texture(tex, v_rgbNE).xyz;
vec3 rgbSW = texture(tex, v_rgbSW).xyz;
vec3 rgbSE = texture(tex, v_rgbSE).xyz;
vec4 texColor = texture(tex, v_rgbM);
vec3 rgbM = texColor.xyz;
vec3 luma = vec3(0.299, 0.587, 0.114);
float lumaNW = dot(rgbNW, luma);
float lumaNE = dot(rgbNE, luma);
float lumaSW = dot(rgbSW, luma);
float lumaSE = dot(rgbSE, luma);
float lumaM = dot(rgbM, luma);
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
vec2 dir;
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
(0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
dir * rcpDirMin)) * inverseVP;
vec3 rgbA = 0.5 * (
texture(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +
texture(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);
vec3 rgbB = rgbA * 0.5 + 0.25 * (
texture(tex, fragCoord * inverseVP + dir * -0.5).xyz +
texture(tex, fragCoord * inverseVP + dir * 0.5).xyz);
float lumaB = dot(rgbB, luma);
if ((lumaB < lumaMin) || (lumaB > lumaMax))
color = vec4(rgbA, texColor.a);
else
color = vec4(rgbB, texColor.a);
return color;
}
void main()
{
vec2 fragCoord = tex_coords * u_viewport_size.xy;
vec2 add = u_viewport_size.zw;
vec2 rgbNW = tex_coords+vec2(-add.x, -add.y);
vec2 rgbNE = tex_coords+vec2( add.x, -add.y);
vec2 rgbSW = tex_coords+vec2(-add.x, add.y);
vec2 rgbSE = tex_coords+vec2( add.x, add.y);
vec2 rgbM = tex_coords;
frag_color = fxaa(u_sampler, fragCoord, add, rgbNW, rgbNE, rgbSW, rgbSE, rgbM);
}

View File

@ -0,0 +1,12 @@
#version 140
in vec3 v_position;
in vec2 v_tex_coord;
out vec2 tex_coords;
void main()
{
tex_coords = v_tex_coord;
gl_Position = vec4(v_position, 1.0);
}

View File

@ -0,0 +1,34 @@
#version 140
uniform sampler2D u_sampler;
uniform mat3 u_convolution_matrix;
uniform vec2 u_viewport_size;
in vec2 tex_coords;
out vec4 frag_color;
vec4 sample(float offsetX, float offsetY)
{
return texture(u_sampler, vec2(tex_coords.x + offsetX, tex_coords.y + offsetY));
}
void main()
{
vec4 pixels[9];
float deltaWidth = 1.0 / u_viewport_size.x;
float deltaHeight = 1.0 / u_viewport_size.y;
pixels[0] = sample(-deltaWidth, deltaHeight );
pixels[1] = sample(0.0, deltaHeight );
pixels[2] = sample(deltaWidth, deltaHeight );
pixels[3] = sample(-deltaWidth, 0.0);
pixels[4] = sample(0.0, 0.0);
pixels[5] = sample(deltaWidth, 0.0);
pixels[6] = sample(-deltaWidth, -deltaHeight);
pixels[7] = sample(0.0, -deltaHeight);
pixels[8] = sample(deltaWidth, -deltaHeight);
vec4 accumulator = vec4(0.0);
for (int i = 0; i < 9; ++i)
{
accumulator += pixels[i] * u_convolution_matrix[i / 3][i % 3];
}
frag_color = accumulator;
}

View File

@ -0,0 +1,12 @@
#version 140
in vec3 v_position;
in vec2 v_tex_coord;
out vec2 tex_coords;
void main()
{
tex_coords = v_tex_coord;
gl_Position = vec4(v_position, 1.0);
}

View File

@ -0,0 +1,111 @@
#version 140
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
//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);
const float EPSILON = 0.0001;
const float ONE_OVER_EPSILON = 1e4;
struct PrintVolumeDetection
{
// 0 = rectangle, 1 = circle, 2 = custom, 3 = invalid
int type;
// type = 0 (rectangle):
// x = min.x, y = min.y, z = max.x, w = max.y
// type = 1 (circle):
// x = center.x, y = center.y, z = radius
vec4 xy_data;
// x = min z, y = max z
vec2 z_data;
};
struct SlopeDetection
{
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
};
uniform vec4 uniform_color;
uniform SlopeDetection slope;
//BBS: add outline_color
uniform bool is_outline;
uniform bool offset_depth_buffer;
#ifdef ENABLE_ENVIRONMENT_MAP
uniform sampler2D environment_tex;
uniform bool use_environment_tex;
#endif // ENABLE_ENVIRONMENT_MAP
in vec3 clipping_planes_dots;
// x = diffuse, y = specular;
in vec2 intensity;
uniform PrintVolumeDetection print_volume;
uniform vec3 extruder_printable_heights;
in vec4 world_pos;
in float world_normal_z;
in vec3 eye_normal;
out vec4 frag_color;
void main()
{
if (any(lessThan(clipping_planes_dots, ZERO)))
discard;
vec3 color = uniform_color.rgb;
float alpha = uniform_color.a;
if (slope.actived) {
if(world_pos.z<0.1&&world_pos.z>-0.1)
{
color = LightBlue;
alpha = 0.8;
}
else if( world_normal_z < slope.normal_z - EPSILON)
{
color = color * 0.5 + LightRed * 0.5;
alpha = 0.8;
}
}
// if the fragment is outside the print volume -> use darker color
vec3 pv_check_min = (world_pos.xyz - vec3(print_volume.xy_data.x, print_volume.xy_data.y, print_volume.z_data.x)) * ONE_OVER_EPSILON;
vec3 pv_check_max = (world_pos.xyz - vec3(print_volume.xy_data.z, print_volume.xy_data.w, print_volume.z_data.y)) * ONE_OVER_EPSILON;
bool is_out_print_limit =(any(lessThan(pv_check_min, vec3(1.0))) || any(greaterThan(pv_check_max, vec3(1.0))));
if (print_volume.type == 0) {// rectangle
color = is_out_print_limit ? mix(color, ZERO, 0.3333) : color;
}
else if (print_volume.type == 1) {
// circle
float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy);
pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x) * ONE_OVER_EPSILON;
pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y) * ONE_OVER_EPSILON;
color = (any(lessThan(pv_check_min, vec3(1.0))) || any(greaterThan(pv_check_max, vec3(1.0)))) ? mix(color, ZERO, 0.3333) : color;
}
if(extruder_printable_heights.x >= 1.0 ){
pv_check_min = (world_pos.xyz - vec3(print_volume.xy_data.x, print_volume.xy_data.y, extruder_printable_heights.y)) * ONE_OVER_EPSILON;
pv_check_max = (world_pos.xyz - vec3(print_volume.xy_data.z, print_volume.xy_data.w, extruder_printable_heights.z)) * ONE_OVER_EPSILON;
bool is_out_printable_height = (all(greaterThan(pv_check_min, vec3(1.0))) && all(lessThan(pv_check_max, vec3(1.0)))) ;
color = is_out_printable_height ? mix(color, ZERO, 0.7) : color;
}
//BBS: add outline_color
if (is_outline)
frag_color = uniform_color;
#ifdef ENABLE_ENVIRONMENT_MAP
else if (use_environment_tex)
frag_color = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha);
#endif
else
frag_color = vec4(vec3(intensity.y) + color * intensity.x, alpha);
// In the support painting gizmo and the seam painting gizmo are painted triangles rendered over the already
// rendered object. To resolved z-fighting between previously rendered object and painted triangles, values
// inside the depth buffer are offset by small epsilon for painted triangles inside those gizmos.
gl_FragDepth = gl_FragCoord.z - (offset_depth_buffer ? EPSILON : 0.0);
}

View File

@ -1,5 +1,4 @@
#version 130
#version 140
#define INTENSITY_CORRECTION 0.6
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
@ -14,6 +13,9 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION)
//#define LIGHT_FRONT_SHININESS 5.0
const vec3 LIGHT_BACK_DIR = vec3(0.1397015, 0.6985074,0.6985074);
#define LIGHT_BACK_DIFFUSE (0.3 * INTENSITY_CORRECTION)
#define INTENSITY_AMBIENT 0.3
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
@ -25,6 +27,13 @@ struct SlopeDetection
mat3 volume_world_normal_matrix;
};
in vec3 v_position;
in vec3 v_normal;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
uniform mat4 volume_world_matrix;
uniform SlopeDetection slope;
@ -32,48 +41,45 @@ uniform SlopeDetection slope;
uniform vec2 z_range;
// Clipping plane - general orientation. Used by the SLA gizmo.
uniform vec4 clipping_plane;
uniform bool is_text_shape;
// x = diffuse, y = specular;
varying vec2 intensity;
out vec2 intensity;
varying vec3 clipping_planes_dots;
out vec3 clipping_planes_dots;
varying vec4 model_pos;
varying vec4 world_pos;
varying float world_normal_z;
varying vec3 eye_normal;
varying vec3 barycentric_coordinates;
out vec4 model_pos;
out vec4 world_pos;
out float world_normal_z;
out vec3 eye_normal;
void main()
{
// First transform the normal into camera space and normalize the result.
eye_normal = normalize(gl_NormalMatrix * gl_Normal);
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;
vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
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;
model_pos = gl_Vertex;
if(!is_text_shape){
NdotL = max(dot(eye_normal, LIGHT_BACK_DIR), 0.0);
intensity.x += NdotL * LIGHT_BACK_DIFFUSE;
}
// Point in homogenous coordinates.
world_pos = volume_world_matrix * gl_Vertex;
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 * gl_Normal)).z : 0.0;
world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * v_normal)).z : 0.0;
gl_Position = ftransform();
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);
//compute the Barycentric Coordinates
int vertexMod3 = gl_VertexID % 3;
barycentric_coordinates = vec3(float(vertexMod3 == 0), float(vertexMod3 == 1), float(vertexMod3 == 2));
}

View File

@ -0,0 +1,14 @@
#version 140
uniform vec4 uniform_color;
uniform float emission_factor;
// x = tainted, y = specular;
in vec2 intensity;
out vec4 frag_color;
void main()
{
frag_color = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
}

View File

@ -1,4 +1,4 @@
#version 110
#version 140
#define INTENSITY_CORRECTION 0.6
@ -14,25 +14,32 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define INTENSITY_AMBIENT 0.3
in vec3 v_position;
in vec3 v_normal;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
// x = tainted, y = specular;
varying vec2 intensity;
out vec2 intensity;
void main()
{
// First transform the normal into camera space and normalize the result.
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
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;
vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
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 = ftransform();
gl_Position = projection_matrix * position;
}

View File

@ -0,0 +1,67 @@
#version 140
#define INTENSITY_CORRECTION 0.6
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
#define INTENSITY_AMBIENT 0.3
// vertex attributes
in vec3 v_position;
in vec3 v_normal;
// instance attributes
in vec3 i_offset;
in vec2 i_scales;
in mat4 instanceMatrix;
uniform mat4 view_matrix;
uniform mat4 projection_matrix;
// x = tainted, y = specular;
out vec2 intensity;
mat3 inverse_mat3(mat3 m) {
float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
float b01 = a22 * a11 - a12 * a21;
float b11 = -a22 * a10 + a12 * a20;
float b21 = a21 * a10 - a11 * a20;
float det = a00 * b01 + a01 * b11 + a02 * b21;
return mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11),
b11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),
b21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det;
}
void main()
{
mat4 view_model_matrix = view_matrix * instanceMatrix;
// First transform the normal into camera space and normalize the result.
vec3 normal = normalize(transpose(inverse_mat3(mat3(view_model_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;
}

View File

@ -0,0 +1,52 @@
#version 140
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
const vec3 WHITE = vec3(1.0, 1.0, 1.0);
const float ONE_OVER_EPSILON = 1e4;
struct PrintVolumeDetection
{
// 0 = rectangle, 1 = circle, 2 = custom, 3 = invalid
int type;
// type = 0 (rectangle):
// x = min.x, y = min.y, z = max.x, w = max.y
// type = 1 (circle):
// x = center.x, y = center.y, z = radius
vec4 xy_data;
// x = min z, y = max z
vec2 z_data;
};
uniform vec4 uniform_color;
uniform float emission_factor;
uniform PrintVolumeDetection print_volume;
// x = diffuse, y = specular;
in vec2 intensity;
in vec4 world_pos;
out vec4 frag_color;
void main()
{
vec3 color = uniform_color.rgb;
float alpha = uniform_color.a;
// if the fragment is outside the print volume -> use darker color
vec3 pv_check_min = ZERO;
vec3 pv_check_max = ZERO;
if (print_volume.type == 0) {// rectangle
pv_check_min = world_pos.xyz - vec3(print_volume.xy_data.x, print_volume.xy_data.y, print_volume.z_data.x);
pv_check_max = world_pos.xyz - vec3(print_volume.xy_data.z, print_volume.xy_data.w, print_volume.z_data.y);
pv_check_min = pv_check_min * ONE_OVER_EPSILON;
pv_check_max = pv_check_max * ONE_OVER_EPSILON;
color = (any(lessThan(pv_check_min, vec3(1.0))) || any(greaterThan(pv_check_max, vec3(1.0)))) ? mix(color, WHITE, 0.3333) : color;
}
else if (print_volume.type == 1) {// circle
float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy);
pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x);
pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y);
pv_check_min = pv_check_min * ONE_OVER_EPSILON;
pv_check_max = pv_check_max * ONE_OVER_EPSILON;
color = (any(lessThan(pv_check_min, vec3(1.0))) || any(greaterThan(pv_check_max, vec3(1.0)))) ? mix(color, WHITE, 0.3333) : color;
}
frag_color = vec4(vec3(intensity.y) + color * (intensity.x + emission_factor), alpha);
}

View File

@ -0,0 +1,47 @@
#version 140
#define INTENSITY_CORRECTION 0.6
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
#define INTENSITY_AMBIENT 0.3
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 view_normal_matrix;
uniform mat4 volume_world_matrix;
in vec3 v_position;
in vec3 v_normal;
// x = tainted, y = specular;
out vec2 intensity;
out vec4 world_pos;
void main()
{
// First transform the normal into camera space and normalize the result.
vec3 normal = normalize(view_normal_matrix * v_normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
world_pos = volume_world_matrix * vec4(v_position, 1.0);
vec4 position = view_model_matrix * vec4(v_position, 1.0);
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
gl_Position = projection_matrix * position;
}

View File

@ -0,0 +1,12 @@
#version 140
uniform sampler2D Texture;
in vec2 Frag_UV;
in vec4 color;
out vec4 frag_color;
void main()
{
frag_color = color * texture(Texture, Frag_UV.st);
}

View File

@ -0,0 +1,17 @@
#version 140
uniform mat4 ProjMtx;
in vec2 Position;
in vec2 UV;
in vec4 Color;
out vec2 Frag_UV;
out vec4 color;
void main()
{
Frag_UV = UV;
color = Color;
gl_Position = ProjMtx * vec4(Position.xy, 0.0, 1.0);
}

View File

@ -0,0 +1,12 @@
#version 140
uniform sampler2D u_sampler;
in vec2 tex_coords;
out vec4 frag_color;
void main()
{
frag_color = texture(u_sampler, tex_coords);
}

View File

@ -0,0 +1,12 @@
#version 140
in vec3 v_position;
in vec2 v_tex_coord;
out vec2 tex_coords;
void main()
{
tex_coords = v_tex_coord;
gl_Position = vec4(v_position, 1.0);
}

View File

@ -0,0 +1,12 @@
#version 140
const float EPSILON = 0.0001;
out vec4 frag_color;
void main()
{
frag_color = vec4(1.0, 1.0, 1.0, 1.0);
// 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;
}

View File

@ -0,0 +1,11 @@
#version 140
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
in vec3 v_position;
void main()
{
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
}

View File

@ -1,4 +1,4 @@
#version 110
#version 140
#define INTENSITY_CORRECTION 0.6
@ -23,9 +23,9 @@ const vec3 LightRed = vec3(0.78, 0.0, 0.0);
const vec3 LightBlue = vec3(0.73, 1.0, 1.0);
uniform vec4 uniform_color;
varying vec3 clipping_planes_dots;
varying vec4 model_pos;
varying vec4 world_pos;
in vec3 clipping_planes_dots;
in vec3 model_pos;
in vec4 world_pos;
uniform bool volume_mirrored;
struct SlopeDetection
@ -36,6 +36,32 @@ struct SlopeDetection
};
uniform SlopeDetection slope;
//BBS: add wireframe logic
in vec3 barycentric_coordinates;
float edgeFactor(float lineWidth) {
vec3 d = fwidth(barycentric_coordinates);
vec3 a3 = smoothstep(vec3(0.0), d * lineWidth, barycentric_coordinates);
return min(min(a3.x, a3.y), a3.z);
}
vec3 wireframe(vec3 fill, vec3 stroke, float lineWidth) {
return mix(stroke, fill, edgeFactor(lineWidth));
//if (any(lessThan(barycentric_coordinates, vec3(0.005, 0.005, 0.005))))
// return vec3(1.0, 0.0, 0.0);
//else
// return fill;
}
vec3 getWireframeColor(vec3 fill) {
float brightness = 0.2126 * fill.r + 0.7152 * fill.g + 0.0722 * fill.b;
return (brightness > 0.75) ? vec3(0.11, 0.165, 0.208) : vec3(0.988, 0.988, 0.988);
}
uniform bool show_wireframe;
uniform mat4 view_model_matrix;
uniform mat3 normal_matrix;
out vec4 frag_color;
void main()
{
if (any(lessThan(clipping_planes_dots, ZERO)))
@ -62,8 +88,9 @@ void main()
alpha = 1.0;
}
}
// First transform the normal into camera space and normalize the result.
vec3 eye_normal = normalize(gl_NormalMatrix * triangle_normal);
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.
@ -72,12 +99,19 @@ void main()
// x = diffuse, y = specular;
vec2 intensity = vec2(0.0, 0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec3 position = (gl_ModelViewMatrix * model_pos).xyz;
vec3 position = (view_model_matrix * vec4(model_pos, 1.0)).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);
if (show_wireframe) {
vec3 wireframeColor = show_wireframe ? getWireframeColor(color) : color;
vec3 triangleColor = wireframe(color, wireframeColor, 1.0);
frag_color = vec4(vec3(intensity.y) + triangleColor * intensity.x, alpha);
}
else {
frag_color = vec4(vec3(intensity.y) + color * intensity.x, alpha);
}
}

View File

@ -0,0 +1,47 @@
#version 140
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
//attribute vec3 v_position;
//attribute vec3 v_barycentric;
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;
in vec3 v_position;
in vec3 v_color;
out vec3 clipping_planes_dots;
out vec3 model_pos;
out vec4 world_pos;
out vec3 barycentric_coordinates;
struct SlopeDetection
{
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
};
uniform SlopeDetection slope;
void main()
{
model_pos = v_position;
//model_pos = vec4(v_position, 1.0);
// Point in homogenous coordinates.
world_pos = volume_world_matrix * vec4(model_pos, 1.0);
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
//gl_Position = gl_ModelViewProjectionMatrix * vec4(v_position, 1.0);
// 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);
//compute the Barycentric Coordinates
//int vertexMod3 = gl_VertexID % 3;
//barycentric_coordinates = vec3(float(vertexMod3 == 0), float(vertexMod3 == 1), float(vertexMod3 == 2));
barycentric_coordinates = v_color.xyz;//v_barycentric
}

View File

@ -0,0 +1,29 @@
#version 140
const vec3 back_color_dark = vec3(0.235, 0.235, 0.235);
const vec3 back_color_light = vec3(0.365, 0.365, 0.365);
uniform sampler2D u_sampler;
uniform bool transparent_background;
uniform bool svg_source;
in vec2 tex_coord;
out vec4 frag_color;
vec4 svg_color(vec2 uv)
{
// takes foreground from u_sampler
vec4 fore_color = texture(u_sampler, uv);
// calculates radial gradient
vec3 back_color = vec3(mix(back_color_light, back_color_dark, smoothstep(0.0, 0.5, length(abs(uv) - 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);
}
vec4 non_svg_color(vec2 uv)
{
// takes foreground from u_sampler
vec4 color = texture(u_sampler, uv);
return vec4(color.rgb, transparent_background ? color.a * 0.25 : color.a);
}
void main()
{
// flip uv
vec2 uv = vec2(tex_coord.x, 1.0 - tex_coord.y);
frag_color = svg_source ? svg_color(uv) : non_svg_color(uv);
}

View File

@ -0,0 +1,15 @@
#version 140
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
in vec3 v_position;
in vec2 v_tex_coord;
out vec2 tex_coord;
void main()
{
tex_coord = v_tex_coord;
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
}

View File

@ -0,0 +1,8 @@
#version 140
uniform vec4 u_base_color;
out vec4 frag_color;
void main()
{
frag_color = u_base_color;
}

View File

@ -0,0 +1,11 @@
#version 140
uniform mat4 u_model_matrix;
uniform mat4 u_view_projection_matrix;
in vec3 v_position;
void main()
{
gl_Position = u_view_projection_matrix * u_model_matrix * vec4(v_position, 1.0);
}

View File

@ -0,0 +1,41 @@
#version 140
uniform sampler2D u_sampler;
uniform mat3 u_convolution_matrix;
uniform vec2 u_viewport_size;
in vec2 tex_coords;
out vec4 frag_color;
vec4 sample(float offsetX, float offsetY)
{
return texture(u_sampler, vec2(tex_coords.x + offsetX, tex_coords.y + offsetY));
}
void main()
{
vec4 pixels[9];
float deltaWidth = 1.0 / u_viewport_size.x;
float deltaHeight = 1.0 / u_viewport_size.y;
float effect_width = 1.0f;
deltaWidth = deltaWidth * effect_width;
deltaWidth = deltaWidth * effect_width;
pixels[0] = sample(-deltaWidth, deltaHeight );
pixels[1] = sample(0.0, deltaHeight );
pixels[2] = sample(deltaWidth, deltaHeight );
pixels[3] = sample(-deltaWidth, 0.0);
pixels[4] = sample(0.0, 0.0);
pixels[5] = sample(deltaWidth, 0.0);
pixels[6] = sample(-deltaWidth, -deltaHeight);
pixels[7] = sample(0.0, -deltaHeight);
pixels[8] = sample(deltaWidth, -deltaHeight);
vec4 accumulator = vec4(0.0);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; ++j)
{
accumulator += pixels[3 * i + j] * u_convolution_matrix[i][j];
}
}
frag_color = accumulator;
}

View File

@ -0,0 +1,12 @@
#version 140
in vec3 v_position;
in vec2 v_tex_coord;
out vec2 tex_coords;
void main()
{
tex_coords = v_tex_coord;
gl_Position = vec4(v_position, 1.0);
}

View File

@ -0,0 +1,23 @@
#version 140
uniform bool ban_light;
uniform vec4 uniform_color;
uniform float emission_factor;
// x = tainted, y = specular;
in vec2 intensity;
//varying float drop;
in vec4 world_pos;
out vec4 frag_color;
void main()
{
if (world_pos.z < 0.0)
discard;
if(ban_light){
frag_color = uniform_color;
} else{
frag_color = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
}
}

View File

@ -0,0 +1,50 @@
#version 140
#define INTENSITY_CORRECTION 0.6
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
#define INTENSITY_AMBIENT 0.3
in vec3 v_position;
in 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;
out vec2 intensity;
out 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 * vec4(v_position, 1.0);
gl_Position = projection_matrix * position;
}

View File

@ -0,0 +1,30 @@
#version 140
// 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);
const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0);
// x = ambient, y = top diffuse, z = front diffuse, w = global
uniform vec4 light_intensity;
uniform vec4 uniform_color;
in vec3 eye_normal;
out vec4 frag_color;
void main()
{
vec3 normal = normalize(eye_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. Take the abs value to light the lines no matter in which direction the normal points.
float NdotL = abs(dot(normal, LIGHT_TOP_DIR));
float intensity = light_intensity.x + NdotL * light_intensity.y;
// Perform the same lighting calculation for the 2nd light source.
NdotL = abs(dot(normal, LIGHT_FRONT_DIR));
intensity += NdotL * light_intensity.z;
frag_color = vec4(uniform_color.rgb * light_intensity.w * intensity, uniform_color.a);
}

View File

@ -0,0 +1,16 @@
#version 140
in vec3 v_position;
in vec3 v_normal;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
out vec3 eye_normal;
void main()
{
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
eye_normal = normal_matrix * v_normal;
}

View File

@ -0,0 +1,43 @@
#version 140
#define M_PI 3.1415926535897932384626433832795
// 2D texture (1D texture split by the rows) of color along the object Z axis.
uniform sampler2D z_texture;
// Scaling from the Z texture rows coordinate to the normalized texture row coordinate.
uniform float z_to_texture_row;
uniform float z_texture_row_to_normalized;
uniform float z_cursor;
uniform float z_cursor_band_width;
// x = tainted, y = specular;
in vec2 intensity;
in float object_z;
out vec4 frag_color;
void main()
{
float object_z_row = z_to_texture_row * object_z;
// Index of the row in the texture.
float z_texture_row = floor(object_z_row);
// Normalized coordinate from 0. to 1.
float z_texture_col = object_z_row - z_texture_row;
float z_blend = 0.25 * cos(min(M_PI, abs(M_PI * (object_z - z_cursor) * 1.8 / z_cursor_band_width))) + 0.25;
// Calculate level of detail from the object Z coordinate.
// This makes the slowly sloping surfaces to be shown with high detail (with stripes),
// and the vertical surfaces to be shown with low detail (no stripes)
float z_in_cells = object_z_row * 190.;
// Gradient of Z projected on the screen.
float dx_vtc = dFdx(z_in_cells);
float dy_vtc = dFdy(z_in_cells);
float lod = clamp(0.5 * log2(max(dx_vtc * dx_vtc, dy_vtc * dy_vtc)), 0., 1.);
// Sample the Z texture. Texture coordinates are normalized to <0, 1>.
vec4 color = vec4(0.25, 0.25, 0.25, 1.0);
if (z_texture_row >= 0.0)
color = mix(texture(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row + 0.5 )), -10000.),
texture(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row * 2. + 1.)), 10000.), lod);
// Mix the final color.
frag_color = vec4(vec3(intensity.y), 1.0) + intensity.x * mix(color, vec4(1.0, 1.0, 0.0, 1.0), z_blend);
}

View File

@ -0,0 +1,60 @@
#version 140
#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
in vec3 v_position;
in vec3 v_normal;
in 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;
out vec2 intensity;
out float object_z;
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)
NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
// Scaled to widths of the Z texture.
if (object_max_z > 0.0)
// when rendering the overlay
object_z = object_max_z * v_tex_coord.y;
else
// when rendering the volumes
object_z = (volume_world_matrix * vec4(v_position, 1.0)).z;
gl_Position = projection_matrix * position;
}

View File

@ -1,6 +0,0 @@
#version 110
void main()
{
gl_Position = ftransform();
}

View File

@ -1,124 +0,0 @@
#version 130
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
//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 float EPSILON = 0.0001;
struct PrintVolumeDetection
{
// 0 = rectangle, 1 = circle, 2 = custom, 3 = invalid
int type;
// type = 0 (rectangle):
// x = min.x, y = min.y, z = max.x, w = max.y
// type = 1 (circle):
// x = center.x, y = center.y, z = radius
vec4 xy_data;
// x = min z, y = max z
vec2 z_data;
};
struct SlopeDetection
{
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
};
//BBS: add wireframe logic
varying vec3 barycentric_coordinates;
float edgeFactor(float lineWidth) {
vec3 d = fwidth(barycentric_coordinates);
vec3 a3 = smoothstep(vec3(0.0), d * lineWidth, barycentric_coordinates);
return min(min(a3.x, a3.y), a3.z);
}
vec3 wireframe(vec3 fill, vec3 stroke, float lineWidth) {
return mix(stroke, fill, edgeFactor(lineWidth));
}
vec3 getWireframeColor(vec3 fill) {
float brightness = 0.2126 * fill.r + 0.7152 * fill.g + 0.0722 * fill.b;
return (brightness > 0.75) ? vec3(0.11, 0.165, 0.208) : vec3(0.988, 0.988, 0.988);
}
uniform vec4 uniform_color;
uniform SlopeDetection slope;
//BBS: add outline_color
uniform bool is_outline;
uniform bool show_wireframe;
uniform bool offset_depth_buffer;
#ifdef ENABLE_ENVIRONMENT_MAP
uniform sampler2D environment_tex;
uniform bool use_environment_tex;
#endif // ENABLE_ENVIRONMENT_MAP
varying vec3 clipping_planes_dots;
// x = diffuse, y = specular;
varying vec2 intensity;
uniform PrintVolumeDetection print_volume;
varying vec4 model_pos;
varying vec4 world_pos;
varying float world_normal_z;
varying vec3 eye_normal;
void main()
{
if (any(lessThan(clipping_planes_dots, ZERO)))
discard;
vec3 color = uniform_color.rgb;
float alpha = uniform_color.a;
if (slope.actived && world_normal_z < slope.normal_z - EPSILON) {
//color = vec3(0.7, 0.7, 1.0);
color = ORANGE;
alpha = 1.0;
}
// if the fragment is outside the print volume -> use darker color
vec3 pv_check_min = ZERO;
vec3 pv_check_max = ZERO;
if (print_volume.type == 0) {
// rectangle
pv_check_min = world_pos.xyz - vec3(print_volume.xy_data.x, print_volume.xy_data.y, print_volume.z_data.x);
pv_check_max = world_pos.xyz - vec3(print_volume.xy_data.z, print_volume.xy_data.w, print_volume.z_data.y);
color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
}
else if (print_volume.type == 1) {
// circle
float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy);
pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x);
pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y);
color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
}
//BBS: add outline_color
if (is_outline)
gl_FragColor = uniform_color;
#ifdef ENABLE_ENVIRONMENT_MAP
else if (use_environment_tex)
gl_FragColor = vec4(0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha);
#endif
else {
//gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
if (show_wireframe) {
vec3 wireframeColor = show_wireframe ? getWireframeColor(color) : color;
vec3 triangleColor = wireframe(color, wireframeColor, 1.0);
gl_FragColor = vec4(vec3(intensity.y) + triangleColor * intensity.x, alpha);
}
else {
gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
}
}
// In the support painting gizmo and the seam painting gizmo are painted triangles rendered over the already
// rendered object. To resolved z-fighting between previously rendered object and painted triangles, values
// inside the depth buffer are offset by small epsilon for painted triangles inside those gizmos.
gl_FragDepth = gl_FragCoord.z - (offset_depth_buffer ? EPSILON : 0.0);
}

View File

@ -1,12 +0,0 @@
#version 110
uniform vec4 uniform_color;
uniform float emission_factor;
// x = tainted, y = specular;
varying vec2 intensity;
void main()
{
gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
}

View File

@ -1,6 +0,0 @@
#version 110
void main()
{
gl_Position = ftransform();
}

View File

@ -1,30 +0,0 @@
#version 110
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
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 = gl_Vertex;
// Point in homogenous coordinates.
world_pos = volume_world_matrix * gl_Vertex;
gl_Position = ftransform();
// 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);
}

View File

@ -1,8 +0,0 @@
#version 110
uniform vec4 uniform_color;
void main()
{
gl_FragColor = uniform_color;
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -1,10 +0,0 @@
#version 110
const vec3 ORANGE = vec3(0.8, 0.4, 0.0);
uniform vec4 uniform_color;
void main()
{
gl_FragColor = uniform_color;
//gl_FragColor = vec4(ORANGE, 1.0);
}

View File

@ -1,12 +0,0 @@
#version 110
attribute vec4 v_position;
attribute vec2 v_tex_coords;
varying vec2 tex_coords;
void main()
{
gl_Position = ftransform();
tex_coords = v_tex_coords;
}

View File

@ -1,9 +0,0 @@
#version 110
varying vec3 eye_normal;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
eye_normal = gl_NormalMatrix * gl_Normal;
}

View File

@ -5199,7 +5199,7 @@ int CLI::run(int argc, char **argv)
//opengl related
Slic3r::GUI::OpenGLManager opengl_mgr;
GLShaderProgram* shader = nullptr;
std::shared_ptr<GLShaderProgram> shader = nullptr;
GLVolumeCollection glvolume_collection;
bool opengl_valid = false;
const ConfigOptionStrings* filament_color = dynamic_cast<const ConfigOptionStrings *>(m_print_config.option("filament_colour"));
@ -5883,6 +5883,7 @@ int CLI::run(int argc, char **argv)
auto cli_generate_thumbnails = [&partplate_list, &model, &glvolume_collection, &colors_out, &shader, &opengl_mgr](const ThumbnailsParams& params) -> ThumbnailsList{
ThumbnailsList thumbnails;
opengl_mgr.bind_vao();
opengl_mgr.bind_shader(shader);
for (const Vec2d& size : params.sizes) {
thumbnails.push_back(ThumbnailData());
Point isize(size); // round to ints
@ -5912,6 +5913,7 @@ int CLI::run(int argc, char **argv)
if (!thumbnails.back().is_valid())
thumbnails.pop_back();
}
opengl_mgr.unbind_shader();
opengl_mgr.unbind_vao();
return thumbnails;
};
@ -6423,6 +6425,7 @@ int CLI::run(int argc, char **argv)
if (opengl_valid) {
Model &model = m_models[0];
opengl_mgr.bind_vao();
opengl_mgr.bind_shader(shader);
for (int i = 0; i < partplate_list.get_plate_count(); i++) {
Slic3r::GUI::PartPlate *part_plate = partplate_list.get_plate(i);
PlateData *plate_data = plate_data_list[i];
@ -6654,7 +6657,7 @@ int CLI::run(int argc, char **argv)
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%: add thumbnail data for top and pick into group")%(i+1);
}
}
opengl_mgr.unbind_shader();
opengl_mgr.unbind_vao();
}
}

View File

@ -201,6 +201,12 @@ void AppConfig::set_defaults()
if (get("prefer_to_use_dgpu").empty())
set_bool("prefer_to_use_dgpu", false);
if (get("msaa_type").empty())
set("msaa_type", "X4");
if (get("enable_advanced_antialiasing").empty())
set_bool("enable_advanced_antialiasing", true);
if (get("show_3d_navigator").empty())
set_bool("show_3d_navigator", true);

View File

@ -1,18 +1,76 @@
#include "Frustum.hpp"
#include <cmath>
namespace Slic3r {
void Frustum::Plane::set_abcd(float a, float b, float c, float d)
{
m_abcd[0] = a;
m_abcd[1] = b;
m_abcd[2] = c;
m_abcd[3] = d;
}
const Vec4f& Frustum::Plane::get_abcd() const
{
return m_abcd;
}
void Frustum::Plane::normailze()
{
float mag;
mag = sqrt(m_abcd[0] * m_abcd[0] + m_abcd[1] * m_abcd[1] + m_abcd[2] * m_abcd[2]);
m_abcd[0] = m_abcd[0] / mag;
m_abcd[1] = m_abcd[1] / mag;
m_abcd[2] = m_abcd[2] / mag;
m_abcd[3] = m_abcd[3] / mag;
}
float Frustum::Plane::distance(const Vec3f& pt) const
{
float result = 0.0f;
for (int i = 0; i < 3; ++i) {
result += pt[i] * m_abcd[i];
}
result += m_abcd[3];
return result;
}
Frustum::Plane::PlaneIntersects Frustum::Plane::intersects(const BoundingBoxf3 &box) const
{
Vec3f center = ((box.min + box.max) * 0.5f).cast<float>();
Vec3f extent = ((box.max - box.min) * 0.5f).cast<float>();
float d = distance(center);
float r = fabsf(extent.x() * normal_.x()) + fabsf(extent.y() * normal_.y()) + fabsf(extent.z() * normal_.z());
if (d == r) {
return Plane::Intersects_Tangent;
} else if (std::abs(d) < r) {
return Plane::Intersects_Cross;
// see https://cgvr.cs.uni-bremen.de/teaching/cg_literatur/lighthouse3d_view_frustum_culling/index.html
Vec3d positive_v = box.min;
if (m_abcd[0] > 0.f)
positive_v[0] = box.max.x();
if (m_abcd[1] > 0.f)
positive_v[1] = box.max.y();
if (m_abcd[2] > 0.f)
positive_v[2] = box.max.z();
float dis_positive = distance(positive_v.cast<float>());
if (dis_positive < 0.f)
{
return Frustum::Plane::PlaneIntersects::Intersects_Back;
}
return (d > 0.0f) ? Plane::Intersects_Front : Plane::Intersects_Back;
Vec3d negitive_v = box.max;
if (m_abcd[0] > 0.f)
negitive_v[0] = box.min.x();
if (m_abcd[1] > 0.f)
negitive_v[1] = box.min.y();
if (m_abcd[2] > 0.f)
negitive_v[2] = box.min.z();
float dis_negitive = distance(negitive_v.cast<float>());
if (dis_negitive < 0.f)
{
return Frustum::Plane::PlaneIntersects::Intersects_Cross;
}
return Frustum::Plane::PlaneIntersects::Intersects_Front;
}
Frustum::Plane::PlaneIntersects Frustum::Plane::intersects(const Vec3f &p0) const
{
@ -51,19 +109,15 @@ Frustum::Plane::PlaneIntersects Frustum::Plane::intersects(const Vec3f &p0, cons
return Plane::Intersects_Tangent;
}
bool Frustum::intersects(const BoundingBoxf3 &box, bool is_perspective) const
bool Frustum::intersects(const BoundingBoxf3 &box) const
{
if (is_perspective) {
for (auto &plane : planes) {
if (plane.intersects(box) == Plane::Intersects_Back) {
return false;
}
for (auto& plane : planes) {
const auto rt = plane.intersects(box);
if (Frustum::Plane::Intersects_Back == rt) {
return false;
}
}
// check box intersects
if (!bbox.intersects(box)) {
return false;
}
return true;
}

View File

@ -13,17 +13,13 @@ public:
class Plane {
public:
enum PlaneIntersects { Intersects_Cross = 0, Intersects_Tangent = 1, Intersects_Front = 2, Intersects_Back = 3 };
void set(const Vec3f &n, const Vec3f &pt)
{
normal_ = n.normalized();
center_ = pt;
d_ = -normal_.dot(pt);
}
float distance(const Vec3f &pt) const { return normal_.dot(pt) + d_; }
void set_abcd(float a, float b, float c, float d);
const Vec4f& get_abcd() const;
void normailze();
float distance(const Vec3f& pt) const;
inline const Vec3f &getNormal() const { return normal_; }
const Vec3f & getCenter() const { return center_; }
Plane::PlaneIntersects intersects(const BoundingBoxf3 &box) const;
//// check intersect with point (world space)
Plane::PlaneIntersects intersects(const Vec3f &p0) const;
@ -32,12 +28,10 @@ public:
// check intersect with triangle (world space)
Plane::PlaneIntersects intersects(const Vec3f &p0, const Vec3f &p1, const Vec3f &p2) const;
private:
Vec3f normal_;
Vec3f center_;
float d_ = 0;
Vec4f m_abcd;
};
bool intersects(const BoundingBoxf3 &box, bool is_perspective) const;
bool intersects(const BoundingBoxf3 &box) const;
// check intersect with point (world space)
bool intersects(const Vec3f &p0) const;
// check intersect with line segment (world space)
@ -46,18 +40,6 @@ public:
bool intersects(const Vec3f &p0, const Vec3f &p1, const Vec3f &p2) const;
Plane planes[6];
/* corners[0]: nearTopLeft;
* corners[1]: nearTopRight;
* corners[2]: nearBottomLeft;
* corners[3]: nearBottomRight;
* corners[4]: farTopLeft;
* corners[5]: farTopRight;
* corners[6]: farBottomLeft;
* corners[7]: farBottomRight;
*/
Vec3f corners[8];
BoundingBoxf3 bbox;
};
enum FrustumClipMask {

View File

@ -152,38 +152,41 @@ void Bed3D::load_render_colors()
void Bed3D::Axes::render() const
{
auto render_axis = [this](const Transform3f& transform) {
glsafe(::glPushMatrix());
glsafe(::glMultMatrixf(transform.data()));
m_arrow.render();
glsafe(::glPopMatrix());
auto render_axis = [this](const Transform3d& transform, const std::shared_ptr<GLShaderProgram>& shader) {
const Camera& camera = wxGetApp().plater()->get_camera();
Transform3d view_matrix = camera.get_view_matrix();
const Transform3d view_model_matrix = view_matrix * transform;
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_arrow.render_geometry();
};
if (!m_arrow.is_initialized())
const_cast<GLModel*>(&m_arrow)->init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length));
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
const auto& shader = wxGetApp().get_shader("gouraud_light");
if (shader == nullptr)
return;
glsafe(::glEnable(GL_DEPTH_TEST));
shader->start_using();
wxGetApp().bind_shader(shader);
shader->set_uniform("emission_factor", 0.0f);
// x axis
const_cast<GLModel*>(&m_arrow)->set_color(-1, AXIS_X_COLOR);
render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }).cast<float>());
render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }), shader);
// y axis
const_cast<GLModel*>(&m_arrow)->set_color(-1, AXIS_Y_COLOR);
render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }).cast<float>());
render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }), shader);
// z axis
const_cast<GLModel*>(&m_arrow)->set_color(-1, AXIS_Z_COLOR);
render_axis(Geometry::assemble_transform(m_origin).cast<float>());
render_axis(Geometry::assemble_transform(m_origin), shader);
shader->stop_using();
wxGetApp().unbind_shader();
glsafe(::glDisable(GL_DEPTH_TEST));
}
@ -548,9 +551,9 @@ void Bed3D::render_system(GLCanvas3D& canvas, bool bottom) const
}
if (m_triangles.get_vertices_count() > 0) {
GLShaderProgram* shader = wxGetApp().get_shader("printbed");
const auto& shader = wxGetApp().get_shader("printbed");
if (shader != nullptr) {
shader->start_using();
wxGetApp().bind_shader(shader);
shader->set_uniform("transparent_background", bottom);
shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg"));
@ -613,7 +616,7 @@ void Bed3D::render_system(GLCanvas3D& canvas, bool bottom) const
if (bottom)
glsafe(::glDepthMask(GL_TRUE));
shader->stop_using();
wxGetApp().unbind_shader();
}
}
}*/
@ -689,9 +692,9 @@ void Bed3D::render_model() const
const Camera & camera = wxGetApp().plater()->get_camera();
const Transform3d &view_matrix = camera.get_view_matrix();
const Transform3d &projection_matrix = camera.get_projection_matrix();
GLShaderProgram* shader = wxGetApp().get_shader("hotbed");
const auto& shader = wxGetApp().get_shader("hotbed");
if (shader != nullptr) {
shader->start_using();
wxGetApp().bind_shader(shader);
shader->set_uniform("emission_factor", 0.0f);
const Transform3d model_matrix = Geometry::assemble_transform(m_model_offset);
shader->set_uniform("volume_world_matrix", model_matrix);
@ -713,7 +716,7 @@ void Bed3D::render_model() const
shader->set_uniform("print_volume.type", -1);
}
model->render_geometry();
shader->stop_using();
wxGetApp().unbind_shader();
}
}
}

View File

@ -254,17 +254,26 @@ void GLIndexedVertexArray::release_geometry()
this->clear();
}
void GLIndexedVertexArray::render() const
void GLIndexedVertexArray::render(const std::shared_ptr<GLShaderProgram>& shader) const
{
assert(this->vertices_and_normals_interleaved_VBO_id != 0);
assert(this->triangle_indices_VBO_id != 0 || this->quad_indices_VBO_id != 0);
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
int position_id = -1;
int normal_id = -1;
position_id = shader->get_attrib_location("v_position");
if (position_id != -1) {
glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
glsafe(::glEnableVertexAttribArray(position_id));
}
normal_id = shader->get_attrib_location("v_normal");
if (normal_id != -1) {
glsafe(::glVertexAttribPointer(normal_id, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), nullptr));
glsafe(::glEnableVertexAttribArray(normal_id));
}
// Render using the Vertex Buffer Objects.
if (this->triangle_indices_size > 0) {
@ -278,30 +287,50 @@ void GLIndexedVertexArray::render() const
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
if (position_id != -1) {
glsafe(::glDisableVertexAttribArray(position_id));
}
if (normal_id != -1) {
glsafe(::glDisableVertexAttribArray(normal_id));
}
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
void GLIndexedVertexArray::render(
const std::shared_ptr<GLShaderProgram>& shader,
const std::pair<size_t, size_t>& tverts_range,
const std::pair<size_t, size_t>& qverts_range) const
{
// this method has been called before calling finalize() ?
if (this->vertices_and_normals_interleaved_VBO_id == 0 && !this->vertices_and_normals_interleaved.empty())
if (0 == vertices_and_normals_interleaved_VBO_id) {
if (!vertices_and_normals_interleaved.empty()) {
BOOST_LOG_TRIVIAL(info) << boost::format("finalize_geometry");
const_cast<GLIndexedVertexArray*>(this)->finalize_geometry(true);
}
}
if (0 == vertices_and_normals_interleaved_VBO_id) {
return;
}
assert(this->vertices_and_normals_interleaved_VBO_id != 0);
assert(this->triangle_indices_VBO_id != 0 || this->quad_indices_VBO_id != 0);
if (0 == triangle_indices_VBO_id && 0 == quad_indices_VBO_id) {
return;
}
// Render using the Vertex Buffer Objects.
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr));
int position_id = -1;
int normal_id = -1;
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
position_id = shader->get_attrib_location("v_position");
if (position_id != -1) {
glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
glsafe(::glEnableVertexAttribArray(position_id));
}
normal_id = shader->get_attrib_location("v_normal");
if (normal_id != -1) {
glsafe(::glVertexAttribPointer(normal_id, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), nullptr));
glsafe(::glEnableVertexAttribArray(normal_id));
}
if (this->triangle_indices_size > 0) {
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id));
@ -314,8 +343,12 @@ void GLIndexedVertexArray::render(
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
if (position_id != -1) {
glsafe(::glDisableVertexAttribArray(position_id));
}
if (normal_id != -1) {
glsafe(::glDisableVertexAttribArray(normal_id));
}
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
@ -324,12 +357,21 @@ const float GLVolume::SinkingContours::HalfWidth = 0.25f;
void GLVolume::SinkingContours::render()
{
const auto& shader = GUI::wxGetApp().get_shader("flat");
if (!shader) {
return;
}
GUI::wxGetApp().bind_shader(shader);
update();
glsafe(::glPushMatrix());
glsafe(::glTranslated(m_shift.x(), m_shift.y(), m_shift.z()));
m_model.render();
glsafe(::glPopMatrix());
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_geometry();
GUI::wxGetApp().unbind_shader();
}
void GLVolume::SinkingContours::update()
@ -483,6 +525,7 @@ GLVolume::GLVolume(float r, float g, float b, float a, bool create_index_data)
, force_native_color(false)
, force_neutral_color(false)
, force_sinking_contours(false)
, picking(false)
, tverts_range(0, size_t(-1))
, qverts_range(0, size_t(-1))
, tverts_range_lod(0, size_t(-1))
@ -777,7 +820,7 @@ void GLVolume::set_range(double min_z, double max_z)
this->qverts_range.first = this->offsets[i * 2];
this->tverts_range.first = this->offsets[i * 2 + 1];
// Some layers are above $min_z. Which?
for (; i < this->print_zs.size() && this->print_zs[i] <= max_z; ++ i);
for (; i < this->print_zs.size() && this->print_zs[i] <= max_z; ++ i);
if (i < this->print_zs.size()) {
this->qverts_range.second = this->offsets[i * 2];
this->tverts_range.second = this->offsets[i * 2 + 1];
@ -789,7 +832,7 @@ void GLVolume::set_range(double min_z, double max_z)
//BBS: add outline related logic
//static unsigned char stencil_data[1284][2944];
void GLVolume::render(bool with_outline, const std::array<float, 4>& body_color) const
void GLVolume::render(const Transform3d& view_matrix, bool with_outline, const std::array<float, 4>& body_color) const
{
if (!is_active)
return;
@ -797,7 +840,6 @@ void GLVolume::render(bool with_outline, const std::array<float, 4>& body_color)
if (this->is_left_handed())
glFrontFace(GL_CW);
glsafe(::glCullFace(GL_BACK));
glsafe(::glPushMatrix());
auto camera = GUI::wxGetApp().plater()->get_camera();
auto zoom = camera.get_zoom();
Transform3d vier_mat = camera.get_view_matrix();
@ -845,8 +887,8 @@ void GLVolume::render(bool with_outline, const std::array<float, 4>& body_color)
}
} while (0);
if (color_volume) {
GLShaderProgram* shader = GUI::wxGetApp().get_current_shader();
const auto shader = GUI::wxGetApp().get_current_shader();
if (color_volume && !picking) {
std::vector<std::array<float, 4>> colors = GUI::wxGetApp().plater()->get_extruders_colors();
//when force_transparent, we need to keep the alpha
@ -854,7 +896,6 @@ void GLVolume::render(bool with_outline, const std::array<float, 4>& body_color)
for (int index = 0; index < colors.size(); index ++)
colors[index][3] = render_color[3];
}
glsafe(::glMultMatrixd(world_matrix().data()));
for (int idx = 0; idx < mmuseg_ivas.size(); idx++) {
GLIndexedVertexArray* iva = &mmuseg_ivas[idx];
if (iva->triangle_indices_size == 0 && iva->quad_indices_size == 0)
@ -886,7 +927,7 @@ void GLVolume::render(bool with_outline, const std::array<float, 4>& body_color)
}
}
}
iva->render(this->tverts_range, this->qverts_range);
iva->render(shader, this->tverts_range, this->qverts_range);
/*if (force_native_color && (render_color[3] < 1.0)) {
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__<< boost::format(", this %1%, name %2%, tverts_range {%3,%4}, qverts_range{%5%, %6%}")
%this %this->name %this->tverts_range.first %this->tverts_range.second
@ -895,20 +936,18 @@ void GLVolume::render(bool with_outline, const std::array<float, 4>& body_color)
}
}
else {
glsafe(::glMultMatrixd(world_matrix().data()));
auto render_which = [this](std::shared_ptr<GLIndexedVertexArray> cur) {
auto render_which = [this](std::shared_ptr<GLIndexedVertexArray> cur, const std::shared_ptr<GLShaderProgram>& shader) {
if (cur->vertices_and_normals_interleaved_VBO_id > 0) {
cur->render(tverts_range_lod, qverts_range_lod);
cur->render(shader, tverts_range_lod, qverts_range_lod);
} else {// if (cur->vertices_and_normals_interleaved_VBO_id == 0)
if (cur->triangle_indices.size() > 0) {
cur->finalize_geometry(true);
cur->render(tverts_range_lod, qverts_range_lod);
cur->render(shader, tverts_range_lod, qverts_range_lod);
} else {
indexed_vertex_array->render(this->tverts_range, this->qverts_range);
indexed_vertex_array->render(shader, this->tverts_range, this->qverts_range);
}
}
};
Transform3d world_tran = world_matrix();
m_lod_update_index++;
if (abs(zoom - LAST_CAMERA_ZOOM_VALUE) > ZOOM_THRESHOLD || m_lod_update_index >= LOD_UPDATE_FREQUENCY){
m_lod_update_index = 0;
@ -916,17 +955,17 @@ void GLVolume::render(bool with_outline, const std::array<float, 4>& body_color)
m_cur_lod_level = calc_volume_box_in_screen_bigger_than_threshold(transformed_bounding_box(), vier_proj_mat, viewport[2], viewport[3]);
}
if (m_cur_lod_level == LOD_LEVEL::SMALL && indexed_vertex_array_small) {
render_which(indexed_vertex_array_small);
render_which(indexed_vertex_array_small, shader);
} else if (m_cur_lod_level == LOD_LEVEL::MIDDLE && indexed_vertex_array_middle) {
render_which(indexed_vertex_array_middle);
render_which(indexed_vertex_array_middle, shader);
} else {
this->indexed_vertex_array->render(this->tverts_range, this->qverts_range);
this->indexed_vertex_array->render(shader, this->tverts_range, this->qverts_range);
}
}
};
//BBS: add logic of outline rendering
GLShaderProgram* shader = GUI::wxGetApp().get_current_shader();
const auto 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)
{
@ -1031,13 +1070,11 @@ void GLVolume::render(bool with_outline, const std::array<float, 4>& body_color)
shader->set_uniform("uniform_color", body_color);
shader->set_uniform("is_outline", true);
glsafe(::glPopMatrix());
glsafe(::glPushMatrix());
Transform3d matrix = world_matrix();
Transform3d world_tran = matrix;
matrix.scale(scale);
glsafe(::glMultMatrixd(matrix.data()));
shader->set_uniform("view_model_matrix", view_matrix * matrix);
m_lod_update_index++;
if (abs(zoom - LAST_CAMERA_ZOOM_VALUE) > ZOOM_THRESHOLD || m_lod_update_index >= LOD_UPDATE_FREQUENCY) {
m_lod_update_index = 0;
@ -1045,11 +1082,11 @@ void GLVolume::render(bool with_outline, const std::array<float, 4>& body_color)
m_cur_lod_level = calc_volume_box_in_screen_bigger_than_threshold(transformed_bounding_box(), vier_proj_mat, viewport[2], viewport[3]);
}
if (m_cur_lod_level == LOD_LEVEL::SMALL && indexed_vertex_array_small && indexed_vertex_array_small->vertices_and_normals_interleaved_VBO_id > 0) {
this->indexed_vertex_array_small->render(this->tverts_range_lod, this->qverts_range_lod);
this->indexed_vertex_array_small->render(shader, this->tverts_range_lod, this->qverts_range_lod);
} else if (m_cur_lod_level == LOD_LEVEL::MIDDLE && indexed_vertex_array_middle && indexed_vertex_array_middle->vertices_and_normals_interleaved_VBO_id > 0) {
this->indexed_vertex_array_middle->render(this->tverts_range_lod, this->qverts_range_lod);
this->indexed_vertex_array_middle->render(shader, this->tverts_range_lod, this->qverts_range_lod);
} else {
this->indexed_vertex_array->render(this->tverts_range, this->qverts_range);
this->indexed_vertex_array->render(shader, this->tverts_range, this->qverts_range);
}
//BOOST_LOG_TRIVIAL(info) << boost::format(": %1%, outline render for body, shader name %2%")%__LINE__ %shader->get_name();
shader->set_uniform("is_outline", false);
@ -1066,18 +1103,16 @@ void GLVolume::render(bool with_outline, const std::array<float, 4>& body_color)
render_body();
//BOOST_LOG_TRIVIAL(info) << boost::format(": %1%, normal render.")%__LINE__;
}
glsafe(::glPopMatrix());
if (this->is_left_handed())
glFrontFace(GL_CCW);
}
//BBS add render for simple case
void GLVolume::simple_render(GLShaderProgram *shader, ModelObjectPtrs &model_objects, std::vector<std::array<float, 4>> &extruder_colors, bool ban_light) const
void GLVolume::simple_render(const std::shared_ptr<GLShaderProgram>& shader, ModelObjectPtrs &model_objects, std::vector<std::array<float, 4>> &extruder_colors, bool ban_light) const
{
if (this->is_left_handed())
glFrontFace(GL_CW);
glsafe(::glCullFace(GL_BACK));
glsafe(::glPushMatrix());
bool color_volume = false;
ModelObject* model_object = nullptr;
@ -1108,8 +1143,7 @@ void GLVolume::simple_render(GLShaderProgram *shader, ModelObjectPtrs &model_obj
}
} while (0);
if (color_volume) {
glsafe(::glMultMatrixd(world_matrix().data()));
if (color_volume && !picking) {
for (int idx = 0; idx < mmuseg_ivas.size(); idx++) {
GLIndexedVertexArray& iva = mmuseg_ivas[idx];
if (iva.triangle_indices_size == 0 && iva.quad_indices_size == 0)
@ -1147,15 +1181,13 @@ void GLVolume::simple_render(GLShaderProgram *shader, ModelObjectPtrs &model_obj
}
}
}
iva.render(this->tverts_range, this->qverts_range);
iva.render(shader, this->tverts_range, this->qverts_range);
}
}
else {
glsafe(::glMultMatrixd(world_matrix().data()));
this->indexed_vertex_array->render(this->tverts_range, this->qverts_range);
this->indexed_vertex_array->render(shader, this->tverts_range, this->qverts_range);
}
glsafe(::glPopMatrix());
if (this->is_left_handed())
glFrontFace(GL_CCW);
}
@ -1195,7 +1227,7 @@ GLWipeTowerVolume::GLWipeTowerVolume(const std::vector<std::array<float, 4>>& co
m_colors = colors;
}
void GLWipeTowerVolume::render(bool with_outline,const std::array<float, 4> &body_color) const
void GLWipeTowerVolume::render(const Transform3d& view_matrix, bool with_outline,const std::array<float, 4> &body_color) const
{
if (!is_active)
return;
@ -1203,22 +1235,28 @@ void GLWipeTowerVolume::render(bool with_outline,const std::array<float, 4> &bod
if (m_colors.size() == 0 || m_colors.size() != iva_per_colors.size())
return;
const auto shader = GUI::wxGetApp().get_current_shader();
if (!shader) {
return;
}
if (this->is_left_handed())
glFrontFace(GL_CW);
glsafe(::glCullFace(GL_BACK));
glsafe(::glPushMatrix());
glsafe(::glMultMatrixd(world_matrix().data()));
GLShaderProgram* shader = GUI::wxGetApp().get_current_shader();
for (int i = 0; i < m_colors.size(); i++) {
if (shader) {
std::array<float, 4> new_color = adjust_color_for_rendering(m_colors[i]);
shader->set_uniform("uniform_color", new_color);
if (!picking) {
ColorRGBA new_color = adjust_color_for_rendering(m_colors[i]);
std::array<float, 4> final_color;
final_color[0] = new_color.r();
final_color[1] = new_color.g();
final_color[2] = new_color.b();
final_color[3] = new_color.a();
shader->set_uniform("uniform_color", final_color);
}
this->iva_per_colors[i].render();
this->iva_per_colors[i].render(shader);
}
glsafe(::glPopMatrix());
if (this->is_left_handed())
glFrontFace(GL_CCW);
}
@ -1537,6 +1575,7 @@ void GLVolumeCollection::render(GUI::ERenderPipelineStage render_pip
GLVolumeCollection::ERenderType type,
bool disable_cullface,
const Transform3d & view_matrix,
const Transform3d& projection_matrix,
std::function<bool(const GLVolume &)> filter_func,
bool with_outline,
const std::array<float, 4> & body_color,
@ -1547,7 +1586,7 @@ void GLVolumeCollection::render(GUI::ERenderPipelineStage render_pip
if (to_render.empty())
return;
GLShaderProgram* shader = GUI::wxGetApp().get_current_shader();
const auto shader = GUI::wxGetApp().get_current_shader();
if (shader == nullptr)
return;
@ -1563,7 +1602,7 @@ void GLVolumeCollection::render(GUI::ERenderPipelineStage render_pip
auto camera = GUI::wxGetApp().plater()->get_camera();
for (GLVolumeWithIdAndZ& volume : to_render) {
auto world_box = volume.first->transformed_bounding_box();
if (!camera.getFrustum().intersects(world_box, camera.get_type_as_string() == "perspective")) {
if (!camera.getFrustum().intersects(world_box)) {
continue;
}
#if ENABLE_MODIFIERS_ALWAYS_TRANSPARENT
@ -1585,15 +1624,12 @@ void GLVolumeCollection::render(GUI::ERenderPipelineStage render_pip
if (m_show_sinking_contours)
if (volume.first->is_sinking() && !volume.first->is_below_printbed() &&
volume.first->hover == GLVolume::HS_None && !volume.first->force_sinking_contours) {
shader->stop_using();
GUI::wxGetApp().unbind_shader();
volume.first->render_sinking_contours();
shader->start_using();
GUI::wxGetApp().bind_shader(shader);
}
}
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
if (GUI::ERenderPipelineStage::Silhouette != render_pipeline_stage) {
shader->set_uniform("is_text_shape", volume.first->is_text_shape);
shader->set_uniform("uniform_color", volume.first->render_color);
@ -1653,14 +1689,19 @@ void GLVolumeCollection::render(GUI::ERenderPipelineStage render_pip
#endif // ENABLE_ENVIRONMENT_MAP
glcheck();
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
auto red_color = std::array<float, 4>({ 1.0f, 0.0f, 0.0f, 1.0f });//slice_error
volume.first->render(with_outline&& volume.first->selected, volume.first->slice_error ? red_color : body_color);
volume.first->render(view_matrix, with_outline&& volume.first->selected, volume.first->slice_error ? red_color : body_color);
}
else {
if (volume.first->selected) {
shader->set_uniform("u_model_matrix", volume.first->world_matrix());
volume.first->render(false, body_color);
volume.first->render(view_matrix, false, body_color);
}
}
@ -1671,9 +1712,6 @@ void GLVolumeCollection::render(GUI::ERenderPipelineStage render_pip
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
}
if (GUI::ERenderPipelineStage::Silhouette != render_pipeline_stage) {
@ -1682,11 +1720,11 @@ void GLVolumeCollection::render(GUI::ERenderPipelineStage render_pip
// render sinking contours of hovered/displaced volumes
if (volume.first->is_sinking() && !volume.first->is_below_printbed() &&
(volume.first->hover != GLVolume::HS_None || volume.first->force_sinking_contours)) {
shader->stop_using();
GUI::wxGetApp().unbind_shader();
glsafe(::glDepthFunc(GL_ALWAYS));
volume.first->render_sinking_contours();
glsafe(::glDepthFunc(GL_LESS));
shader->start_using();
GUI::wxGetApp().bind_shader(shader);
}
}
}

View File

@ -16,6 +16,7 @@
#include <functional>
#include <optional>
#include <memory>
#ifndef NDEBUG
#define HAS_GLSAFE
@ -228,8 +229,8 @@ public:
// Release the geometry data, release OpenGL VBOs.
void release_geometry();
void render() const;
void render(const std::pair<size_t, size_t>& tverts_range, const std::pair<size_t, size_t>& qverts_range) const;
void render(const std::shared_ptr<GLShaderProgram>& shader) const;
void render(const std::shared_ptr<GLShaderProgram>& shader, const std::pair<size_t, size_t>& tverts_range, const std::pair<size_t, size_t>& qverts_range) const;
// Is there any geometry data stored?
bool empty() const { return vertices_and_normals_interleaved_size == 0; }
@ -451,6 +452,7 @@ public:
bool force_sinking_contours : 1;
// slice error
bool slice_error : 1;
bool picking : 1;
};
// Is mouse or rectangle selection over this object to select/deselect it ?
@ -582,11 +584,12 @@ public:
void set_range(double low, double high);
//BBS: add outline related logic and add virtual specifier
virtual void render(bool with_outline = false,
virtual void render(const Transform3d& view_matrix,
bool with_outline = false,
const std::array<float, 4> &body_color = {1.0f, 1.0f, 1.0f, 1.0f} ) const;
//BBS: add simple render function for thumbnail
void simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_objects, std::vector<std::array<float, 4>>& extruder_colors,bool ban_light =false) const;
void simple_render(const std::shared_ptr<GLShaderProgram>& shader, ModelObjectPtrs& model_objects, std::vector<std::array<float, 4>>& extruder_colors,bool ban_light =false) const;
void finalize_geometry(bool opengl_initialized) { this->indexed_vertex_array->finalize_geometry(opengl_initialized); }
void release_geometry() { this->indexed_vertex_array->release_geometry(); }
@ -614,7 +617,7 @@ public:
class GLWipeTowerVolume : public GLVolume {
public:
GLWipeTowerVolume(const std::vector<std::array<float, 4>>& colors);
virtual void render(bool with_outline = false, const std::array<float, 4> &body_color = {1.0f, 1.0f, 1.0f, 1.0f}) const;
void render(const Transform3d& view_matrix, bool with_outline = false, const std::array<float, 4> &body_color = {1.0f, 1.0f, 1.0f, 1.0f}) const override;
std::vector<GLIndexedVertexArray> iva_per_colors;
bool IsTransparent();
@ -727,6 +730,7 @@ public:
ERenderType type,
bool disable_cullface,
const Transform3d & view_matrix,
const Transform3d& projection_matrix,
std::function<bool(const GLVolume &)> filter_func = std::function<bool(const GLVolume &)>(),
bool with_outline = true,
const std::array<float, 4> & body_color = {1.0f, 1.0f, 1.0f, 1.0f},

View File

@ -144,12 +144,27 @@ void Camera::select_view(ViewAngleType type)
default: break;
}
}
const Transform3d Camera::get_view_matrix_for_billboard() const
{
Transform3d view_matrix_for_billboard{ Transform3d::Identity() };
double gui_scale = get_gui_scale();
view_matrix_for_billboard.data()[3 * 4 + 0] = 0.0f;
view_matrix_for_billboard.data()[3 * 4 + 1] = 0.0f;
view_matrix_for_billboard.data()[3 * 4 + 2] = -(get_near_z() + 0.10);
view_matrix_for_billboard.data()[0 * 4 + 0] = gui_scale;
view_matrix_for_billboard.data()[1 * 4 + 1] = gui_scale;
view_matrix_for_billboard.data()[2 * 4 + 2] = 1.0f;
return view_matrix_for_billboard;
}
//how to use
//BoundingBox bbox = mesh.aabb.transform(transform);
//return camera_->getFrustum().intersects(bbox);
void Camera::debug_frustum()
{
ImGuiWrapper &imgui = *wxGetApp().imgui();
/*ImGuiWrapper &imgui = *wxGetApp().imgui();
imgui.begin(std::string("Camera debug_frusm"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
Vec3f frustum_min = m_frustum.bbox.min.cast<float>();
@ -176,134 +191,63 @@ void Camera::debug_frustum()
Vec3f center = m_frustum.planes[i].getCenter();
ImGui::InputFloat3(name.c_str(), center.data(), "%.6f", ImGuiInputTextFlags_ReadOnly);
}
imgui.end();
imgui.end();*/
}
void Camera::update_frustum()
{
Vec3f eye_ = get_position().cast<float>();
Vec3f center_ = get_target().cast<float>();
Vec3f up_ = get_dir_up().cast<float>();
float near_ = m_frustrum_zs.first;
float far_ = m_frustrum_zs.second;
float aspect_ = m_viewport[2] / (double)m_viewport[3];
float fov_ = (float) Geometry::deg2rad(get_fov());
float eps = 0.01;
if (m_last_eye.isApprox(eye_) && m_last_center.isApprox(center_) && m_last_up.isApprox(up_)
&& abs(m_last_near - near_) < eps && abs(m_last_far - far_) < eps &&
abs(m_last_aspect - aspect_) < eps && abs(m_last_fov - fov_) < eps && abs(m_last_zoom - m_zoom) < eps) {
return;
}
m_last_eye = eye_;
m_last_center = center_;
m_last_up = up_;
m_last_near = near_;
m_last_far = far_;
m_last_aspect = aspect_;
m_last_fov = fov_;
m_last_zoom = m_zoom;
Vec3f forward((center_ - eye_).normalized());
Vec3f side((forward.cross(up_)).normalized());
Vec3f up((side.cross(forward)).normalized());
// see https://www8.cs.umu.se/kurser/5DV051/HT12/lab/plane_extraction.pdf
const auto vp = m_projection_matrix.matrix() * m_view_matrix.matrix();
const auto& vp_matrix = vp.eval();
float nearHeightHalf = near_ * std::tan(fov_ / 2.f);
float farHeightHalf = far_ * std::tan(fov_ / 2.f);
float nearWidthHalf = nearHeightHalf * aspect_;
float farWidthHalf = farHeightHalf * aspect_;
const auto vp_data = vp_matrix.data();
// left
float a = vp_data[0 * 4 + 3] + vp_data[0 * 4 + 0];
float b = vp_data[1 * 4 + 3] + vp_data[1 * 4 + 0];
float c = vp_data[2 * 4 + 3] + vp_data[2 * 4 + 0];
float d = vp_data[3 * 4 + 3] + vp_data[3 * 4 + 0];
m_frustum.planes[0].set_abcd(a, b, c, d);
m_frustum.planes[0].normailze();
// near plane
Vec3f nearCenter = eye_ + forward * near_;
Vec3f nearNormal = forward;
m_frustum.planes[0].set(nearNormal, nearCenter);
// right
a = vp_data[0 * 4 + 3] - vp_data[0 * 4 + 0];
b = vp_data[1 * 4 + 3] - vp_data[1 * 4 + 0];
c = vp_data[2 * 4 + 3] - vp_data[2 * 4 + 0];
d = vp_data[3 * 4 + 3] - vp_data[3 * 4 + 0];
m_frustum.planes[1].set_abcd(a, b, c, d);
m_frustum.planes[1].normailze();
// far plane
Vec3f farCenter = eye_ + forward * far_;
Vec3f farNormal = -forward;
m_frustum.planes[1].set(farNormal, farCenter);
if (m_type == EType::Ortho) {
double right = 1.0 / m_projection_matrix.matrix()(0, 0) - 0.5 * m_projection_matrix.matrix()(0, 0) * m_projection_matrix.matrix()(0, 3);
double top = 1.0 / m_projection_matrix.matrix()(1, 1) - 0.5 * m_projection_matrix.matrix()(1, 1) * m_projection_matrix.matrix()(1, 3);
auto dz = (far_ - near_) / 2.0;
Vec3f center = eye_ + forward * (far_ + near_) /2.0f;
m_frustum.bbox.reset();
Vec3f corner = farCenter + up * top + side * right;
m_frustum.bbox.merge(corner.cast<double>());
// bottom
a = vp_data[0 * 4 + 3] + vp_data[0 * 4 + 1];
b = vp_data[1 * 4 + 3] + vp_data[1 * 4 + 1];
c = vp_data[2 * 4 + 3] + vp_data[2 * 4 + 1];
d = vp_data[3 * 4 + 3] + vp_data[3 * 4 + 1];
m_frustum.planes[2].set_abcd(a, b, c, d);
m_frustum.planes[2].normailze();
corner = farCenter - up * top + side * right;
m_frustum.bbox.merge(corner.cast<double>());
// top
a = vp_data[0 * 4 + 3] - vp_data[0 * 4 + 1];
b = vp_data[1 * 4 + 3] - vp_data[1 * 4 + 1];
c = vp_data[2 * 4 + 3] - vp_data[2 * 4 + 1];
d = vp_data[3 * 4 + 3] - vp_data[3 * 4 + 1];
m_frustum.planes[3].set_abcd(a, b, c, d);
m_frustum.planes[3].normailze();
corner = farCenter + up * top - side * right;
m_frustum.bbox.merge(corner.cast<double>());
// near
a = vp_data[0 * 4 + 3] + vp_data[0 * 4 + 2];
b = vp_data[1 * 4 + 3] + vp_data[1 * 4 + 2];
c = vp_data[2 * 4 + 3] + vp_data[2 * 4 + 2];
d = vp_data[3 * 4 + 3] + vp_data[3 * 4 + 2];
m_frustum.planes[4].set_abcd(a, b, c, d);
m_frustum.planes[4].normailze();
corner = farCenter - up * top - side * right;
m_frustum.bbox.merge(corner.cast<double>());
//nearCenter
corner = nearCenter + up * top + side * right;
m_frustum.bbox.merge(corner.cast<double>());
corner = nearCenter - up * top + side * right;
m_frustum.bbox.merge(corner.cast<double>());
corner = nearCenter + up * top - side * right;
m_frustum.bbox.merge(corner.cast<double>());
corner = nearCenter - up * top - side * right;
m_frustum.bbox.merge(corner.cast<double>());
return;
}
// top plane
Vec3f topCenter = nearCenter + up * nearHeightHalf;
Vec3f topNormal = (topCenter - eye_).normalized().cross(side);
m_frustum.planes[2].set(topNormal, topCenter);
// bottom plane
Vec3f bottomCenter = nearCenter - up * nearHeightHalf;
Vec3f bottomNormal = side.cross((bottomCenter - eye_).normalized());
m_frustum.planes[3].set(bottomNormal, bottomCenter);
// left plane
Vec3f leftCenter = nearCenter - side * nearWidthHalf;
Vec3f leftNormal = (leftCenter - eye_).normalized().cross(up);
m_frustum.planes[4].set(leftNormal, leftCenter);
// right plane
Vec3f rightCenter = nearCenter + side * nearWidthHalf;
Vec3f rightNormal = up.cross((rightCenter - eye_).normalized());
m_frustum.planes[5].set(rightNormal, rightCenter);
//// 8 corners
Vec3f nearTopLeft = nearCenter + up * nearHeightHalf - side * nearWidthHalf;
Vec3f nearTopRight = nearCenter + up * nearHeightHalf + side * nearWidthHalf;
Vec3f nearBottomLeft = nearCenter - up * nearHeightHalf - side * nearWidthHalf;
Vec3f nearBottomRight = nearCenter - up * nearHeightHalf + side * nearWidthHalf;
Vec3f farTopLeft = farCenter + up * farHeightHalf - side * farWidthHalf;
Vec3f farTopRight = farCenter + up * farHeightHalf + side * farWidthHalf;
Vec3f farBottomLeft = farCenter - up * farHeightHalf - side * farWidthHalf;
Vec3f farBottomRight = farCenter - up * farHeightHalf + side * farWidthHalf;
m_frustum.corners[0] = nearTopLeft;
m_frustum.corners[1] = nearTopRight;
m_frustum.corners[2] = nearBottomLeft;
m_frustum.corners[3] = nearBottomRight;
m_frustum.corners[4] = farTopLeft;
m_frustum.corners[5] = farTopRight;
m_frustum.corners[6] = farBottomLeft;
m_frustum.corners[7] = farBottomRight;
// bounding box
auto double_min = std::numeric_limits<double>::min();
auto double_max = std::numeric_limits<double>::max();
m_frustum.bbox.min = Vec3d(double_max, double_max, double_max);
m_frustum.bbox.max = Vec3d(double_min, double_min, double_min);
for (auto &corner : m_frustum.corners) {
m_frustum.bbox.min[0] = std::min((float)m_frustum.bbox.min.x(), corner.x());
m_frustum.bbox.min[1] = std::min((float)m_frustum.bbox.min.y(), corner.y());
m_frustum.bbox.min[2] = std::min((float)m_frustum.bbox.min.z(), corner.z());
m_frustum.bbox.max[0] = std::max((float)m_frustum.bbox.max.x(), corner.x());
m_frustum.bbox.max[1] = std::max((float)m_frustum.bbox.max.y(), corner.y());
m_frustum.bbox.max[2] = std::max((float)m_frustum.bbox.max.z(), corner.z());
}
// far
a = vp_data[0 * 4 + 3] - vp_data[0 * 4 + 2];
b = vp_data[1 * 4 + 3] - vp_data[1 * 4 + 2];
c = vp_data[2 * 4 + 3] - vp_data[2 * 4 + 2];
d = vp_data[3 * 4 + 3] - vp_data[3 * 4 + 2];
m_frustum.planes[5].set_abcd(a, b, c, d);
m_frustum.planes[5].normailze();
}
double Camera::get_fov() const
@ -320,15 +264,11 @@ double Camera::get_fov() const
void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h)
{
glsafe(::glViewport(0, 0, w, h));
glsafe(::glGetIntegerv(GL_VIEWPORT, m_viewport.data()));
}
void Camera::apply_view_matrix()
{
glsafe(::glMatrixMode(GL_MODELVIEW));
glsafe(::glLoadIdentity());
glsafe(::glMultMatrixd(m_view_matrix.data()));
glsafe(::glViewport(x, y, w, h));
m_viewport[0] = x;
m_viewport[1] = y;
m_viewport[2] = w;
m_viewport[3] = h;
}
void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double far_z)
@ -336,11 +276,7 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
double w = 0.0;
double h = 0.0;
const double old_distance = m_distance;
m_frustrum_zs = calc_tight_frustrum_zs_around(box);
if (m_distance != old_distance)
// the camera has been moved re-apply view matrix
apply_view_matrix();
if (near_z > 0.0)
m_frustrum_zs.first = std::max(std::min(m_frustrum_zs.first, near_z), FrustrumMinNearZ);
@ -374,26 +310,55 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
}
}
glsafe(::glMatrixMode(GL_PROJECTION));
glsafe(::glLoadIdentity());
switch (m_type)
{
default:
case EType::Ortho:
{
glsafe(::glOrtho(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second));
// see https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/glOrtho.xml
//glsafe(::glOrtho(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second));
m_projection_matrix(0, 0) = 2.0f / (w - (-w));
m_projection_matrix(0, 1) = 0.0f;
m_projection_matrix(0, 2) = 0.0f;
m_projection_matrix(0, 3) = -(w + (-w)) / (w - (-w));
m_projection_matrix(1, 0) = 0.0f;
m_projection_matrix(1, 1) = 2.0f / (h - (-h));
m_projection_matrix(1, 2) = 0.0f;
m_projection_matrix(1, 3) = -(h + (-h)) / (h - (-h));
m_projection_matrix(2, 0) = 0.0f;
m_projection_matrix(2, 1) = 0.0f;
m_projection_matrix(2, 2) = -2.0f / (m_frustrum_zs.second - m_frustrum_zs.first);
m_projection_matrix(2, 3) = -(m_frustrum_zs.second + m_frustrum_zs.first) / (m_frustrum_zs.second - m_frustrum_zs.first);
m_projection_matrix(3, 0) = 0.0f;
m_projection_matrix(3, 1) = 0.0f;
m_projection_matrix(3, 2) = 0.0f;
m_projection_matrix(3, 3) = 1.0f;
break;
}
case EType::Perspective:
{
glsafe(::glFrustum(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second));
// see https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/glFrustum.xml
//glsafe(::glFrustum(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second));
m_projection_matrix(0, 0) = 2.0f * m_frustrum_zs.first / (w - (-w));
m_projection_matrix(0, 1) = 0.0f;
m_projection_matrix(0, 2) = (w + (-w)) / (w - (-w));
m_projection_matrix(0, 3) = 0.0f;
m_projection_matrix(1, 0) = 0.0f;
m_projection_matrix(1, 1) = 2.0f * m_frustrum_zs.first / (h - (-h));
m_projection_matrix(1, 2) = (h + (-h)) / (h - (-h));
m_projection_matrix(1, 3) = 0.0f;
m_projection_matrix(2, 0) = 0.0f;
m_projection_matrix(2, 1) = 0.0f;
m_projection_matrix(2, 2) = -(m_frustrum_zs.second + m_frustrum_zs.first) / (m_frustrum_zs.second - m_frustrum_zs.first);
m_projection_matrix(2, 3) = -2.0f * m_frustrum_zs.second * m_frustrum_zs.first / (m_frustrum_zs.second - m_frustrum_zs.first);
m_projection_matrix(3, 0) = 0.0f;
m_projection_matrix(3, 1) = 0.0f;
m_projection_matrix(3, 2) = -1.0f;
m_projection_matrix(3, 3) = 0.0f;
break;
}
}
glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, m_projection_matrix.data()));
glsafe(::glMatrixMode(GL_MODELVIEW));
}
void Camera::zoom_to_box(const BoundingBoxf3& box, double margin_factor)

View File

@ -109,6 +109,7 @@ public:
const std::array<int, 4>& 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; }
const Transform3d get_view_matrix_for_billboard() const;
//BBS
const Eigen::Quaterniond& get_view_rotation() const {return m_view_rotation; }
@ -127,7 +128,6 @@ public:
double get_fov() const;
void apply_viewport(int x, int y, unsigned int w, unsigned int h);
void apply_view_matrix();
// Calculates and applies the projection matrix tighting the frustrum z range around the given box.
// If larger z span is needed, pass the desired values of near and far z (negative values are ignored)
void apply_projection(const BoundingBoxf3& box, double near_z = -1.0, double far_z = -1.0);

View File

@ -362,24 +362,25 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he
if (!m_visible)
return;
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
const auto& shader = wxGetApp().get_shader("gouraud_light");
if (shader == nullptr)
return;
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
shader->start_using();
wxGetApp().bind_shader(shader);
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<double>();
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();
m_model.render_geometry();
glsafe(::glPopMatrix());
shader->stop_using();
wxGetApp().unbind_shader();
glsafe(::glDisable(GL_BLEND));
@ -911,11 +912,6 @@ void GCodeViewer::init(ConfigOptionMode mode, PresetBundle* preset_bundle)
m_sequential_view.marker.init(filename);
// initializes point sizes
std::array<int, 2> point_sizes;
::glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, point_sizes.data());
m_detected_point_sizes = { static_cast<float>(point_sizes[0]), static_cast<float>(point_sizes[1]) };
// BBS initialzed view_type items
m_user_mode = mode;
update_by_mode(m_user_mode);
@ -1395,7 +1391,6 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
camera.set_type(Camera::EType::Ortho);
camera.set_target(center);
camera.select_view("top");
camera.apply_view_matrix();
camera.zoom_to_box(plate_box, 1.0f);
camera.apply_projection(plate_box);
@ -1442,9 +1437,9 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
};
#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
@ -1460,12 +1455,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));
@ -1489,10 +1488,11 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
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));
buffer_range.first = buffer_range.last;
@ -1508,9 +1508,16 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
if (!buffer.visible || !buffer.has_data())
continue;
GLShaderProgram* shader = opengl_manager.get_shader("cali");
const auto& shader = opengl_manager.get_shader("flat");
if (shader != nullptr) {
shader->start_using();
opengl_manager.bind_shader(shader);
const auto& view_matrix = camera.get_view_matrix();
const auto& proj_matrix = camera.get_projection_matrix();
shader->set_uniform("view_model_matrix", view_matrix);
shader->set_uniform("projection_matrix", proj_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);
@ -1519,7 +1526,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 {
@ -1537,12 +1544,17 @@ 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));
@ -1559,15 +1571,16 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
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));
}
}
shader->stop_using();
opengl_manager.unbind_shader();
}
else {
BOOST_LOG_TRIVIAL(info) << boost::format("render_calibration_thumbnail: can not find shader");
@ -4004,17 +4017,30 @@ void GCodeViewer::render_toolpaths()
};
Range buffer_range = { 0, 0 };
size_t indices_per_instance = buffer.model.data.indices_count();
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());
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));
const int position_id = shader.get_attrib_location("v_position");
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;
int normal_id = -1;
if (has_normals) {
glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
normal_id = shader.get_attrib_location("v_normal");
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));
@ -4038,10 +4064,11 @@ void GCodeViewer::render_toolpaths()
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
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));
buffer_range.first = buffer_range.last;
@ -4056,14 +4083,18 @@ void GCodeViewer::render_toolpaths()
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 auto& p_ogl_manager = wxGetApp().get_opengl_manager();
for (unsigned char i = begin_id; i < end_id; ++i) {
TBuffer& buffer = m_buffers[i];
if (!buffer.visible || !buffer.has_data())
continue;
GLShaderProgram* shader = wxGetApp().get_shader(buffer.shader.c_str());
const auto& shader = wxGetApp().get_shader(buffer.shader.c_str());
if (shader != nullptr) {
shader->start_using();
wxGetApp().bind_shader(shader);
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());
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel) {
shader->set_uniform("emission_factor", 0.25f);
@ -4095,12 +4126,20 @@ void GCodeViewer::render_toolpaths()
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));
const int position_id = shader->get_attrib_location("v_position");
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;
int normal_id = -1;
if (has_normals) {
glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
normal_id = shader->get_attrib_location("v_normal");
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));
@ -4113,7 +4152,7 @@ void GCodeViewer::render_toolpaths()
break;
}
case TBuffer::ERenderPrimitiveType::Line: {
glsafe(::glLineWidth(static_cast<GLfloat>(line_width(zoom))));
p_ogl_manager->set_line_width(static_cast<float>(line_width(zoom)));
render_as_lines(it_path, buffer.render_paths.rend(), *shader, uniform_color);
break;
}
@ -4126,15 +4165,16 @@ void GCodeViewer::render_toolpaths()
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
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));
}
}
shader->stop_using();
wxGetApp().unbind_shader();
}
}
@ -4144,17 +4184,29 @@ 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());
const auto& shader = wxGetApp().get_shader(cap.buffer->shader.c_str());
if (shader != nullptr) {
shader->start_using();
wxGetApp().bind_shader(shader);
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());
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));
const int position_id = shader->get_attrib_location("v_position");
if (position_id != -1) {
glsafe(::glVertexAttribPointer(position_id, cap.buffer->vertices.position_size_floats(), GL_FLOAT, GL_FALSE, cap.buffer->vertices.vertex_size_bytes(), (const void*)cap.buffer->vertices.position_offset_bytes()));
glsafe(::glEnableVertexAttribArray(position_id));
}
bool has_normals = cap.buffer->vertices.normal_size_floats() > 0;
int normal_id = -1;
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));
normal_id = shader->get_attrib_location("v_normal");
if (normal_id != -1) {
glsafe(::glVertexAttribPointer(normal_id, cap.buffer->vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, cap.buffer->vertices.vertex_size_bytes(), (const void*)cap.buffer->vertices.normal_offset_bytes()));
glsafe(::glEnableVertexAttribArray(normal_id));
}
}
shader->set_uniform("uniform_color", cap.color);
@ -4167,13 +4219,14 @@ void GCodeViewer::render_toolpaths()
++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));
shader->stop_using();
wxGetApp().unbind_shader();
}
};
@ -4190,7 +4243,7 @@ void GCodeViewer::render_shells()
//if (!m_shells.visible || m_shells.volumes.empty())
return;
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
const auto& shader = wxGetApp().get_shader("gouraud_light");
if (shader == nullptr)
return;
@ -4203,10 +4256,13 @@ void GCodeViewer::render_shells()
}
glsafe(::glDepthMask(GL_FALSE));
shader->start_using();
wxGetApp().bind_shader(shader);
//BBS: reopen cul faces
m_shells.volumes.render(GUI::ERenderPipelineStage::Normal, GLVolumeCollection::ERenderType::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix());
shader->stop_using();
const auto& camera = wxGetApp().plater()->get_camera();
const auto& view_matrix = camera.get_view_matrix();
const auto& projection_matrix = camera.get_projection_matrix();
m_shells.volumes.render(GUI::ERenderPipelineStage::Normal, GLVolumeCollection::ERenderType::Transparent, false, view_matrix, projection_matrix);
wxGetApp().unbind_shader();
glsafe(::glDepthMask(GL_TRUE));
}

View File

@ -806,7 +806,6 @@ private:
#if ENABLE_GCODE_VIEWER_STATISTICS
Statistics m_statistics;
#endif // ENABLE_GCODE_VIEWER_STATISTICS
std::array<float, 2> m_detected_point_sizes = { 0.0f, 0.0f };
GCodeProcessorResult::SettingsIds m_settings_ids;
std::array<SequentialRangeCap, 2> m_sequential_range_caps;

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@
#include <chrono>
#include <cstdint>
#include <stack>
#include <vector>
#include "GLToolbar.hpp"
#include "Event.hpp"
@ -20,6 +21,7 @@
#include "IMToolbar.hpp"
#include "slic3r/GUI/3DBed.hpp"
#include "libslic3r/Slicing.hpp"
#include "libslic3r/Point.hpp"
#include "GLEnums.hpp"
#include <float.h>
@ -263,6 +265,15 @@ class GLCanvas3D
};
LayersTexture m_layers_texture;
mutable GLModel m_background;
mutable float m_cached_background_thickness{ 0.0f };
mutable Transform3d m_model_matrix_for_background{ Transform3d::Identity() };
mutable Matrix3d m_normal_matrix_for_background{ Matrix3d::Identity() };
mutable GLModel m_baseline;
mutable GLModel m_profile_curve;
mutable bool m_profile_dirty{ true };
public:
EState state{ Unknown };
float band_width{ 2.0f };
@ -309,7 +320,7 @@ class GLCanvas3D
bool is_initialized() const;
void generate_layer_height_texture();
void render_background_texture(const GLCanvas3D& canvas, const Rect& bar_rect);
void render_background_texture(const GLCanvas3D& canvas);
void render_curve(const Rect& bar_rect);
void update_slicing_parameters();
@ -341,6 +352,8 @@ class GLCanvas3D
Drag drag;
bool ignore_left_up;
bool ignore_right_up;
bool rotating{ false };
bool panning{ false };
Mouse();
@ -361,12 +374,12 @@ class GLCanvas3D
{
struct Triangles
{
Pointf3s object;
Pointf3s supports;
GLModel object;
GLModel supports;
};
typedef std::map<unsigned int, Triangles> ObjectIdToTrianglesMap;
typedef std::map<unsigned int, Triangles> ObjectIdToModelsMap;
double z;
ObjectIdToTrianglesMap triangles;
ObjectIdToModelsMap triangles;
SlaCap() { reset(); }
void reset() { z = DBL_MAX; triangles.clear(); }
@ -550,6 +563,7 @@ private:
bool m_is_dark = false;
wxGLCanvas* m_canvas;
wxGLContext* m_context;
bool m_dirty_context{ true };
Bed3D &m_bed;
std::map<std::string, wxString> m_assembly_view_desc;
#if ENABLE_RETINA_GL
@ -666,7 +680,14 @@ private:
int assembly_view_count = 0;
std::stack<ERenderPipelineStage> m_render_pipeline_stage_stack;
GLModel m_full_screen_mesh;
mutable GLModel m_full_screen_mesh;
using FrameCallback = std::function<void()>;
std::vector<FrameCallback> m_frame_callback_list;
#if ENABLE_SHOW_CAMERA_TARGET
mutable GLModel m_camera_target_mark;
#endif // ENABLE_SHOW_CAMERA_TARGET
public:
OrientSettings& get_orient_settings()
@ -702,10 +723,12 @@ public:
public:
//BBS: add the height logic
~SequentialPrintClearance();
void set_polygons(const Polygons& polygons, const std::vector<std::pair<Polygon, float>>& height_polygons);
void set_render_fill(bool render_fill) { m_render_fill = render_fill; }
void set_visible(bool visible) { m_visible = visible; }
void render();
void reset();
friend class GLCanvas3D;
};
@ -746,14 +769,17 @@ public:
m_gizmo_highlighter;
bool m_can_show_navigator = true;
// for debug draw
GLModel m_unit_cube;
public:
explicit GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed);
~GLCanvas3D();
bool is_initialized() const { return m_initialized; }
void set_context(wxGLContext* context) { m_context = context; }
void set_type(ECanvasType type) { m_canvas_type = type; }
void set_context(wxGLContext* context);
void set_type(ECanvasType type);
ECanvasType get_canvas_type() { return m_canvas_type; }
wxGLCanvas* get_wxglcanvas() { return m_canvas; }
@ -925,7 +951,7 @@ public:
bool ban_light = false);
static void render_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects,
const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors,
GLShaderProgram * shader,
const std::shared_ptr<GLShaderProgram>& shader,
Camera::EType camera_type,
Camera::ViewAngleType camera_view_angle_type = Camera::ViewAngleType::Iso,
bool for_picking = false,
@ -933,7 +959,7 @@ public:
// render thumbnail using an off-screen framebuffer
static void render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params,
PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors,
GLShaderProgram * shader,
const std::shared_ptr<GLShaderProgram>& shader,
Camera::EType camera_type,
Camera::ViewAngleType camera_view_angle_type = Camera::ViewAngleType::Iso,
bool for_picking = false,
@ -941,7 +967,7 @@ public:
// render thumbnail using an off-screen framebuffer when GLEW_EXT_framebuffer_object is supported
static void render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params,
PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors,
GLShaderProgram * shader,
const std::shared_ptr<GLShaderProgram>& shader,
Camera::EType camera_type,
Camera::ViewAngleType camera_view_angle_type = Camera::ViewAngleType::Iso,
bool for_picking = false,
@ -956,7 +982,7 @@ public:
ModelObjectPtrs & model_objects,
const GLVolumeCollection & volumes,
std::vector<std::array<float, 4>> &extruder_colors,
GLShaderProgram * shader,
const std::shared_ptr<GLShaderProgram>& shader,
Camera::EType camera_type,
Camera::ViewAngleType camera_view_angle_type = Camera::ViewAngleType::Iso,
bool for_picking = false,
@ -1169,10 +1195,12 @@ public:
// Convert the screen space coordinate to an object space coordinate.
// If the Z screen space coordinate is not provided, a depth buffer value is substituted.
Vec3d _mouse_to_3d(const Point& mouse_pos, float* z = nullptr);
Vec3d _mouse_to_3d(const Camera& camera, const Point& mouse_pos, float* z = nullptr, const std::string& frame_name = "");
bool make_current_for_postinit();
void mark_context_dirty();
private:
bool _is_shown_on_screen() const;
@ -1188,7 +1216,7 @@ private:
//bool _init_view_toolbar();
bool _init_collapse_toolbar();
bool _set_current();
bool _set_current(bool force_update = false);
void _resize(unsigned int w, unsigned int h);
//BBS: add part plate related logic
@ -1300,6 +1328,19 @@ private:
ERenderPipelineStage _get_current_render_stage() const;
void _render_silhouette_effect();
void _composite_silhouette_effect();
void _init_fullscreen_mesh() const;
void _composite_main_frame(bool off_screen_rendering_enabled) const;
void _debug_draw_camera(const Camera& t_camera);
void _debug_draw_aabb();
void _init_unit_cube();
void _append_to_frame_callback(const FrameCallback& cb);
};
const ModelVolume *get_model_volume(const GLVolume &v, const Model &model);

View File

@ -493,16 +493,17 @@ void GLModel::init_from(Geometry &&data, bool generate_mesh)
m_render_data.back().color = data.color.get_data();
if (generate_mesh) {
if (!mesh) { mesh = new TriangleMesh(); }
mesh->its = std::move(data.get_as_indexed_triangle_set());
mesh->its = data.get_as_indexed_triangle_set();
}
m_render_data.back().geometry = std::move(data);
const auto& geometry = m_render_data.back().geometry;
// update bounding box
for (size_t i = 0; i < data.vertices_count(); ++i) {
const size_t position_stride = Geometry::position_stride_floats(data.format);
for (size_t i = 0; i < geometry.vertices_count(); ++i) {
const size_t position_stride = Geometry::position_stride_floats(geometry.format);
if (position_stride == 3)
m_bounding_box.merge(m_render_data.back().geometry.extract_position_3(i).cast<double>());
m_bounding_box.merge(geometry.extract_position_3(i).cast<double>());
else if (position_stride == 2) {
const Vec2f position = m_render_data.back().geometry.extract_position_2(i);
const Vec2f position = geometry.extract_position_2(i);
m_bounding_box.merge(Vec3f(position.x(), position.y(), 0.0f).cast<double>());
}
}
@ -522,6 +523,8 @@ void GLModel::init_from(const InitializationData& data)
RenderData rdata;
rdata.type = entity.type;
rdata.color = entity.color;
rdata.geometry.color = entity.color;
rdata.geometry.format.type = entity.type;
// vertices/normals data
std::vector<float> vertices(6 * entity.positions.size());
@ -638,6 +641,42 @@ bool GLModel::init_from_file(const std::string& filename)
return true;
}
void GLModel::init_model_from_polygon(const Polygons &polygons, float z)
{
if (polygons.empty()) {
assert(false);
return;
}
GLModel::Geometry data;
data.format = {PrimitiveType::Lines, Geometry::EVertexLayout::P3};
size_t segments_count = 0;
for (const Polygon &polygon : polygons) { segments_count += polygon.points.size(); }
data.reserve_vertices(2 * segments_count);
data.reserve_indices(2 * segments_count);
// vertices + indices
unsigned int vertices_counter = 0;
for (const Polygon &poly : polygons) {
for (size_t i = 0; i < poly.points.size(); ++i) {
const Point &p0 = poly.points[i];
const Point &p1 = (i == poly.points.size() - 1) ? poly.points.front() : poly.points[i + 1];
data.add_vertex(Vec3f(unscale<float>(p0.x()), unscale<float>(p0.y()), z));
data.add_vertex(Vec3f(unscale<float>(p1.x()), unscale<float>(p1.y()), z));
vertices_counter += 2;
data.add_line(vertices_counter - 2, vertices_counter - 1);
}
}
// update bounding box
for (size_t i = 0; i < data.vertices_count(); ++i) {
m_bounding_box.merge(data.extract_position_3(i).cast<double>());
}
init_from(std::move(data), false);
}
bool GLModel::init_model_from_poly(const std::vector<Vec2f> &triangles, float z, bool generate_mesh)
{
if (triangles.empty() || triangles.size() % 3 != 0)
@ -803,77 +842,23 @@ static GLenum get_index_type(const GLModel::Geometry &data)
}
}
void GLModel::render() const
{
GLShaderProgram* shader = wxGetApp().get_current_shader();
for (const RenderData& data : m_render_data) {
// sends data to gpu if not done yet
if (data.vbo_id == 0 || data.ibo_id == 0) {
auto origin_data = const_cast<RenderData *>(&data);
if (data.geometry.vertices_count() > 0 && data.geometry.indices_count() > 0
&& !send_to_gpu(*origin_data, data.geometry.vertices, data.geometry.indices))
continue;
}
bool has_normal = true;
if (data.geometry.vertices_count() > 0) {
has_normal = Geometry::has_normal(data.geometry.format);
}
GLenum mode;
switch (data.type)
{
default:
case PrimitiveType::Triangles: { mode = GL_TRIANGLES; break; }
case PrimitiveType::Lines: { mode = GL_LINES; break; }
case PrimitiveType::LineStrip: { mode = GL_LINE_STRIP; break; }
case PrimitiveType::LineLoop: { mode = GL_LINE_LOOP; break; }
}
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, data.vbo_id));
if (has_normal) {
glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void *) 0));
glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), (const void *) (3 * sizeof(float))));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
} else {
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), (const void *) 0));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
}
if (shader != nullptr)
shader->set_uniform("uniform_color", data.color);
else
glsafe(::glColor4fv(data.color.data()));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ibo_id));
glsafe(::glDrawElements(mode, static_cast<GLsizei>(data.indices_count), GL_UNSIGNED_INT, (const void*)0));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
}
void GLModel::render_geometry() {
void GLModel::render_geometry() const {
render_geometry(0,std::make_pair<size_t, size_t>(0, get_indices_count()));
}
void GLModel::render_geometry(int i,const std::pair<size_t, size_t> &range)
void GLModel::render_geometry(int i,const std::pair<size_t, size_t> &range) const
{
if (range.second == range.first) return;
GLShaderProgram *shader = wxGetApp().get_current_shader();
const auto shader = wxGetApp().get_current_shader();
if (shader == nullptr) return;
auto &render_data = m_render_data[i];
// sends data to gpu if not done yet
if (render_data.vbo_id == 0 || render_data.ibo_id == 0) {
auto origin_data = const_cast<RenderData*>(&render_data);
if (render_data.geometry.vertices_count() > 0 && render_data.geometry.indices_count() > 0 &&
!send_to_gpu(render_data, render_data.geometry.vertices, render_data.geometry.indices))
!send_to_gpu(*origin_data, render_data.geometry.vertices, render_data.geometry.indices))
return;
}
const Geometry &data = render_data.geometry;
@ -942,36 +927,40 @@ void GLModel::create_or_update_mats_vbo(unsigned int &vbo, const std::vector<Sli
for (size_t i = 0; i < mats.size(); i++) {
out_mats.emplace_back(mats[i].get_matrix().matrix().cast<float>());
}
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glsafe(::glGenBuffers(1, &vbo));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, vbo));
auto one_mat_all_size = sizeof(float) * 16;
glBufferData(GL_ARRAY_BUFFER, mats.size() * one_mat_all_size, out_mats.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glsafe(::glBufferData(GL_ARRAY_BUFFER, mats.size() * one_mat_all_size, out_mats.data(), GL_STATIC_DRAW));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
void GLModel::bind_mats_vbo(unsigned int instance_mats_vbo, unsigned int instances_count, int location)
void GLModel::bind_mats_vbo(unsigned int instance_mats_vbo, unsigned int instances_count, const std::vector<int>& locations)
{
if (instance_mats_vbo == 0 || instances_count == 0) {
return;
}
if (locations.size() < 4) {
return;
}
auto one_mat_all_size = sizeof(float) * 16;
auto one_mat_col_size = sizeof(float) * 4;
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, instance_mats_vbo));
for (unsigned int i = 0; i < instances_count; i++) { // set attribute pointers for matrix (4 times vec4)
glsafe(glEnableVertexAttribArray(location));
glsafe(glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, one_mat_all_size, (void *) 0));
glsafe(glEnableVertexAttribArray(location + 1));
glsafe(glVertexAttribPointer(location + 1, 4, GL_FLOAT, GL_FALSE, one_mat_all_size, (void *) (one_mat_col_size)));
glsafe(glEnableVertexAttribArray(location + 2));
glsafe(glVertexAttribPointer(location + 2, 4, GL_FLOAT, GL_FALSE, one_mat_all_size, (void *) (2 * one_mat_col_size)));
glsafe(glEnableVertexAttribArray(location + 3));
glsafe(glVertexAttribPointer(location + 3, 4, GL_FLOAT, GL_FALSE, one_mat_all_size, (void *) (3 * one_mat_col_size)));
// Update the matrix every time after an object is drawn//useful
glsafe(glVertexAttribDivisor(location, 1));
glsafe(glVertexAttribDivisor(location + 1, 1));
glsafe(glVertexAttribDivisor(location + 2, 1));
glsafe(glVertexAttribDivisor(location + 3, 1));
}
glsafe(glEnableVertexAttribArray(locations[0]));
glsafe(glVertexAttribPointer(locations[0], 4, GL_FLOAT, GL_FALSE, one_mat_all_size, (void*)0));
glsafe(glEnableVertexAttribArray(locations[1]));
glsafe(glVertexAttribPointer(locations[1], 4, GL_FLOAT, GL_FALSE, one_mat_all_size, (void*)(one_mat_col_size)));
glsafe(glEnableVertexAttribArray(locations[2]));
glsafe(glVertexAttribPointer(locations[2], 4, GL_FLOAT, GL_FALSE, one_mat_all_size, (void*)(2 * one_mat_col_size)));
glsafe(glEnableVertexAttribArray(locations[3]));
glsafe(glVertexAttribPointer(locations[3], 4, GL_FLOAT, GL_FALSE, one_mat_all_size, (void*)(3 * one_mat_col_size)));
// Update the matrix every time after an object is drawn//useful
glsafe(glVertexAttribDivisor(locations[0], 1));
glsafe(glVertexAttribDivisor(locations[1], 1));
glsafe(glVertexAttribDivisor(locations[2], 1));
glsafe(glVertexAttribDivisor(locations[3], 1));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
void GLModel::render_geometry_instance(unsigned int instance_mats_vbo, unsigned int instances_count)
@ -985,7 +974,7 @@ void GLModel::render_geometry_instance(unsigned int instance_mats_vbo, unsigned
return;
}
if (m_render_data.size() != 1) { return; }
GLShaderProgram *shader = wxGetApp().get_current_shader();
const auto shader = wxGetApp().get_current_shader();
if (shader == nullptr) return;
auto &render_data = m_render_data[0];
@ -1012,7 +1001,6 @@ void GLModel::render_geometry_instance(unsigned int instance_mats_vbo, unsigned
int position_id = -1;
int normal_id = -1;
int tex_coord_id = -1;
int instace_mats_id = -1;
if (position) {
position_id = shader->get_attrib_location("v_position");
if (position_id != -1) {
@ -1037,12 +1025,19 @@ void GLModel::render_geometry_instance(unsigned int instance_mats_vbo, unsigned
glsafe(::glEnableVertexAttribArray(tex_coord_id));
}
}
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
//glBindAttribLocation(shader->get_id(), 2, "instanceMatrix");
//glBindAttribLocation(2, "instanceMatrix");
//shader->bind(shaderProgram, 0, 'position');
instace_mats_id = shader->get_attrib_location("instanceMatrix");
if (instace_mats_id != -1) {
bind_mats_vbo(instance_mats_vbo, instances_count, instace_mats_id);
const int i_loc0 = shader->get_attrib_location("i_data0");
const int i_loc1 = shader->get_attrib_location("i_data1");
const int i_loc2 = shader->get_attrib_location("i_data2");
const int i_loc3 = shader->get_attrib_location("i_data3");
const bool has_instancing_attributes = (i_loc0 != -1 && i_loc1 != -1 && i_loc2 != -1 && i_loc3 != -1);
if (has_instancing_attributes) {
bind_mats_vbo(instance_mats_vbo, instances_count, { i_loc0, i_loc1, i_loc2, i_loc3});
}
else {
return;
@ -1053,13 +1048,19 @@ void GLModel::render_geometry_instance(unsigned int instance_mats_vbo, unsigned
glsafe(::glDrawElementsInstanced(mode, range.second - range.first, index_type, (const void *) (range.first * Geometry::index_stride_bytes(data)), instances_count));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
if (instace_mats_id != -1) glsafe(::glDisableVertexAttribArray(instace_mats_id));
if (has_instancing_attributes && instance_mats_vbo > 0) {
glsafe(::glVertexAttribDivisor(i_loc0, 0));
glsafe(::glVertexAttribDivisor(i_loc1, 0));
glsafe(::glVertexAttribDivisor(i_loc2, 0));
glsafe(::glVertexAttribDivisor(i_loc3, 0));
glsafe(::glDisableVertexAttribArray(i_loc0));
glsafe(::glDisableVertexAttribArray(i_loc1));
glsafe(::glDisableVertexAttribArray(i_loc2));
glsafe(::glDisableVertexAttribArray(i_loc3));
}
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));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instances_count) const
@ -1067,7 +1068,7 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
if (instances_vbo == 0)
return;
GLShaderProgram* shader = wxGetApp().get_current_shader();
const auto shader = wxGetApp().get_current_shader();
assert(shader == nullptr || boost::algorithm::iends_with(shader->get_name(), "_instanced"));
// vertex attributes

View File

@ -181,6 +181,7 @@ namespace GUI {
void init_from(const indexed_triangle_set& its);
void init_from(const Polygons& polygons, float z);
bool init_from_file(const std::string& filename);
void init_model_from_polygon(const Polygons &polygons, float z);
bool init_model_from_poly(const std::vector<Vec2f> &triangles, float z, bool generate_mesh = false);
bool init_model_from_lines(const Lines &lines, float z, bool generate_mesh = false);
bool init_model_from_lines(const Lines3 &lines, bool generate_mesh = false);
@ -190,11 +191,10 @@ namespace GUI {
void set_color(const ColorRGBA &color);
void reset();
void render() const;
void render_geometry();
void render_geometry(int i,const std::pair<size_t, size_t> &range);
void render_geometry() const;
void render_geometry(int i,const std::pair<size_t, size_t> &range) const;
static void create_or_update_mats_vbo(unsigned int &vbo, const std::vector<Slic3r::Geometry::Transformation> &mats);
void bind_mats_vbo(unsigned int instance_mats_vbo, unsigned int instances_count, int location);
void bind_mats_vbo(unsigned int instance_mats_vbo, unsigned int instances_count, const std::vector<int>& locations);
void render_geometry_instance(unsigned int instance_mats_vbo, unsigned int instances_count);
void render_geometry_instance(unsigned int instance_mats_vbo, unsigned int instances_count, const std::pair<size_t, size_t> &range);
void render_instanced(unsigned int instances_vbo, unsigned int instances_count) const;

View File

@ -4,6 +4,7 @@
#include "GLCanvas3D.hpp"
#include "GUI_App.hpp"
#include "Plater.hpp"
#include "OpenGLManager.hpp"
#include <igl/project.h>
#include <GL/glew.h>
@ -75,13 +76,18 @@ namespace GUI {
return;
const Camera& camera = wxGetApp().plater()->get_camera();
const auto& view_matrix = camera.get_view_matrix_for_billboard();
const auto& proj_matrix = camera.get_projection_matrix();
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 int cnv_width = cnv_size.get_width();
const int cnv_height = cnv_size.get_height();
if (0 == cnv_width || 0 == cnv_height) {
return;
}
float cnv_half_width = 0.5f * static_cast<float>(cnv_width);
float cnv_half_height = 0.5f * static_cast<float>(cnv_height);
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));
@ -91,37 +97,73 @@ namespace GUI {
float right = (float)std::max(start(0), end(0)) * inv_zoom;
float bottom = (float)std::min(start(1), end(1)) * inv_zoom;
glsafe(::glLineWidth(1.5f));
float color[3];
color[0] = 0.00f;
color[1] = 1.00f;
color[2] = 0.38f;
glsafe(::glColor3fv(color));
const auto& p_flat_shader = wxGetApp().get_shader("flat");
if (!p_flat_shader) {
return;
}
if (!m_rectangle.is_initialized()) {
GLModel::Geometry init_data;
init_data.format = { GLModel::PrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P3 };
init_data.reserve_vertices(4);
init_data.reserve_indices(4);
// vertices
init_data.add_vertex(Vec3f(-0.5f, -0.5f, 0.0f));
init_data.add_vertex(Vec3f(0.5f, -0.5f, 0.0f));
init_data.add_vertex(Vec3f(0.5f, 0.5f, 0.0f));
init_data.add_vertex(Vec3f(-0.5f, 0.5f, 0.0f));
// indices
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));
}
Transform3d model_matrix{ Transform3d::Identity() };
model_matrix.data()[3 * 4 + 0] = (left + right) * 0.5f;
model_matrix.data()[3 * 4 + 1] = (top + bottom) * 0.5f;
model_matrix.data()[0 * 4 + 0] = (right - left);
model_matrix.data()[1 * 4 + 1] = (top - bottom);
GLboolean was_line_stipple_enabled = GL_FALSE;
const auto& p_ogl_manager = wxGetApp().get_opengl_manager();
p_ogl_manager->set_line_width(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
double gui_scale = camera.get_gui_scale();
glsafe(::glScaled(gui_scale, gui_scale, 1.0));
#ifdef __APPLE__
const auto& gl_info = p_ogl_manager->get_gl_info();
const auto formated_gl_version = gl_info.get_formated_gl_version();
if (formated_gl_version < 30)
#endif
{
glsafe(::glGetBooleanv(GL_LINE_STIPPLE, &was_line_stipple_enabled));
glsafe(::glLineStipple(4, 0xAAAA));
glsafe(::glEnable(GL_LINE_STIPPLE));
}
glsafe(::glPushAttrib(GL_ENABLE_BIT));
glsafe(::glLineStipple(4, 0xAAAA));
glsafe(::glEnable(GL_LINE_STIPPLE));
wxGetApp().bind_shader(p_flat_shader);
::glBegin(GL_LINE_LOOP);
::glVertex2f((GLfloat)left, (GLfloat)bottom);
::glVertex2f((GLfloat)right, (GLfloat)bottom);
::glVertex2f((GLfloat)right, (GLfloat)top);
::glVertex2f((GLfloat)left, (GLfloat)top);
glsafe(::glEnd());
p_flat_shader->set_uniform("view_model_matrix", view_matrix * model_matrix);
p_flat_shader->set_uniform("projection_matrix", proj_matrix);
glsafe(::glPopAttrib());
m_rectangle.set_color({ 0.0f, 1.0f, 0.38f, 1.0f });
m_rectangle.render_geometry();
glsafe(::glPopMatrix());
wxGetApp().unbind_shader();
if (!was_line_stipple_enabled) {
#ifdef __APPLE__
if (formated_gl_version < 30)
#endif
{
glsafe(::glDisable(GL_LINE_STIPPLE));
}
}
}
} // namespace GUI

View File

@ -2,7 +2,7 @@
#define slic3r_GLSelectionRectangle_hpp_
#include "libslic3r/Point.hpp"
#include "GLModel.hpp"
namespace Slic3r {
namespace GUI {
@ -46,6 +46,7 @@ private:
EState m_state = Off;
Vec2d m_start_corner;
Vec2d m_end_corner;
mutable GLModel m_rectangle;
};

View File

@ -168,9 +168,6 @@ bool GLShaderProgram::init_from_texts(const std::string& name, const ShaderSourc
if (shader_ids[i] > 0)
glsafe(::glAttachShader(m_id, shader_ids[i]));
}
if (boost::ends_with(name,"_instance")) {
glBindAttribLocation(m_id, 3, "instanceMatrix");
}
glsafe(::glLinkProgram(m_id));
GLint params;
@ -204,11 +201,6 @@ void GLShaderProgram::start_using() const
glsafe(::glUseProgram(m_id));
}
void GLShaderProgram::stop_using() const
{
glsafe(::glUseProgram(0));
}
bool GLShaderProgram::set_uniform(const char* name, int value) const
{
int id = get_uniform_location(name);
@ -387,13 +379,13 @@ int GLShaderProgram::get_attrib_location(const char* name) const
// Shader program not loaded. This should not happen.
return -1;
//auto it = std::find_if(m_attrib_location_cache.begin(), m_attrib_location_cache.end(), [name](const auto& p) { return p.first == name; });
//if (it != m_attrib_location_cache.end())
// // Attrib ID cached.
// return it->second;
auto it = std::find_if(m_attrib_location_cache.begin(), m_attrib_location_cache.end(), [name](const auto& p) { return p.first == name; });
if (it != m_attrib_location_cache.end())
// Attrib ID cached.
return it->second;
int id = ::glGetAttribLocation(m_id, name);
//const_cast<GLShaderProgram*>(this)->m_attrib_location_cache.push_back({ name, id });
const_cast<GLShaderProgram*>(this)->m_attrib_location_cache.push_back({ name, id });
return id;
}

View File

@ -11,6 +11,7 @@ namespace Slic3r {
class GLShaderProgram
{
friend class GLShadersManager;
public:
enum class EShaderType
{
@ -41,9 +42,6 @@ public:
const std::string& get_name() const { return m_name; }
unsigned int get_id() const { return m_id; }
void start_using() const;
void stop_using() const;
bool set_uniform(const char* name, int value) const;
bool set_uniform(const char* name, bool value) const;
bool set_uniform(const char* name, float value) const;
@ -68,6 +66,9 @@ public:
int get_attrib_location(const char* name) const;
// returns -1 if not found
int get_uniform_location(const char* name) const;
private:
void start_using() const;
};
} // namespace Slic3r

View File

@ -3,6 +3,7 @@
#include "GLShadersManager.hpp"
#include "3DScene.hpp"
#include "GUI_App.hpp"
#include "GLShader.hpp"
#include <cassert>
#include <algorithm>
@ -33,43 +34,34 @@ std::pair<bool, std::string> GLShadersManager::init()
bool valid = true;
const std::string glsl_version_prefix = GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 1) ? "140/" : "110/";
// 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", { glsl_version_prefix + "gouraud_light.vs", glsl_version_prefix + "gouraud_light.fs" });
//used to render thumbnail
valid &= append_shader("thumbnail", { "thumbnail.vs", "thumbnail.fs" });
valid &= append_shader("thumbnail", { glsl_version_prefix + "thumbnail.vs", glsl_version_prefix + "thumbnail.fs" });
// used to render first layer for calibration
valid &= append_shader("cali", { "cali.vs", "cali.fs"});
valid &= append_shader("flat", {"110/flat.vs", "110/flat.fs"});
valid &= append_shader("flat_instance", {"110/flat_instance.vs", "110/flat.fs"});
valid &= append_shader("flat", { glsl_version_prefix + "flat.vs", glsl_version_prefix + "flat.fs"});
valid &= append_shader("flat_instance", { glsl_version_prefix + "flat_instance.vs", glsl_version_prefix + "flat.fs"});
// used to render printbed
valid &= append_shader("printbed", {"110/printbed.vs", "110/printbed.fs"});
valid &= append_shader("hotbed", {"110/hotbed.vs", "110/hotbed.fs"});
valid &= append_shader("printbed", { glsl_version_prefix + "printbed.vs", glsl_version_prefix + "printbed.fs"});
valid &= append_shader("hotbed", { glsl_version_prefix + "hotbed.vs", glsl_version_prefix + "hotbed.fs"});
// used to render options in gcode preview
if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3))
valid &= append_shader("gouraud_light_instanced", { "gouraud_light_instanced.vs", "gouraud_light_instanced.fs" });
valid &= append_shader("gouraud_light_instanced", { glsl_version_prefix + "gouraud_light_instanced.vs", glsl_version_prefix + "gouraud_light.fs" });
// used to render extrusion and travel paths as lines in gcode preview
valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" });
valid &= append_shader("toolpaths_lines", { glsl_version_prefix + "toolpaths_lines.vs", glsl_version_prefix + "toolpaths_lines.fs" });
// used to render objects in 3d editor
//if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 0)) {
if (0) {
valid &= append_shader("gouraud", { "gouraud_130.vs", "gouraud_130.fs" }
#if ENABLE_ENVIRONMENT_MAP
, { "ENABLE_ENVIRONMENT_MAP"sv }
#endif // ENABLE_ENVIRONMENT_MAP
);
}
else {
valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }
valid &= append_shader("gouraud", { glsl_version_prefix + "gouraud.vs", glsl_version_prefix + "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", { glsl_version_prefix + "variable_layer_height.vs", glsl_version_prefix + "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", { glsl_version_prefix + "mm_contour.vs", glsl_version_prefix + "mm_contour.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.
@ -80,23 +72,30 @@ std::pair<bool, std::string> GLShadersManager::init()
//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_wireframe.vs", "mm_gouraud_wireframe.fs"}, {"FLIP_TRIANGLE_NORMALS"sv});//{"mm_gouraud.vs", "mm_gouraud.fs"}
valid &= append_shader("mm_gouraud", { glsl_version_prefix + "mm_gouraud_wireframe.vs", glsl_version_prefix + "mm_gouraud_wireframe.fs"}, {"FLIP_TRIANGLE_NORMALS"sv});//{"mm_gouraud.vs", "mm_gouraud.fs"}
}
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_wireframe.vs", "mm_gouraud_wireframe.fs"});//{"mm_gouraud.vs", "mm_gouraud.fs"}
valid &= append_shader("mm_gouraud", { glsl_version_prefix + "mm_gouraud_wireframe.vs", glsl_version_prefix + "mm_gouraud_wireframe.fs"});//{"mm_gouraud.vs", "mm_gouraud.fs"}
}
//BBS: add shader for outline
valid &= append_shader("outline", { "outline.vs", "outline.fs" });
valid &= append_shader("silhouette", { glsl_version_prefix + "silhouette.vs", glsl_version_prefix + "silhouette.fs" });
valid &= append_shader("silhouette", { "110/silhouette.vs", "110/silhouette.fs" });
valid &= append_shader("silhouette_composite", { glsl_version_prefix + "silhouette_composite.vs", glsl_version_prefix + "silhouette_composite.fs" });
valid &= append_shader("silhouette_composite", { "110/silhouette_composite.vs", "110/silhouette_composite.fs" });
valid &= append_shader("background", { glsl_version_prefix + "background.vs", glsl_version_prefix + "background.fs" });
valid &= append_shader("imgui", { "110/imgui.vs", "110/imgui.fs" });
valid &= append_shader("flat_texture", { glsl_version_prefix + "flat_texture.vs", glsl_version_prefix + "flat_texture.fs" });
valid &= append_shader("imgui", { glsl_version_prefix + "imgui.vs", glsl_version_prefix + "imgui.fs" });
valid &= append_shader("mainframe_composite", { glsl_version_prefix + "mainframe_composite.vs", glsl_version_prefix + "mainframe_composite.fs" });
valid &= append_shader("fxaa", { glsl_version_prefix + "fxaa.vs", glsl_version_prefix + "fxaa.fs" });
valid &= append_shader("gaussian_blur33", { glsl_version_prefix + "gaussian_blur33.vs", glsl_version_prefix + "gaussian_blur33.fs" });
return { valid, error };
}
@ -106,21 +105,38 @@ void GLShadersManager::shutdown()
m_shaders.clear();
}
GLShaderProgram* GLShadersManager::get_shader(const std::string& shader_name)
const std::shared_ptr<GLShaderProgram>& GLShadersManager::get_shader(const std::string& shader_name) const
{
auto it = std::find_if(m_shaders.begin(), m_shaders.end(), [&shader_name](std::unique_ptr<GLShaderProgram>& p) { return p->get_name() == shader_name; });
return (it != m_shaders.end()) ? it->get() : nullptr;
const auto& it = std::find_if(m_shaders.begin(), m_shaders.end(), [&shader_name](const std::shared_ptr<GLShaderProgram>& p) { return p->get_name() == shader_name; });
if (it != m_shaders.end()) {
return *it;
}
static std::shared_ptr<GLShaderProgram> s_empty_shader{ nullptr };
return s_empty_shader;
}
GLShaderProgram* GLShadersManager::get_current_shader()
std::shared_ptr<GLShaderProgram> GLShadersManager::get_current_shader() const
{
GLint id = 0;
glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, &id));
if (id == 0)
return nullptr;
auto rt = m_current_shader.lock();
return rt;
}
auto it = std::find_if(m_shaders.begin(), m_shaders.end(), [id](std::unique_ptr<GLShaderProgram>& p) { return static_cast<GLint>(p->get_id()) == id; });
return (it != m_shaders.end()) ? it->get() : nullptr;
void GLShadersManager::bind_shader(const std::shared_ptr<GLShaderProgram>& p_shader)
{
if (p_shader) {
p_shader->start_using();
}
else {
glsafe(::glUseProgram(0));
}
m_current_shader = p_shader;
}
void GLShadersManager::unbind_shader()
{
glsafe(::glUseProgram(0));
m_current_shader.reset();
}
} // namespace Slic3r

Some files were not shown because too many files have changed in this diff Show More