[Bf-blender-cvs] [a3716f5945b] blender2.8: GPU_batch: Add GPU_batch_wire_from_poly_2d_encoded

Campbell Barton noreply at git.blender.org
Sat Jan 20 09:32:14 CET 2018


Commit: a3716f5945b4ea0451281e9ae4ba9e43d2793938
Author: Campbell Barton
Date:   Sat Jan 20 18:41:11 2018 +1100
Branches: blender2.8
https://developer.blender.org/rBa3716f5945b4ea0451281e9ae4ba9e43d2793938

GPU_batch: Add GPU_batch_wire_from_poly_2d_encoded

Draws wire around polygon shapes:
better visibility w/ any background color.

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

M	source/blender/editors/manipulator_library/manipulator_types/button2d_manipulator.c
M	source/blender/editors/space_view3d/view3d_manipulator_navigate.c
M	source/blender/gpu/GPU_batch.h
M	source/blender/gpu/intern/gpu_batch.c

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

diff --git a/source/blender/editors/manipulator_library/manipulator_types/button2d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/button2d_manipulator.c
index a60204b5f0a..2951ad84c0d 100644
--- a/source/blender/editors/manipulator_library/manipulator_types/button2d_manipulator.c
+++ b/source/blender/editors/manipulator_library/manipulator_types/button2d_manipulator.c
@@ -69,7 +69,7 @@ typedef struct ButtonManipulator2D {
 	bool is_init;
 	/* Use an icon or shape */
 	int icon;
-	Gwn_Batch *shape_batch;
+	Gwn_Batch *shape_batch[2];
 } ButtonManipulator2D;
 
 #define CIRCLE_RESOLUTION 32
@@ -114,7 +114,8 @@ static void button2d_draw_intern(
 			/* We shouldn't need the +1, but a NULL char is set. */
 			char *polys = MEM_mallocN(polys_len + 1, __func__);
 			RNA_property_string_get(mpr->ptr, prop, polys);
-			button->shape_batch = GPU_batch_from_poly_2d_encoded((uchar *)polys, polys_len, NULL);
+			button->shape_batch[0] = GPU_batch_tris_from_poly_2d_encoded((uchar *)polys, polys_len, NULL);
+			button->shape_batch[1] = GPU_batch_wire_from_poly_2d_encoded((uchar *)polys, polys_len, NULL);
 			MEM_freeN(polys);
 		}
 	}
@@ -131,11 +132,21 @@ static void button2d_draw_intern(
 	glEnable(GL_BLEND);
 
 	if (select == false) {
-		if (button->shape_batch != NULL) {
+		if (button->shape_batch[0] != NULL) {
 			glEnable(GL_POLYGON_SMOOTH);
-			GWN_batch_program_set_builtin(button->shape_batch, GPU_SHADER_2D_UNIFORM_COLOR);
-			GWN_batch_uniform_4f(button->shape_batch, "color", UNPACK4(color));
-			GWN_batch_draw(button->shape_batch);
+			glEnable(GL_LINE_SMOOTH);
+			glLineWidth(1.0f);
+			for (uint i = 0; i < ARRAY_SIZE(button->shape_batch) && button->shape_batch[i]; i++) {
+				GWN_batch_program_set_builtin(button->shape_batch[i], GPU_SHADER_2D_UNIFORM_COLOR);
+				GWN_batch_uniform_4f(button->shape_batch[i], "color", UNPACK4(color));
+				GWN_batch_draw(button->shape_batch[i]);
+				if (i == 0) {
+					/* Invert line color. */
+					color[0] = 1.0f - color[0];
+					color[1] = 1.0f - color[1];
+					color[2] = 1.0f - color[2];
+				}
+			}
 			glDisable(GL_POLYGON_SMOOTH);
 			gpuPopMatrix();
 		}
@@ -203,7 +214,10 @@ static int manipulator_button2d_cursor_get(wmManipulator *UNUSED(mpr))
 static void manipulator_button2d_free(wmManipulator *mpr)
 {
 	ButtonManipulator2D *shape = (ButtonManipulator2D *)mpr;
-	GWN_BATCH_DISCARD_SAFE(shape->shape_batch);
+
+	for (uint i = 0; i < ARRAY_SIZE(shape->shape_batch); i++) {
+		GWN_BATCH_DISCARD_SAFE(shape->shape_batch[i]);
+	}
 }
 
 /** \} */
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_navigate.c b/source/blender/editors/space_view3d/view3d_manipulator_navigate.c
index 0f7df8fe6aa..3fc3300e2c1 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_navigate.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_navigate.c
@@ -201,6 +201,7 @@ static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmManipulatorG
 			        mpr->ptr, prop,
 			        (const char *)info->shape, info->shape_size);
 			/* don't fade icons so much */
+			copy_v3_fl(mpr->color, 0.0f);
 			mpr->color[3] = 0.5f;
 		}
 
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index 4eaf90b486e..d2f3409dc07 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -47,7 +47,10 @@ struct rctf;
 /* gpu_batch.c */
 void GWN_batch_program_set_builtin(Gwn_Batch *batch, GPUBuiltinShader shader_id) ATTR_NONNULL(1);
 
-Gwn_Batch *GPU_batch_from_poly_2d_encoded(
+Gwn_Batch *GPU_batch_tris_from_poly_2d_encoded(
+        const uchar *polys_flat, uint polys_flat_len, const struct rctf *rect
+        ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
+Gwn_Batch *GPU_batch_wire_from_poly_2d_encoded(
         const uchar *polys_flat, uint polys_flat_len, const struct rctf *rect
         ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
 
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c
index d96edb0f2f9..1e99db2c32f 100644
--- a/source/blender/gpu/intern/gpu_batch.c
+++ b/source/blender/gpu/intern/gpu_batch.c
@@ -35,6 +35,7 @@
 #include "BLI_rect.h"
 #include "BLI_math.h"
 #include "BLI_polyfill2d.h"
+#include "BLI_sort_utils.h"
 
 
 #include "GPU_batch.h"  /* own include */
@@ -67,11 +68,11 @@ void GWN_batch_program_set_builtin(Gwn_Batch *batch, GPUBuiltinShader shader_id)
  * \param polys_flat_len: Length of the array (must be an even number).
  * \param rect: Optional region to map the byte 0..255 coords to. When not set use -1..1.
  */
-Gwn_Batch *GPU_batch_from_poly_2d_encoded(
+Gwn_Batch *GPU_batch_tris_from_poly_2d_encoded(
         const uchar *polys_flat, uint polys_flat_len, const rctf *rect)
 {
-	uchar (*polys)[2] = (void *)polys_flat;
-	uint polys_len = polys_flat_len / 2;
+	const uchar (*polys)[2] = (const void *)polys_flat;
+	const uint polys_len = polys_flat_len / 2;
 	BLI_assert(polys_flat_len == polys_len * 2);
 
 	/* Over alloc in both cases */
@@ -100,10 +101,10 @@ Gwn_Batch *GPU_batch_from_poly_2d_encoded(
 		if (polys[i_poly - 1][0] == polys[i_poly][0] &&
 		    polys[i_poly - 1][1] == polys[i_poly][1])
 		{
-			const uint verts_len = (&verts[i_vert]) - verts_step;
-			BLI_assert(verts_len >= 3);
-			const uint tris_len = (verts_len - 2);
-			BLI_polyfill_calc(verts_step, verts_len, -1, tris_step);
+			const uint verts_step_len = (&verts[i_vert]) - verts_step;
+			BLI_assert(verts_step_len >= 3);
+			const uint tris_len = (verts_step_len - 2);
+			BLI_polyfill_calc(verts_step, verts_step_len, -1, tris_step);
 			/* offset indices */
 			if (verts_step != verts) {
 				uint *t = tris_step[0];
@@ -115,8 +116,8 @@ Gwn_Batch *GPU_batch_from_poly_2d_encoded(
 				}
 				BLI_assert(t == tris_step[tris_len]);
 			}
-			verts_step += verts_len;
-			tris_step += (verts_len - 2);
+			verts_step += verts_step_len;
+			tris_step += tris_len;
 			i_poly++;
 			/* ignore the duplicate point */
 		}
@@ -157,6 +158,108 @@ Gwn_Batch *GPU_batch_from_poly_2d_encoded(
 	        GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX);
 }
 
+Gwn_Batch *GPU_batch_wire_from_poly_2d_encoded(
+        const uchar *polys_flat, uint polys_flat_len, const rctf *rect)
+{
+	const uchar (*polys)[2] = (const void *)polys_flat;
+	const uint polys_len = polys_flat_len / 2;
+	BLI_assert(polys_flat_len == polys_len * 2);
+
+	/* Over alloc */
+	int32_t *lines = MEM_mallocN(sizeof(*lines) * polys_len, __func__);
+	int32_t *lines_step = lines;
+
+	const float range_uchar[2] = {
+		(rect ? (rect->xmax - rect->xmin) : 2.0f) / 255.0f,
+		(rect ? (rect->ymax - rect->ymin) : 2.0f) / 255.0f,
+	};
+	const float min_uchar[2] = {
+		(rect ? rect->xmin : -1.0f),
+		(rect ? rect->ymin : -1.0f),
+	};
+
+	const bool hide_lines = true;
+
+	uint i_poly_prev = 0;
+	uint i_poly = 0;
+	while (i_poly != polys_len) {
+		i_poly++;
+		if (polys[i_poly - 1][0] == polys[i_poly][0] &&
+		    polys[i_poly - 1][1] == polys[i_poly][1])
+		{
+			const uchar (*polys_step)[2] = polys + i_poly_prev;
+			const uint polys_step_len = i_poly - i_poly_prev;
+			BLI_assert(polys_step_len >= 2);
+			for (uint i_prev = polys_step_len - 1, i = 0; i < polys_step_len; i_prev = i++) {
+				union {
+					uint8_t  as_u8[4];
+					uint16_t as_u16[2];
+					uint32_t as_u32;
+				} data;
+				data.as_u16[0] = *((const uint16_t *)polys_step[i_prev]);
+				data.as_u16[1] = *((const uint16_t *)polys_step[i]);
+				if (data.as_u16[0] > data.as_u16[1]) {
+					SWAP(uint16_t, data.as_u16[0], data.as_u16[1]);
+				}
+				*lines_step = data.as_u32;
+				lines_step++;
+			}
+			i_poly++;
+			i_poly_prev = i_poly;
+			/* ignore the duplicate point */
+		}
+	}
+
+	uint lines_len = (lines_step - lines);
+	uint lines_hide_len = 0;
+	if (hide_lines) {
+		qsort(lines, lines_len, sizeof(int32_t), BLI_sortutil_cmp_int);
+		for (uint i_prev = 0, i = 1; i < lines_len; i_prev = i++) {
+			if ((lines[i] == lines[i_prev])) {
+				lines_hide_len++;
+			}
+		}
+	}
+
+	/* We have vertices and tris, make a batch from this. */
+	static Gwn_VertFormat format = {0};
+	static struct { uint pos; } attr_id;
+	if (format.attrib_ct == 0) {
+		attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+	}
+
+	Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
+	GWN_vertbuf_data_alloc(vbo, (lines_len - lines_hide_len) * 2);
+
+	Gwn_VertBufRaw pos_step;
+	GWN_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step);
+
+	for (uint i = 0; i < lines_len; i++) {
+		if (hide_lines) {
+			if ((i + 1 != lines_len) && (lines[i + 1] == lines[i])) {
+				i++;
+				continue;
+			}
+		}
+		union {
+			uint8_t  as_u8_pair[2][2];
+			uint32_t as_u32;
+		} data;
+		data.as_u32 = lines[i];
+		for (uint k = 0; k < 2; k++) {
+			float *pos_v2 = GWN_vertbuf_raw_step(&pos_step);
+			for (uint j = 0; j < 2; j++) {
+				pos_v2[j] = min_uchar[j] + ((float)data.as_u8_pair[k][j] * range_uchar[j]);
+			}
+		}
+	}
+	MEM_freeN(lines);
+	return GWN_batch_create_ex(
+	        GWN_PRIM_LINES, vbo,
+	        NULL,
+	        GWN_BATCH_OWNS_VBO);
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */



More information about the Bf-blender-cvs mailing list