[Bf-blender-cvs] [2cccffd20b6] master: Wireframe: Add workaround for osx wide wires

Clément Foucault noreply at git.blender.org
Mon Feb 18 14:18:26 CET 2019


Commit: 2cccffd20b67beecb5743e8871dbda779d1e03f1
Author: Clément Foucault
Date:   Wed Feb 13 18:09:16 2019 +0100
Branches: master
https://developer.blender.org/rB2cccffd20b67beecb5743e8871dbda779d1e03f1

Wireframe: Add workaround for osx wide wires

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

M	source/blender/draw/modes/overlay_mode.c
M	source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl
M	source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl

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

diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index e3e64ba6f22..ea502e176f1 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -32,6 +32,9 @@
 #include "GPU_shader.h"
 #include "DRW_render.h"
 
+#ifdef __APPLE__
+#define USE_GEOM_SHADER_WORKAROUND
+#endif
 
 /* Structures */
 typedef struct OVERLAY_StorageList {
@@ -54,7 +57,6 @@ typedef struct OVERLAY_Data {
 typedef struct OVERLAY_PrivateData {
 	DRWShadingGroup *face_orientation_shgrp;
 	DRWShadingGroup *face_wires_shgrp;
-	DRWShadingGroup *sculpt_wires_shgrp;
 	View3DOverlay overlay;
 	float wire_step_param;
 	bool ghost_stencil_test;
@@ -67,7 +69,6 @@ typedef struct OVERLAY_Shaders {
 	/* Wireframe shader */
 	struct GPUShader *select_wireframe;
 	struct GPUShader *face_wireframe;
-	struct GPUShader *face_wireframe_sculpt;
 } OVERLAY_Shaders;
 
 /* *********** STATIC *********** */
@@ -121,16 +122,21 @@ static void overlay_engine_init(void *vedata)
 		        .frag = (const char *[]){datatoc_gpu_shader_depth_only_frag_glsl, NULL},
 		        .defs = (const char *[]){sh_cfg_data->def, "#define SELECT_EDGES\n", NULL},
 		});
+#ifdef USE_GEOM_SHADER_WORKAROUND
+		/* Apple drivers does not support wide wires. Use geometry shader as a workaround. */
 		sh_data->face_wireframe = GPU_shader_create_from_arrays({
 		        .vert = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_vert_glsl, NULL},
+		        .geom = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_geom_glsl, NULL},
 		        .frag = (const char *[]){datatoc_overlay_face_wireframe_frag_glsl, NULL},
-		        .defs = (const char *[]){sh_cfg_data->def, NULL},
+		        .defs = (const char *[]){sh_cfg_data->def, "#define USE_GEOM\n", NULL},
 		});
-		sh_data->face_wireframe_sculpt = GPU_shader_create_from_arrays({
+#else
+		sh_data->face_wireframe = GPU_shader_create_from_arrays({
 		        .vert = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_vert_glsl, NULL},
 		        .frag = (const char *[]){datatoc_overlay_face_wireframe_frag_glsl, NULL},
 		        .defs = (const char *[]){sh_cfg_data->def, NULL},
 		});
+#endif
 	}
 }
 
@@ -179,8 +185,9 @@ static void overlay_cache_init(void *vedata)
 
 	{
 		/* Wireframe */
-		DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_FIRST_VERTEX_CONVENTION | DRW_STATE_OFFSET_NEGATIVE;
-		float wire_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f;
+		DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS |
+		                 DRW_STATE_FIRST_VERTEX_CONVENTION | DRW_STATE_OFFSET_NEGATIVE;
+		float wire_size = U.pixelsize * 0.5f;
 
 		float winmat[4][4];
 		float viewdist = rv3d->dist;
@@ -192,27 +199,25 @@ static void overlay_cache_init(void *vedata)
 		const float depth_ofs = bglPolygonOffsetCalc((float *)winmat, viewdist, 1.0f);
 
 		const bool use_select = (DRW_state_is_select() || DRW_state_is_depth());
-		GPUShader *sculpt_wire_sh = use_select ? sh_data->select_wireframe : sh_data->face_wireframe_sculpt;
 		GPUShader *face_wires_sh = use_select ? sh_data->select_wireframe : sh_data->face_wireframe;
 
 		psl->face_wireframe_pass = DRW_pass_create("Face Wires", state);
 
-		g_data->sculpt_wires_shgrp = DRW_shgroup_create(sculpt_wire_sh, psl->face_wireframe_pass);
-		if (rv3d->rflag & RV3D_CLIPPING) {
-			DRW_shgroup_world_clip_planes_from_rv3d(g_data->sculpt_wires_shgrp, rv3d);
-		}
-
 		g_data->face_wires_shgrp = DRW_shgroup_create(face_wires_sh, psl->face_wireframe_pass);
 		DRW_shgroup_uniform_float(g_data->face_wires_shgrp, "wireStepParam", &g_data->wire_step_param, 1);
 		DRW_shgroup_uniform_float_copy(g_data->face_wires_shgrp, "ofs", depth_ofs);
-		if (rv3d->rflag & RV3D_CLIPPING) {
-			DRW_shgroup_world_clip_planes_from_rv3d(g_data->face_wires_shgrp, rv3d);
-		}
-
+#ifdef USE_GEOM_SHADER_WORKAROUND
+		DRW_shgroup_uniform_float_copy(g_data->face_wires_shgrp, "wireSize", wire_size);
+		DRW_shgroup_uniform_vec2(g_data->face_wires_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
+		DRW_shgroup_uniform_vec2(g_data->face_wires_shgrp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
+#else
 		if (!use_select) {
-			DRW_shgroup_uniform_float_copy(g_data->sculpt_wires_shgrp, "wireSize", wire_size);
 			DRW_shgroup_uniform_float_copy(g_data->face_wires_shgrp, "wireSize", wire_size);
 		}
+#endif
+		if (rv3d->rflag & RV3D_CLIPPING) {
+			DRW_shgroup_world_clip_planes_from_rv3d(g_data->face_wires_shgrp, rv3d);
+		}
 
 		g_data->wire_step_param = stl->g_data->overlay.wireframe_threshold - 254.0f / 255.0f;
 	}
@@ -312,13 +317,13 @@ static void overlay_cache_populate(void *vedata, Object *ob)
 			geom = DRW_cache_object_face_wireframe_get(ob);
 
 			if (geom || is_sculpt_mode) {
-				shgrp = (is_sculpt_mode) ? pd->sculpt_wires_shgrp : pd->face_wires_shgrp;
-				shgrp = DRW_shgroup_create_sub(shgrp);
+				shgrp = DRW_shgroup_create_sub(pd->face_wires_shgrp);
 
 				static float all_wires_param = 10.0f;
-				DRW_shgroup_uniform_vec2(
-				        shgrp, "wireStepParam", (all_wires) ?
-				        &all_wires_param : &pd->wire_step_param, 1);
+				DRW_shgroup_uniform_float(
+				        shgrp, "wireStepParam",
+				        (all_wires || is_sculpt_mode) ? &all_wires_param : &pd->wire_step_param,
+				        1);
 
 				if (!(DRW_state_is_select() || DRW_state_is_depth())) {
 					DRW_shgroup_stencil_mask(shgrp, stencil_mask);
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl
index d4d53b7d24d..8f52c4fdf95 100644
--- a/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl
@@ -1,85 +1,60 @@
 
-/* This shader is only used for edge selection & sculpt mode wires (because of indexed drawing). */
+/* This shader is only used for edge selection and OSX workaround for large wires. */
 
-layout(triangles) in;
-#ifdef SELECT_EDGES
-layout(line_strip, max_vertices = 6) out;
-#else
-layout(triangle_strip, max_vertices = 3) out;
-#endif
+uniform float wireSize;
+uniform vec2 viewportSize;
+uniform vec2 viewportSizeInv;
+
+layout(lines) in;
+layout(triangle_strip, max_vertices = 4) out;
 
 in float facing_g[];
 in float edgeSharpness_g[];
 
 #ifndef SELECT_EDGES
 out float facing;
-out vec3 barycentric;
-flat out vec3 edgeSharpness;
+flat out float edgeSharpness;
 #endif
 
-void vert_from_gl_in(int v)
+void do_vertex(const int i, float coord, vec2 offset)
 {
-	gl_Position = gl_in[v].gl_Position;
+#ifndef SELECT_EDGES
+	edgeSharpness = edgeSharpness_g[i];
+	facing = facing_g[i];
+#endif
+	gl_Position = gl_in[i].gl_Position;
+	/* Multiply offset by 2 because gl_Position range is [-1..1]. */
+	gl_Position.xy += offset * 2.0 * gl_Position.w;
 #ifdef USE_WORLD_CLIP_PLANES
-	world_clip_planes_set_clip_distance(gl_in[v].gl_ClipDistance);
+	world_clip_planes_set_clip_distance(gl_in[i].gl_ClipDistance);
 #endif
+	EmitVertex();
 }
 
-void main(void)
+void main()
 {
-#ifdef SELECT_EDGES
-	const float edge_select_threshold = 0.3;
-	if (edgeSharpness_g[0] > edge_select_threshold) {
-		vert_from_gl_in(0);
-		EmitVertex();
-		vert_from_gl_in(1);
-		EmitVertex();
+	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;
 
-		EndPrimitive();
-	}
+	vec2 line = ss_pos[0] - ss_pos[1];
+	line = abs(line) * viewportSize;
 
-	if (edgeSharpness_g[1] > edge_select_threshold) {
-		vert_from_gl_in(1);
-		EmitVertex();
-		vert_from_gl_in(2);
-		EmitVertex();
+	float half_size = wireSize;
 
-		EndPrimitive();
-	}
+	vec3 edge_ofs = half_size * viewportSizeInv.xyy * vec3(1.0, 1.0, 0.0);
 
-	if (edgeSharpness_g[2] > edge_select_threshold) {
-		vert_from_gl_in(2);
-		EmitVertex();
-		vert_from_gl_in(0);
-		EmitVertex();
+	bool horizontal = line.x > line.y;
+	edge_ofs = (horizontal) ? edge_ofs.zyz : edge_ofs.xzz;
 
-		EndPrimitive();
+	if (edgeSharpness_g[0] < 0.0) {
+		return;
 	}
-#else
-	/* Originally was:
-	 *   edgeSharpness = vec3(edgeSharpness_g[0], edgeSharpness_g[1], edgeSharpness_g[2]);
-	 *
-	 * But that strangely does not work for some AMD GPUs.
-	 * However since this code is currently only used for sculpt mode
-	 * and in this mode the `edgeSharpness_g` is not calculated,
-	 * let's simply set all to 1.0.
-	 */
-	edgeSharpness = vec3(1.0);
 
-	barycentric = vec3(1.0, 0.0, 0.0);
-	vert_from_gl_in(0);
-	facing = facing_g[0];
-	EmitVertex();
+	do_vertex(0,  half_size,  edge_ofs.xy);
+	do_vertex(0, -half_size, -edge_ofs.xy);
+	do_vertex(1,  half_size,  edge_ofs.xy);
+	do_vertex(1, -half_size, -edge_ofs.xy);
 
-	barycentric = vec3(0.0, 1.0, 0.0);
-	vert_from_gl_in(1);
-	facing = facing_g[1];
-	EmitVertex();
-
-	barycentric = vec3(0.0, 0.0, 1.0);
-	vert_from_gl_in(2);
-	facing = facing_g[2];
-	EmitVertex();
 	EndPrimitive();
-#endif /* SELECT_EDGES */
 }
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
index 53279a74352..2a328a71366 100644
--- a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
@@ -7,13 +7,17 @@ uniform mat3 NormalMatrix;
 uniform float wireStepParam;
 uniform float ofs;
 
+#ifndef USE_SCULPT
 float get_edge_sharpness(float wd)
 {
 	return (wd == 1.0) ? 1.0 : ((wd == 0.0) ? -1.0 : (wd + wireStepParam));
 }
+#else
+float get_edge_sharpness(float wd) { return 1.0; }
+#endif
 
 /* Geometry shader version */
-#if defined(SELECT_EDGES) || defined(USE_SCULPT)
+#if defined(SELECT_EDGES) || defined(USE_GEOM)
 
 in vec3 pos;
 in vec3 nor;
@@ -24,12 +28,7 @@ out float edgeSharpness_g;
 
 void main()
 {
-#  ifndef USE_SCULPT
 	edgeSharpness_g = get_edge_sharpness(wd);
-#  else
-	/* TODO approximation using normals. */
-	edgeSharpness_g = 1.0;
-#  endif
 
 	mat4 projmat = ProjectionMatrix;
 	projmat[3][2] -= ofs;
@@ -43,7 +42,7 @@ void main()
 #endif
 }
 
-#else /* SELECT_EDGES */
+#else /* USE_GEOM */
 
 in vec3 pos;
 in vec3 nor;



More information about the Bf-blender-cvs mailing list