Merge remote-tracking branch 'origin/et_opengl_es_rebase'

This commit is contained in:
enricoturri1966 2022-08-18 13:23:38 +02:00
commit f586a3e727
47 changed files with 1227 additions and 69 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,10 @@
#version 100
precision highp float;
uniform vec4 uniform_color;
void main()
{
gl_FragColor = uniform_color;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,10 @@
#version 100
precision highp float;
uniform vec4 uniform_color;
void main()
{
gl_FragColor = uniform_color;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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

View File

@ -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

View File

@ -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<int> load_object(

View File

@ -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<VertexBuffer*>(::glMapBufferRange(GL_ARRAY_BUFFER, 0,
static_cast<GLsizeiptr>(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<GLsizeiptr>(t_buffer.vertices.sizes[i]), static_cast<void*>(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<IndexBuffer*>(::glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER,
static_cast<GLintptr>(render_path.offsets[j]), static_cast<GLsizeiptr>(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<GLintptr>(render_path.offsets[j]),
static_cast<GLsizeiptr>(render_path.sizes[j] * sizeof(IBufferType)), static_cast<void*>(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<IBufferType*>(::glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER,
static_cast<GLintptr>(offset * sizeof(IBufferType)), static_cast<GLsizeiptr>(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<GLintptr>(offset * sizeof(IBufferType)), static_cast<GLsizeiptr>(sizeof(IBufferType)), static_cast<void*>(&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<Vec3f*>(::glMapBufferRange(GL_ARRAY_BUFFER,
static_cast<GLintptr>(index * buffer.vertices.vertex_size_bytes()),
static_cast<GLsizeiptr>(buffer.vertices.position_size_bytes()), GL_MAP_READ_BIT));
glcheck();
glsafe(::glUnmapBuffer(GL_ARRAY_BUFFER));
#else
glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast<GLintptr>(index * buffer.vertices.vertex_size_bytes()), static_cast<GLsizeiptr>(3 * sizeof(float)), static_cast<void*>(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<IBufferType, 6> 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<IBufferType*>(::glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER,
static_cast<GLintptr>(offset * sizeof(IBufferType)), static_cast<GLsizeiptr>(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<GLintptr>((offset + 0) * sizeof(IBufferType)), static_cast<GLsizeiptr>(sizeof(IBufferType)), static_cast<void*>(&indices[0])));
glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLintptr>((offset + 7) * sizeof(IBufferType)), static_cast<GLsizeiptr>(sizeof(IBufferType)), static_cast<void*>(&indices[1])));
glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLintptr>((offset + 1) * sizeof(IBufferType)), static_cast<GLsizeiptr>(sizeof(IBufferType)), static_cast<void*>(&indices[2])));
glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLintptr>((offset + 13) * sizeof(IBufferType)), static_cast<GLsizeiptr>(sizeof(IBufferType)), static_cast<void*>(&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<IBufferType, 6> 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<IBufferType*>(::glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER,
static_cast<GLintptr>(offset * sizeof(IBufferType)), static_cast<GLsizeiptr>(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<GLintptr>((offset + 2) * sizeof(IBufferType)), static_cast<GLsizeiptr>(sizeof(IBufferType)), static_cast<void*>(&indices[0])));
glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLintptr>((offset + 4) * sizeof(IBufferType)), static_cast<GLsizeiptr>(sizeof(IBufferType)), static_cast<void*>(&indices[1])));
glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLintptr>((offset + 10) * sizeof(IBufferType)), static_cast<GLsizeiptr>(sizeof(IBufferType)), static_cast<void*>(&indices[2])));
glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLintptr>((offset + 16) * sizeof(IBufferType)), static_cast<GLsizeiptr>(sizeof(IBufferType)), static_cast<void*>(&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

View File

@ -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 {

View File

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

View File

@ -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<size_t, size_t>& 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))
@ -898,6 +987,9 @@ void GLModel::render(const std::pair<size_t, size_t>& range)
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<size_t, size_t>& 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<size_t, size_t>& 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)

View File

@ -64,6 +64,9 @@ namespace GUI {
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
#if ENABLE_OPENGL_ES
P3N3E3, // position 3 floats + normal 3 floats + extra 3 floats
#endif // ENABLE_OPENGL_ES
P4, // position 4 floats
};
@ -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
{

View File

@ -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<int, 4>& 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());

View File

@ -37,7 +37,13 @@ std::pair<bool, std::string> 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<bool, std::string> 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

View File

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

View File

@ -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<int, 4>& 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

View File

@ -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<Vec3f, 3> 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

View File

@ -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

View File

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

View File

@ -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<std::string> 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;

View File

@ -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