[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