Path: blob/master/scene/main/shader_globals_override.cpp
21371 views
/**************************************************************************/1/* shader_globals_override.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "shader_globals_override.h"3132#include "scene/main/node.h"33#include "servers/rendering/rendering_server.h"3435StringName *ShaderGlobalsOverride::_remap(const StringName &p_name) const {36StringName *r = param_remaps.getptr(p_name);37if (!r) {38//not cached, do caching39String p = p_name;40if (p.begins_with("params/")) {41String q = p.replace_first("params/", "");42param_remaps[p] = q;43r = param_remaps.getptr(p);44}45}4647return r;48}4950bool ShaderGlobalsOverride::_set(const StringName &p_name, const Variant &p_value) {51StringName *r = _remap(p_name);5253if (r) {54Override *o = overrides.getptr(*r);55if (!o) {56Override ov;57ov.in_use = false;58overrides[*r] = ov;59o = overrides.getptr(*r);60}61if (o) {62o->override = p_value;63if (active) {64if (o->override.get_type() == Variant::OBJECT) {65RID tex_rid = p_value;66RS::get_singleton()->global_shader_parameter_set_override(*r, tex_rid);67} else {68RS::get_singleton()->global_shader_parameter_set_override(*r, p_value);69}70}71o->in_use = p_value.get_type() != Variant::NIL;72return true;73}74}7576return false;77}7879bool ShaderGlobalsOverride::_get(const StringName &p_name, Variant &r_ret) const {80StringName *r = _remap(p_name);8182if (r) {83const Override *o = overrides.getptr(*r);84if (o) {85r_ret = o->override;86return true;87}88}8990return false;91}9293void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const {94Vector<StringName> variables;95variables = RS::get_singleton()->global_shader_parameter_get_list();96for (int i = 0; i < variables.size(); i++) {97PropertyInfo pinfo;98pinfo.name = "params/" + variables[i];99pinfo.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;100101switch (RS::get_singleton()->global_shader_parameter_get_type(variables[i])) {102case RS::GLOBAL_VAR_TYPE_BOOL: {103pinfo.type = Variant::BOOL;104} break;105case RS::GLOBAL_VAR_TYPE_BVEC2: {106pinfo.type = Variant::INT;107pinfo.hint = PROPERTY_HINT_FLAGS;108pinfo.hint_string = "x,y";109} break;110case RS::GLOBAL_VAR_TYPE_BVEC3: {111pinfo.type = Variant::INT;112pinfo.hint = PROPERTY_HINT_FLAGS;113pinfo.hint_string = "x,y,z";114} break;115case RS::GLOBAL_VAR_TYPE_BVEC4: {116pinfo.type = Variant::INT;117pinfo.hint = PROPERTY_HINT_FLAGS;118pinfo.hint_string = "x,y,z,w";119} break;120case RS::GLOBAL_VAR_TYPE_INT: {121pinfo.type = Variant::INT;122} break;123case RS::GLOBAL_VAR_TYPE_IVEC2: {124pinfo.type = Variant::VECTOR2I;125} break;126case RS::GLOBAL_VAR_TYPE_IVEC3: {127pinfo.type = Variant::VECTOR3I;128} break;129case RS::GLOBAL_VAR_TYPE_IVEC4: {130pinfo.type = Variant::VECTOR4I;131} break;132case RS::GLOBAL_VAR_TYPE_RECT2I: {133pinfo.type = Variant::RECT2I;134} break;135case RS::GLOBAL_VAR_TYPE_UINT: {136pinfo.type = Variant::INT;137} break;138case RS::GLOBAL_VAR_TYPE_UVEC2: {139pinfo.type = Variant::VECTOR2I;140} break;141case RS::GLOBAL_VAR_TYPE_UVEC3: {142pinfo.type = Variant::VECTOR3I;143} break;144case RS::GLOBAL_VAR_TYPE_UVEC4: {145pinfo.type = Variant::VECTOR4I;146} break;147case RS::GLOBAL_VAR_TYPE_FLOAT: {148pinfo.type = Variant::FLOAT;149} break;150case RS::GLOBAL_VAR_TYPE_VEC2: {151pinfo.type = Variant::VECTOR2;152} break;153case RS::GLOBAL_VAR_TYPE_VEC3: {154pinfo.type = Variant::VECTOR3;155} break;156case RS::GLOBAL_VAR_TYPE_VEC4: {157pinfo.type = Variant::VECTOR4;158} break;159case RS::GLOBAL_VAR_TYPE_RECT2: {160pinfo.type = Variant::RECT2;161} break;162case RS::GLOBAL_VAR_TYPE_COLOR: {163pinfo.type = Variant::COLOR;164} break;165case RS::GLOBAL_VAR_TYPE_MAT2: {166pinfo.type = Variant::PACKED_FLOAT32_ARRAY;167} break;168case RS::GLOBAL_VAR_TYPE_MAT3: {169pinfo.type = Variant::BASIS;170} break;171case RS::GLOBAL_VAR_TYPE_MAT4: {172pinfo.type = Variant::PROJECTION;173} break;174case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: {175pinfo.type = Variant::TRANSFORM2D;176} break;177case RS::GLOBAL_VAR_TYPE_TRANSFORM: {178pinfo.type = Variant::TRANSFORM3D;179} break;180case RS::GLOBAL_VAR_TYPE_SAMPLER2D: {181pinfo.type = Variant::OBJECT;182pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;183pinfo.hint_string = "Texture2D";184} break;185case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: {186pinfo.type = Variant::OBJECT;187pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;188pinfo.hint_string = "Texture2DArray";189} break;190case RS::GLOBAL_VAR_TYPE_SAMPLER3D: {191pinfo.type = Variant::OBJECT;192pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;193pinfo.hint_string = "Texture3D";194} break;195case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: {196pinfo.type = Variant::OBJECT;197pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;198pinfo.hint_string = "Cubemap";199} break;200case RS::GLOBAL_VAR_TYPE_SAMPLEREXT: {201pinfo.type = Variant::OBJECT;202pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;203pinfo.hint_string = "ExternalTexture";204} break;205default: {206} break;207}208209if (!overrides.has(variables[i])) {210Override o;211o.in_use = false;212Callable::CallError ce;213Variant::construct(pinfo.type, o.override, nullptr, 0, ce);214overrides[variables[i]] = o;215}216217Override *o = overrides.getptr(variables[i]);218if (o->in_use && o->override.get_type() != Variant::NIL) {219pinfo.usage |= PROPERTY_USAGE_CHECKED;220pinfo.usage |= PROPERTY_USAGE_STORAGE;221}222223p_list->push_back(pinfo);224}225}226227void ShaderGlobalsOverride::_activate() {228ERR_FAIL_NULL(get_tree());229Vector<Node *> nodes = get_tree()->get_nodes_in_group(SceneStringName(shader_overrides_group_active));230if (nodes.is_empty()) {231//good we are the only override, enable all232active = true;233add_to_group(SceneStringName(shader_overrides_group_active));234235for (const KeyValue<StringName, Override> &E : overrides) {236const Override *o = &E.value;237if (o->in_use && o->override.get_type() != Variant::NIL) {238if (o->override.get_type() == Variant::OBJECT) {239RID tex_rid = o->override;240RS::get_singleton()->global_shader_parameter_set_override(E.key, tex_rid);241} else {242RS::get_singleton()->global_shader_parameter_set_override(E.key, o->override);243}244}245246update_configuration_warnings(); //may have activated247}248}249}250251void ShaderGlobalsOverride::_notification(int p_what) {252switch (p_what) {253case Node::NOTIFICATION_ENTER_TREE: {254add_to_group(SceneStringName(shader_overrides_group));255_activate();256} break;257258case Node::NOTIFICATION_EXIT_TREE: {259if (active) {260//remove overrides261for (const KeyValue<StringName, Override> &E : overrides) {262const Override *o = &E.value;263if (o->in_use) {264RS::get_singleton()->global_shader_parameter_set_override(E.key, Variant());265}266}267}268269remove_from_group(SceneStringName(shader_overrides_group_active));270remove_from_group(SceneStringName(shader_overrides_group));271get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(shader_overrides_group), "_activate"); //another may want to activate when this is removed272active = false;273} break;274}275}276277PackedStringArray ShaderGlobalsOverride::get_configuration_warnings() const {278PackedStringArray warnings = Node::get_configuration_warnings();279280if (!active) {281warnings.push_back(RTR("ShaderGlobalsOverride is not active because another node of the same type is in the scene."));282}283284return warnings;285}286287void ShaderGlobalsOverride::_bind_methods() {288ClassDB::bind_method(D_METHOD("_activate"), &ShaderGlobalsOverride::_activate);289}290291292