diff options
Diffstat (limited to 'servers/rendering/renderer_canvas_cull.cpp')
-rw-r--r-- | servers/rendering/renderer_canvas_cull.cpp | 244 |
1 files changed, 74 insertions, 170 deletions
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index 706477cedb..097580f3bd 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -76,7 +76,7 @@ void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas } } -void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2D p_transform, RendererCanvasCull::Item *p_material_owner, RendererCanvasCull::Item **r_items, int &r_index, int p_z) { +void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2D p_transform, RendererCanvasCull::Item *p_material_owner, const Color &p_modulate, RendererCanvasCull::Item **r_items, int &r_index, int p_z) { int child_item_count = p_canvas_item->child_items.size(); RendererCanvasCull::Item **child_items = p_canvas_item->child_items.ptrw(); for (int i = 0; i < child_item_count; i++) { @@ -87,6 +87,7 @@ void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2 child_items[i]->ysort_xform = p_transform; child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.columns[2]); child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : nullptr; + child_items[i]->ysort_modulate = p_modulate; child_items[i]->ysort_index = r_index; child_items[i]->ysort_parent_abs_z_index = p_z; @@ -101,7 +102,7 @@ void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2 r_index++; if (child_items[i]->sort_y) { - _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index, abs_z); + _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], p_modulate * child_items[i]->modulate, r_items, r_index, abs_z); } } } @@ -301,7 +302,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2 if (allow_y_sort) { if (ci->ysort_children_count == -1) { ci->ysort_children_count = 0; - _collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count, p_z); + _collect_ysort_children(ci, Transform2D(), p_material_owner, Color(1, 1, 1, 1), nullptr, ci->ysort_children_count, p_z); } child_item_count = ci->ysort_children_count + 1; @@ -310,14 +311,14 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2 ci->ysort_parent_abs_z_index = parent_z; child_items[0] = ci; int i = 1; - _collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i, p_z); + _collect_ysort_children(ci, Transform2D(), p_material_owner, Color(1, 1, 1, 1), child_items, i, p_z); ci->ysort_xform = ci->xform.affine_inverse(); SortArray<Item *, ItemPtrSort> sorter; sorter.sort(child_items, child_item_count); for (i = 0; i < child_item_count; i++) { - _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, child_items[i]->ysort_parent_abs_z_index, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false, canvas_cull_mask); + _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate * child_items[i]->ysort_modulate, child_items[i]->ysort_parent_abs_z_index, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false, canvas_cull_mask); } } else { RendererCanvasRender::Item *canvas_group_from = nullptr; @@ -880,8 +881,9 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point PackedColorArray colors; PackedVector2Array points; - colors.resize(polyline_point_count); - points.resize(polyline_point_count); + // Additional 2+2 vertices to antialias begin+end of the middle triangle strip. + colors.resize(polyline_point_count + ((p_antialiased && !loop) ? 4 : 0)); + points.resize(polyline_point_count + ((p_antialiased && !loop) ? 4 : 0)); Vector2 *points_ptr = points.ptrw(); Color *colors_ptr = colors.ptrw(); @@ -897,96 +899,30 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point } Color color2 = Color(1, 1, 1, 0); - PackedColorArray colors_begin; - PackedVector2Array points_begin; - - colors_begin.resize(4); - points_begin.resize(4); - - PackedColorArray colors_begin_left_corner; - PackedVector2Array points_begin_left_corner; - - colors_begin_left_corner.resize(4); - points_begin_left_corner.resize(4); - - PackedColorArray colors_begin_right_corner; - PackedVector2Array points_begin_right_corner; - - colors_begin_right_corner.resize(4); - points_begin_right_corner.resize(4); - - PackedColorArray colors_end; - PackedVector2Array points_end; - - colors_end.resize(4); - points_end.resize(4); - - PackedColorArray colors_end_left_corner; - PackedVector2Array points_end_left_corner; - - colors_end_left_corner.resize(4); - points_end_left_corner.resize(4); - - PackedColorArray colors_end_right_corner; - PackedVector2Array points_end_right_corner; + Item::CommandPolygon *pline_left = canvas_item->alloc_command<Item::CommandPolygon>(); + ERR_FAIL_COND(!pline_left); - colors_end_right_corner.resize(4); - points_end_right_corner.resize(4); + Item::CommandPolygon *pline_right = canvas_item->alloc_command<Item::CommandPolygon>(); + ERR_FAIL_COND(!pline_right); PackedColorArray colors_left; PackedVector2Array points_left; - colors_left.resize(polyline_point_count); - points_left.resize(polyline_point_count); - PackedColorArray colors_right; PackedVector2Array points_right; - colors_right.resize(polyline_point_count); - points_right.resize(polyline_point_count); - - Item::CommandPolygon *pline_begin = canvas_item->alloc_command<Item::CommandPolygon>(); - ERR_FAIL_COND(!pline_begin); - - Item::CommandPolygon *pline_begin_left_corner = canvas_item->alloc_command<Item::CommandPolygon>(); - ERR_FAIL_COND(!pline_begin_left_corner); + // 2+2 additional vertices for begin+end corners. + // 1 additional vertex to swap the orientation of the triangles within the end corner's quad. + colors_left.resize(polyline_point_count + (loop ? 0 : 5)); + points_left.resize(polyline_point_count + (loop ? 0 : 5)); - Item::CommandPolygon *pline_begin_right_corner = canvas_item->alloc_command<Item::CommandPolygon>(); - ERR_FAIL_COND(!pline_begin_right_corner); + colors_right.resize(polyline_point_count + (loop ? 0 : 5)); + points_right.resize(polyline_point_count + (loop ? 0 : 5)); - Item::CommandPolygon *pline_end = canvas_item->alloc_command<Item::CommandPolygon>(); - ERR_FAIL_COND(!pline_end); - - Item::CommandPolygon *pline_end_left_corner = canvas_item->alloc_command<Item::CommandPolygon>(); - ERR_FAIL_COND(!pline_end_left_corner); - - Item::CommandPolygon *pline_end_right_corner = canvas_item->alloc_command<Item::CommandPolygon>(); - ERR_FAIL_COND(!pline_end_right_corner); - - Item::CommandPolygon *pline_left = canvas_item->alloc_command<Item::CommandPolygon>(); - ERR_FAIL_COND(!pline_left); - - Item::CommandPolygon *pline_right = canvas_item->alloc_command<Item::CommandPolygon>(); - ERR_FAIL_COND(!pline_right); - - // Makes nine triangle strips for drawing the antialiased line. - - Vector2 *points_begin_ptr = points_begin.ptrw(); - Vector2 *points_begin_left_corner_ptr = points_begin_left_corner.ptrw(); - Vector2 *points_begin_right_corner_ptr = points_begin_right_corner.ptrw(); - Vector2 *points_end_ptr = points_end.ptrw(); - Vector2 *points_end_left_corner_ptr = points_end_left_corner.ptrw(); - Vector2 *points_end_right_corner_ptr = points_end_right_corner.ptrw(); + Color *colors_left_ptr = colors_left.ptrw(); Vector2 *points_left_ptr = points_left.ptrw(); - Vector2 *points_right_ptr = points_right.ptrw(); - Color *colors_begin_ptr = colors_begin.ptrw(); - Color *colors_begin_left_corner_ptr = colors_begin_left_corner.ptrw(); - Color *colors_begin_right_corner_ptr = colors_begin_right_corner.ptrw(); - Color *colors_end_ptr = colors_end.ptrw(); - Color *colors_end_left_corner_ptr = colors_end_left_corner.ptrw(); - Color *colors_end_right_corner_ptr = colors_end_right_corner.ptrw(); - Color *colors_left_ptr = colors_left.ptrw(); + Vector2 *points_right_ptr = points_right.ptrw(); Color *colors_right_ptr = colors_right.ptrw(); Vector2 prev_segment_dir; @@ -1014,117 +950,85 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point Vector2 border = base_edge_offset * border_size; Vector2 pos = p_points[i]; - points_ptr[i * 2 + 0] = pos + edge_offset; - points_ptr[i * 2 + 1] = pos - edge_offset; + int j = i * 2 + (loop ? 0 : 2); - points_left_ptr[i * 2 + 0] = pos + edge_offset + border; - points_left_ptr[i * 2 + 1] = pos + edge_offset; + points_ptr[j + 0] = pos + edge_offset; + points_ptr[j + 1] = pos - edge_offset; - points_right_ptr[i * 2 + 0] = pos - edge_offset; - points_right_ptr[i * 2 + 1] = pos - edge_offset - border; + points_left_ptr[j + 0] = pos + edge_offset; + points_left_ptr[j + 1] = pos + edge_offset + border; + + points_right_ptr[j + 0] = pos - edge_offset; + points_right_ptr[j + 1] = pos - edge_offset - border; if (i < p_colors.size()) { color = p_colors[i]; color2 = Color(color.r, color.g, color.b, 0); } - colors_ptr[i * 2 + 0] = color; - colors_ptr[i * 2 + 1] = color; + colors_ptr[j + 0] = color; + colors_ptr[j + 1] = color; - colors_left_ptr[i * 2 + 0] = color2; - colors_left_ptr[i * 2 + 1] = color; + colors_left_ptr[j + 0] = color; + colors_left_ptr[j + 1] = color2; - colors_right_ptr[i * 2 + 0] = color; - colors_right_ptr[i * 2 + 1] = color2; + colors_right_ptr[j + 0] = color; + colors_right_ptr[j + 1] = color2; - if (is_first_point) { - Vector2 begin_border = loop ? Vector2() : -segment_dir * border_size; + if (is_first_point && !loop) { + Vector2 begin_border = -segment_dir * border_size; - points_begin_ptr[0] = pos + edge_offset + begin_border; - points_begin_ptr[1] = pos - edge_offset + begin_border; - points_begin_ptr[2] = pos + edge_offset; - points_begin_ptr[3] = pos - edge_offset; + points_ptr[0] = pos + edge_offset + begin_border; + points_ptr[1] = pos - edge_offset + begin_border; - colors_begin_ptr[0] = color2; - colors_begin_ptr[1] = color2; - colors_begin_ptr[2] = color; - colors_begin_ptr[3] = color; + colors_ptr[0] = color2; + colors_ptr[1] = color2; - points_begin_left_corner_ptr[0] = pos - edge_offset - border; - points_begin_left_corner_ptr[1] = pos - edge_offset + begin_border - border; - points_begin_left_corner_ptr[2] = pos - edge_offset; - points_begin_left_corner_ptr[3] = pos - edge_offset + begin_border; + points_left_ptr[0] = pos + edge_offset + begin_border; + points_left_ptr[1] = pos + edge_offset + begin_border + border; - colors_begin_left_corner_ptr[0] = color2; - colors_begin_left_corner_ptr[1] = color2; - colors_begin_left_corner_ptr[2] = color; - colors_begin_left_corner_ptr[3] = color2; + colors_left_ptr[0] = color2; + colors_left_ptr[1] = color2; - points_begin_right_corner_ptr[0] = pos + edge_offset + begin_border; - points_begin_right_corner_ptr[1] = pos + edge_offset + begin_border + border; - points_begin_right_corner_ptr[2] = pos + edge_offset; - points_begin_right_corner_ptr[3] = pos + edge_offset + border; + points_right_ptr[0] = pos - edge_offset + begin_border; + points_right_ptr[1] = pos - edge_offset + begin_border - border; - colors_begin_right_corner_ptr[0] = color2; - colors_begin_right_corner_ptr[1] = color2; - colors_begin_right_corner_ptr[2] = color; - colors_begin_right_corner_ptr[3] = color2; + colors_right_ptr[0] = color2; + colors_right_ptr[1] = color2; } - if (is_last_point) { - Vector2 end_border = loop ? Vector2() : prev_segment_dir * border_size; - - points_end_ptr[0] = pos + edge_offset + end_border; - points_end_ptr[1] = pos - edge_offset + end_border; - points_end_ptr[2] = pos + edge_offset; - points_end_ptr[3] = pos - edge_offset; - - colors_end_ptr[0] = color2; - colors_end_ptr[1] = color2; - colors_end_ptr[2] = color; - colors_end_ptr[3] = color; - - points_end_left_corner_ptr[0] = pos - edge_offset - border; - points_end_left_corner_ptr[1] = pos - edge_offset + end_border - border; - points_end_left_corner_ptr[2] = pos - edge_offset; - points_end_left_corner_ptr[3] = pos - edge_offset + end_border; - - colors_end_left_corner_ptr[0] = color2; - colors_end_left_corner_ptr[1] = color2; - colors_end_left_corner_ptr[2] = color; - colors_end_left_corner_ptr[3] = color2; - - points_end_right_corner_ptr[0] = pos + edge_offset + end_border; - points_end_right_corner_ptr[1] = pos + edge_offset + end_border + border; - points_end_right_corner_ptr[2] = pos + edge_offset; - points_end_right_corner_ptr[3] = pos + edge_offset + border; - - colors_end_right_corner_ptr[0] = color2; - colors_end_right_corner_ptr[1] = color2; - colors_end_right_corner_ptr[2] = color; - colors_end_right_corner_ptr[3] = color2; - } + if (is_last_point && !loop) { + Vector2 end_border = prev_segment_dir * border_size; + int end_index = polyline_point_count + 2; - prev_segment_dir = segment_dir; - } + points_ptr[end_index + 0] = pos + edge_offset + end_border; + points_ptr[end_index + 1] = pos - edge_offset + end_border; - pline_begin->primitive = RS::PRIMITIVE_TRIANGLE_STRIP; - pline_begin->polygon.create(indices, points_begin, colors_begin); + colors_ptr[end_index + 0] = color2; + colors_ptr[end_index + 1] = color2; - pline_begin_left_corner->primitive = RS::PRIMITIVE_TRIANGLE_STRIP; - pline_begin_left_corner->polygon.create(indices, points_begin_left_corner, colors_begin_left_corner); + // Swap orientation of the triangles within both end corner quads so the visual seams + // between triangles goes from the edge corner. Done by going back to the edge corner + // (1 additional vertex / zero-area triangle per left/right corner). + points_left_ptr[end_index + 0] = pos + edge_offset; + points_left_ptr[end_index + 1] = pos + edge_offset + end_border + border; + points_left_ptr[end_index + 2] = pos + edge_offset + end_border; - pline_begin_right_corner->primitive = RS::PRIMITIVE_TRIANGLE_STRIP; - pline_begin_right_corner->polygon.create(indices, points_begin_right_corner, colors_begin_right_corner); + colors_left_ptr[end_index + 0] = color; + colors_left_ptr[end_index + 1] = color2; + colors_left_ptr[end_index + 2] = color2; - pline_end->primitive = RS::PRIMITIVE_TRIANGLE_STRIP; - pline_end->polygon.create(indices, points_end, colors_end); + points_right_ptr[end_index + 0] = pos - edge_offset; + points_right_ptr[end_index + 1] = pos - edge_offset + end_border - border; + points_right_ptr[end_index + 2] = pos - edge_offset + end_border; - pline_end_left_corner->primitive = RS::PRIMITIVE_TRIANGLE_STRIP; - pline_end_left_corner->polygon.create(indices, points_end_left_corner, colors_end_left_corner); + colors_right_ptr[end_index + 0] = color; + colors_right_ptr[end_index + 1] = color2; + colors_right_ptr[end_index + 2] = color2; + } - pline_end_right_corner->primitive = RS::PRIMITIVE_TRIANGLE_STRIP; - pline_end_right_corner->polygon.create(indices, points_end_right_corner, colors_end_right_corner); + prev_segment_dir = segment_dir; + } pline_left->primitive = RS::PRIMITIVE_TRIANGLE_STRIP; pline_left->polygon.create(indices, points_left, colors_left); |