diff --git a/resources/shaders/ES/background.fs b/resources/shaders/ES/background.fs new file mode 100644 index 000000000..5f46e658f --- /dev/null +++ b/resources/shaders/ES/background.fs @@ -0,0 +1,13 @@ +#version 100 + +precision highp float; + +uniform vec4 top_color; +uniform vec4 bottom_color; + +varying vec2 tex_coord; + +void main() +{ + gl_FragColor = mix(bottom_color, top_color, tex_coord.y); +} diff --git a/resources/shaders/ES/background.vs b/resources/shaders/ES/background.vs new file mode 100644 index 000000000..6334c83b1 --- /dev/null +++ b/resources/shaders/ES/background.vs @@ -0,0 +1,12 @@ +#version 100 + +attribute vec3 v_position; +attribute vec2 v_tex_coord; + +varying vec2 tex_coord; + +void main() +{ + tex_coord = v_tex_coord; + gl_Position = vec4(v_position, 1.0); +} diff --git a/resources/shaders/ES/dashed_lines.fs b/resources/shaders/ES/dashed_lines.fs new file mode 100644 index 000000000..9aecd0240 --- /dev/null +++ b/resources/shaders/ES/dashed_lines.fs @@ -0,0 +1,20 @@ +#version 100 + +precision highp float; + +// see as reference: https://stackoverflow.com/questions/52928678/dashed-line-in-opengl3 + +uniform float dash_size; +uniform float gap_size; +uniform vec4 uniform_color; + +varying float coord_s; + +void main() +{ + float inv_stride = 1.0 / (dash_size + gap_size); + if (gap_size > 0.0 && fract(coord_s * inv_stride) > dash_size * inv_stride) + discard; + + gl_FragColor = uniform_color; +} diff --git a/resources/shaders/ES/dashed_lines.vs b/resources/shaders/ES/dashed_lines.vs new file mode 100644 index 000000000..540715a11 --- /dev/null +++ b/resources/shaders/ES/dashed_lines.vs @@ -0,0 +1,17 @@ +#version 100 + +// see as reference: https://stackoverflow.com/questions/52928678/dashed-line-in-opengl3 + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; + +// v_position.w = coordinate along the line +attribute vec4 v_position; + +varying float coord_s; + +void main() +{ + coord_s = v_position.w; + gl_Position = projection_matrix * view_model_matrix * vec4(v_position.xyz, 1.0); +} \ No newline at end of file diff --git a/resources/shaders/ES/flat.fs b/resources/shaders/ES/flat.fs new file mode 100644 index 000000000..f27e5d38c --- /dev/null +++ b/resources/shaders/ES/flat.fs @@ -0,0 +1,10 @@ +#version 100 + +precision highp float; + +uniform vec4 uniform_color; + +void main() +{ + gl_FragColor = uniform_color; +} diff --git a/resources/shaders/ES/flat.vs b/resources/shaders/ES/flat.vs new file mode 100644 index 000000000..a83587239 --- /dev/null +++ b/resources/shaders/ES/flat.vs @@ -0,0 +1,11 @@ +#version 100 + +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); +} diff --git a/resources/shaders/ES/flat_clip.fs b/resources/shaders/ES/flat_clip.fs new file mode 100644 index 000000000..8de7d1921 --- /dev/null +++ b/resources/shaders/ES/flat_clip.fs @@ -0,0 +1,17 @@ +#version 100 + +precision highp float; + +const vec3 ZERO = vec3(0.0, 0.0, 0.0); + +uniform vec4 uniform_color; + +varying vec3 clipping_planes_dots; + +void main() +{ + if (any(lessThan(clipping_planes_dots, ZERO))) + discard; + + gl_FragColor = uniform_color; +} diff --git a/resources/shaders/ES/flat_clip.vs b/resources/shaders/ES/flat_clip.vs new file mode 100644 index 000000000..baf5a3385 --- /dev/null +++ b/resources/shaders/ES/flat_clip.vs @@ -0,0 +1,23 @@ +#version 100 + +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; + +varying vec3 clipping_planes_dots; + +void main() +{ + // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded. + vec4 world_pos = volume_world_matrix * vec4(v_position, 1.0); + clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); + + gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); +} diff --git a/resources/shaders/ES/flat_texture.fs b/resources/shaders/ES/flat_texture.fs new file mode 100644 index 000000000..ec41960f7 --- /dev/null +++ b/resources/shaders/ES/flat_texture.fs @@ -0,0 +1,12 @@ +#version 100 + +precision highp float; + +uniform sampler2D uniform_texture; + +varying vec2 tex_coord; + +void main() +{ + gl_FragColor = texture2D(uniform_texture, tex_coord); +} diff --git a/resources/shaders/ES/flat_texture.vs b/resources/shaders/ES/flat_texture.vs new file mode 100644 index 000000000..e83cacd59 --- /dev/null +++ b/resources/shaders/ES/flat_texture.vs @@ -0,0 +1,15 @@ +#version 100 + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; + +attribute vec3 v_position; +attribute vec2 v_tex_coord; + +varying vec2 tex_coord; + +void main() +{ + tex_coord = v_tex_coord; + gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); +} diff --git a/resources/shaders/ES/gouraud.fs b/resources/shaders/ES/gouraud.fs new file mode 100644 index 000000000..368a50279 --- /dev/null +++ b/resources/shaders/ES/gouraud.fs @@ -0,0 +1,81 @@ +#version 100 + +precision highp float; + +const vec3 ZERO = vec3(0.0, 0.0, 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; +}; + +uniform vec4 uniform_color; +uniform SlopeDetection slope; + +#ifdef ENABLE_ENVIRONMENT_MAP + uniform sampler2D environment_tex; + uniform bool use_environment_tex; +#endif // ENABLE_ENVIRONMENT_MAP + +uniform PrintVolumeDetection print_volume; + +varying vec3 clipping_planes_dots; + +// x = diffuse, y = specular; +varying vec2 intensity; + +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); + 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); + } + 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; + +#ifdef ENABLE_ENVIRONMENT_MAP + 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); + else +#endif + gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha); +} diff --git a/resources/shaders/ES/gouraud.vs b/resources/shaders/ES/gouraud.vs new file mode 100644 index 000000000..431e48556 --- /dev/null +++ b/resources/shaders/ES/gouraud.vs @@ -0,0 +1,77 @@ +#version 100 + +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) +//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION) +//#define LIGHT_FRONT_SHININESS 5.0 + +#define INTENSITY_AMBIENT 0.3 + +const vec3 ZERO = vec3(0.0, 0.0, 0.0); + +struct SlopeDetection +{ + bool actived; + float normal_z; + mat3 volume_world_normal_matrix; +}; + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat3 view_normal_matrix; +uniform mat4 volume_world_matrix; +uniform SlopeDetection slope; + +// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane. +uniform vec2 z_range; +// Clipping plane - general orientation. Used by the SLA gizmo. +uniform vec4 clipping_plane; + +attribute vec3 v_position; +attribute vec3 v_normal; + +// x = diffuse, y = specular; +varying vec2 intensity; + +varying vec3 clipping_planes_dots; + +varying vec4 world_pos; +varying float world_normal_z; +varying vec3 eye_normal; + +void main() +{ + // First transform the normal into camera space and normalize the result. + eye_normal = normalize(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(eye_normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + vec4 position = view_model_matrix * vec4(v_position, 1.0); + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + // Point in homogenous coordinates. + world_pos = volume_world_matrix * vec4(v_position, 1.0); + + // z component of normal vector in world coordinate used for slope shading + world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * v_normal)).z : 0.0; + + gl_Position = projection_matrix * position; + // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded. + clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); +} diff --git a/resources/shaders/ES/gouraud_light.fs b/resources/shaders/ES/gouraud_light.fs new file mode 100644 index 000000000..a8de5879c --- /dev/null +++ b/resources/shaders/ES/gouraud_light.fs @@ -0,0 +1,14 @@ +#version 100 + +precision highp float; + +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); +} diff --git a/resources/shaders/ES/gouraud_light.vs b/resources/shaders/ES/gouraud_light.vs new file mode 100644 index 000000000..98bde435d --- /dev/null +++ b/resources/shaders/ES/gouraud_light.vs @@ -0,0 +1,45 @@ +#version 100 + +#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; + +attribute vec3 v_position; +attribute vec3 v_normal; + +// x = tainted, y = specular; +varying vec2 intensity; + +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; + vec4 position = view_model_matrix * vec4(v_position, 1.0); + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + gl_Position = projection_matrix * position; +} diff --git a/resources/shaders/ES/gouraud_light_instanced.fs b/resources/shaders/ES/gouraud_light_instanced.fs new file mode 100644 index 000000000..d737137ee --- /dev/null +++ b/resources/shaders/ES/gouraud_light_instanced.fs @@ -0,0 +1,12 @@ +#version 100 + +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); +} diff --git a/resources/shaders/ES/gouraud_light_instanced.vs b/resources/shaders/ES/gouraud_light_instanced.vs new file mode 100644 index 000000000..0aebd7a0b --- /dev/null +++ b/resources/shaders/ES/gouraud_light_instanced.vs @@ -0,0 +1,50 @@ +#version 100 + +#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; + +// vertex attributes +attribute vec3 v_position; +attribute vec3 v_normal; +// instance attributes +attribute vec3 i_offset; +attribute vec2 i_scales; + +// x = tainted, y = specular; +varying vec2 intensity; + +void main() +{ + // First transform the normal into camera space and normalize the result. + vec3 eye_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(eye_normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + vec4 world_position = vec4(v_position * vec3(vec2(1.5 * i_scales.x), 1.5 * i_scales.y) + i_offset - vec3(0.0, 0.0, 0.5 * i_scales.y), 1.0); + vec4 eye_position = view_model_matrix * world_position; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position.xyz), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + gl_Position = projection_matrix * eye_position; +} diff --git a/resources/shaders/ES/imgui.fs b/resources/shaders/ES/imgui.fs new file mode 100644 index 000000000..2174f955d --- /dev/null +++ b/resources/shaders/ES/imgui.fs @@ -0,0 +1,13 @@ +#version 100 + +precision highp float; + +uniform sampler2D Texture; + +varying vec2 Frag_UV; +varying vec4 Frag_Color; + +void main() +{ + gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st); +} \ No newline at end of file diff --git a/resources/shaders/ES/imgui.vs b/resources/shaders/ES/imgui.vs new file mode 100644 index 000000000..7abb3f405 --- /dev/null +++ b/resources/shaders/ES/imgui.vs @@ -0,0 +1,17 @@ +#version 100 + +uniform mat4 ProjMtx; + +attribute vec2 Position; +attribute vec2 UV; +attribute vec4 Color; + +varying vec2 Frag_UV; +varying vec4 Frag_Color; + +void main() +{ + Frag_UV = UV; + Frag_Color = Color; + gl_Position = ProjMtx * vec4(Position.xy, 0.0, 1.0); +} \ No newline at end of file diff --git a/resources/shaders/ES/mm_contour.fs b/resources/shaders/ES/mm_contour.fs new file mode 100644 index 000000000..f27e5d38c --- /dev/null +++ b/resources/shaders/ES/mm_contour.fs @@ -0,0 +1,10 @@ +#version 100 + +precision highp float; + +uniform vec4 uniform_color; + +void main() +{ + gl_FragColor = uniform_color; +} diff --git a/resources/shaders/ES/mm_contour.vs b/resources/shaders/ES/mm_contour.vs new file mode 100644 index 000000000..7142a5de6 --- /dev/null +++ b/resources/shaders/ES/mm_contour.vs @@ -0,0 +1,15 @@ +#version 100 + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform float offset; + +attribute vec3 v_position; + +void main() +{ + // Add small epsilon to z to solve z-fighting + vec4 clip_position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); + clip_position.z -= offset * abs(clip_position.w); + gl_Position = clip_position; +} diff --git a/resources/shaders/ES/mm_gouraud.fs b/resources/shaders/ES/mm_gouraud.fs new file mode 100644 index 000000000..4824753f1 --- /dev/null +++ b/resources/shaders/ES/mm_gouraud.fs @@ -0,0 +1,66 @@ +#version 100 +#extension GL_OES_standard_derivatives : enable + +precision highp float; + +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +#define INTENSITY_AMBIENT 0.3 + +const vec3 ZERO = vec3(0.0, 0.0, 0.0); +const float EPSILON = 0.0001; + +uniform vec4 uniform_color; + +uniform bool volume_mirrored; + +uniform mat4 view_model_matrix; +uniform mat3 view_normal_matrix; + +varying vec3 clipping_planes_dots; +varying vec4 model_pos; + +void main() +{ + if (any(lessThan(clipping_planes_dots, ZERO))) + discard; + vec3 color = uniform_color.rgb; + float alpha = uniform_color.a; + + vec3 triangle_normal = normalize(cross(dFdx(model_pos.xyz), dFdy(model_pos.xyz))); +#ifdef FLIP_TRIANGLE_NORMALS + triangle_normal = -triangle_normal; +#endif + + if (volume_mirrored) + triangle_normal = -triangle_normal; + + // First transform the normal into camera space and normalize the result. + vec3 eye_normal = normalize(view_normal_matrix * triangle_normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0); + + // x = diffuse, y = specular; + vec2 intensity = vec2(0.0); + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + vec3 position = (view_model_matrix * model_pos).xyz; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha); +} diff --git a/resources/shaders/ES/mm_gouraud.vs b/resources/shaders/ES/mm_gouraud.vs new file mode 100644 index 000000000..8ad5fca68 --- /dev/null +++ b/resources/shaders/ES/mm_gouraud.vs @@ -0,0 +1,28 @@ +#version 100 + +const vec3 ZERO = vec3(0.0, 0.0, 0.0); + +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; + +varying vec3 clipping_planes_dots; +varying vec4 model_pos; + +void main() +{ + model_pos = vec4(v_position, 1.0); + // Point in homogenous coordinates. + vec4 world_pos = volume_world_matrix * model_pos; + + gl_Position = projection_matrix * view_model_matrix * model_pos; + // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded. + clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); +} diff --git a/resources/shaders/ES/printbed.fs b/resources/shaders/ES/printbed.fs new file mode 100644 index 000000000..517536467 --- /dev/null +++ b/resources/shaders/ES/printbed.fs @@ -0,0 +1,38 @@ +#version 100 + +precision highp float; + +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 bool transparent_background; +uniform bool svg_source; + +varying vec2 tex_coord; + +vec4 svg_color() +{ + // takes foreground from texture + vec4 fore_color = texture2D(texture, tex_coord); + + // calculates radial gradient + vec3 back_color = vec3(mix(back_color_light, back_color_dark, smoothstep(0.0, 0.5, length(abs(tex_coord.xy) - vec2(0.5))))); + + // blends foreground with background + return vec4(mix(back_color, fore_color.rgb, fore_color.a), transparent_background ? fore_color.a : 1.0); +} + +vec4 non_svg_color() +{ + // takes foreground from texture + vec4 color = texture2D(texture, tex_coord); + return vec4(color.rgb, transparent_background ? color.a * 0.25 : color.a); +} + +void main() +{ + vec4 color = svg_source ? svg_color() : non_svg_color(); + color.a = transparent_background ? color.a * 0.5 : color.a; + gl_FragColor = color; +} \ No newline at end of file diff --git a/resources/shaders/ES/printbed.vs b/resources/shaders/ES/printbed.vs new file mode 100644 index 000000000..e83cacd59 --- /dev/null +++ b/resources/shaders/ES/printbed.vs @@ -0,0 +1,15 @@ +#version 100 + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; + +attribute vec3 v_position; +attribute vec2 v_tex_coord; + +varying vec2 tex_coord; + +void main() +{ + tex_coord = v_tex_coord; + gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); +} diff --git a/resources/shaders/ES/toolpaths_cog.fs b/resources/shaders/ES/toolpaths_cog.fs new file mode 100644 index 000000000..f5e4404be --- /dev/null +++ b/resources/shaders/ES/toolpaths_cog.fs @@ -0,0 +1,21 @@ +#version 100 + +precision highp float; + +const vec4 BLACK = vec4(vec3(0.1), 1.0); +const vec4 WHITE = vec4(vec3(1.0), 1.0); + +const float emission_factor = 0.25; + +uniform vec3 world_center; + +// x = tainted, y = specular; +varying vec2 intensity; +varying vec3 world_position; + +void main() +{ + vec3 delta = world_position - world_center; + vec4 color = delta.x * delta.y * delta.z > 0.0 ? BLACK : WHITE; + gl_FragColor = vec4(vec3(intensity.y) + color.rgb * (intensity.x + emission_factor), 1.0); +} diff --git a/resources/shaders/ES/toolpaths_cog.vs b/resources/shaders/ES/toolpaths_cog.vs new file mode 100644 index 000000000..72b5835bd --- /dev/null +++ b/resources/shaders/ES/toolpaths_cog.vs @@ -0,0 +1,47 @@ +#version 100 + +#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; + +attribute vec3 v_position; +attribute vec3 v_normal; + +// x = tainted, y = specular; +varying vec2 intensity; +varying vec3 world_position; + +void main() +{ + // First transform the normal into camera space and normalize the result. + vec3 normal = normalize(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; + vec4 position = view_model_matrix * vec4(v_position, 1.0); + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + world_position = v_position; + gl_Position = projection_matrix * position; +} diff --git a/resources/shaders/ES/variable_layer_height.fs b/resources/shaders/ES/variable_layer_height.fs new file mode 100644 index 000000000..ac96f31b7 --- /dev/null +++ b/resources/shaders/ES/variable_layer_height.fs @@ -0,0 +1,44 @@ +#version 100 +#extension GL_OES_standard_derivatives : enable + +precision highp float; + +#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; +varying vec2 intensity; + +varying float object_z; + +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(texture2D(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row + 0.5 )), -10000.), + texture2D(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row * 2. + 1.)), 10000.), lod); + // Mix the final color. + gl_FragColor = vec4(vec3(intensity.y), 1.0) + intensity.x * mix(color, vec4(1.0, 1.0, 0.0, 1.0), z_blend); +} diff --git a/resources/shaders/ES/variable_layer_height.vs b/resources/shaders/ES/variable_layer_height.vs new file mode 100644 index 000000000..8deaf8368 --- /dev/null +++ b/resources/shaders/ES/variable_layer_height.vs @@ -0,0 +1,60 @@ +#version 100 + +#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 + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat3 view_normal_matrix; +uniform mat4 volume_world_matrix; +uniform float object_max_z; + +attribute vec3 v_position; +attribute vec3 v_normal; +attribute vec2 v_tex_coord; + +// x = tainted, y = specular; +varying vec2 intensity; + +varying float object_z; + +void main() +{ + // ===================================================== + // NOTE: + // when object_max_z > 0.0 we are rendering the overlay + // when object_max_z == 0.0 we are rendering the volumes + // ===================================================== + + // First transform the normal into camera space and normalize the result. + vec3 normal = (object_max_z > 0.0) ? vec3(0.0, 0.0, 1.0) : normalize(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; + vec4 position = view_model_matrix * vec4(v_position, 1.0); + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular) + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + // Scaled to widths of the Z texture. + object_z = (object_max_z > 0.0) ? object_max_z * v_tex_coord.y : (volume_world_matrix * vec4(v_position, 1.0)).z; + + gl_Position = projection_matrix * position; +} diff --git a/resources/shaders/ES/wireframe.fs b/resources/shaders/ES/wireframe.fs new file mode 100644 index 000000000..036ee8879 --- /dev/null +++ b/resources/shaders/ES/wireframe.fs @@ -0,0 +1,19 @@ +#version 100 +#extension GL_OES_standard_derivatives : enable + +// see for reference: https://stackoverflow.com/questions/7361582/opengl-debugging-single-pass-wireframe-rendering + +precision highp float; + +uniform vec4 uniform_color; + +varying vec3 barycentric; + +void main() +{ + float min_dist = min(min(barycentric.x, barycentric.y), barycentric.z); + if (min_dist > 0.5 * fwidth(min_dist)) + discard; + + gl_FragColor = uniform_color; +} \ No newline at end of file diff --git a/resources/shaders/ES/wireframe.vs b/resources/shaders/ES/wireframe.vs new file mode 100644 index 000000000..00a5214f5 --- /dev/null +++ b/resources/shaders/ES/wireframe.vs @@ -0,0 +1,20 @@ +#version 100 + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform float offset; + +attribute vec3 v_position; +attribute vec3 v_normal; +attribute vec3 v_extra; + +varying vec3 barycentric; + +void main() +{ + barycentric = v_extra; + // Add small epsilon to z to solve z-fighting + vec4 clip_position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); + clip_position.z -= offset * abs(clip_position.w); + gl_Position = clip_position; +} \ No newline at end of file diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 92f21e90a..ee2c0cd80 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -53,8 +53,10 @@ #define ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL (1 && ENABLE_2_5_0_ALPHA1) // Enable removal of legacy OpenGL calls #define ENABLE_LEGACY_OPENGL_REMOVAL (1 && ENABLE_2_5_0_ALPHA1) +// Enable OpenGL ES +#define ENABLE_OPENGL_ES (0 && ENABLE_LEGACY_OPENGL_REMOVAL) // Enable OpenGL core profile context (tested against Mesa 20.1.8 on Windows) -#define ENABLE_GL_CORE_PROFILE (1 && ENABLE_LEGACY_OPENGL_REMOVAL) +#define ENABLE_GL_CORE_PROFILE (1 && ENABLE_LEGACY_OPENGL_REMOVAL && !ENABLE_OPENGL_ES) // Enable OpenGL debug messages using debug context #define ENABLE_OPENGL_DEBUG_OPTION (1 && ENABLE_GL_CORE_PROFILE) // Shows an imgui dialog with GLModel statistics data diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 19c12b803..32b21e4f9 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -913,13 +913,25 @@ void GLVolumeCollection::load_object_auxiliary( #if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL +#if ENABLE_OPENGL_ES +int GLVolumeCollection::load_wipe_tower_preview( + float pos_x, float pos_y, float width, float depth, float height, + float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh) +#else int GLVolumeCollection::load_wipe_tower_preview( float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width) +#endif // ENABLE_OPENGL_ES +#else +#if ENABLE_OPENGL_ES +int GLVolumeCollection::load_wipe_tower_preview( + int obj_idx, float pos_x, float pos_y, float width, float depth, float height, + float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh) #else int GLVolumeCollection::load_wipe_tower_preview( int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width) +#endif // ENABLE_OPENGL_ES #endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL #else #if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL @@ -1180,6 +1192,10 @@ int GLVolumeCollection::load_wipe_tower_preview( volumes.emplace_back(new GLVolume(color)); GLVolume& v = *volumes.back(); #if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_OPENGL_ES + if (out_mesh != nullptr) + *out_mesh = mesh; +#endif // ENABLE_OPENGL_ES v.model.init_from(mesh); v.model.set_color(color); #if ENABLE_RAYCAST_PICKING diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 02a4715ee..b48ad90a8 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -669,11 +669,21 @@ public: size_t timestamp); #if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL +#if ENABLE_OPENGL_ES + int load_wipe_tower_preview( + float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh = nullptr); +#else int load_wipe_tower_preview( float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width); +#endif // ENABLE_OPENGL_ES +#else +#if ENABLE_OPENGL_ES + int load_wipe_tower_preview( + int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh = nullptr); #else int load_wipe_tower_preview( int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width); +#endif // ENABLE_OPENGL_ES #endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL #else std::vector load_object( diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index c153e34dd..3e7939749 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1214,9 +1214,16 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const // get vertices/normals data from vertex buffers on gpu for (size_t i = 0; i < t_buffer.vertices.vbos.size(); ++i) { const size_t floats_count = t_buffer.vertices.sizes[i] / sizeof(float); - VertexBuffer vertices(floats_count); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, t_buffer.vertices.vbos[i])); +#if ENABLE_OPENGL_ES + const VertexBuffer vertices = *static_cast(::glMapBufferRange(GL_ARRAY_BUFFER, 0, + static_cast(t_buffer.vertices.sizes[i]), GL_MAP_READ_BIT)); + glcheck(); + glsafe(::glUnmapBuffer(GL_ARRAY_BUFFER)); +#else + VertexBuffer vertices(floats_count); glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, 0, static_cast(t_buffer.vertices.sizes[i]), static_cast(vertices.data()))); +#endif // ENABLE_OPENGL_ES glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); const size_t vertices_count = floats_count / floats_per_vertex; for (size_t j = 0; j < vertices_count; ++j) { @@ -1264,9 +1271,17 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const // get indices data from index buffer on gpu glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuffer.ibo)); for (size_t j = 0; j < render_path.sizes.size(); ++j) { +#if ENABLE_OPENGL_ES + const IndexBuffer indices = *static_cast(::glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, + static_cast(render_path.offsets[j]), static_cast(render_path.sizes[j] * sizeof(IBufferType)), + GL_MAP_READ_BIT)); + glcheck(); + glsafe(::glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER)); +#else IndexBuffer indices(render_path.sizes[j]); glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast(render_path.offsets[j]), static_cast(render_path.sizes[j] * sizeof(IBufferType)), static_cast(indices.data()))); +#endif // ENABLE_OPENGL_ES const size_t triangles_count = render_path.sizes[j] / 3; for (size_t k = 0; k < triangles_count; ++k) { @@ -2678,14 +2693,30 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool // gets the vertex index from the index buffer on gpu const IBuffer& i_buffer = buffer.indices[sub_path.first.b_id]; - IBufferType index = 0; glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); +#if ENABLE_OPENGL_ES + IBufferType index = *static_cast(::glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, + static_cast(offset * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), + GL_MAP_READ_BIT)); + glcheck(); + glsafe(::glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER)); +#else + IBufferType index = 0; glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast(offset * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&index))); +#endif // ENABLE_OPENGL_ES glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); // gets the position from the vertices buffer on gpu glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); +#if ENABLE_OPENGL_ES + sequential_view->current_position = *static_cast(::glMapBufferRange(GL_ARRAY_BUFFER, + static_cast(index * buffer.vertices.vertex_size_bytes()), + static_cast(buffer.vertices.position_size_bytes()), GL_MAP_READ_BIT)); + glcheck(); + glsafe(::glUnmapBuffer(GL_ARRAY_BUFFER)); +#else glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(index * buffer.vertices.vertex_size_bytes()), static_cast(3 * sizeof(float)), static_cast(sequential_view->current_position.data()))); +#endif // ENABLE_OPENGL_ES glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); sequential_view->current_offset = Vec3f::Zero(); @@ -2893,10 +2924,22 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool // extract indices from index buffer std::array indices{ 0, 0, 0, 0, 0, 0 }; glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); +#if ENABLE_OPENGL_ES + IBufferType* index_ptr = static_cast(::glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, + static_cast(offset * sizeof(IBufferType)), static_cast(14 * sizeof(IBufferType)), + GL_MAP_READ_BIT)); + glcheck(); + indices[0] = *(index_ptr + 0); + indices[1] = *(index_ptr + 7); + indices[2] = *(index_ptr + 1); + indices[4] = *(index_ptr + 13); + glsafe(::glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER)); +#else glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 0) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[0]))); glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 7) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[1]))); glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 1) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[2]))); glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 13) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[4]))); +#endif // ENABLE_OPENGL_ES glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); indices[3] = indices[0]; indices[5] = indices[1]; @@ -2942,10 +2985,22 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool // extract indices from index buffer std::array indices{ 0, 0, 0, 0, 0, 0 }; glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo)); +#if ENABLE_OPENGL_ES + IBufferType* index_ptr = static_cast(::glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, + static_cast(offset * sizeof(IBufferType)), static_cast(17 * sizeof(IBufferType)), + GL_MAP_READ_BIT)); + glcheck(); + indices[0] = *(index_ptr + 2); + indices[1] = *(index_ptr + 4); + indices[2] = *(index_ptr + 10); + indices[5] = *(index_ptr + 16); + glsafe(::glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER)); +#else glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 2) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[0]))); glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 4) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[1]))); glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 10) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[2]))); glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast((offset + 16) * sizeof(IBufferType)), static_cast(sizeof(IBufferType)), static_cast(&indices[5]))); +#endif // ENABLE_OPENGL_ES glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); indices[3] = indices[0]; indices[4] = indices[2]; @@ -3027,7 +3082,13 @@ void GCodeViewer::render_toolpaths() shader.set_uniform("gap_size", 0.0f); #endif // ENABLE_GL_CORE_PROFILE +#if ENABLE_OPENGL_ES + for (size_t i = 0; i < path.sizes.size(); ++i) { + glsafe(::glDrawElements(GL_LINES, (GLsizei)path.sizes[i], GL_UNSIGNED_SHORT, (const void*)path.offsets[i])); + } +#else glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); +#endif // ENABLE_OPENGL_ES #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_lines_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -3045,7 +3106,13 @@ void GCodeViewer::render_toolpaths() assert(! path.sizes.empty()); assert(! path.offsets.empty()); shader.set_uniform(uniform_color, path.color); +#if ENABLE_OPENGL_ES + for (size_t i = 0; i < path.sizes.size(); ++i) { + glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)path.sizes[i], GL_UNSIGNED_SHORT, (const void*)path.offsets[i])); + } +#else glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); +#endif // ENABLE_OPENGL_ES #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_triangles_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9d74874a8..dcc0d2db4 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1215,7 +1215,11 @@ bool GLCanvas3D::init() return false; glsafe(::glClearColor(1.0f, 1.0f, 1.0f, 1.0f)); +#if ENABLE_OPENGL_ES + glsafe(::glClearDepthf(1.0f)); +#else glsafe(::glClearDepth(1.0f)); +#endif // ENABLE_OPENGL_ES glsafe(::glDepthFunc(GL_LESS)); @@ -2076,6 +2080,9 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re if (volume->is_wipe_tower) { // There is only one wipe tower. assert(volume_idx_wipe_tower_old == -1); +#if ENABLE_OPENGL_ES + m_wipe_tower_mesh.clear(); +#endif // ENABLE_OPENGL_ES volume_idx_wipe_tower_old = (int)volume_id; } if (!m_reload_delayed) { @@ -2324,13 +2331,25 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re #if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL +#if ENABLE_OPENGL_ES + int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( + x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), + brim_width, &m_wipe_tower_mesh); +#else int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), brim_width); +#endif // ENABLE_OPENGL_ES +#else +#if ENABLE_OPENGL_ES + int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( + 1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), + brim_width, &m_wipe_tower_mesh); #else int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( 1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), brim_width); +#endif // ENABLE_OPENGL_ES #endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL #else #if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL @@ -5642,7 +5661,11 @@ void GLCanvas3D::_rectangular_selection_picking_pass() glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, render_tex, 0)); glsafe(::glGenRenderbuffers(1, &render_depth)); glsafe(::glBindRenderbuffer(GL_RENDERBUFFER, render_depth)); +#if ENABLE_OPENGL_ES + glsafe(::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height)); +#else glsafe(::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height)); +#endif // ENABLE_OPENGL_ES glsafe(::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, render_depth)); } else { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 2d3698980..4b78b66d9 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -517,6 +517,9 @@ private: bool m_event_handlers_bound{ false }; GLVolumeCollection m_volumes; +#if ENABLE_OPENGL_ES + TriangleMesh m_wipe_tower_mesh; +#endif // ENABLE_OPENGL_ES GCodeViewer m_gcode_viewer; RenderTimer m_render_timer; diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 50c53d1f7..5ae7f9fbf 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -125,6 +125,22 @@ void GLModel::Geometry::add_vertex(const Vec3f& position, const Vec3f& normal, c vertices.emplace_back(tex_coord.y()); } +#if ENABLE_OPENGL_ES +void GLModel::Geometry::add_vertex(const Vec3f& position, const Vec3f& normal, const Vec3f& extra) +{ + assert(format.vertex_layout == EVertexLayout::P3N3E3); + vertices.emplace_back(position.x()); + vertices.emplace_back(position.y()); + vertices.emplace_back(position.z()); + vertices.emplace_back(normal.x()); + vertices.emplace_back(normal.y()); + vertices.emplace_back(normal.z()); + vertices.emplace_back(extra.x()); + vertices.emplace_back(extra.y()); + vertices.emplace_back(extra.z()); +} +#endif // ENABLE_OPENGL_ES + void GLModel::Geometry::add_vertex(const Vec4f& position) { assert(format.vertex_layout == EVertexLayout::P4); @@ -272,6 +288,9 @@ size_t GLModel::Geometry::vertex_stride_floats(const Format& format) case EVertexLayout::P3T2: { return 5; } case EVertexLayout::P3N3: { return 6; } case EVertexLayout::P3N3T2: { return 8; } +#if ENABLE_OPENGL_ES + case EVertexLayout::P3N3E3: { return 9; } +#endif // ENABLE_OPENGL_ES case EVertexLayout::P4: { return 4; } default: { assert(false); return 0; } }; @@ -286,7 +305,12 @@ size_t GLModel::Geometry::position_stride_floats(const Format& format) case EVertexLayout::P3: case EVertexLayout::P3T2: case EVertexLayout::P3N3: +#if ENABLE_OPENGL_ES + case EVertexLayout::P3N3T2: + case EVertexLayout::P3N3E3: { return 3; } +#else case EVertexLayout::P3N3T2: { return 3; } +#endif // ENABLE_OPENGL_ES case EVertexLayout::P4: { return 4; } default: { assert(false); return 0; } }; @@ -302,6 +326,9 @@ size_t GLModel::Geometry::position_offset_floats(const Format& format) case EVertexLayout::P3T2: case EVertexLayout::P3N3: case EVertexLayout::P3N3T2: +#if ENABLE_OPENGL_ES + case EVertexLayout::P3N3E3: +#endif // ENABLE_OPENGL_ES case EVertexLayout::P4: { return 0; } default: { assert(false); return 0; } }; @@ -312,7 +339,12 @@ size_t GLModel::Geometry::normal_stride_floats(const Format& format) switch (format.vertex_layout) { case EVertexLayout::P3N3: +#if ENABLE_OPENGL_ES + case EVertexLayout::P3N3T2: + case EVertexLayout::P3N3E3: { return 3; } +#else case EVertexLayout::P3N3T2: { return 3; } +#endif // ENABLE_OPENGL_ES default: { assert(false); return 0; } }; } @@ -322,7 +354,12 @@ size_t GLModel::Geometry::normal_offset_floats(const Format& format) switch (format.vertex_layout) { case EVertexLayout::P3N3: +#if ENABLE_OPENGL_ES + case EVertexLayout::P3N3T2: + case EVertexLayout::P3N3E3: { return 3; } +#else case EVertexLayout::P3N3T2: { return 3; } +#endif // ENABLE_OPENGL_ES default: { assert(false); return 0; } }; } @@ -349,6 +386,26 @@ size_t GLModel::Geometry::tex_coord_offset_floats(const Format& format) }; } +#if ENABLE_OPENGL_ES +size_t GLModel::Geometry::extra_stride_floats(const Format& format) +{ + switch (format.vertex_layout) + { + case EVertexLayout::P3N3E3: { return 3; } + default: { assert(false); return 0; } + }; +} + +size_t GLModel::Geometry::extra_offset_floats(const Format& format) +{ + switch (format.vertex_layout) + { + case EVertexLayout::P3N3E3: { return 6; } + default: { assert(false); return 0; } + }; +} +#endif // ENABLE_OPENGL_ES + size_t GLModel::Geometry::index_stride_bytes(const Geometry& data) { switch (data.index_type) @@ -370,6 +427,9 @@ bool GLModel::Geometry::has_position(const Format& format) case EVertexLayout::P3T2: case EVertexLayout::P3N3: case EVertexLayout::P3N3T2: +#if ENABLE_OPENGL_ES + case EVertexLayout::P3N3E3: +#endif // ENABLE_OPENGL_ES case EVertexLayout::P4: { return true; } default: { assert(false); return false; } }; @@ -385,7 +445,12 @@ bool GLModel::Geometry::has_normal(const Format& format) case EVertexLayout::P3T2: case EVertexLayout::P4: { return false; } case EVertexLayout::P3N3: +#if ENABLE_OPENGL_ES + case EVertexLayout::P3N3T2: + case EVertexLayout::P3N3E3: { return true; } +#else case EVertexLayout::P3N3T2: { return true; } +#endif // ENABLE_OPENGL_ES default: { assert(false); return false; } }; } @@ -400,10 +465,31 @@ bool GLModel::Geometry::has_tex_coord(const Format& format) case EVertexLayout::P2: case EVertexLayout::P3: case EVertexLayout::P3N3: +#if ENABLE_OPENGL_ES + case EVertexLayout::P3N3E3: +#endif // ENABLE_OPENGL_ES case EVertexLayout::P4: { return false; } default: { assert(false); return false; } }; } + +#if ENABLE_OPENGL_ES +bool GLModel::Geometry::has_extra(const Format& format) +{ + switch (format.vertex_layout) + { + case EVertexLayout::P3N3E3: { return true; } + case EVertexLayout::P2: + case EVertexLayout::P2T2: + case EVertexLayout::P3: + case EVertexLayout::P3T2: + case EVertexLayout::P3N3: + case EVertexLayout::P3N3T2: + case EVertexLayout::P4: { return false; } + default: { assert(false); return false; } + }; +} +#endif // ENABLE_OPENGL_ES #else size_t GLModel::Geometry::vertices_count() const { @@ -887,6 +973,9 @@ void GLModel::render(const std::pair& range) const bool position = Geometry::has_position(data.format); const bool normal = Geometry::has_normal(data.format); const bool tex_coord = Geometry::has_tex_coord(data.format); +#if ENABLE_OPENGL_ES + const bool extra = Geometry::has_extra(data.format); +#endif // ENABLE_OPENGL_ES #if ENABLE_GL_CORE_PROFILE if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) @@ -895,9 +984,12 @@ void GLModel::render(const std::pair& range) #endif // ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id)); - int position_id = -1; - int normal_id = -1; + int position_id = -1; + int normal_id = -1; int tex_coord_id = -1; +#if ENABLE_OPENGL_ES + int extra_id = -1; +#endif // ENABLE_OPENGL_ES if (position) { position_id = shader->get_attrib_location("v_position"); @@ -920,6 +1012,15 @@ void GLModel::render(const std::pair& range) glsafe(::glEnableVertexAttribArray(tex_coord_id)); } } +#if ENABLE_OPENGL_ES + if (extra) { + extra_id = shader->get_attrib_location("v_extra"); + if (extra_id != -1) { + glsafe(::glVertexAttribPointer(extra_id, Geometry::extra_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (const void*)Geometry::extra_offset_bytes(data.format))); + glsafe(::glEnableVertexAttribArray(extra_id)); + } + } +#endif // ENABLE_OPENGL_ES shader->set_uniform("uniform_color", data.color); @@ -932,6 +1033,10 @@ void GLModel::render(const std::pair& range) glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); #endif // !ENABLE_GL_CORE_PROFILE +#if ENABLE_OPENGL_ES + if (extra_id != -1) + glsafe(::glDisableVertexAttribArray(extra_id)); +#endif // ENABLE_OPENGL_ES if (tex_coord_id != -1) glsafe(::glDisableVertexAttribArray(tex_coord_id)); if (normal_id != -1) diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index a73766fdf..f3c62d786 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -58,13 +58,16 @@ namespace GUI { enum class EVertexLayout : unsigned char { - P2, // position 2 floats - P2T2, // position 2 floats + texture coords 2 floats - P3, // position 3 floats - P3T2, // position 3 floats + texture coords 2 floats - P3N3, // position 3 floats + normal 3 floats + P2, // position 2 floats + P2T2, // position 2 floats + texture coords 2 floats + P3, // position 3 floats + P3T2, // position 3 floats + texture coords 2 floats + P3N3, // position 3 floats + normal 3 floats P3N3T2, // position 3 floats + normal 3 floats + texture coords 2 floats - P4, // position 4 floats +#if ENABLE_OPENGL_ES + P3N3E3, // position 3 floats + normal 3 floats + extra 3 floats +#endif // ENABLE_OPENGL_ES + P4, // position 4 floats }; enum class EIndexType : unsigned char @@ -95,6 +98,9 @@ namespace GUI { void add_vertex(const Vec3f& position, const Vec2f& tex_coord); // EVertexLayout::P3T2 void add_vertex(const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3 void add_vertex(const Vec3f& position, const Vec3f& normal, const Vec2f& tex_coord); // EVertexLayout::P3N3T2 +#if ENABLE_OPENGL_ES + void add_vertex(const Vec3f& position, const Vec3f& normal, const Vec3f& extra); // EVertexLayout::P3N3E3 +#endif // ENABLE_OPENGL_ES void add_vertex(const Vec4f& position); // EVertexLayout::P4 void set_vertex(size_t id, const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3 @@ -141,11 +147,21 @@ namespace GUI { static size_t tex_coord_offset_floats(const Format& format); static size_t tex_coord_offset_bytes(const Format& format) { return tex_coord_offset_floats(format) * sizeof(float); } +#if ENABLE_OPENGL_ES + static size_t extra_stride_floats(const Format& format); + static size_t extra_stride_bytes(const Format& format) { return extra_stride_floats(format) * sizeof(float); } + static size_t extra_offset_floats(const Format& format); + static size_t extra_offset_bytes(const Format& format) { return extra_offset_floats(format) * sizeof(float); } +#endif // ENABLE_OPENGL_ES + static size_t index_stride_bytes(const Geometry& data); static bool has_position(const Format& format); static bool has_normal(const Format& format); static bool has_tex_coord(const Format& format); +#if ENABLE_OPENGL_ES + static bool has_extra(const Format& format); +#endif // ENABLE_OPENGL_ES #else struct Entity { diff --git a/src/slic3r/GUI/GLSelectionRectangle.cpp b/src/slic3r/GUI/GLSelectionRectangle.cpp index 9249afc83..32dc9ad18 100644 --- a/src/slic3r/GUI/GLSelectionRectangle.cpp +++ b/src/slic3r/GUI/GLSelectionRectangle.cpp @@ -140,6 +140,7 @@ namespace GUI { glsafe(::glScaled(gui_scale, gui_scale, 1.0)); #endif // !ENABLE_LEGACY_OPENGL_REMOVAL +#if !ENABLE_OPENGL_ES #if ENABLE_GL_CORE_PROFILE if (!core_profile) { #endif // ENABLE_GL_CORE_PROFILE @@ -149,13 +150,16 @@ namespace GUI { #if ENABLE_GL_CORE_PROFILE } #endif // ENABLE_GL_CORE_PROFILE +#endif // !ENABLE_OPENGL_ES #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_OPENGL_ES + GLShaderProgram* shader = wxGetApp().get_shader("dashed_lines"); +#elif ENABLE_GL_CORE_PROFILE GLShaderProgram* shader = core_profile ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); #else GLShaderProgram* shader = wxGetApp().get_shader("flat"); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_OPENGL_ES if (shader != nullptr) { shader->start_using(); @@ -165,7 +169,7 @@ namespace GUI { m_rectangle.reset(); GLModel::Geometry init_data; -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P4 }; init_data.reserve_vertices(8); init_data.reserve_indices(8); @@ -173,10 +177,10 @@ namespace GUI { init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 }; init_data.reserve_vertices(4); init_data.reserve_indices(4); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES // vertices -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES const float width = right - left; const float height = top - bottom; float perimeter = 0.0f; @@ -213,14 +217,17 @@ namespace GUI { init_data.add_index(1); init_data.add_index(2); init_data.add_index(3); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES m_rectangle.init_from(std::move(init_data)); } shader->set_uniform("view_model_matrix", Transform3d::Identity()); shader->set_uniform("projection_matrix", Transform3d::Identity()); -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_OPENGL_ES + shader->set_uniform("dash_size", 0.01f); + shader->set_uniform("gap_size", 0.0075f); +#elif ENABLE_GL_CORE_PROFILE if (core_profile) { const std::array& viewport = wxGetApp().plater()->get_camera().get_viewport(); shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); @@ -228,7 +235,7 @@ namespace GUI { shader->set_uniform("dash_size", 0.01f); shader->set_uniform("gap_size", 0.0075f); } -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_OPENGL_ES m_rectangle.set_color(ColorRGBA((m_state == EState::Select) ? 0.3f : 1.0f, (m_state == EState::Select) ? 1.0f : 0.3f, 0.3f, 1.0f)); m_rectangle.render(); @@ -243,10 +250,12 @@ namespace GUI { glsafe(::glEnd()); #endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if !ENABLE_OPENGL_ES #if ENABLE_GL_CORE_PROFILE if (!core_profile) #endif // ENABLE_GL_CORE_PROFILE glsafe(::glPopAttrib()); +#endif // !ENABLE_OPENGL_ES #if !ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glPopMatrix()); diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index f09194fa0..f0b91faf3 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -37,7 +37,13 @@ std::pair GLShadersManager::init() bool valid = true; #if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_OPENGL_ES + const std::string prefix = "ES/"; + // used to render wireframed triangles + valid &= append_shader("wireframe", { prefix + "wireframe.vs", prefix + "wireframe.fs" }); +#else const std::string prefix = GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 1) ? "140/" : "110/"; +#endif // ENABLE_OPENGL_ES // imgui shader valid &= append_shader("imgui", { prefix + "imgui.vs", prefix + "imgui.fs" }); // basic shader, used to render all what was previously rendered using the immediate mode @@ -48,11 +54,14 @@ std::pair GLShadersManager::init() valid &= append_shader("flat_texture", { prefix + "flat_texture.vs", prefix + "flat_texture.fs" }); // used to render 3D scene background valid &= append_shader("background", { prefix + "background.vs", prefix + "background.fs" }); -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_OPENGL_ES + // used to render dashed lines + valid &= append_shader("dashed_lines", { prefix + "dashed_lines.vs", prefix + "dashed_lines.fs" }); +#elif ENABLE_GL_CORE_PROFILE if (GUI::OpenGLManager::get_gl_info().is_core_profile()) // used to render thick and/or dashed lines valid &= append_shader("dashed_thick_lines", { prefix + "dashed_thick_lines.vs", prefix + "dashed_thick_lines.fs", prefix + "dashed_thick_lines.gs" }); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_OPENGL_ES #endif // ENABLE_LEGACY_OPENGL_REMOVAL // used to render toolpaths center of gravity #if ENABLE_LEGACY_OPENGL_REMOVAL diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp index 53566a9dc..a3b22d020 100644 --- a/src/slic3r/GUI/GLTexture.cpp +++ b/src/slic3r/GUI/GLTexture.cpp @@ -335,10 +335,10 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right, glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); -#if !ENABLE_GL_CORE_PROFILE +#if !ENABLE_GL_CORE_PROFILE && !ENABLE_OPENGL_ES glsafe(::glEnable(GL_TEXTURE_2D)); glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)); -#endif // !ENABLE_GL_CORE_PROFILE +#endif // !ENABLE_GL_CORE_PROFILE && !ENABLE_OPENGL_ES glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id)); @@ -382,9 +382,9 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right, glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); -#if !ENABLE_GL_CORE_PROFILE +#if !ENABLE_GL_CORE_PROFILE && !ENABLE_OPENGL_ES glsafe(::glDisable(GL_TEXTURE_2D)); -#endif // !ENABLE_GL_CORE_PROFILE +#endif // !ENABLE_GL_CORE_PROFILE && !ENABLE_OPENGL_ES glsafe(::glDisable(GL_BLEND)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index f326ab472..62611ac25 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -182,12 +182,12 @@ void GLGizmoPainterBase::render_cursor_circle() const float cnv_inv_height = 1.0f / cnv_height; const Vec2d center = m_parent.get_local_mouse_position(); -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES const float zoom = float(wxGetApp().plater()->get_camera().get_zoom()); const float radius = m_cursor_radius * zoom; #else const float radius = m_cursor_radius * float(wxGetApp().plater()->get_camera().get_zoom()); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES #else const float cnv_half_width = 0.5f * float(cnv_size.get_width()); const float cnv_half_height = 0.5f * float(cnv_size.get_height()); @@ -218,14 +218,14 @@ void GLGizmoPainterBase::render_cursor_circle() glsafe(::glScaled(gui_scale, gui_scale, 1.0)); #endif // !ENABLE_LEGACY_OPENGL_REMOVAL -#if !ENABLE_GL_CORE_PROFILE +#if !ENABLE_GL_CORE_PROFILE && !ENABLE_OPENGL_ES glsafe(::glPushAttrib(GL_ENABLE_BIT)); glsafe(::glLineStipple(4, 0xAAAA)); glsafe(::glEnable(GL_LINE_STIPPLE)); -#endif // !ENABLE_GL_CORE_PROFILE +#endif // !ENABLE_GL_CORE_PROFILE && !ENABLE_OPENGL_ES #if ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES if (!m_circle.is_initialized() || std::abs(m_old_cursor_radius - radius) > EPSILON) { m_old_cursor_radius = radius; m_circle.reset(); @@ -234,10 +234,10 @@ void GLGizmoPainterBase::render_cursor_circle() m_old_cursor_radius = radius; m_old_center = center; m_circle.reset(); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES GLModel::Geometry init_data; -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES const unsigned int StepsCount = (unsigned int)(2 * (4 + int(252 * (zoom - 1.0f) / (250.0f - 1.0f)))); const float StepSize = 2.0f * float(PI) / float(StepsCount); init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P2 }; @@ -245,14 +245,14 @@ void GLGizmoPainterBase::render_cursor_circle() static const unsigned int StepsCount = 32; static const float StepSize = 2.0f * float(PI) / float(StepsCount); init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 }; -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES init_data.color = { 0.0f, 1.0f, 0.3f, 1.0f }; init_data.reserve_vertices(StepsCount); init_data.reserve_indices(StepsCount); // vertices + indices for (unsigned int i = 0; i < StepsCount; ++i) { -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES if (i % 2 != 0) continue; const float angle_i = float(i) * StepSize; @@ -269,7 +269,7 @@ void GLGizmoPainterBase::render_cursor_circle() init_data.add_vertex(Vec2f(2.0f * ((center.x() + ::cos(angle) * radius) * cnv_inv_width - 0.5f), -2.0f * ((center.y() + ::sin(angle) * radius) * cnv_inv_height - 0.5f))); init_data.add_index(i); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES } m_circle.init_from(std::move(init_data)); @@ -282,13 +282,13 @@ void GLGizmoPainterBase::render_cursor_circle() #endif // ENABLE_GL_CORE_PROFILE if (shader != nullptr) { shader->start_using(); -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES const Transform3d view_model_matrix = Geometry::translation_transform(Vec3d(2.0f * (center.x() * cnv_inv_width - 0.5f), -2.0f * (center.y() * cnv_inv_height - 0.5f), 0.0)) * Geometry::scale_transform(Vec3d(2.0f * radius * cnv_inv_width, 2.0f * radius * cnv_inv_height, 1.0f)); shader->set_uniform("view_model_matrix", view_model_matrix); #else shader->set_uniform("view_model_matrix", Transform3d::Identity()); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES shader->set_uniform("projection_matrix", Transform3d::Identity()); #if ENABLE_GL_CORE_PROFILE const std::array& viewport = wxGetApp().plater()->get_camera().get_viewport(); @@ -306,9 +306,9 @@ void GLGizmoPainterBase::render_cursor_circle() glsafe(::glEnd()); #endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if !ENABLE_GL_CORE_PROFILE +#if !ENABLE_GL_CORE_PROFILE && !ENABLE_OPENGL_ES glsafe(::glPopAttrib()); -#endif // !ENABLE_GL_CORE_PROFILE +#endif // !ENABLE_GL_CORE_PROFILE && !ENABLE_OPENGL_ES #if !ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glPopMatrix()); #endif // !ENABLE_LEGACY_OPENGL_REMOVAL diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp index 0134cf450..d501e6459 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp @@ -698,7 +698,30 @@ void GLGizmoSimplify::update_model(const State::Data &data) auto color = glmodel.get_color(); // when not reset it keeps old shape glmodel.reset(); +#if ENABLE_OPENGL_ES + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3E3 }; + init_data.reserve_vertices(3 * its.indices.size()); + init_data.reserve_indices(3 * its.indices.size()); + + // vertices + indices + std::array barycentric_coords = { Vec3f::UnitX(), Vec3f::UnitY(), Vec3f::UnitZ() }; + unsigned int vertices_counter = 0; + for (uint32_t i = 0; i < its.indices.size(); ++i) { + const stl_triangle_vertex_indices face = its.indices[i]; + const stl_vertex vertex[3] = { its.vertices[face[0]], its.vertices[face[1]], its.vertices[face[2]] }; + const stl_vertex n = face_normal_normalized(vertex); + for (size_t j = 0; j < 3; ++j) { + init_data.add_vertex(vertex[j], n, barycentric_coords[j]); + } + vertices_counter += 3; + init_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); + } + + glmodel.init_from(std::move(init_data)); +#else glmodel.init_from(its); +#endif // ENABLE_OPENGL_ES #if ENABLE_LEGACY_OPENGL_REMOVAL glmodel.set_color(color); #else @@ -743,11 +766,11 @@ void GLGizmoSimplify::on_render() glsafe(::glMultMatrixd(trafo_matrix.data())); #endif // !ENABLE_LEGACY_OPENGL_REMOVAL auto* gouraud_shader = wxGetApp().get_shader("gouraud_light"); -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES bool depth_test_enabled = ::glIsEnabled(GL_DEPTH_TEST); #else glsafe(::glPushAttrib(GL_DEPTH_TEST)); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES glsafe(::glEnable(GL_DEPTH_TEST)); gouraud_shader->start_using(); #if ENABLE_LEGACY_OPENGL_REMOVAL @@ -763,7 +786,11 @@ void GLGizmoSimplify::on_render() gouraud_shader->stop_using(); if (m_show_wireframe) { +#if ENABLE_OPENGL_ES + auto* contour_shader = wxGetApp().get_shader("wireframe"); +#else auto *contour_shader = wxGetApp().get_shader("mm_contour"); +#endif // ENABLE_OPENGL_ES contour_shader->start_using(); contour_shader->set_uniform("offset", OpenGLManager::get_gl_info().is_mesa() ? 0.0005 : 0.00001); #if ENABLE_LEGACY_OPENGL_REMOVAL @@ -776,20 +803,24 @@ void GLGizmoSimplify::on_render() if (!OpenGLManager::get_gl_info().is_core_profile()) #endif // ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth(1.0f)); +#if !ENABLE_OPENGL_ES glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); +#endif // !ENABLE_OPENGL_ES glmodel.render(); +#if !ENABLE_OPENGL_ES glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); +#endif // !ENABLE_OPENGL_ES #if ENABLE_LEGACY_OPENGL_REMOVAL glmodel.set_color(color); #endif // ENABLE_LEGACY_OPENGL_REMOVAL contour_shader->stop_using(); } -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES if (depth_test_enabled) glsafe(::glEnable(GL_DEPTH_TEST)); #else glsafe(::glPopAttrib()); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES #if !ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glPopMatrix()); #endif // !ENABLE_LEGACY_OPENGL_REMOVAL diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index 19d073151..ce3ba1d4a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -222,23 +222,23 @@ void InstancesHider::render_cut() const glsafe(::glColor4fv(color.data())); } #endif // !ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES bool depth_test_enabled = ::glIsEnabled(GL_DEPTH_TEST); #else glsafe(::glPushAttrib(GL_DEPTH_TEST)); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES glsafe(::glDisable(GL_DEPTH_TEST)); #if ENABLE_LEGACY_OPENGL_REMOVAL clipper->render_cut(mv->is_model_part() ? ColorRGBA(0.8f, 0.3f, 0.0f, 1.0f) : color_from_model_volume(*mv)); #else clipper->render_cut(); #endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES if (depth_test_enabled) glsafe(::glEnable(GL_DEPTH_TEST)); #else glsafe(::glPopAttrib()); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES #if !ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glPopMatrix()); #endif // !ENABLE_LEGACY_OPENGL_REMOVAL diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index b5d5ad613..fa6e2c903 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -1480,7 +1480,7 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) draw_data->ScaleClipRects(io.DisplayFramebufferScale); #endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES // Backup GL state GLenum last_active_texture; glsafe(::glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture)); GLuint last_program; glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_program)); @@ -1537,7 +1537,7 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) glsafe(::glEnable(GL_TEXTURE_2D)); glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES #if ENABLE_LEGACY_OPENGL_REMOVAL // Setup viewport, orthographic projection matrix @@ -1679,7 +1679,7 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) #endif // ENABLE_LEGACY_OPENGL_REMOVAL } -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES // Restore modified GL state glsafe(::glBindTexture(GL_TEXTURE_2D, last_texture)); glsafe(::glActiveTexture(last_active_texture)); @@ -1713,7 +1713,7 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) glsafe(::glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]))); glsafe(::glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3])); glsafe(::glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3])); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES #if ENABLE_LEGACY_OPENGL_REMOVAL shader->stop_using(); diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index 9a296e172..5df41d59a 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -130,8 +130,16 @@ static bool version_greater_or_equal_to(const std::string& version, unsigned int if (tokens.empty()) return false; +#if ENABLE_OPENGL_ES + const std::string version_container = (tokens.size() > 1 && boost::istarts_with(tokens[1], "ES")) ? tokens[2] : tokens[0]; +#endif // ENABLE_OPENGL_ES + std::vector numbers; +#if ENABLE_OPENGL_ES + boost::split(numbers, version_container, boost::is_any_of("."), boost::token_compress_on); +#else boost::split(numbers, tokens[0], boost::is_any_of("."), boost::token_compress_on); +#endif // ENABLE_OPENGL_ES unsigned int gl_major = 0; unsigned int gl_minor = 0; @@ -320,9 +328,9 @@ static void CustomGLDebugOutput(GLenum source, GLenum type, unsigned int id, GLe bool OpenGLManager::init_gl() { if (!m_gl_initialized) { -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES glewExperimental = true; -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES GLenum err = glewInit(); if (err != GLEW_OK) { BOOST_LOG_TRIVIAL(error) << "Unable to init glew library: " << glewGetErrorString(err); @@ -356,22 +364,27 @@ bool OpenGLManager::init_gl() else s_framebuffers_type = EFramebufferType::Unknown; -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_OPENGL_ES + bool valid_version = s_gl_info.is_version_greater_or_equal_to(2, 0); +#elif ENABLE_GL_CORE_PROFILE bool valid_version = s_gl_info.is_core_profile() ? s_gl_info.is_version_greater_or_equal_to(3, 2) : s_gl_info.is_version_greater_or_equal_to(2, 0); #else bool valid_version = s_gl_info.is_version_greater_or_equal_to(2, 0); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_OPENGL_ES if (!valid_version) { // Complain about the OpenGL version. wxString message = from_u8((boost::format( -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_OPENGL_ES + _utf8(L("PrusaSlicer requires OpenGL ES 2.0 capable graphics driver to run correctly, \n" + "while OpenGL version %s, render %s, vendor %s was detected."))) % s_gl_info.get_version() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str()); +#elif ENABLE_GL_CORE_PROFILE _utf8(L("PrusaSlicer requires OpenGL %s capable graphics driver to run correctly, \n" "while OpenGL version %s, render %s, vendor %s was detected."))) % (s_gl_info.is_core_profile() ? "3.3" : "2.0") % s_gl_info.get_version() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str()); #else _utf8(L("PrusaSlicer requires OpenGL 2.0 capable graphics driver to run correctly, \n" "while OpenGL version %s, render %s, vendor %s was detected."))) % s_gl_info.get_version() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str()); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_OPENGL_ES message += "\n"; message += _L("You may need to update your graphics card driver."); #ifdef _WIN32 @@ -414,7 +427,11 @@ wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas) #endif // ENABLE_GL_CORE_PROFILE { if (m_context == nullptr) { -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_OPENGL_ES + wxGLContextAttrs attrs; + attrs.PlatformDefaults().ES2().MajorVersion(2).EndList(); + m_context = new wxGLContext(&canvas, nullptr, &attrs); +#elif ENABLE_GL_CORE_PROFILE #if ENABLE_OPENGL_DEBUG_OPTION m_debug_enabled = enable_debug; #endif // ENABLE_OPENGL_DEBUG_OPTION @@ -491,7 +508,7 @@ wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas) #endif // ENABLE_OPENGL_DEBUG_OPTION #else m_context = new wxGLContext(&canvas); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_OPENGL_ES #ifdef __APPLE__ // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets @@ -505,7 +522,7 @@ wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas) wxGLCanvas* OpenGLManager::create_wxglcanvas(wxWindow& parent) { -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES wxGLAttributes attribList; attribList.PlatformDefaults().RGBA().DoubleBuffer().MinRGBA(8, 8, 8, 8).Depth(24).SampleBuffers(1).Samplers(4).EndList(); #ifdef __APPLE__ @@ -528,7 +545,7 @@ wxGLCanvas* OpenGLManager::create_wxglcanvas(wxWindow& parent) WX_GL_SAMPLES, 4, 0 }; -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES if (s_multisample == EMultisampleState::Unknown) { detect_multisample(attribList); @@ -537,7 +554,7 @@ wxGLCanvas* OpenGLManager::create_wxglcanvas(wxWindow& parent) } if (!can_multisample()) -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES { attribList.Reset(); attribList.PlatformDefaults().RGBA().DoubleBuffer().MinRGBA(8, 8, 8, 8).Depth(24).EndList(); @@ -552,14 +569,14 @@ wxGLCanvas* OpenGLManager::create_wxglcanvas(wxWindow& parent) attribList[12] = 0; return new wxGLCanvas(&parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES } -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES void OpenGLManager::detect_multisample(const wxGLAttributes& attribList) #else void OpenGLManager::detect_multisample(int* attribList) -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES { int wxVersion = wxMAJOR_VERSION * 10000 + wxMINOR_VERSION * 100 + wxRELEASE_NUMBER; bool enable_multisample = wxVersion >= 30003; diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp index fb9d385a4..d8ca7eebb 100644 --- a/src/slic3r/GUI/OpenGLManager.hpp +++ b/src/slic3r/GUI/OpenGLManager.hpp @@ -6,9 +6,9 @@ class wxWindow; class wxGLCanvas; class wxGLContext; -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES class wxGLAttributes; -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES namespace Slic3r { namespace GUI { @@ -48,6 +48,14 @@ public: void set_core_profile(bool value) { m_core_profile = value; } bool is_mesa() const; + bool is_es() const { + return +#if ENABLE_OPENGL_ES + true; +#else + false; +#endif // ENABLE_OPENGL_ES + } int get_max_tex_size() const; float get_max_anisotropy() const; @@ -126,11 +134,11 @@ public: static const GLInfo& get_gl_info() { return s_gl_info; } private: -#if ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES static void detect_multisample(const wxGLAttributes& attribList); #else static void detect_multisample(int* attribList); -#endif // ENABLE_GL_CORE_PROFILE +#endif // ENABLE_GL_CORE_PROFILE || ENABLE_OPENGL_ES }; } // namespace GUI