summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/tests/test_math.cpp400
-rw-r--r--core/object_type_db.cpp174
-rw-r--r--core/object_type_db.h15
-rw-r--r--doc/base/classes.xml3
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp4
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp1
-rw-r--r--drivers/gles2/shaders/canvas.glsl4
-rw-r--r--drivers/gles2/shaders/material.glsl4
-rw-r--r--main/main.cpp5
-rw-r--r--scene/2d/camera_2d.cpp11
-rw-r--r--scene/resources/shader_graph.cpp4
-rw-r--r--servers/visual/shader_language.cpp1
-rw-r--r--tools/editor/editor_node.cpp23
-rw-r--r--tools/editor/editor_node.h9
-rw-r--r--tools/editor/plugins/shader_graph_editor_plugin.cpp2
15 files changed, 646 insertions, 14 deletions
diff --git a/bin/tests/test_math.cpp b/bin/tests/test_math.cpp
index 4b686e8af8..e5667bff64 100644
--- a/bin/tests/test_math.cpp
+++ b/bin/tests/test_math.cpp
@@ -40,12 +40,376 @@
#include "scene/resources/texture.h"
#include "vmap.h"
#include "os/os.h"
+#include "os/file_access.h"
#include "method_ptrcall.h"
namespace TestMath {
+class GetClassAndNamespace {
+
+ String code;
+ int idx;
+ int line;
+ String error_str;
+ bool error;
+ Variant value;
+
+ String class_name;
+
+ enum Token {
+ TK_BRACKET_OPEN,
+ TK_BRACKET_CLOSE,
+ TK_CURLY_BRACKET_OPEN,
+ TK_CURLY_BRACKET_CLOSE,
+ TK_PERIOD,
+ TK_COLON,
+ TK_COMMA,
+ TK_SYMBOL,
+ TK_IDENTIFIER,
+ TK_STRING,
+ TK_NUMBER,
+ TK_EOF,
+ TK_ERROR
+ };
+
+
+ Token get_token() {
+
+ while (true) {
+ switch(code[idx]) {
+
+ case '\n': {
+
+ line++;
+ idx++;
+ break;
+ };
+ case 0: {
+ return TK_EOF;
+
+ } break;
+ case '{': {
+
+ idx++;
+ return TK_CURLY_BRACKET_OPEN;
+ };
+ case '}': {
+
+ idx++;
+ return TK_CURLY_BRACKET_CLOSE;
+ };
+ case '[': {
+
+ idx++;
+ return TK_BRACKET_OPEN;
+ };
+ case ']': {
+
+ idx++;
+ return TK_BRACKET_CLOSE;
+ };
+ case ':': {
+
+ idx++;
+ return TK_COLON;
+ };
+ case ',': {
+
+ idx++;
+ return TK_COMMA;
+ };
+ case '.': {
+
+ idx++;
+ return TK_PERIOD;
+ };
+ case '#': {
+ //compiler directive
+ while(code[idx]!='\n' && code[idx]!=0) {
+ idx++;
+ }
+ continue;
+ } break;
+ case '/': {
+
+
+ switch(code[idx+1]) {
+ case '*': { // block comment
+
+ idx+=2;
+ while(true) {
+ if (code[idx]==0) {
+ error_str="Unterminated comment";
+ error=true;
+ return TK_ERROR;
+ } if (code[idx]=='*' &&code[idx+1]=='/') {
+
+ idx+=2;
+ break;
+ } if (code[idx]=='\n') {
+ line++;
+ }
+
+ idx++;
+ }
+
+ } break;
+ case '/': { // line comment skip
+
+ while(code[idx]!='\n' && code[idx]!=0) {
+ idx++;
+ }
+
+ } break;
+ default: {
+ value="/";
+ idx++;
+ return TK_SYMBOL;
+ }
+
+ }
+
+ continue; // a comment
+ } break;
+ case '\'':
+ case '"': {
+
+ CharType begin_str = code[idx];
+ idx++;
+ String tk_string=String();
+ while(true) {
+ if (code[idx]==0) {
+ error_str="Unterminated String";
+ error=true;
+ return TK_ERROR;
+ } else if (code[idx]==begin_str) {
+ idx++;
+ break;
+ } else if (code[idx]=='\\') {
+ //escaped characters...
+ idx++;
+ CharType next = code[idx];
+ if (next==0) {
+ error_str="Unterminated String";
+ error=true;
+ return TK_ERROR;
+ }
+ CharType res=0;
+
+ switch(next) {
+
+ case 'b': res=8; break;
+ case 't': res=9; break;
+ case 'n': res=10; break;
+ case 'f': res=12; break;
+ case 'r': res=13; break;
+ /* too much, not needed for now
+ case 'u': {
+ //hexnumbarh - oct is deprecated
+
+
+ for(int j=0;j<4;j++) {
+ CharType c = code[idx+j+1];
+ if (c==0) {
+ r_err_str="Unterminated String";
+ return ERR_PARSE_ERROR;
+ }
+ if (!((c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F'))) {
+
+ r_err_str="Malformed hex constant in string";
+ return ERR_PARSE_ERROR;
+ }
+ CharType v;
+ if (c>='0' && c<='9') {
+ v=c-'0';
+ } else if (c>='a' && c<='f') {
+ v=c-'a';
+ v+=10;
+ } else if (c>='A' && c<='F') {
+ v=c-'A';
+ v+=10;
+ } else {
+ ERR_PRINT("BUG");
+ v=0;
+ }
+
+ res<<=4;
+ res|=v;
+
+
+ }
+ idx+=4; //will add at the end anyway
+
+
+ } break;*/
+ case '\"': res='\"'; break;
+ case '\\': res='\\'; break;
+ //case '/': res='/'; break;
+ default: {
+ res = next;
+ //r_err_str="Invalid escape sequence";
+ //return ERR_PARSE_ERROR;
+ } break;
+ }
+
+ tk_string+=res;
+
+ } else {
+ if (code[idx]=='\n')
+ line++;
+ tk_string+=code[idx];
+ }
+ idx++;
+ }
+
+ value=tk_string;
+
+ return TK_STRING;
+
+ } break;
+ default: {
+
+ if (code[idx]<=32) {
+ idx++;
+ break;
+ }
+
+ if ( (code[idx]>=33 && code[idx]<=47) || (code[idx]>=58 && code[idx]<=64) || (code[idx]>=91 && code[idx]<=96) || (code[idx]>=123 && code[idx]<=127)){
+ value=String::chr(code[idx]);
+ idx++;
+ return TK_SYMBOL;
+ }
+
+ if (code[idx]=='-' || (code[idx]>='0' && code[idx]<='9')) {
+ //a number
+ const CharType *rptr;
+ double number = String::to_double(&code[idx],&rptr);
+ idx+=(rptr - &code[idx]);
+ value=number;
+ return TK_NUMBER;
+
+ } else if ((code[idx]>='A' && code[idx]<='Z') || (code[idx]>='a' && code[idx]<='z') || code[idx]>127) {
+
+ String id;
+
+ while((code[idx]>='A' && code[idx]<='Z') || (code[idx]>='a' && code[idx]<='z') || code[idx]>127) {
+
+ id+=code[idx];
+ idx++;
+ }
+
+ value=id;
+ return TK_IDENTIFIER;
+ } else {
+ error_str="Unexpected character.";
+ error=true;
+ return TK_ERROR;
+ }
+ }
+
+ }
+ }
+ }
+
+public:
+ Error parse(const String& p_code,const String& p_known_class_name=String()) {
+
+ code=p_code;
+ idx=0;
+ line=0;
+ error_str=String();
+ error=false;
+ value=Variant();
+ class_name=String();
+
+ bool use_next_class=false;
+ Token tk = get_token();
+
+ Map<int,String> namespace_stack;
+ int curly_stack=0;
+
+
+ while(!error || tk!=TK_EOF) {
+
+ if (tk==TK_BRACKET_OPEN) {
+ tk = get_token();
+ if (tk==TK_IDENTIFIER && String(value)=="ScriptClass") {
+ if (get_token()==TK_BRACKET_CLOSE) {
+ use_next_class=true;
+ }
+ }
+ } else if (tk==TK_IDENTIFIER && String(value)=="class") {
+ tk = get_token();
+ if (tk==TK_IDENTIFIER) {
+ String name = value;
+ if (use_next_class || p_known_class_name==name) {
+ for (Map<int,String>::Element *E=namespace_stack.front();E;E=E->next()) {
+ class_name+=E->get()+".";
+ }
+ class_name+=String(value);
+ break;
+ }
+ }
+
+ } else if (tk==TK_IDENTIFIER && String(value)=="namespace") {
+ String name;
+ int at_level = curly_stack;
+ while(true) {
+ tk = get_token();
+ if (tk==TK_IDENTIFIER) {
+ name+=String(value);
+ }
+
+ tk = get_token();
+ if (tk==TK_PERIOD) {
+ name+=".";
+ } else if (tk==TK_CURLY_BRACKET_OPEN) {
+ curly_stack++;
+ break;
+ } else {
+ break; //whathever else
+ }
+
+ }
+
+ if (name!=String()) {
+ namespace_stack[at_level]=name;
+ }
+
+ } else if (tk==TK_CURLY_BRACKET_OPEN) {
+ curly_stack++;
+ } else if (tk==TK_CURLY_BRACKET_CLOSE) {
+ curly_stack--;
+ if (namespace_stack.has(curly_stack)) {
+ namespace_stack.erase(curly_stack);
+ }
+ }
+
+ tk = get_token();
+ }
+
+ if (error)
+ return ERR_PARSE_ERROR;
+
+
+
+ return OK;
+
+ }
+
+ String get_error() {
+ return error_str;
+ }
+
+ String get_class() {
+ return class_name;
+ }
+
+};
+
+
void test_vec(Plane p_vec) {
@@ -113,7 +477,41 @@ uint32_t ihash3( uint32_t a)
MainLoop* test() {
- print_line(itos(Math::step_decimals( 0.0001 )));
+
+ List<String> cmdlargs = OS::get_singleton()->get_cmdline_args();
+
+ if (cmdlargs.empty()) {
+ //try editor!
+ return NULL;
+ }
+
+ String test = cmdlargs.back()->get();
+
+ FileAccess *fa = FileAccess::open(test,FileAccess::READ);
+
+ if (!fa) {
+ ERR_EXPLAIN("Could not open file: "+test);
+ ERR_FAIL_V(NULL);
+ }
+
+
+ Vector<uint8_t> buf;
+ int flen = fa->get_len();
+ buf.resize(fa->get_len()+1);
+ fa->get_buffer(&buf[0],flen);
+ buf[flen]=0;
+
+
+ String code;
+ code.parse_utf8((const char*)&buf[0]);
+
+ GetClassAndNamespace getclass;
+ if (getclass.parse(code)) {
+ print_line("Parse error: "+getclass.get_error());
+ } else {
+ print_line("Found class: "+getclass.get_class());
+ }
+
return NULL;
{
diff --git a/core/object_type_db.cpp b/core/object_type_db.cpp
index aa641923e6..e121dc9e98 100644
--- a/core/object_type_db.cpp
+++ b/core/object_type_db.cpp
@@ -189,6 +189,14 @@ MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,co
#endif
+
+ObjectTypeDB::APIType ObjectTypeDB::current_api=API_CORE;
+
+void ObjectTypeDB::set_current_api(APIType p_api) {
+
+ current_api=p_api;
+}
+
HashMap<StringName,ObjectTypeDB::TypeInfo,StringNameHasher> ObjectTypeDB::types;
HashMap<StringName,StringName,StringNameHasher> ObjectTypeDB::resource_base_extensions;
HashMap<StringName,StringName,StringNameHasher> ObjectTypeDB::compat_types;
@@ -258,6 +266,171 @@ StringName ObjectTypeDB::type_inherits_from(const StringName& p_type) {
return ti->inherits;
}
+ObjectTypeDB::APIType ObjectTypeDB::get_api_type(const StringName &p_type) {
+
+ OBJTYPE_LOCK;
+
+ TypeInfo *ti = types.getptr(p_type);
+ ERR_FAIL_COND_V(!ti,API_NONE);
+ return ti->api;
+}
+
+uint64_t ObjectTypeDB::get_api_hash(APIType p_api) {
+
+#ifdef DEBUG_METHODS_ENABLED
+
+ uint64_t hash = hash_djb2_one_64(HashMapHahserDefault::hash(VERSION_FULL_NAME));
+
+ List<StringName> names;
+
+ const StringName *k=NULL;
+
+ while((k=types.next(k))) {
+
+ names.push_back(*k);
+ }
+ //must be alphabetically sorted for hash to compute
+ names.sort_custom<StringName::AlphCompare>();
+
+ for (List<StringName>::Element *E=names.front();E;E=E->next()) {
+
+ TypeInfo *t = types.getptr(E->get());
+ ERR_FAIL_COND_V(!t,0);
+ if (t->api!=p_api)
+ continue;
+ hash = hash_djb2_one_64(t->name.hash(),hash);
+ hash = hash_djb2_one_64(t->inherits.hash(),hash);
+
+ { //methods
+
+ List<StringName> snames;
+
+ k=NULL;
+
+ while((k=t->method_map.next(k))) {
+
+ snames.push_back(*k);
+ }
+
+ snames.sort_custom<StringName::AlphCompare>();
+
+ for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
+
+ MethodBind *mb = t->method_map[F->get()];
+ hash = hash_djb2_one_64( mb->get_name().hash(), hash);
+ hash = hash_djb2_one_64( mb->get_argument_count(), hash);
+ hash = hash_djb2_one_64( mb->get_argument_type(-1), hash); //return
+
+ for(int i=0;i<mb->get_argument_count();i++) {
+ hash = hash_djb2_one_64( mb->get_argument_info(i).type, hash );
+ hash = hash_djb2_one_64( mb->get_argument_info(i).name.hash(), hash );
+ hash = hash_djb2_one_64( mb->get_argument_info(i).hint, hash );
+ hash = hash_djb2_one_64( mb->get_argument_info(i).hint_string.hash(), hash );
+ }
+
+ hash = hash_djb2_one_64( mb->get_default_argument_count(), hash);
+
+ for(int i=0;i<mb->get_default_argument_count();i++) {
+ //hash should not change, i hope for tis
+ Variant da = mb->get_default_argument(i);
+ hash = hash_djb2_one_64( da.hash(), hash );
+ }
+
+ hash = hash_djb2_one_64( mb->get_hint_flags(), hash);
+
+ }
+ }
+
+
+ { //constants
+
+ List<StringName> snames;
+
+ k=NULL;
+
+ while((k=t->constant_map.next(k))) {
+
+ snames.push_back(*k);
+ }
+
+ snames.sort_custom<StringName::AlphCompare>();
+
+ for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
+
+ hash = hash_djb2_one_64(F->get().hash(), hash);
+ hash = hash_djb2_one_64( t->constant_map[F->get()], hash);
+ }
+ }
+
+
+ { //signals
+
+ List<StringName> snames;
+
+ k=NULL;
+
+ while((k=t->signal_map.next(k))) {
+
+ snames.push_back(*k);
+ }
+
+ snames.sort_custom<StringName::AlphCompare>();
+
+ for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
+
+ MethodInfo &mi = t->signal_map[F->get()];
+ hash = hash_djb2_one_64( F->get().hash(), hash);
+ for(int i=0;i<mi.arguments.size();i++) {
+ hash = hash_djb2_one_64( mi.arguments[i].type, hash);
+ }
+ }
+ }
+
+ { //properties
+
+ List<StringName> snames;
+
+ k=NULL;
+
+ while((k=t->property_setget.next(k))) {
+
+ snames.push_back(*k);
+ }
+
+ snames.sort_custom<StringName::AlphCompare>();
+
+ for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
+
+ PropertySetGet *psg=t->property_setget.getptr(F->get());
+
+ hash = hash_djb2_one_64( F->get().hash(), hash);
+ hash = hash_djb2_one_64( psg->setter.hash(), hash);
+ hash = hash_djb2_one_64( psg->getter.hash(), hash);
+
+ }
+ }
+
+ //property list
+ for (List<PropertyInfo>::Element *F=t->property_list.front();F;F=F->next()) {
+
+ hash = hash_djb2_one_64( F->get().name.hash(), hash);
+ hash = hash_djb2_one_64( F->get().type, hash);
+ hash = hash_djb2_one_64( F->get().hint, hash);
+ hash = hash_djb2_one_64( F->get().hint_string.hash(), hash);
+ hash = hash_djb2_one_64( F->get().usage, hash);
+ }
+
+
+ }
+
+
+ return hash;
+#else
+ return 0;
+#endif
+
+}
+
bool ObjectTypeDB::type_exists(const StringName &p_type) {
OBJTYPE_LOCK;
@@ -309,6 +482,7 @@ void ObjectTypeDB::_add_type2(const StringName& p_type, const StringName& p_inhe
TypeInfo &ti=types[name];
ti.name=name;
ti.inherits=p_inherits;
+ ti.api=current_api;
if (ti.inherits) {
diff --git a/core/object_type_db.h b/core/object_type_db.h
index 725b424c9a..9e9029ff2f 100644
--- a/core/object_type_db.h
+++ b/core/object_type_db.h
@@ -109,7 +109,13 @@ static _FORCE_INLINE_ const char* _MD(const char* m_name, ...) { return m_name;
#endif
class ObjectTypeDB {
-
+public:
+ enum APIType {
+ API_CORE,
+ API_EDITOR,
+ API_NONE
+ };
+public:
struct PropertySetGet {
int index;
@@ -122,6 +128,7 @@ class ObjectTypeDB {
struct TypeInfo {
+ APIType api;
TypeInfo *inherits_ptr;
HashMap<StringName,MethodBind*,StringNameHasher> method_map;
HashMap<StringName,int,StringNameHasher> constant_map;
@@ -161,6 +168,7 @@ class ObjectTypeDB {
#endif
+ static APIType current_api;
static void _add_type2(const StringName& p_type, const StringName& p_inherits);
public:
@@ -236,6 +244,9 @@ public:
static bool is_type(const StringName &p_type,const StringName& p_inherits);
static bool can_instance(const StringName &p_type);
static Object *instance(const StringName &p_type);
+ static APIType get_api_type(const StringName &p_type);
+
+ static uint64_t get_api_hash(APIType p_api);
#if 0
template<class N, class M>
@@ -499,6 +510,8 @@ public:
static void add_compatibility_type(const StringName& p_type,const StringName& p_fallback);
static void init();
+
+ static void set_current_api(APIType p_api);
static void cleanup();
};
diff --git a/doc/base/classes.xml b/doc/base/classes.xml
index 916ca09c92..6865bb1378 100644
--- a/doc/base/classes.xml
+++ b/doc/base/classes.xml
@@ -16640,7 +16640,8 @@
<argument index="3" name="duration" type="float" default="0">
</argument>
<description>
- Starts to vibrate the joystick. Joysticks usually come with two rumble motors, a strong and a weak one. weak_magnitude is the strength of the weak motor (between 0 and 1) and strong_magnitude is the strength of the strong motor (between 0 and 1). duration is the duration of the effect in seconds (a duration of 0 will play the vibration indefinitely).
+ Starts to vibrate the joystick. Joysticks usually come with two rumble motors, a strong and a weak one. weak_magnitude is the strength of the weak motor (between 0 and 1) and strong_magnitude is the strength of the strong motor (between 0 and 1). duration is the duration of the effect in seconds (a duration of 0 will try to play the vibration indefinitely).
+ Note that not every hardware is compatible with long effect durations, it is recommended to restart an effect if in need to play it for more than a few seconds.
</description>
</method>
<method name="stop_joy_vibration">
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 8350fb0674..d5becc0bfc 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -4666,7 +4666,7 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
enablers.push_back("#define USE_LIGHT_SHADER_CODE\n");
}
if (light_flags.uses_shadow_color) {
- enablers.push_back("#define USE_LIGHT_SHADOW_COLOR\n");
+ enablers.push_back("#define USE_OUTPUT_SHADOW_COLOR\n");
}
if (light_flags.uses_time || fragment_flags.uses_time || vertex_flags.uses_time) {
enablers.push_back("#define USE_TIME\n");
@@ -4709,7 +4709,7 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
enablers.push_back("#define USE_TEXPIXEL_SIZE\n");
}
if (light_flags.uses_shadow_color) {
- enablers.push_back("#define USE_LIGHT_SHADOW_COLOR\n");
+ enablers.push_back("#define USE_OUTPUT_SHADOW_COLOR\n");
}
if (vertex_flags.uses_worldvec) {
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 3be0fdab17..d4636ed444 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -904,6 +904,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT_VEC"]="light_vec";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT_HEIGHT"]="light_height";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT_COLOR"]="light";
+ mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT_SHADOW"]="light_shadow_color";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT_UV"]="light_uv";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT"]="light_out";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["SHADOW"]="shadow_color";
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index 285abd30ff..5f4767940d 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -244,7 +244,7 @@ FRAGMENT_SHADER_CODE
vec2 light_uv = light_uv_interp.xy;
vec4 light = texture2D(light_texture,light_uv) * light_color;
-#if defined(USE_LIGHT_SHADOW_COLOR)
+#if defined(USE_OUTPUT_SHADOW_COLOR)
vec4 shadow_color=vec4(0.0,0.0,0.0,0.0);
#endif
@@ -380,7 +380,7 @@ LIGHT_SHADER_CODE
#endif
-#if defined(USE_LIGHT_SHADOW_COLOR)
+#if defined(USE_OUTPUT_SHADOW_COLOR)
color=mix(shadow_color,color,shadow_attenuation);
#else
//color*=shadow_attenuation;
diff --git a/drivers/gles2/shaders/material.glsl b/drivers/gles2/shaders/material.glsl
index fd778f3442..477a451f2f 100644
--- a/drivers/gles2/shaders/material.glsl
+++ b/drivers/gles2/shaders/material.glsl
@@ -1185,7 +1185,7 @@ FRAGMENT_SHADER_CODE
vec3 mdiffuse = diffuse.rgb;
vec3 light;
-#if defined(USE_LIGHT_SHADOW_COLOR)
+#if defined(USE_OUTPUT_SHADOW_COLOR)
vec3 shadow_color=vec3(0.0,0.0,0.0);
#endif
@@ -1209,7 +1209,7 @@ LIGHT_SHADER_CODE
#endif
diffuse.rgb = const_light_mult * ambient_light *diffuse.rgb + light * attenuation * shadow_attenuation;
-#if defined(USE_LIGHT_SHADOW_COLOR)
+#if defined(USE_OUTPUT_SHADOW_COLOR)
diffuse.rgb += light * shadow_color * attenuation * (1.0 - shadow_attenuation);
#endif
diff --git a/main/main.cpp b/main/main.cpp
index ec4386ab20..d2ba38b094 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -994,8 +994,11 @@ Error Main::setup2() {
}
}
#ifdef TOOLS_ENABLED
+ ObjectTypeDB::set_current_api(ObjectTypeDB::API_EDITOR);
EditorNode::register_editor_types();
ObjectTypeDB::register_type<PCKPacker>(); // todo: move somewhere else
+ ObjectTypeDB::set_current_api(ObjectTypeDB::API_CORE);
+
#endif
MAIN_PRINT("Main: Load Scripts, Modules, Drivers");
@@ -1022,6 +1025,8 @@ Error Main::setup2() {
_start_success=true;
locale=String();
+ ObjectTypeDB::set_current_api(ObjectTypeDB::API_NONE); //no more api is registered at this point
+
MAIN_PRINT("Main: Done");
return OK;
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index 17352705c7..f33faaabd8 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -76,8 +76,9 @@ Matrix32 Camera2D::get_camera_transform() {
if (!get_tree())
return Matrix32();
- Size2 screen_size = get_viewport_rect().size;
- screen_size=get_viewport_rect().size;
+ ERR_FAIL_COND_V( custom_viewport && !ObjectDB::get_instance(custom_viewport_id), Matrix32() );
+
+ Size2 screen_size = viewport->get_visible_rect().size;
Point2 new_camera_pos = get_global_transform().get_origin();
@@ -446,8 +447,10 @@ void Camera2D::reset_smoothing() {
void Camera2D::align() {
- Size2 screen_size = get_viewport_rect().size;
- screen_size=get_viewport_rect().size;
+ ERR_FAIL_COND( custom_viewport && !ObjectDB::get_instance(custom_viewport_id) );
+
+ Size2 screen_size = viewport->get_visible_rect().size;
+
Point2 current_camera_pos = get_global_transform().get_origin();
if (anchor_mode==ANCHOR_MODE_DRAG_CENTER) {
if (h_ofs<0) {
diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp
index 40ae26ba5d..02faa9425d 100644
--- a/scene/resources/shader_graph.cpp
+++ b/scene/resources/shader_graph.cpp
@@ -1483,6 +1483,8 @@ const ShaderGraph::InOutParamInfo ShaderGraph::inout_param_info[]={
{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},
@@ -1490,6 +1492,8 @@ const ShaderGraph::InOutParamInfo ShaderGraph::inout_param_info[]={
//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},
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 09b3ada509..fdf3cb622d 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -1180,6 +1180,7 @@ const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_light_builtins_defs[]={
{ "LIGHT_HEIGHT", TYPE_FLOAT},
{ "LIGHT_COLOR", TYPE_VEC4},
{ "LIGHT_UV", TYPE_VEC2},
+ { "LIGHT_SHADOW", TYPE_VEC4},
{ "LIGHT", TYPE_VEC4},
{ "SHADOW", TYPE_VEC4},
{ "POINT_COORD", TYPE_VEC2},
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index dd84b30add..3b1e90a907 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -1217,6 +1217,7 @@ void EditorNode::_dialog_action(String p_file) {
//_save_scene(p_file);
_save_scene_with_preview(p_file);
+ _call_build();
_run(true);
}
} break;
@@ -2636,6 +2637,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
} break;
case RUN_PLAY: {
_menu_option_confirm(RUN_STOP,true);
+ _call_build();
_run(false);
} break;
@@ -2671,6 +2673,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
} break;
case RUN_PLAY_SCENE: {
_menu_option_confirm(RUN_STOP,true);
+ _call_build();
_run(true);
} break;
@@ -2682,6 +2685,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
}
if (run_native->is_deploy_debug_remote_enabled()){
_menu_option_confirm(RUN_STOP,true);
+ _call_build();
emit_signal("play_pressed");
editor_run.run_native_notify();
}
@@ -4042,6 +4046,7 @@ void EditorNode::_quick_opened() {
void EditorNode::_quick_run() {
+ _call_build();
_run(false,quick_run->get_selected());
}
@@ -5244,6 +5249,24 @@ void EditorNode::add_plugin_init_callback(EditorPluginInitializeCallback p_callb
EditorPluginInitializeCallback EditorNode::plugin_init_callbacks[EditorNode::MAX_INIT_CALLBACKS];
+int EditorNode::build_callback_count=0;
+
+void EditorNode::add_build_callback(EditorBuildCallback p_callback) {
+
+ ERR_FAIL_COND(build_callback_count==MAX_INIT_CALLBACKS);
+
+ build_callbacks[build_callback_count++]=p_callback;
+}
+
+EditorPluginInitializeCallback EditorNode::build_callbacks[EditorNode::MAX_BUILD_CALLBACKS];
+
+void EditorNode::_call_build() {
+
+ for(int i=0;i<build_callback_count;i++) {
+ build_callbacks[i]();
+ }
+}
+
void EditorNode::_bind_methods() {
diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h
index 96242a144d..2fae5daced 100644
--- a/tools/editor/editor_node.h
+++ b/tools/editor/editor_node.h
@@ -95,6 +95,7 @@
typedef void (*EditorNodeInitCallback)();
typedef void (*EditorPluginInitializeCallback)();
+typedef void (*EditorBuildCallback)();
class EditorPluginList;
@@ -580,13 +581,18 @@ private:
void _toggle_distraction_free_mode();
enum {
- MAX_INIT_CALLBACKS=128
+ MAX_INIT_CALLBACKS=128,
+ MAX_BUILD_CALLBACKS=128
};
static int plugin_init_callback_count;
static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS];
+
+ void _call_build();
+ static int build_callback_count;
+ static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS];
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -754,6 +760,7 @@ public:
void get_singleton(const char* arg1, bool arg2);
static void add_init_callback(EditorNodeInitCallback p_callback) { _init_callbacks.push_back(p_callback); }
+ static void add_build_callback(EditorBuildCallback p_callback);
diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp
index aa66a2e0d9..3ab906f84e 100644
--- a/tools/editor/plugins/shader_graph_editor_plugin.cpp
+++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp
@@ -2422,6 +2422,7 @@ void ShaderGraphView::_create_node(int p_id) {
colors.push_back("Color");
colors.push_back("LightColor");
colors.push_back("Light");
+ colors.push_back("ShadowColor");
colors.push_back("Diffuse");
colors.push_back("Specular");
colors.push_back("Emmision");
@@ -2434,6 +2435,7 @@ void ShaderGraphView::_create_node(int p_id) {
reals.push_back("ShadeParam");
reals.push_back("SpecularExp");
reals.push_back("LightAlpha");
+ reals.push_back("ShadowAlpha");
reals.push_back("PointSize");
reals.push_back("Discard");