[Bf-blender-cvs] [f23db59] blender2.8: GPencil: Display stroke filling while drawing

Antonioya noreply at git.blender.org
Fri Oct 14 12:07:26 CEST 2016


Commit: f23db59e48024a6f89b80ff5c2fc36dc45694fc3
Author: Antonioya
Date:   Fri Oct 14 12:02:49 2016 +0200
Branches: blender2.8
https://developer.blender.org/rBf23db59e48024a6f89b80ff5c2fc36dc45694fc3

GPencil: Display stroke filling while drawing

Before this change, the stroke was filled only after complete the stroke drawing. For artist is better to get a feedback of the area he is filling while drawing, so this commit draws the filling area while drawing.

The triangulation of the stroke is recalculated every time the function is called because using a cache is not useful because the points information is changing all the time while the stroke is being drawing.

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

M	source/blender/editors/gpencil/drawgpencil.c
M	source/blender/editors/gpencil/gpencil_paint.c
M	source/blender/makesdna/DNA_gpencil_types.h

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

diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 8e62066..5564cab 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -123,9 +123,72 @@ static void gp_set_point_varying_color(const bGPDspoint *pt, const float ink[4],
 	immAttrib4ub(attrib_id, F2UB(ink[0]), F2UB(ink[1]), F2UB(ink[2]), F2UB(alpha));
 }
 
+/* draw fills for buffer stroke */
+static void gp_draw_stroke_buffer_fill(tGPspoint *points, int totpoints, float ink[4])
+{
+	if (totpoints < 3) {
+		return;
+	}
+	int tot_triangles = totpoints - 2;
+	/* allocate memory for temporary areas */
+	unsigned int(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * tot_triangles, "GP Stroke buffer temp triangulation");
+	float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * totpoints, "GP Stroke buffer temp 2d points");
+
+	/* Convert points to array and triangulate
+	* Here a cache is not used because while drawing the information changes all the time, so the cache
+	* would be recalculated constantly, so it is better to do direct calculation for each function call
+	*/
+	for (int i = 0; i < totpoints; i++) {
+		const tGPspoint *pt = &points[i];
+		points2d[i][0] = pt->x;
+		points2d[i][1] = pt->y;
+	}
+	BLI_polyfill_calc((const float(*)[2])points2d, (unsigned int)totpoints, 0, (unsigned int(*)[3])tmp_triangles);
+
+	/* draw triangulation data */
+	if (tot_triangles > 0) {
+		VertexFormat *format = immVertexFormat();
+		unsigned pos = add_attrib(format, "pos", GL_INT, 2, CONVERT_INT_TO_FLOAT);
+		unsigned color = add_attrib(format, "color", GL_UNSIGNED_BYTE, 4, NORMALIZE_INT_TO_FLOAT);
+
+		immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
+		/* Draw all triangles for filling the polygon */
+		immBegin(GL_TRIANGLES, tot_triangles * 3);
+		/* TODO: use batch instead of immediate mode, to share vertices */
+
+		tGPspoint *pt;
+		for (int i = 0; i < tot_triangles; i++) {
+			/* vertex 1 */
+			pt = &points[tmp_triangles[i][0]];
+			gp_set_tpoint_varying_color(pt, ink, color);
+			immVertex2iv(pos, &pt->x);
+			/* vertex 2 */
+			pt = &points[tmp_triangles[i][1]];
+			gp_set_tpoint_varying_color(pt, ink, color);
+			immVertex2iv(pos, &pt->x);
+			/* vertex 3 */
+			pt = &points[tmp_triangles[i][2]];
+			gp_set_tpoint_varying_color(pt, ink, color);
+			immVertex2iv(pos, &pt->x);
+		}
+
+		immEnd();
+		immUnbindProgram();
+	}
+
+	/* clear memory */
+	if (tmp_triangles) {
+		MEM_freeN(tmp_triangles);
+	}
+	if (points2d) {
+		MEM_freeN(points2d);
+	}
+}
+
 /* draw stroke defined in buffer (simple ogl lines/points for now, as dotted lines) */
 static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short thickness,
-                                  short dflag, short sflag, float ink[4])
+                                  short dflag, short sflag, float ink[4], float fill_ink[4])
 {
 	/* error checking */
 	if ((points == NULL) || (totpoints <= 0))
@@ -194,6 +257,11 @@ static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short
 
 	immEnd();
 	immUnbindProgram();
+
+	// draw fill
+	if (fill_ink[3] > GPENCIL_ALPHA_OPACITY_THRESH) {
+		gp_draw_stroke_buffer_fill(points, totpoints, fill_ink);
+	}
 }
 
 /* --------- 2D Stroke Drawing Helpers --------- */
@@ -1410,7 +1478,7 @@ static void gp_draw_data_layers(
 				                                 dflag, gpd->scolor);
 			}
 			else {
-				gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag, gpd->scolor);
+				gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag, gpd->scolor, gpd->sfill);
 			}
 		}
 	}
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 4a5b170..8820c2f 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -1467,6 +1467,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
 	bGPDpalettecolor *palcolor = p->palettecolor;
 	bGPdata *pdata = p->gpd;
 	copy_v4_v4(pdata->scolor, palcolor->color);
+	copy_v4_v4(pdata->sfill, palcolor->fill);
 	pdata->sflag = palcolor->flag;
 
 	return 1;
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 23b7342..180dd55 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -295,6 +295,7 @@ typedef struct bGPdata {
 	short sbuffer_sflag;		/* flags for stroke that cache represents */
 	void *sbuffer;				/* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */
 	float scolor[4];            /* buffer color using palettes */
+	float sfill[4];             /* buffer fill color */
 	char  pad[6];               /* padding for compiler alignment error */
 	short sflag;                /* settings for palette color */




More information about the Bf-blender-cvs mailing list