Initial Grease Pencil 3.0 stage #106848

Merged
Falk David merged 224 commits from filedescriptor/blender:grease-pencil-v3 into main 2023-05-30 11:14:22 +02:00
4 changed files with 112 additions and 118 deletions
Showing only changes of commit 00726d67d9 - Show all commits

View File

@ -401,8 +401,7 @@ blender::Span<GreasePencilDrawingOrReference *> GreasePencil::drawings() const
}
void GreasePencil::foreach_visible_drawing(
int frame,
blender::FunctionRef<void(GreasePencilDrawing &, blender::bke::gpencil::Layer &)> function)
int frame, blender::FunctionRef<void(GreasePencilDrawing &)> function)
{
using namespace blender::bke::gpencil;
@ -419,7 +418,7 @@ void GreasePencil::foreach_visible_drawing(
GreasePencilDrawingOrReference *drawing_or_reference = drawings[index];
if (drawing_or_reference->type == GREASE_PENCIL_DRAWING) {
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_or_reference);
function(*drawing, layer);
function(*drawing);
}
else if (drawing_or_reference->type == GREASE_PENCIL_DRAWING_REFERENCE) {
/* TODO */

View File

@ -25,7 +25,6 @@ using namespace draw;
class ObjectModule {
private:
LayerModule &layers_;
MaterialModule &materials_;
ShaderModule &shaders_;
@ -152,39 +151,39 @@ class ObjectModule {
GPUVertBuf *color_tx = DRW_cache_grease_pencil_color_buffer_get(object, current_frame_);
GPUBatch *geom = DRW_cache_grease_pencil_get(object, current_frame_);
grease_pencil.foreach_visible_drawing(
current_frame_, [&](GreasePencilDrawing &drawing, bke::gpencil::Layer &layer) {
/* TODO(fclem): Pass per frame object matrix here. */
ResourceHandle handle = manager.resource_handle(object_ref);
gpObject &ob = objects_buf_.get_or_resize(handle.resource_index());
ob.is_shadeless = false;
ob.stroke_order3d = false;
ob.tint = float4(1.0); // frame_tint_get(gpd, frame.gpf, current_frame_);
ob.layer_offset = layer_offset;
ob.material_offset = material_offset;
// grease_pencil.foreach_visible_drawing(current_frame_, [&](GreasePencilDrawing & /*drawing*/)
// {
/* TODO(fclem): Pass per frame object matrix here. */
ResourceHandle handle = manager.resource_handle(object_ref);
gpObject &ob = objects_buf_.get_or_resize(handle.resource_index());
ob.is_shadeless = false;
ob.stroke_order3d = false;
ob.tint = float4(1.0); // frame_tint_get(gpd, frame.gpf, current_frame_);
ob.layer_offset = layer_offset;
ob.material_offset = material_offset;
if (do_layer_blending) {
// for (const LayerData &layer : frame.layers) {
// UNUSED_VARS(layer);
// if (has_blending(layer)) {
// object_subpass.framebuffer_set(*vfx_fb.current());
// }
if (do_layer_blending) {
// for (const LayerData &layer : frame.layers) {
// UNUSED_VARS(layer);
// if (has_blending(layer)) {
// object_subpass.framebuffer_set(*vfx_fb.current());
// }
/* TODO(fclem): Only draw subrange of geometry for this layer. */
object_subpass.draw(geom, handle);
/* TODO(fclem): Only draw subrange of geometry for this layer. */
object_subpass.draw(geom, handle);
// if (has_blending(layer)) {
// layer_blend_sync(object_ref, object_subpass);
// }
// }
}
else {
/* Fast path. */
object_subpass.bind_texture("gp_pos_tx", position_tx);
object_subpass.bind_texture("gp_col_tx", color_tx);
object_subpass.draw(geom, handle);
}
});
// if (has_blending(layer)) {
// layer_blend_sync(object_ref, object_subpass);
// }
// }
}
else {
/* Fast path. */
object_subpass.bind_texture("gp_pos_tx", position_tx);
object_subpass.bind_texture("gp_col_tx", color_tx);
object_subpass.draw(geom, handle);
}
// });
#if 0
if (object_has_vfx) {
Review

Add a comment what is this about, or remove.

Add a comment what is this about, or remove.

View File

@ -226,16 +226,15 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
/* First count how many vertices and triangles are needed for the whole object. */
int total_points_num = 0;
int total_triangles_num = 0;
grease_pencil.foreach_visible_drawing(
cfra, [&](GreasePencilDrawing &drawing, blender::bke::gpencil::Layer &layer) {
bke::CurvesGeometry &curves = drawing.geometry.wrap();
int num_cyclic = count_cyclic_curves(curves);
/* 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;
total_triangles_num += (curves.points_num() + num_cyclic) * 2;
total_triangles_num += drawing.runtime->triangles_cache.size();
});
grease_pencil.foreach_visible_drawing(cfra, [&](GreasePencilDrawing &drawing) {
bke::CurvesGeometry &curves = drawing.geometry.wrap();
int num_cyclic = count_cyclic_curves(curves);
/* 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;
total_triangles_num += (curves.points_num() + num_cyclic) * 2;
total_triangles_num += drawing.runtime->triangles_cache.size();
});
GPUUsageType vbo_flag = GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY;
/* Create VBOs. */
@ -259,86 +258,84 @@ static void grease_pencil_batches_ensure(GreasePencil &grease_pencil, int cfra)
/* Fill buffers with data. */
int v = 0;
grease_pencil.foreach_visible_drawing(
cfra, [&](GreasePencilDrawing &drawing, blender::bke::gpencil::Layer &layer) {
bke::CurvesGeometry &curves = drawing.geometry.wrap();
bke::AttributeAccessor attributes = curves.attributes();
offset_indices::OffsetIndices<int> points_by_curve = curves.points_by_curve();
const Span<float3> positions = curves.positions();
const VArray<bool> cyclic = curves.cyclic();
VArray<float> radii = attributes.lookup_or_default<float>(
"radius", ATTR_DOMAIN_POINT, 1.0f);
VArray<float> opacities = attributes.lookup_or_default<float>(
"opacity", ATTR_DOMAIN_POINT, 1.0f);
VArray<int> materials = attributes.lookup_or_default<int>(
"material_index", ATTR_DOMAIN_CURVE, -1);
grease_pencil.foreach_visible_drawing(cfra, [&](GreasePencilDrawing &drawing) {
bke::CurvesGeometry &curves = drawing.geometry.wrap();
bke::AttributeAccessor attributes = curves.attributes();
offset_indices::OffsetIndices<int> points_by_curve = curves.points_by_curve();
const Span<float3> positions = curves.positions();
const VArray<bool> cyclic = curves.cyclic();
VArray<float> radii = attributes.lookup_or_default<float>("radius", ATTR_DOMAIN_POINT, 1.0f);
VArray<float> opacities = attributes.lookup_or_default<float>(
"opacity", ATTR_DOMAIN_POINT, 1.0f);
VArray<int> materials = attributes.lookup_or_default<int>(
"material_index", ATTR_DOMAIN_CURVE, -1);
auto populate_point = [&](int curve_i, int point_i, int v_start, int v) {
copy_v3_v3(verts[v].pos, positions[point_i]);
verts[v].radius = radii[point_i];
verts[v].opacity = opacities[point_i];
verts[v].point_id = v;
verts[v].stroke_id = v_start;
verts[v].mat = materials[curve_i] % GPENCIL_MATERIAL_BUFFER_LEN;
auto populate_point = [&](int curve_i, int point_i, int v_start, int v) {
copy_v3_v3(verts[v].pos, positions[point_i]);
verts[v].radius = radii[point_i];
verts[v].opacity = opacities[point_i];
verts[v].point_id = v;
verts[v].stroke_id = v_start;
verts[v].mat = materials[curve_i] % GPENCIL_MATERIAL_BUFFER_LEN;
/* TODO */
verts[v].packed_asp_hard_rot = pack_rotation_aspect_hardness(0.0f, 1.0f, 1.0f);
/* TODO */
verts[v].u_stroke = 0;
/* TODO */
verts[v].uv_fill[0] = verts[v].uv_fill[1] = 0;
/* TODO */
verts[v].packed_asp_hard_rot = pack_rotation_aspect_hardness(0.0f, 1.0f, 1.0f);
/* TODO */
verts[v].u_stroke = 0;
/* TODO */
verts[v].uv_fill[0] = verts[v].uv_fill[1] = 0;
/* TODO */
copy_v4_v4(cols[v].vcol, float4(0.0f, 0.0f, 0.0f, 0.0f));
copy_v4_v4(cols[v].fcol, float4(0.0f, 0.0f, 0.0f, 0.0f));
/* TODO */
copy_v4_v4(cols[v].vcol, float4(0.0f, 0.0f, 0.0f, 0.0f));
copy_v4_v4(cols[v].fcol, float4(0.0f, 0.0f, 0.0f, 0.0f));
/* TODO */
cols[v].fcol[3] = (int(cols[v].fcol[3] * 10000.0f) * 10.0f) + 1.0f;
/* TODO */
cols[v].fcol[3] = (int(cols[v].fcol[3] * 10000.0f) * 10.0f) + 1.0f;
int v_mat = (v << GP_VERTEX_ID_SHIFT) | GP_IS_STROKE_VERTEX_BIT;
GPU_indexbuf_add_tri_verts(&ibo, v_mat + 0, v_mat + 1, v_mat + 2);
GPU_indexbuf_add_tri_verts(&ibo, v_mat + 2, v_mat + 1, v_mat + 3);
};
int v_mat = (v << GP_VERTEX_ID_SHIFT) | GP_IS_STROKE_VERTEX_BIT;
GPU_indexbuf_add_tri_verts(&ibo, v_mat + 0, v_mat + 1, v_mat + 2);
GPU_indexbuf_add_tri_verts(&ibo, v_mat + 2, v_mat + 1, v_mat + 3);
};
int t = 0;
for (const int curve_i : curves.curves_range()) {
IndexRange points = points_by_curve[curve_i];
const bool is_cyclic = cyclic[curve_i];
const int v_start = v;
int num_triangles = 0;
int t = 0;
for (const int curve_i : curves.curves_range()) {
IndexRange points = points_by_curve[curve_i];
const bool is_cyclic = cyclic[curve_i];
const int v_start = v;
int num_triangles = 0;
/* First point is not drawn. */
verts[v].mat = -1;
v++;
/* First point is not drawn. */
verts[v].mat = -1;
v++;
if (points.size() >= 3) {
num_triangles = points.size() - 2;
for (const int tri_i : IndexRange(num_triangles)) {
uint3 tri = drawing.runtime->triangles_cache[t + tri_i];
GPU_indexbuf_add_tri_verts(&ibo,
(v + tri.x) << GP_VERTEX_ID_SHIFT,
(v + tri.y) << GP_VERTEX_ID_SHIFT,
(v + tri.z) << GP_VERTEX_ID_SHIFT);
}
}
for (const int point_i : points) {
populate_point(curve_i, point_i, v_start, v);
v++;
}
if (is_cyclic) {
populate_point(curve_i, points.first(), v_start, v);
v++;
}
/* Last point is not drawn. */
verts[v].mat = -1;
v++;
t += num_triangles;
if (points.size() >= 3) {
num_triangles = points.size() - 2;
for (const int tri_i : IndexRange(num_triangles)) {
uint3 tri = drawing.runtime->triangles_cache[t + tri_i];
GPU_indexbuf_add_tri_verts(&ibo,
(v + tri.x) << GP_VERTEX_ID_SHIFT,
(v + tri.y) << GP_VERTEX_ID_SHIFT,
(v + tri.z) << GP_VERTEX_ID_SHIFT);
}
});
}
for (const int point_i : points) {
populate_point(curve_i, point_i, v_start, v);
v++;
}
if (is_cyclic) {
populate_point(curve_i, points.first(), v_start, v);
v++;
}
/* Last point is not drawn. */
verts[v].mat = -1;
v++;
t += num_triangles;
}
});
/* Mark last 2 verts as invalid. */
verts[total_points_num + 0].mat = -1;

View File

@ -167,9 +167,8 @@ typedef struct GreasePencil {
#ifdef __cplusplus
blender::Span<GreasePencilDrawingOrReference *> drawings() const;
void foreach_visible_drawing(
int frame,
blender::FunctionRef<void(GreasePencilDrawing &, blender::bke::gpencil::Layer &)> function);
void foreach_visible_drawing(int frame,
blender::FunctionRef<void(GreasePencilDrawing &)> function);
void read_drawing_array(BlendDataReader *reader);
void write_drawing_array(BlendWriter *writer);
void free_drawing_array();