GPv3: Add initial edit mode overlay support #108511

Merged
Falk David merged 6 commits from filedescriptor/blender:overlay-grease-pencil-v3 into main 2023-06-02 15:12:55 +02:00
7 changed files with 163 additions and 27 deletions

View File

@ -209,7 +209,8 @@ set(SRC
engines/overlay/overlay_extra.cc
engines/overlay/overlay_facing.cc
engines/overlay/overlay_fade.cc
engines/overlay/overlay_gpencil.cc
engines/overlay/overlay_gpencil_legacy.cc
engines/overlay/overlay_grease_pencil.cc
engines/overlay/overlay_grid.cc
engines/overlay/overlay_image.cc
engines/overlay/overlay_lattice.cc

View File

@ -194,11 +194,18 @@ static void OVERLAY_cache_init(void *vedata)
OVERLAY_sculpt_cache_init(data);
break;
case CTX_MODE_EDIT_GPENCIL:
if (U.experimental.use_grease_pencil_version3) {
OVERLAY_edit_grease_pencil_cache_init(data);
}
else {
OVERLAY_edit_gpencil_legacy_cache_init(data);
}
break;
case CTX_MODE_PAINT_GPENCIL:
case CTX_MODE_SCULPT_GPENCIL:
case CTX_MODE_VERTEX_GPENCIL:
case CTX_MODE_WEIGHT_GPENCIL:
OVERLAY_edit_gpencil_cache_init(data);
OVERLAY_edit_gpencil_legacy_cache_init(data);
break;
case CTX_MODE_EDIT_CURVES:
OVERLAY_edit_curves_cache_init(data);
@ -220,7 +227,7 @@ static void OVERLAY_cache_init(void *vedata)
OVERLAY_mode_transfer_cache_init(data);
OVERLAY_extra_cache_init(data);
OVERLAY_facing_cache_init(data);
OVERLAY_gpencil_cache_init(data);
OVERLAY_gpencil_legacy_cache_init(data);
OVERLAY_grid_cache_init(data);
OVERLAY_image_cache_init(data);
OVERLAY_metaball_cache_init(data);
@ -279,6 +286,8 @@ static bool overlay_object_is_edit_mode(const OVERLAY_PrivateData *pd, const Obj
case OB_VOLUME:
/* No edit mode yet. */
return false;
case OB_GREASE_PENCIL:
return pd->ctx_mode == CTX_MODE_EDIT_GPENCIL;
}
}
return false;
@ -430,6 +439,11 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
case OB_CURVES:
OVERLAY_edit_curves_cache_populate(data, ob);
break;
case OB_GREASE_PENCIL:
if (U.experimental.use_grease_pencil_version3) {
OVERLAY_edit_grease_pencil_cache_populate(data, ob);
}
break;
}
}
else if (in_pose_mode && draw_bones) {
@ -478,7 +492,7 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
}
break;
case OB_GPENCIL_LEGACY:
OVERLAY_gpencil_cache_populate(data, ob);
OVERLAY_gpencil_legacy_cache_populate(data, ob);
break;
}
}
@ -650,7 +664,7 @@ static void OVERLAY_draw_scene(void *vedata)
OVERLAY_armature_draw(data);
OVERLAY_particle_draw(data);
OVERLAY_metaball_draw(data);
OVERLAY_gpencil_draw(data);
OVERLAY_gpencil_legacy_draw(data);
OVERLAY_extra_draw(data);
if (pd->overlay.flag & V3D_OVERLAY_VIEWER_ATTRIBUTE) {
OVERLAY_viewer_attribute_draw(data);
@ -718,11 +732,18 @@ static void OVERLAY_draw_scene(void *vedata)
OVERLAY_edit_particle_draw(data);
break;
case CTX_MODE_EDIT_GPENCIL:
if (U.experimental.use_grease_pencil_version3) {
OVERLAY_edit_grease_pencil_draw(data);
}
else {
OVERLAY_edit_gpencil_legacy_draw(data);
}
break;
case CTX_MODE_PAINT_GPENCIL:
case CTX_MODE_SCULPT_GPENCIL:
case CTX_MODE_VERTEX_GPENCIL:
case CTX_MODE_WEIGHT_GPENCIL:
OVERLAY_edit_gpencil_draw(data);
OVERLAY_edit_gpencil_legacy_draw(data);
break;
case CTX_MODE_SCULPT_CURVES:
break;

View File

@ -23,7 +23,7 @@
#include "draw_common.h"
#include "draw_manager_text.h"
void OVERLAY_edit_gpencil_cache_init(OVERLAY_Data *vedata)
void OVERLAY_edit_gpencil_legacy_cache_init(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
@ -205,7 +205,7 @@ void OVERLAY_edit_gpencil_cache_init(OVERLAY_Data *vedata)
}
}
void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
void OVERLAY_gpencil_legacy_cache_init(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
@ -426,7 +426,7 @@ static void OVERLAY_gpencil_color_names(Object *ob)
nullptr, ob, nullptr, overlay_gpencil_draw_stroke_color_name, ob, false, cfra);
}
void OVERLAY_gpencil_cache_populate(OVERLAY_Data *vedata, Object *ob)
void OVERLAY_gpencil_legacy_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
View3D *v3d = draw_ctx->v3d;
@ -450,7 +450,7 @@ void OVERLAY_gpencil_cache_populate(OVERLAY_Data *vedata, Object *ob)
}
}
void OVERLAY_gpencil_draw(OVERLAY_Data *vedata)
void OVERLAY_gpencil_legacy_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
@ -459,7 +459,7 @@ void OVERLAY_gpencil_draw(OVERLAY_Data *vedata)
}
}
void OVERLAY_edit_gpencil_draw(OVERLAY_Data *vedata)
void OVERLAY_edit_gpencil_legacy_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;

View File

@ -0,0 +1,49 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2023 Blender Foundation. */
/** \file
* \ingroup draw_engine
*/
#include "DRW_render.h"
#include "BKE_grease_pencil.hh"
#include "overlay_private.hh"
void OVERLAY_edit_grease_pencil_cache_init(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
GPUShader *sh;
DRWShadingGroup *grp;
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
DRW_STATE_BLEND_ALPHA;
DRW_PASS_CREATE(psl->edit_grease_pencil_ps, (state | pd->clipping_state));
sh = OVERLAY_shader_edit_particle_point();
grp = pd->edit_grease_pencil_points_grp = DRW_shgroup_create(sh, psl->edit_grease_pencil_ps);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
}
void OVERLAY_edit_grease_pencil_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
DRWShadingGroup *points_grp = pd->edit_grease_pencil_points_grp;
if (points_grp) {
struct GPUBatch *geom = DRW_cache_grease_pencil_edit_points_get(ob, pd->cfra);
DRW_shgroup_call_no_cull(points_grp, geom, ob);
}
}
void OVERLAY_edit_grease_pencil_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
if (psl->edit_grease_pencil_ps) {
DRW_draw_pass(psl->edit_grease_pencil_ps);
}
}

View File

@ -73,6 +73,7 @@ typedef struct OVERLAY_PassList {
DRWPass *edit_gpencil_ps;
DRWPass *edit_gpencil_gizmos_ps;
DRWPass *edit_gpencil_curve_ps;
DRWPass *edit_grease_pencil_ps;
DRWPass *edit_lattice_ps;
DRWPass *edit_mesh_depth_ps[2];
DRWPass *edit_mesh_verts_ps[2];
@ -250,6 +251,7 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *edit_lattice_wires_grp;
DRWShadingGroup *edit_gpencil_points_grp;
DRWShadingGroup *edit_gpencil_wires_grp;
DRWShadingGroup *edit_grease_pencil_points_grp;
DRWShadingGroup *edit_gpencil_curve_handle_grp;
DRWShadingGroup *edit_gpencil_curve_points_grp;
DRWShadingGroup *edit_mesh_depth_grp[2];
@ -555,11 +557,15 @@ void OVERLAY_edit_curve_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_edit_surf_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_edit_curve_draw(OVERLAY_Data *vedata);
void OVERLAY_edit_gpencil_cache_init(OVERLAY_Data *vedata);
void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata);
void OVERLAY_gpencil_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_gpencil_draw(OVERLAY_Data *vedata);
void OVERLAY_edit_gpencil_draw(OVERLAY_Data *vedata);
void OVERLAY_edit_gpencil_legacy_cache_init(OVERLAY_Data *vedata);
void OVERLAY_gpencil_legacy_cache_init(OVERLAY_Data *vedata);
void OVERLAY_gpencil_legacy_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_gpencil_legacy_draw(OVERLAY_Data *vedata);
void OVERLAY_edit_gpencil_legacy_draw(OVERLAY_Data *vedata);
void OVERLAY_edit_grease_pencil_cache_init(OVERLAY_Data *vedata);
void OVERLAY_edit_grease_pencil_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_edit_grease_pencil_draw(OVERLAY_Data *vedata);
void OVERLAY_edit_lattice_cache_init(OVERLAY_Data *vedata);
void OVERLAY_edit_lattice_cache_populate(OVERLAY_Data *vedata, Object *ob);

View File

@ -280,6 +280,7 @@ void DRW_cache_gpencil_sbuffer_clear(struct Object *ob);
/* Grease Pencil */
struct GPUBatch *DRW_cache_grease_pencil_get(struct Object *ob, int cfra);
struct GPUBatch *DRW_cache_grease_pencil_edit_points_get(struct Object *ob, int cfra);
struct GPUVertBuf *DRW_cache_grease_pencil_position_buffer_get(struct Object *ob, int cfra);
struct GPUVertBuf *DRW_cache_grease_pencil_color_buffer_get(struct Object *ob, int cfra);

View File

@ -36,6 +36,12 @@ struct GreasePencilBatchCache {
GPUIndexBuf *ibo;
/** Batches */
GPUBatch *geom_batch;
GPUBatch *edit_points;
/* Crazy-space point positions for original points. */
GPUVertBuf *edit_points_pos;
/* Selection of original points. */
GPUVertBuf *edit_points_selection;
/** Cache is dirty. */
bool is_dirty;
@ -132,6 +138,10 @@ static void grease_pencil_batch_cache_clear(GreasePencil &grease_pencil)
GPU_VERTBUF_DISCARD_SAFE(cache->vbo_col);
GPU_INDEXBUF_DISCARD_SAFE(cache->ibo);
GPU_BATCH_DISCARD_SAFE(cache->edit_points);
GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_pos);
GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_selection);
cache->is_dirty = true;
}
@ -177,7 +187,7 @@ BLI_INLINE int32_t pack_rotation_aspect_hardness(float rot, float asp, float har
return packed;
}
static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfra)
{
BLI_assert(grease_pencil.runtime != nullptr);
GreasePencilBatchCache *cache = static_cast<GreasePencilBatchCache *>(
@ -199,6 +209,7 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
/* First, count how many vertices and triangles are needed for the whole object. Also record the
* offsets into the curves for the vertices and triangles. */
int total_points_num = 0;
int total_verts_num = 0;
int total_triangles_num = 0;
int v_offset = 0;
Vector<Array<int>> verts_start_offsets_per_visible_drawing;
@ -239,15 +250,17 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
v_offset += 1 + points.size() + (is_cyclic ? 1 : 0) + 1;
}
total_points_num += curves.points_num();
/* One vertex is stored before and after as padding. Cyclic strokes have one extra
* vertex. */
total_points_num += curves.points_num() + num_cyclic + curves.curves_num() * 2;
* vertex.*/
total_verts_num += curves.points_num() + num_cyclic + curves.curves_num() * 2;
total_triangles_num += (curves.points_num() + num_cyclic) * 2;
total_triangles_num += drawing.triangles().size();
if (drawing.has_stroke_buffer()) {
const int num_buffer_points = drawing.stroke_buffer().size();
total_points_num += 1 + num_buffer_points + 1;
total_verts_num += 1 + num_buffer_points + 1;
total_triangles_num += num_buffer_points * 2;
verts_start_offsets[curves.curves_range().size()] = v_offset;
/* TODO: triangles for stroke buffer. */
@ -258,6 +271,22 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
tris_start_offsets_per_visible_drawing.append(std::move(tris_start_offsets));
}
static GPUVertFormat format_edit_points_pos = {0};
if (format_edit_points_pos.attr_len == 0) {
GPU_vertformat_attr_add(&format_edit_points_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
}
static GPUVertFormat format_edit_points_selection = {0};
if (format_edit_points_selection.attr_len == 0) {
GPU_vertformat_attr_add(
&format_edit_points_selection, "selection", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
}
cache->edit_points_pos = GPU_vertbuf_create_with_format(&format_edit_points_pos);
cache->edit_points_selection = GPU_vertbuf_create_with_format(&format_edit_points_selection);
GPU_vertbuf_data_alloc(cache->edit_points_pos, total_points_num);
GPU_vertbuf_data_alloc(cache->edit_points_selection, total_points_num);
GPUUsageType vbo_flag = GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY;
/* Create VBOs. */
GPUVertFormat *format = grease_pencil_stroke_format();
@ -265,8 +294,8 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
cache->vbo = GPU_vertbuf_create_with_format_ex(format, vbo_flag);
cache->vbo_col = GPU_vertbuf_create_with_format_ex(format_col, vbo_flag);
/* Add extra space at the end of the buffer because of quad load. */
GPU_vertbuf_data_alloc(cache->vbo, total_points_num + 2);
GPU_vertbuf_data_alloc(cache->vbo_col, total_points_num + 2);
GPU_vertbuf_data_alloc(cache->vbo, total_verts_num + 2);
GPU_vertbuf_data_alloc(cache->vbo_col, total_verts_num + 2);
GPUIndexBufBuilder ibo;
MutableSpan<GreasePencilStrokeVert> verts = {
@ -275,10 +304,17 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
MutableSpan<GreasePencilColorVert> cols = {
static_cast<GreasePencilColorVert *>(GPU_vertbuf_get_data(cache->vbo_col)),
GPU_vertbuf_get_vertex_len(cache->vbo_col)};
MutableSpan<float3> edit_points = {
static_cast<float3 *>(GPU_vertbuf_get_data(cache->edit_points_pos)),
GPU_vertbuf_get_vertex_len(cache->edit_points_pos)};
MutableSpan<float> edit_points_selection = {
static_cast<float *>(GPU_vertbuf_get_data(cache->edit_points_selection)),
GPU_vertbuf_get_vertex_len(cache->edit_points_selection)};
/* Create IBO. */
GPU_indexbuf_init(&ibo, GPU_PRIM_TRIS, total_triangles_num, 0xFFFFFFFFu);
/* Fill buffers with data. */
int drawing_start_offset = 0;
for (const int drawing_i : drawings.index_range()) {
const GreasePencilDrawing &drawing = *drawings[drawing_i];
const bke::CurvesGeometry &curves = drawing.geometry.wrap();
@ -290,6 +326,8 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
"radius", ATTR_DOMAIN_POINT, 1.0f);
const VArray<float> opacities = *attributes.lookup_or_default<float>(
"opacity", ATTR_DOMAIN_POINT, 1.0f);
const VArray<float> selection_float = *attributes.lookup_or_default<float>(
".selection", ATTR_DOMAIN_POINT, false);
const VArray<int8_t> start_caps = *attributes.lookup_or_default<int8_t>(
"start_cap", ATTR_DOMAIN_CURVE, 0);
const VArray<int8_t> end_caps = *attributes.lookup_or_default<int8_t>(
@ -300,6 +338,12 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
const Span<int> verts_start_offsets = verts_start_offsets_per_visible_drawing[drawing_i];
const Span<int> tris_start_offsets = tris_start_offsets_per_visible_drawing[drawing_i];
edit_points.slice(drawing_start_offset, curves.points_num()).copy_from(curves.positions());
MutableSpan<float> selection_slice = edit_points_selection.slice(drawing_start_offset,
curves.points_num());
selection_float.materialize(selection_slice);
drawing_start_offset += curves.points_num();
auto populate_point = [&](IndexRange verts_range,
int curve_i,
int8_t start_cap,
@ -435,8 +479,8 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
}
/* Mark last 2 verts as invalid. */
verts[total_points_num + 0].mat = -1;
verts[total_points_num + 1].mat = -1;
verts[total_verts_num + 0].mat = -1;
verts[total_verts_num + 1].mat = -1;
/* Also mark first vert as invalid. */
verts[0].mat = -1;
@ -448,6 +492,10 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
GPU_vertbuf_use(cache->vbo);
GPU_vertbuf_use(cache->vbo_col);
/* Create the batches */
cache->edit_points = GPU_batch_create(GPU_PRIM_POINTS, cache->edit_points_pos, nullptr);
GPU_batch_vertbuf_add(cache->edit_points, cache->edit_points_selection, false);
cache->is_dirty = false;
}
@ -498,17 +546,27 @@ GPUBatch *DRW_cache_grease_pencil_get(Object *ob, int cfra)
using namespace blender::draw;
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil, cfra);
grease_pencil_batches_ensure(grease_pencil, cfra);
grease_pencil_geom_batch_ensure(grease_pencil, cfra);
return cache->geom_batch;
}
GPUBatch *DRW_cache_grease_pencil_edit_points_get(Object *ob, int cfra)
{
using namespace blender::draw;
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil, cfra);
grease_pencil_geom_batch_ensure(grease_pencil, cfra);
return cache->edit_points;
}
GPUVertBuf *DRW_cache_grease_pencil_position_buffer_get(Object *ob, int cfra)
{
using namespace blender::draw;
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil, cfra);
grease_pencil_batches_ensure(grease_pencil, cfra);
grease_pencil_geom_batch_ensure(grease_pencil, cfra);
return cache->vbo;
}
@ -518,7 +576,7 @@ GPUVertBuf *DRW_cache_grease_pencil_color_buffer_get(Object *ob, int cfra)
using namespace blender::draw;
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil, cfra);
grease_pencil_batches_ensure(grease_pencil, cfra);
grease_pencil_geom_batch_ensure(grease_pencil, cfra);
return cache->vbo_col;
}