[Bf-blender-cvs] [773f3428cfc] master: Edit Mesh: Add workaround for system that does not support wide lines

Clément Foucault noreply at git.blender.org
Tue Feb 5 15:38:22 CET 2019


Commit: 773f3428cfc5212641c59536f56179a58acf318a
Author: Clément Foucault
Date:   Mon Feb 4 22:28:39 2019 +0100
Branches: master
https://developer.blender.org/rB773f3428cfc5212641c59536f56179a58acf318a

Edit Mesh: Add workaround for system that does not support wide lines

This adds a new geometry shader (specific to edit mesh for now) that
reproduces the effect of glLineWidth > 1.0, since this is not supported on
all platform.

This fix could be generalized to other shaders later.

===================================================================

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/modes/edit_mesh_mode.c
A	source/blender/draw/modes/shaders/edit_mesh_overlay_geom.glsl
M	source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl

===================================================================

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index b3e643dafdb..1b7c2a15cc3 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -270,6 +270,7 @@ data_to_c_simple(modes/shaders/armature_dof_vert.glsl SRC)
 data_to_c_simple(modes/shaders/edit_mesh_overlay_common_lib.glsl SRC)
 data_to_c_simple(modes/shaders/edit_mesh_overlay_frag.glsl SRC)
 data_to_c_simple(modes/shaders/edit_mesh_overlay_vert.glsl SRC)
+data_to_c_simple(modes/shaders/edit_mesh_overlay_geom.glsl SRC)
 data_to_c_simple(modes/shaders/edit_mesh_overlay_mix_frag.glsl SRC)
 data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_vert.glsl SRC)
 data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_frag.glsl SRC)
diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c
index d9c60115e14..bd4a1e85ca8 100644
--- a/source/blender/draw/modes/edit_mesh_mode.c
+++ b/source/blender/draw/modes/edit_mesh_mode.c
@@ -23,7 +23,7 @@
 #include "DRW_engine.h"
 #include "DRW_render.h"
 
-#include "GPU_shader.h"
+#include "GPU_extensions.h"
 
 #include "DNA_mesh_types.h"
 #include "DNA_view3d_types.h"
@@ -51,6 +51,7 @@ extern char datatoc_paint_weight_frag_glsl[];
 extern char datatoc_edit_mesh_overlay_common_lib_glsl[];
 extern char datatoc_edit_mesh_overlay_frag_glsl[];
 extern char datatoc_edit_mesh_overlay_vert_glsl[];
+extern char datatoc_edit_mesh_overlay_geom_glsl[];
 extern char datatoc_edit_mesh_overlay_mix_frag_glsl[];
 extern char datatoc_edit_mesh_overlay_facefill_vert_glsl[];
 extern char datatoc_edit_mesh_overlay_facefill_frag_glsl[];
@@ -192,6 +193,12 @@ static void EDIT_MESH_engine_init(void *vedata)
 		});
 
 		char *lib = BLI_string_joinN(world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_common_lib_glsl);
+		const bool use_geom_shader = GPU_max_line_width() <= 2.0f;
+		const char *geom_sh_code[] = {lib, datatoc_edit_mesh_overlay_geom_glsl, NULL};
+		if (!use_geom_shader) {
+			geom_sh_code[0] = NULL;
+		}
+		const char *use_geom_def = use_geom_shader ? "#define USE_GEOM_SHADER\n" : "";
 		sh_data->overlay_face = DRW_shader_create_from_arrays({
 		        .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
 		        .frag = (const char *[]){datatoc_gpu_shader_3D_smooth_color_frag_glsl, NULL},
@@ -200,17 +207,20 @@ static void EDIT_MESH_engine_init(void *vedata)
 		sh_data->overlay_edge = DRW_shader_create_from_arrays({
 		        .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
 		        .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL},
-		        .defs = (const char *[]){world_clip_def_or_empty, "#define EDGE\n", NULL},
+		        .defs = (const char *[]){world_clip_def_or_empty, use_geom_def, "#define EDGE\n", NULL},
+		        .geom = (use_geom_shader) ? geom_sh_code : NULL,
 		});
 		sh_data->overlay_edge_flat = DRW_shader_create_from_arrays({
 		        .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
 		        .frag = (const char *[]){datatoc_gpu_shader_flat_color_frag_glsl, NULL},
-		        .defs = (const char *[]){world_clip_def_or_empty, "#define EDGE\n", "#define FLAT\n", NULL},
+		        .defs = (const char *[]){world_clip_def_or_empty, use_geom_def, "#define EDGE\n", "#define FLAT\n", NULL},
+		        .geom = (use_geom_shader) ? geom_sh_code : NULL,
 		});
 		sh_data->overlay_edge_deco = DRW_shader_create_from_arrays({
 		        .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
 		        .frag = (const char *[]){datatoc_gpu_shader_flat_color_frag_glsl, NULL},
-		        .defs = (const char *[]){world_clip_def_or_empty, "#define EDGE_DECORATION\n", "#define FLAT\n", NULL},
+		        .defs = (const char *[]){world_clip_def_or_empty, use_geom_def, "#define EDGE_DECORATION\n", "#define FLAT\n", NULL},
+		        .geom = (use_geom_shader) ? geom_sh_code : NULL,
 		});
 		sh_data->overlay_vert = DRW_shader_create_from_arrays({
 		        .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
@@ -305,7 +315,6 @@ static DRWPass *edit_mesh_create_overlay_pass(
 
 	grp = *r_face_shgrp = DRW_shgroup_create(face_sh, pass);
 	DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
-	DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
 	DRW_shgroup_uniform_float(grp, "faceAlphaMod", face_alpha, 1);
 	DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1);
 	DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1);
@@ -322,6 +331,8 @@ static DRWPass *edit_mesh_create_overlay_pass(
 	/* Edges */
 	grp = *r_edge_deco_shgrp = DRW_shgroup_create(edge_deco_sh, pass);
 	DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
+	DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
+	DRW_shgroup_uniform_vec2(grp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
 	DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1);
 	DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges);
 	DRW_shgroup_uniform_float_copy(grp, "ofs", depth_ofs);
@@ -336,6 +347,8 @@ static DRWPass *edit_mesh_create_overlay_pass(
 
 	grp = *r_edge_shgrp = DRW_shgroup_create(edge_sh, pass);
 	DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
+	DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
+	DRW_shgroup_uniform_vec2(grp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
 	DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1);
 	DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1);
 	DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges);
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom.glsl
new file mode 100644
index 00000000000..66792b61fb7
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom.glsl
@@ -0,0 +1,64 @@
+
+layout(lines) in;
+layout(triangle_strip, max_vertices = 4) out;
+
+uniform vec2 viewportSize;
+uniform vec2 viewportSizeInv;
+
+in VertexData {
+	vec4 finalColor;
+#if defined(EDGE) && !defined(FLAT)
+	int selectOveride;
+#endif
+} v[];
+
+#ifdef FLAT
+#  define interp_col flat
+#else
+#  define interp_col
+#endif
+
+interp_col out vec4 finalColor;
+#if defined(EDGE) && !defined(FLAT)
+flat out int selectOveride;
+#endif
+
+void do_vertex(const int i, vec2 offset)
+{
+	finalColor = v[i].finalColor;
+#if defined(EDGE) && !defined(FLAT)
+	selectOveride = v[0].selectOveride;
+#endif
+	gl_Position = gl_in[i].gl_Position;
+	gl_Position.xy += offset * gl_Position.w;
+	EmitVertex();
+}
+
+void main()
+{
+	vec2 ss_pos[2];
+	ss_pos[0] = gl_in[0].gl_Position.xy / gl_in[0].gl_Position.w;
+	ss_pos[1] = gl_in[1].gl_Position.xy / gl_in[1].gl_Position.w;
+
+	vec2 line = ss_pos[0] - ss_pos[1];
+
+	vec3 edge_ofs = sizeEdge * 2.0 * viewportSizeInv.xyy * vec3(1.0, 1.0, 0.0);
+
+#ifdef EDGE_DECORATION
+	edge_ofs *= 3.0;
+
+	if (finalColor.a == 0.0) {
+		return;
+	}
+#endif
+
+	bool horizontal = abs(line.x) > abs(line.y);
+	edge_ofs = (horizontal) ? edge_ofs.zyz : edge_ofs.xzz;
+
+	do_vertex(0,  edge_ofs.xy);
+	do_vertex(0, -edge_ofs.xy);
+	do_vertex(1,  edge_ofs.xy);
+	do_vertex(1, -edge_ofs.xy);
+
+	EndPrimitive();
+}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl
index e27e1d01750..bc25ff17e74 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl
@@ -17,13 +17,32 @@ in vec4 norAndFlag;
 #  define vnor norAndFlag.xyz
 #endif
 
-#ifdef FLAT
-flat out vec4 finalColor;
+#ifdef USE_GEOM_SHADER
+#  define qual_col
+#  define qual_sel
 #else
-out vec4 finalColor;
-#  ifdef EDGE
-flat out int selectOveride;
+#  ifdef FLAT
+#    define qual_col flat out
+#  else
+#    define qual_col out
 #  endif
+#  define qual_sel flat out
+#endif
+
+#ifdef USE_GEOM_SHADER
+out VertexData {
+#endif
+
+qual_col vec4 finalColor;
+#if defined(EDGE) && !defined(FLAT)
+qual_sel int selectOveride;
+#endif
+
+#ifdef USE_GEOM_SHADER
+} v;
+# define v(a) v.a
+#else
+# define v(a) a
 #endif
 
 void main()
@@ -41,7 +60,7 @@ void main()
 	ivec4 m_data = data & dataMask;
 
 #if defined(VERT)
-	finalColor = EDIT_MESH_vertex_color(m_data.y);
+	v(finalColor) = EDIT_MESH_vertex_color(m_data.y);
 	gl_PointSize = sizeVertex * 2.0;
 	gl_Position.z -= 3e-5 * ((ProjectionMatrix[3][3] == 0.0) ? 1.0 : 0.0);
 	/* Make selected and active vertex always on top. */
@@ -54,23 +73,23 @@ void main()
 
 #elif defined(EDGE)
 #  ifdef FLAT
-	finalColor = EDIT_MESH_edge_color_inner(m_data.y);
+	v(finalColor) = EDIT_MESH_edge_color_inner(m_data.y);
 #  else
-	finalColor = EDIT_MESH_edge_vertex_color(m_data.y);
-	selectOveride = (m_data.y & EDGE_SELECTED);
+	v(finalColor) = EDIT_MESH_edge_vertex_color(m_data.y);
+	v(selectOveride) = (m_data.y & EDGE_SELECTED);
 #  endif
 
 #elif defined(EDGE_DECORATION)
 	float crease = float(m_data.z) / 255.0;
 	float bweight = float(m_data.w) / 255.0;
-	finalColor = EDIT_MESH_edge_color_outer(m_data.y, m_data.x, crease, bweight);
+	v(finalColor) = EDIT_MESH_edge_color_outer(m_data.y, m_data.x, crease, bweight);
 
 #elif defined(FACE)
-	finalColor = EDIT_MESH_face_color(m_data.x);
-	finalColor.a *= faceAlphaMod;
+	v(finalColor) = EDIT_MESH_face_color(m_data.x);
+	v(finalColor).a *= faceAlphaMod;
 
 #elif defined(FACEDOT)
-	finalColor = EDIT_MESH_facedot_color(norAndFlag.w);
+	v(finalColor) = EDIT_MESH_facedot_color(norAndFlag.w);
 	/* Bias Facedot Z position in clipspace. */
 	gl_Position.z -= 0.00035;
 	gl_PointSize = sizeFaceDot;
@@ -87,12 +106,12 @@ void main()
 	float facing = dot(view_vec, view_normal);
 	facing = 1.0 - abs(facing) * 0.3;
 
-	finalColor = mix(colorEditMeshMiddle, finalColor, facing);
-	finalColor.a = 1.0;
+	v(finalColor) = mix(colorEditMeshMiddle, v(finalColor), facing);
+	v(finalColor).a = 1.0;
 
 #  if defined(EDGE) && !defined(FLAT)
 	/* Hack to blend color in pixel shader in case of overide.  */
-	finalColor.a = facing;
+	v(finalColor).a = facing;
 #  endif
 
 #endif



More information about the Bf-blender-cvs mailing list