diff options
Diffstat (limited to 'scene/resources')
-rw-r--r-- | scene/resources/animation.cpp | 2 | ||||
-rw-r--r-- | scene/resources/bit_mask.cpp | 16 | ||||
-rw-r--r-- | scene/resources/dynamic_font.cpp | 4 | ||||
-rw-r--r-- | scene/resources/dynamic_font_stb.cpp | 5 | ||||
-rw-r--r-- | scene/resources/mesh.cpp | 2 | ||||
-rw-r--r-- | scene/resources/packed_scene.cpp | 13 | ||||
-rw-r--r-- | scene/resources/shader_graph.cpp | 2596 | ||||
-rw-r--r-- | scene/resources/shader_graph.h | 446 | ||||
-rw-r--r-- | scene/resources/surface_tool.cpp | 10 | ||||
-rw-r--r-- | scene/resources/texture.cpp | 177 | ||||
-rw-r--r-- | scene/resources/texture.h | 19 | ||||
-rw-r--r-- | scene/resources/visual_shader.cpp | 2 |
12 files changed, 169 insertions, 3123 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 7041b62487..58e6db3f5e 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -2906,8 +2906,6 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons //able to optimize more erase = false; } else { - - //print_line(itos(i)+"because of interp"); } } } diff --git a/scene/resources/bit_mask.cpp b/scene/resources/bit_mask.cpp index 39206ed043..5694099754 100644 --- a/scene/resources/bit_mask.cpp +++ b/scene/resources/bit_mask.cpp @@ -492,18 +492,14 @@ static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_ } } while (reenter || popped); -#ifdef DEBUG_ENABLED - print_line("max stack size: " + itos(stack.size())); -#endif + print_verbose("BitMap: Max stack size: " + itos(stack.size())); } Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon) const { Rect2i r = Rect2i(0, 0, width, height).clip(p_rect); + print_verbose("BitMap: Rect: " + r); -#ifdef DEBUG_ENABLED - print_line("Rect: " + r); -#endif Point2i from; Ref<BitMap> fill; fill.instance(); @@ -515,13 +511,9 @@ Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, fl if (!fill->get_bit(Point2(j, i)) && get_bit(Point2(j, i))) { Vector<Vector2> polygon = _march_square(r, Point2i(j, i)); -#ifdef DEBUG_ENABLED - print_line("pre reduce: " + itos(polygon.size())); -#endif + print_verbose("BitMap: Pre reduce: " + itos(polygon.size())); polygon = reduce(polygon, r, p_epsilon); -#ifdef DEBUG_ENABLED - print_line("post reduce: " + itos(polygon.size())); -#endif + print_verbose("BitMap: Post reduce: " + itos(polygon.size())); polygons.push_back(polygon); fill_bits(this, fill, Point2i(j, i), r); } diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 2f2abd4e08..4df849df6a 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -435,8 +435,6 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp break; } - //print_line("CHAR: "+String::chr(p_char)+" TEX INDEX: "+itos(tex_index)+" X: "+itos(tex_x)+" Y: "+itos(tex_y)); - if (ret.index == -1) { //could not find texture to fit, create one ret.x = 0; @@ -1036,6 +1034,8 @@ SelfList<DynamicFont>::List DynamicFont::dynamic_fonts; DynamicFont::DynamicFont() : font_list(this) { + cache_id.size = 16; + outline_cache_id.size = 16; spacing_top = 0; spacing_bottom = 0; spacing_char = 0; diff --git a/scene/resources/dynamic_font_stb.cpp b/scene/resources/dynamic_font_stb.cpp index 29f1106d16..be394e19c4 100644 --- a/scene/resources/dynamic_font_stb.cpp +++ b/scene/resources/dynamic_font_stb.cpp @@ -214,7 +214,6 @@ void DynamicFontAtSize::_update_char(CharType p_char) { int advance; stbtt_GetCodepointHMetrics(&font->info, p_char, &advance, 0); - //print_line("char has no bitmap: "+itos(p_char)+" but advance is "+itos(advance*scale)); Character ch; ch.texture_idx = -1; ch.advance = advance * scale; @@ -279,8 +278,6 @@ void DynamicFontAtSize::_update_char(CharType p_char) { break; } - //print_line("CHAR: "+String::chr(p_char)+" TEX INDEX: "+itos(tex_index)+" X: "+itos(tex_x)+" Y: "+itos(tex_y)); - if (tex_index == -1) { //could not find texture to fit, create one tex_x = 0; @@ -364,8 +361,6 @@ void DynamicFontAtSize::_update_char(CharType p_char) { chr.rect = Rect2(tex_x + rect_margin, tex_y + rect_margin, w, h); - //print_line("CHAR: "+String::chr(p_char)+" TEX INDEX: "+itos(tex_index)+" RECT: "+chr.rect+" X OFS: "+itos(xofs)+" Y OFS: "+itos(yofs)); - char_map[p_char] = chr; stbtt_FreeBitmap(cpbitmap, NULL); diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index dcd87a2a61..042cf28fec 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -1241,7 +1241,7 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe surfaces_tools.push_back(st); //stay there } - print_line("gen indices: " + itos(gen_index_count)); + print_verbose("Mesh: Gen indices: " + itos(gen_index_count)); //go through all indices for (int i = 0; i < gen_index_count; i += 3) { diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 07783d5f4a..f034e07ff9 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -106,7 +106,6 @@ Node *SceneState::instance(GenEditState p_edit_state) const { if (i == 0 && base_scene_idx >= 0) { //scene inheritance on root node - //print_line("scene inherit"); Ref<PackedScene> sdata = props[base_scene_idx]; ERR_FAIL_COND_V(!sdata.is_valid(), NULL); node = sdata->instance(p_edit_state == GEN_EDIT_STATE_DISABLED ? PackedScene::GEN_EDIT_STATE_DISABLED : PackedScene::GEN_EDIT_STATE_INSTANCE); //only main gets main edit state @@ -117,7 +116,6 @@ Node *SceneState::instance(GenEditState p_edit_state) const { } else if (n.instance >= 0) { //instance a scene into this node - //print_line("instance"); if (n.instance & FLAG_INSTANCE_IS_PLACEHOLDER) { String path = props[n.instance & FLAG_MASK]; @@ -141,7 +139,6 @@ Node *SceneState::instance(GenEditState p_edit_state) const { } } else if (n.type == TYPE_INSTANCED) { - //print_line("instanced"); //get the node from somewhere, it likely already exists from another instance if (parent) { node = parent->_get_child_by_name(snames[n.name]); @@ -152,7 +149,6 @@ Node *SceneState::instance(GenEditState p_edit_state) const { #endif } } else if (ClassDB::is_class_enabled(snames[n.type])) { - //print_line("created"); //node belongs to this scene and must be created Object *obj = ClassDB::instance(snames[n.type]); if (!Object::cast_to<Node>(obj)) { @@ -491,15 +487,6 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map if (E->get().usage & PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE) { isdefault = true; //is script default value } - /* - if (nd.instance<0 && ((E->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO) && value.is_zero()) || ((E->get().usage & PROPERTY_USAGE_STORE_IF_NONONE) && value.is_one())) { - continue; - } - */ - - //print_line("PASSED!"); - //print_line("at: "+String(p_node->get_name())+"::"+name+": - nz: "+itos(E->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO)+" no: "+itos(E->get().usage&PROPERTY_USAGE_STORE_IF_NONONE)); - //print_line("value: "+String(value)+" is zero: "+itos(value.is_zero())+" is one" +itos(value.is_one())); if (pack_state_stack.size()) { // we are on part of an instanced subscene diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp deleted file mode 100644 index 070cc84863..0000000000 --- a/scene/resources/shader_graph.cpp +++ /dev/null @@ -1,2596 +0,0 @@ -/*************************************************************************/ -/* shader_graph.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "shader_graph.h" - -#include "scene/scene_string_names.h" - -// FIXME: Needs to be ported to the new 3.0 shader API -#if 0 -Array ShaderGraph::_get_node_list(ShaderType p_type) const { - - List<int> nodes; - get_node_list(p_type,&nodes); - Array arr(true); - for (List<int>::Element *E=nodes.front();E;E=E->next()) - arr.push_back(E->get()); - return arr; -} -Array ShaderGraph::_get_connections(ShaderType p_type) const { - - List<Connection> connections; - get_node_connections(p_type,&connections); - Array arr(true); - for (List<Connection>::Element *E=connections.front();E;E=E->next()) { - - Dictionary d(true); - d["src_id"]=E->get().src_id; - d["src_slot"]=E->get().src_slot; - d["dst_id"]=E->get().dst_id; - d["dst_slot"]=E->get().dst_slot; - arr.push_back(d); - - } - return arr; -} - -void ShaderGraph::_set_data(const Dictionary &p_data) { - - Dictionary d=p_data; - ERR_FAIL_COND(!d.has("shaders")); - Array sh=d["shaders"]; - ERR_FAIL_COND(sh.size()!=3); - - for(int t=0;t<3;t++) { - Array data=sh[t]; - ERR_FAIL_COND((data.size()%6)!=0); - shader[t].node_map.clear(); - for(int i=0;i<data.size();i+=6) { - - Node n; - n.id=data[i+0]; - n.type=NodeType(int(data[i+1])); - n.pos=data[i+2]; - n.param1=data[i+3]; - n.param2=data[i+4]; - - Array conns=data[i+5]; - ERR_FAIL_COND((conns.size()%3)!=0); - - for(int j=0;j<conns.size();j+=3) { - SourceSlot ss; - int ls=conns[j+0]; - if (ls == SLOT_DEFAULT_VALUE) { - n.defaults[conns[j+1]]=conns[j+2]; - } else { - ss.id=conns[j+1]; - ss.slot=conns[j+2]; - n.connections[ls]=ss; - } - } - shader[t].node_map[n.id]=n; - - } - } - - _pending_update_shader=true; - _update_shader(); - -} - -Dictionary ShaderGraph::_get_data() const { - - Array sh; - for(int i=0;i<3;i++) { - Array data; - int ec = shader[i].node_map.size(); - data.resize(ec*6); - int idx=0; - for (Map<int,Node>::Element*E=shader[i].node_map.front();E;E=E->next()) { - - data[idx+0]=E->key(); - data[idx+1]=E->get().type; - data[idx+2]=E->get().pos; - data[idx+3]=E->get().param1; - data[idx+4]=E->get().param2; - - Array conns; - conns.resize(E->get().connections.size()*3+E->get().defaults.size()*3); - int idx2=0; - for(Map<int,SourceSlot>::Element*F=E->get().connections.front();F;F=F->next()) { - - conns[idx2+0]=F->key(); - conns[idx2+1]=F->get().id; - conns[idx2+2]=F->get().slot; - idx2+=3; - } - for(Map<int,Variant>::Element*F=E->get().defaults.front();F;F=F->next()) { - - conns[idx2+0]=SLOT_DEFAULT_VALUE; - conns[idx2+1]=F->key(); - conns[idx2+2]=F->get(); - idx2+=3; - } - - data[idx+5]=conns; - idx+=6; - } - sh.push_back(data); - } - - Dictionary data; - data["shaders"]=sh; - return data; -} - - - -ShaderGraph::GraphError ShaderGraph::get_graph_error(ShaderType p_type) const { - - ERR_FAIL_INDEX_V(p_type,3,GRAPH_OK); - return shader[p_type].error; -} - -int ShaderGraph::node_count(ShaderType p_which, int p_type) -{ - int count=0; - for (Map<int,Node>::Element *E=shader[p_which].node_map.front();E;E=E->next()) - if (E->get().type==p_type) - count++; - return count; -} - -void ShaderGraph::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_update_shader"),&ShaderGraph::_update_shader); - - ClassDB::bind_method(D_METHOD("node_add","shader_type","node_type","id"),&ShaderGraph::node_add); - ClassDB::bind_method(D_METHOD("node_remove","shader_type","id"),&ShaderGraph::node_remove); - ClassDB::bind_method(D_METHOD("node_set_position","shader_type","id","position"),&ShaderGraph::node_set_position); - ClassDB::bind_method(D_METHOD("node_get_position","shader_type","id"),&ShaderGraph::node_get_position); - - ClassDB::bind_method(D_METHOD("node_get_type","shader_type","id"),&ShaderGraph::node_get_type); - - ClassDB::bind_method(D_METHOD("get_node_list","shader_type"),&ShaderGraph::_get_node_list); - - ClassDB::bind_method(D_METHOD("default_set_value","shader_type","id","param_id","value"), &ShaderGraph::default_set_value); - ClassDB::bind_method(D_METHOD("default_get_value","shader_type","id","param_id"), &ShaderGraph::default_get_value); - - ClassDB::bind_method(D_METHOD("scalar_const_node_set_value","shader_type","id","value"),&ShaderGraph::scalar_const_node_set_value); - ClassDB::bind_method(D_METHOD("scalar_const_node_get_value","shader_type","id"),&ShaderGraph::scalar_const_node_get_value); - - ClassDB::bind_method(D_METHOD("vec_const_node_set_value","shader_type","id","value"),&ShaderGraph::vec_const_node_set_value); - ClassDB::bind_method(D_METHOD("vec_const_node_get_value","shader_type","id"),&ShaderGraph::vec_const_node_get_value); - - ClassDB::bind_method(D_METHOD("rgb_const_node_set_value","shader_type","id","value"),&ShaderGraph::rgb_const_node_set_value); - ClassDB::bind_method(D_METHOD("rgb_const_node_get_value","shader_type","id"),&ShaderGraph::rgb_const_node_get_value); - - ClassDB::bind_method(D_METHOD("xform_const_node_set_value","shader_type","id","value"),&ShaderGraph::xform_const_node_set_value); - ClassDB::bind_method(D_METHOD("xform_const_node_get_value","shader_type","id"),&ShaderGraph::xform_const_node_get_value); - - - //void get_node_list(ShaderType p_which,List<int> *p_node_list) const; - - ClassDB::bind_method(D_METHOD("texture_node_set_filter_size","shader_type","id","filter_size"),&ShaderGraph::texture_node_set_filter_size); - ClassDB::bind_method(D_METHOD("texture_node_get_filter_size","shader_type","id"),&ShaderGraph::texture_node_get_filter_size); - - ClassDB::bind_method(D_METHOD("texture_node_set_filter_strength","shader_type","id","filter_strength"),&ShaderGraph::texture_node_set_filter_strength); - ClassDB::bind_method(D_METHOD("texture_node_get_filter_strength","shader_type","id"),&ShaderGraph::texture_node_get_filter_strength); - - ClassDB::bind_method(D_METHOD("scalar_op_node_set_op","shader_type","id","op"),&ShaderGraph::scalar_op_node_set_op); - ClassDB::bind_method(D_METHOD("scalar_op_node_get_op","shader_type","id"),&ShaderGraph::scalar_op_node_get_op); - - ClassDB::bind_method(D_METHOD("vec_op_node_set_op","shader_type","id","op"),&ShaderGraph::vec_op_node_set_op); - ClassDB::bind_method(D_METHOD("vec_op_node_get_op","shader_type","id"),&ShaderGraph::vec_op_node_get_op); - - ClassDB::bind_method(D_METHOD("vec_scalar_op_node_set_op","shader_type","id","op"),&ShaderGraph::vec_scalar_op_node_set_op); - ClassDB::bind_method(D_METHOD("vec_scalar_op_node_get_op","shader_type","id"),&ShaderGraph::vec_scalar_op_node_get_op); - - ClassDB::bind_method(D_METHOD("rgb_op_node_set_op","shader_type","id","op"),&ShaderGraph::rgb_op_node_set_op); - ClassDB::bind_method(D_METHOD("rgb_op_node_get_op","shader_type","id"),&ShaderGraph::rgb_op_node_get_op); - - - ClassDB::bind_method(D_METHOD("xform_vec_mult_node_set_no_translation","shader_type","id","disable"),&ShaderGraph::xform_vec_mult_node_set_no_translation); - ClassDB::bind_method(D_METHOD("xform_vec_mult_node_get_no_translation","shader_type","id"),&ShaderGraph::xform_vec_mult_node_get_no_translation); - - ClassDB::bind_method(D_METHOD("scalar_func_node_set_function","shader_type","id","func"),&ShaderGraph::scalar_func_node_set_function); - ClassDB::bind_method(D_METHOD("scalar_func_node_get_function","shader_type","id"),&ShaderGraph::scalar_func_node_get_function); - - ClassDB::bind_method(D_METHOD("vec_func_node_set_function","shader_type","id","func"),&ShaderGraph::vec_func_node_set_function); - ClassDB::bind_method(D_METHOD("vec_func_node_get_function","shader_type","id"),&ShaderGraph::vec_func_node_get_function); - - ClassDB::bind_method(D_METHOD("input_node_set_name","shader_type","id","name"),&ShaderGraph::input_node_set_name); - ClassDB::bind_method(D_METHOD("input_node_get_name","shader_type","id"),&ShaderGraph::input_node_get_name); - - ClassDB::bind_method(D_METHOD("scalar_input_node_set_value","shader_type","id","value"),&ShaderGraph::scalar_input_node_set_value); - ClassDB::bind_method(D_METHOD("scalar_input_node_get_value","shader_type","id"),&ShaderGraph::scalar_input_node_get_value); - - ClassDB::bind_method(D_METHOD("vec_input_node_set_value","shader_type","id","value"),&ShaderGraph::vec_input_node_set_value); - ClassDB::bind_method(D_METHOD("vec_input_node_get_value","shader_type","id"),&ShaderGraph::vec_input_node_get_value); - - ClassDB::bind_method(D_METHOD("rgb_input_node_set_value","shader_type","id","value"),&ShaderGraph::rgb_input_node_set_value); - ClassDB::bind_method(D_METHOD("rgb_input_node_get_value","shader_type","id"),&ShaderGraph::rgb_input_node_get_value); - - ClassDB::bind_method(D_METHOD("xform_input_node_set_value","shader_type","id","value"),&ShaderGraph::xform_input_node_set_value); - ClassDB::bind_method(D_METHOD("xform_input_node_get_value","shader_type","id"),&ShaderGraph::xform_input_node_get_value); - - ClassDB::bind_method(D_METHOD("texture_input_node_set_value","shader_type","id","value"),&ShaderGraph::texture_input_node_set_value); - ClassDB::bind_method(D_METHOD("texture_input_node_get_value","shader_type","id"),&ShaderGraph::texture_input_node_get_value); - - ClassDB::bind_method(D_METHOD("cubemap_input_node_set_value","shader_type","id","value"),&ShaderGraph::cubemap_input_node_set_value); - ClassDB::bind_method(D_METHOD("cubemap_input_node_get_value","shader_type","id"),&ShaderGraph::cubemap_input_node_get_value); - - ClassDB::bind_method(D_METHOD("comment_node_set_text","shader_type","id","text"),&ShaderGraph::comment_node_set_text); - ClassDB::bind_method(D_METHOD("comment_node_get_text","shader_type","id"),&ShaderGraph::comment_node_get_text); - - ClassDB::bind_method(D_METHOD("color_ramp_node_set_ramp","shader_type","id","colors","offsets"),&ShaderGraph::color_ramp_node_set_ramp); - ClassDB::bind_method(D_METHOD("color_ramp_node_get_colors","shader_type","id"),&ShaderGraph::color_ramp_node_get_colors); - ClassDB::bind_method(D_METHOD("color_ramp_node_get_offsets","shader_type","id"),&ShaderGraph::color_ramp_node_get_offsets); - - ClassDB::bind_method(D_METHOD("curve_map_node_set_points","shader_type","id","points"),&ShaderGraph::curve_map_node_set_points); - ClassDB::bind_method(D_METHOD("curve_map_node_get_points","shader_type","id"),&ShaderGraph::curve_map_node_get_points); - - ClassDB::bind_method(D_METHOD("connect_node","shader_type","src_id","src_slot","dst_id","dst_slot"),&ShaderGraph::connect_node); - ClassDB::bind_method(D_METHOD("is_node_connected","shader_type","src_id","src_slot","dst_id","dst_slot"),&ShaderGraph::is_node_connected); - ClassDB::bind_method(D_METHOD("disconnect_node","shader_type","src_id","src_slot","dst_id","dst_slot"),&ShaderGraph::disconnect_node); - ClassDB::bind_method(D_METHOD("get_node_connections","shader_type"),&ShaderGraph::_get_connections); - - ClassDB::bind_method(D_METHOD("clear","shader_type"),&ShaderGraph::clear); - - ClassDB::bind_method(D_METHOD("node_set_state","shader_type","id","state"),&ShaderGraph::node_set_state); - ClassDB::bind_method(D_METHOD("node_get_state","shader_type","id"),&ShaderGraph::node_get_state); - - ClassDB::bind_method(D_METHOD("_set_data"),&ShaderGraph::_set_data); - ClassDB::bind_method(D_METHOD("_get_data"),&ShaderGraph::_get_data); - - ADD_PROPERTY( PropertyInfo(Variant::DICTIONARY,"_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data","_get_data"); - - //void get_connections(ShaderType p_which,List<Connection> *p_connections) const; - - - BIND_ENUM_CONSTANT( NODE_INPUT ); // all inputs (shader type dependent) - BIND_ENUM_CONSTANT( NODE_SCALAR_CONST ); //scalar constant - BIND_ENUM_CONSTANT( NODE_VEC_CONST ); //vec3 constant - BIND_ENUM_CONSTANT( NODE_RGB_CONST ); //rgb constant (shows a color picker instead) - BIND_ENUM_CONSTANT( NODE_XFORM_CONST ); // 4x4 matrix constant - BIND_ENUM_CONSTANT( NODE_TIME ); // time in seconds - BIND_ENUM_CONSTANT( NODE_SCREEN_TEX ); // screen texture sampler (takes UV) (only usable in fragment shader) - BIND_ENUM_CONSTANT( NODE_SCALAR_OP ); // scalar vs scalar op (mul ); add ); div ); etc) - BIND_ENUM_CONSTANT( NODE_VEC_OP ); // vec3 vs vec3 op (mul );ad );div );crossprod );etc) - BIND_ENUM_CONSTANT( NODE_VEC_SCALAR_OP ); // vec3 vs scalar op (mul ); add ); div ); etc) - BIND_ENUM_CONSTANT( NODE_RGB_OP ); // vec3 vs vec3 rgb op (with scalar amount) ); like brighten ); darken ); burn ); dodge ); multiply ); etc. - BIND_ENUM_CONSTANT( NODE_XFORM_MULT ); // mat4 x mat4 - BIND_ENUM_CONSTANT( NODE_XFORM_VEC_MULT ); // mat4 x vec3 mult (with no-translation option) - BIND_ENUM_CONSTANT( NODE_XFORM_VEC_INV_MULT ); // mat4 x vec3 inverse mult (with no-translation option) - BIND_ENUM_CONSTANT( NODE_SCALAR_FUNC ); // scalar function (sin ); cos ); etc) - BIND_ENUM_CONSTANT( NODE_VEC_FUNC ); // vector function (normalize ); negate ); reciprocal ); rgb2hsv ); hsv2rgb ); etc ); etc) - BIND_ENUM_CONSTANT( NODE_VEC_LEN ); // vec3 length - BIND_ENUM_CONSTANT( NODE_DOT_PROD ); // vec3 . vec3 (dot product -> scalar output) - BIND_ENUM_CONSTANT( NODE_VEC_TO_SCALAR ); // 1 vec3 input ); 3 scalar outputs - BIND_ENUM_CONSTANT( NODE_SCALAR_TO_VEC ); // 3 scalar input ); 1 vec3 output - BIND_ENUM_CONSTANT( NODE_VEC_TO_XFORM ); // 3 vec input ); 1 xform output - BIND_ENUM_CONSTANT( NODE_XFORM_TO_VEC ); // 3 vec input ); 1 xform output - BIND_ENUM_CONSTANT( NODE_SCALAR_INTERP ); // scalar interpolation (with optional curve) - BIND_ENUM_CONSTANT( NODE_VEC_INTERP ); // vec3 interpolation (with optional curve) - BIND_ENUM_CONSTANT( NODE_COLOR_RAMP ); - BIND_ENUM_CONSTANT( NODE_CURVE_MAP ); - BIND_ENUM_CONSTANT( NODE_SCALAR_INPUT ); // scalar uniform (assignable in material) - BIND_ENUM_CONSTANT( NODE_VEC_INPUT ); // vec3 uniform (assignable in material) - BIND_ENUM_CONSTANT( NODE_RGB_INPUT ); // color uniform (assignable in material) - BIND_ENUM_CONSTANT( NODE_XFORM_INPUT ); // mat4 uniform (assignable in material) - BIND_ENUM_CONSTANT( NODE_TEXTURE_INPUT ); // texture input (assignable in material) - BIND_ENUM_CONSTANT( NODE_CUBEMAP_INPUT ); // cubemap input (assignable in material) - BIND_ENUM_CONSTANT( NODE_DEFAULT_TEXTURE ); - BIND_ENUM_CONSTANT( NODE_OUTPUT ); // output (shader type dependent) - BIND_ENUM_CONSTANT( NODE_COMMENT ); // comment - BIND_ENUM_CONSTANT( NODE_TYPE_MAX ); - - BIND_ENUM_CONSTANT( SLOT_TYPE_SCALAR ); - BIND_ENUM_CONSTANT( SLOT_TYPE_VEC ); - BIND_ENUM_CONSTANT( SLOT_TYPE_XFORM ); - BIND_ENUM_CONSTANT( SLOT_TYPE_TEXTURE ); - BIND_ENUM_CONSTANT( SLOT_MAX ); - - BIND_ENUM_CONSTANT( SHADER_TYPE_VERTEX ); - BIND_ENUM_CONSTANT( SHADER_TYPE_FRAGMENT ); - BIND_ENUM_CONSTANT( SHADER_TYPE_LIGHT ); - BIND_ENUM_CONSTANT( SHADER_TYPE_MAX ); - - - BIND_ENUM_CONSTANT( SLOT_IN ); - BIND_ENUM_CONSTANT( SLOT_OUT ); - - BIND_ENUM_CONSTANT( GRAPH_OK ); - BIND_ENUM_CONSTANT( GRAPH_ERROR_CYCLIC ); - BIND_ENUM_CONSTANT( GRAPH_ERROR_MISSING_CONNECTIONS ); - - BIND_ENUM_CONSTANT( SCALAR_OP_ADD ); - BIND_ENUM_CONSTANT( SCALAR_OP_SUB ); - BIND_ENUM_CONSTANT( SCALAR_OP_MUL ); - BIND_ENUM_CONSTANT( SCALAR_OP_DIV ); - BIND_ENUM_CONSTANT( SCALAR_OP_MOD ); - BIND_ENUM_CONSTANT( SCALAR_OP_POW ); - BIND_ENUM_CONSTANT( SCALAR_OP_MAX ); - BIND_ENUM_CONSTANT( SCALAR_OP_MIN ); - BIND_ENUM_CONSTANT( SCALAR_OP_ATAN2 ); - BIND_ENUM_CONSTANT( SCALAR_MAX_OP ); - - BIND_ENUM_CONSTANT( VEC_OP_ADD ); - BIND_ENUM_CONSTANT( VEC_OP_SUB ); - BIND_ENUM_CONSTANT( VEC_OP_MUL ); - BIND_ENUM_CONSTANT( VEC_OP_DIV ); - BIND_ENUM_CONSTANT( VEC_OP_MOD ); - BIND_ENUM_CONSTANT( VEC_OP_POW ); - BIND_ENUM_CONSTANT( VEC_OP_MAX ); - BIND_ENUM_CONSTANT( VEC_OP_MIN ); - BIND_ENUM_CONSTANT( VEC_OP_CROSS ); - BIND_ENUM_CONSTANT( VEC_MAX_OP ); - - BIND_ENUM_CONSTANT( VEC_SCALAR_OP_MUL ); - BIND_ENUM_CONSTANT( VEC_SCALAR_OP_DIV ); - BIND_ENUM_CONSTANT( VEC_SCALAR_OP_POW ); - BIND_ENUM_CONSTANT( VEC_SCALAR_MAX_OP ); - - BIND_ENUM_CONSTANT( RGB_OP_SCREEN ); - BIND_ENUM_CONSTANT( RGB_OP_DIFFERENCE ); - BIND_ENUM_CONSTANT( RGB_OP_DARKEN ); - BIND_ENUM_CONSTANT( RGB_OP_LIGHTEN ); - BIND_ENUM_CONSTANT( RGB_OP_OVERLAY ); - BIND_ENUM_CONSTANT( RGB_OP_DODGE ); - BIND_ENUM_CONSTANT( RGB_OP_BURN ); - BIND_ENUM_CONSTANT( RGB_OP_SOFT_LIGHT ); - BIND_ENUM_CONSTANT( RGB_OP_HARD_LIGHT ); - BIND_ENUM_CONSTANT( RGB_MAX_OP ); - - BIND_ENUM_CONSTANT( SCALAR_FUNC_SIN ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_COS ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_TAN ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_ASIN ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_ACOS ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_ATAN ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_SINH ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_COSH ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_TANH ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_LOG ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_EXP ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_SQRT ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_ABS ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_SIGN ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_FLOOR ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_ROUND ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_CEIL ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_FRAC ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_SATURATE ); - BIND_ENUM_CONSTANT( SCALAR_FUNC_NEGATE ); - BIND_ENUM_CONSTANT( SCALAR_MAX_FUNC ); - - BIND_ENUM_CONSTANT( VEC_FUNC_NORMALIZE ); - BIND_ENUM_CONSTANT( VEC_FUNC_SATURATE ); - BIND_ENUM_CONSTANT( VEC_FUNC_NEGATE ); - BIND_ENUM_CONSTANT( VEC_FUNC_RECIPROCAL ); - BIND_ENUM_CONSTANT( VEC_FUNC_RGB2HSV ); - BIND_ENUM_CONSTANT( VEC_FUNC_HSV2RGB ); - BIND_ENUM_CONSTANT( VEC_MAX_FUNC ); - - ADD_SIGNAL(MethodInfo("updated")); -} - - -String ShaderGraph::_find_unique_name(const String& p_base) { - - - - int idx=1; - while(true) { - String tocmp=p_base; - if (idx>1) { - tocmp+="_"+itos(idx); - } - bool valid=true; - for(int i=0;i<3;i++) { - if (!valid) - break; - for (Map<int,Node>::Element *E=shader[i].node_map.front();E;E=E->next()) { - if (E->get().type!=NODE_SCALAR_INPUT && E->get().type!=NODE_VEC_INPUT && E->get().type==NODE_RGB_INPUT && E->get().type==NODE_XFORM_INPUT && E->get().type==NODE_TEXTURE_INPUT && E->get().type==NODE_CUBEMAP_INPUT) - continue; - String name = E->get().param1; - if (name==tocmp) { - valid=false; - break; - } - - } - } - - if (!valid) { - idx++; - continue; - } - return tocmp; - } - return String(); -} - -void ShaderGraph::node_add(ShaderType p_type, NodeType p_node_type,int p_id) { - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(p_id==0); - ERR_FAIL_COND(p_node_type==NODE_OUTPUT); //can't create output - ERR_FAIL_COND( shader[p_type].node_map.has(p_id ) ); - ERR_FAIL_INDEX( p_node_type, NODE_TYPE_MAX ); - Node node; - - if (p_node_type==NODE_INPUT) { - //see if it already exists - for(Map<int,Node>::Element *E=shader[p_type].node_map.front();E;E=E->next()) { - if (E->get().type==NODE_INPUT) { - ERR_EXPLAIN("Only one input node can be added to the graph."); - ERR_FAIL_COND(E->get().type==NODE_INPUT); - } - } - } - node.type=p_node_type; - node.id=p_id; - - switch(p_node_type) { - case NODE_INPUT: {} break; // all inputs (shader type dependent) - case NODE_SCALAR_CONST: { node.param1=0;} break; //scalar constant - case NODE_VEC_CONST: {node.param1=Vector3();} break; //vec3 constant - case NODE_RGB_CONST: {node.param1=Color();} break; //rgb constant (shows a color picker instead) - case NODE_XFORM_CONST: {node.param1=Transform();} break; // 4x4 matrix constant - case NODE_TIME: {} break; // time in seconds - case NODE_SCREEN_TEX: {Array arr; arr.push_back(0); arr.push_back(0); node.param2=arr;} break; // screen texture sampler (takes UV) (only usable in fragment shader) - case NODE_SCALAR_OP: {node.param1=SCALAR_OP_ADD;} break; // scalar vs scalar op (mul: {} break; add: {} break; div: {} break; etc) - case NODE_VEC_OP: {node.param1=VEC_OP_ADD;} break; // vec3 vs vec3 op (mul: {} break;ad: {} break;div: {} break;crossprod: {} break;etc) - case NODE_VEC_SCALAR_OP: {node.param1=VEC_SCALAR_OP_MUL;} break; // vec3 vs scalar op (mul: {} break; add: {} break; div: {} break; etc) - case NODE_RGB_OP: {node.param1=RGB_OP_SCREEN;} break; // vec3 vs vec3 rgb op (with scalar amount): {} break; like brighten: {} break; darken: {} break; burn: {} break; dodge: {} break; multiply: {} break; etc. - case NODE_XFORM_MULT: {} break; // mat4 x mat4 - case NODE_XFORM_VEC_MULT: {} break; // mat4 x vec3 mult (with no-translation option) - case NODE_XFORM_VEC_INV_MULT: {} break; // mat4 x vec3 inverse mult (with no-translation option) - case NODE_SCALAR_FUNC: {node.param1=SCALAR_FUNC_SIN;} break; // scalar function (sin: {} break; cos: {} break; etc) - case NODE_VEC_FUNC: {node.param1=VEC_FUNC_NORMALIZE;} break; // vector function (normalize: {} break; negate: {} break; reciprocal: {} break; rgb2hsv: {} break; hsv2rgb: {} break; etc: {} break; etc) - case NODE_VEC_LEN: {} break; // vec3 length - case NODE_DOT_PROD: {} break; // vec3 . vec3 (dot product -> scalar output) - case NODE_VEC_TO_SCALAR: {} break; // 1 vec3 input: {} break; 3 scalar outputs - case NODE_SCALAR_TO_VEC: {} break; // 3 scalar input: {} break; 1 vec3 output - case NODE_VEC_TO_XFORM: {} break; // 3 scalar input: {} break; 1 vec3 output - case NODE_XFORM_TO_VEC: {} break; // 3 scalar input: {} break; 1 vec3 output - case NODE_SCALAR_INTERP: {} break; // scalar interpolation (with optional curve) - case NODE_VEC_INTERP: {} break; // vec3 interpolation (with optional curve) - case NODE_COLOR_RAMP: { node.param1=PoolVector<Color>(); node.param2=PoolVector<real_t>();} break; // vec3 interpolation (with optional curve) - case NODE_CURVE_MAP: { node.param1=PoolVector<Vector2>();} break; // vec3 interpolation (with optional curve) - case NODE_SCALAR_INPUT: {node.param1=_find_unique_name("Scalar"); node.param2=0;} break; // scalar uniform (assignable in material) - case NODE_VEC_INPUT: {node.param1=_find_unique_name("Vec3");node.param2=Vector3();} break; // vec3 uniform (assignable in material) - case NODE_RGB_INPUT: {node.param1=_find_unique_name("Color");node.param2=Color();} break; // color uniform (assignable in material) - case NODE_XFORM_INPUT: {node.param1=_find_unique_name("XForm"); node.param2=Transform();} break; // mat4 uniform (assignable in material) - case NODE_TEXTURE_INPUT: {node.param1=_find_unique_name("Tex"); } break; // texture input (assignable in material) - case NODE_CUBEMAP_INPUT: {node.param1=_find_unique_name("Cube"); } break; // cubemap input (assignable in material) - case NODE_DEFAULT_TEXTURE: {}; break; - case NODE_OUTPUT: {} break; // output (shader type dependent) - case NODE_COMMENT: {} break; // comment - case NODE_TYPE_MAX: {}; - } - - shader[p_type].node_map[p_id]=node; - _request_update(); -} - -void ShaderGraph::node_set_position(ShaderType p_type,int p_id, const Vector2& p_pos) { - ERR_FAIL_INDEX(p_type,3); - - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - shader[p_type].node_map[p_id].pos=p_pos; - _request_update(); - -} -Vector2 ShaderGraph::node_get_position(ShaderType p_type,int p_id) const { - ERR_FAIL_INDEX_V(p_type,3,Vector2()); - - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Vector2()); - return shader[p_type].node_map[p_id].pos; -} - - -void ShaderGraph::node_remove(ShaderType p_type,int p_id) { - - ERR_FAIL_COND(p_id==0); - ERR_FAIL_INDEX(p_type,3); - - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - - //erase connections associated with node - for(Map<int,Node>::Element *E=shader[p_type].node_map.front();E;E=E->next()) { - if (E->key()==p_id) - continue; //no self - - for (Map<int,SourceSlot>::Element *F=E->get().connections.front();F;) { - Map<int,SourceSlot>::Element *N=F->next(); - - if (F->get().id==p_id) { - E->get().connections.erase(F); - } - - F=N; - } - } - - shader[p_type].node_map.erase(p_id); - - _request_update(); - -} - - - -void ShaderGraph::get_node_list(ShaderType p_type,List<int> *p_node_list) const { - - ERR_FAIL_INDEX(p_type,3); - - Map<int,Node>::Element *E = shader[p_type].node_map.front(); - - while(E) { - - p_node_list->push_back(E->key()); - E=E->next(); - } -} - - -ShaderGraph::NodeType ShaderGraph::node_get_type(ShaderType p_type,int p_id) const { - - ERR_FAIL_INDEX_V(p_type,3,NODE_TYPE_MAX); - - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),NODE_TYPE_MAX); - return shader[p_type].node_map[p_id].type; -} - - -Error ShaderGraph::connect_node(ShaderType p_type,int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) { - ERR_FAIL_INDEX_V(p_type,3,ERR_INVALID_PARAMETER); - - ERR_FAIL_COND_V(p_src_id==p_dst_id, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_src_id), ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_dst_id), ERR_INVALID_PARAMETER); - NodeType type_src=shader[p_type].node_map[p_src_id].type; - NodeType type_dst=shader[p_type].node_map[p_dst_id].type; - ERR_FAIL_INDEX_V( p_src_slot, get_node_output_slot_count(get_mode(),p_type,type_src), ERR_INVALID_PARAMETER ); - ERR_FAIL_INDEX_V( p_dst_slot, get_node_input_slot_count(get_mode(),p_type,type_dst), ERR_INVALID_PARAMETER ); - ERR_FAIL_COND_V(get_node_output_slot_type(get_mode(),p_type,type_src,p_src_slot) != get_node_input_slot_type(get_mode(),p_type,type_dst,p_dst_slot), ERR_INVALID_PARAMETER ); - - - SourceSlot ts; - ts.id=p_src_id; - ts.slot=p_src_slot; - shader[p_type].node_map[p_dst_id].connections[p_dst_slot]=ts; - _request_update(); - - return OK; -} - -bool ShaderGraph::is_node_connected(ShaderType p_type,int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) const { - - ERR_FAIL_INDEX_V(p_type,3,false); - - SourceSlot ts; - ts.id=p_src_id; - ts.slot=p_src_slot; - return shader[p_type].node_map.has(p_dst_id) && shader[p_type].node_map[p_dst_id].connections.has(p_dst_slot) && - shader[p_type].node_map[p_dst_id].connections[p_dst_slot]==ts; -} - -void ShaderGraph::disconnect_node(ShaderType p_type,int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) { - ERR_FAIL_INDEX(p_type,3); - - SourceSlot ts; - ts.id=p_src_id; - ts.slot=p_src_slot; - if (shader[p_type].node_map.has(p_dst_id) && shader[p_type].node_map[p_dst_id].connections.has(p_dst_slot) && - shader[p_type].node_map[p_dst_id].connections[p_dst_slot]==ts) { - shader[p_type].node_map[p_dst_id].connections.erase(p_dst_slot); - - } - _request_update(); - -} - -void ShaderGraph::get_node_connections(ShaderType p_type,List<Connection> *p_connections) const { - - ERR_FAIL_INDEX(p_type,3); - - for(const Map<int,Node>::Element *E=shader[p_type].node_map.front();E;E=E->next()) { - for (const Map<int,SourceSlot>::Element *F=E->get().connections.front();F;F=F->next()) { - - Connection c; - c.dst_id=E->key(); - c.dst_slot=F->key(); - c.src_id=F->get().id; - c.src_slot=F->get().slot; - p_connections->push_back(c); - } - } -} - -bool ShaderGraph::is_slot_connected(ShaderGraph::ShaderType p_type, int p_dst_id, int slot_id) -{ - for(const Map<int,Node>::Element *E=shader[p_type].node_map.front();E;E=E->next()) { - for (const Map<int,SourceSlot>::Element *F=E->get().connections.front();F;F=F->next()) { - - if (p_dst_id == E->key() && slot_id==F->key()) - return true; - } - } - return false; -} - - -void ShaderGraph::clear(ShaderType p_type) { - - ERR_FAIL_INDEX(p_type,3); - shader[p_type].node_map.clear(); - Node out; - out.pos=Vector2(300,300); - out.type=NODE_OUTPUT; - shader[p_type].node_map.insert(0,out); - - _request_update(); - -} - - -void ShaderGraph::scalar_const_node_set_value(ShaderType p_type,int p_id,float p_value) { - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_SCALAR_CONST); - n.param1=p_value; - _request_update(); - -} - -float ShaderGraph::scalar_const_node_get_value(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,0); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),0); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_SCALAR_CONST,0); - return n.param1; -} - -void ShaderGraph::vec_const_node_set_value(ShaderType p_type,int p_id,const Vector3& p_value){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_VEC_CONST); - n.param1=p_value; - _request_update(); - - -} -Vector3 ShaderGraph::vec_const_node_get_value(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,Vector3()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Vector3()); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_VEC_CONST,Vector3()); - return n.param1; - -} - -void ShaderGraph::rgb_const_node_set_value(ShaderType p_type,int p_id,const Color& p_value){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_RGB_CONST); - n.param1=p_value; - _request_update(); - -} -Color ShaderGraph::rgb_const_node_get_value(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,Color()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Color()); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_RGB_CONST,Color()); - return n.param1; - -} - -void ShaderGraph::xform_const_node_set_value(ShaderType p_type,int p_id,const Transform& p_value){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_XFORM_CONST); - n.param1=p_value; - _request_update(); - -} -Transform ShaderGraph::xform_const_node_get_value(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,Transform()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Transform()); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_XFORM_CONST,Transform()); - return n.param1; - -} - -void ShaderGraph::texture_node_set_filter_size(ShaderType p_type,int p_id,int p_size){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_TEXTURE_INPUT && n.type!=NODE_SCREEN_TEX); - Array arr = n.param2; - arr[0]=p_size; - n.param2=arr; - _request_update(); - -} -int ShaderGraph::texture_node_get_filter_size(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,0); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),0); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_TEXTURE_INPUT && n.type!=NODE_SCREEN_TEX,0); - Array arr = n.param2; - return arr[0]; - -} - -void ShaderGraph::texture_node_set_filter_strength(ShaderType p_type,float p_id,float p_strength){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_TEXTURE_INPUT && n.type!=NODE_SCREEN_TEX); - Array arr = n.param2; - arr[1]=p_strength; - n.param2=arr; - _request_update(); - -} -float ShaderGraph::texture_node_get_filter_strength(ShaderType p_type,float p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,0); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),0); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_TEXTURE_INPUT && n.type!=NODE_SCREEN_TEX,0); - Array arr = n.param2; - return arr[1]; -} - -void ShaderGraph::duplicate_nodes(ShaderType p_which, List<int> &p_nodes) -{ - //Create new node IDs - Map<int,int> duplicates = Map<int,int>(); - int i=1; - for(List<int>::Element *E=p_nodes.front();E; E=E->next()) { - while (shader[p_which].node_map.has(i)) - i++; - duplicates.insert(E->get(), i); - i++; - } - - for(List<int>::Element *E = p_nodes.front();E; E=E->next()) { - - const Node &n=shader[p_which].node_map[E->get()]; - Node nn=n; - nn.id=duplicates.find(n.id)->get(); - nn.pos += Vector2(0,100); - for (Map<int,SourceSlot>::Element *C=nn.connections.front();C;C=C->next()) { - SourceSlot &c=C->get(); - if (p_nodes.find(c.id)) - c.id=duplicates.find(c.id)->get(); - } - shader[p_which].node_map[nn.id]=nn; - } - _request_update(); -} - -List<int> ShaderGraph::generate_ids(ShaderType p_type, int count) -{ - List<int> ids = List<int>(); - int i=1; - while (ids.size() < count) { - while (shader[p_type].node_map.has(i)) - i++; - ids.push_back(i); - i++; - } - return ids; -} - - -void ShaderGraph::scalar_op_node_set_op(ShaderType p_type,float p_id,ScalarOp p_op){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_SCALAR_OP); - n.param1=p_op; - _request_update(); - -} -ShaderGraph::ScalarOp ShaderGraph::scalar_op_node_get_op(ShaderType p_type,float p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,SCALAR_MAX_OP); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),SCALAR_MAX_OP); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_SCALAR_OP,SCALAR_MAX_OP); - int op = n.param1; - return ScalarOp(op); - -} - - -void ShaderGraph::vec_op_node_set_op(ShaderType p_type,float p_id,VecOp p_op){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_VEC_OP); - n.param1=p_op; - _request_update(); - -} -ShaderGraph::VecOp ShaderGraph::vec_op_node_get_op(ShaderType p_type,float p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,VEC_MAX_OP); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),VEC_MAX_OP); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_VEC_OP,VEC_MAX_OP); - int op = n.param1; - return VecOp(op); - -} - - -void ShaderGraph::vec_scalar_op_node_set_op(ShaderType p_type,float p_id,VecScalarOp p_op){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_VEC_SCALAR_OP); - n.param1=p_op; - _request_update(); - -} -ShaderGraph::VecScalarOp ShaderGraph::vec_scalar_op_node_get_op(ShaderType p_type,float p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,VEC_SCALAR_MAX_OP); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),VEC_SCALAR_MAX_OP); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_VEC_SCALAR_OP,VEC_SCALAR_MAX_OP); - int op = n.param1; - return VecScalarOp(op); - -} - -void ShaderGraph::rgb_op_node_set_op(ShaderType p_type,float p_id,RGBOp p_op){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_RGB_OP); - n.param1=p_op; - - _request_update(); - -} -ShaderGraph::RGBOp ShaderGraph::rgb_op_node_get_op(ShaderType p_type,float p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,RGB_MAX_OP); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),RGB_MAX_OP); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_RGB_OP,RGB_MAX_OP); - int op = n.param1; - return RGBOp(op); - -} - - -void ShaderGraph::xform_vec_mult_node_set_no_translation(ShaderType p_type,int p_id,bool p_no_translation){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_XFORM_VEC_MULT && n.type!=NODE_XFORM_VEC_INV_MULT); - n.param1=p_no_translation; - _request_update(); - -} -bool ShaderGraph::xform_vec_mult_node_get_no_translation(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,false); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),false); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_XFORM_VEC_MULT && n.type!=NODE_XFORM_VEC_INV_MULT,false); - return n.param1; - -} - -void ShaderGraph::scalar_func_node_set_function(ShaderType p_type,int p_id,ScalarFunc p_func){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_SCALAR_FUNC); - int func = p_func; - ERR_FAIL_INDEX(func,SCALAR_MAX_FUNC); - n.param1=func; - _request_update(); - -} -ShaderGraph::ScalarFunc ShaderGraph::scalar_func_node_get_function(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,SCALAR_MAX_FUNC); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),SCALAR_MAX_FUNC); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_SCALAR_FUNC,SCALAR_MAX_FUNC); - int func = n.param1; - return ScalarFunc(func); -} - -void ShaderGraph::default_set_value(ShaderGraph::ShaderType p_which, int p_id, int p_param, const Variant &p_value) -{ - ERR_FAIL_INDEX(p_which,3); - ERR_FAIL_COND(!shader[p_which].node_map.has(p_id)); - Node& n = shader[p_which].node_map[p_id]; - if(p_value.get_type()==Variant::NIL) - n.defaults.erase(n.defaults.find(p_param)); - else - n.defaults[p_param]=p_value; - - _request_update(); - -} - -Variant ShaderGraph::default_get_value(ShaderGraph::ShaderType p_which, int p_id, int p_param) -{ - ERR_FAIL_INDEX_V(p_which,3,Variant()); - ERR_FAIL_COND_V(!shader[p_which].node_map.has(p_id),Variant()); - const Node& n = shader[p_which].node_map[p_id]; - - if (!n.defaults.has(p_param)) - return Variant(); - return n.defaults[p_param]; -} - - - -void ShaderGraph::vec_func_node_set_function(ShaderType p_type,int p_id,VecFunc p_func){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_VEC_FUNC); - int func = p_func; - ERR_FAIL_INDEX(func,VEC_MAX_FUNC); - n.param1=func; - - _request_update(); - -} -ShaderGraph::VecFunc ShaderGraph::vec_func_node_get_function(ShaderType p_type, int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,VEC_MAX_FUNC); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),VEC_MAX_FUNC); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_VEC_FUNC,VEC_MAX_FUNC); - int func = n.param1; - return VecFunc(func); -} - -void ShaderGraph::color_ramp_node_set_ramp(ShaderType p_type,int p_id,const PoolVector<Color>& p_colors, const PoolVector<real_t>& p_offsets){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - ERR_FAIL_COND(p_colors.size()!=p_offsets.size()); - Node& n = shader[p_type].node_map[p_id]; - n.param1=p_colors; - n.param2=p_offsets; - _request_update(); - -} - -PoolVector<Color> ShaderGraph::color_ramp_node_get_colors(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,PoolVector<Color>()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),PoolVector<Color>()); - const Node& n = shader[p_type].node_map[p_id]; - return n.param1; - - -} - -PoolVector<real_t> ShaderGraph::color_ramp_node_get_offsets(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,PoolVector<real_t>()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),PoolVector<real_t>()); - const Node& n = shader[p_type].node_map[p_id]; - return n.param2; - -} - - -void ShaderGraph::curve_map_node_set_points(ShaderType p_type,int p_id,const PoolVector<Vector2>& p_points) { - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - n.param1=p_points; - _request_update(); - -} - -PoolVector<Vector2> ShaderGraph::curve_map_node_get_points(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,PoolVector<Vector2>()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),PoolVector<Vector2>()); - const Node& n = shader[p_type].node_map[p_id]; - return n.param1; - -} - - - -void ShaderGraph::input_node_set_name(ShaderType p_type,int p_id,const String& p_name){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - ERR_FAIL_COND(!p_name.is_valid_identifier()); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_SCALAR_INPUT && n.type!=NODE_VEC_INPUT && n.type==NODE_RGB_INPUT && n.type==NODE_XFORM_INPUT && n.type==NODE_TEXTURE_INPUT && n.type==NODE_CUBEMAP_INPUT); - - n.param1=""; - n.param1=_find_unique_name(p_name); - _request_update(); - -} -String ShaderGraph::input_node_get_name(ShaderType p_type,int p_id){ - - ERR_FAIL_INDEX_V(p_type,3,String()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),String()); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_SCALAR_INPUT && n.type!=NODE_VEC_INPUT && n.type==NODE_RGB_INPUT && n.type==NODE_XFORM_INPUT && n.type==NODE_TEXTURE_INPUT && n.type==NODE_CUBEMAP_INPUT,String()); - return n.param1; -} - - -void ShaderGraph::scalar_input_node_set_value(ShaderType p_type,int p_id,float p_value) { - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_SCALAR_INPUT); - n.param2=p_value; - _request_update(); - -} - -float ShaderGraph::scalar_input_node_get_value(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,0); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),0); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_SCALAR_INPUT,0); - - return n.param2; -} - -void ShaderGraph::vec_input_node_set_value(ShaderType p_type,int p_id,const Vector3& p_value){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_VEC_INPUT); - - n.param2=p_value; - _request_update(); - -} -Vector3 ShaderGraph::vec_input_node_get_value(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,Vector3()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Vector3()); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_VEC_INPUT,Vector3()); - return n.param2; -} - -void ShaderGraph::rgb_input_node_set_value(ShaderType p_type,int p_id,const Color& p_value){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_RGB_INPUT); - n.param2=p_value; - _request_update(); - -} -Color ShaderGraph::rgb_input_node_get_value(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,Color()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Color()); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_RGB_INPUT,Color()); - return n.param2; -} - -void ShaderGraph::xform_input_node_set_value(ShaderType p_type,int p_id,const Transform& p_value){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_XFORM_INPUT); - n.param2=p_value; - _request_update(); - -} -Transform ShaderGraph::xform_input_node_get_value(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,Transform()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Transform()); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_XFORM_INPUT,Transform()); - return n.param2; -} - - -void ShaderGraph::texture_input_node_set_value(ShaderType p_type,int p_id,const Ref<Texture>& p_texture) { - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_TEXTURE_INPUT); - n.param2=p_texture; - _request_update(); - -} - -Ref<Texture> ShaderGraph::texture_input_node_get_value(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,Ref<Texture>()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Ref<Texture>()); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_TEXTURE_INPUT,Ref<Texture>()); - return n.param2; -} - -void ShaderGraph::cubemap_input_node_set_value(ShaderType p_type,int p_id,const Ref<CubeMap>& p_cubemap){ - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_CUBEMAP_INPUT); - n.param2=p_cubemap; - _request_update(); - -} - -Ref<CubeMap> ShaderGraph::cubemap_input_node_get_value(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,Ref<CubeMap>()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Ref<CubeMap>()); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_CUBEMAP_INPUT,Ref<CubeMap>()); - return n.param2; - -} - - -void ShaderGraph::comment_node_set_text(ShaderType p_type,int p_id,const String& p_comment) { - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND(n.type!=NODE_COMMENT); - n.param1=p_comment; - -} - -String ShaderGraph::comment_node_get_text(ShaderType p_type,int p_id) const{ - - ERR_FAIL_INDEX_V(p_type,3,String()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),String()); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_COMMENT,String()); - return n.param1; - -} - -void ShaderGraph::_request_update() { - - if (_pending_update_shader) - return; - - _pending_update_shader=true; - call_deferred("_update_shader"); - -} - -Variant ShaderGraph::node_get_state(ShaderType p_type,int p_id) const { - - ERR_FAIL_INDEX_V(p_type,3,Variant()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),Variant()); - const Node& n = shader[p_type].node_map[p_id]; - Dictionary s; - s["position"]=n.pos; - s["param1"]=n.param1; - s["param2"]=n.param2; - Array keys; - for (Map<int,Variant>::Element *E=n.defaults.front();E;E=E->next()) { - keys.append(E->key()); - s[E->key()]=E->get(); - } - s["default_keys"]=keys; - return s; - -} -void ShaderGraph::node_set_state(ShaderType p_type,int p_id,const Variant& p_state) { - - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - Dictionary d = p_state; - ERR_FAIL_COND(!d.has("position")); - ERR_FAIL_COND(!d.has("param1")); - ERR_FAIL_COND(!d.has("param2")); - ERR_FAIL_COND(!d.has("default_keys")); - - n.pos=d["position"]; - n.param1=d["param1"]; - n.param2=d["param2"]; - Array keys = d["default_keys"]; - for(int i=0;i<keys.size();i++) { - n.defaults[keys[i]]=d[keys[i]]; - } -} - -ShaderGraph::ShaderGraph(Mode p_mode) : Shader(p_mode) { - - //shader = VisualServer::get_singleton()->shader_create(); - _pending_update_shader=false; - - Node input; - input.id=1; - input.pos=Vector2(50,40); - input.type=NODE_INPUT; - - Node output; - output.id=0; - output.pos=Vector2(350,40); - output.type=NODE_OUTPUT; - - for(int i=0;i<3;i++) { - - shader[i].node_map.insert(0,output); - shader[i].node_map.insert(1,input); - } -} - -ShaderGraph::~ShaderGraph() { - - //VisualServer::get_singleton()->free(shader); -} - - -const ShaderGraph::InOutParamInfo ShaderGraph::inout_param_info[]={ - //material vertex in - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Vertex","SRC_VERTEX","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Normal","SRC_NORMAL","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Tangent","SRC_TANGENT","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"BinormalF","SRC_BINORMALF","",SLOT_TYPE_SCALAR,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Color","SRC_COLOR","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Alpha","SRC_ALPHA","",SLOT_TYPE_SCALAR,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"UV","SRC_UV","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"UV2","SRC_UV2","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"WorldMatrix","WORLD_MATRIX","",SLOT_TYPE_XFORM,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"InvCameraMatrix","INV_CAMERA_MATRIX","",SLOT_TYPE_XFORM,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"ProjectionMatrix","PROJECTION_MATRIX","",SLOT_TYPE_XFORM,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"ModelviewMatrix","MODELVIEW_MATRIX","",SLOT_TYPE_XFORM,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"InstanceID","INSTANCE_ID","",SLOT_TYPE_SCALAR,SLOT_IN}, - - //material vertex out - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Vertex","VERTEX","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Normal","NORMAL","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Tangent","TANGENT","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Binormal","BINORMAL","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"UV","UV",".xy",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"UV2","UV2",".xy",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Color","COLOR.rgb","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Alpha","COLOR.a","",SLOT_TYPE_SCALAR,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Var1","VAR1.rgb","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"Var2","VAR2.rgb","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"SpecExp","SPEC_EXP","",SLOT_TYPE_SCALAR,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_VERTEX,"PointSize","POINT_SIZE","",SLOT_TYPE_SCALAR,SLOT_OUT}, - //pixel vertex in - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Vertex","VERTEX","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Position","POSITION.xyz","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Normal","IN_NORMAL","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Tangent","TANGENT","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Binormal","BINORMAL","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"UV","vec3(UV,0)","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"UV2","vec3(UV2,0)","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"UVScreen","vec3(SCREEN_UV,0)","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"PointCoord","POINT_COORD","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Color","COLOR.rgb","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Alpha","COLOR.a","",SLOT_TYPE_SCALAR,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"InvCameraMatrix","INV_CAMERA_MATRIX","",SLOT_TYPE_XFORM,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Var1","VAR1.rgb","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Var2","VAR2.rgb","",SLOT_TYPE_VEC,SLOT_IN}, - //pixel vertex out - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Diffuse","DIFFUSE_OUT","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"DiffuseAlpha","ALPHA_OUT","",SLOT_TYPE_SCALAR,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Specular","SPECULAR","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"SpecularExp","SPEC_EXP","",SLOT_TYPE_SCALAR,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Emission","EMISSION","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Glow","GLOW","",SLOT_TYPE_SCALAR,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"ShadeParam","SHADE_PARAM","",SLOT_TYPE_SCALAR,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Normal","NORMAL","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"NormalMap","NORMALMAP","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"NormalMapDepth","NORMALMAP_DEPTH","",SLOT_TYPE_SCALAR,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Discard","DISCARD",">0.5",SLOT_TYPE_SCALAR,SLOT_OUT}, - //light in - {MODE_MATERIAL,SHADER_TYPE_LIGHT,"Normal","NORMAL","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_LIGHT,"LightDir","LIGHT_DIR","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_LIGHT,"LightDiffuse","LIGHT_DIFFUSE","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_LIGHT,"LightSpecular","LIGHT_SPECULAR","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_LIGHT,"EyeVec","EYE_VEC","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_LIGHT,"Diffuse","DIFFUSE","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_LIGHT,"Specular","SPECULAR","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_LIGHT,"SpecExp","SPECULAR_EXP","",SLOT_TYPE_SCALAR,SLOT_IN}, - {MODE_MATERIAL,SHADER_TYPE_LIGHT,"ShadeParam","SHADE_PARAM","",SLOT_TYPE_SCALAR,SLOT_IN}, - //light out - {MODE_MATERIAL,SHADER_TYPE_LIGHT,"Light","LIGHT","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_MATERIAL,SHADER_TYPE_LIGHT,"Shadow", "SHADOW", "",SLOT_TYPE_VEC, SLOT_OUT }, - //canvas item vertex in - {MODE_CANVAS_ITEM,SHADER_TYPE_VERTEX,"Vertex","vec3(SRC_VERTEX,0)","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_VERTEX,"UV","SRC_UV","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_VERTEX,"Color","SRC_COLOR.rgb","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_VERTEX,"Alpha","SRC_COLOR.a","",SLOT_TYPE_SCALAR,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_VERTEX,"WorldMatrix","WORLD_MATRIX","",SLOT_TYPE_XFORM,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_VERTEX,"ExtraMatrix","EXTRA_MATRIX","",SLOT_TYPE_XFORM,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_VERTEX,"ProjectionMatrix","PROJECTION_MATRIX","",SLOT_TYPE_XFORM,SLOT_IN}, - //canvas item vertex out - {MODE_CANVAS_ITEM,SHADER_TYPE_VERTEX,"Vertex","VERTEX",".xy",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_CANVAS_ITEM,SHADER_TYPE_VERTEX,"UV","UV",".xy",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_CANVAS_ITEM,SHADER_TYPE_VERTEX,"Color","COLOR.rgb","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_CANVAS_ITEM,SHADER_TYPE_VERTEX,"Alpha","COLOR.a","",SLOT_TYPE_SCALAR,SLOT_OUT}, - {MODE_CANVAS_ITEM,SHADER_TYPE_VERTEX,"Var1","VAR1.rgb","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_CANVAS_ITEM,SHADER_TYPE_VERTEX,"Var2","VAR2.rgb","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_CANVAS_ITEM,SHADER_TYPE_VERTEX,"PointSize","POINT_SIZE","",SLOT_TYPE_SCALAR,SLOT_OUT}, - //canvas item fragment in - {MODE_CANVAS_ITEM,SHADER_TYPE_FRAGMENT,"Color","SRC_COLOR.rgb","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_FRAGMENT,"Alpha","SRC_COLOR.a","",SLOT_TYPE_SCALAR,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_FRAGMENT,"UV","vec3(UV,0)","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_FRAGMENT,"UVScreen","vec3(SCREEN_UV,0)","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_FRAGMENT,"TexPixelSize","vec3(TEXTURE_PIXEL_SIZE,0)","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_FRAGMENT,"Var1","VAR1.rgb","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_FRAGMENT,"Var2","VAR2.rgb","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_FRAGMENT,"PointCoord","POINT_COORD","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_FRAGMENT,"Position","POSITION","",SLOT_TYPE_VEC,SLOT_IN}, - //canvas item fragment out - {MODE_CANVAS_ITEM,SHADER_TYPE_FRAGMENT,"Color","COLOR.rgb","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_CANVAS_ITEM,SHADER_TYPE_FRAGMENT,"Alpha","COLOR.a","",SLOT_TYPE_SCALAR,SLOT_OUT}, - {MODE_CANVAS_ITEM,SHADER_TYPE_FRAGMENT,"Normal","NORMAL","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_CANVAS_ITEM,SHADER_TYPE_FRAGMENT,"NormalMap","NORMALMAP","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_CANVAS_ITEM,SHADER_TYPE_FRAGMENT,"NormalMapDepth","NORMALMAP_DEPTH","",SLOT_TYPE_SCALAR,SLOT_OUT}, - //canvas item light in - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"Color","COLOR.rgb","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"Alpha","COLOR.a","",SLOT_TYPE_SCALAR,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"Normal","NORMAL","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"UV","vec3(UV,0)","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"LightColor","LIGHT_COLOR.rgb","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"LightAlpha","LIGHT_COLOR.a","",SLOT_TYPE_SCALAR,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"LightHeight","LIGHT_HEIGHT","",SLOT_TYPE_SCALAR,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"ShadowColor","LIGHT_SHADOW.rgb","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"ShadowAlpha","LIGHT_SHADOW.a","",SLOT_TYPE_SCALAR,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"TexPixelSize","vec3(TEXTURE_PIXEL_SIZE,0)","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"Var1","VAR1.rgb","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"Var2","VAR2.rgb","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"PointCoord","POINT_COORD","",SLOT_TYPE_VEC,SLOT_IN}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"Position","POSITION","",SLOT_TYPE_VEC,SLOT_IN}, - //canvas item light out - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"LightColor","LIGHT.rgb","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"LightAlpha","LIGHT.a","",SLOT_TYPE_SCALAR,SLOT_OUT}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"ShadowColor","SHADOW.rgb","",SLOT_TYPE_VEC,SLOT_OUT}, - {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"ShadowAlpha","SHADOW.a","",SLOT_TYPE_SCALAR,SLOT_OUT}, - //end - {MODE_MATERIAL,SHADER_TYPE_FRAGMENT,NULL,NULL,NULL,SLOT_TYPE_SCALAR,SLOT_OUT}, - - - -}; - -void ShaderGraph::get_input_output_node_slot_info(Mode p_mode, ShaderType p_type, List<SlotInfo> *r_slots) { - - const InOutParamInfo* iop = &inout_param_info[0]; - while(iop->name) { - if (p_mode==iop->shader_mode && p_type==iop->shader_type) { - - SlotInfo si; - si.dir=iop->dir; - si.name=iop->name; - si.type=iop->slot_type; - r_slots->push_back(si); - } - iop++; - } -} - - -const ShaderGraph::NodeSlotInfo ShaderGraph::node_slot_info[]= { - - {NODE_SCALAR_CONST,{SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, //scalar constant - {NODE_VEC_CONST,{SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, //vec3 constant - {NODE_RGB_CONST,{SLOT_MAX},{SLOT_TYPE_VEC,SLOT_TYPE_SCALAR,SLOT_MAX}}, //rgb constant (shows a color picker instead) - {NODE_XFORM_CONST,{SLOT_MAX},{SLOT_TYPE_XFORM,SLOT_MAX}}, // 4x4 matrix constant - {NODE_TIME,{SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // time in seconds - {NODE_SCREEN_TEX,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // screen texture sampler (takes UV) (only usable in fragment shader) - {NODE_SCALAR_OP,{SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // scalar vs scalar op (mul,{SLOT_MAX},{SLOT_MAX}}, add,{SLOT_MAX},{SLOT_MAX}}, div,{SLOT_MAX},{SLOT_MAX}}, etc) - {NODE_VEC_OP,{SLOT_TYPE_VEC,SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // scalar vs scalar op (mul,{SLOT_MAX},{SLOT_MAX}}, add,{SLOT_MAX},{SLOT_MAX}}, div,{SLOT_MAX},{SLOT_MAX}}, etc) - {NODE_VEC_SCALAR_OP,{SLOT_TYPE_VEC,SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 vs scalar op (mul,{SLOT_MAX},{SLOT_MAX}}, add,{SLOT_MAX},{SLOT_MAX}}, div,{SLOT_MAX},{SLOT_MAX}}, etc) - {NODE_RGB_OP,{SLOT_TYPE_VEC,SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 vs scalar op (mul,{SLOT_MAX},{SLOT_MAX}}, add,{SLOT_MAX},{SLOT_MAX}}, div,{SLOT_MAX},{SLOT_MAX}}, etc) - {NODE_XFORM_MULT,{SLOT_TYPE_XFORM,SLOT_TYPE_XFORM,SLOT_MAX},{SLOT_TYPE_XFORM,SLOT_MAX}}, // mat4 x mat4 - {NODE_XFORM_VEC_MULT,{SLOT_TYPE_XFORM,SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // mat4 x vec3 mult (with no-translation option) - {NODE_XFORM_VEC_INV_MULT,{SLOT_TYPE_VEC,SLOT_TYPE_XFORM,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // mat4 x vec3 inverse mult (with no-translation option) - {NODE_SCALAR_FUNC,{SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // scalar function (sin,{SLOT_MAX},{SLOT_MAX}}, cos,{SLOT_MAX},{SLOT_MAX}}, etc) - {NODE_VEC_FUNC,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // vector function (normalize,{SLOT_MAX},{SLOT_MAX}}, negate,{SLOT_MAX},{SLOT_MAX}}, reciprocal,{SLOT_MAX},{SLOT_MAX}}, rgb2hsv,{SLOT_MAX},{SLOT_MAX}}, hsv2rgb,{SLOT_MAX},{SLOT_MAX}}, etc,{SLOT_MAX},{SLOT_MAX}}, etc) - {NODE_VEC_LEN,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // vec3 length - {NODE_DOT_PROD,{SLOT_TYPE_VEC,SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // vec3 . vec3 (dot product -> scalar output) - {NODE_VEC_TO_SCALAR,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR}}, // 1 vec3 input,{SLOT_MAX},{SLOT_MAX}}, 3 scalar outputs - {NODE_SCALAR_TO_VEC,{SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR},{SLOT_TYPE_VEC,SLOT_MAX}}, // 3 scalar input,{SLOT_MAX},{SLOT_MAX}}, 1 vec3 output - {NODE_SCALAR_INTERP,{SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // scalar interpolation (with optional curve) - {NODE_VEC_INTERP,{SLOT_TYPE_VEC,SLOT_TYPE_VEC,SLOT_TYPE_SCALAR},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 interpolation (with optional curve) - {NODE_COLOR_RAMP,{SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_TYPE_SCALAR,SLOT_MAX}}, // vec3 interpolation (with optional curve) - {NODE_CURVE_MAP,{SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // vec3 interpolation (with optional curve) - {NODE_SCALAR_INPUT,{SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // scalar uniform (assignable in material) - {NODE_VEC_INPUT,{SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 uniform (assignable in material) - {NODE_RGB_INPUT,{SLOT_MAX},{SLOT_TYPE_VEC,SLOT_TYPE_SCALAR,SLOT_MAX}}, // color uniform (assignable in material) - {NODE_XFORM_INPUT,{SLOT_MAX},{SLOT_TYPE_XFORM,SLOT_MAX}}, // mat4 uniform (assignable in material) - {NODE_TEXTURE_INPUT,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_TYPE_SCALAR,SLOT_MAX}}, // texture input (assignable in material) - {NODE_CUBEMAP_INPUT,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_TYPE_SCALAR,SLOT_MAX}}, // cubemap input (assignable in material) - {NODE_DEFAULT_TEXTURE,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_TYPE_SCALAR,SLOT_MAX}}, // cubemap input (assignable in material) - {NODE_COMMENT,{SLOT_MAX},{SLOT_MAX}}, // comment - {NODE_TYPE_MAX,{SLOT_MAX},{SLOT_MAX}} -}; - -int ShaderGraph::get_node_input_slot_count(Mode p_mode, ShaderType p_shader_type,NodeType p_type) { - - if (p_type==NODE_INPUT || p_type==NODE_OUTPUT) { - - const InOutParamInfo* iop = &inout_param_info[0]; - int pc=0; - while(iop->name) { - if (p_mode==iop->shader_mode && p_shader_type==iop->shader_type) { - - if (iop->dir==SLOT_OUT) - pc++; - } - iop++; - } - return pc; - } else if (p_type==NODE_VEC_TO_XFORM){ - return 4; - } else if (p_type==NODE_XFORM_TO_VEC){ - return 1; - } else { - - const NodeSlotInfo*nsi=&node_slot_info[0]; - while(nsi->type!=NODE_TYPE_MAX) { - - if (nsi->type==p_type) { - int pc=0; - for(int i=0;i<NodeSlotInfo::MAX_INS;i++) { - if (nsi->ins[i]==SLOT_MAX) - break; - pc++; - } - return pc; - } - - nsi++; - } - - return 0; - - } -} - -int ShaderGraph::get_node_output_slot_count(Mode p_mode, ShaderType p_shader_type,NodeType p_type){ - - if (p_type==NODE_INPUT || p_type==NODE_OUTPUT) { - - const InOutParamInfo* iop = &inout_param_info[0]; - int pc=0; - while(iop->name) { - if (p_mode==iop->shader_mode && p_shader_type==iop->shader_type) { - - if (iop->dir==SLOT_IN) - pc++; - } - iop++; - } - return pc; - } else if (p_type==NODE_VEC_TO_XFORM){ - return 1; - } else if (p_type==NODE_XFORM_TO_VEC){ - return 4; - } else { - - const NodeSlotInfo*nsi=&node_slot_info[0]; - while(nsi->type!=NODE_TYPE_MAX) { - - if (nsi->type==p_type) { - int pc=0; - for(int i=0;i<NodeSlotInfo::MAX_OUTS;i++) { - if (nsi->outs[i]==SLOT_MAX) - break; - pc++; - } - return pc; - } - - nsi++; - } - - return 0; - - } -} -ShaderGraph::SlotType ShaderGraph::get_node_input_slot_type(Mode p_mode, ShaderType p_shader_type,NodeType p_type,int p_idx){ - - if (p_type==NODE_INPUT || p_type==NODE_OUTPUT) { - - const InOutParamInfo* iop = &inout_param_info[0]; - int pc=0; - while(iop->name) { - if (p_mode==iop->shader_mode && p_shader_type==iop->shader_type) { - - if (iop->dir==SLOT_OUT) { - if (pc==p_idx) - return iop->slot_type; - pc++; - } - } - iop++; - } - ERR_FAIL_V(SLOT_MAX); - } else if (p_type==NODE_VEC_TO_XFORM){ - return SLOT_TYPE_VEC; - } else if (p_type==NODE_XFORM_TO_VEC){ - return SLOT_TYPE_XFORM; - } else { - - const NodeSlotInfo*nsi=&node_slot_info[0]; - while(nsi->type!=NODE_TYPE_MAX) { - - if (nsi->type==p_type) { - for(int i=0;i<NodeSlotInfo::MAX_INS;i++) { - - if (nsi->ins[i]==SLOT_MAX) - break; - if (i==p_idx) - return nsi->ins[i]; - } - } - - nsi++; - } - - ERR_FAIL_V(SLOT_MAX); - - } -} -ShaderGraph::SlotType ShaderGraph::get_node_output_slot_type(Mode p_mode, ShaderType p_shader_type,NodeType p_type,int p_idx){ - - if (p_type==NODE_INPUT || p_type==NODE_OUTPUT) { - - const InOutParamInfo* iop = &inout_param_info[0]; - int pc=0; - while(iop->name) { - if (p_mode==iop->shader_mode && p_shader_type==iop->shader_type) { - - if (iop->dir==SLOT_IN) { - if (pc==p_idx) - return iop->slot_type; - pc++; - } - } - iop++; - } - ERR_FAIL_V(SLOT_MAX); - } else if (p_type==NODE_VEC_TO_XFORM){ - return SLOT_TYPE_XFORM; - } else if (p_type==NODE_XFORM_TO_VEC){ - return SLOT_TYPE_VEC; - } else { - - const NodeSlotInfo*nsi=&node_slot_info[0]; - while(nsi->type!=NODE_TYPE_MAX) { - - if (nsi->type==p_type) { - for(int i=0;i<NodeSlotInfo::MAX_OUTS;i++) { - if (nsi->outs[i]==SLOT_MAX) - break; - if (i==p_idx) - return nsi->outs[i]; - } - } - - nsi++; - } - - ERR_FAIL_V(SLOT_MAX); - } -} - - - - - -void ShaderGraph::_update_shader() { - - - String code[3]; - - List<StringName> names; - get_default_texture_param_list(&names); - - for (List<StringName>::Element *E=names.front();E;E=E->next()) { - - set_default_texture_param(E->get(),Ref<Texture>()); - } - - - for(int i=0;i<3;i++) { - - int idx=0; - for (Map<int,Node>::Element *E=shader[i].node_map.front();E;E=E->next()) { - - E->get().sort_order=idx++; - } - //simple method for graph solving using bubblesort derived algorithm - int iters=0; - int iter_max=shader[i].node_map.size()*shader[i].node_map.size(); - - while(true) { - if (iters>iter_max) - break; - - int swaps=0; - for (Map<int,Node>::Element *E=shader[i].node_map.front();E;E=E->next()) { - - for(Map<int,SourceSlot>::Element *F=E->get().connections.front();F;F=F->next()) { - - //this is kinda slow, could be sped up - Map<int,Node>::Element *G = shader[i].node_map.find(F->get().id); - ERR_FAIL_COND(!G); - if (G->get().sort_order > E->get().sort_order) { - - SWAP(G->get().sort_order,E->get().sort_order); - swaps++; - } - } - } - - iters++; - if (swaps==0) { - iters=0; - break; - } - } - - if (iters>0) { - - shader[i].error=GRAPH_ERROR_CYCLIC; - continue; - } - - Vector<Node*> order; - order.resize(shader[i].node_map.size()); - - for (Map<int,Node>::Element *E=shader[i].node_map.front();E;E=E->next()) { - - order[E->get().sort_order]=&E->get(); - } - - //generate code for the ordered graph - bool failed=false; - - if (i==SHADER_TYPE_FRAGMENT && get_mode()==MODE_MATERIAL) { - code[i]+="vec3 DIFFUSE_OUT=vec3(0,0,0);\n"; - code[i]+="float ALPHA_OUT=0;\n"; - } - - - Map<String,String> inputs_xlate; - Map<String,String> input_names_xlate; - Set<String> inputs_used; - - for(int j=0;j<order.size();j++) { - - Node *n=order[j]; - if (n->type==NODE_INPUT) { - - const InOutParamInfo* iop = &inout_param_info[0]; - int idx=0; - while(iop->name) { - if (get_mode()==iop->shader_mode && i==iop->shader_type && SLOT_IN==iop->dir) { - - const char *typestr[4]={"float","vec3","mat4","texture"}; - - String vname=("nd"+itos(n->id)+"sl"+itos(idx)); - inputs_xlate[vname]=String(typestr[iop->slot_type])+" "+vname+"="+iop->variable+";\n"; - input_names_xlate[vname]=iop->variable; - idx++; - } - iop++; - } - - } else if (n->type==NODE_OUTPUT) { - - - bool use_alpha=false; - const InOutParamInfo* iop = &inout_param_info[0]; - int idx=0; - while(iop->name) { - if (get_mode()==iop->shader_mode && i==iop->shader_type && SLOT_OUT==iop->dir) { - - if (n->connections.has(idx)) { - String iname=("nd"+itos(n->connections[idx].id)+"sl"+itos(n->connections[idx].slot)); - if (node_get_type(ShaderType(i),n->connections[idx].id)==NODE_INPUT) - inputs_used.insert(iname); - code[i]+=String(iop->variable)+"="+iname+String(iop->postfix)+";\n"; - if (i==SHADER_TYPE_FRAGMENT && get_mode()==MODE_MATERIAL && String(iop->name)=="DiffuseAlpha") - use_alpha=true; - } - idx++; - } - iop++; - } - - if (i==SHADER_TYPE_FRAGMENT && get_mode()==MODE_MATERIAL) { - - if (use_alpha) { - code[i]+="DIFFUSE_ALPHA=vec4(DIFFUSE_OUT,ALPHA_OUT);\n"; - } else { - code[i]+="DIFFUSE=DIFFUSE_OUT;\n"; - } - } - - } else { - Vector<String> inputs; - int max = get_node_input_slot_count(get_mode(),ShaderType(i),n->type); - for(int k=0;k<max;k++) { - String iname; - if (!n->connections.has(k)) { - iname="nd"+itos(n->id)+"sl"+itos(k)+"def"; - } else { - iname="nd"+itos(n->connections[k].id)+"sl"+itos(n->connections[k].slot); - if (node_get_type(ShaderType(i),n->connections[k].id)==NODE_INPUT) { - inputs_used.insert(iname); - } - - } - inputs.push_back(iname); - } - - if (failed) - break; - - if (n->type==NODE_TEXTURE_INPUT || n->type==NODE_CUBEMAP_INPUT) { - - set_default_texture_param(n->param1,n->param2); - - } - _add_node_code(ShaderType(i),n,inputs,code[i]); - } - - } - - if (failed) - continue; - - - for(Set<String>::Element *E=inputs_used.front();E;E=E->next()) { - - ERR_CONTINUE( !inputs_xlate.has(E->get())); - code[i]=inputs_xlate[E->get()]+code[i]; - String name=input_names_xlate[E->get()]; - - if (i==SHADER_TYPE_VERTEX && get_mode()==MODE_MATERIAL) { - if (name==("SRC_COLOR")) - code[i]="vec3 SRC_COLOR=COLOR.rgb;\n"+code[i]; - if (name==("SRC_ALPHA")) - code[i]="float SRC_ALPHA=COLOR.a;\n"+code[i]; - if (name==("SRC_UV")) - code[i]="vec3 SRC_UV=vec3(UV,0);\n"+code[i]; - if (name==("SRC_UV2")) - code[i]="float SRC_UV2=vec3(UV2,0);\n"+code[i]; - } else if (i==SHADER_TYPE_FRAGMENT && get_mode()==MODE_MATERIAL) { - if (name==("IN_NORMAL")) - code[i]="vec3 IN_NORMAL=NORMAL;\n"+code[i]; - } else if (i==SHADER_TYPE_VERTEX && get_mode()==MODE_CANVAS_ITEM) { - if (name==("SRC_COLOR")) - code[i]="vec3 SRC_COLOR=COLOR.rgb;\n"+code[i]; - if (name==("SRC_UV")) - code[i]="vec3 SRC_UV=vec3(UV,0);\n"+code[i]; - } - - } - - - - shader[i].error=GRAPH_OK; - - } - - bool all_ok=true; - for(int i=0;i<3;i++) { - if (shader[i].error!=GRAPH_OK) - all_ok=false; - } - - /*print_line("VERTEX: \n"+code[0]); - print_line("FRAGMENT: \n"+code[1]); - print_line("LIGHT: \n"+code[2]);*/ - - if (all_ok) { - set_code(code[0],code[1],code[2]); - } - //do shader here - - _pending_update_shader=false; - emit_signal(SceneStringNames::get_singleton()->updated); -} - -void ShaderGraph::_plot_curve(const Vector2& p_a,const Vector2& p_b,const Vector2& p_c,const Vector2& p_d,uint8_t* p_heights,bool *p_useds) { - - float geometry[4][4]; - float tmp1[4][4]; - float tmp2[4][4]; - float deltas[4][4]; - double x, dx, dx2, dx3; - double y, dy, dy2, dy3; - double d, d2, d3; - int lastx, lasty; - int newx, newy; - int ntimes; - int i,j; - - int xmax=255; - int ymax=255; - - /* construct the geometry matrix from the segment */ - for (i = 0; i < 4; i++) { - geometry[i][2] = 0; - geometry[i][3] = 0; - } - - geometry[0][0] = (p_a[0] * xmax); - geometry[1][0] = (p_b[0] * xmax); - geometry[2][0] = (p_c[0] * xmax); - geometry[3][0] = (p_d[0] * xmax); - - geometry[0][1] = (p_a[1] * ymax); - geometry[1][1] = (p_b[1] * ymax); - geometry[2][1] = (p_c[1] * ymax); - geometry[3][1] = (p_d[1] * ymax); - - /* subdivide the curve ntimes (1000) times */ - ntimes = 4 * xmax; - /* ntimes can be adjusted to give a finer or coarser curve */ - d = 1.0 / ntimes; - d2 = d * d; - d3 = d * d * d; - - /* construct a temporary matrix for determining the forward differencing deltas */ - tmp2[0][0] = 0; tmp2[0][1] = 0; tmp2[0][2] = 0; tmp2[0][3] = 1; - tmp2[1][0] = d3; tmp2[1][1] = d2; tmp2[1][2] = d; tmp2[1][3] = 0; - tmp2[2][0] = 6*d3; tmp2[2][1] = 2*d2; tmp2[2][2] = 0; tmp2[2][3] = 0; - tmp2[3][0] = 6*d3; tmp2[3][1] = 0; tmp2[3][2] = 0; tmp2[3][3] = 0; - - /* compose the basis and geometry matrices */ - - static const float CR_basis[4][4] = { - { -0.5, 1.5, -1.5, 0.5 }, - { 1.0, -2.5, 2.0, -0.5 }, - { -0.5, 0.0, 0.5, 0.0 }, - { 0.0, 1.0, 0.0, 0.0 }, - }; - - for (i = 0; i < 4; i++) - { - for (j = 0; j < 4; j++) - { - tmp1[i][j] = (CR_basis[i][0] * geometry[0][j] + - CR_basis[i][1] * geometry[1][j] + - CR_basis[i][2] * geometry[2][j] + - CR_basis[i][3] * geometry[3][j]); - } - } - /* compose the above results to get the deltas matrix */ - - for (i = 0; i < 4; i++) - { - for (j = 0; j < 4; j++) - { - deltas[i][j] = (tmp2[i][0] * tmp1[0][j] + - tmp2[i][1] * tmp1[1][j] + - tmp2[i][2] * tmp1[2][j] + - tmp2[i][3] * tmp1[3][j]); - } - } - - - /* extract the x deltas */ - x = deltas[0][0]; - dx = deltas[1][0]; - dx2 = deltas[2][0]; - dx3 = deltas[3][0]; - - /* extract the y deltas */ - y = deltas[0][1]; - dy = deltas[1][1]; - dy2 = deltas[2][1]; - dy3 = deltas[3][1]; - - - lastx = CLAMP (x, 0, xmax); - lasty = CLAMP (y, 0, ymax); - - p_heights[lastx] = lasty; - p_useds[lastx] = true; - - /* loop over the curve */ - for (i = 0; i < ntimes; i++) - { - /* increment the x values */ - x += dx; - dx += dx2; - dx2 += dx3; - - /* increment the y values */ - y += dy; - dy += dy2; - dy2 += dy3; - - newx = CLAMP ((Math::round (x)), 0, xmax); - newy = CLAMP ((Math::round (y)), 0, ymax); - - /* if this point is different than the last one...then draw it */ - if ((lastx != newx) || (lasty != newy)) - { - p_useds[newx]=true; - p_heights[newx]=newy; - } - - lastx = newx; - lasty = newy; - } -} - - -void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<String>& p_inputs,String& code) { - - - const char *typestr[4]={"float","vec3","mat4","texture"}; -#define OUTNAME(id, slot) (String(typestr[get_node_output_slot_type(get_mode(), p_type, p_node->type, slot)]) + " " + ("nd" + itos(id) + "sl" + itos(slot))) -#define OUTVAR(id, slot) ("nd" + itos(id) + "sl" + itos(slot)) -#define DEF_VEC(slot) \ - if (p_inputs[slot].ends_with("def")) { \ - Vector3 v = p_node->defaults[slot]; \ - code += String(typestr[1]) + " " + p_inputs[slot] + "=vec3(" + v + ");\n"; \ - } -#define DEF_SCALAR(slot) \ - if (p_inputs[slot].ends_with("def")) { \ - double v = p_node->defaults[slot]; \ - code += String(typestr[0]) + " " + p_inputs[slot] + "=" + rtos(v) + ";\n"; \ - } -#define DEF_COLOR(slot) \ - if (p_inputs[slot].ends_with("def")) { \ - Color col = p_node->defaults[slot]; \ - code += String(typestr[1]) + " " + p_inputs[slot] + "=vec3(" + rtos(col.r) + "," + rtos(col.g) + "," + rtos(col.b) + ");\n"; \ - } -#define DEF_MATRIX(slot) \ - if (p_inputs[slot].ends_with("def")) { \ - Transform xf = p_node->defaults[slot]; \ - code += String(typestr[2]) + " " + p_inputs[slot] + "=mat4(\n"; \ - code += "\tvec4(vec3(" + rtos(xf.basis.get_axis(0).x) + "," + rtos(xf.basis.get_axis(0).y) + "," + rtos(xf.basis.get_axis(0).z) + "),0),\n"; \ - code += "\tvec4(vec3(" + rtos(xf.basis.get_axis(1).x) + "," + rtos(xf.basis.get_axis(1).y) + "," + rtos(xf.basis.get_axis(1).z) + "),0),\n"; \ - code += "\tvec4(vec3(" + rtos(xf.basis.get_axis(2).x) + "," + rtos(xf.basis.get_axis(2).y) + "," + rtos(xf.basis.get_axis(2).z) + "),0),\n"; \ - code += "\tvec4(vec3(" + rtos(xf.origin.x) + "," + rtos(xf.origin.y) + "," + rtos(xf.origin.z) + "),1)\n"; \ - code += ");\n"; \ - } - - switch(p_node->type) { - - case NODE_INPUT: { - - - }break; - case NODE_SCALAR_CONST: { - - double scalar = p_node->param1; - code+=OUTNAME(p_node->id,0)+"="+rtos(scalar)+";\n"; - }break; - case NODE_VEC_CONST: { - Vector3 vec = p_node->param1; - code+=OUTNAME(p_node->id,0)+"=vec3("+rtos(vec.x)+","+rtos(vec.y)+","+rtos(vec.z)+");\n"; - }break; - case NODE_RGB_CONST: { - Color col = p_node->param1; - code+=OUTNAME(p_node->id,0)+"=vec3("+rtos(col.r)+","+rtos(col.g)+","+rtos(col.b)+");\n"; - code+=OUTNAME(p_node->id,1)+"="+rtos(col.a)+";\n"; - }break; - case NODE_XFORM_CONST: { - - Transform xf = p_node->param1; - code+=OUTNAME(p_node->id,0)+"=mat4(\n"; - code+="\tvec4(vec3("+rtos(xf.basis.get_axis(0).x)+","+rtos(xf.basis.get_axis(0).y)+","+rtos(xf.basis.get_axis(0).z)+"),0),\n"; - code+="\tvec4(vec3("+rtos(xf.basis.get_axis(1).x)+","+rtos(xf.basis.get_axis(1).y)+","+rtos(xf.basis.get_axis(1).z)+"),0),\n"; - code+="\tvec4(vec3("+rtos(xf.basis.get_axis(2).x)+","+rtos(xf.basis.get_axis(2).y)+","+rtos(xf.basis.get_axis(2).z)+"),0),\n"; - code+="\tvec4(vec3("+rtos(xf.origin.x)+","+rtos(xf.origin.y)+","+rtos(xf.origin.z)+"),1)\n"; - code+=");"; - - }break; - case NODE_TIME: { - code+=OUTNAME(p_node->id,0)+"=TIME;\n"; - }break; - case NODE_SCREEN_TEX: { - DEF_VEC(0); - code+=OUTNAME(p_node->id,0)+"=texscreen("+p_inputs[0]+".xy);\n"; - }break; - case NODE_SCALAR_OP: { - DEF_SCALAR(0); - DEF_SCALAR(1); - int op = p_node->param1; - String optxt; - switch(op) { - - case SCALAR_OP_ADD: optxt = p_inputs[0]+"+"+p_inputs[1]+";"; break; - case SCALAR_OP_SUB: optxt = p_inputs[0]+"-"+p_inputs[1]+";"; break; - case SCALAR_OP_MUL: optxt = p_inputs[0]+"*"+p_inputs[1]+";"; break; - case SCALAR_OP_DIV: optxt = p_inputs[0]+"/"+p_inputs[1]+";"; break; - case SCALAR_OP_MOD: optxt = "mod("+p_inputs[0]+","+p_inputs[1]+");"; break; - case SCALAR_OP_POW: optxt = "pow("+p_inputs[0]+","+p_inputs[1]+");"; break; - case SCALAR_OP_MAX: optxt = "max("+p_inputs[0]+","+p_inputs[1]+");"; break; - case SCALAR_OP_MIN: optxt = "min("+p_inputs[0]+","+p_inputs[1]+");"; break; - case SCALAR_OP_ATAN2: optxt = "atan2("+p_inputs[0]+","+p_inputs[1]+");"; break; - - } - code+=OUTNAME(p_node->id,0)+"="+optxt+"\n"; - - }break; - case NODE_VEC_OP: { - DEF_VEC(0); - DEF_VEC(1); - int op = p_node->param1; - String optxt; - switch(op) { - case VEC_OP_ADD: optxt = p_inputs[0]+"+"+p_inputs[1]+";"; break; - case VEC_OP_SUB: optxt = p_inputs[0]+"-"+p_inputs[1]+";"; break; - case VEC_OP_MUL: optxt = p_inputs[0]+"*"+p_inputs[1]+";"; break; - case VEC_OP_DIV: optxt = p_inputs[0]+"/"+p_inputs[1]+";"; break; - case VEC_OP_MOD: optxt = "mod("+p_inputs[0]+","+p_inputs[1]+");"; break; - case VEC_OP_POW: optxt = "pow("+p_inputs[0]+","+p_inputs[1]+");"; break; - case VEC_OP_MAX: optxt = "max("+p_inputs[0]+","+p_inputs[1]+");"; break; - case VEC_OP_MIN: optxt = "min("+p_inputs[0]+","+p_inputs[1]+");"; break; - case VEC_OP_CROSS: optxt = "cross("+p_inputs[0]+","+p_inputs[1]+");"; break; - } - code+=OUTNAME(p_node->id,0)+"="+optxt+"\n"; - - }break; - case NODE_VEC_SCALAR_OP: { - DEF_VEC(0); - DEF_SCALAR(1); - int op = p_node->param1; - String optxt; - switch(op) { - case VEC_SCALAR_OP_MUL: optxt = p_inputs[0]+"*"+p_inputs[1]+";"; break; - case VEC_SCALAR_OP_DIV: optxt = p_inputs[0]+"/"+p_inputs[1]+";"; break; - case VEC_SCALAR_OP_POW: optxt = "pow("+p_inputs[0]+","+p_inputs[1]+");"; break; - } - code+=OUTNAME(p_node->id,0)+"="+optxt+"\n"; - - }break; - case NODE_RGB_OP: { - DEF_COLOR(0); - DEF_COLOR(1); - - int op = p_node->param1; - static const char*axisn[3]={"x","y","z"}; - switch(op) { - case RGB_OP_SCREEN: { - - code += OUTNAME(p_node->id,0)+"=vec3(1.0)-(vec3(1.0)-"+p_inputs[0]+")*(vec3(1.0)-"+p_inputs[1]+");\n"; - } break; - case RGB_OP_DIFFERENCE: { - - code += OUTNAME(p_node->id,0)+"=abs("+p_inputs[0]+"-"+p_inputs[1]+");\n"; - } break; - case RGB_OP_DARKEN: { - - code += OUTNAME(p_node->id,0)+"=min("+p_inputs[0]+","+p_inputs[1]+");\n"; - } break; - case RGB_OP_LIGHTEN: { - - code += OUTNAME(p_node->id,0)+"=max("+p_inputs[0]+","+p_inputs[1]+");\n"; - - } break; - case RGB_OP_OVERLAY: { - - code += OUTNAME(p_node->id,0)+";\n"; - for(int i=0;i<3;i++) { - code += "{\n"; - code += "\tfloat base="+p_inputs[0]+"."+axisn[i]+";\n"; - code += "\tfloat blend="+p_inputs[1]+"."+axisn[i]+";\n"; - code += "\tif (base < 0.5) {\n"; - code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = 2.0 * base * blend;\n"; - code += "\t} else {\n"; - code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = 1.0 - 2.0 * (1.0 - blend) * (1.0 - base);\n"; - code += "\t}\n"; - code += "}\n"; - } - - } break; - case RGB_OP_DODGE: { - - code += OUTNAME(p_node->id,0)+"=("+p_inputs[0]+")/(vec3(1.0)-"+p_inputs[1]+");\n"; - - } break; - case RGB_OP_BURN: { - - code += OUTNAME(p_node->id,0)+"=vec3(1.0)-(vec3(1.0)-"+p_inputs[0]+")/("+p_inputs[1]+");\n"; - } break; - case RGB_OP_SOFT_LIGHT: { - - code += OUTNAME(p_node->id,0)+";\n"; - for(int i=0;i<3;i++) { - code += "{\n"; - code += "\tfloat base="+p_inputs[0]+"."+axisn[i]+";\n"; - code += "\tfloat blend="+p_inputs[1]+"."+axisn[i]+";\n"; - code += "\tif (base < 0.5) {\n"; - code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = (base * (blend+0.5));\n"; - code += "\t} else {\n"; - code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = (1 - (1-base) * (1-(blend-0.5)));\n"; - code += "\t}\n"; - code += "}\n"; - } - - } break; - case RGB_OP_HARD_LIGHT: { - - code += OUTNAME(p_node->id,0)+";\n"; - for(int i=0;i<3;i++) { - code += "{\n"; - code += "\tfloat base="+p_inputs[0]+"."+axisn[i]+";\n"; - code += "\tfloat blend="+p_inputs[1]+"."+axisn[i]+";\n"; - code += "\tif (base < 0.5) {\n"; - code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = (base * (2*blend));\n"; - code += "\t} else {\n"; - code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = (1 - (1-base) * (1-2*(blend-0.5)));\n"; - code += "\t}\n"; - code += "}\n"; - } - - } break; - } - }break; - case NODE_XFORM_MULT: { - DEF_MATRIX(0); - DEF_MATRIX(1); - - code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+"*"+p_inputs[1]+";\n"; - - }break; - case NODE_XFORM_VEC_MULT: { - DEF_MATRIX(0); - DEF_VEC(1); - - bool no_translation = p_node->param1; - if (no_translation) { - code += OUTNAME(p_node->id,0)+"=("+p_inputs[0]+"*vec4("+p_inputs[1]+",0)).xyz;\n"; - } else { - code += OUTNAME(p_node->id,0)+"=("+p_inputs[0]+"*vec4("+p_inputs[1]+",1)).xyz;\n"; - } - - }break; - case NODE_XFORM_VEC_INV_MULT: { - DEF_VEC(0); - DEF_MATRIX(1); - bool no_translation = p_node->param1; - if (no_translation) { - code += OUTNAME(p_node->id,0)+"=("+p_inputs[1]+"*vec4("+p_inputs[0]+",0)).xyz;\n"; - } else { - code += OUTNAME(p_node->id,0)+"=("+p_inputs[1]+"*vec4("+p_inputs[0]+",1)).xyz;\n"; - } - }break; - case NODE_SCALAR_FUNC: { - DEF_SCALAR(0); - static const char*scalar_func_id[SCALAR_MAX_FUNC]={ - "sin($)", - "cos($)", - "tan($)", - "asin($)", - "acos($)", - "atan($)", - "sinh($)", - "cosh($)", - "tanh($)", - "log($)", - "exp($)", - "sqrt($)", - "abs($)", - "sign($)", - "floor($)", - "round($)", - "ceil($)", - "fract($)", - "min(max($,0),1)", - "-($)", - }; - - int func = p_node->param1; - ERR_FAIL_INDEX(func,SCALAR_MAX_FUNC); - code += OUTNAME(p_node->id,0)+"="+String(scalar_func_id[func]).replace("$",p_inputs[0])+";\n"; - - } break; - case NODE_VEC_FUNC: { - DEF_VEC(0); - static const char*vec_func_id[VEC_MAX_FUNC]={ - "normalize($)", - "max(min($,vec3(1,1,1)),vec3(0,0,0))", - "-($)", - "1.0/($)", - "", - "", - }; - - - int func = p_node->param1; - ERR_FAIL_INDEX(func,VEC_MAX_FUNC); - if (func==VEC_FUNC_RGB2HSV) { - code += OUTNAME(p_node->id,0)+";\n"; - code+="{\n"; - code+="\tvec3 c = "+p_inputs[0]+";\n"; - code+="\tvec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n"; - code+="\tvec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n"; - code+="\tvec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n"; - code+="\tfloat d = q.x - min(q.w, q.y);\n"; - code+="\tfloat e = 1.0e-10;\n"; - code+="\t"+OUTVAR(p_node->id,0)+"=vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n"; - code+="}\n"; - } else if (func==VEC_FUNC_HSV2RGB) { - code += OUTNAME(p_node->id,0)+";\n"; - code+="{\n"; - code+="\tvec3 c = "+p_inputs[0]+";\n"; - code+="\tvec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n"; - code+="\tvec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n"; - code+="\t"+OUTVAR(p_node->id,0)+"=c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n"; - code+="}\n"; - - } else { - code += OUTNAME(p_node->id,0)+"="+String(vec_func_id[func]).replace("$",p_inputs[0])+";\n"; - } - }break; - case NODE_VEC_LEN: { - DEF_VEC(0); - - code += OUTNAME(p_node->id,0)+"=length("+p_inputs[0]+");\n"; - - }break; - case NODE_DOT_PROD: { - DEF_VEC(0); - DEF_VEC(1); - code += OUTNAME(p_node->id,0)+"=dot("+p_inputs[1]+","+p_inputs[0]+");\n"; - - }break; - case NODE_VEC_TO_SCALAR: { - DEF_VEC(0); - code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+".x;\n"; - code += OUTNAME(p_node->id,1)+"="+p_inputs[0]+".y;\n"; - code += OUTNAME(p_node->id,2)+"="+p_inputs[0]+".z;\n"; - - }break; - case NODE_SCALAR_TO_VEC: { - DEF_SCALAR(0); - DEF_SCALAR(1); - DEF_SCALAR(2); - code += OUTNAME(p_node->id,0)+"=vec3("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+""+");\n"; - - }break; - case NODE_VEC_TO_XFORM: { - DEF_VEC(0); - DEF_VEC(1); - DEF_VEC(2); - DEF_VEC(3); - code += OUTNAME(p_node->id, 0) + "=mat4(" + - "vec4(" + p_inputs[0] + ".x," + p_inputs[0] + ".y," + p_inputs[0] + ".z, 0.0)," - "vec4(" + p_inputs[1] + ".x," + p_inputs[1] + ".y," + p_inputs[1] + ".z, 0.0)," - "vec4(" + p_inputs[2] + ".x," + p_inputs[2] + ".y," + p_inputs[2] + ".z, 0.0)," - "vec4(" + p_inputs[3] + ".x," + p_inputs[3] + ".y," + p_inputs[3] + ".z, 1.0));\n"; - - }break; - case NODE_XFORM_TO_VEC: { - DEF_MATRIX(0); - code += OUTNAME(p_node->id, 0) + ";\n"; - code += OUTNAME(p_node->id, 1) + ";\n"; - code += OUTNAME(p_node->id, 2) + ";\n"; - code += OUTNAME(p_node->id, 3) + ";\n"; - code += "{\n"; - code += "\tvec4 xform_row_01=" + p_inputs[0] + ".x;\n"; - code += "\tvec4 xform_row_02=" + p_inputs[0] + ".y;\n"; - code += "\tvec4 xform_row_03=" + p_inputs[0] + ".z;\n"; - code += "\tvec4 xform_row_04=" + p_inputs[0] + ".w;\n"; - code += "\t" + OUTVAR(p_node->id, 0) + "=vec3(xform_row_01.x, xform_row_01.y, xform_row_01.z);\n"; - code += "\t" + OUTVAR(p_node->id, 1) + "=vec3(xform_row_02.x, xform_row_02.y, xform_row_02.z);\n"; - code += "\t" + OUTVAR(p_node->id, 2) + "=vec3(xform_row_03.x, xform_row_03.y, xform_row_03.z);\n"; - code += "\t" + OUTVAR(p_node->id, 3) + "=vec3(xform_row_04.x, xform_row_04.y, xform_row_04.z);\n"; - code += "}\n"; - }break; - case NODE_SCALAR_INTERP: { - DEF_SCALAR(0); - DEF_SCALAR(1); - DEF_SCALAR(2); - - code += OUTNAME(p_node->id,0)+"=mix("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+");\n"; - - }break; - case NODE_VEC_INTERP: { - DEF_VEC(0); - DEF_VEC(1); - DEF_SCALAR(2); - code += OUTNAME(p_node->id,0)+"=mix("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+");\n"; - - }break; - case NODE_COLOR_RAMP: { - DEF_SCALAR(0); - - static const int color_ramp_len=512; - PoolVector<uint8_t> cramp; - cramp.resize(color_ramp_len*4); - { - - PoolVector<Color> colors=p_node->param1; - PoolVector<real_t> offsets=p_node->param2; - int cc =colors.size(); - PoolVector<uint8_t>::Write crw = cramp.write(); - PoolVector<Color>::Read cr = colors.read(); - PoolVector<real_t>::Read ofr = offsets.read(); - - int at=0; - Color color_at(0,0,0,1); - for(int i=0;i<=cc;i++) { - - int pos; - Color to; - if (i==cc) { - if (at==color_ramp_len) - break; - pos=color_ramp_len; - to=Color(1,1,1,1); - } else { - to=cr[i]; - pos= MIN(ofr[i]*color_ramp_len,color_ramp_len); - } - for(int j=at;j<pos;j++) { - float t = (j-at)/float(pos-at); - Color c = color_at.linear_interpolate(to,t); - crw[j*4+0]=Math::fast_ftoi( CLAMP(c.r*255.0,0,255) ); - crw[j*4+1]=Math::fast_ftoi( CLAMP(c.g*255.0,0,255) ); - crw[j*4+2]=Math::fast_ftoi( CLAMP(c.b*255.0,0,255) ); - crw[j*4+3]=Math::fast_ftoi( CLAMP(c.a*255.0,0,255) ); - } - - at=pos; - color_at=to; - } - } - - Image gradient(color_ramp_len,1,0,Image::FORMAT_RGBA8,cramp); - Ref<ImageTexture> it = memnew( ImageTexture ); - it->create_from_image(gradient,Texture::FLAG_FILTER|Texture::FLAG_MIPMAPS); - - String crampname= "cramp_"+itos(p_node->id); - set_default_texture_param(crampname,it); - - code +="uniform texture "+crampname+";\n"; - code +="vec4 "+crampname+"_r=tex("+crampname+",vec2("+p_inputs[0]+",0));\n"; - code += OUTNAME(p_node->id,0)+"="+crampname+"_r.rgb;\n"; - code += OUTNAME(p_node->id,1)+"="+crampname+"_r.a;\n"; - - }break; - case NODE_CURVE_MAP: { - DEF_SCALAR(0); - static const int curve_map_len=256; - bool mapped[256]; - zeromem(mapped,sizeof(mapped)); - PoolVector<uint8_t> cmap; - cmap.resize(curve_map_len); - { - - PoolVector<Point2> points=p_node->param1; - int pc =points.size(); - PoolVector<uint8_t>::Write cmw = cmap.write(); - PoolVector<Point2>::Read pr = points.read(); - - Vector2 prev=Vector2(0,0); - Vector2 prev2=Vector2(0,0); - - for(int i=-1;i<pc;i++) { - - Vector2 next; - Vector2 next2; - if (i+1>=pc) { - next=Vector2(1,1); - } else { - next=Vector2(pr[i+1].x,pr[i+1].y); - } - - if (i+2>=pc) { - next2=Vector2(1,1); - } else { - next2=Vector2(pr[i+2].x,pr[i+2].y); - } - - /*if (i==-1 && prev.offset==next.offset) { - prev=next; - continue; - }*/ - - _plot_curve(prev2,prev,next,next2,cmw.ptr(),mapped); - - prev2=prev; - prev=next; - } - - uint8_t pp=0; - for(int i=0;i<curve_map_len;i++) { - - if (!mapped[i]) { - cmw[i]=pp; - } else { - pp=cmw[i]; - } - } - } - - - - Image gradient(curve_map_len,1,0,Image::FORMAT_L8,cmap); - Ref<ImageTexture> it = memnew( ImageTexture ); - it->create_from_image(gradient,Texture::FLAG_FILTER|Texture::FLAG_MIPMAPS); - - String cmapname= "cmap_"+itos(p_node->id); - set_default_texture_param(cmapname,it); - - code +="uniform texture "+cmapname+";\n"; - code += OUTNAME(p_node->id,0)+"=tex("+cmapname+",vec2("+p_inputs[0]+",0)).r;\n"; - - }break; - case NODE_SCALAR_INPUT: { - String name = p_node->param1; - float dv=p_node->param2; - code +="uniform float "+name+"="+rtos(dv)+";\n"; - code += OUTNAME(p_node->id,0)+"="+name+";\n"; - }break; - case NODE_VEC_INPUT: { - - String name = p_node->param1; - Vector3 dv=p_node->param2; - code +="uniform vec3 "+name+"=vec3("+rtos(dv.x)+","+rtos(dv.y)+","+rtos(dv.z)+");\n"; - code += OUTNAME(p_node->id,0)+"="+name+";\n"; - }break; - case NODE_RGB_INPUT: { - - String name = p_node->param1; - Color dv= p_node->param2; - - code +="uniform color "+name+"=vec4("+rtos(dv.r)+","+rtos(dv.g)+","+rtos(dv.b)+","+rtos(dv.a)+");\n"; - code += OUTNAME(p_node->id,0)+"="+name+".rgb;\n"; - code += OUTNAME(p_node->id,1)+"="+name+".a;\n"; - - }break; - case NODE_XFORM_INPUT: { - - String name = p_node->param1; - Transform dv= p_node->param2; - - code +="uniform mat4 "+name+"=mat4(\n"; - code+="\tvec4(vec3("+rtos(dv.basis.get_axis(0).x)+","+rtos(dv.basis.get_axis(0).y)+","+rtos(dv.basis.get_axis(0).z)+"),0),\n"; - code+="\tvec4(vec3("+rtos(dv.basis.get_axis(1).x)+","+rtos(dv.basis.get_axis(1).y)+","+rtos(dv.basis.get_axis(1).z)+"),0),\n"; - code+="\tvec4(vec3("+rtos(dv.basis.get_axis(2).x)+","+rtos(dv.basis.get_axis(2).y)+","+rtos(dv.basis.get_axis(2).z)+"),0),\n"; - code+="\tvec4(vec3("+rtos(dv.origin.x)+","+rtos(dv.origin.y)+","+rtos(dv.origin.z)+"),1)\n"; - code+=");"; - - code += OUTNAME(p_node->id,0)+"="+name+";\n"; - - }break; - case NODE_TEXTURE_INPUT: { - DEF_VEC(0); - String name = p_node->param1; - String rname="rt_read_tex"+itos(p_node->id); - code +="uniform texture "+name+";"; - code +="vec4 "+rname+"=tex("+name+","+p_inputs[0]+".xy);\n"; - code += OUTNAME(p_node->id,0)+"="+rname+".rgb;\n"; - code += OUTNAME(p_node->id,1)+"="+rname+".a;\n"; - - }break; - case NODE_CUBEMAP_INPUT: { - DEF_VEC(0); - String name = p_node->param1; - code +="uniform cubemap "+name+";"; - String rname="rt_read_tex"+itos(p_node->id); - code +="vec4 "+rname+"=texcube("+name+","+p_inputs[0]+".xy);\n"; - code += OUTNAME(p_node->id,0)+"="+rname+".rgb;\n"; - code += OUTNAME(p_node->id,1)+"="+rname+".a;\n"; - }break; - case NODE_DEFAULT_TEXTURE: { - DEF_VEC(0); - - if (get_mode()==MODE_CANVAS_ITEM && p_type==SHADER_TYPE_FRAGMENT) { - - String rname="rt_default_tex"+itos(p_node->id); - code +="vec4 "+rname+"=tex(TEXTURE,"+p_inputs[0]+".xy);\n"; - code += OUTNAME(p_node->id,0)+"="+rname+".rgb;\n"; - code += OUTNAME(p_node->id,1)+"="+rname+".a;\n"; - - } else { - //not supported - code += OUTNAME(p_node->id,0)+"=vec3(0,0,0);\n"; - code += OUTNAME(p_node->id,1)+"=1.0;\n"; - - } - } break; - case NODE_OUTPUT: { - - - }break; - case NODE_COMMENT: { - - }break; - case NODE_TYPE_MAX: { - - } - } -#undef DEF_SCALAR -#undef DEF_COLOR -#undef DEF_MATRIX -#undef DEF_VEC -} - -#endif diff --git a/scene/resources/shader_graph.h b/scene/resources/shader_graph.h deleted file mode 100644 index e3a68f8572..0000000000 --- a/scene/resources/shader_graph.h +++ /dev/null @@ -1,446 +0,0 @@ -/*************************************************************************/ -/* shader_graph.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef SHADER_GRAPH_H -#define SHADER_GRAPH_H - -// FIXME: Needs to be ported to the new 3.0 shader API -#if 0 -#include "map.h" -#include "scene/resources/shader.h" - -class ShaderGraph : public Shader { - - GDCLASS( ShaderGraph, Shader ); - RES_BASE_EXTENSION("vshader"); - -public: - - enum NodeType { - NODE_INPUT, // all inputs (shader type dependent) - NODE_SCALAR_CONST, //scalar constant - NODE_VEC_CONST, //vec3 constant - NODE_RGB_CONST, //rgb constant (shows a color picker instead) - NODE_XFORM_CONST, // 4x4 matrix constant - NODE_TIME, // time in seconds - NODE_SCREEN_TEX, // screen texture sampler (takes UV) (only usable in fragment shader) - NODE_SCALAR_OP, // scalar vs scalar op (mul, add, div, etc) - NODE_VEC_OP, // vec3 vs vec3 op (mul,ad,div,crossprod,etc) - NODE_VEC_SCALAR_OP, // vec3 vs scalar op (mul, add, div, etc) - NODE_RGB_OP, // vec3 vs vec3 rgb op (with scalar amount), like brighten, darken, burn, dodge, multiply, etc. - NODE_XFORM_MULT, // mat4 x mat4 - NODE_XFORM_VEC_MULT, // mat4 x vec3 mult (with no-translation option) - NODE_XFORM_VEC_INV_MULT, // mat4 x vec3 inverse mult (with no-translation option) - NODE_SCALAR_FUNC, // scalar function (sin, cos, etc) - NODE_VEC_FUNC, // vector function (normalize, negate, reciprocal, rgb2hsv, hsv2rgb, etc, etc) - NODE_VEC_LEN, // vec3 length - NODE_DOT_PROD, // vec3 . vec3 (dot product -> scalar output) - NODE_VEC_TO_SCALAR, // 1 vec3 input, 3 scalar outputs - NODE_SCALAR_TO_VEC, // 3 scalar input, 1 vec3 output - NODE_XFORM_TO_VEC, // 3 vec input, 1 xform output - NODE_VEC_TO_XFORM, // 3 vec input, 1 xform output - NODE_SCALAR_INTERP, // scalar interpolation (with optional curve) - NODE_VEC_INTERP, // vec3 interpolation (with optional curve) - NODE_COLOR_RAMP, //take scalar, output vec3 - NODE_CURVE_MAP, //take scalar, otput scalar - NODE_SCALAR_INPUT, // scalar uniform (assignable in material) - NODE_VEC_INPUT, // vec3 uniform (assignable in material) - NODE_RGB_INPUT, // color uniform (assignable in material) - NODE_XFORM_INPUT, // mat4 uniform (assignable in material) - NODE_TEXTURE_INPUT, // texture input (assignable in material) - NODE_CUBEMAP_INPUT, // cubemap input (assignable in material) - NODE_DEFAULT_TEXTURE, - NODE_OUTPUT, // output (shader type dependent) - NODE_COMMENT, // comment - NODE_TYPE_MAX - }; - - - struct Connection { - - int src_id; - int src_slot; - int dst_id; - int dst_slot; - }; - - enum SlotType { - - SLOT_TYPE_SCALAR, - SLOT_TYPE_VEC, - SLOT_TYPE_XFORM, - SLOT_TYPE_TEXTURE, - SLOT_MAX - }; - - enum ShaderType { - SHADER_TYPE_VERTEX, - SHADER_TYPE_FRAGMENT, - SHADER_TYPE_LIGHT, - SHADER_TYPE_MAX - }; - - enum SlotDir { - SLOT_IN, - SLOT_OUT - }; - - enum GraphError { - GRAPH_OK, - GRAPH_ERROR_CYCLIC, - GRAPH_ERROR_MISSING_CONNECTIONS - }; - -private: - - String _find_unique_name(const String& p_base); - - enum {SLOT_DEFAULT_VALUE = 0x7FFFFFFF}; - struct SourceSlot { - - int id; - int slot; - bool operator==(const SourceSlot& p_slot) const { - return id==p_slot.id && slot==p_slot.slot; - } - }; - - struct Node { - - Vector2 pos; - NodeType type; - Variant param1; - Variant param2; - Map<int, Variant> defaults; - int id; - mutable int order; // used for sorting - int sort_order; - Map<int,SourceSlot> connections; - - }; - - struct ShaderData { - Map<int,Node> node_map; - GraphError error; - } shader[3]; - - - - struct InOutParamInfo { - Mode shader_mode; - ShaderType shader_type; - const char *name; - const char *variable; - const char *postfix; - SlotType slot_type; - SlotDir dir; - }; - - static const InOutParamInfo inout_param_info[]; - - struct NodeSlotInfo { - - enum { MAX_INS=3, MAX_OUTS=3 }; - NodeType type; - const SlotType ins[MAX_INS]; - const SlotType outs[MAX_OUTS]; - }; - - static const NodeSlotInfo node_slot_info[]; - - bool _pending_update_shader; - void _update_shader(); - void _request_update(); - - void _plot_curve(const Vector2& p_a,const Vector2& p_b,const Vector2& p_c,const Vector2& p_d,uint8_t* p_heights,bool *p_useds); - void _add_node_code(ShaderType p_type,Node *p_node,const Vector<String>& p_inputs,String& code); - - Array _get_node_list(ShaderType p_type) const; - Array _get_connections(ShaderType p_type) const; - - void _set_data(const Dictionary& p_data); - Dictionary _get_data() const; -protected: - - static void _bind_methods(); - -public: - - - void node_add(ShaderType p_type, NodeType p_node_type, int p_id); - void node_remove(ShaderType p_which,int p_id); - void node_set_position(ShaderType p_which,int p_id,const Point2& p_pos); - Point2 node_get_position(ShaderType p_which,int p_id) const; - - void get_node_list(ShaderType p_which,List<int> *p_node_list) const; - NodeType node_get_type(ShaderType p_which,int p_id) const; - - void scalar_const_node_set_value(ShaderType p_which,int p_id,float p_value); - float scalar_const_node_get_value(ShaderType p_which,int p_id) const; - - void vec_const_node_set_value(ShaderType p_which,int p_id,const Vector3& p_value); - Vector3 vec_const_node_get_value(ShaderType p_which,int p_id) const; - - void rgb_const_node_set_value(ShaderType p_which,int p_id,const Color& p_value); - Color rgb_const_node_get_value(ShaderType p_which,int p_id) const; - - void xform_const_node_set_value(ShaderType p_which,int p_id,const Transform& p_value); - Transform xform_const_node_get_value(ShaderType p_which,int p_id) const; - - void texture_node_set_filter_size(ShaderType p_which,int p_id,int p_size); - int texture_node_get_filter_size(ShaderType p_which,int p_id) const; - - void texture_node_set_filter_strength(ShaderType p_which,float p_id,float p_strength); - float texture_node_get_filter_strength(ShaderType p_which,float p_id) const; - - void duplicate_nodes(ShaderType p_which, List<int> &p_nodes); - - List<int> generate_ids(ShaderType p_type, int count); - - enum ScalarOp { - SCALAR_OP_ADD, - SCALAR_OP_SUB, - SCALAR_OP_MUL, - SCALAR_OP_DIV, - SCALAR_OP_MOD, - SCALAR_OP_POW, - SCALAR_OP_MAX, - SCALAR_OP_MIN, - SCALAR_OP_ATAN2, - SCALAR_MAX_OP - }; - - void scalar_op_node_set_op(ShaderType p_which,float p_id,ScalarOp p_op); - ScalarOp scalar_op_node_get_op(ShaderType p_which,float p_id) const; - - enum VecOp { - VEC_OP_ADD, - VEC_OP_SUB, - VEC_OP_MUL, - VEC_OP_DIV, - VEC_OP_MOD, - VEC_OP_POW, - VEC_OP_MAX, - VEC_OP_MIN, - VEC_OP_CROSS, - VEC_MAX_OP - }; - - void vec_op_node_set_op(ShaderType p_which,float p_id,VecOp p_op); - VecOp vec_op_node_get_op(ShaderType p_which,float p_id) const; - - enum VecScalarOp { - VEC_SCALAR_OP_MUL, - VEC_SCALAR_OP_DIV, - VEC_SCALAR_OP_POW, - VEC_SCALAR_MAX_OP - }; - - void vec_scalar_op_node_set_op(ShaderType p_which,float p_id,VecScalarOp p_op); - VecScalarOp vec_scalar_op_node_get_op(ShaderType p_which,float p_id) const; - - enum RGBOp { - RGB_OP_SCREEN, - RGB_OP_DIFFERENCE, - RGB_OP_DARKEN, - RGB_OP_LIGHTEN, - RGB_OP_OVERLAY, - RGB_OP_DODGE, - RGB_OP_BURN, - RGB_OP_SOFT_LIGHT, - RGB_OP_HARD_LIGHT, - RGB_MAX_OP - }; - - void rgb_op_node_set_op(ShaderType p_which,float p_id,RGBOp p_op); - RGBOp rgb_op_node_get_op(ShaderType p_which,float p_id) const; - - void xform_vec_mult_node_set_no_translation(ShaderType p_which,int p_id,bool p_no_translation); - bool xform_vec_mult_node_get_no_translation(ShaderType p_which,int p_id) const; - - enum ScalarFunc { - SCALAR_FUNC_SIN, - SCALAR_FUNC_COS, - SCALAR_FUNC_TAN, - SCALAR_FUNC_ASIN, - SCALAR_FUNC_ACOS, - SCALAR_FUNC_ATAN, - SCALAR_FUNC_SINH, - SCALAR_FUNC_COSH, - SCALAR_FUNC_TANH, - SCALAR_FUNC_LOG, - SCALAR_FUNC_EXP, - SCALAR_FUNC_SQRT, - SCALAR_FUNC_ABS, - SCALAR_FUNC_SIGN, - SCALAR_FUNC_FLOOR, - SCALAR_FUNC_ROUND, - SCALAR_FUNC_CEIL, - SCALAR_FUNC_FRAC, - SCALAR_FUNC_SATURATE, - SCALAR_FUNC_NEGATE, - SCALAR_MAX_FUNC - }; - - void scalar_func_node_set_function(ShaderType p_which,int p_id,ScalarFunc p_func); - ScalarFunc scalar_func_node_get_function(ShaderType p_which,int p_id) const; - - enum VecFunc { - VEC_FUNC_NORMALIZE, - VEC_FUNC_SATURATE, - VEC_FUNC_NEGATE, - VEC_FUNC_RECIPROCAL, - VEC_FUNC_RGB2HSV, - VEC_FUNC_HSV2RGB, - VEC_MAX_FUNC - }; - - void default_set_value(ShaderType p_which,int p_id,int p_param, const Variant& p_value); - Variant default_get_value(ShaderType p_which,int p_id,int p_param); - - void vec_func_node_set_function(ShaderType p_which,int p_id,VecFunc p_func); - VecFunc vec_func_node_get_function(ShaderType p_which,int p_id) const; - - void color_ramp_node_set_ramp(ShaderType p_which,int p_id,const PoolVector<Color>& p_colors, const PoolVector<real_t>& p_offsets); - PoolVector<Color> color_ramp_node_get_colors(ShaderType p_which,int p_id) const; - PoolVector<real_t> color_ramp_node_get_offsets(ShaderType p_which,int p_id) const; - - void curve_map_node_set_points(ShaderType p_which, int p_id, const PoolVector<Vector2>& p_points); - PoolVector<Vector2> curve_map_node_get_points(ShaderType p_which,int p_id) const; - - void input_node_set_name(ShaderType p_which,int p_id,const String& p_name); - String input_node_get_name(ShaderType p_which,int p_id); - - void scalar_input_node_set_value(ShaderType p_which,int p_id,float p_value); - float scalar_input_node_get_value(ShaderType p_which,int p_id) const; - - void vec_input_node_set_value(ShaderType p_which,int p_id,const Vector3& p_value); - Vector3 vec_input_node_get_value(ShaderType p_which,int p_id) const; - - void rgb_input_node_set_value(ShaderType p_which,int p_id,const Color& p_value); - Color rgb_input_node_get_value(ShaderType p_which,int p_id) const; - - void xform_input_node_set_value(ShaderType p_which,int p_id,const Transform& p_value); - Transform xform_input_node_get_value(ShaderType p_which,int p_id) const; - - void texture_input_node_set_value(ShaderType p_which,int p_id,const Ref<Texture>& p_texture); - Ref<Texture> texture_input_node_get_value(ShaderType p_which,int p_id) const; - - void cubemap_input_node_set_value(ShaderType p_which,int p_id,const Ref<CubeMap>& p_cubemap); - Ref<CubeMap> cubemap_input_node_get_value(ShaderType p_which,int p_id) const; - - void comment_node_set_text(ShaderType p_which,int p_id,const String& p_comment); - String comment_node_get_text(ShaderType p_which,int p_id) const; - - Error connect_node(ShaderType p_which,int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot); - bool is_node_connected(ShaderType p_which,int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) const; - void disconnect_node(ShaderType p_which,int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot); - - void get_node_connections(ShaderType p_which,List<Connection> *p_connections) const; - - bool is_slot_connected(ShaderType p_which,int p_dst_id,int slot_id); - - void clear(ShaderType p_which); - - Variant node_get_state(ShaderType p_type, int p_node) const; - void node_set_state(ShaderType p_type, int p_id, const Variant& p_state); - - GraphError get_graph_error(ShaderType p_type) const; - - int node_count(ShaderType p_which, int p_type); - - static int get_type_input_count(NodeType p_type); - static int get_type_output_count(NodeType p_type); - static SlotType get_type_input_type(NodeType p_type,int p_idx); - static SlotType get_type_output_type(NodeType p_type,int p_idx); - static bool is_type_valid(Mode p_mode,ShaderType p_type); - - - struct SlotInfo { - String name; - SlotType type; - SlotDir dir; - }; - - static void get_input_output_node_slot_info(Mode p_mode, ShaderType p_type, List<SlotInfo> *r_slots); - - static int get_node_input_slot_count(Mode p_mode, ShaderType p_shader_type,NodeType p_type); - static int get_node_output_slot_count(Mode p_mode, ShaderType p_shader_type,NodeType p_type); - static SlotType get_node_input_slot_type(Mode p_mode, ShaderType p_shader_type,NodeType p_type,int p_idx); - static SlotType get_node_output_slot_type(Mode p_mode, ShaderType p_shader_type,NodeType p_type,int p_idx); - - - ShaderGraph(Mode p_mode); - ~ShaderGraph(); -}; - -//helper functions - - - - -VARIANT_ENUM_CAST( ShaderGraph::NodeType ); -VARIANT_ENUM_CAST( ShaderGraph::ShaderType ); -VARIANT_ENUM_CAST( ShaderGraph::SlotType ); -VARIANT_ENUM_CAST( ShaderGraph::ScalarOp ); -VARIANT_ENUM_CAST( ShaderGraph::VecOp ); -VARIANT_ENUM_CAST( ShaderGraph::VecScalarOp ); -VARIANT_ENUM_CAST( ShaderGraph::RGBOp ); -VARIANT_ENUM_CAST( ShaderGraph::ScalarFunc ); -VARIANT_ENUM_CAST( ShaderGraph::VecFunc ); -VARIANT_ENUM_CAST( ShaderGraph::GraphError ); - - -class MaterialShaderGraph : public ShaderGraph { - - GDCLASS( MaterialShaderGraph, ShaderGraph ); - -public: - - - MaterialShaderGraph() : ShaderGraph(MODE_MATERIAL) { - - } -}; - -class CanvasItemShaderGraph : public ShaderGraph { - - GDCLASS( CanvasItemShaderGraph, ShaderGraph ); - -public: - - - CanvasItemShaderGraph() : ShaderGraph(MODE_CANVAS_ITEM) { - - } -}; - -#endif -#endif // SHADER_GRAPH_H diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index ec489e5c5b..81fabf40fe 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -755,15 +755,11 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const for (List<int>::Element *E = nindices.front(); E; E = E->next()) { int dst_index = E->get() + vfrom; - /* - if (dst_index <0 || dst_index>=vertex_array.size()) { - print_line("invalid index!"); - } - */ index_array.push_back(dst_index); } - if (index_array.size() % 3) - print_line("IA not div of 3?"); + if (index_array.size() % 3) { + WARN_PRINT("SurfaceTool: Index array not a multiple of 3."); + } } //mikktspace callbacks diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index d8efbeba17..811e5c3d2c 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "texture.h" +#include "bit_mask.h" #include "core/method_bind_ext.gen.inc" #include "core/os/os.h" #include "core_string_names.h" @@ -39,6 +40,9 @@ Size2 Texture::get_size() const { return Size2(get_width(), get_height()); } +bool Texture::is_pixel_opaque(int p_x, int p_y) const { + return true; +} void Texture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); @@ -234,6 +238,7 @@ void ImageTexture::set_data(const Ref<Image> &p_image) { VisualServer::get_singleton()->texture_set_data(texture, p_image); _change_notify(); + alpha_cache.unref(); } void ImageTexture::_resource_path_changed() { @@ -288,6 +293,41 @@ void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv); } +bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const { + + if (!alpha_cache.is_valid()) { + Ref<Image> img = get_data(); + if (img.is_valid()) { + if (img->is_compressed()) { //must decompress, if compressed + Ref<Image> decom = img->duplicate(); + decom->decompress(); + img = decom; + } + alpha_cache.instance(); + alpha_cache->create_from_image_alpha(img); + } + } + + if (alpha_cache.is_valid()) { + + int aw = int(alpha_cache->get_size().width); + int ah = int(alpha_cache->get_size().height); + if (aw == 0 || ah == 0) { + return true; + } + + int x = p_x * aw / w; + int y = p_y * ah / h; + + x = CLAMP(x, 0, aw); + y = CLAMP(y, 0, aw); + + return alpha_cache->get_bit(Point2(x, y)); + } + + return true; +} + void ImageTexture::set_size_override(const Size2 &p_size) { Size2 s = p_size; @@ -421,6 +461,8 @@ Image::Format StreamTexture::get_format() const { Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &flags, Ref<Image> &image, int p_size_limit) { + alpha_cache.unref(); + ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER); FileAccess *f = FileAccess::open(p_path, FileAccess::READ); @@ -438,7 +480,7 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla flags = f->get_32(); //texture flags! uint32_t df = f->get_32(); //data format -/* + /* print_line("width: " + itos(tw)); print_line("height: " + itos(th)); print_line("flags: " + itos(flags)); @@ -709,6 +751,40 @@ Ref<Image> StreamTexture::get_data() const { return VS::get_singleton()->texture_get_data(texture); } +bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const { + + if (!alpha_cache.is_valid()) { + Ref<Image> img = get_data(); + if (img.is_valid()) { + if (img->is_compressed()) { //must decompress, if compressed + Ref<Image> decom = img->duplicate(); + decom->decompress(); + img = decom; + } + alpha_cache.instance(); + alpha_cache->create_from_image_alpha(img); + } + } + + if (alpha_cache.is_valid()) { + + int aw = int(alpha_cache->get_size().width); + int ah = int(alpha_cache->get_size().height); + if (aw == 0 || ah == 0) { + return true; + } + + int x = p_x * aw / w; + int y = p_y * ah / h; + + x = CLAMP(x, 0, aw); + y = CLAMP(y, 0, aw); + + return alpha_cache->get_bit(Point2(x, y)); + } + + return true; +} void StreamTexture::set_flags(uint32_t p_flags) { flags = p_flags; VS::get_singleton()->texture_set_flags(texture, flags); @@ -946,30 +1022,12 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const { //this might not necessarily work well if using a rect, needs to be fixed properly - Rect2 rc = region; - if (!atlas.is_valid()) return; - Rect2 src = p_src_rect; - src.position += (rc.position - margin.position); - Rect2 src_c = rc.clip(src); - if (src_c.size == Size2()) - return; - Vector2 ofs = (src_c.position - src.position); - - Vector2 scale = p_rect.size / p_src_rect.size; - if (scale.x < 0) { - float mx = (margin.size.width - margin.position.x); - mx -= margin.position.x; - ofs.x = -(ofs.x + mx); - } - if (scale.y < 0) { - float my = margin.size.height - margin.position.y; - my -= margin.position.y; - ofs.y = -(ofs.y + my); - } - Rect2 dr(p_rect.position + ofs * scale, src_c.size * scale); + Rect2 dr; + Rect2 src_c; + get_rect_region(p_rect, p_src_rect, dr, src_c); RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, normal_rid, filter_clip); @@ -983,13 +1041,17 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, return false; Rect2 src = p_src_rect; + if (src.size == Size2()) { + src.size = rc.size; + } + Vector2 scale = p_rect.size / src.size; + src.position += (rc.position - margin.position); Rect2 src_c = rc.clip(src); if (src_c.size == Size2()) return false; Vector2 ofs = (src_c.position - src.position); - Vector2 scale = p_rect.size / p_src_rect.size; if (scale.x < 0) { float mx = (margin.size.width - margin.position.x); mx -= margin.position.x; @@ -1007,6 +1069,15 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, return true; } +bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const { + + if (atlas.is_valid()) { + return atlas->is_pixel_opaque(p_x + region.position.x + margin.position.x, p_x + region.position.y + margin.position.y); + } + + return true; +} + AtlasTexture::AtlasTexture() { filter_clip = false; } @@ -1184,6 +1255,23 @@ void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons } } +bool LargeTexture::is_pixel_opaque(int p_x, int p_y) const { + + for (int i = 0; i < pieces.size(); i++) { + + // TODO + if (!pieces[i].texture.is_valid()) + continue; + + Rect2 rect(pieces[i].offset, pieces[i].texture->get_size()); + if (rect.has_point(Point2(p_x, p_y))) { + return pieces[i].texture->is_pixel_opaque(p_x - rect.position.x, p_y - rect.position.y); + } + } + + return true; +} + LargeTexture::LargeTexture() { } @@ -1666,7 +1754,7 @@ ProxyTexture::~ProxyTexture() { void AnimatedTexture::_update_proxy() { - _THREAD_SAFE_METHOD_ + RWLockRead r(rw_lock); float delta; if (prev_ticks == 0) { @@ -1712,7 +1800,7 @@ void AnimatedTexture::_update_proxy() { void AnimatedTexture::set_frames(int p_frames) { ERR_FAIL_COND(p_frames < 1 || p_frames > MAX_FRAMES); - _THREAD_SAFE_METHOD_ + RWLockWrite r(rw_lock); frame_count = p_frames; } @@ -1723,14 +1811,14 @@ int AnimatedTexture::get_frames() const { void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture> &p_texture) { ERR_FAIL_INDEX(p_frame, MAX_FRAMES); - _THREAD_SAFE_METHOD_ + RWLockWrite w(rw_lock); frames[p_frame].texture = p_texture; } Ref<Texture> AnimatedTexture::get_frame_texture(int p_frame) const { ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, Ref<Texture>()); - _THREAD_SAFE_METHOD_ + RWLockRead r(rw_lock); return frames[p_frame].texture; } @@ -1738,14 +1826,14 @@ Ref<Texture> AnimatedTexture::get_frame_texture(int p_frame) const { void AnimatedTexture::set_frame_delay(int p_frame, float p_delay_sec) { ERR_FAIL_INDEX(p_frame, MAX_FRAMES); - _THREAD_SAFE_METHOD_ + RWLockRead r(rw_lock); frames[p_frame].delay_sec = p_delay_sec; } float AnimatedTexture::get_frame_delay(int p_frame) const { ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, 0); - _THREAD_SAFE_METHOD_ + RWLockRead r(rw_lock); return frames[p_frame].delay_sec; } @@ -1760,8 +1848,7 @@ float AnimatedTexture::get_fps() const { } int AnimatedTexture::get_width() const { - - _THREAD_SAFE_METHOD_ + RWLockRead r(rw_lock); if (!frames[current_frame].texture.is_valid()) { return 1; @@ -1770,8 +1857,7 @@ int AnimatedTexture::get_width() const { return frames[current_frame].texture->get_width(); } int AnimatedTexture::get_height() const { - - _THREAD_SAFE_METHOD_ + RWLockRead r(rw_lock); if (!frames[current_frame].texture.is_valid()) { return 1; @@ -1785,7 +1871,7 @@ RID AnimatedTexture::get_rid() const { bool AnimatedTexture::has_alpha() const { - _THREAD_SAFE_METHOD_ + RWLockRead r(rw_lock); if (!frames[current_frame].texture.is_valid()) { return false; @@ -1796,7 +1882,7 @@ bool AnimatedTexture::has_alpha() const { Ref<Image> AnimatedTexture::get_data() const { - _THREAD_SAFE_METHOD_ + RWLockRead r(rw_lock); if (!frames[current_frame].texture.is_valid()) { return Ref<Image>(); @@ -1805,11 +1891,21 @@ Ref<Image> AnimatedTexture::get_data() const { return frames[current_frame].texture->get_data(); } +bool AnimatedTexture::is_pixel_opaque(int p_x, int p_y) const { + + RWLockRead r(rw_lock); + + if (frames[current_frame].texture.is_valid()) { + return frames[current_frame].texture->is_pixel_opaque(p_x, p_y); + } + return true; +} + void AnimatedTexture::set_flags(uint32_t p_flags) { } uint32_t AnimatedTexture::get_flags() const { - _THREAD_SAFE_METHOD_ + RWLockRead r(rw_lock); if (!frames[current_frame].texture.is_valid()) { return 0; @@ -1862,10 +1958,19 @@ AnimatedTexture::AnimatedTexture() { prev_ticks = 0; current_frame = 0; VisualServer::get_singleton()->connect("frame_pre_draw", this, "_update_proxy"); + +#ifndef NO_THREADS + rw_lock = RWLock::create(); +#else + rw_lock = NULL; +#endif } AnimatedTexture::~AnimatedTexture() { VS::get_singleton()->free(proxy); + if (rw_lock) { + memdelete(rw_lock); + } } /////////////////////////////// diff --git a/scene/resources/texture.h b/scene/resources/texture.h index c1331fb3fe..79e6d2cdf9 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -34,6 +34,7 @@ #include "curve.h" #include "io/resource_loader.h" #include "os/mutex.h" +#include "os/rw_lock.h" #include "os/thread_safe.h" #include "rect2.h" #include "resource.h" @@ -67,6 +68,8 @@ public: virtual Size2 get_size() const; virtual RID get_rid() const = 0; + virtual bool is_pixel_opaque(int p_x, int p_y) const; + virtual bool has_alpha() const = 0; virtual void set_flags(uint32_t p_flags) = 0; @@ -84,6 +87,8 @@ public: VARIANT_ENUM_CAST(Texture::Flags); +class BitMap; + class ImageTexture : public Texture { GDCLASS(ImageTexture, Texture); @@ -104,6 +109,7 @@ private: Storage storage; Size2 size_override; float lossy_storage_quality; + mutable Ref<BitMap> alpha_cache; protected: virtual void reload_from_file(); @@ -143,6 +149,8 @@ public: void set_storage(Storage p_storage); Storage get_storage() const; + bool is_pixel_opaque(int p_x, int p_y) const; + void set_lossy_storage_quality(float p_lossy_storage_quality); float get_lossy_storage_quality() const; @@ -183,6 +191,7 @@ private: Image::Format format; uint32_t flags; int w, h; + mutable Ref<BitMap> alpha_cache; virtual void reload_from_file(); @@ -215,6 +224,7 @@ public: virtual bool has_alpha() const; virtual void set_flags(uint32_t p_flags); + bool is_pixel_opaque(int p_x, int p_y) const; virtual Ref<Image> get_data() const; @@ -272,6 +282,8 @@ public: virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const; virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const; + bool is_pixel_opaque(int p_x, int p_y) const; + AtlasTexture(); }; @@ -319,6 +331,8 @@ public: virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const; + bool is_pixel_opaque(int p_x, int p_y) const; + LargeTexture(); }; @@ -609,7 +623,8 @@ public: class AnimatedTexture : public Texture { GDCLASS(AnimatedTexture, Texture) - _THREAD_SAFE_CLASS_ + //use readers writers lock for this, since its far more times read than written to + RWLock *rw_lock; private: enum { @@ -668,6 +683,8 @@ public: virtual Ref<Image> get_data() const; + bool is_pixel_opaque(int p_x, int p_y) const; + AnimatedTexture(); ~AnimatedTexture(); }; diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index d8fc3677fb..dac12205b6 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -431,7 +431,6 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port global_code += "\n\n"; String final_code = global_code; final_code += code; - //print_line(final_code); return final_code; } @@ -914,7 +913,6 @@ void VisualShader::_update_shader() const { String final_code = global_code; final_code += code; const_cast<VisualShader *>(this)->set_code(final_code); - //print_line(final_code); for (int i = 0; i < default_tex_params.size(); i++) { const_cast<VisualShader *>(this)->set_default_texture_param(default_tex_params[i].name, default_tex_params[i].param); } |