mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
Implement 2D instance shader parameters
Co-authored-by: kobewi <kobewi4e@gmail.com> Co-authored-by: yesfish <huwpascoe@users.noreply.github.com> Co-authored-by: Álex Román Núñez <eirexe123@gmail.com>
This commit is contained in:
parent
b9437c3938
commit
ceefc0d38a
24 changed files with 626 additions and 168 deletions
|
@ -44,6 +44,29 @@
|
|||
// while not making lines appear too soft.
|
||||
const static float FEATHER_SIZE = 1.25f;
|
||||
|
||||
static RendererCanvasCull *_canvas_cull_singleton = nullptr;
|
||||
|
||||
void RendererCanvasCull::_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker) {
|
||||
Item *item = (Item *)p_tracker->userdata;
|
||||
|
||||
switch (p_notification) {
|
||||
case Dependency::DEPENDENCY_CHANGED_MATERIAL: {
|
||||
_canvas_cull_singleton->_item_queue_update(item, true);
|
||||
} break;
|
||||
default: {
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void RendererCanvasCull::_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) {
|
||||
Item *item = (Item *)p_tracker->userdata;
|
||||
|
||||
if (p_dependency == item->material) {
|
||||
_canvas_cull_singleton->canvas_item_set_material(item->self, RID());
|
||||
}
|
||||
_canvas_cull_singleton->_item_queue_update(item, true);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t p_canvas_cull_mask, RenderingMethod::RenderInfo *r_render_info) {
|
||||
RENDER_TIMESTAMP("Cull CanvasItem Tree");
|
||||
|
||||
|
@ -525,6 +548,8 @@ RID RendererCanvasCull::canvas_item_allocate() {
|
|||
}
|
||||
void RendererCanvasCull::canvas_item_initialize(RID p_rid) {
|
||||
canvas_item_owner.initialize_rid(p_rid);
|
||||
Item *instance = canvas_item_owner.get_or_null(p_rid);
|
||||
instance->self = p_rid;
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_parent(RID p_item, RID p_parent) {
|
||||
|
@ -1844,6 +1869,7 @@ void RendererCanvasCull::canvas_item_clear(RID p_item) {
|
|||
ERR_FAIL_NULL(canvas_item);
|
||||
|
||||
canvas_item->clear();
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (debug_redraw) {
|
||||
canvas_item->debug_redraw_time = debug_redraw_time;
|
||||
|
@ -1875,6 +1901,7 @@ void RendererCanvasCull::canvas_item_set_material(RID p_item, RID p_material) {
|
|||
ERR_FAIL_NULL(canvas_item);
|
||||
|
||||
canvas_item->material = p_material;
|
||||
_item_queue_update(canvas_item, true);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_use_parent_material(RID p_item, bool p_enable) {
|
||||
|
@ -1882,6 +1909,37 @@ void RendererCanvasCull::canvas_item_set_use_parent_material(RID p_item, bool p_
|
|||
ERR_FAIL_NULL(canvas_item);
|
||||
|
||||
canvas_item->use_parent_material = p_enable;
|
||||
_item_queue_update(canvas_item, true);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_instance_shader_parameter(RID p_item, const StringName &p_parameter, const Variant &p_value) {
|
||||
Item *item = canvas_item_owner.get_or_null(p_item);
|
||||
ERR_FAIL_NULL(item);
|
||||
|
||||
item->instance_uniforms.set(item->self, p_parameter, p_value);
|
||||
}
|
||||
|
||||
Variant RendererCanvasCull::canvas_item_get_instance_shader_parameter(RID p_item, const StringName &p_parameter) const {
|
||||
const Item *item = const_cast<RendererCanvasCull *>(this)->canvas_item_owner.get_or_null(p_item);
|
||||
ERR_FAIL_NULL_V(item, Variant());
|
||||
|
||||
return item->instance_uniforms.get(p_parameter);
|
||||
}
|
||||
|
||||
Variant RendererCanvasCull::canvas_item_get_instance_shader_parameter_default_value(RID p_item, const StringName &p_parameter) const {
|
||||
const Item *item = const_cast<RendererCanvasCull *>(this)->canvas_item_owner.get_or_null(p_item);
|
||||
ERR_FAIL_NULL_V(item, Variant());
|
||||
|
||||
return item->instance_uniforms.get_default(p_parameter);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_get_instance_shader_parameter_list(RID p_item, List<PropertyInfo> *p_parameters) const {
|
||||
ERR_FAIL_NULL(p_parameters);
|
||||
const Item *item = const_cast<RendererCanvasCull *>(this)->canvas_item_owner.get_or_null(p_item);
|
||||
ERR_FAIL_NULL(item);
|
||||
const_cast<RendererCanvasCull *>(this)->update_dirty_items();
|
||||
|
||||
item->instance_uniforms.get_property_list(*p_parameters);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_visibility_notifier(RID p_item, bool p_enable, const Rect2 &p_area, const Callable &p_enter_callable, const Callable &p_exit_callable) {
|
||||
|
@ -2411,6 +2469,63 @@ Rect2 RendererCanvasCull::_debug_canvas_item_get_rect(RID p_item) {
|
|||
return canvas_item->get_rect();
|
||||
}
|
||||
|
||||
void RendererCanvasCull::_item_queue_update(Item *p_item, bool p_update_dependencies) {
|
||||
if (p_update_dependencies) {
|
||||
p_item->update_dependencies = true;
|
||||
}
|
||||
|
||||
if (!p_item->update_item.in_list()) {
|
||||
_item_update_list.add(&p_item->update_item);
|
||||
}
|
||||
}
|
||||
|
||||
void RendererCanvasCull::update_dirty_items() {
|
||||
while (_item_update_list.first()) {
|
||||
_update_dirty_item(_item_update_list.first()->self());
|
||||
}
|
||||
|
||||
// Instance updates may affect resources.
|
||||
RSG::utilities->update_dirty_resources();
|
||||
}
|
||||
|
||||
void RendererCanvasCull::_update_dirty_item(Item *p_item) {
|
||||
if (p_item->update_dependencies) {
|
||||
RID material = p_item->material;
|
||||
|
||||
if (p_item->use_parent_material) {
|
||||
Item *parent = canvas_item_owner.get_or_null(p_item->parent);
|
||||
while (parent != nullptr) {
|
||||
material = parent->material;
|
||||
if (!parent->use_parent_material) {
|
||||
break;
|
||||
}
|
||||
parent = canvas_item_owner.get_or_null(parent->parent);
|
||||
}
|
||||
}
|
||||
|
||||
p_item->dependency_tracker.update_begin();
|
||||
|
||||
p_item->instance_uniforms.materials_start();
|
||||
|
||||
if (material.is_valid()) {
|
||||
p_item->instance_uniforms.materials_append(material);
|
||||
RSG::material_storage->material_update_dependency(material, &p_item->dependency_tracker);
|
||||
}
|
||||
|
||||
if (p_item->instance_uniforms.materials_finish(p_item->self)) {
|
||||
p_item->instance_allocated_shader_uniforms_offset = p_item->instance_uniforms.location();
|
||||
}
|
||||
|
||||
p_item->dependency_tracker.update_end();
|
||||
}
|
||||
_item_update_list.remove(&p_item->update_item);
|
||||
p_item->update_dependencies = false;
|
||||
}
|
||||
|
||||
void RendererCanvasCull::update() {
|
||||
update_dirty_items();
|
||||
}
|
||||
|
||||
bool RendererCanvasCull::free(RID p_rid) {
|
||||
if (canvas_owner.owns(p_rid)) {
|
||||
Canvas *canvas = canvas_owner.get_or_null(p_rid);
|
||||
|
@ -2468,11 +2583,9 @@ bool RendererCanvasCull::free(RID p_rid) {
|
|||
visibility_notifier_allocator.free(canvas_item->visibility_notifier);
|
||||
}
|
||||
|
||||
/*
|
||||
if (canvas_item->material) {
|
||||
canvas_item->material->owners.erase(canvas_item);
|
||||
}
|
||||
*/
|
||||
canvas_item_set_material(canvas_item->self, RID());
|
||||
canvas_item->instance_uniforms.free(canvas_item->self);
|
||||
update_dirty_items();
|
||||
|
||||
if (canvas_item->canvas_group != nullptr) {
|
||||
memdelete(canvas_item->canvas_group);
|
||||
|
@ -2634,6 +2747,8 @@ void RendererCanvasCull::InterpolationData::notify_free_canvas_light_occluder(RI
|
|||
}
|
||||
|
||||
RendererCanvasCull::RendererCanvasCull() {
|
||||
_canvas_cull_singleton = this;
|
||||
|
||||
z_list = (RendererCanvasRender::Item **)memalloc(z_range * sizeof(RendererCanvasRender::Item *));
|
||||
z_last_list = (RendererCanvasRender::Item **)memalloc(z_range * sizeof(RendererCanvasRender::Item *));
|
||||
|
||||
|
@ -2646,4 +2761,5 @@ RendererCanvasCull::RendererCanvasCull() {
|
|||
RendererCanvasCull::~RendererCanvasCull() {
|
||||
memfree(z_list);
|
||||
memfree(z_last_list);
|
||||
_canvas_cull_singleton = nullptr;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue