[Bf-blender-cvs] [72bfa849ee9] blender2.8: UI: Node Editor: Port nodelink drawing to shader based drawing.

Clément Foucault noreply at git.blender.org
Thu Apr 5 16:08:30 CEST 2018


Commit: 72bfa849ee9769e899399ac90c0921618ea18004
Author: Clément Foucault
Date:   Thu Apr 5 15:41:17 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB72bfa849ee9769e899399ac90c0921618ea18004

UI: Node Editor: Port nodelink drawing to shader based drawing.

Use the new GPU_SHADER_2D_NODELINK and GPU_SHADER_2D_NODELINK_INST to
accelerate nodelink drawing.

This commit does not include the batching functionnality. So this should
not make a lot of difference.

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

M	source/blender/editors/space_node/drawnode.c
M	source/blender/editors/space_node/node_draw.c
M	source/blender/editors/space_node/node_intern.h

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

diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 3c00114579e..8865e7b40f9 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -53,6 +53,7 @@
 #include "BIF_glutil.h"
 
 #include "GPU_draw.h"
+#include "GPU_batch.h"
 #include "GPU_immediate.h"
 #include "GPU_matrix.h"
 
@@ -3292,11 +3293,10 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
 	BKE_image_release_ibuf(ima, ibuf, lock);
 }
 
-
-/* if v2d not NULL, it clips and returns 0 if not visible */
-bool node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
+/* return quadratic beziers points for a given nodelink and clip if v2d is not NULL. */
+static bool node_link_bezier_handles(View2D *v2d, SpaceNode *snode, bNodeLink *link, float vec[4][2])
 {
-	float dist, vec[4][2];
+	float dist;
 	float deltax, deltay;
 	float cursor[2] = {0.0f, 0.0f};
 	int toreroute, fromreroute;
@@ -3364,13 +3364,23 @@ bool node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, flo
 		vec[2][0] = vec[3][0] - dist;
 		vec[2][1] = vec[3][1];
 	}
+
 	if (v2d && min_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax) {
-		/* clipped */
+		return 0; /* clipped */
 	}
 	else if (v2d && max_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin) {
-		/* clipped */
+		return 0; /* clipped */
 	}
-	else {
+
+	return 1;
+}
+
+/* if v2d not NULL, it clips and returns 0 if not visible */
+bool node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
+{
+	float vec[4][2];
+
+	if (node_link_bezier_handles(v2d, snode, link, vec)) {
 		/* always do all three, to prevent data hanging around */
 		BKE_curve_forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0],
 		                              coord_array[0] + 0, resol, sizeof(float) * 2);
@@ -3382,135 +3392,241 @@ bool node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, flo
 	return 0;
 }
 
+#define NODELINK_GROUP_SIZE 256
 #define LINK_RESOL  24
-#define LINK_ARROW  12  /* position of arrow on the link, LINK_RESOL/2 */
-#define ARROW_SIZE (7 * UI_DPI_FAC)
-void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link,
-                           int th_col1, bool do_shaded, int th_col2, bool do_triple, int th_col3)
-{
-	float coord_array[LINK_RESOL + 1][2];
-	
-	if (node_link_bezier_points(v2d, snode, link, coord_array, LINK_RESOL)) {
-		float dist, spline_step = 0.0f;
-		int i;
-		int drawarrow;
-		/* store current linewidth */
-		float linew;
-		float arrow[2], arrow1[2], arrow2[2];
-		glGetFloatv(GL_LINE_WIDTH, &linew);
-		unsigned int pos;
-		
-		/* we can reuse the dist variable here to increment the GL curve eval amount*/
-		dist = 1.0f / (float)LINK_RESOL;
-		
-		glEnable(GL_LINE_SMOOTH);
-		
-		drawarrow = ((link->tonode && (link->tonode->type == NODE_REROUTE)) &&
-		             (link->fromnode && (link->fromnode->type == NODE_REROUTE)));
-
-		if (drawarrow) {
-			/* draw arrow in line segment LINK_ARROW */
-			float d_xy[2], len;
-
-			sub_v2_v2v2(d_xy, coord_array[LINK_ARROW], coord_array[LINK_ARROW - 1]);
-			len = len_v2(d_xy);
-			mul_v2_fl(d_xy, ARROW_SIZE / len);
-			arrow1[0] = coord_array[LINK_ARROW][0] - d_xy[0] + d_xy[1];
-			arrow1[1] = coord_array[LINK_ARROW][1] - d_xy[1] - d_xy[0];
-			arrow2[0] = coord_array[LINK_ARROW][0] - d_xy[0] - d_xy[1];
-			arrow2[1] = coord_array[LINK_ARROW][1] - d_xy[1] + d_xy[0];
-			arrow[0] = coord_array[LINK_ARROW][0];
-			arrow[1] = coord_array[LINK_ARROW][1];
+#define LINK_WIDTH  2.5f
+// #define ARROW_SIZE (7 * UI_DPI_FAC)
+#define ARROW_SIZE 7
+
+static float arrow_verts[3][2] = {{-ARROW_SIZE, ARROW_SIZE}, {0.0f, 0.0f}, {-ARROW_SIZE, -ARROW_SIZE}};
+static float arrow_expand_axis[3][2] = {{0.7071f, 0.7071f}, {M_SQRT2, 0.0f}, {0.7071f, -0.7071f}};
+
+struct {
+	Gwn_Batch *batch; /* for batching line together */
+	Gwn_Batch *batch_single; /* for single line */
+	Gwn_VertBuf *inst_vbo;
+	unsigned int p0_id, p1_id, p2_id, p3_id;
+	unsigned int colid_id;
+	Gwn_VertBufRaw p0_step, p1_step, p2_step, p3_step;
+	Gwn_VertBufRaw colid_step;
+	unsigned int count;
+	bool enabled;
+} g_batch_link = {0};
+
+static void nodelink_batch_reset(void)
+{
+	GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p0_id, &g_batch_link.p0_step);
+	GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p1_id, &g_batch_link.p1_step);
+	GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p2_id, &g_batch_link.p2_step);
+	GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p3_id, &g_batch_link.p3_step);
+	GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.colid_id, &g_batch_link.colid_step);
+	g_batch_link.count = 0;
+}
+
+static void set_nodelink_vertex(
+        Gwn_VertBuf *vbo,
+        unsigned int uv_id, unsigned int pos_id, unsigned int exp_id, unsigned int v,
+        const unsigned char uv[2], const float pos[2], const float exp[2])
+{
+	GWN_vertbuf_attr_set(vbo, uv_id, v, uv);
+	GWN_vertbuf_attr_set(vbo, pos_id, v, pos);
+	GWN_vertbuf_attr_set(vbo, exp_id, v, exp);
+}
+
+static void nodelink_batch_init(void)
+{
+	Gwn_VertFormat format = {0};
+	unsigned int uv_id = GWN_vertformat_attr_add(&format, "uv", GWN_COMP_U8, 2, GWN_FETCH_INT_TO_FLOAT_UNIT);
+	unsigned int pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+	unsigned int expand_id = GWN_vertformat_attr_add(&format, "expand", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+	Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format_ex(&format, GWN_USAGE_STATIC);
+	int vcount = LINK_RESOL * 2; /* curve */
+	vcount += 2; /* restart strip */
+	vcount += 3*2; /* arrow */
+	vcount *= 2; /* shadow */
+	vcount += 2; /* restart strip */
+	GWN_vertbuf_data_alloc(vbo, vcount);
+	int v = 0;
+
+	for (int k = 0; k < 2; ++k) {
+		unsigned char uv[2] = {0, 0};
+		float pos[2] = {0.0f, 0.0f};
+		float exp[2] = {0.0f, 1.0f};
+
+		/* restart */
+		if (k == 1)
+			set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
+
+		/* curve strip */
+		for (int i = 0; i < LINK_RESOL; ++i) {
+			uv[0] = 255 * (i / (float)(LINK_RESOL-1));
+			uv[1] = 0;
+			set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
+			uv[1] = 255;
+			set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
 		}
-
-		if (do_triple || drawarrow || (!do_shaded)) {
-			pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
-			immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+		/* restart */
+		set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
+
+		uv[0] = 127;
+		uv[1] = 0;
+		copy_v2_v2(pos, arrow_verts[0]);
+		copy_v2_v2(exp, arrow_expand_axis[0]);
+		set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
+		/* arrow */
+		for (int i = 0; i < 3; ++i) {
+			uv[1] = 0;
+			copy_v2_v2(pos, arrow_verts[i]);
+			copy_v2_v2(exp, arrow_expand_axis[i]);
+			set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
+
+			uv[1] = 255;
+			set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
 		}
 
-		if (do_triple) {
-			immUniformThemeColorShadeAlpha(th_col3, -80, -120);
-			glLineWidth(4.0f);
+		/* restart */
+		if (k == 0)
+			set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
+	}
 
-			immBegin(GWN_PRIM_LINE_STRIP, (LINK_RESOL + 1));
+	g_batch_link.batch = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO);
+	gpu_batch_presets_register(g_batch_link.batch);
 
-			for (i = 0; i <= LINK_RESOL; i++) {
-				immVertex2fv(pos, coord_array[i]);
-			}
+	g_batch_link.batch_single = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, 0);
+	gpu_batch_presets_register(g_batch_link.batch_single);
 
-			immEnd();
+	/* Instances data */
+	Gwn_VertFormat format_inst = {0};
+	g_batch_link.p0_id = GWN_vertformat_attr_add(&format_inst, "P0", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+	g_batch_link.p1_id = GWN_vertformat_attr_add(&format_inst, "P1", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+	g_batch_link.p2_id = GWN_vertformat_attr_add(&format_inst, "P2", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+	g_batch_link.p3_id = GWN_vertformat_attr_add(&format_inst, "P3", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+	g_batch_link.colid_id = GWN_vertformat_attr_add(&format_inst, "colid_doarrow", GWN_COMP_U8, 4, GWN_FETCH_INT);
+	g_batch_link.inst_vbo = GWN_vertbuf_create_with_format_ex(&format_inst, GWN_USAGE_STREAM);
+	GWN_vertbuf_data_alloc(g_batch_link.inst_vbo, NODELINK_GROUP_SIZE); /* Alloc max count but only draw the range we need. */
 
-			if (drawarrow) {
-				immBegin(GWN_PRIM_LINE_STRIP, 3);
-				immVertex2fv(pos, arrow1);
-				immVertex2fv(pos, arrow);
-				immVertex2fv(pos, arrow2);
-				immEnd();
-			}
-		}
+	GWN_batch_instbuf_set(g_batch_link.batch, g_batch_link.inst_vbo, true);
 
-		glLineWidth(1.5f);
+	nodelink_batch_reset();
+}
 
-		if (drawarrow) {
-			immUniformThemeColorBlend(th_col1, th_col2, 0.5f);
+static char nodelink_get_color_id(int th_col)
+{
+	switch (th_col) {
+		case TH_WIRE:        return 1;
+		case TH_WIRE_INNER:  return 2;
+		case TH_ACTIVE:      return 3;
+		case TH_EDGE_SELECT: return 4;
+		case TH_REDALERT:    return 5;
+	}
+	return 0;
+}
 
-			immBegin(GWN_PRIM_LINE_STRIP, 3);
-			immVertex2fv(pos, arrow1);
-			immVertex2fv(pos, arrow);
-			immVertex2fv(pos, arrow2);
-			immEnd();
-		}
+static void nodelink_batch_draw(SpaceNode *snode)
+{
+	if (g_batch_link.count == 0)
+		return;
 
-		if (!do_shaded) {
-			immUniformThemeColor(th_col1);
+	glEnable(GL_BLEND);
 
-			immBegin(GWN_PRIM_LINE_STRIP, (LINK_RESOL + 1));
+	float colors[6][4] = {{0.0f}};
+	UI_GetThemeColor4fv(TH_WIRE_INNER,  colors[nodelink_get_color_id(TH_WIRE_INNER)]);
+	UI_GetThemeColor4fv(TH_WIRE,        colors[nodelink_get_color_id(TH_WIRE)]);
+	UI_GetThemeColor4fv(TH_ACTIVE,      colors[nodelink_get_color_id(TH_ACTIVE)]);
+	UI_GetThemeColor4fv(TH_EDGE_SELECT, colors[nodelink_get_color_id(TH_EDGE_SELECT)]);
+	UI_GetThemeColor4fv(TH_REDALERT,    colors[nodelink_get_color_id(TH_REDALERT)]);
 
-			for (i = 0; i <

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list