Initial Grease Pencil 3.0 stage #106848
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
Sergey Sharybin
commented
Typically dead code is discouraged. Typically dead code is discouraged.
Not sure what is it part of, so can't really give strong suggestions.
|
||||
// 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) {
|
||||
Sergey Sharybin
commented
Add a comment what is this about, or remove. Add a comment what is this about, or remove.
|
||||
|
|
|
@ -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]);
|
||||
Hans Goudey
commented
Use the Use the `*` overload rather than adding `.varray` at the end
|
||||
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;
|
||||
Hans Goudey
commented
These These `.as_span()` calls shouldn't be necessary
|
||||
|
||||
/* 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;
|
||||
|
||||
Sergey Sharybin
commented
Add details about TODO. Something that helps others to pick up a task, or to understand that specific case is not expected to be yet working. Add details about TODO. Something that helps others to pick up a task, or to understand that specific case is not expected to be yet working.
|
||||
/* 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;
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue
Forget if we talked about this already, but without
std::move
in the function, there doesn't seem to be much of a point to this second override. Usually there is one for a const reference and one for an rvalue, I haven't seen a non-const reference override like this before.Maybe @JacquesLucke can clarify here, but I believe sine
add_overwrite
has an implementation with an r-value reference that does thestd::move
I think this is fine?I recommend just using a debugger to see if this calls the function you intend to call (the one with an rvalue reference). Haven't tried right now, but it will probably call the const reference version without
std::move
.