[Bf-blender-cvs] [a2dff881403] greasepencil-object: WIP: Add current stroke buffer to drawing manager

Antonio Vazquez noreply at git.blender.org
Sat Apr 22 12:48:29 CEST 2017


Commit: a2dff881403ea6a9e695027ee92317a9d1ec9599
Author: Antonio Vazquez
Date:   Sat Apr 22 12:48:07 2017 +0200
Branches: greasepencil-object
https://developer.blender.org/rBa2dff881403ea6a9e695027ee92317a9d1ec9599

WIP: Add current stroke buffer to drawing manager

Pending to solve the error for first stroke before frame is created

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

M	source/blender/draw/engines/gpencil/gpencil_draw.c
M	source/blender/draw/engines/gpencil/gpencil_mode.c
M	source/blender/draw/engines/gpencil/gpencil_mode.h

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

diff --git a/source/blender/draw/engines/gpencil/gpencil_draw.c b/source/blender/draw/engines/gpencil/gpencil_draw.c
index c52d4ded62d..b4f45767f6b 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw.c
@@ -31,6 +31,8 @@
 #include "BLI_polyfill2d.h"
 
 #include "DNA_gpencil_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_view3d_types.h"
 
 #include "BKE_gpencil.h"
 #include "BKE_action.h"
@@ -41,6 +43,7 @@
 #include "GPU_draw.h"
 
 #include "ED_gpencil.h"
+#include "ED_view3d.h"
 
 #include "UI_resources.h"
 
@@ -59,7 +62,7 @@ static void gpencil_set_stroke_point(VertexBuffer *vbo, const bGPDspoint *pt, in
 
 	float thick = max_ff(pt->pressure * thickness, 1.0f);
 	VertexBuffer_set_attrib(vbo, thickness_id, idx, &thick);
-
+	
 	copy_v3_v3(fpt, &pt->x);
 	if (inverse) {
 		mul_v3_fl(fpt, -1.0f);
@@ -118,6 +121,182 @@ Batch *gpencil_get_stroke_geom(bGPDstroke *gps, short thickness, const float ink
 	return Batch_create(PRIM_LINE_STRIP_ADJACENCY, vbo, NULL);
 }
 
+/* helper to convert 2d to 3d for simple drawing buffer */
+static void gpencil_stroke_convertcoords(Scene *scene, ARegion *ar, ScrArea *sa, tGPspoint *point2D, float out[3], float *depth)
+{
+	float mval_f[2] = { point2D->x, point2D->y };
+	float mval_prj[2];
+	float rvec[3], dvec[3];
+	float zfac;
+
+	/* Current method just converts each point in screen-coordinates to
+	* 3D-coordinates using the 3D-cursor as reference.
+	*/
+	View3D *v3d = sa->spacedata.first;
+	const float *cursor = ED_view3d_cursor3d_get(scene, v3d);
+	copy_v3_v3(rvec, cursor);
+
+	zfac = ED_view3d_calc_zfac(ar->regiondata, rvec, NULL);
+
+	if (ED_view3d_project_float_global(ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+		sub_v2_v2v2(mval_f, mval_prj, mval_f);
+		ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
+		sub_v3_v3v3(out, rvec, dvec);
+	}
+	else {
+		zero_v3(out);
+	}
+}
+
+/* create batch geometry data for current buffer stroke shader */
+Batch *gpencil_get_buffer_stroke_geom(bGPdata *gpd, short thickness)
+{
+	const struct bContext *C = DRW_get_context();
+	Scene *scene = CTX_data_scene(C);
+	ScrArea *sa = CTX_wm_area(C);
+	ARegion *ar = CTX_wm_region(C);
+
+	tGPspoint *points = gpd->sbuffer;
+	int totpoints = gpd->sbuffer_size;
+
+	static VertexFormat format = { 0 };
+	static unsigned int pos_id, color_id, thickness_id;
+	if (format.attrib_ct == 0) {
+		pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+		color_id = VertexFormat_add_attrib(&format, "color", COMP_F32, 4, KEEP_FLOAT);
+		thickness_id = VertexFormat_add_attrib(&format, "thickness", COMP_F32, 1, KEEP_FLOAT);
+	}
+
+	VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+	VertexBuffer_allocate_data(vbo, totpoints + 2);
+
+	/* draw stroke curve */
+	const tGPspoint *tpt = points;
+	bGPDspoint pt;
+	int idx = 0;
+	float p3d[3];
+
+	float viewinvmat[4][4];
+	DRW_viewport_matrix_get(viewinvmat, DRW_MAT_VIEWINV);
+
+	for (int i = 0; i < totpoints; i++, tpt++) {
+		/* need conversion to 3d format */
+		gpencil_stroke_convertcoords(scene, ar, sa, tpt, p3d, NULL);
+		copy_v3_v3(&pt.x, p3d);
+		pt.pressure = tpt->pressure;
+		pt.strength = tpt->strength;
+
+		/* first point for adjacency (not drawn) */
+		if (i == 0) {
+			gpencil_set_stroke_point(vbo, &pt, idx, pos_id, color_id, thickness_id, thickness, gpd->scolor, true);
+			++idx;
+		}
+		/* set point */
+		gpencil_set_stroke_point(vbo, &pt, idx, pos_id, color_id, thickness_id, thickness, gpd->scolor, false);
+		++idx;
+	}
+
+	/* last adjacency point (not drawn) */
+	gpencil_set_stroke_point(vbo, &pt, idx, pos_id, color_id, thickness_id, thickness, gpd->scolor, true);
+
+	return Batch_create(PRIM_LINE_STRIP_ADJACENCY, vbo, NULL);
+}
+
+/* create batch geometry data for current buffer fill shader */
+Batch *gpencil_get_buffer_fill_geom(const tGPspoint *points, int totpoints, float ink[4])
+{
+	if (totpoints < 3) {
+		return NULL;
+	}
+
+	const struct bContext *C = DRW_get_context();
+	Scene *scene = CTX_data_scene(C);
+	ScrArea *sa = CTX_wm_area(C);
+	ARegion *ar = CTX_wm_region(C);
+
+	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);
+
+	static VertexFormat format = { 0 };
+	static unsigned int pos_id, color_id;
+	if (format.attrib_ct == 0) {
+		pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+		color_id = VertexFormat_add_attrib(&format, "color", COMP_F32, 4, KEEP_FLOAT);
+	}
+
+	VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+
+	/* draw triangulation data */
+	if (tot_triangles > 0) {
+		VertexBuffer_allocate_data(vbo, tot_triangles * 3);
+
+		const tGPspoint *tpt;
+		bGPDspoint pt;
+
+		int idx = 0;
+		float p3d[3];
+		for (int i = 0; i < tot_triangles; i++) {
+			/* vertex 1 */
+			tpt = &points[tmp_triangles[i][0]];
+			/* need conversion to 3d format */
+			gpencil_stroke_convertcoords(scene, ar, sa, tpt, p3d, NULL);
+			copy_v3_v3(&pt.x, p3d);
+			pt.pressure = tpt->pressure;
+			pt.strength = tpt->strength;
+
+			VertexBuffer_set_attrib(vbo, pos_id, idx, &pt.x);
+			VertexBuffer_set_attrib(vbo, color_id, idx, ink);
+			++idx;
+			/* vertex 2 */
+			tpt = &points[tmp_triangles[i][1]];
+			/* need conversion to 3d format */
+			gpencil_stroke_convertcoords(scene, ar, sa, tpt, p3d, NULL);
+			copy_v3_v3(&pt.x, p3d);
+			pt.pressure = tpt->pressure;
+			pt.strength = tpt->strength;
+
+			VertexBuffer_set_attrib(vbo, pos_id, idx, &pt.x);
+			VertexBuffer_set_attrib(vbo, color_id, idx, ink);
+			++idx;
+			/* vertex 3 */
+			tpt = &points[tmp_triangles[i][2]];
+			/* need conversion to 3d format */
+			gpencil_stroke_convertcoords(scene, ar, sa, tpt, p3d, NULL);
+			copy_v3_v3(&pt.x, p3d);
+			pt.pressure = tpt->pressure;
+			pt.strength = tpt->strength;
+
+			VertexBuffer_set_attrib(vbo, pos_id, idx, &pt.x);
+			VertexBuffer_set_attrib(vbo, color_id, idx, ink);
+			++idx;
+		}
+	}
+
+	/* clear memory */
+	if (tmp_triangles) {
+		MEM_freeN(tmp_triangles);
+	}
+	if (points2d) {
+		MEM_freeN(points2d);
+	}
+
+	return Batch_create(PRIM_TRIANGLES, vbo, NULL);
+}
+
+
 /* Helper for doing all the checks on whether a stroke can be drawn */
 bool gpencil_can_draw_stroke(const bGPDstroke *gps)
 {
diff --git a/source/blender/draw/engines/gpencil/gpencil_mode.c b/source/blender/draw/engines/gpencil/gpencil_mode.c
index 1ce7189b313..2c03df791f1 100644
--- a/source/blender/draw/engines/gpencil/gpencil_mode.c
+++ b/source/blender/draw/engines/gpencil/gpencil_mode.c
@@ -69,6 +69,7 @@ typedef struct GPENCIL_PassList {
 	struct DRWPass *stroke_pass;
 	struct DRWPass *fill_pass;
 	struct DRWPass *edit_pass;
+	struct DRWPass *drawing_pass;
 } GPENCIL_PassList;
 
 /* keep it under MAX_BUFFERS */
@@ -92,13 +93,17 @@ typedef struct GPENCIL_Data {
 /* *********** STATIC *********** */
 typedef struct g_data{
 	DRWShadingGroup *shgrps_edit_volumetric;
+	DRWShadingGroup *shgrps_drawing_stroke;
+	DRWShadingGroup *shgrps_drawing_fill;
 } g_data; /* Transient data */
 
 static struct {
 	struct GPUShader *gpencil_fill_sh;
 	struct GPUShader *gpencil_stroke_sh;
-	struct GPUShader *gpencil_point_sh;
+	struct GPUShader *gpencil_stroke_2D_sh;
 	struct GPUShader *gpencil_volumetric_sh;
+	struct GPUShader *gpencil_drawing_point_sh;
+	struct GPUShader *gpencil_drawing_fill_sh;
 } e_data = {NULL}; /* Engine data */
 
 /* *********** FUNCTIONS *********** */
@@ -116,10 +121,13 @@ static void GPENCIL_engine_init(void *vedata)
 												 datatoc_gpencil_stroke_geom_glsl,
 												 datatoc_gpencil_stroke_frag_glsl,
 												 NULL);
-	e_data.gpencil_point_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
 
 	e_data.gpencil_volumetric_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
 
+	e_data.gpencil_drawing_point_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
+
+	e_data.gpencil_drawing_fill_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR);
+
 	if (!stl->storage) {
 		stl->storage = MEM_callocN(sizeof(GPENCIL_Storage), "GPENCIL_Storage");
 	}
@@ -130,6 +138,7 @@ static void GPENCIL_engine_free(void)
 {
 	DRW_SHADER_FREE_SAFE(e_data.gpencil_fill_sh);
 	DRW_SHADER_FREE_SAFE(e_data.gpencil_stroke_sh);
+	DRW_SHADER_FREE_SAFE(e_data.gpencil_stroke_2D_sh);
 }
 
 /* create shading group for filling */
@@ -192,6 +201,25 @@ static DRWShadingGroup *GPENCIL_shgroup_edit_volumetric_create(GPENCIL_Data *ved
 	return grp;
 }
 
+/* create shading group for drawing strokes */
+static DRWShadingGroup *GPENCIL_shgroup_drawing_stroke_create(GPENCIL_Data *vedata, DRWPass *pass, PaletteColor *palcolor)
+{
+	GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+
+	DRWShadingGroup *grp = DRW_shgroup_create(e_data.gpencil_stroke_sh, pass);
+	DRW_shgroup_uniform_vec2(grp, "Viewport", DRW_viewport_size_get(), 1);
+	return grp;
+}
+
+/* create shading group for drawing fill */
+static DRWShadingGroup *GPENCIL_shgroup_drawing_fill_create(GPENCIL_Data *vedata, DRWPass *pass, PaletteColor *palcolor)
+{
+	GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+
+	DRWShadingGroup *grp = DRW_shgroup_create(e_data.gpencil_drawing_fill_sh, pass);
+	return grp;
+}
+
 static void GPENCIL_cache_init(void *vedata)
 {
 	GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
@@ -202,6 +230,7 @@ static void GPENCIL_cache_init(void *vedata)
 	const struct bContext *C = DRW_get_context();
 	Scene *scene = CTX_data_scene(C);
 	Scene

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list