[Bf-blender-cvs] [2e609a45822] greasepencil-refactor: GPencil: Refactor: Add fill vertex color suppport
Clément Foucault
noreply at git.blender.org
Sat Jan 11 19:40:23 CET 2020
Commit: 2e609a45822e69562ab5877c52698132f07ac4b3
Author: Clément Foucault
Date: Sat Jan 11 19:36:03 2020 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rB2e609a45822e69562ab5877c52698132f07ac4b3
GPencil: Refactor: Add fill vertex color suppport
This is a waste of GPU memory tho. It is duplicated for each gp points.
A better approach would be to store a per stroke data that we could fetch
using a stroke id.
===================================================================
M source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
M source/blender/draw/intern/draw_cache_impl_gpencil.c
===================================================================
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
index 7d12c6e61e4..8062c5c26bb 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
@@ -217,6 +217,8 @@ in vec4 uv2;
in vec4 col1;
in vec4 col2;
+in vec4 fcol1;
+
void discard_vert()
{
/* We set the vertex at the camera origin to generate 0 fragments. */
@@ -481,7 +483,7 @@ void fill_vertex()
fill_col.a = 1.0;
}
- color_output(fill_col, vec4(0.0), 1.0, mix_tex);
+ color_output(fill_col, fcol1, 1.0, mix_tex);
matFlag = materials[m].flag & GP_FILL_FLAGS;
matFlag |= m << GP_MATID_SHIFT;
diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.c b/source/blender/draw/intern/draw_cache_impl_gpencil.c
index e546a575de4..6ca49250eff 100644
--- a/source/blender/draw/intern/draw_cache_impl_gpencil.c
+++ b/source/blender/draw/intern/draw_cache_impl_gpencil.c
@@ -46,6 +46,7 @@
typedef struct GpencilBatchCache {
/** Instancing Data */
GPUVertBuf *vbo;
+ GPUVertBuf *vbo_col;
/** Fill Topology */
GPUIndexBuf *ibo;
/** Instancing Batches */
@@ -121,6 +122,7 @@ static void gpencil_batch_cache_clear(GpencilBatchCache *cache)
GPU_BATCH_DISCARD_SAFE(cache->fill_batch);
GPU_BATCH_DISCARD_SAFE(cache->stroke_batch);
GPU_VERTBUF_DISCARD_SAFE(cache->vbo);
+ GPU_VERTBUF_DISCARD_SAFE(cache->vbo_col);
GPU_INDEXBUF_DISCARD_SAFE(cache->ibo);
GPU_BATCH_DISCARD_SAFE(cache->edit_lines_batch);
@@ -188,7 +190,6 @@ typedef struct gpStrokeVert {
float mat, strength, stroke_id, point_id;
/** Position and thickness packed in the same attribute. */
float pos[3], thickness;
- float col[4];
float uv_fill[2], u_stroke, v_rot;
} gpStrokeVert;
@@ -198,7 +199,6 @@ static GPUVertFormat *gpencil_stroke_format(void)
if (format.attr_len == 0) {
GPU_vertformat_attr_add(&format, "ma", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- GPU_vertformat_attr_add(&format, "col", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
GPU_vertformat_attr_add(&format, "uv", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
/* IMPORTANT: This means having only 4 attributes to fit into GPU module limit of 16 attrib. */
GPU_vertformat_multiload_enable(&format, 4);
@@ -222,6 +222,24 @@ static GPUVertFormat *gpencil_edit_stroke_format(void)
return &format;
}
+/* MUST match the format below. */
+typedef struct gpColorVert {
+ float vcol[4]; /* Vertex color */
+ float fcol[4]; /* Fill color */
+} gpColorVert;
+
+static GPUVertFormat *gpencil_color_format(void)
+{
+ static GPUVertFormat format = {0};
+ if (format.attr_len == 0) {
+ GPU_vertformat_attr_add(&format, "col", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ GPU_vertformat_attr_add(&format, "fcol", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ /* IMPORTANT: This means having only 4 attributes to fit into GPU module limit of 16 attrib. */
+ GPU_vertformat_multiload_enable(&format, 4);
+ }
+ return &format;
+}
+
/* MUST match the format below. */
typedef struct gpExtraDataVert {
float layer_rand;
@@ -248,6 +266,7 @@ typedef struct gpIterData {
gpStrokeVert *verts;
gpExtraDataVert *verts_extra;
};
+ gpColorVert *cols;
GPUIndexBufBuilder ibo;
int vert_len;
int tri_len;
@@ -266,16 +285,22 @@ static int gpencil_stroke_is_cyclic(const bGPDstroke *gps)
return ((gps->flag & GP_STROKE_CYCLIC) != 0) && (gps->totpoints > 2);
}
-static void gpencil_buffer_add_point(
- gpStrokeVert *verts, const bGPDstroke *gps, const bGPDspoint *pt, int v, bool is_endpoint)
+static void gpencil_buffer_add_point(gpStrokeVert *verts,
+ gpColorVert *cols,
+ const bGPDstroke *gps,
+ const bGPDspoint *pt,
+ int v,
+ bool is_endpoint)
{
/* Note: we use the sign of stength and thickness to pass cap flag. */
const bool round_cap0 = (gps->caps[0] == GP_STROKE_CAP_ROUND);
const bool round_cap1 = (gps->caps[1] == GP_STROKE_CAP_ROUND);
gpStrokeVert *vert = &verts[v];
+ gpColorVert *col = &cols[v];
copy_v3_v3(vert->pos, &pt->x);
copy_v2_v2(vert->uv_fill, pt->uv_fill);
- copy_v4_v4(vert->col, pt->vert_color);
+ copy_v4_v4(col->vcol, pt->vert_color);
+ copy_v4_v4(col->fcol, gps->vert_color_fill);
vert->strength = (round_cap0) ? pt->strength : -pt->strength;
vert->u_stroke = pt->uv_fac;
vert->stroke_id = gps->runtime.stroke_start;
@@ -288,7 +313,9 @@ static void gpencil_buffer_add_point(
vert->mat = (is_endpoint) ? -1 : (gps->mat_nr % GP_MATERIAL_BUFFER_LEN);
}
-static void gpencil_buffer_add_stroke(gpStrokeVert *verts, const bGPDstroke *gps)
+static void gpencil_buffer_add_stroke(gpStrokeVert *verts,
+ gpColorVert *cols,
+ const bGPDstroke *gps)
{
const bGPDspoint *pts = gps->points;
int pts_len = gps->totpoints;
@@ -297,18 +324,18 @@ static void gpencil_buffer_add_stroke(gpStrokeVert *verts, const bGPDstroke *gps
/* First point for adjacency (not drawn). */
int adj_idx = (is_cyclic) ? (pts_len - 1) : min_ii(pts_len - 1, 1);
- gpencil_buffer_add_point(verts, gps, &pts[adj_idx], v++, true);
+ gpencil_buffer_add_point(verts, cols, gps, &pts[adj_idx], v++, true);
for (int i = 0; i < pts_len; i++) {
- gpencil_buffer_add_point(verts, gps, &pts[i], v++, false);
+ gpencil_buffer_add_point(verts, cols, gps, &pts[i], v++, false);
}
/* Draw line to first point to complete the loop for cyclic strokes. */
if (is_cyclic) {
- gpencil_buffer_add_point(verts, gps, &pts[0], v++, false);
+ gpencil_buffer_add_point(verts, cols, gps, &pts[0], v++, false);
}
/* Last adjacency point (not drawn). */
adj_idx = (is_cyclic) ? 1 : max_ii(0, pts_len - 2);
- gpencil_buffer_add_point(verts, gps, &pts[adj_idx], v++, true);
+ gpencil_buffer_add_point(verts, cols, gps, &pts[adj_idx], v++, true);
}
static void gpencil_buffer_add_fill(GPUIndexBufBuilder *ibo, const bGPDstroke *gps)
@@ -327,7 +354,7 @@ static void gpencil_stroke_iter_cb(bGPDlayer *UNUSED(gpl),
void *thunk)
{
gpIterData *iter = (gpIterData *)thunk;
- gpencil_buffer_add_stroke(iter->verts, gps);
+ gpencil_buffer_add_stroke(iter->verts, iter->cols, gps);
if (gps->tot_triangles > 0) {
gpencil_buffer_add_fill(&iter->ibo, gps);
}
@@ -372,12 +399,16 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfr
};
BKE_gpencil_visible_stroke_iter(ob, NULL, gp_object_verts_count_cb, &iter, do_onion, cfra);
- /* Create VBO. */
+ /* Create VBOs. */
GPUVertFormat *format = gpencil_stroke_format();
+ GPUVertFormat *format_col = gpencil_color_format();
cache->vbo = GPU_vertbuf_create_with_format(format);
+ cache->vbo_col = GPU_vertbuf_create_with_format(format_col);
/* Add extra space at the end of the buffer because of quad load. */
GPU_vertbuf_data_alloc(cache->vbo, iter.vert_len + 2);
+ GPU_vertbuf_data_alloc(cache->vbo_col, iter.vert_len + 2);
iter.verts = (gpStrokeVert *)cache->vbo->data;
+ iter.cols = (gpColorVert *)cache->vbo_col->data;
/* Create IBO. */
GPU_indexbuf_init(&iter.ibo, GPU_PRIM_TRIS, iter.tri_len, iter.vert_len);
@@ -394,8 +425,10 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfr
/* Create the batches */
cache->fill_batch = GPU_batch_create(GPU_PRIM_TRIS, cache->vbo, cache->ibo);
+ GPU_batch_vertbuf_add(cache->fill_batch, cache->vbo_col);
cache->stroke_batch = GPU_batch_create(GPU_PRIM_TRI_STRIP, gpencil_dummy_buffer_get(), NULL);
GPU_batch_instbuf_add_ex(cache->stroke_batch, cache->vbo, 0);
+ GPU_batch_instbuf_add_ex(cache->stroke_batch, cache->vbo_col, 0);
gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY;
cache->is_dirty = false;
@@ -546,16 +579,21 @@ static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_stroke, bool do_
/* Create VBO. */
GPUVertFormat *format = gpencil_stroke_format();
+ GPUVertFormat *format_color = gpencil_color_format();
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(format);
+ GPUVertBuf *vbo_col = GPU_vertbuf_create_with_format(format_color);
/* Add extra space at the end (and start) of the buffer because of quad load and cyclic. */
GPU_vertbuf_data_alloc(vbo, 1 + vert_len + 1 + 2);
+ GPU_vertbuf_data_alloc(vbo_col, 1 + vert_len + 1 + 2);
gpStrokeVert *verts = (gpStrokeVert *)vbo->data;
+ gpColorVert *cols = (gpColorVert *)vbo_col->data;
/* Fill buffers with data. */
- gpencil_buffer_add_stroke(verts, gps);
+ gpencil_buffer_add_stroke(verts, cols, gps);
GPUBatch *batch = GPU_batch_create(GPU_PRIM_TRI_STRIP, gpencil_dummy_buffer_get(), NULL);
GPU_batch_instbuf_add_ex(batch, vbo, true);
+ GPU_batch_instbuf_add_ex(batch, vbo_col, true);
gpd->runtime.sbuffer_stroke_batch = batch;
@@ -589,8 +627,10 @@ static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_stroke, bool do_
GPUIndexBuf *ibo = GPU_indexbuf_build(&ibo_builder);
GPUVertBuf *vbo = gpd->runtime.sbuffer_stroke_batch->inst[0];
+ GPUVertBuf *vbo_col = gpd->runtime.sbuffer_stroke_batch->inst[1];
GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, ibo, GPU_BATCH_OWNS_INDEX);
+ GPU_batch_vertbuf_add(batch, vbo_col);
gpd->runtime.sbuffer_fill_batch = batch;
}
More information about the Bf-blender-cvs
mailing list