[Bf-blender-cvs] [14057b670d0] greasepencil-object: WIP: Add basic stroke drawing using new draw manager

Antonio Vazquez noreply at git.blender.org
Tue Apr 11 19:44:40 CEST 2017


Commit: 14057b670d0f58dd627893429e81e2efd4db8b1a
Author: Antonio Vazquez
Date:   Tue Apr 11 19:43:53 2017 +0200
Branches: greasepencil-object
https://developer.blender.org/rB14057b670d0f58dd627893429e81e2efd4db8b1a

WIP: Add basic stroke drawing using new draw manager

The position is not correct and fill is still missing

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

M	source/blender/draw/CMakeLists.txt
A	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/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 62ac14bae52..ce7cad42691 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -71,6 +71,7 @@ set(SRC
 
 	engines/gpencil/gpencil_mode.h
 	engines/gpencil/gpencil_mode.c
+	engines/gpencil/gpencil_draw.c
 
 	modes/object_mode.c
 	modes/edit_armature_mode.c
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw.c b/source/blender/draw/engines/gpencil/gpencil_draw.c
new file mode 100644
index 00000000000..7819f928431
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/gpencil_draw.c
@@ -0,0 +1,162 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2008, Blender Foundation
+ * This is a new part of Blender
+ *
+ * Contributor(s): Joshua Leung, Antonio Vazquez
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/gpencil/drawgpencil.c
+ *  \ingroup edgpencil
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <math.h>
+#include <float.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_sys_types.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "BLI_polyfill2d.h"
+
+#include "BLF_api.h"
+#include "BLT_translation.h"
+
+#include "DNA_gpencil_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_gpencil.h"
+#include "BKE_image.h"
+
+#include "WM_api.h"
+
+#include "BIF_glutil.h"
+
+#include "GPU_immediate.h"
+#include "GPU_draw.h"
+
+#include "ED_gpencil.h"
+
+/* set stroke point to vbo */
+static void gpencil_set_stroke_point(VertexBuffer *vbo, const bGPDspoint *pt, int idx,
+						    unsigned int pos_id, unsigned int color_id,
+							unsigned int thickness_id, short thickness,
+	                        const float diff_mat[4][4], const float ink[4], bool inverse)
+{
+	float fpt[3];
+
+	float alpha = ink[3] * pt->strength;
+	CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
+	float col[4] = { ink[0], ink[1], ink[2], alpha };
+	VertexBuffer_set_attrib(vbo, color_id, idx, col);
+
+	float thick = max_ff(pt->pressure * thickness, 1.0f);
+	VertexBuffer_set_attrib(vbo, thickness_id, idx, &thick);
+
+	mul_v3_m4v3(fpt, diff_mat, &pt->x);
+	if (inverse) {
+		mul_v3_fl(fpt, -1.0f);
+	}
+	VertexBuffer_set_attrib(vbo, pos_id, idx, fpt);
+}
+
+/* create batch geometry data for stroke shader */
+Batch *gpencil_get_stroke_geom(bGPDstroke *gps, short thickness, const float diff_mat[4][4], const float ink[4])
+{
+	bGPDspoint *points = gps->points;
+	int totpoints = gps->totpoints;
+	/* if cyclic needs more vertex */
+	int cyclic_add = (gps->flag & GP_STROKE_CYCLIC) ? 2 : 0;
+
+	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 + cyclic_add + 2);
+
+	/* draw stroke curve */
+	const bGPDspoint *pt = points;
+	int idx = 0;
+	for (int i = 0; i < totpoints; i++, pt++) {
+		/* first point for adjacency (not drawn) */
+		if (i == 0) {
+			gpencil_set_stroke_point(vbo, pt, idx, pos_id, color_id, thickness_id, thickness, diff_mat, ink, true);
+			++idx;
+		}
+		/* set point */
+		gpencil_set_stroke_point(vbo, pt, idx, pos_id, color_id, thickness_id, thickness, diff_mat, ink, false);
+		++idx;
+	}
+
+	if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) {
+		/* draw line to first point to complete the cycle */
+		gpencil_set_stroke_point(vbo, &points[0], idx, pos_id, color_id, thickness_id, thickness, diff_mat, ink, false);
+		++idx;
+		/* now add adjacency points using 2nd & 3rd point to get smooth transition */
+		gpencil_set_stroke_point(vbo, &points[1], idx, pos_id, color_id, thickness_id, thickness, diff_mat, ink, false);
+		++idx;
+		gpencil_set_stroke_point(vbo, &points[2], idx, pos_id, color_id, thickness_id, thickness, diff_mat, ink, false);
+		++idx;
+	}
+	/* last adjacency point (not drawn) */
+	else {
+		gpencil_set_stroke_point(vbo, &points[totpoints - 1], idx, pos_id, color_id, thickness_id, thickness, diff_mat, ink, true);
+	}
+
+	return Batch_create(PRIM_LINE_STRIP_ADJACENCY, vbo, NULL);
+}
+
+/* Helper for doing all the checks on whether a stroke can be drawn */
+bool gpencil_can_draw_stroke(const bGPDstroke *gps)
+{
+	/* skip stroke if it doesn't have any valid data */
+	if ((gps->points == NULL) || (gps->totpoints < 1))
+		return false;
+
+	/* check if the color is visible */
+	PaletteColor *palcolor = gps->palcolor;
+	if ((palcolor == NULL) ||
+		(palcolor->flag & PC_COLOR_HIDE))
+	{
+		return false;
+	}
+
+	/* stroke can be drawn */
+	return true;
+}
diff --git a/source/blender/draw/engines/gpencil/gpencil_mode.c b/source/blender/draw/engines/gpencil/gpencil_mode.c
index fa78db98790..3273455b2f6 100644
--- a/source/blender/draw/engines/gpencil/gpencil_mode.c
+++ b/source/blender/draw/engines/gpencil/gpencil_mode.c
@@ -27,6 +27,7 @@
 #include "DRW_render.h"
 
 #include "BKE_gpencil.h"
+#include "ED_gpencil.h"
 
 #include "DNA_gpencil_types.h"
 
@@ -36,6 +37,7 @@
 #include "draw_common.h"
 
 #include "draw_mode_engines.h"
+#include "gpencil_mode.h"
 
 extern char datatoc_gpencil_fill_vert_glsl[];
 extern char datatoc_gpencil_fill_frag_glsl[];
@@ -172,9 +174,8 @@ static DRWShadingGroup *GPENCIL_shgroup_stroke_create(GPENCIL_Data *vedata, DRWP
 {
 	GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
 
-	float *viewport_size = DRW_viewport_size_get();
 	DRWShadingGroup *grp = DRW_shgroup_create(e_data.gpencil_stroke_sh, pass);
-	DRW_shgroup_uniform_vec2(grp, "Viewport", viewport_size, 1);
+	DRW_shgroup_uniform_vec2(grp, "Viewport", DRW_viewport_size_get(), 1);
 
 	return grp;
 }
@@ -207,6 +208,7 @@ static void GPENCIL_cache_init(void *vedata)
 	}
 }
 
+/* find shader group */
 static int GPENCIL_shgroup_find(GPENCIL_Storage *storage, PaletteColor *palcolor)
 {
 	for (int i = 0; i < storage->pal_id; ++i) {
@@ -227,6 +229,9 @@ static void GPENCIL_cache_populate(void *vedata, Object *ob)
 	DRWShadingGroup *strokegrp;
 	const bContext *C = DRW_get_context();
 	Scene *scene = CTX_data_scene(C);
+	float diff_mat[4][4];
+	float ink[4];
+	float tcolor[4];
 
 	UNUSED_VARS(psl, stl);
 
@@ -240,8 +245,13 @@ static void GPENCIL_cache_populate(void *vedata, Object *ob)
 			if (gpf == NULL)
 				continue;
 
-			// TODO: need to replace this code with full drawing checks
+			/* calculate parent position */
+			ED_gpencil_parent_location(ob, ob->gpd, gpl, diff_mat);
 			for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+				/* check if stroke can be drawn */
+				if (gpencil_can_draw_stroke(gps) == false) {
+					continue;
+				}
 				/* try to find shader group or create a new one */
 				int id = GPENCIL_shgroup_find(stl->storage, gps->palcolor);
 				if (id == -1) {
@@ -259,12 +269,17 @@ static void GPENCIL_cache_populate(void *vedata, Object *ob)
 				struct Batch *fill_geom = DRW_cache_surface_get(ob); // TODO: replace with real funct
 				/* Add fill geom to a shading group */
 				DRW_shgroup_call_add(fillgrp, fill_geom, ob->obmat);
-
-				/* stroke */
-				struct Batch *stroke_geom = DRW_cache_surface_get(ob); // TODO: replace with real funct
-				/* Add stroke geom to a shading group */
-				DRW_shgroup_call_add(strokegrp, stroke_geom, ob->obmat);
 #endif
+				/* stroke */
+				interp_v3_v3v3(tcolor, gps->palcolor->rgb, gpl->tintcolor, gpl->tintcolor[3]);
+				tcolor[3] = gps->palcolor->rgb[3] * gpl->opacity;
+				copy_v4_v4(ink, tcolor);
+
+				short sthickness = gps->thickness + gpl->thickness;
+				if (sthickness > 0) {
+					struct Batch *stroke_geom = gpencil_get_stroke_geom(gps, sthickness, diff_mat, ink);
+					DRW_shgroup_call_add(strokegrp, stroke_geom, ob->obmat);
+				}
 			}
 		}
 	}
diff --git a/source/blender/draw/engines/gpencil/gpencil_mode.h b/source/blender/draw/engines/gpencil/gpencil_mode.h
index fbbae6601ea..5fa2f304945 100644
--- a/source/blender/draw/engines/gpencil/gpencil_mode.h
+++ b/source/blender/draw/engines/gpencil/gpencil_mode.h
@@ -26,6 +26,9 @@
 #ifndef __GPENCIL_MODE_H__
 #define __GPENCIL_MODE_H__
 
+struct Batch;
 
+struct Batch *gpencil_get_stroke_geom(struct bGPDstroke *gps, short thickness, const float diff_mat[4][4], const float ink[4]);
+bool gpencil_can_draw_stroke(const struct bGPDstroke *gps);
 
 #endif /* __GPENCIL_MODE_H__ */
\ No newline at end of file




More information about the Bf-blender-cvs mailing list