Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonioya <blendergit@gmail.com>2018-12-15 19:21:47 +0300
committerAntonioya <blendergit@gmail.com>2018-12-15 19:21:47 +0300
commit351f537fa832c50971454af304a071c096427e71 (patch)
tree3746ee812d1104dd6cdc13549ea80ee7e16b00dc /source/blender/draw
parentf9917a8d431f5480d9a5d58dfcf84863911f3bf2 (diff)
GP: New Curve primitive and other primitive improvements
This commit adds support for new curve tool and adds more functionalities to the existing primitives, including new handles, editing, stroke thickness curve, noise, preview of the real stroke, etc. Thanks to @charlie for his great contribution to this improvement.
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c83
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_utils.c68
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c3
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.h3
4 files changed, 124 insertions, 33 deletions
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
index c75445f3ae5..a098fb74bc8 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -252,6 +252,9 @@ GPUBatch *DRW_gpencil_get_buffer_stroke_geom(bGPdata *gpd, short thickness)
tGPspoint *points = gpd->runtime.sbuffer;
int totpoints = gpd->runtime.sbuffer_size;
+ /* if cyclic needs more vertex */
+ int cyclic_add = (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC) ? 1 : 0;
+ int totvertex = totpoints + cyclic_add + 2;
static GPUVertFormat format = { 0 };
static uint pos_id, color_id, thickness_id, uvdata_id;
@@ -263,11 +266,11 @@ GPUBatch *DRW_gpencil_get_buffer_stroke_geom(bGPdata *gpd, short thickness)
}
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(vbo, totpoints + 2);
+ GPU_vertbuf_data_alloc(vbo, totvertex);
/* draw stroke curve */
const tGPspoint *tpt = points;
- bGPDspoint pt, pt2;
+ bGPDspoint pt, pt2, pt3;
int idx = 0;
/* get origin to reproject point */
@@ -281,19 +284,22 @@ GPUBatch *DRW_gpencil_get_buffer_stroke_geom(bGPdata *gpd, short thickness)
/* first point for adjacency (not drawn) */
if (i == 0) {
- if (totpoints > 1) {
- ED_gpencil_tpoint_to_point(ar, origin, &points[1], &pt2);
+ if (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC && totpoints > 2) {
+ ED_gpencil_tpoint_to_point(ar, origin, &points[totpoints - 1], &pt2);
gpencil_set_stroke_point(
- vbo, &pt2, idx,
- pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ vbo, &pt2, idx,
+ pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ idx++;
}
else {
+ ED_gpencil_tpoint_to_point(ar, origin, &points[1], &pt2);
gpencil_set_stroke_point(
- vbo, &pt, idx,
- pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ vbo, &pt2, idx,
+ pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ idx++;
}
- idx++;
}
+
/* set point */
gpencil_set_stroke_point(
vbo, &pt, idx,
@@ -302,16 +308,27 @@ GPUBatch *DRW_gpencil_get_buffer_stroke_geom(bGPdata *gpd, short thickness)
}
/* last adjacency point (not drawn) */
- if (totpoints > 2) {
- ED_gpencil_tpoint_to_point(ar, origin, &points[totpoints - 2], &pt2);
+ if (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC && totpoints > 2) {
+ /* draw line to first point to complete the cycle */
+ ED_gpencil_tpoint_to_point(ar, origin, &points[0], &pt2);
gpencil_set_stroke_point(
- vbo, &pt2, idx,
- pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ vbo, &pt2, idx,
+ pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ idx++;
+ /* now add adjacency point (not drawn) */
+ ED_gpencil_tpoint_to_point(ar, origin, &points[1], &pt3);
+ gpencil_set_stroke_point(
+ vbo, &pt3, idx,
+ pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ idx++;
}
+ /* last adjacency point (not drawn) */
else {
+ ED_gpencil_tpoint_to_point(ar, origin, &points[totpoints - 2], &pt2);
gpencil_set_stroke_point(
- vbo, &pt, idx,
- pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ vbo, &pt2, idx,
+ pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ idx++;
}
return GPU_batch_create_ex(GPU_PRIM_LINE_STRIP_ADJ, vbo, NULL, GPU_BATCH_OWNS_VBO);
@@ -367,6 +384,42 @@ GPUBatch *DRW_gpencil_get_buffer_point_geom(bGPdata *gpd, short thickness)
return GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
+/* create batch geometry data for current buffer control point shader */
+GPUBatch *DRW_gpencil_get_buffer_ctrlpoint_geom(bGPdata *gpd)
+{
+ bGPDcontrolpoint *cps = gpd->runtime.cp_points;
+ int totpoints = gpd->runtime.tot_cp_points;
+
+ static GPUVertFormat format = { 0 };
+ static uint pos_id, color_id, size_id;
+ if (format.attr_len == 0) {
+ pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ size_id = GPU_vertformat_attr_add(&format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ }
+
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, totpoints);
+
+ int idx = 0;
+ for (int i = 0; i < gpd->runtime.tot_cp_points; i++) {
+ bGPDcontrolpoint *cp = &cps[i];
+ float color[4];
+ copy_v3_v3(color, cp->color);
+ color[3] = 0.5f;
+ GPU_vertbuf_attr_set(vbo, color_id, idx, color);
+
+ /* scale size */
+ float size = cp->size * 0.8f;
+ GPU_vertbuf_attr_set(vbo, size_id, idx, &size);
+
+ GPU_vertbuf_attr_set(vbo, pos_id, idx, &cp->x);
+ idx++;
+ }
+
+ return GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO);
+}
+
/* create batch geometry data for current buffer fill shader */
GPUBatch *DRW_gpencil_get_buffer_fill_geom(bGPdata *gpd)
{
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
index 87772a72015..3b1c51cb8eb 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
@@ -434,7 +434,7 @@ DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(
DRW_shgroup_uniform_int(grp, "xraymode", (const int *) &gpd->xray_mode, 1);
}
else {
- /* for drawing always on front */
+ /* for drawing always on predefined z-depth */
DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1);
}
@@ -527,7 +527,7 @@ static DRWShadingGroup *DRW_gpencil_shgroup_point_create(
DRW_shgroup_uniform_int(grp, "xraymode", (const int *)&gpd->xray_mode, 1);
}
else {
- /* for drawing always on front */
+ /* for drawing always on on predefined z-depth */
DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1);
}
@@ -1161,6 +1161,9 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, T
{
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+ const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) : true;
Brush *brush = BKE_paint_brush(&ts->gp_paint->paint);
bGPdata *gpd_eval = ob->data;
/* need the original to avoid cow overhead while drawing */
@@ -1184,7 +1187,7 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, T
/* Check if may need to draw the active stroke cache, only if this layer is the active layer
* that is being edited. (Stroke buffer is currently stored in gp-data)
*/
- if (ED_gpencil_session_active() && (gpd->runtime.sbuffer_size > 0)) {
+ if (gpd->runtime.sbuffer_size > 0) {
if ((gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) {
/* It should also be noted that sbuffer contains temporary point types
* i.e. tGPspoints NOT bGPDspoints
@@ -1194,11 +1197,11 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, T
if (gpd->runtime.sbuffer_size > 1) {
if ((gp_style) && (gp_style->mode == GP_STYLE_MODE_LINE)) {
stl->g_data->shgrps_drawing_stroke = DRW_gpencil_shgroup_stroke_create(
- e_data, vedata, psl->drawing_pass, e_data->gpencil_stroke_sh, NULL, gpd, gp_style, -1, false);
+ e_data, vedata, psl->drawing_pass, e_data->gpencil_stroke_sh, NULL, gpd, gp_style, -1, false);
}
else {
stl->g_data->shgrps_drawing_stroke = DRW_gpencil_shgroup_point_create(
- e_data, vedata, psl->drawing_pass, e_data->gpencil_point_sh, NULL, gpd, gp_style, -1, false);
+ e_data, vedata, psl->drawing_pass, e_data->gpencil_point_sh, NULL, gpd, gp_style, -1, false);
}
/* clean previous version of the batch */
@@ -1211,32 +1214,32 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, T
/* use unit matrix because the buffer is in screen space and does not need conversion */
if (gpd->runtime.mode == GP_STYLE_MODE_LINE) {
e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_stroke_geom(
- gpd, lthick);
+ gpd, lthick);
}
else {
e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_point_geom(
- gpd, lthick);
+ gpd, lthick);
}
if (gp_style->flag & GP_STYLE_STROKE_SHOW) {
DRW_shgroup_call_add(
- stl->g_data->shgrps_drawing_stroke,
- e_data->batch_buffer_stroke,
- stl->storage->unit_matrix);
+ stl->g_data->shgrps_drawing_stroke,
+ e_data->batch_buffer_stroke,
+ stl->storage->unit_matrix);
}
if ((gpd->runtime.sbuffer_size >= 3) &&
- (gpd->runtime.sfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) &&
- ((gpd->runtime.sbuffer_sflag & GP_STROKE_NOFILL) == 0) &&
- ((brush->gpencil_settings->flag & GP_BRUSH_DISSABLE_LASSO) == 0) &&
- (gp_style->flag & GP_STYLE_FILL_SHOW))
+ (gpd->runtime.sfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) &&
+ ((gpd->runtime.sbuffer_sflag & GP_STROKE_NOFILL) == 0) &&
+ ((brush->gpencil_settings->flag & GP_BRUSH_DISSABLE_LASSO) == 0) &&
+ (gp_style->flag & GP_STYLE_FILL_SHOW))
{
/* if not solid, fill is simulated with solid color */
if (gpd->runtime.bfill_style > 0) {
gpd->runtime.sfill[3] = 0.5f;
}
stl->g_data->shgrps_drawing_fill = DRW_shgroup_create(
- e_data->gpencil_drawing_fill_sh, psl->drawing_pass);
+ e_data->gpencil_drawing_fill_sh, psl->drawing_pass);
/* clean previous version of the batch */
if (stl->storage->buffer_fill) {
@@ -1247,15 +1250,44 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, T
e_data->batch_buffer_fill = DRW_gpencil_get_buffer_fill_geom(gpd);
DRW_shgroup_call_add(
- stl->g_data->shgrps_drawing_fill,
- e_data->batch_buffer_fill,
- stl->storage->unit_matrix);
+ stl->g_data->shgrps_drawing_fill,
+ e_data->batch_buffer_fill,
+ stl->storage->unit_matrix);
stl->storage->buffer_fill = true;
}
stl->storage->buffer_stroke = true;
}
}
}
+
+ /* control points */
+ if ((overlay) && (gpd->runtime.tot_cp_points > 0) &&
+ ((gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) &&
+ ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) &&
+ ((v3d->gizmo_flag & V3D_GIZMO_HIDE_TOOL) == 0))
+ {
+
+ DRWShadingGroup *shgrp = DRW_shgroup_create(
+ e_data->gpencil_edit_point_sh, psl->drawing_pass);
+ const float *viewport_size = DRW_viewport_size_get();
+ DRW_shgroup_uniform_vec2(shgrp, "Viewport", viewport_size, 1);
+
+ /* clean previous version of the batch */
+ if (stl->storage->buffer_ctrlpoint) {
+ GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_ctrlpoint);
+ MEM_SAFE_FREE(e_data->batch_buffer_ctrlpoint);
+ stl->storage->buffer_ctrlpoint = false;
+ }
+
+ e_data->batch_buffer_ctrlpoint = DRW_gpencil_get_buffer_ctrlpoint_geom(gpd);
+
+ DRW_shgroup_call_add(
+ shgrp,
+ e_data->batch_buffer_ctrlpoint,
+ stl->storage->unit_matrix);
+
+ stl->storage->buffer_ctrlpoint = true;
+ }
}
/* create all missing batches */
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 66d9bac1fac..dc62ca34c92 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -289,6 +289,9 @@ static void GPENCIL_engine_free(void)
GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_fill);
MEM_SAFE_FREE(e_data.batch_buffer_fill);
+ GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_ctrlpoint);
+ MEM_SAFE_FREE(e_data.batch_buffer_ctrlpoint);
+
GPU_BATCH_DISCARD_SAFE(e_data.batch_grid);
MEM_SAFE_FREE(e_data.batch_grid);
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 3c0675c5e8c..6f2b40136ca 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -133,6 +133,7 @@ typedef struct GPENCIL_Storage {
bool reset_cache;
bool buffer_stroke;
bool buffer_fill;
+ bool buffer_ctrlpoint;
const float *pixsize;
float render_pixsize;
int tonemapping;
@@ -299,6 +300,7 @@ typedef struct GPENCIL_e_data {
/* for buffer only one batch is nedeed because the drawing is only of one stroke */
GPUBatch *batch_buffer_stroke;
GPUBatch *batch_buffer_fill;
+ GPUBatch *batch_buffer_ctrlpoint;
/* grid geometry */
GPUBatch *batch_grid;
@@ -386,6 +388,7 @@ void DRW_gpencil_get_edlin_geom(struct GpencilBatchCacheElem *be, struct bGPDstr
struct GPUBatch *DRW_gpencil_get_buffer_stroke_geom(struct bGPdata *gpd, short thickness);
struct GPUBatch *DRW_gpencil_get_buffer_fill_geom(struct bGPdata *gpd);
struct GPUBatch *DRW_gpencil_get_buffer_point_geom(struct bGPdata *gpd, short thickness);
+struct GPUBatch *DRW_gpencil_get_buffer_ctrlpoint_geom(struct bGPdata *gpd);
struct GPUBatch *DRW_gpencil_get_grid(Object *ob);
/* object cache functions */