Path: blob/master/scene/main/shader_globals_override.cpp
9902 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"3334StringName *ShaderGlobalsOverride::_remap(const StringName &p_name) const {35StringName *r = param_remaps.getptr(p_name);36if (!r) {37//not cached, do caching38String p = p_name;39if (p.begins_with("params/")) {40String q = p.replace_first("params/", "");41param_remaps[p] = q;42r = param_remaps.getptr(p);43}44}4546return r;47}4849bool ShaderGlobalsOverride::_set(const StringName &p_name, const Variant &p_value) {50StringName *r = _remap(p_name);5152if (r) {53Override *o = overrides.getptr(*r);54if (!o) {55Override ov;56ov.in_use = false;57overrides[*r] = ov;58o = overrides.getptr(*r);59}60if (o) {61o->override = p_value;62if (active) {63if (o->override.get_type() == Variant::OBJECT) {64RID tex_rid = p_value;65RS::get_singleton()->global_shader_parameter_set_override(*r, tex_rid);66} else {67RS::get_singleton()->global_shader_parameter_set_override(*r, p_value);68}69}70o->in_use = p_value.get_type() != Variant::NIL;71return true;72}73}7475return false;76}7778bool ShaderGlobalsOverride::_get(const StringName &p_name, Variant &r_ret) const {79StringName *r = _remap(p_name);8081if (r) {82const Override *o = overrides.getptr(*r);83if (o) {84r_ret = o->override;85return true;86}87}8889return false;90}9192void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const {93Vector<StringName> variables;94variables = RS::get_singleton()->global_shader_parameter_get_list();95for (int i = 0; i < variables.size(); i++) {96PropertyInfo pinfo;97pinfo.name = "params/" + variables[i];98pinfo.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;99100switch (RS::get_singleton()->global_shader_parameter_get_type(variables[i])) {101case RS::GLOBAL_VAR_TYPE_BOOL: {102pinfo.type = Variant::BOOL;103} break;104case RS::GLOBAL_VAR_TYPE_BVEC2: {105pinfo.type = Variant::INT;106pinfo.hint = PROPERTY_HINT_FLAGS;107pinfo.hint_string = "x,y";108} break;109case RS::GLOBAL_VAR_TYPE_BVEC3: {110pinfo.type = Variant::INT;111pinfo.hint = PROPERTY_HINT_FLAGS;112pinfo.hint_string = "x,y,z";113} break;114case RS::GLOBAL_VAR_TYPE_BVEC4: {115pinfo.type = Variant::INT;116pinfo.hint = PROPERTY_HINT_FLAGS;117pinfo.hint_string = "x,y,z,w";118} break;119case RS::GLOBAL_VAR_TYPE_INT: {120pinfo.type = Variant::INT;121} break;122case RS::GLOBAL_VAR_TYPE_IVEC2: {123pinfo.type = Variant::VECTOR2I;124} break;125case RS::GLOBAL_VAR_TYPE_IVEC3: {126pinfo.type = Variant::VECTOR3I;127} break;128case RS::GLOBAL_VAR_TYPE_IVEC4: {129pinfo.type = Variant::VECTOR4I;130} break;131case RS::GLOBAL_VAR_TYPE_RECT2I: {132pinfo.type = Variant::RECT2I;133} break;134case RS::GLOBAL_VAR_TYPE_UINT: {135pinfo.type = Variant::INT;136} break;137case RS::GLOBAL_VAR_TYPE_UVEC2: {138pinfo.type = Variant::VECTOR2I;139} break;140case RS::GLOBAL_VAR_TYPE_UVEC3: {141pinfo.type = Variant::VECTOR3I;142} break;143case RS::GLOBAL_VAR_TYPE_UVEC4: {144pinfo.type = Variant::VECTOR4I;145} break;146case RS::GLOBAL_VAR_TYPE_FLOAT: {147pinfo.type = Variant::FLOAT;148} break;149case RS::GLOBAL_VAR_TYPE_VEC2: {150pinfo.type = Variant::VECTOR2;151} break;152case RS::GLOBAL_VAR_TYPE_VEC3: {153pinfo.type = Variant::VECTOR3;154} break;155case RS::GLOBAL_VAR_TYPE_VEC4: {156pinfo.type = Variant::VECTOR4;157} break;158case RS::GLOBAL_VAR_TYPE_RECT2: {159pinfo.type = Variant::RECT2;160} break;161case RS::GLOBAL_VAR_TYPE_COLOR: {162pinfo.type = Variant::COLOR;163} break;164case RS::GLOBAL_VAR_TYPE_MAT2: {165pinfo.type = Variant::PACKED_FLOAT32_ARRAY;166} break;167case RS::GLOBAL_VAR_TYPE_MAT3: {168pinfo.type = Variant::BASIS;169} break;170case RS::GLOBAL_VAR_TYPE_MAT4: {171pinfo.type = Variant::PROJECTION;172} break;173case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: {174pinfo.type = Variant::TRANSFORM2D;175} break;176case RS::GLOBAL_VAR_TYPE_TRANSFORM: {177pinfo.type = Variant::TRANSFORM3D;178} break;179case RS::GLOBAL_VAR_TYPE_SAMPLER2D: {180pinfo.type = Variant::OBJECT;181pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;182pinfo.hint_string = "Texture2D";183} break;184case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: {185pinfo.type = Variant::OBJECT;186pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;187pinfo.hint_string = "Texture2DArray";188} break;189case RS::GLOBAL_VAR_TYPE_SAMPLER3D: {190pinfo.type = Variant::OBJECT;191pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;192pinfo.hint_string = "Texture3D";193} break;194case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: {195pinfo.type = Variant::OBJECT;196pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;197pinfo.hint_string = "Cubemap";198} break;199case RS::GLOBAL_VAR_TYPE_SAMPLEREXT: {200pinfo.type = Variant::OBJECT;201pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;202pinfo.hint_string = "ExternalTexture";203} break;204default: {205} break;206}207208if (!overrides.has(variables[i])) {209Override o;210o.in_use = false;211Callable::CallError ce;212Variant::construct(pinfo.type, o.override, nullptr, 0, ce);213overrides[variables[i]] = o;214}215216Override *o = overrides.getptr(variables[i]);217if (o->in_use && o->override.get_type() != Variant::NIL) {218pinfo.usage |= PROPERTY_USAGE_CHECKED;219pinfo.usage |= PROPERTY_USAGE_STORAGE;220}221222p_list->push_back(pinfo);223}224}225226void ShaderGlobalsOverride::_activate() {227ERR_FAIL_NULL(get_tree());228List<Node *> nodes;229get_tree()->get_nodes_in_group(SceneStringName(shader_overrides_group_active), &nodes);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