From 2af2a84a03fd707cfa4c682aff34d722343d8985 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Fri, 27 Jun 2014 23:21:45 -0300 Subject: [PATCH] Misc Fixes ========== -NOTIFICATION_WM_QUIT fixed on android (seems tha way this is reported changed in newer sdk) -WIP implementation of APK Expansion APIs for publishing games larger than 50mb in Play Store -Feaures in the new tutorials are all present in the sourcecode -This (hopefully) should get rid of the animation list order getting corrupted -Improved 3D Scene Importer (Skeletons, Animations and other stuff were not being merged). Anything missing? -In code editor, the automatic syntax checker will only use file_exists() to check preload() else it might freeze the editor too much while typing if the preload is a big resource -Fixed bugs in PolygonPathFinder, stil pending to do a node and a demo --- bin/tests/test_detailer.cpp | 2 +- bin/tests/test_misc.cpp | 4 +- bin/tests/test_particles.cpp | 2 +- bin/tests/test_render.cpp | 4 +- bin/tests/test_shader_lang.cpp | 4 +- core/globals.cpp | 17 +- core/globals.h | 2 +- core/io/resource_format_binary.cpp | 10 +- core/io/resource_format_binary.h | 1 + core/io/resource_format_xml.cpp | 14 +- core/io/resource_format_xml.h | 1 + core/io/resource_saver.h | 1 + core/resource.cpp | 15 +- core/resource.h | 2 +- core/ucaps.h | 6 +- demos/3d/platformer/engine.cfg | 2 + demos/3d/platformer/stage.xml | 34 ++- demos/3d/platformer/tiles.res | Bin 81673 -> 81338 bytes drivers/gles1/rasterizer_gles1.cpp | 63 ++--- drivers/gles1/rasterizer_gles1.h | 28 +-- drivers/gles2/rasterizer_gles2.cpp | 198 ++++++++++----- drivers/gles2/rasterizer_gles2.h | 25 +- drivers/gles2/shader_compiler_gles2.cpp | 47 +++- drivers/gles2/shader_compiler_gles2.h | 9 +- drivers/gles2/shader_gles2.cpp | 24 +- drivers/gles2/shader_gles2.h | 4 +- drivers/gles2/shaders/copy.glsl | 75 +++++- drivers/gles2/shaders/material.glsl | 62 +++-- main/main.cpp | 21 +- modules/gdscript/gd_editor.cpp | 2 +- modules/gdscript/gd_parser.cpp | 26 +- modules/gdscript/gd_parser.h | 3 +- platform/android/export/export.cpp | 39 ++- .../java/src/com/android/godot/Godot.java | 232 ++++++++++++++---- .../godot/GodotDownloaderAlarmReceiver.java | 27 ++ .../android/godot/GodotDownloaderService.java | 47 ++++ platform/android/java_glue.cpp | 46 +++- platform/android/os_android.cpp | 21 +- platform/android/os_android.h | 3 +- scene/3d/camera.cpp | 2 +- scene/3d/follow_camera.cpp | 2 +- scene/3d/light.cpp | 7 +- scene/3d/light.h | 1 - scene/3d/particles.cpp | 2 +- scene/3d/portal.cpp | 2 +- scene/3d/room_instance.cpp | 2 +- scene/3d/skeleton.cpp | 2 +- scene/3d/spatial_player.cpp | 2 +- scene/resources/environment.cpp | 26 +- scene/resources/environment.h | 13 +- scene/resources/material.cpp | 124 +++------- scene/resources/material.h | 62 ++--- scene/resources/polygon_path_finder.cpp | 156 ++++++++++-- scene/resources/polygon_path_finder.h | 6 +- scene/resources/shader.cpp | 23 +- scene/resources/shader.h | 3 +- servers/visual/rasterizer.cpp | 127 +++++++--- servers/visual/rasterizer.h | 24 +- servers/visual/rasterizer_dummy.cpp | 42 ++-- servers/visual/rasterizer_dummy.h | 22 +- servers/visual/shader_language.cpp | 55 ++++- servers/visual/shader_language.h | 4 +- servers/visual/visual_server_raster.cpp | 51 ++-- servers/visual/visual_server_raster.h | 18 +- servers/visual/visual_server_wrap_mt.h | 15 +- servers/visual_server.cpp | 6 +- servers/visual_server.h | 68 ++--- tools/editor/editor_node.cpp | 1 + .../io_plugins/editor_import_collada.cpp | 8 +- .../io_plugins/editor_scene_import_plugin.cpp | 47 +++- tools/editor/plugins/shader_editor_plugin.cpp | 17 +- tools/editor/plugins/shader_editor_plugin.h | 1 + tools/editor/resources_dock.cpp | 2 +- tools/editor/spatial_editor_gizmos.cpp | 12 +- 74 files changed, 1416 insertions(+), 662 deletions(-) create mode 100644 platform/android/java/src/com/android/godot/GodotDownloaderAlarmReceiver.java create mode 100644 platform/android/java/src/com/android/godot/GodotDownloaderService.java diff --git a/bin/tests/test_detailer.cpp b/bin/tests/test_detailer.cpp index 7eac6755d7b..4cb927411a1 100644 --- a/bin/tests/test_detailer.cpp +++ b/bin/tests/test_detailer.cpp @@ -176,7 +176,7 @@ public: vs->camera_set_transform(camera, Transform( Matrix3(), Vector3(0,0,2 ) ) ); RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL ); - vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.3,0.3,0.3) ); + //vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.3,0.3,0.3) ); light = vs->instance_create2( lightaux,scenario ); vs->instance_set_transform(light,Transform(Matrix3(Vector3(0.1,0.4,0.7).normalized(),0.9))); diff --git a/bin/tests/test_misc.cpp b/bin/tests/test_misc.cpp index 32d1bbf0903..819afc0d06d 100644 --- a/bin/tests/test_misc.cpp +++ b/bin/tests/test_misc.cpp @@ -407,7 +407,7 @@ public: RID cylinder_material = vs->fixed_material_create(); vs->fixed_material_set_param( cylinder_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(0.8,0.2,0.9)); vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_ONTOP,true); - vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_WIREFRAME,true); + //vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_WIREFRAME,true); vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_DOUBLE_SIDED,true); vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_UNSHADED,true); @@ -429,7 +429,7 @@ public: light = vs->instance_create2( lightaux ); */ RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL ); - vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) ); + //vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) ); //vs->light_set_shadow( lightaux, true ); RID light = vs->instance_create2( lightaux,scenario ); diff --git a/bin/tests/test_particles.cpp b/bin/tests/test_particles.cpp index f6f526fb218..2ccbb310172 100644 --- a/bin/tests/test_particles.cpp +++ b/bin/tests/test_particles.cpp @@ -87,7 +87,7 @@ public: light = vs->instance_create2( lightaux ); */ RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL ); - vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) ); + // vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) ); light = vs->instance_create2( lightaux, scenario ); ofs=0; diff --git a/bin/tests/test_render.cpp b/bin/tests/test_render.cpp index b45b356ee3d..cad3658d845 100644 --- a/bin/tests/test_render.cpp +++ b/bin/tests/test_render.cpp @@ -185,7 +185,7 @@ public: //* lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL ); - vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) ); + //vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) ); vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_DIFFUSE, Color(1.0,1.0,1.0) ); //vs->light_set_shadow( lightaux, true ); light = vs->instance_create2( lightaux, scenario ); @@ -198,7 +198,7 @@ public: //* lightaux = vs->light_create( VisualServer::LIGHT_OMNI ); - vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,1.0) ); +// vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,1.0) ); vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_DIFFUSE, Color(1.0,1.0,0.0) ); vs->light_set_param( lightaux, VisualServer::LIGHT_PARAM_RADIUS, 4 ); vs->light_set_param( lightaux, VisualServer::LIGHT_PARAM_ENERGY, 8 ); diff --git a/bin/tests/test_shader_lang.cpp b/bin/tests/test_shader_lang.cpp index 3ee32fe1aaf..059781b64cd 100644 --- a/bin/tests/test_shader_lang.cpp +++ b/bin/tests/test_shader_lang.cpp @@ -264,13 +264,15 @@ static String dump_node_code(SL::Node *p_node,int p_level) { } -static void recreate_code(void *p_str,SL::ProgramNode *p_program) { +static Error recreate_code(void *p_str,SL::ProgramNode *p_program) { print_line("recr"); String *str=(String*)p_str; *str=dump_node_code(p_program,0); + return OK; + } diff --git a/core/globals.cpp b/core/globals.cpp index 7df76808278..3a04becef45 100644 --- a/core/globals.cpp +++ b/core/globals.cpp @@ -243,12 +243,27 @@ bool Globals::_load_resource_pack(const String& p_pack) { return true; } -Error Globals::setup(const String& p_path) { +Error Globals::setup(const String& p_path,const String & p_main_pack) { //an absolute mess of a function, must be cleaned up and reorganized somehow at some point //_load_settings(p_path+"/override.cfg"); + if (p_main_pack!="") { + + bool ok = _load_resource_pack(p_main_pack); + ERR_FAIL_COND_V(!ok,ERR_CANT_OPEN); + + if (_load_settings("res://engine.cfg")==OK || _load_settings_binary("res://engine.cfb")==OK) { + + _load_settings("res://override.cfg"); + + } + + return OK; + + } + if (OS::get_singleton()->get_executable_path()!="") { if (_load_resource_pack(OS::get_singleton()->get_executable_path())) { diff --git a/core/globals.h b/core/globals.h index b8dc3f93675..580fd0fecd1 100644 --- a/core/globals.h +++ b/core/globals.h @@ -110,7 +110,7 @@ public: int get_order(const String& p_name) const; void set_order(const String& p_name, int p_order); - Error setup(const String& p_path); + Error setup(const String& p_path, const String &p_main_pack); Error save_custom(const String& p_path="",const CustomMap& p_custom=CustomMap(),const Set& p_ignore_masks=Set()); Error save(); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 33f4cafeddf..e2371fe24f4 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1751,7 +1751,10 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_ skip_editor=p_flags&ResourceSaver::FLAG_OMIT_EDITOR_PROPERTIES; bundle_resources=p_flags&ResourceSaver::FLAG_BUNDLE_RESOURCES; big_endian=p_flags&ResourceSaver::FLAG_SAVE_BIG_ENDIAN; + takeover_paths=p_flags&ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; + if (!p_path.begins_with("res://")) + takeover_paths=false; local_path=p_path.get_base_dir(); //bin_meta_idx = get_string_index("__bin_meta__"); //is often used, so create @@ -1841,9 +1844,12 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_ for(List::Element *E=saved_resources.front();E;E=E->next()) { RES r = E->get(); - if (r->get_path()=="" || r->get_path().find("::")!=-1) + if (r->get_path()=="" || r->get_path().find("::")!=-1) { save_unicode_string("local://"+itos(ofs_pos.size())); - else + if (takeover_paths) { + r->set_path(p_path+"::"+itos(ofs_pos.size()),true); + } + } else save_unicode_string(r->get_path()); //actual external ofs_pos.push_back(f->get_pos()); f->store_64(0); //offset in 64 bits diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index bd33fee82ce..cc26357bfb4 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -125,6 +125,7 @@ class ResourceFormatSaverBinaryInstance { bool bundle_resources; bool skip_editor; bool big_endian; + bool takeover_paths; int bin_meta_idx; FileAccess *f; String magic; diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp index dae95097d3e..e6eede7de61 100644 --- a/core/io/resource_format_xml.cpp +++ b/core/io/resource_format_xml.cpp @@ -2505,6 +2505,10 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res relative_paths=p_flags&ResourceSaver::FLAG_RELATIVE_PATHS; skip_editor=p_flags&ResourceSaver::FLAG_OMIT_EDITOR_PROPERTIES; bundle_resources=p_flags&ResourceSaver::FLAG_BUNDLE_RESOURCES; + takeover_paths=p_flags&ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; + if (!p_path.begins_with("res://")) { + takeover_paths=false; + } depth=0; // save resources @@ -2541,8 +2545,14 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res enter_tag("main_resource",""); //bundled else if (res->get_path().length() && res->get_path().find("::") == -1 ) enter_tag("resource","type=\""+res->get_type()+"\" path=\""+res->get_path()+"\""); //bundled - else - enter_tag("resource","type=\""+res->get_type()+"\" path=\"local://"+itos(resource_map[res])+"\""); + else { + int idx = resource_map[res]; + enter_tag("resource","type=\""+res->get_type()+"\" path=\"local://"+itos(idx)+"\""); + if (takeover_paths) { + res->set_path(p_path+"::"+itos(idx),true); + } + + } write_string("\n",false); diff --git a/core/io/resource_format_xml.h b/core/io/resource_format_xml.h index cfa47449150..40aaa014513 100644 --- a/core/io/resource_format_xml.h +++ b/core/io/resource_format_xml.h @@ -117,6 +117,7 @@ class ResourceFormatSaverXMLInstance { + bool takeover_paths; bool relative_paths; bool bundle_resources; bool skip_editor; diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h index fd4575c8726..e3076687216 100644 --- a/core/io/resource_saver.h +++ b/core/io/resource_saver.h @@ -74,6 +74,7 @@ public: FLAG_OMIT_EDITOR_PROPERTIES=8, FLAG_SAVE_BIG_ENDIAN=16, FLAG_COMPRESS=32, + FLAG_REPLACE_SUBRESOURCE_PATHS=64, }; diff --git a/core/resource.cpp b/core/resource.cpp index f07c37fb06d..ccfeaa6bb97 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -157,7 +157,7 @@ void Resource::_resource_path_changed() { } -void Resource::set_path(const String& p_path) { +void Resource::set_path(const String& p_path, bool p_take_over) { if (path_cache==p_path) return; @@ -168,7 +168,16 @@ void Resource::set_path(const String& p_path) { } path_cache=""; - ERR_FAIL_COND( ResourceCache::resources.has( p_path ) ); + if (ResourceCache::resources.has( p_path )) { + if (p_take_over) { + + ResourceCache::resources.get(p_path)->set_name(""); + } else { + ERR_EXPLAIN("Another resource is loaded from path: "+p_path); + ERR_FAIL_COND( ResourceCache::resources.has( p_path ) ); + } + + } path_cache=p_path; if (path_cache!="") { @@ -240,7 +249,7 @@ void Resource::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_path","path"),&Resource::set_path); ObjectTypeDB::bind_method(_MD("get_path"),&Resource::get_path); - ObjectTypeDB::bind_method(_MD("set_name","name"),&Resource::set_name); + ObjectTypeDB::bind_method(_MD("set_name","name","take_over"),&Resource::set_name,DEFVAL(false)); ObjectTypeDB::bind_method(_MD("get_name"),&Resource::get_name); ObjectTypeDB::bind_method(_MD("get_rid"),&Resource::get_rid); ObjectTypeDB::bind_method(_MD("set_import_metadata","metadata"),&Resource::set_import_metadata); diff --git a/core/resource.h b/core/resource.h index 8d2c72d1205..2e336e1cafc 100644 --- a/core/resource.h +++ b/core/resource.h @@ -126,7 +126,7 @@ public: void set_name(const String& p_name); String get_name() const; - void set_path(const String& p_path); + void set_path(const String& p_path,bool p_take_over=false); String get_path() const; Ref duplicate(bool p_subresources=false); diff --git a/core/ucaps.h b/core/ucaps.h index 855a946c211..9c07828006a 100644 --- a/core/ucaps.h +++ b/core/ucaps.h @@ -673,7 +673,7 @@ static const int caps_table[CAPS_LEN][2]={ {0xFF5A,0xFF3A}, }; -static const int reverse_caps_table[CAPS_LEN][2]={ +static const int reverse_caps_table[CAPS_LEN-1][2]={ {0x41,0x61}, {0x42,0x62}, {0x43,0x63}, @@ -755,7 +755,7 @@ static const int reverse_caps_table[CAPS_LEN][2]={ {0x12a,0x12b}, {0x12c,0x12d}, {0x12e,0x12f}, -{0x49,0x131}, +//{0x49,0x131}, {0x132,0x133}, {0x134,0x135}, {0x136,0x137}, @@ -1370,7 +1370,7 @@ static int _find_lower(int ch) { int low = 0; - int high = CAPS_LEN -1; + int high = CAPS_LEN -2; int middle; while( low <= high ) diff --git a/demos/3d/platformer/engine.cfg b/demos/3d/platformer/engine.cfg index f4b380f4db1..793ac36364c 100644 --- a/demos/3d/platformer/engine.cfg +++ b/demos/3d/platformer/engine.cfg @@ -24,3 +24,5 @@ max_shadow_buffer_size=1024 framebuffer_shrink=1 shadow_filter=3 debug_shadow_maps=false +fp16_framebuffer=true +debug_hdr=false diff --git a/demos/3d/platformer/stage.xml b/demos/3d/platformer/stage.xml index 25722cbc718..f3a5caffa9f 100644 --- a/demos/3d/platformer/stage.xml +++ b/demos/3d/platformer/stage.xml @@ -1,11 +1,14 @@ - - + + + True + 0, 0.409429, 0.596681, 1 + 1 False 4 0, 0, 0, 1 @@ -43,16 +46,17 @@ 1 1 1.608 - False - 1.414214 + False "names" - + "world" "Spatial" + "_import_path" + "_import_transform" "__meta__" "GridMap" "theme/theme" @@ -71,13 +75,14 @@ "params/enabled" "params/bake_mode" "params/energy" - "colors/ambient" "colors/diffuse" "colors/specular" "shadow/shadow" "shadow/darkening" "shadow/z_offset" "shadow/z_slope_scale" + "shadow/esm_multiplier" + "shadow/blur_passes" "projector" "operator" "shadow/mode" @@ -148,7 +153,9 @@ "node_count" 55 "variants" - + + "" + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 "__editor_plugin_states__" @@ -175,17 +182,17 @@ "distance" - 4.173348 + 0.261354 "x_rot" - 0.558294 + 0.458294 "y_rot" - 1.049999 + -1.2 "use_orthogonal" False "use_environment" False "pos" - 13.4293, 5.68289, 13.9717 + 13.4535, 5.75047, 13.8175 "distance" @@ -272,11 +279,12 @@ 1 0 1.5 - 0.159092, 0.219774, 0.52093, 1 1, 1, 1, 1 0 0.08 0.5 + 60 + 1 2 40 0.410558 @@ -339,7 +347,7 @@ 0.0160676, 0, -0.999871, 0, 1, 0, 0.999871, 0, 0.0160676, 8.50167, 4.15811, 15.9334 "nodes" - -1, -1, 1, 0, -1, 1, 2, 0, 0, 0, 0, 3, 3, -1, 11, 4, 1, 5, 2, 6, 2, 7, 3, 8, 4, 9, 5, 10, 5, 11, 5, 12, 6, 13, 7, 2, 8, 0, 0, 0, 14, 14, -1, 18, 15, 9, 16, 10, 17, 5, 18, 11, 19, 12, 20, 13, 21, 14, 22, 14, 23, 5, 24, 15, 25, 16, 26, 17, 27, 18, 28, 11, 29, 19, 30, 20, 31, 21, 32, 3, 0, 0, 0, 34, 33, -1, 1, 33, 22, 0, 0, 0, 36, 35, -1, 1, 2, 23, 0, 4, 0, 38, 37, 24, 1, 15, 25, 0, 4, 0, 38, 39, 24, 1, 15, 26, 0, 4, 0, 38, 40, 24, 1, 15, 27, 0, 4, 0, 38, 41, 24, 1, 15, 28, 0, 4, 0, 38, 42, 24, 1, 15, 29, 0, 4, 0, 38, 43, 24, 1, 15, 30, 0, 4, 0, 38, 44, 24, 1, 15, 31, 0, 4, 0, 38, 45, 24, 1, 15, 32, 0, 4, 0, 38, 46, 24, 1, 15, 33, 0, 4, 0, 38, 47, 24, 1, 15, 34, 0, 4, 0, 38, 48, 24, 1, 15, 35, 0, 4, 0, 38, 49, 24, 1, 15, 36, 0, 4, 0, 38, 50, 24, 1, 15, 37, 0, 4, 0, 38, 51, 24, 1, 15, 38, 0, 4, 0, 38, 52, 24, 1, 15, 39, 0, 4, 0, 38, 53, 24, 1, 15, 40, 0, 4, 0, 38, 54, 24, 1, 15, 41, 0, 4, 0, 38, 55, 24, 1, 15, 42, 0, 4, 0, 38, 56, 24, 1, 15, 43, 0, 4, 0, 38, 57, 24, 1, 15, 44, 0, 4, 0, 38, 58, 24, 1, 15, 45, 0, 4, 0, 38, 59, 24, 1, 15, 46, 0, 4, 0, 38, 60, 24, 1, 15, 47, 0, 4, 0, 38, 61, 24, 1, 15, 48, 0, 4, 0, 38, 62, 24, 1, 15, 49, 0, 4, 0, 38, 63, 24, 1, 15, 50, 0, 4, 0, 38, 64, 24, 1, 15, 51, 0, 4, 0, 38, 65, 24, 1, 15, 52, 0, 4, 0, 38, 66, 24, 1, 15, 53, 0, 4, 0, 38, 67, 24, 1, 15, 54, 0, 4, 0, 38, 68, 24, 1, 15, 55, 0, 4, 0, 38, 69, 24, 1, 15, 56, 0, 4, 0, 38, 70, 24, 1, 15, 57, 0, 4, 0, 38, 71, 24, 1, 15, 58, 0, 4, 0, 38, 72, 24, 1, 15, 59, 0, 4, 0, 38, 73, 24, 1, 15, 60, 0, 4, 0, 38, 74, 24, 1, 15, 61, 0, 4, 0, 38, 75, 24, 1, 15, 62, 0, 4, 0, 38, 76, 24, 1, 15, 63, 0, 4, 0, 38, 77, 24, 1, 15, 64, 0, 4, 0, 38, 78, 24, 1, 15, 65, 0, 4, 0, 38, 79, 24, 1, 15, 66, 0, 4, 0, 38, 80, 24, 1, 15, 67, 0, 4, 0, 38, 81, 24, 1, 15, 68, 0, 0, 0, 36, 82, -1, 0, 0, 49, 0, 84, 83, 69, 1, 15, 70, 0, 49, 0, 84, 85, 69, 1, 15, 71, 0, 49, 0, 84, 86, 69, 1, 15, 72, 0, 49, 0, 84, 87, 69, 1, 15, 73, 0, 0, 0, 84, 88, 74, 1, 15, 75, 0 + -1, -1, 1, 0, -1, 3, 2, 0, 3, 1, 4, 2, 0, 0, 0, 5, 5, -1, 13, 2, 0, 3, 1, 6, 3, 7, 4, 8, 4, 9, 5, 10, 6, 11, 7, 12, 7, 13, 7, 14, 8, 15, 9, 4, 10, 0, 0, 0, 16, 16, -1, 21, 2, 0, 3, 1, 17, 11, 18, 12, 19, 7, 20, 13, 21, 14, 22, 15, 23, 15, 24, 7, 25, 16, 26, 17, 27, 18, 28, 19, 29, 20, 30, 21, 31, 13, 32, 22, 33, 23, 34, 24, 35, 5, 0, 0, 0, 37, 36, -1, 3, 2, 0, 3, 1, 36, 25, 0, 0, 0, 39, 38, -1, 2, 2, 0, 4, 26, 0, 4, 0, 41, 40, 27, 1, 17, 28, 0, 4, 0, 41, 42, 27, 1, 17, 29, 0, 4, 0, 41, 43, 27, 1, 17, 30, 0, 4, 0, 41, 44, 27, 1, 17, 31, 0, 4, 0, 41, 45, 27, 1, 17, 32, 0, 4, 0, 41, 46, 27, 1, 17, 33, 0, 4, 0, 41, 47, 27, 1, 17, 34, 0, 4, 0, 41, 48, 27, 1, 17, 35, 0, 4, 0, 41, 49, 27, 1, 17, 36, 0, 4, 0, 41, 50, 27, 1, 17, 37, 0, 4, 0, 41, 51, 27, 1, 17, 38, 0, 4, 0, 41, 52, 27, 1, 17, 39, 0, 4, 0, 41, 53, 27, 1, 17, 40, 0, 4, 0, 41, 54, 27, 1, 17, 41, 0, 4, 0, 41, 55, 27, 1, 17, 42, 0, 4, 0, 41, 56, 27, 1, 17, 43, 0, 4, 0, 41, 57, 27, 1, 17, 44, 0, 4, 0, 41, 58, 27, 1, 17, 45, 0, 4, 0, 41, 59, 27, 1, 17, 46, 0, 4, 0, 41, 60, 27, 1, 17, 47, 0, 4, 0, 41, 61, 27, 1, 17, 48, 0, 4, 0, 41, 62, 27, 1, 17, 49, 0, 4, 0, 41, 63, 27, 1, 17, 50, 0, 4, 0, 41, 64, 27, 1, 17, 51, 0, 4, 0, 41, 65, 27, 1, 17, 52, 0, 4, 0, 41, 66, 27, 1, 17, 53, 0, 4, 0, 41, 67, 27, 1, 17, 54, 0, 4, 0, 41, 68, 27, 1, 17, 55, 0, 4, 0, 41, 69, 27, 1, 17, 56, 0, 4, 0, 41, 70, 27, 1, 17, 57, 0, 4, 0, 41, 71, 27, 1, 17, 58, 0, 4, 0, 41, 72, 27, 1, 17, 59, 0, 4, 0, 41, 73, 27, 1, 17, 60, 0, 4, 0, 41, 74, 27, 1, 17, 61, 0, 4, 0, 41, 75, 27, 1, 17, 62, 0, 4, 0, 41, 76, 27, 1, 17, 63, 0, 4, 0, 41, 77, 27, 1, 17, 64, 0, 4, 0, 41, 78, 27, 1, 17, 65, 0, 4, 0, 41, 79, 27, 1, 17, 66, 0, 4, 0, 41, 80, 27, 1, 17, 67, 0, 4, 0, 41, 81, 27, 1, 17, 68, 0, 4, 0, 41, 82, 27, 1, 17, 69, 0, 4, 0, 41, 83, 27, 1, 17, 70, 0, 4, 0, 41, 84, 27, 1, 17, 71, 0, 0, 0, 39, 85, -1, 1, 2, 0, 0, 49, 0, 87, 86, 72, 1, 17, 73, 0, 49, 0, 87, 88, 72, 1, 17, 74, 0, 49, 0, 87, 89, 72, 1, 17, 75, 0, 49, 0, 87, 90, 72, 1, 17, 76, 0, 0, 0, 87, 91, 77, 1, 17, 78, 0 "conns" diff --git a/demos/3d/platformer/tiles.res b/demos/3d/platformer/tiles.res index e7e810f23fb1e4803737e24f8898c98dc7a92eae..53534788a1a3b67debecbffb2e1090d74a873d6e 100644 GIT binary patch delta 28754 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 Q%W=b>E?`wn5r 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 mi=}^YqxM$DyKU*-~TlqhQ31s#F diff --git a/drivers/gles1/rasterizer_gles1.cpp b/drivers/gles1/rasterizer_gles1.cpp index 9a6c928711b..ad0c8e3c7f9 100644 --- a/drivers/gles1/rasterizer_gles1.cpp +++ b/drivers/gles1/rasterizer_gles1.cpp @@ -891,6 +891,7 @@ RID RasterizerGLES1::shader_create(VS::ShaderMode p_mode) { shader->has_alpha=false; shader->fragment_line=0; shader->vertex_line=0; + shader->light_line=0; RID rid = shader_owner.make_rid(shader); shader_set_mode(rid,p_mode); // _shader_make_dirty(shader); @@ -921,19 +922,22 @@ VS::ShaderMode RasterizerGLES1::shader_get_mode(RID p_shader) const { -void RasterizerGLES1::shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,int p_vertex_ofs,int p_fragment_ofs) { +void RasterizerGLES1::shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,const String& p_light,int p_vertex_ofs,int p_fragment_ofs,int p_light_ofs) { + Shader *shader=shader_owner.get(p_shader); ERR_FAIL_COND(!shader); #ifdef DEBUG_ENABLED - if (shader->vertex_code==p_vertex && shader->fragment_code==p_fragment) + if (shader->vertex_code==p_vertex && shader->fragment_code==p_fragment && shader->light_code==p_light) return; #endif shader->fragment_code=p_fragment; shader->vertex_code=p_vertex; + shader->light_code=p_light; shader->fragment_line=p_fragment_ofs; shader->vertex_line=p_vertex_ofs; + shader->light_line=p_light_ofs; } @@ -953,6 +957,13 @@ String RasterizerGLES1::shader_get_fragment_code(RID p_shader) const { } +String RasterizerGLES1::shader_get_light_code(RID p_shader) const { + + Shader *shader=shader_owner.get(p_shader); + ERR_FAIL_COND_V(!shader,String()); + return shader->light_code; + +} void RasterizerGLES1::shader_get_param_list(RID p_shader, List *p_param_list) const { @@ -1099,39 +1110,21 @@ bool RasterizerGLES1::material_get_flag(RID p_material,VS::MaterialFlag p_flag) } -void RasterizerGLES1::material_set_hint(RID p_material, VS::MaterialHint p_hint,bool p_enabled) { +void RasterizerGLES1::material_set_depth_draw_mode(RID p_material, VS::MaterialDepthDrawMode p_mode) { Material *material = material_owner.get(p_material); ERR_FAIL_COND(!material); - ERR_FAIL_INDEX(p_hint,VS::MATERIAL_HINT_MAX); - material->hints[p_hint]=p_enabled; - + material->depth_draw_mode=p_mode; } -bool RasterizerGLES1::material_get_hint(RID p_material,VS::MaterialHint p_hint) const { +VS::MaterialDepthDrawMode RasterizerGLES1::material_get_depth_draw_mode(RID p_material) const{ + Material *material = material_owner.get(p_material); - ERR_FAIL_COND_V(!material,false); - ERR_FAIL_INDEX_V(p_hint,VS::MATERIAL_HINT_MAX,false); - return material->hints[p_hint]; - + ERR_FAIL_COND_V(!material,VS::MATERIAL_DEPTH_DRAW_ALWAYS); + return material->depth_draw_mode; } -void RasterizerGLES1::material_set_shade_model(RID p_material, VS::MaterialShadeModel p_model) { - - Material *material = material_owner.get(p_material); - ERR_FAIL_COND(!material); - material->shade_model=p_model; - -}; - -VS::MaterialShadeModel RasterizerGLES1::material_get_shade_model(RID p_material) const { - - Material *material = material_owner.get(p_material); - ERR_FAIL_COND_V(!material,VS::MATERIAL_SHADE_MODEL_LAMBERT); - return material->shade_model; -}; - void RasterizerGLES1::material_set_blend_mode(RID p_material,VS::MaterialBlendMode p_mode) { @@ -1223,20 +1216,6 @@ RID RasterizerGLES1::fixed_material_get_texture(RID p_material,VS::FixedMaterial return m->textures[p_parameter]; } -void RasterizerGLES1::fixed_material_set_detail_blend_mode(RID p_material,VS::MaterialBlendMode p_mode) { - - Material *m=material_owner.get( p_material ); - ERR_FAIL_COND(!m); - - m->detail_blend_mode = p_mode; -} -VS::MaterialBlendMode RasterizerGLES1::fixed_material_get_detail_blend_mode(RID p_material) const { - - Material *m=material_owner.get( p_material ); - ERR_FAIL_COND_V(!m, VS::MATERIAL_BLEND_MODE_MIX); - - return m->detail_blend_mode; -} void RasterizerGLES1::fixed_material_set_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter, VS::FixedMaterialTexCoordMode p_mode) { @@ -3395,7 +3374,7 @@ void RasterizerGLES1::_setup_material(const Geometry *p_geometry,const Material } - bool current_depth_write=!p_material->hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW]; + bool current_depth_write=p_material->depth_draw_mode!=VS::MATERIAL_DEPTH_DRAW_ALWAYS; //broken bool current_depth_test=!p_material->flags[VS::MATERIAL_FLAG_ONTOP]; @@ -3460,7 +3439,7 @@ void RasterizerGLES1::_setup_light(LightInstance* p_instance, int p_idx) { glLightfv(glid , GL_DIFFUSE, diffuse_sdark); - Color amb_color = ld->colors[VS::LIGHT_COLOR_AMBIENT]; + Color amb_color = Color(0,0,0); GLfloat amb_stexsize[4]={ amb_color.r, amb_color.g, diff --git a/drivers/gles1/rasterizer_gles1.h b/drivers/gles1/rasterizer_gles1.h index 10b2d7694de..e7937f43c3d 100644 --- a/drivers/gles1/rasterizer_gles1.h +++ b/drivers/gles1/rasterizer_gles1.h @@ -132,10 +132,12 @@ class RasterizerGLES1 : public Rasterizer { String vertex_code; String fragment_code; + String light_code; VS::ShaderMode mode; Map params; int fragment_line; int vertex_line; + int light_line; bool valid; bool has_alpha; bool use_world_transform; @@ -149,15 +151,14 @@ class RasterizerGLES1 : public Rasterizer { bool fixed_flags[VS::FIXED_MATERIAL_FLAG_MAX]; bool flags[VS::MATERIAL_FLAG_MAX]; - bool hints[VS::MATERIAL_HINT_MAX]; Variant parameters[VisualServer::FIXED_MATERIAL_PARAM_MAX]; RID textures[VisualServer::FIXED_MATERIAL_PARAM_MAX]; - VS::MaterialShadeModel shade_model; + VS::MaterialDepthDrawMode depth_draw_mode; + Transform uv_transform; VS::FixedMaterialTexCoordMode texcoord_mode[VisualServer::FIXED_MATERIAL_PARAM_MAX]; - VS::MaterialBlendMode detail_blend_mode; VS::MaterialBlendMode blend_mode; float line_width; @@ -179,8 +180,6 @@ class RasterizerGLES1 : public Rasterizer { for(int i=0;i *p_param_list) const; @@ -881,11 +881,8 @@ public: virtual void material_set_flag(RID p_material, VS::MaterialFlag p_flag,bool p_enabled); virtual bool material_get_flag(RID p_material,VS::MaterialFlag p_flag) const; - virtual void material_set_hint(RID p_material, VS::MaterialHint p_hint,bool p_enabled); - virtual bool material_get_hint(RID p_material,VS::MaterialHint p_hint) const; - - virtual void material_set_shade_model(RID p_material, VS::MaterialShadeModel p_model); - virtual VS::MaterialShadeModel material_get_shade_model(RID p_material) const; + virtual void material_set_depth_draw_mode(RID p_material, VS::MaterialDepthDrawMode p_mode); + virtual VS::MaterialDepthDrawMode material_get_depth_draw_mode(RID p_material) const; virtual void material_set_blend_mode(RID p_material,VS::MaterialBlendMode p_mode); virtual VS::MaterialBlendMode material_get_blend_mode(RID p_material) const; @@ -906,9 +903,6 @@ public: virtual void fixed_material_set_texture(RID p_material,VS::FixedMaterialParam p_parameter, RID p_texture); virtual RID fixed_material_get_texture(RID p_material,VS::FixedMaterialParam p_parameter) const; - virtual void fixed_material_set_detail_blend_mode(RID p_material,VS::MaterialBlendMode p_mode); - virtual VS::MaterialBlendMode fixed_material_get_detail_blend_mode(RID p_material) const; - virtual void fixed_material_set_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter, VS::FixedMaterialTexCoordMode p_mode); virtual VS::FixedMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter) const; diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index d660d02f6cd..681a0e72654 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -1132,20 +1132,22 @@ VS::ShaderMode RasterizerGLES2::shader_get_mode(RID p_shader) const { } +void RasterizerGLES2::shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,const String& p_light,int p_vertex_ofs,int p_fragment_ofs,int p_light_ofs) { -void RasterizerGLES2::shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,int p_vertex_ofs,int p_fragment_ofs) { Shader *shader=shader_owner.get(p_shader); ERR_FAIL_COND(!shader); #ifdef DEBUG_ENABLED - if (shader->vertex_code==p_vertex && shader->fragment_code==p_fragment) + if (shader->vertex_code==p_vertex && shader->fragment_code==p_fragment && shader->light_code==p_light) return; #endif shader->fragment_code=p_fragment; shader->vertex_code=p_vertex; + shader->light_code=p_light; shader->fragment_line=p_fragment_ofs; shader->vertex_line=p_vertex_ofs; + shader->light_line=p_light_ofs; _shader_make_dirty(shader); } @@ -1166,6 +1168,14 @@ String RasterizerGLES2::shader_get_fragment_code(RID p_shader) const { } +String RasterizerGLES2::shader_get_light_code(RID p_shader) const { + + Shader *shader=shader_owner.get(p_shader); + ERR_FAIL_COND_V(!shader,String()); + return shader->light_code; + +} + void RasterizerGLES2::_shader_make_dirty(Shader* p_shader) { if (p_shader->dirty_list.in_list()) @@ -1334,38 +1344,22 @@ bool RasterizerGLES2::material_get_flag(RID p_material,VS::MaterialFlag p_flag) } -void RasterizerGLES2::material_set_hint(RID p_material, VS::MaterialHint p_hint,bool p_enabled) { +void RasterizerGLES2::material_set_depth_draw_mode(RID p_material, VS::MaterialDepthDrawMode p_mode) { Material *material = material_owner.get(p_material); ERR_FAIL_COND(!material); - ERR_FAIL_INDEX(p_hint,VS::MATERIAL_HINT_MAX); - material->hints[p_hint]=p_enabled; + material->depth_draw_mode=p_mode; } -bool RasterizerGLES2::material_get_hint(RID p_material,VS::MaterialHint p_hint) const { +VS::MaterialDepthDrawMode RasterizerGLES2::material_get_depth_draw_mode(RID p_material) const { Material *material = material_owner.get(p_material); - ERR_FAIL_COND_V(!material,false); - ERR_FAIL_INDEX_V(p_hint,VS::MATERIAL_HINT_MAX,false); - return material->hints[p_hint]; + ERR_FAIL_COND_V(!material,VS::MATERIAL_DEPTH_DRAW_ALWAYS); + return material->depth_draw_mode; } -void RasterizerGLES2::material_set_shade_model(RID p_material, VS::MaterialShadeModel p_model) { - - Material *material = material_owner.get(p_material); - ERR_FAIL_COND(!material); - material->shade_model=p_model; - -}; - -VS::MaterialShadeModel RasterizerGLES2::material_get_shade_model(RID p_material) const { - - Material *material = material_owner.get(p_material); - ERR_FAIL_COND_V(!material,VS::MATERIAL_SHADE_MODEL_LAMBERT); - return material->shade_model; -}; void RasterizerGLES2::material_set_blend_mode(RID p_material,VS::MaterialBlendMode p_mode) { @@ -3455,14 +3449,21 @@ RID RasterizerGLES2::viewport_data_create() { glGenFramebuffers(1, &vd->lum_fbo); glBindFramebuffer(GL_FRAMEBUFFER, vd->lum_fbo); + GLuint format_luminance = use_fp16_fb?_GL_RG_EXT:GL_RGBA; + GLuint format_luminance_type = use_fp16_fb?(full_float_fb_supported?GL_FLOAT:_GL_HALF_FLOAT_OES):GL_UNSIGNED_BYTE; + GLuint format_luminance_components = use_fp16_fb?_GL_RG_EXT:GL_RGBA; + glGenTextures(1, &vd->lum_color); glBindTexture(GL_TEXTURE_2D, vd->lum_color); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); + //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, + // GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, format_luminance, 1, 1, 0, + format_luminance_components, format_luminance_type, NULL); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, vd->lum_color, 0); @@ -3934,10 +3935,12 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const { String vertex_code; String vertex_globals; - ShaderCompilerGLES2::Flags flags; + ShaderCompilerGLES2::Flags vertex_flags; + ShaderCompilerGLES2::Flags fragment_flags; + ShaderCompilerGLES2::Flags light_flags; if (p_shader->mode==VS::SHADER_MATERIAL) { - Error err = shader_precompiler.compile(p_shader->vertex_code,ShaderLanguage::SHADER_MATERIAL_VERTEX,vertex_code,vertex_globals,flags,&p_shader->uniforms); + Error err = shader_precompiler.compile(p_shader->vertex_code,ShaderLanguage::SHADER_MATERIAL_VERTEX,vertex_code,vertex_globals,vertex_flags,&p_shader->uniforms); if (err) { return; //invalid } @@ -3950,11 +3953,26 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const { String fragment_code; String fragment_globals; - Error err = shader_precompiler.compile(p_shader->fragment_code,(p_shader->mode==VS::SHADER_MATERIAL?ShaderLanguage::SHADER_MATERIAL_FRAGMENT:ShaderLanguage::SHADER_POST_PROCESS),fragment_code,fragment_globals,flags,&p_shader->uniforms); + Error err = shader_precompiler.compile(p_shader->fragment_code,(p_shader->mode==VS::SHADER_MATERIAL?ShaderLanguage::SHADER_MATERIAL_FRAGMENT:ShaderLanguage::SHADER_POST_PROCESS),fragment_code,fragment_globals,fragment_flags,&p_shader->uniforms); if (err) { return; //invalid } + + String light_code; + String light_globals; + + if (p_shader->mode==VS::SHADER_MATERIAL) { + + Error err = shader_precompiler.compile(p_shader->light_code,(ShaderLanguage::SHADER_MATERIAL_LIGHT),light_code,light_globals,light_flags,&p_shader->uniforms); + if (err) { + return; //invalid + } + } + + fragment_globals+=light_globals; //both fragment anyway + + //print_line("compiled fragment: "+fragment_code); // ("compiled fragment globals: "+fragment_globals); @@ -3975,40 +3993,43 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const { if (p_shader->mode==VS::SHADER_MATERIAL) { //print_line("setting code to id.. "+itos(p_shader->custom_code_id)); Vector enablers; - if (flags.use_color_interp) + if (fragment_flags.use_color_interp) enablers.push_back("#define ENABLE_COLOR_INTERP\n"); - if (flags.use_uv_interp) + if (fragment_flags.use_uv_interp) enablers.push_back("#define ENABLE_UV_INTERP\n"); - if (flags.use_uv2_interp) + if (fragment_flags.use_uv2_interp) enablers.push_back("#define ENABLE_UV2_INTERP\n"); - if (flags.use_tangent_interp) + if (fragment_flags.use_tangent_interp) enablers.push_back("#define ENABLE_TANGENT_INTERP\n"); - if (flags.use_var1_interp) + if (fragment_flags.use_var1_interp) enablers.push_back("#define ENABLE_VAR1_INTERP\n"); - if (flags.use_var2_interp) + if (fragment_flags.use_var2_interp) enablers.push_back("#define ENABLE_VAR2_INTERP\n"); - if (flags.uses_texscreen) { + if (fragment_flags.uses_texscreen) { enablers.push_back("#define ENABLE_TEXSCREEN\n"); } - if (flags.uses_screen_uv) { + if (fragment_flags.uses_screen_uv) { enablers.push_back("#define ENABLE_SCREEN_UV\n"); } - if (flags.uses_discard) { + if (fragment_flags.uses_discard) { enablers.push_back("#define ENABLE_DISCARD\n"); } + if (light_flags.uses_light) { + enablers.push_back("#define USE_LIGHT_SHADER_CODE\n"); + } - material_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, fragment_globals,uniform_names,enablers); + material_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, light_code, fragment_globals,uniform_names,enablers); } else { //postprocess_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, fragment_globals,uniform_names); } p_shader->valid=true; - p_shader->has_alpha=flags.uses_alpha || flags.uses_texscreen; - p_shader->writes_vertex=flags.vertex_code_writes_vertex; - p_shader->uses_discard=flags.uses_discard; - p_shader->has_texscreen=flags.uses_texscreen; - p_shader->has_screen_uv=flags.uses_screen_uv; - p_shader->can_zpass=!flags.uses_discard && !flags.vertex_code_writes_vertex; + p_shader->has_alpha=fragment_flags.uses_alpha || fragment_flags.uses_texscreen; + p_shader->writes_vertex=vertex_flags.vertex_code_writes_vertex; + p_shader->uses_discard=fragment_flags.uses_discard; + p_shader->has_texscreen=fragment_flags.uses_texscreen; + p_shader->has_screen_uv=fragment_flags.uses_screen_uv; + p_shader->can_zpass=!fragment_flags.uses_discard && !vertex_flags.vertex_code_writes_vertex; p_shader->version++; } @@ -4073,10 +4094,10 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD if (shadow) { - if (has_blend_alpha || (has_base_alpha && !m->hints[VS::MATERIAL_HINT_OPAQUE_PRE_PASS])) + if (has_blend_alpha || (has_base_alpha && m->depth_draw_mode!=VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA)) return; //bye - if (m->shader_cache && !m->shader_cache->writes_vertex && !m->shader_cache->uses_discard && !m->hints[VS::MATERIAL_HINT_OPAQUE_PRE_PASS]) { + if (m->shader_cache && !m->shader_cache->writes_vertex && !m->shader_cache->uses_discard && m->depth_draw_mode!=VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA) { //shader does not use discard and does not write a vertex position, use generic material m = shadow_mat_ptr; if (m->last_pass!=frame) { @@ -4159,7 +4180,7 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD e->light_type=0xFF; // no lights! e->light=0xFFFF; - if (!shadow && !has_blend_alpha && has_alpha && m->hints[VS::MATERIAL_HINT_OPAQUE_PRE_PASS]) { + if (!shadow && !has_blend_alpha && has_alpha && m->depth_draw_mode==VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA) { //if nothing exists, add this element as opaque too RenderList::Element *oe = opaque_render_list.add_element(); @@ -4411,7 +4432,7 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PCF_HQ,shadow_filter==SHADOW_FILTER_PCF13); material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_ESM,shadow_filter==SHADOW_FILTER_ESM); - if (p_opaque_pass && p_material->hints[VS::MATERIAL_HINT_OPAQUE_PRE_PASS] && p_material->shader_cache && p_material->shader_cache->has_alpha) { + if (p_opaque_pass && p_material->depth_draw_mode==VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA && p_material->shader_cache && p_material->shader_cache->has_alpha) { material_shader.set_conditional(MaterialShaderGLES2::ENABLE_CLIP_ALPHA,true); } else { @@ -4423,7 +4444,8 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material if (!shadow) { bool depth_test=!p_material->flags[VS::MATERIAL_FLAG_ONTOP]; - bool depth_write=!p_material->hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW] && (p_opaque_pass || !p_material->hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW_FOR_ALPHA]); + bool depth_write=p_material->depth_draw_mode!=VS::MATERIAL_DEPTH_DRAW_NEVER && (p_opaque_pass || p_material->depth_draw_mode==VS::MATERIAL_DEPTH_DRAW_ALWAYS); + //bool depth_write=!p_material->hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW] && (p_opaque_pass || !p_material->hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW_FOR_ALPHA]); if (current_depth_mask!=depth_write) { current_depth_mask=depth_write; @@ -4594,7 +4616,6 @@ void RasterizerGLES2::_setup_light(uint16_t p_light) { VL_LIGHT_DIR, VL_LIGHT_ATTENUATION, VL_LIGHT_SPOT_ATTENUATION, - VL_LIGHT_AMBIENT, VL_LIGHT_DIFFUSE, VL_LIGHT_SPECULAR, VL_LIGHT_MAX @@ -4605,7 +4626,6 @@ void RasterizerGLES2::_setup_light(uint16_t p_light) { MaterialShaderGLES2::LIGHT_DIRECTION, MaterialShaderGLES2::LIGHT_ATTENUATION, MaterialShaderGLES2::LIGHT_SPOT_ATTENUATION, - MaterialShaderGLES2::LIGHT_AMBIENT, MaterialShaderGLES2::LIGHT_DIFFUSE, MaterialShaderGLES2::LIGHT_SPECULAR, }; @@ -4617,12 +4637,10 @@ void RasterizerGLES2::_setup_light(uint16_t p_light) { LightInstance *li=light_instances[p_light]; Light *l=li->base; - Color col_ambient=_convert_color(l->colors[VS::LIGHT_COLOR_AMBIENT]); Color col_diffuse=_convert_color(l->colors[VS::LIGHT_COLOR_DIFFUSE]); Color col_specular=_convert_color(l->colors[VS::LIGHT_COLOR_SPECULAR]); for(int j=0;j<3;j++) { - light_data[VL_LIGHT_AMBIENT][j]=col_ambient[j]; light_data[VL_LIGHT_DIFFUSE][j]=col_diffuse[j]; light_data[VL_LIGHT_SPECULAR][j]=col_specular[j]; } @@ -5761,6 +5779,17 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans //material_shader.set_uniform(MaterialShaderGLES2::SKELETON_MATRICES,6); material_shader.set_uniform(MaterialShaderGLES2::SKELTEX_PIXEL_SIZE,skeleton->pixel_size); } + if (!shadow) { + + if (!additive && current_env && current_env->fx_enabled[VS::ENV_FX_AMBIENT_LIGHT]) { + Color ambcolor = current_env->fx_param[VS::ENV_FX_PARAM_AMBIENT_LIGHT_COLOR]; + float ambnrg = current_env->fx_param[VS::ENV_FX_PARAM_AMBIENT_LIGHT_ENERGY]; + material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_LIGHT,Vector3(ambcolor.r*ambnrg,ambcolor.g*ambnrg,ambcolor.b*ambnrg)); + } else { + material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_LIGHT,Vector3()); + } + } + _rinfo.shader_change_count++; } @@ -5908,6 +5937,8 @@ void RasterizerGLES2::_process_glow_bloom() { glBindTexture(GL_TEXTURE_2D, current_vd->lum_color ); glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::HDR_SOURCE),2); copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_EXPOSURE,float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE])); + copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_WHITE,float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_WHITE])); +// copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_WHITE,1.0); copy_shader.set_uniform(CopyShaderGLES2::HDR_GLOW_TRESHOLD,float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_GLOW_TRESHOLD])); copy_shader.set_uniform(CopyShaderGLES2::HDR_GLOW_SCALE,float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_GLOW_SCALE])); @@ -5987,7 +6018,7 @@ void RasterizerGLES2::_process_hdr() { _copy_screen_quad(); copy_shader.set_conditional(CopyShaderGLES2::USE_HDR_COPY,false); - int passes = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_PASSES]; +// int passes = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_PASSES]; copy_shader.set_conditional(CopyShaderGLES2::USE_HDR_REDUCE,true); copy_shader.bind(); @@ -6351,6 +6382,28 @@ void RasterizerGLES2::end_scene() { glDepthMask(false); if (current_env && current_env->fx_enabled[VS::ENV_FX_HDR]) { + + int hdr_tm = current_env->fx_param[VS::ENV_FX_PARAM_HDR_TONEMAPPER]; + switch(hdr_tm) { + case VS::ENV_FX_HDR_TONE_MAPPER_LINEAR: { + + + } break; + case VS::ENV_FX_HDR_TONE_MAPPER_LOG: { + copy_shader.set_conditional(CopyShaderGLES2::USE_LOG_TONEMAPPER,true); + + } break; + case VS::ENV_FX_HDR_TONE_MAPPER_REINHARDT: { + copy_shader.set_conditional(CopyShaderGLES2::USE_REINHARDT_TONEMAPPER,true); + } break; + case VS::ENV_FX_HDR_TONE_MAPPER_REINHARDT_AUTOWHITE: { + + copy_shader.set_conditional(CopyShaderGLES2::USE_REINHARDT_TONEMAPPER,true); + copy_shader.set_conditional(CopyShaderGLES2::USE_AUTOWHITE,true); + } break; + } + + _process_hdr(); } if (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) { @@ -6400,6 +6453,7 @@ void RasterizerGLES2::end_scene() { glBindTexture(GL_TEXTURE_2D, current_vd->lum_color ); glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::HDR_SOURCE),2); copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_EXPOSURE,float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE])); + copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_WHITE,float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_WHITE])); } @@ -6430,6 +6484,9 @@ void RasterizerGLES2::end_scene() { copy_shader.set_conditional(CopyShaderGLES2::USE_FXAA,false); copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SCREEN,false); copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SOFTLIGHT,false); + copy_shader.set_conditional(CopyShaderGLES2::USE_REINHARDT_TONEMAPPER,false); + copy_shader.set_conditional(CopyShaderGLES2::USE_AUTOWHITE,false); + copy_shader.set_conditional(CopyShaderGLES2::USE_LOG_TONEMAPPER,false); material_shader.set_conditional(MaterialShaderGLES2::USE_8BIT_HDR,false); @@ -6444,6 +6501,7 @@ void RasterizerGLES2::end_scene() { if (GLOBAL_DEF("rasterizer/debug_shadow_maps",false)) { _debug_shadows(); } +// _debug_luminances(); } @@ -6813,7 +6871,7 @@ void RasterizerGLES2::_debug_draw_shadows_type(Vector& p_shadows,P void RasterizerGLES2::_debug_luminances() { - canvas_shader.set_conditional(CanvasShaderGLES2::DEBUG_ENCODED_32,true); + canvas_shader.set_conditional(CanvasShaderGLES2::DEBUG_ENCODED_32,!use_fp16_fb); canvas_begin(); glDisable(GL_BLEND); canvas_shader.bind(); @@ -6821,10 +6879,17 @@ void RasterizerGLES2::_debug_luminances() { Size2 debug_size(128,128); Size2 ofs; - for (int i=0;ilum_color, Rect2( ofs, debug_size )); + } else { + _debug_draw_shadow(framebuffer.luminance[i].color, Rect2( ofs, debug_size )); + } + ofs.x+=debug_size.x/2; if ( (ofs.x+debug_size.x) > viewport.width ) { ofs.x=0; @@ -7936,9 +8001,14 @@ void RasterizerGLES2::_update_framebuffer() { GLuint format_rgba = GL_RGBA; GLuint format_rgb = use_fp16_fb?_GL_RGB16F_EXT:GL_RGB; GLuint format_type = use_fp16_fb?_GL_HALF_FLOAT_OES:GL_UNSIGNED_BYTE; - GLuint format_luminance = use_fp16_fb?_GL_RED_EXT:GL_RGBA; + /*GLuint format_luminance = use_fp16_fb?GL_RGB16F:GL_RGBA; + GLuint format_luminance_type = use_fp16_fb?(use_fu_GL_HALF_FLOAT_OES):GL_UNSIGNED_BYTE; + GLuint format_luminance_components = use_fp16_fb?GL_RGB:GL_RGBA;*/ + + GLuint format_luminance = use_fp16_fb?_GL_RG_EXT:GL_RGBA; GLuint format_luminance_type = use_fp16_fb?(full_float_fb_supported?GL_FLOAT:_GL_HALF_FLOAT_OES):GL_UNSIGNED_BYTE; - GLuint format_luminance_components = use_fp16_fb?_GL_RED_EXT:GL_RGBA; + GLuint format_luminance_components = use_fp16_fb?_GL_RG_EXT:GL_RGBA; + @@ -8082,8 +8152,8 @@ void RasterizerGLES2::_update_framebuffer() { glGenTextures(1, &lb.color); glBindTexture(GL_TEXTURE_2D, lb.color); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, format_luminance, lb.size, lb.size, 0, diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index cf4c8717e94..60a7731feac 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -163,8 +163,10 @@ class RasterizerGLES2 : public Rasterizer { String vertex_code; String fragment_code; + String light_code; int vertex_line; int fragment_line; + int light_line; VS::ShaderMode mode; uint32_t custom_code_id; @@ -193,6 +195,7 @@ class RasterizerGLES2 : public Rasterizer { version=1; vertex_line=0; fragment_line=0; + light_line=0; can_zpass=true; has_texscreen=false; has_screen_uv=false; @@ -211,10 +214,9 @@ class RasterizerGLES2 : public Rasterizer { struct Material { bool flags[VS::MATERIAL_FLAG_MAX]; - bool hints[VS::MATERIAL_HINT_MAX]; - VS::MaterialShadeModel shade_model; VS::MaterialBlendMode blend_mode; + VS::MaterialDepthDrawMode depth_draw_mode; float line_width; bool has_alpha; @@ -241,12 +243,10 @@ class RasterizerGLES2 : public Rasterizer { for(int i=0;i *p_param_list) const; @@ -1192,11 +1194,8 @@ public: virtual void material_set_flag(RID p_material, VS::MaterialFlag p_flag,bool p_enabled); virtual bool material_get_flag(RID p_material,VS::MaterialFlag p_flag) const; - virtual void material_set_hint(RID p_material, VS::MaterialHint p_hint,bool p_enabled); - virtual bool material_get_hint(RID p_material,VS::MaterialHint p_hint) const; - - virtual void material_set_shade_model(RID p_material, VS::MaterialShadeModel p_model); - virtual VS::MaterialShadeModel material_get_shade_model(RID p_material) const; + virtual void material_set_depth_draw_mode(RID p_material, VS::MaterialDepthDrawMode p_mode); + virtual VS::MaterialDepthDrawMode material_get_depth_draw_mode(RID p_material) const; virtual void material_set_blend_mode(RID p_material,VS::MaterialBlendMode p_mode); virtual VS::MaterialBlendMode material_get_blend_mode(RID p_material) const; diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index db63c3aeba3..dfab3ea3d1f 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -181,6 +181,13 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a flags->use_tangent_interp=true; } + } + if (type==ShaderLanguage::SHADER_MATERIAL_LIGHT) { + + if (vnode->name==vname_light) { + uses_light=true; + } + } code=replace_string(vnode->name); @@ -410,7 +417,7 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a } -void ShaderCompilerGLES2::compile_node(SL::ProgramNode *p_program) { +Error ShaderCompilerGLES2::compile_node(SL::ProgramNode *p_program) { // feed the local replace table and global code global_code=""; @@ -423,8 +430,15 @@ void ShaderCompilerGLES2::compile_node(SL::ProgramNode *p_program) { for(Map::Element *E=p_program->uniforms.front();E;E=E->next()) { String uline="uniform "+_typestr(E->get().type)+" _"+E->key().operator String()+";"ENDL; + global_code+=uline; if (uniforms) { + //if (uniforms->has(E->key())) { + // //repeated uniform, error + // ERR_EXPLAIN("Uniform already exists from other shader: "+String(E->key())); + // ERR_FAIL_COND_V(uniforms->has(E->key()),ERR_ALREADY_EXISTS); +// +// } SL::Uniform u = E->get(); u.order+=ubase; uniforms->insert(E->key(),u); @@ -474,12 +488,14 @@ void ShaderCompilerGLES2::compile_node(SL::ProgramNode *p_program) { print_line(code); code=code.replace("\n",""); #endif + + return OK; } -void ShaderCompilerGLES2::create_glsl_120_code(void *p_str,SL::ProgramNode *p_program) { +Error ShaderCompilerGLES2::create_glsl_120_code(void *p_str,SL::ProgramNode *p_program) { ShaderCompilerGLES2 *compiler=(ShaderCompilerGLES2*)p_str; - compiler->compile_node(p_program); + return compiler->compile_node(p_program); } @@ -505,6 +521,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT uses_alpha=false; uses_discard=false; uses_screen_uv=false; + uses_light=false; vertex_code_writes_vertex=false; uniforms=r_uniforms; flags=&r_flags; @@ -533,6 +550,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT r_flags.vertex_code_writes_vertex=vertex_code_writes_vertex; r_flags.uses_discard=uses_discard; r_flags.uses_screen_uv=uses_screen_uv; + r_flags.uses_light=uses_light; r_code_line=code; r_globals_line=global_code; return OK; @@ -577,6 +595,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { replace_table["clamp"]= "clamp"; replace_table["mix" ]= "mix"; replace_table["step" ]= "step"; + replace_table["smoothstep" ]= "smoothstep"; replace_table["length"]= "length"; replace_table["distance"]= "distance"; replace_table["dot" ]= "dot"; @@ -628,6 +647,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { mode_replace_table[1]["DIFFUSE_ALPHA"]="diffuse"; mode_replace_table[1]["SPECULAR"]="specular"; mode_replace_table[1]["EMISSION"]="emission"; + mode_replace_table[1]["SHADE_PARAM"]="shade_param"; mode_replace_table[1]["SPEC_EXP"]="specular_exp"; mode_replace_table[1]["GLOW"]="glow"; mode_replace_table[1]["DISCARD"]="discard_"; @@ -638,6 +658,26 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { //mode_replace_table[1]["SCREEN_TEXEL_SIZE"]="SCREEN_TEXEL_SIZE"; mode_replace_table[1]["TIME"]="time"; + ////////////// + + mode_replace_table[2]["NORMAL"]="normal"; + //mode_replace_table[2]["POSITION"]="IN_POSITION"; + mode_replace_table[2]["LIGHT_DIR"]="light_dir"; + mode_replace_table[2]["LIGHT_DIFFUSE"]="light_diffuse"; + mode_replace_table[2]["LIGHT_SPECULAR"]="light_specular"; + mode_replace_table[2]["EYE_VEC"]="eye_vec"; + mode_replace_table[2]["DIFFUSE"]="mdiffuse"; + mode_replace_table[2]["SPECULAR"]="specular"; + mode_replace_table[2]["SPECULAR_EXP"]="specular_exp"; + mode_replace_table[2]["SHADE_PARAM"]="shade_param"; + mode_replace_table[2]["LIGHT"]="light"; + mode_replace_table[2]["POINT_COORD"]="gl_PointCoord"; + mode_replace_table[2]["TIME"]="time"; + + //mode_replace_table[2]["SCREEN_POS"]="SCREEN_POS"; + //mode_replace_table[2]["SCREEN_TEXEL_SIZE"]="SCREEN_TEXEL_SIZE"; + + out_vertex_name="VERTEX"; vname_discard="DISCARD"; @@ -651,5 +691,6 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { vname_var1_interp="VAR1"; vname_var2_interp="VAR2"; vname_vertex="VERTEX"; + vname_light="LIGHT"; } diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h index d683f5b4f30..d63915a2b68 100644 --- a/drivers/gles2/shader_compiler_gles2.h +++ b/drivers/gles2/shader_compiler_gles2.h @@ -39,10 +39,11 @@ private: ShaderLanguage::ProgramNode *program_node; String dump_node_code(ShaderLanguage::Node *p_node,int p_level,bool p_assign_left=false); - void compile_node(ShaderLanguage::ProgramNode *p_program); - static void create_glsl_120_code(void *p_str,ShaderLanguage::ProgramNode *p_program); + Error compile_node(ShaderLanguage::ProgramNode *p_program); + static Error create_glsl_120_code(void *p_str,ShaderLanguage::ProgramNode *p_program); + bool uses_light; bool uses_texscreen; bool uses_texpos; bool uses_alpha; @@ -62,6 +63,7 @@ private: StringName vname_var1_interp; StringName vname_var2_interp; StringName vname_vertex; + StringName vname_light; Map *uniforms; @@ -73,7 +75,7 @@ private: String replace_string(const StringName& p_string); - Map mode_replace_table[2]; + Map mode_replace_table[3]; Map replace_table; public: @@ -92,6 +94,7 @@ public: bool use_tangent_interp; bool use_var1_interp; bool use_var2_interp; + bool uses_light; }; Error compile(const String& p_code, ShaderLanguage::ShaderType p_type, String& r_code_line, String& r_globals_line, Flags& r_flags, Map *r_uniforms=NULL); diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp index bcd3e6ad4b9..dc68ee489af 100644 --- a/drivers/gles2/shader_gles2.cpp +++ b/drivers/gles2/shader_gles2.cpp @@ -285,6 +285,7 @@ ShaderGLES2::Version* ShaderGLES2::get_current_version() { //keep them around during the function CharString code_string; + CharString code_string2; CharString code_globals; @@ -437,6 +438,14 @@ ShaderGLES2::Version* ShaderGLES2::get_current_version() { } strings.push_back(fragment_code2.get_data()); + + if (cc) { + code_string2=cc->light.ascii(); + strings.push_back(code_string2.get_data()); + } + + strings.push_back(fragment_code3.get_data()); + #ifdef DEBUG_SHADER DEBUG_PRINT("\nFragment Code:\n\n"+String(code_string.get_data())); for(int i=0;i& p_uniforms,const Vector &p_custom_defines) { +void ShaderGLES2::set_custom_shader_code(uint32_t p_code_id, const String& p_vertex, const String& p_vertex_globals,const String& p_fragment,const String& p_light, const String& p_fragment_globals,const Vector& p_uniforms,const Vector &p_custom_defines) { ERR_FAIL_COND(!custom_code_map.has(p_code_id)); CustomCode *cc=&custom_code_map[p_code_id]; @@ -705,6 +724,7 @@ void ShaderGLES2::set_custom_shader_code(uint32_t p_code_id, const String& p_ver cc->vertex_globals=p_vertex_globals; cc->fragment=p_fragment; cc->fragment_globals=p_fragment_globals; + cc->light=p_light; cc->custom_uniforms=p_uniforms; cc->custom_defines=p_custom_defines; cc->version++; diff --git a/drivers/gles2/shader_gles2.h b/drivers/gles2/shader_gles2.h index 17d893e349e..9cd6142eb09 100644 --- a/drivers/gles2/shader_gles2.h +++ b/drivers/gles2/shader_gles2.h @@ -98,6 +98,7 @@ private: String vertex_globals; String fragment; String fragment_globals; + String light; uint32_t version; Vector custom_uniforms; Vector custom_defines; @@ -157,6 +158,7 @@ private: CharString fragment_code0; CharString fragment_code1; CharString fragment_code2; + CharString fragment_code3; CharString vertex_code0; CharString vertex_code1; @@ -292,7 +294,7 @@ public: void clear_caches(); uint32_t create_custom_shader(); - void set_custom_shader_code(uint32_t p_id,const String& p_vertex, const String& p_vertex_globals,const String& p_fragment, const String& p_fragment_globals,const Vector& p_uniforms,const Vector &p_custom_defines); + void set_custom_shader_code(uint32_t p_id,const String& p_vertex, const String& p_vertex_globals,const String& p_fragment,const String& p_p_light,const String& p_fragment_globals,const Vector& p_uniforms,const Vector &p_custom_defines); void set_custom_shader(uint32_t p_id); void free_custom_shader(uint32_t p_id); diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl index f96ec1d1bd3..d8fb03f3a3a 100644 --- a/drivers/gles2/shaders/copy.glsl +++ b/drivers/gles2/shaders/copy.glsl @@ -78,7 +78,7 @@ uniform highp float hdr_glow_scale; uniform sampler2D hdr_source; uniform highp float tonemap_exposure; - +uniform highp float tonemap_white; #endif #ifdef USE_BCS @@ -318,6 +318,7 @@ void main() { #ifdef USE_HDR + highp float white_mult = 1.0; #ifdef USE_8BIT_HDR highp vec4 _mult = vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1); @@ -325,11 +326,37 @@ void main() { color.rgb*=LUM_RANGE; hdr_lum*=LUM_RANGE; //restore to full range #else - highp float hdr_lum = texture2D( hdr_source, vec2(0.0) ).r; + + highp vec2 lv = texture2D( hdr_source, vec2(0.0) ).rg; + highp float hdr_lum = lv.r; +#ifdef USE_AUTOWHITE + white_mult=lv.g; #endif +#endif + +#ifdef USE_REINHARDT_TONEMAPPER + float src_lum = dot(color.rgb,vec3(0.3, 0.58, 0.12)); + float lp = tonemap_exposure/hdr_lum*src_lum; + float white = tonemap_white; +#ifdef USE_AUTOWHITE + white_mult = (white_mult + 1.0 * white_mult); + white_mult*=white_mult; + white*=white_mult; +#endif + lp = ( lp * ( 1.0 + ( lp / ( white) ) ) ) / ( 1.0 + lp ); + color.rgb*=lp; + +#else + +#ifdef USE_LOG_TONEMAPPER + color.rgb = tonemap_exposure * log(color.rgb+1.0)/log(hdr_lum+1.0); +#else highp float tone_scale = tonemap_exposure / hdr_lum; //only linear supported color.rgb*=tone_scale; +#endif + +#endif #endif @@ -393,7 +420,11 @@ void main() { #ifdef USE_HDR_COPY //highp float lum = dot(color.rgb,highp vec3(1.0/3.0,1.0/3.0,1.0/3.0)); - highp float lum = max(color.r,max(color.g,color.b)); + //highp float lum = max(color.r,max(color.g,color.b)); + highp float lum = dot(color.rgb,vec3(0.3, 0.58, 0.12)); + + //lum=log(lum+0.0001); //everyone does it + #ifdef USE_8BIT_HDR highp vec4 comp = fract(lum * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0)); comp -= comp.xxyz * vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0); @@ -422,21 +453,33 @@ void main() { #else highp float lum_accum = color.r; - lum_accum += texture2D( source, uv_interp+vec2(-pixel_size.x,-pixel_size.y) ).r; - lum_accum += texture2D( source, uv_interp+vec2(0.0,-pixel_size.y) ).r; - lum_accum += texture2D( source, uv_interp+vec2(pixel_size.x,-pixel_size.y) ).r; - lum_accum += texture2D( source, uv_interp+vec2(-pixel_size.x,0.0) ).r; - lum_accum += texture2D( source, uv_interp+vec2(pixel_size.x,0.0) ).r; - lum_accum += texture2D( source, uv_interp+vec2(-pixel_size.x,pixel_size.y) ).r; - lum_accum += texture2D( source, uv_interp+vec2(0.0,pixel_size.y) ).r; - lum_accum += texture2D( source, uv_interp+vec2(pixel_size.x,pixel_size.y) ).r; + highp float lum_max = color.g; + +#define LUM_REDUCE(m_uv) \ + {\ + vec2 val = texture2D( source, uv_interp+m_uv ).rg;\ + lum_accum+=val.x;\ + lum_max=max(val.y,lum_max);\ + } + + LUM_REDUCE( vec2(-pixel_size.x,-pixel_size.y) ); + LUM_REDUCE( vec2(0.0,-pixel_size.y) ); + LUM_REDUCE( vec2(pixel_size.x,-pixel_size.y) ); + LUM_REDUCE( vec2(-pixel_size.x,0.0) ); + LUM_REDUCE( vec2(pixel_size.x,0.0) ); + LUM_REDUCE( vec2(-pixel_size.x,pixel_size.y) ); + LUM_REDUCE( vec2(0.0,pixel_size.y) ); + LUM_REDUCE( vec2(pixel_size.x,pixel_size.y) ); lum_accum/=9.0; #endif #ifdef USE_HDR_STORE -#ifdef USE_8BIT_HDR + //lum_accum=exp(lum_accum); + +#ifdef USE_8BIT_HDR + highp float vd_lum = dot(texture2D( source_vd_lum, vec2(0.0) ), _multcv ); lum_accum = clamp( vd_lum + (lum_accum-vd_lum)*hdr_time_delta*hdr_exp_adj_speed,min_luminance*(1.0/LUM_RANGE),max_luminance*(1.0/LUM_RANGE)); #else @@ -450,6 +493,10 @@ void main() { highp vec4 comp = fract(lum_accum * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0)); comp -= comp.xxyz * vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0); color=comp; +#else +#ifdef USE_AUTOWHITE + color.r=lum_accum; + color.g=lum_max; #else color.rgb=vec3(lum_accum); #endif @@ -457,6 +504,10 @@ void main() { #endif +#endif + + + #ifdef USE_RGBE color.rgb = pow(color.rgb,color.a*255.0-(8.0+128.0)); diff --git a/drivers/gles2/shaders/material.glsl b/drivers/gles2/shaders/material.glsl index 8e7d321fe77..602620a04bb 100644 --- a/drivers/gles2/shaders/material.glsl +++ b/drivers/gles2/shaders/material.glsl @@ -115,7 +115,6 @@ uniform vec3 light_pos; uniform vec3 light_direction; uniform vec3 light_attenuation; uniform vec3 light_spot_attenuation; -uniform vec3 light_ambient; uniform vec3 light_diffuse; uniform vec3 light_specular; @@ -132,6 +131,7 @@ varying vec3 specular_interp; uniform float time; uniform float instance_id; +uniform vec3 ambient_light; #if !defined(USE_DEPTH_SHADOWS) && defined(USE_SHADOW_PASS) @@ -404,7 +404,7 @@ VERTEX_SHADER_CODE float NdotL = max(0.0,dot( normal_interp, light_dir )); vec3 half_vec = normalize(light_dir + eye_vec); float eye_light = max(dot(normal_interp, half_vec),0.0); - diffuse_interp.rgb=light_diffuse * NdotL * attenuation;// + light_ambient; + diffuse_interp.rgb=light_diffuse * NdotL * attenuation; diffuse_interp.a=attenuation; if (NdotL > 0.0) { specular_interp=light_specular * pow( eye_light, vertex_specular_exp ) * attenuation; @@ -510,28 +510,16 @@ uniform vec3 light_pos; uniform vec3 light_direction; uniform vec3 light_attenuation; uniform vec3 light_spot_attenuation; -uniform vec3 light_ambient; uniform vec3 light_diffuse; uniform vec3 light_specular; +uniform vec3 ambient_light; + #ifdef USE_FRAGMENT_LIGHTING -vec3 process_shade(in vec3 normal, in vec3 light_dir, in vec3 eye_vec, in vec3 diffuse, in vec3 specular, in float specular_exp, in float attenuation) { - - float NdotL = max(0.0,dot( normal, light_dir )); - vec3 half_vec = normalize(light_dir + eye_vec); - float eye_light = max(dot(normal, half_vec),0.0); - - vec3 ret = light_ambient *diffuse + light_diffuse * diffuse * NdotL * attenuation; - if (NdotL > 0.0) { - ret+=light_specular * specular * pow( eye_light, specular_exp ) * attenuation; - } - return ret; -} - # ifdef USE_DEPTH_SHADOWS # else # endif @@ -770,9 +758,12 @@ void main() { bool discard_=false; #endif +{ + FRAGMENT_SHADER_CODE +} #if defined(ENABLE_DISCARD) if (discard_) { @@ -1009,9 +1000,8 @@ FRAGMENT_SHADER_CODE #ifdef LIGHT_TYPE_DIRECTIONAL vec3 light_dir = -light_direction; - float light_attenuation = light_attenuation.r; + float attenuation = light_attenuation.r; - diffuse.rgb=process_shade(normal,light_dir,eye_vec,diffuse.rgb,specular,specular_exp,shadow_attenuation)*light_attenuation; #endif @@ -1023,7 +1013,6 @@ FRAGMENT_SHADER_CODE light_dir=normalize(light_dir); float attenuation = pow( max(1.0 - dist/radius, 0.0), light_attenuation.b ) * light_attenuation.r; - diffuse.rgb=process_shade(normal,light_dir,eye_vec,diffuse.rgb,specular,specular_exp,shadow_attenuation)*attenuation; #endif @@ -1040,10 +1029,39 @@ FRAGMENT_SHADER_CODE float rim = (1.0 - scos) / (1.0 - spot_cutoff); attenuation *= 1.0 - pow( rim, light_spot_attenuation.g); - diffuse.rgb=process_shade(normal,light_dir,eye_vec,diffuse.rgb,specular,specular_exp,shadow_attenuation)*attenuation; - #endif +# if defined(LIGHT_TYPE_DIRECTIONAL) || defined(LIGHT_TYPE_OMNI) || defined (LIGHT_TYPE_SPOT) + + { + + vec3 mdiffuse = diffuse.rgb; + vec3 light; + +#if defined(USE_LIGHT_SHADER_CODE) +//light is written by the light shader +{ + +LIGHT_SHADER_CODE + +} +#else +//traditional lambert + blinn + float NdotL = max(0.0,dot( normal, light_dir )); + vec3 half_vec = normalize(light_dir + eye_vec); + float eye_light = max(dot(normal, half_vec),0.0); + + light = light_diffuse * mdiffuse * NdotL; + if (NdotL > 0.0) { + light+=specular * light_specular * pow( eye_light, specular_exp ); + } +#endif + diffuse.rgb = ambient_light *diffuse.rgb + light * attenuation * shadow_attenuation; + + } + + +# endif # if !defined(LIGHT_TYPE_DIRECTIONAL) && !defined(LIGHT_TYPE_OMNI) && !defined (LIGHT_TYPE_SPOT) //none @@ -1062,7 +1080,7 @@ FRAGMENT_SHADER_CODE #ifdef USE_VERTEX_LIGHTING - vec3 ambient = light_ambient*diffuse.rgb; + vec3 ambient = ambient_light*diffuse.rgb; # if defined(LIGHT_TYPE_OMNI) || defined (LIGHT_TYPE_SPOT) ambient*=diffuse_interp.a; //attenuation affects ambient too # endif diff --git a/main/main.cpp b/main/main.cpp index 0d9e94346e0..f5b5953ff46 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -211,6 +211,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas while (I) { I->get()=unescape_cmdline(I->get().strip_escapes()); +// print_line("CMD: "+I->get()); I=I->next(); } @@ -223,6 +224,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas String game_path="."; String debug_mode; String debug_host; + String main_pack; int rtm=-1; String remotefs; @@ -237,9 +239,9 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas I=args.front(); - packed_data = PackedData::get_singleton(); - if (!packed_data) - packed_data = memnew(PackedData); + packed_data = PackedData::get_singleton(); + if (!packed_data) + packed_data = memnew(PackedData); #ifdef MINIZIP_ENABLED packed_data->add_pack_source(ZipArchive::get_singleton()); @@ -425,6 +427,17 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas goto error; }; + } else if (I->get() == "-main_pack") { + + if (I->next()) { + + main_pack=I->next()->get(); + N = I->next()->next(); + } else { + + goto error; + }; + } else if (I->get()=="-debug" || I->get()=="-d") { debug_mode="local"; } else if (I->get()=="-editor_scene") { @@ -541,7 +554,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas #endif - if (globals->setup(game_path)!=OK) { + if (globals->setup(game_path,main_pack)!=OK) { #ifdef TOOLS_ENABLED editor=false; diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp index 5f5de8b5db2..a98b07ab92d 100644 --- a/modules/gdscript/gd_editor.cpp +++ b/modules/gdscript/gd_editor.cpp @@ -65,7 +65,7 @@ bool GDScriptLanguage::validate(const String& p_script, int &r_line_error,int &r GDParser parser; - Error err = parser.parse(p_script,p_path.get_base_dir()); + Error err = parser.parse(p_script,p_path.get_base_dir(),true); if (err) { r_line_error=parser.get_error_line(); r_col_error=parser.get_error_column(); diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index 2829132d99c..40c262c5032 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -29,6 +29,7 @@ #include "gd_parser.h" #include "print_string.h" #include "io/resource_loader.h" +#include "os/file_access.h" /* TODO: *Property reduce constant expressions @@ -224,12 +225,23 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_ String path = tokenizer->get_token_constant(); if (!path.is_abs_path() && base_path!="") path=base_path+"/"+path; - path = path.replace("///","//"); + path = path.replace("///","//"); - Ref res = ResourceLoader::load(path); - if (!res.is_valid()) { - _set_error("Can't preload resource at path: "+path); - return NULL; + Ref res; + if (!validating) { + + //this can be too slow for just validating code + res = ResourceLoader::load(path); + if (!res.is_valid()) { + _set_error("Can't preload resource at path: "+path); + return NULL; + } + } else { + + if (!FileAccess::exists(path)) { + _set_error("Can't preload resource at path: "+path); + return NULL; + } } tokenizer->advance(); @@ -2468,12 +2480,13 @@ Error GDParser::parse_bytecode(const Vector &p_bytecode,const String& p } -Error GDParser::parse(const String& p_code,const String& p_base_path) { +Error GDParser::parse(const String& p_code,const String& p_base_path,bool p_just_validate) { GDTokenizerText *tt = memnew( GDTokenizerText ); tt->set_code(p_code); + validating=p_just_validate; tokenizer=tt; Error ret = _parse(p_base_path); memdelete(tt); @@ -2498,6 +2511,7 @@ void GDParser::clear() { head=NULL; list=NULL; + validating=false; error_set=false; tab_level.clear(); tab_level.push_back(0); diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gd_parser.h index 825bd954d13..ae43a26f5a0 100644 --- a/modules/gdscript/gd_parser.h +++ b/modules/gdscript/gd_parser.h @@ -356,6 +356,7 @@ private: template T* alloc_node(); + bool validating; int parenthesis; bool error_set; String error; @@ -392,7 +393,7 @@ public: String get_error() const; int get_error_line() const; int get_error_column() const; - Error parse(const String& p_code,const String& p_base_path=""); + Error parse(const String& p_code, const String& p_base_path="", bool p_just_validate=false); Error parse_bytecode(const Vector &p_bytecode,const String& p_base_path=""); const Node *get_parse_tree() const; diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index d1ee7087e7d..f47ff4ed500 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -258,7 +258,11 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant& String n=p_name; - if (n=="version/code") + if (n=="custom_package/debug") + custom_debug_package=p_value; + else if (n=="custom_package/release") + custom_release_package=p_value; + else if (n=="version/code") version_code=p_value; else if (n=="version/name") version_name=p_value; @@ -317,8 +321,11 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant& bool EditorExportPlatformAndroid::_get(const StringName& p_name,Variant &r_ret) const{ String n=p_name; - - if (n=="version/code") + if (n=="custom_package/debug") + r_ret=custom_debug_package; + else if (n=="custom_package/release") + r_ret=custom_release_package; + else if (n=="version/code") r_ret=version_code; else if (n=="version/name") r_ret=version_name; @@ -389,7 +396,7 @@ void EditorExportPlatformAndroid::_get_property_list( List *p_list p_list->push_back( PropertyInfo( Variant::STRING, "keystore/release_user" ) ); p_list->push_back( PropertyInfo( Variant::BOOL, "apk_expansion/enable" ) ); p_list->push_back( PropertyInfo( Variant::STRING, "apk_expansion/SALT" ) ); - p_list->push_back( PropertyInfo( Variant::STRING, "apk_expansion/pubic_key" ) ); + p_list->push_back( PropertyInfo( Variant::STRING, "apk_expansion/public_key",PROPERTY_HINT_MULTILINE_TEXT ) ); const char **perms = android_perms; while(*perms) { @@ -1095,6 +1102,12 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d ep.step("Adding Files..",1); Error err=OK; Vector cl = cmdline.strip_edges().split(" "); + for(int i=0;i65535) { + Log.d("GODOT", "**ERROR** Wrong command len\n"); + return new String[0]; + } + byte[] arg = new byte[strlen]; + r = is.read(arg); + if (r==strlen) { + cmdline[i]=new String(arg,"UTF-8"); + } } - int argc=((int)(len[3])<<24) | ((int)(len[2])<<16) | ((int)(len[1])<<8) | ((int)(len[0])); - String[] cmdline = new String[argc]; - for(int i=0;i65535) { - System.out.printf("**ERROR** Wrong command len\n"); - return new String[0]; - } - byte[] arg = new byte[strlen]; - r = is.read(arg); - if (r!=strlen) { - cmdline[i]=new String(arg,"UTF-8"); - } - - } - return cmdline; } catch (Exception e) { - + e.printStackTrace(); + System.out.printf("**ERROR** No commandline.\n"); + Log.d("GODOT", "**ERROR** Exception " + e.getClass().getName() + ":" + e.getMessage()); return new String[0]; } } + + String expansion_pack_path; + + + private void initializeGodot() { + + if (expansion_pack_path!=null) { + + String[] new_cmdline; + int cll=0; + if (command_line!=null) { + new_cmdline = new String[ command_line.length + 2 ]; + cll=command_line.length; + for(int i=0;i new_args = new LinkedList(); - io = new GodotIO(this); - io.unique_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID); - GodotLib.io=io; - GodotLib.initialize(this,io.needsReloadHooks(),getCommandLine()); - mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); - mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); - mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); + for(int i=0;i 0) { + complete.update(buffer, 0, numRead); + } + } while (numRead != -1); + + + fis.close(); + byte[] messageDigest = complete.digest(); + + // Create Hex String + StringBuffer hexString = new StringBuffer(); + for (int i=0; i + */ +public class GodotDownloaderAlarmReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + try { + DownloaderClientMarshaller.startDownloadServiceIfRequired(context, intent, GodotDownloaderService.class); + } catch (NameNotFoundException e) { + e.printStackTrace(); + } + } +} diff --git a/platform/android/java/src/com/android/godot/GodotDownloaderService.java b/platform/android/java/src/com/android/godot/GodotDownloaderService.java new file mode 100644 index 00000000000..e0fe95ad963 --- /dev/null +++ b/platform/android/java/src/com/android/godot/GodotDownloaderService.java @@ -0,0 +1,47 @@ +package com.android.godot; + +import com.google.android.vending.expansion.downloader.impl.DownloaderService; + +/** + * This class demonstrates the minimal client implementation of the + * DownloaderService from the Downloader library. + */ +public class GodotDownloaderService extends DownloaderService { + // stuff for LVL -- MODIFY FOR YOUR APPLICATION! + private static final String BASE64_PUBLIC_KEY = "REPLACE THIS WITH YOUR PUBLIC KEY"; + // used by the preference obfuscater + private static final byte[] SALT = new byte[] { + 1, 43, -12, -1, 54, 98, + -100, -12, 43, 2, -8, -4, 9, 5, -106, -108, -33, 45, -1, 84 + }; + + /** + * This public key comes from your Android Market publisher account, and it + * used by the LVL to validate responses from Market on your behalf. + */ + @Override + public String getPublicKey() { + return BASE64_PUBLIC_KEY; + } + + /** + * This is used by the preference obfuscater to make sure that your + * obfuscated preferences are different than the ones used by other + * applications. + */ + @Override + public byte[] getSALT() { + return SALT; + } + + /** + * Fill this in with the class name for your alarm receiver. We do this + * because receivers must be unique across all of Android (it's a good idea + * to make sure that your receiver is in your unique package) + */ + @Override + public String getAlarmReceiverClassName() { + return GodotDownloaderAlarmReceiver.class.getName(); + } + +} diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index b11994eef0b..b9e13892d27 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -747,8 +747,34 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env, } + const char ** cmdline=NULL; + int cmdlen=0; + bool use_apk_expansion=false; + if (p_cmdline) { + int cmdlen = env->GetArrayLength(p_cmdline); + if (cmdlen) { + cmdline = (const char**)malloc((env->GetArrayLength(p_cmdline)+1)*sizeof(const char*)); + cmdline[cmdlen]=NULL; - os_android = new OS_Android(_gfx_init_func,env,_open_uri,_get_data_dir,_get_locale, _get_model,_show_vk, _hide_vk,_set_screen_orient,_get_unique_id, _play_video, _is_video_playing, _pause_video, _stop_video); + for (int i=0; iGetObjectArrayElement(p_cmdline, i); + const char *rawString = env->GetStringUTFChars(string, 0); + if (!rawString) { + __android_log_print(ANDROID_LOG_INFO,"godot","cmdline arg %i is null\n",i); + } else { + // __android_log_print(ANDROID_LOG_INFO,"godot","cmdline arg %i is: %s\n",i,rawString); + + if (strcmp(rawString,"-main_pack")==0) + use_apk_expansion=true; + } + + cmdline[i]=rawString; + } + } + } + + os_android = new OS_Android(_gfx_init_func,env,_open_uri,_get_data_dir,_get_locale, _get_model,_show_vk, _hide_vk,_set_screen_orient,_get_unique_id, _play_video, _is_video_playing, _pause_video, _stop_video,use_apk_expansion); os_android->set_need_reload_hooks(p_need_reload_hook); char wd[500]; @@ -759,16 +785,6 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env, __android_log_print(ANDROID_LOG_INFO,"godot","**SETUP"); - const char ** cmdline=NULL; - int cmdlen = env->GetArrayLength(p_cmdline); - cmdline = (const char**)malloc((env->GetArrayLength(p_cmdline)+1)*sizeof(const char*)); - cmdline[cmdlen]=NULL; - for (int i=0; iGetObjectArrayElement(p_cmdline, i); - const char *rawString = env->GetStringUTFChars(string, 0); - cmdline[i]=rawString; - } #if 0 char *args[]={"-test","render",NULL}; @@ -833,6 +849,7 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_quit(JNIEnv * env, jobjec input_mutex->lock(); quit_request=true; + print_line("BACK PRESSED"); input_mutex->unlock(); } @@ -1289,7 +1306,10 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_key(JNIEnv * env, jobject } else if (val == 61453) { ievent.key.scancode = KEY_ENTER; ievent.key.unicode = KEY_ENTER; - } + } else if (p_scancode==4) { + + quit_request=true; + } input_mutex->lock(); key_events.push_back(ievent); @@ -1390,7 +1410,7 @@ static Variant::Type get_jni_type(const String& p_type) { static const char* get_jni_sig(const String& p_type) { - print_line("getting sig for " + p_type); + static struct { const char *name; const char *sig; diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 5bc433e85f4..5fad4386fa3 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -87,11 +87,17 @@ void OS_Android::initialize_core() { #else - FileAccess::make_default >(FileAccess::ACCESS_RESOURCES); + if (use_apk_expansion) + FileAccess::make_default(FileAccess::ACCESS_RESOURCES); + else + FileAccess::make_default >(FileAccess::ACCESS_RESOURCES); FileAccess::make_default(FileAccess::ACCESS_USERDATA); FileAccess::make_default(FileAccess::ACCESS_FILESYSTEM); //FileAccessBufferedFA::make_default(); - DirAccess::make_default(DirAccess::ACCESS_RESOURCES); + if (use_apk_expansion) + DirAccess::make_default(DirAccess::ACCESS_RESOURCES); + else + DirAccess::make_default(DirAccess::ACCESS_RESOURCES); DirAccess::make_default(DirAccess::ACCESS_USERDATA); DirAccess::make_default(DirAccess::ACCESS_FILESYSTEM); @@ -698,9 +704,10 @@ void OS_Android::native_video_stop() { video_stop_func(); } -OS_Android::OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func,GetModelFunc p_get_model_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, SetScreenOrientationFunc p_screen_orient,GetUniqueIDFunc p_get_unique_id, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func) { +OS_Android::OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func,GetModelFunc p_get_model_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, SetScreenOrientationFunc p_screen_orient,GetUniqueIDFunc p_get_unique_id, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func,bool p_use_apk_expansion) { + use_apk_expansion=p_use_apk_expansion; default_videomode.width=800; default_videomode.height=600; default_videomode.fullscreen=true; @@ -720,10 +727,10 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFu get_model_func=p_get_model_func; get_unique_id_func=p_get_unique_id; - video_play_func = p_video_play_func; - video_is_playing_func = p_video_is_playing_func; - video_pause_func = p_video_pause_func; - video_stop_func = p_video_stop_func; + video_play_func = p_video_play_func; + video_is_playing_func = p_video_is_playing_func; + video_pause_func = p_video_pause_func; + video_stop_func = p_video_stop_func; show_virtual_keyboard_func = p_show_vk; hide_virtual_keyboard_func = p_hide_vk; diff --git a/platform/android/os_android.h b/platform/android/os_android.h index e6d0f7ededd..bc52a43002e 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -88,6 +88,7 @@ private: bool use_gl2; bool use_reload_hooks; + bool use_apk_expansion; Rasterizer *rasterizer; VisualServer *visual_server; @@ -213,7 +214,7 @@ public: virtual void native_video_pause(); virtual void native_video_stop(); - OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func,GetModelFunc p_get_model_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, SetScreenOrientationFunc p_screen_orient,GetUniqueIDFunc p_get_unique_id, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func); + OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func,GetModelFunc p_get_model_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, SetScreenOrientationFunc p_screen_orient,GetUniqueIDFunc p_get_unique_id, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func,bool p_use_apk_expansion); ~OS_Android(); }; diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index ecdfc8a7f91..56fbf358bc3 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -344,7 +344,7 @@ RES Camera::_get_gizmo_geometry() const { mat->set_line_width(4); mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); mat->set_flag(Material::FLAG_UNSHADED,true); - mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); + //mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); surface_tool->begin(Mesh::PRIMITIVE_LINES); surface_tool->set_material(mat); diff --git a/scene/3d/follow_camera.cpp b/scene/3d/follow_camera.cpp index 20a1654b92b..e7ced6c2ba4 100644 --- a/scene/3d/follow_camera.cpp +++ b/scene/3d/follow_camera.cpp @@ -548,7 +548,7 @@ RES FollowCamera::_get_gizmo_geometry() const { mat->set_line_width(4); mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); mat->set_flag(Material::FLAG_UNSHADED,true); - mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); +// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); surface_tool->begin(Mesh::PRIMITIVE_LINES); surface_tool->set_material(mat); diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index b79fd8617f0..25f3b3d3a55 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -165,7 +165,7 @@ RES Light::_get_gizmo_geometry() const { mat_area->set_parameter( FixedMaterial::PARAM_EMISSION,Color(0.7,0.7,0.7) ); mat_area->set_blend_mode( Material::BLEND_MODE_ADD ); mat_area->set_flag(Material::FLAG_DOUBLE_SIDED,true); - mat_area->set_hint(Material::HINT_NO_DEPTH_DRAW,true); +// mat_area->set_hint(Material::HINT_NO_DEPTH_DRAW,true); Ref mat_light( memnew( FixedMaterial )); @@ -474,7 +474,6 @@ void Light::_bind_methods() { }*/ - ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "colors/ambient"), _SCS("set_color"), _SCS("get_color"),COLOR_AMBIENT); ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "colors/diffuse"), _SCS("set_color"), _SCS("get_color"),COLOR_DIFFUSE); ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "colors/specular"), _SCS("set_color"), _SCS("get_color"),COLOR_SPECULAR); ADD_PROPERTY( PropertyInfo( Variant::BOOL, "shadow/shadow"), _SCS("set_project_shadows"), _SCS("has_project_shadows")); @@ -495,7 +494,7 @@ void Light::_bind_methods() { BIND_CONSTANT( PARAM_SHADOW_DARKENING ); BIND_CONSTANT( PARAM_SHADOW_Z_OFFSET ); - BIND_CONSTANT( COLOR_AMBIENT ); + BIND_CONSTANT( COLOR_DIFFUSE ); BIND_CONSTANT( COLOR_SPECULAR ); @@ -518,7 +517,7 @@ Light::Light(VisualServer::LightType p_type) { set_parameter(PARAM_SHADOW_ESM_MULTIPLIER,60); set_parameter(PARAM_SHADOW_BLUR_PASSES,1); - set_color( COLOR_AMBIENT, Color(0,0,0)); + set_color( COLOR_DIFFUSE, Color(1,1,1)); set_color( COLOR_SPECULAR, Color(1,1,1)); diff --git a/scene/3d/light.h b/scene/3d/light.h index f090ae5782d..6b1ea2d455d 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -61,7 +61,6 @@ public: enum LightColor { - COLOR_AMBIENT=VisualServer::LIGHT_COLOR_AMBIENT, COLOR_DIFFUSE=VisualServer::LIGHT_COLOR_DIFFUSE, COLOR_SPECULAR=VisualServer::LIGHT_COLOR_SPECULAR }; diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp index d74768f0ab8..b47f1644e3c 100644 --- a/scene/3d/particles.cpp +++ b/scene/3d/particles.cpp @@ -324,7 +324,7 @@ RES Particles::_get_gizmo_geometry() const { mat->set_parameter( FixedMaterial::PARAM_EMISSION,Color(0.5,0.7,0.8) ); mat->set_blend_mode( Material::BLEND_MODE_ADD ); mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); - mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); +// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); surface_tool->begin(Mesh::PRIMITIVE_TRIANGLES); diff --git a/scene/3d/portal.cpp b/scene/3d/portal.cpp index 12b9dc4b7a8..fe627c2cc0f 100644 --- a/scene/3d/portal.cpp +++ b/scene/3d/portal.cpp @@ -106,7 +106,7 @@ RES Portal::_get_gizmo_geometry() const { mat->set_line_width(4); mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); mat->set_flag(Material::FLAG_UNSHADED,true); - mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); +// mat->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER,true); surface_tool->begin(Mesh::PRIMITIVE_LINES); surface_tool->set_material(mat); diff --git a/scene/3d/room_instance.cpp b/scene/3d/room_instance.cpp index 0f390c15af3..fa1d3ecf6b5 100644 --- a/scene/3d/room_instance.cpp +++ b/scene/3d/room_instance.cpp @@ -99,7 +99,7 @@ RES Room::_get_gizmo_geometry() const { mat->set_line_width(4); mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); mat->set_flag(Material::FLAG_UNSHADED,true); - mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); +// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); surface_tool->begin(Mesh::PRIMITIVE_LINES); surface_tool->set_material(mat); diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp index b77a4e0fe32..323bfa4dc41 100644 --- a/scene/3d/skeleton.cpp +++ b/scene/3d/skeleton.cpp @@ -445,7 +445,7 @@ RES Skeleton::_get_gizmo_geometry() const { mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); mat->set_flag(Material::FLAG_UNSHADED,true); mat->set_flag(Material::FLAG_ONTOP,true); - mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); +// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); surface_tool->begin(Mesh::PRIMITIVE_LINES); surface_tool->set_material(mat); diff --git a/scene/3d/spatial_player.cpp b/scene/3d/spatial_player.cpp index 08475983567..8e3a0d30ead 100644 --- a/scene/3d/spatial_player.cpp +++ b/scene/3d/spatial_player.cpp @@ -98,7 +98,7 @@ RES SpatialPlayer::_get_gizmo_geometry() const { mat->set_parameter( FixedMaterial::PARAM_EMISSION,Color(0.5,0.7,0.8) ); mat->set_blend_mode( Material::BLEND_MODE_ADD ); mat->set_flag(Material::FLAG_DOUBLE_SIDED,true); - mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); +// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true); surface_tool->begin(Mesh::PRIMITIVE_TRIANGLES); diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 5c1d190b2ed..df18e4f0f5c 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -101,6 +101,11 @@ void Environment::_bind_methods() { ObjectTypeDB::bind_method(_MD("fx_set_param","param","value"),&Environment::fx_set_param); ObjectTypeDB::bind_method(_MD("fx_get_param","param"),&Environment::fx_get_param); + ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"ambient_light/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_AMBIENT_LIGHT); + ADD_PROPERTYI( PropertyInfo(Variant::COLOR,"ambient_light/color",PROPERTY_HINT_COLOR_NO_ALPHA),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_AMBIENT_LIGHT_COLOR); + ADD_PROPERTYI( PropertyInfo(Variant::REAL,"ambient_light/energy",PROPERTY_HINT_RANGE,"0,64,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_AMBIENT_LIGHT_ENERGY); + + ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"fxaa/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_FXAA); ADD_PROPERTY( PropertyInfo(Variant::INT,"background/mode",PROPERTY_HINT_ENUM,"Keep,Default Color,Color,Texture,Cubemap,Texture RGBE,Cubemap RGBE"),_SCS("set_background"),_SCS("get_background")); @@ -123,8 +128,9 @@ void Environment::_bind_methods() { ADD_PROPERTYI( PropertyInfo(Variant::REAL,"dof_blur/begin",PROPERTY_HINT_RANGE,"0,4096,0.1"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_DOF_BLUR_BEGIN); ADD_PROPERTYI( PropertyInfo(Variant::REAL,"dof_blur/range",PROPERTY_HINT_RANGE,"0,4096,0.1"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_DOF_BLUR_RANGE); ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"hdr/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_HDR); + ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/tonemapper",PROPERTY_HINT_ENUM,"Linear,Log,Reinhardt,ReinhardtAutoWhite"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_TONEMAPPER); ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/exposure",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_EXPOSURE); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/scalar",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_SCALAR); + ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/white",PROPERTY_HINT_RANGE,"0.01,16,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_WHITE); ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/glow_treshold",PROPERTY_HINT_RANGE,"0.00,8,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_GLOW_TRESHOLD); ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/glow_scale",PROPERTY_HINT_RANGE,"0.00,16,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_GLOW_SCALE); ADD_PROPERTYI( PropertyInfo(Variant::REAL,"hdr/min_luminance",PROPERTY_HINT_RANGE,"0.01,64,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_HDR_MIN_LUMINANCE); @@ -153,7 +159,7 @@ void Environment::_bind_methods() { FX_PARAM_DOF_BLUR_BEGIN=VS::ENV_FX_PARAM_DOF_BLUR_BEGIN, FX_PARAM_DOF_BLUR_END=VS::ENV_FX_PARAM_DOF_BLUR_END, FX_PARAM_HDR_EXPOSURE=VS::ENV_FX_PARAM_HDR_EXPOSURE, - FX_PARAM_HDR_SCALAR=VS::ENV_FX_PARAM_HDR_SCALAR, + FX_PARAM_HDR_WHITE=VS::ENV_FX_PARAM_HDR_WHITE, FX_PARAM_HDR_GLOW_TRESHOLD=VS::ENV_FX_PARAM_HDR_GLOW_TRESHOLD, FX_PARAM_HDR_GLOW_SCALE=VS::ENV_FX_PARAM_HDR_GLOW_SCALE, FX_PARAM_HDR_MIN_LUMINANCE=VS::ENV_FX_PARAM_HDR_MIN_LUMINANCE, @@ -188,6 +194,7 @@ void Environment::_bind_methods() { BIND_CONSTANT( BG_PARAM_MAX ); + BIND_CONSTANT( FX_AMBIENT_LIGHT ); BIND_CONSTANT( FX_FXAA ); BIND_CONSTANT( FX_GLOW ); BIND_CONSTANT( FX_DOF_BLUR ); @@ -202,6 +209,13 @@ void Environment::_bind_methods() { BIND_CONSTANT( FX_BLUR_BLEND_MODE_SCREEN ); BIND_CONSTANT( FX_BLUR_BLEND_MODE_SOFTLIGHT ); + BIND_CONSTANT( FX_HDR_TONE_MAPPER_LINEAR ); + BIND_CONSTANT( FX_HDR_TONE_MAPPER_LOG ); + BIND_CONSTANT( FX_HDR_TONE_MAPPER_REINHARDT ); + BIND_CONSTANT( FX_HDR_TONE_MAPPER_REINHARDT_AUTOWHITE ); + + BIND_CONSTANT( FX_PARAM_AMBIENT_LIGHT_COLOR ); + BIND_CONSTANT( FX_PARAM_AMBIENT_LIGHT_ENERGY ); BIND_CONSTANT( FX_PARAM_GLOW_BLUR_PASSES ); BIND_CONSTANT( FX_PARAM_GLOW_BLUR_SCALE ); BIND_CONSTANT( FX_PARAM_GLOW_BLUR_STRENGTH ); @@ -211,8 +225,9 @@ void Environment::_bind_methods() { BIND_CONSTANT( FX_PARAM_DOF_BLUR_PASSES ); BIND_CONSTANT( FX_PARAM_DOF_BLUR_BEGIN ); BIND_CONSTANT( FX_PARAM_DOF_BLUR_RANGE ); + BIND_CONSTANT( FX_PARAM_HDR_TONEMAPPER); BIND_CONSTANT( FX_PARAM_HDR_EXPOSURE ); - BIND_CONSTANT( FX_PARAM_HDR_SCALAR ); + BIND_CONSTANT( FX_PARAM_HDR_WHITE ); BIND_CONSTANT( FX_PARAM_HDR_GLOW_TRESHOLD ); BIND_CONSTANT( FX_PARAM_HDR_GLOW_SCALE ); BIND_CONSTANT( FX_PARAM_HDR_MIN_LUMINANCE ); @@ -245,6 +260,8 @@ Environment::Environment() { for(int i=0;imaterial_set_hint(material,(VS::MaterialHint)p_hint,p_enabled); - _change_notify(); -} - -bool Material::get_hint(Hint p_hint) const { - - ERR_FAIL_INDEX_V(p_hint,HINT_MAX,false); - return hints[p_hint]; -} - void Material::set_blend_mode(BlendMode p_blend_mode) { ERR_FAIL_INDEX(p_blend_mode,3); @@ -108,17 +78,15 @@ Material::BlendMode Material::get_blend_mode() const { } -void Material::set_shade_model(ShadeModel p_model) { - - ERR_FAIL_INDEX(p_model,8); - shade_model=p_model; - VisualServer::get_singleton()->material_set_shade_model(material,(VS::MaterialShadeModel)p_model); +void Material::set_depth_draw_mode(DepthDrawMode p_depth_draw_mode) { + depth_draw_mode=p_depth_draw_mode; + VisualServer::get_singleton()->material_set_depth_draw_mode(material,(VS::MaterialDepthDrawMode)p_depth_draw_mode); } -Material::ShadeModel Material::get_shade_model() const { +Material::DepthDrawMode Material::get_depth_draw_mode() const { - return shade_model; + return depth_draw_mode; } bool Material::get_flag(Flag p_flag) const { @@ -144,49 +112,32 @@ void Material::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_flag","flag","enable"),&Material::set_flag); ObjectTypeDB::bind_method(_MD("get_flag","flag"),&Material::get_flag); - ObjectTypeDB::bind_method(_MD("set_hint","hint","enable"),&Material::set_hint); - ObjectTypeDB::bind_method(_MD("get_hint","hint"),&Material::get_hint); ObjectTypeDB::bind_method(_MD("set_blend_mode","mode"),&Material::set_blend_mode); ObjectTypeDB::bind_method(_MD("get_blend_mode"),&Material::get_blend_mode); - ObjectTypeDB::bind_method(_MD("set_shade_model","model"),&Material::set_shade_model); - ObjectTypeDB::bind_method(_MD("get_shade_model"),&Material::get_shade_model); ObjectTypeDB::bind_method(_MD("set_line_width","width"),&Material::set_line_width); ObjectTypeDB::bind_method(_MD("get_line_width"),&Material::get_line_width); + ObjectTypeDB::bind_method(_MD("set_depth_draw_mode","mode"),&Material::set_depth_draw_mode); + ObjectTypeDB::bind_method(_MD("get_depth_draw_mode"),&Material::get_depth_draw_mode); for(int i=0;ifixed_material_set_light_shader(material,VS::FixedMaterialLightShader(p_shader)); +} + +FixedMaterial::LightShader FixedMaterial::get_light_shader() const { + + return light_shader; +} + void FixedMaterial::set_uv_transform(const Transform& p_transform) { @@ -356,16 +314,6 @@ Transform FixedMaterial::get_uv_transform() const { -void FixedMaterial::set_detail_blend_mode(BlendMode p_mode) { - - detail_blend_mode=p_mode; - VS::get_singleton()->fixed_material_set_detail_blend_mode(material,(VS::MaterialBlendMode)p_mode); -} - -Material::BlendMode FixedMaterial::get_detail_blend_mode() const { - - return detail_blend_mode; -} void FixedMaterial::set_fixed_flag(FixedFlag p_flag, bool p_value) { ERR_FAIL_INDEX(p_flag,4); @@ -412,12 +360,12 @@ void FixedMaterial::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_uv_transform","transform"),&FixedMaterial::set_uv_transform); ObjectTypeDB::bind_method(_MD("get_uv_transform"),&FixedMaterial::get_uv_transform); + ObjectTypeDB::bind_method(_MD("set_light_shader","shader"),&FixedMaterial::set_light_shader); + ObjectTypeDB::bind_method(_MD("get_light_shader"),&FixedMaterial::get_light_shader); ObjectTypeDB::bind_method(_MD("set_point_size","size"),&FixedMaterial::set_point_size); ObjectTypeDB::bind_method(_MD("get_point_size"),&FixedMaterial::get_point_size); - ObjectTypeDB::bind_method(_MD("set_detail_blend_mode","mode"),&FixedMaterial::set_detail_blend_mode); - ObjectTypeDB::bind_method(_MD("get_detail_blend_mode"),&FixedMaterial::get_detail_blend_mode); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_alpha" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_ALPHA); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_color_array" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_COLOR_ARRAY); @@ -427,11 +375,10 @@ void FixedMaterial::_bind_methods() { ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/specular", PROPERTY_HINT_COLOR_NO_ALPHA ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPECULAR ); ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/emission", PROPERTY_HINT_COLOR_NO_ALPHA ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_EMISSION ); ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/specular_exp", PROPERTY_HINT_RANGE,"1,64,0.01" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPECULAR_EXP ); - ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/detail_blend", PROPERTY_HINT_ENUM,"Mix,Add,Sub,Mul" ), _SCS("set_detail_blend_mode"), _SCS("get_detail_blend_mode") ); ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/detail_mix", PROPERTY_HINT_RANGE,"0,1,0.01" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_DETAIL ); ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/normal_depth", PROPERTY_HINT_RANGE,"-4,4,0.01" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_NORMAL ); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/shade_param", PROPERTY_HINT_RANGE,"0,1,0.01" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADE_PARAM ); - + ADD_PROPERTY( PropertyInfo( Variant::INT, "params/shader", PROPERTY_HINT_ENUM,"Lambert,Wrap,Velvet,Toon" ), _SCS("set_light_shader"), _SCS("get_light_shader") ); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/shader_param", PROPERTY_HINT_RANGE,"0,1,0.01" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADE_PARAM ); ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/glow", PROPERTY_HINT_RANGE,"0,8,0.01" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_GLOW ); ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/point_size", PROPERTY_HINT_RANGE,"0,1024,1" ), _SCS("set_point_size"), _SCS("get_point_size")); ADD_PROPERTY( PropertyInfo( Variant::TRANSFORM, "uv_xform"), _SCS("set_uv_transform"), _SCS("get_uv_transform") ); @@ -479,7 +426,7 @@ FixedMaterial::FixedMaterial() : Material(VS::get_singleton()->fixed_material_cr param[PARAM_SHADE_PARAM]=0.5; param[PARAM_DETAIL]=1.0; - detail_blend_mode=BLEND_MODE_MIX; + fixed_flags[FLAG_USE_ALPHA]=false; fixed_flags[FLAG_USE_COLOR_ARRAY]=false; @@ -490,6 +437,8 @@ FixedMaterial::FixedMaterial() : Material(VS::get_singleton()->fixed_material_cr texture_texcoord[i]=TEXCOORD_UV; } + light_shader=LIGHT_SHADER_LAMBERT; + point_size=1.0; } @@ -633,7 +582,7 @@ ParticleSystemMaterial::ParticleSystemMaterial() :Material(VisualServer::get_sin set_flag(FLAG_DOUBLE_SIDED,true); set_flag(FLAG_UNSHADED,true); - set_hint(HINT_NO_DEPTH_DRAW,true); + set_depth_draw_mode(DEPTH_DRAW_NEVER); VisualServer::get_singleton()->fixed_material_set_flag(material,VS::FIXED_MATERIAL_FLAG_USE_ALPHA,true); VisualServer::get_singleton()->fixed_material_set_flag(material,VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true); } @@ -680,7 +629,8 @@ void UnshadedMaterial::set_use_alpha(bool p_use_alpha) { alpha=p_use_alpha; VS::get_singleton()->fixed_material_set_flag(material,VS::FIXED_MATERIAL_FLAG_USE_ALPHA,p_use_alpha); - set_hint(HINT_NO_DEPTH_DRAW,p_use_alpha); + //set_depth_draw_mode(); + //set_hint(HINT,p_use_alpha); } diff --git a/scene/resources/material.h b/scene/resources/material.h index 2057b3cac9f..23ecb18fac8 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -53,23 +53,10 @@ public: FLAG_INVERT_FACES = VS::MATERIAL_FLAG_INVERT_FACES, FLAG_UNSHADED = VS::MATERIAL_FLAG_UNSHADED, FLAG_ONTOP = VS::MATERIAL_FLAG_ONTOP, - FLAG_WIREFRAME = VS::MATERIAL_FLAG_WIREFRAME, - FLAG_BILLBOARD_TOGGLE = VS::MATERIAL_FLAG_BILLBOARD, + FLAG_LIGHTMAP_ON_UV2 = VS::MATERIAL_FLAG_LIGHTMAP_ON_UV2, FLAG_MAX = VS::MATERIAL_FLAG_MAX }; - enum ShadeModel { - SHADE_MODEL_LAMBERT, - SHADE_MODEL_LAMBERT_WRAP, - SHADE_MODEL_FRESNEL, - SHADE_MODEL_TOON, - SHADE_MODEL_CUSTOM_0, - SHADE_MODEL_CUSTOM_1, - SHADE_MODEL_CUSTOM_2, - SHADE_MODEL_CUSTOM_3 - }; - - enum BlendMode { BLEND_MODE_MIX = VS::MATERIAL_BLEND_MODE_MIX, BLEND_MODE_MUL = VS::MATERIAL_BLEND_MODE_MUL, @@ -79,23 +66,20 @@ public: }; - enum Hint { - - HINT_DECAL=VS::MATERIAL_HINT_DECAL, - HINT_OPAQUE_PRE_PASS=VS::MATERIAL_HINT_OPAQUE_PRE_PASS, - HINT_NO_SHADOW=VS::MATERIAL_HINT_NO_SHADOW, - HINT_NO_DEPTH_DRAW=VS::MATERIAL_HINT_NO_DEPTH_DRAW, - HINT_NO_DEPTH_DRAW_FOR_ALPHA=VS::MATERIAL_HINT_NO_DEPTH_DRAW_FOR_ALPHA, - HINT_MAX=VS::MATERIAL_HINT_MAX + enum DepthDrawMode { + DEPTH_DRAW_ALWAYS = VS::MATERIAL_DEPTH_DRAW_ALWAYS, + DEPTH_DRAW_OPAQUE_ONLY = VS::MATERIAL_DEPTH_DRAW_OPAQUE_ONLY, + DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA = VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA, + DEPTH_DRAW_NEVER = VS::MATERIAL_DEPTH_DRAW_NEVER }; + private: BlendMode blend_mode; bool flags[VS::MATERIAL_FLAG_MAX]; - bool hints[VS::MATERIAL_HINT_MAX]; - ShadeModel shade_model; float line_width; + DepthDrawMode depth_draw_mode; protected: RID material; @@ -105,18 +89,15 @@ public: void set_flag(Flag p_flag,bool p_enabled); bool get_flag(Flag p_flag) const; - void set_hint(Hint p_hint,bool p_enabled); - bool get_hint(Hint p_hint) const; - void set_blend_mode(BlendMode p_blend_mode); BlendMode get_blend_mode() const; + void set_depth_draw_mode(DepthDrawMode p_depth_draw_mode); + DepthDrawMode get_depth_draw_mode() const; + void set_line_width(float p_width); float get_line_width() const; - void set_shade_model(ShadeModel p_model); - ShadeModel get_shade_model() const; - virtual RID get_rid() const; Material(const RID& p_rid=RID()); @@ -124,8 +105,8 @@ public: }; VARIANT_ENUM_CAST( Material::Flag ); -VARIANT_ENUM_CAST( Material::Hint ); -VARIANT_ENUM_CAST( Material::ShadeModel); +VARIANT_ENUM_CAST( Material::DepthDrawMode ); + VARIANT_ENUM_CAST( Material::BlendMode ); @@ -163,6 +144,14 @@ public: FLAG_DISCARD_ALPHA=VS::FIXED_MATERIAL_FLAG_DISCARD_ALPHA }; + enum LightShader { + + LIGHT_SHADER_LAMBERT=VS::FIXED_MATERIAL_LIGHT_SHADER_LAMBERT, + LIGHT_SHADER_WRAP=VS::FIXED_MATERIAL_LIGHT_SHADER_WRAP, + LIGHT_SHADER_VELVET=VS::FIXED_MATERIAL_LIGHT_SHADER_VELVET, + LIGHT_SHADER_TOON=VS::FIXED_MATERIAL_LIGHT_SHADER_TOON + }; + private: @@ -173,10 +162,10 @@ private: int tex; }; - BlendMode detail_blend_mode; Variant param[PARAM_MAX]; Ref texture_param[PARAM_MAX]; TexCoordMode texture_texcoord[PARAM_MAX]; + LightShader light_shader; bool fixed_flags[3]; float point_size; @@ -203,15 +192,15 @@ public: void set_texcoord_mode(Parameter p_parameter, TexCoordMode p_mode); TexCoordMode get_texcoord_mode(Parameter p_parameter) const; + void set_light_shader(LightShader p_shader); + LightShader get_light_shader() const; + void set_uv_transform(const Transform& p_transform); Transform get_uv_transform() const; void set_point_size(float p_transform); float get_point_size() const; - void set_detail_blend_mode(BlendMode p_mode); - BlendMode get_detail_blend_mode() const; - FixedMaterial(); ~FixedMaterial(); @@ -222,6 +211,7 @@ public: VARIANT_ENUM_CAST( FixedMaterial::Parameter ); VARIANT_ENUM_CAST( FixedMaterial::TexCoordMode ); VARIANT_ENUM_CAST( FixedMaterial::FixedFlag ); +VARIANT_ENUM_CAST( FixedMaterial::LightShader ); class ShaderMaterial : public Material { diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp index ca8b6bc110e..afb0ae18156 100644 --- a/scene/resources/polygon_path_finder.cpp +++ b/scene/resources/polygon_path_finder.cpp @@ -41,6 +41,7 @@ void PolygonPathFinder::setup(const Vector& p_points, const Vector for(int i=0;i& p_points, const Vector Vector PolygonPathFinder::find_path(const Vector2& p_from, const Vector2& p_to) { Vector path; - if (!_is_point_inside(p_from)) { - printf("p_from outside\n"); - return path; + + Vector2 from=p_from; + Vector2 to=p_to; + Edge ignore_from_edge(-1,-1); + Edge ignore_to_edge(-1,-1); + + if (!_is_point_inside(from)) { + + float closest_dist=1e20; + Vector2 closest_point; + + for (Set::Element *E=edges.front();E;E=E->next()) { + + const Edge& e=E->get(); + Vector2 seg[2]={ + points[e.points[0]].pos, + points[e.points[1]].pos + }; + + + Vector2 closest = Geometry::get_closest_point_to_segment_2d(from,seg); + float d = from.distance_squared_to(closest); + + if (dget(); + closest_dist=d; + } + } + + from=closest_point; }; - if (!_is_point_inside(p_to)) { - printf("p_to outside\n"); - return path; + + + if (!_is_point_inside(to)) { + float closest_dist=1e20; + Vector2 closest_point; + + for (Set::Element *E=edges.front();E;E=E->next()) { + + const Edge& e=E->get(); + Vector2 seg[2]={ + points[e.points[0]].pos, + points[e.points[1]].pos + }; + + + Vector2 closest = Geometry::get_closest_point_to_segment_2d(to,seg); + float d = to.distance_squared_to(closest); + + if (dget(); + closest_dist=d; + } + } + + to=closest_point; }; //test direct connection @@ -132,11 +182,16 @@ Vector PolygonPathFinder::find_path(const Vector2& p_from, const Vector for (Set::Element *E=edges.front();E;E=E->next()) { const Edge& e=E->get(); + if (e.points[0]==ignore_from_edge.points[0] && e.points[1]==ignore_from_edge.points[1]) + continue; + if (e.points[0]==ignore_to_edge.points[0] && e.points[1]==ignore_to_edge.points[1]) + continue; + Vector2 a = points[e.points[0]].pos; Vector2 b = points[e.points[1]].pos; - if (Geometry::segment_intersects_segment_2d(a,b,p_from,p_to,NULL)) { + if (Geometry::segment_intersects_segment_2d(a,b,from,to,NULL)) { can_see_eachother=false; break; } @@ -145,8 +200,8 @@ Vector PolygonPathFinder::find_path(const Vector2& p_from, const Vector if (can_see_eachother) { - path.push_back(p_from); - path.push_back(p_to); + path.push_back(from); + path.push_back(to); return path; } } @@ -155,12 +210,15 @@ Vector PolygonPathFinder::find_path(const Vector2& p_from, const Vector int aidx = points.size()-2; int bidx = points.size()-1; - points[aidx].pos=p_from; - points[bidx].pos=p_to; + points[aidx].pos=from; + points[bidx].pos=to; points[aidx].distance=0; points[bidx].distance=0; points[aidx].prev=-1; points[bidx].prev=-1; + points[aidx].penalty=0; + points[bidx].penalty=0; + for(int i=0;i PolygonPathFinder::find_path(const Vector2& p_from, const Vector points[i].prev=-1; points[i].distance=0; + if (!_is_point_inside(from*0.5+points[i].pos*0.5)) { + valid_a=false; + + } + + + if (!_is_point_inside(to*0.5+points[i].pos*0.5)) { + valid_b=false; + + } + + for (Set::Element *E=edges.front();E;E=E->next()) { const Edge& e=E->get(); @@ -178,28 +248,45 @@ Vector PolygonPathFinder::find_path(const Vector2& p_from, const Vector if (e.points[0]==i || e.points[1]==i) continue; + Vector2 a = points[e.points[0]].pos; Vector2 b = points[e.points[1]].pos; if (valid_a) { - if (Geometry::segment_intersects_segment_2d(a,b,p_from,points[i].pos,NULL)) { - valid_a=false; + if (e.points[0]!=ignore_from_edge.points[1] && + e.points[1]!=ignore_from_edge.points[1] && + e.points[0]!=ignore_from_edge.points[0] && + e.points[1]!=ignore_from_edge.points[0]) { + + + if (Geometry::segment_intersects_segment_2d(a,b,from,points[i].pos,NULL)) { + valid_a=false; + } } } if (valid_b) { - if (Geometry::segment_intersects_segment_2d(a,b,p_to,points[i].pos,NULL)) { - valid_b=false; + if (e.points[0]!=ignore_to_edge.points[1] && + e.points[1]!=ignore_to_edge.points[1] && + e.points[0]!=ignore_to_edge.points[0] && + e.points[1]!=ignore_to_edge.points[0]) { + + + if (Geometry::segment_intersects_segment_2d(a,b,to,points[i].pos,NULL)) { + valid_b=false; + } } } if (!valid_a && !valid_b) break; + } + if (valid_a) { points[i].connections.insert(aidx); points[aidx].connections.insert(i); @@ -220,7 +307,7 @@ Vector PolygonPathFinder::find_path(const Vector2& p_from, const Vector for(Set::Element *E=points[aidx].connections.front();E;E=E->next()) { open_list.insert(E->get()); - points[E->get()].distance=p_from.distance_to(points[E->get()].pos); + points[E->get()].distance=from.distance_to(points[E->get()].pos); points[E->get()].prev=aidx; } @@ -244,7 +331,9 @@ Vector PolygonPathFinder::find_path(const Vector2& p_from, const Vector const Point& p =points[E->get()]; float cost = p.distance; - cost+=p.pos.distance_to(p_to); + cost+=p.pos.distance_to(to); + cost+=p.penalty; + if (costget(); @@ -352,6 +441,17 @@ void PolygonPathFinder::_set_data(const Dictionary& p_data) { } + if (p_data.has("penalties")) { + + DVector penalties=p_data["penalties"]; + if (penalties.size()==pc) { + DVector::Read pr = penalties.read(); + for(int i=0;i segs=p_data["segments"]; int sc=segs.size(); ERR_FAIL_COND(sc&1); @@ -374,10 +474,15 @@ Dictionary PolygonPathFinder::_get_data() const{ p.resize(points.size()-2); connections.resize(points.size()-2); ind.resize(edges.size()*2); + DVector penalties; + penalties.resize(points.size()-2); { DVector::Write wp=p.write(); + DVector::Write pw=penalties.write(); + for(int i=0;i c; c.resize(points[i].connections.size()); { @@ -403,6 +508,7 @@ Dictionary PolygonPathFinder::_get_data() const{ d["bounds"]=bounds; d["points"]=p; + d["penalties"]=penalties; d["connections"]=connections; d["segments"]=ind; @@ -458,6 +564,19 @@ Rect2 PolygonPathFinder::get_bounds() const { return bounds; } +void PolygonPathFinder::set_point_penalty(int p_point,float p_penalty) { + + ERR_FAIL_INDEX(p_point,points.size()-2); + points[p_point].penalty=p_penalty; +} + +float PolygonPathFinder::get_point_penalty(int p_point) const { + + ERR_FAIL_INDEX_V(p_point,points.size()-2,0); + return points[p_point].penalty; + +} + void PolygonPathFinder::_bind_methods() { @@ -466,6 +585,9 @@ void PolygonPathFinder::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_intersections","from","to"),&PolygonPathFinder::get_intersections); ObjectTypeDB::bind_method(_MD("get_closest_point","point"),&PolygonPathFinder::get_closest_point); ObjectTypeDB::bind_method(_MD("is_point_inside","point"),&PolygonPathFinder::is_point_inside); + ObjectTypeDB::bind_method(_MD("set_point_penalty","idx","penalty"),&PolygonPathFinder::set_point_penalty); + ObjectTypeDB::bind_method(_MD("get_point_penalty","idx"),&PolygonPathFinder::get_point_penalty); + ObjectTypeDB::bind_method(_MD("get_bounds"),&PolygonPathFinder::get_bounds); ObjectTypeDB::bind_method(_MD("_set_data"),&PolygonPathFinder::_set_data); ObjectTypeDB::bind_method(_MD("_get_data"),&PolygonPathFinder::_get_data); diff --git a/scene/resources/polygon_path_finder.h b/scene/resources/polygon_path_finder.h index 002ce709ec8..2cbe3e949d2 100644 --- a/scene/resources/polygon_path_finder.h +++ b/scene/resources/polygon_path_finder.h @@ -11,6 +11,7 @@ class PolygonPathFinder : public Resource { Vector2 pos; Set connections; float distance; + float penalty; int prev; }; @@ -55,9 +56,12 @@ public: void setup(const Vector& p_points, const Vector& p_connections); Vector find_path(const Vector2& p_from, const Vector2& p_to); + void set_point_penalty(int p_point,float p_penalty); + float get_point_penalty(int p_point) const; + bool is_point_inside(const Vector2& p_point) const; Vector2 get_closest_point(const Vector2& p_point) const; - Vector get_intersections(const Vector2& p_from, const Vector2& p_to) const; + Vector get_intersections(const Vector2& p_from, const Vector2& p_to) const; Rect2 get_bounds() const; diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index ffdd92c2d1b..6d65da37824 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -45,9 +45,9 @@ Shader::Mode Shader::get_mode() const { return (Mode)VisualServer::get_singleton()->shader_get_mode(shader); } -void Shader::set_code( const String& p_vertex, const String& p_fragment, int p_vertex_ofs,int p_fragment_ofs) { +void Shader::set_code( const String& p_vertex, const String& p_fragment, const String& p_light,int p_fragment_ofs,int p_light_ofs) { - VisualServer::get_singleton()->shader_set_code(shader,p_vertex,p_fragment,p_vertex_ofs,p_fragment_ofs); + VisualServer::get_singleton()->shader_set_code(shader,p_vertex,p_fragment,p_light,0,p_fragment_ofs,p_light_ofs); params_cache_dirty=true; emit_signal(SceneStringNames::get_singleton()->changed); } @@ -64,6 +64,11 @@ String Shader::get_fragment_code() const { } +String Shader::get_light_code() const { + + return VisualServer::get_singleton()->shader_get_light_code(shader); + +} bool Shader::has_param(const StringName& p_param) const { @@ -106,12 +111,15 @@ Dictionary Shader::_get_code() { String fs = VisualServer::get_singleton()->shader_get_fragment_code(shader); String vs = VisualServer::get_singleton()->shader_get_vertex_code(shader); + String ls = VisualServer::get_singleton()->shader_get_light_code(shader); Dictionary c; c["fragment"]=fs; c["fragment_ofs"]=0; c["vertex"]=vs; c["vertex_ofs"]=0; + c["light"]=ls; + c["light_ofs"]=0; return c; } @@ -119,8 +127,11 @@ void Shader::_set_code(const Dictionary& p_string) { ERR_FAIL_COND(!p_string.has("fragment")); ERR_FAIL_COND(!p_string.has("vertex")); + String light; + if (p_string.has("light")) + light=p_string["light"]; - set_code(p_string["vertex"],p_string["fragment"]); + set_code(p_string["vertex"],p_string["fragment"],light); } void Shader::_bind_methods() { @@ -128,9 +139,10 @@ void Shader::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_mode","mode"),&Shader::set_mode); ObjectTypeDB::bind_method(_MD("get_mode"),&Shader::get_mode); - ObjectTypeDB::bind_method(_MD("set_code","vcode","fcode","vofs","fofs"),&Shader::set_code,DEFVAL(0),DEFVAL(0)); + ObjectTypeDB::bind_method(_MD("set_code","vcode","fcode","lcode","fofs","lofs"),&Shader::set_code,DEFVAL(0),DEFVAL(0)); ObjectTypeDB::bind_method(_MD("get_vertex_code"),&Shader::get_vertex_code); ObjectTypeDB::bind_method(_MD("get_fragment_code"),&Shader::get_fragment_code); + ObjectTypeDB::bind_method(_MD("get_light_code"),&Shader::get_light_code); ObjectTypeDB::bind_method(_MD("has_param","name"),&Shader::has_param); @@ -169,6 +181,7 @@ RES ResourceFormatLoaderShader::load(const String &p_path,const String& p_origin String fragment_code; String vertex_code; + String light_code; int mode=-1; @@ -377,7 +390,7 @@ RES ResourceFormatLoaderShader::load(const String &p_path,const String& p_origin } } - shader->set_code(vertex_code,fragment_code); + shader->set_code(vertex_code,fragment_code,light_code); f->close(); memdelete(f); diff --git a/scene/resources/shader.h b/scene/resources/shader.h index d04774dada9..fff6f1d28a5 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -64,9 +64,10 @@ public: void set_mode(Mode p_mode); Mode get_mode() const; - void set_code( const String& p_vertex, const String& p_fragment, int p_vertex_ofs=0,int p_fragment_ofs=0); + void set_code( const String& p_vertex, const String& p_fragment, const String& p_light,int p_fragment_ofs=0,int p_light_ofs=0); String get_vertex_code() const; String get_fragment_code() const; + String get_light_code() const; void get_param_list(List *p_params) const; bool has_param(const StringName& p_param) const; diff --git a/servers/visual/rasterizer.cpp b/servers/visual/rasterizer.cpp index e21848eac27..e2427448671 100644 --- a/servers/visual/rasterizer.cpp +++ b/servers/visual/rasterizer.cpp @@ -134,23 +134,8 @@ RID Rasterizer::_create_shader(const FixedMaterialShaderKey& p_key) { dcode+="uniform texture fmp_detail_tex;\n"; dcode+="uniform float fmp_detail;\n"; dcode+="color detail=tex( fmp_detail_tex,"+_TEXUVSTR(VS::FIXED_MATERIAL_PARAM_DETAIL)+");\n"; - - switch(p_key.detail_blend) { - - case VS::MATERIAL_BLEND_MODE_MIX: - - dcode+="diffuse=vec4(mix(diffuse.rgb,detail.rgb,detail.a*fmp_detail),diffuse.a);\n"; - break; - case VS::MATERIAL_BLEND_MODE_ADD: - dcode+="diffuse=vec4(diffuse.rgb+detail.rgb*fmp_detail,diffuse.a);\n"; - break; - case VS::MATERIAL_BLEND_MODE_SUB: - dcode+="diffuse=vec4(diffuse.rgb+detail.rgb*fmp_detail,diffuse.a);\n"; - break; - case VS::MATERIAL_BLEND_MODE_MUL: - dcode+="diffuse=diffuse*mix(vec4(1,1,1,1),detail,fmp_detail);\n"; - break; - } + //aways mix + dcode+="diffuse=vec4(mix(diffuse.rgb,detail.rgb,detail.a*fmp_detail),diffuse.a);\n"; code+=dcode; } @@ -223,6 +208,22 @@ RID Rasterizer::_create_shader(const FixedMaterialShaderKey& p_key) { code+="GLOW=glow;\n"; + if (p_key.texture_mask&(1<get_ticks_usec()-t)/1000.0; // print_line("generate: "+rtos(tf)); - shader_set_code(fms.shader,vcode,code,0,0); + shader_set_code(fms.shader,vcode,code,lcode,0,0); fixed_material_shaders[p_key]=fms; return fms.shader; @@ -389,28 +436,6 @@ RID Rasterizer::fixed_material_get_texture(RID p_material,VS::FixedMaterialParam return fm.texture[p_parameter]; } -void Rasterizer::fixed_material_set_detail_blend_mode(RID p_material,VS::MaterialBlendMode p_mode){ - - Map::Element *E = fixed_materials.find(p_material); - ERR_FAIL_COND(!E); - FixedMaterial &fm=*E->get(); - - - fm.get_key(); - ERR_FAIL_INDEX(p_mode,4); - fm.detail_blend=p_mode; - if (!fm.dirty_list.in_list()) - fixed_material_dirty_list.add( &fm.dirty_list ); - -} -VS::MaterialBlendMode Rasterizer::fixed_material_get_detail_blend_mode(RID p_material) const{ - - const Map::Element *E = fixed_materials.find(p_material); - ERR_FAIL_COND_V(!E,VS::MATERIAL_BLEND_MODE_MIX); - const FixedMaterial &fm=*E->get(); - - return fm.detail_blend; -} void Rasterizer::fixed_material_set_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter, VS::FixedMaterialTexCoordMode p_mode) { @@ -462,6 +487,28 @@ Transform Rasterizer::fixed_material_get_uv_transform(RID p_material) const { return fm.uv_xform; } +void Rasterizer::fixed_material_set_light_shader(RID p_material,VS::FixedMaterialLightShader p_shader) { + + Map::Element *E = fixed_materials.find(p_material); + ERR_FAIL_COND(!E); + FixedMaterial &fm=*E->get(); + + fm.light_shader=p_shader; + + if (!fm.dirty_list.in_list()) + fixed_material_dirty_list.add( &fm.dirty_list ); + +} + +VS::FixedMaterialLightShader Rasterizer::fixed_material_get_light_shader(RID p_material) const { + + const Map::Element *E = fixed_materials.find(p_material); + ERR_FAIL_COND_V(!E,VS::FIXED_MATERIAL_LIGHT_SHADER_LAMBERT); + const FixedMaterial &fm=*E->get(); + + return fm.light_shader; +} + void Rasterizer::fixed_material_set_point_size(RID p_material,float p_size) { Map::Element *E = fixed_materials.find(p_material); diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index dc43a789845..2b02a81a441 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -51,7 +51,7 @@ protected: struct { uint16_t texcoord_mask; uint8_t texture_mask; - uint8_t detail_blend:2; + uint8_t light_shader:2; bool use_alpha:1; bool use_color_array:1; bool use_pointsize:1; @@ -85,7 +85,7 @@ protected: bool use_pointsize; float point_size; Transform uv_xform; - VS::MaterialBlendMode detail_blend; + VS::FixedMaterialLightShader light_shader; RID texture[VS::FIXED_MATERIAL_PARAM_MAX]; Variant param[VS::FIXED_MATERIAL_PARAM_MAX]; VS::FixedMaterialTexCoordMode texture_tc[VS::FIXED_MATERIAL_PARAM_MAX]; @@ -103,7 +103,7 @@ protected: k.use_color_array=use_color_array; k.use_pointsize=use_pointsize; k.discard_alpha=discard_alpha; - k.detail_blend=detail_blend; + k.light_shader=light_shader; k.valid=true; for(int i=0;i *p_param_list) const=0; @@ -211,11 +212,8 @@ public: virtual void material_set_flag(RID p_material, VS::MaterialFlag p_flag,bool p_enabled)=0; virtual bool material_get_flag(RID p_material,VS::MaterialFlag p_flag) const=0; - virtual void material_set_hint(RID p_material, VS::MaterialHint p_hint,bool p_enabled)=0; - virtual bool material_get_hint(RID p_material,VS::MaterialHint p_hint) const=0; - - virtual void material_set_shade_model(RID p_material, VS::MaterialShadeModel p_model)=0; - virtual VS::MaterialShadeModel material_get_shade_model(RID p_material) const=0; + virtual void material_set_depth_draw_mode(RID p_material, VS::MaterialDepthDrawMode p_mode)=0; + virtual VS::MaterialDepthDrawMode material_get_depth_draw_mode(RID p_material) const=0; virtual void material_set_blend_mode(RID p_material,VS::MaterialBlendMode p_mode)=0; virtual VS::MaterialBlendMode material_get_blend_mode(RID p_material) const=0; @@ -237,15 +235,15 @@ public: virtual void fixed_material_set_texture(RID p_material,VS::FixedMaterialParam p_parameter, RID p_texture); virtual RID fixed_material_get_texture(RID p_material,VS::FixedMaterialParam p_parameter) const; - virtual void fixed_material_set_detail_blend_mode(RID p_material,VS::MaterialBlendMode p_mode); - virtual VS::MaterialBlendMode fixed_material_get_detail_blend_mode(RID p_material) const; - virtual void fixed_material_set_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter, VS::FixedMaterialTexCoordMode p_mode); virtual VS::FixedMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter) const; virtual void fixed_material_set_uv_transform(RID p_material,const Transform& p_transform); virtual Transform fixed_material_get_uv_transform(RID p_material) const; + virtual void fixed_material_set_light_shader(RID p_material,VS::FixedMaterialLightShader p_shader); + virtual VS::FixedMaterialLightShader fixed_material_get_light_shader(RID p_material) const; + virtual void fixed_material_set_point_size(RID p_material,float p_size); virtual float fixed_material_get_point_size(RID p_material) const; diff --git a/servers/visual/rasterizer_dummy.cpp b/servers/visual/rasterizer_dummy.cpp index 3a04ba7504f..e0c19325891 100644 --- a/servers/visual/rasterizer_dummy.cpp +++ b/servers/visual/rasterizer_dummy.cpp @@ -151,6 +151,7 @@ RID RasterizerDummy::shader_create(VS::ShaderMode p_mode) { shader->mode=p_mode; shader->fragment_line=0; shader->vertex_line=0; + shader->light_line=0; RID rid = shader_owner.make_rid(shader); return rid; @@ -174,16 +175,17 @@ VS::ShaderMode RasterizerDummy::shader_get_mode(RID p_shader) const { return shader->mode; } +void RasterizerDummy::shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,const String& p_light,int p_vertex_ofs,int p_fragment_ofs,int p_light_ofs) { -void RasterizerDummy::shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,int p_vertex_ofs,int p_fragment_ofs) { - Shader *shader=shader_owner.get(p_shader); ERR_FAIL_COND(!shader); shader->fragment_code=p_fragment; shader->vertex_code=p_vertex; + shader->light_code=p_light; shader->fragment_line=p_fragment_ofs; shader->vertex_line=p_vertex_ofs; + shader->light_line=p_vertex_ofs; } @@ -204,6 +206,14 @@ String RasterizerDummy::shader_get_fragment_code(RID p_shader) const { } +String RasterizerDummy::shader_get_light_code(RID p_shader) const { + + Shader *shader=shader_owner.get(p_shader); + ERR_FAIL_COND_V(!shader,String()); + return shader->light_code; + +} + void RasterizerDummy::shader_get_param_list(RID p_shader, List *p_param_list) const { Shader *shader=shader_owner.get(p_shader); @@ -274,39 +284,21 @@ bool RasterizerDummy::material_get_flag(RID p_material,VS::MaterialFlag p_flag) } -void RasterizerDummy::material_set_hint(RID p_material, VS::MaterialHint p_hint,bool p_enabled) { +void RasterizerDummy::material_set_depth_draw_mode(RID p_material, VS::MaterialDepthDrawMode p_mode) { Material *material = material_owner.get(p_material); ERR_FAIL_COND(!material); - ERR_FAIL_INDEX(p_hint,VS::MATERIAL_HINT_MAX); - material->hints[p_hint]=p_enabled; - + material->depth_draw_mode=p_mode; } -bool RasterizerDummy::material_get_hint(RID p_material,VS::MaterialHint p_hint) const { +VS::MaterialDepthDrawMode RasterizerDummy::material_get_depth_draw_mode(RID p_material) const{ Material *material = material_owner.get(p_material); - ERR_FAIL_COND_V(!material,false); - ERR_FAIL_INDEX_V(p_hint,VS::MATERIAL_HINT_MAX,false); - return material->hints[p_hint]; + ERR_FAIL_COND_V(!material,VS::MATERIAL_DEPTH_DRAW_ALWAYS); + return material->depth_draw_mode; } -void RasterizerDummy::material_set_shade_model(RID p_material, VS::MaterialShadeModel p_model) { - - Material *material = material_owner.get(p_material); - ERR_FAIL_COND(!material); - material->shade_model=p_model; - -}; - -VS::MaterialShadeModel RasterizerDummy::material_get_shade_model(RID p_material) const { - - Material *material = material_owner.get(p_material); - ERR_FAIL_COND_V(!material,VS::MATERIAL_SHADE_MODEL_LAMBERT); - return material->shade_model; -}; - void RasterizerDummy::material_set_blend_mode(RID p_material,VS::MaterialBlendMode p_mode) { diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h index a837d54b9b6..01ae6c76444 100644 --- a/servers/visual/rasterizer_dummy.h +++ b/servers/visual/rasterizer_dummy.h @@ -71,10 +71,12 @@ class RasterizerDummy : public Rasterizer { String vertex_code; String fragment_code; + String light_code; VS::ShaderMode mode; Map params; int fragment_line; int vertex_line; + int light_line; bool valid; bool has_alpha; bool use_world_transform; @@ -87,9 +89,8 @@ class RasterizerDummy : public Rasterizer { struct Material { bool flags[VS::MATERIAL_FLAG_MAX]; - bool hints[VS::MATERIAL_HINT_MAX]; - VS::MaterialShadeModel shade_model; + VS::MaterialDepthDrawMode depth_draw_mode; VS::MaterialBlendMode blend_mode; @@ -107,9 +108,8 @@ class RasterizerDummy : public Rasterizer { for(int i=0;i *p_param_list) const; @@ -434,11 +435,8 @@ public: virtual void material_set_flag(RID p_material, VS::MaterialFlag p_flag,bool p_enabled); virtual bool material_get_flag(RID p_material,VS::MaterialFlag p_flag) const; - virtual void material_set_hint(RID p_material, VS::MaterialHint p_hint,bool p_enabled); - virtual bool material_get_hint(RID p_material,VS::MaterialHint p_hint) const; - - virtual void material_set_shade_model(RID p_material, VS::MaterialShadeModel p_model); - virtual VS::MaterialShadeModel material_get_shade_model(RID p_material) const; + virtual void material_set_depth_draw_mode(RID p_material, VS::MaterialDepthDrawMode p_mode); + virtual VS::MaterialDepthDrawMode material_get_depth_draw_mode(RID p_material) const; virtual void material_set_blend_mode(RID p_material,VS::MaterialBlendMode p_mode); virtual VS::MaterialBlendMode material_get_blend_mode(RID p_material) const; diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index cdc1f678e72..16a725010dd 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -859,7 +859,20 @@ const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[]={ {"mix",TYPE_VEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_FLOAT,TYPE_VOID}}, {"mix",TYPE_VEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VEC4,TYPE_VOID}}, {"step",TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}}, + {"step",TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}}, {"step",TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}}, + {"step",TYPE_VEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VOID}}, + {"step",TYPE_VEC2,{TYPE_FLOAT,TYPE_VEC2,TYPE_VOID}}, + {"step",TYPE_VEC3,{TYPE_FLOAT,TYPE_VEC3,TYPE_VOID}}, + {"step",TYPE_VEC4,{TYPE_FLOAT,TYPE_VEC4,TYPE_VOID}}, + {"smoothstep",TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}}, + {"smoothstep",TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VEC2,TYPE_VOID}}, + {"smoothstep",TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VEC3,TYPE_VOID}}, + {"smoothstep",TYPE_VEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VEC4,TYPE_VOID}}, + {"smoothstep",TYPE_VEC2,{TYPE_FLOAT,TYPE_FLOAT,TYPE_VEC2,TYPE_VOID}}, + {"smoothstep",TYPE_VEC3,{TYPE_FLOAT,TYPE_FLOAT,TYPE_VEC3,TYPE_VOID}}, + {"smoothstep",TYPE_VEC4,{TYPE_FLOAT,TYPE_FLOAT,TYPE_VEC4,TYPE_VOID}}, + //intrinsics - geometric {"length",TYPE_FLOAT,{TYPE_VEC2,TYPE_VOID}}, {"length",TYPE_FLOAT,{TYPE_VEC3,TYPE_VOID}}, @@ -1045,6 +1058,27 @@ const ShaderLanguage::BuiltinsDef ShaderLanguage::fragment_builtins_defs[]={ { NULL, TYPE_VOID} }; + +const ShaderLanguage::BuiltinsDef ShaderLanguage::light_builtins_defs[]={ + + { "NORMAL", TYPE_VEC3}, + { "LIGHT_DIR", TYPE_VEC3}, + { "LIGHT_DIFFUSE", TYPE_VEC3}, + { "LIGHT_SPECULAR", TYPE_VEC3}, + { "EYE_VEC", TYPE_VEC3}, + { "DIFFUSE", TYPE_VEC3}, + { "SPECULAR", TYPE_VEC3}, + { "SPECULAR_EXP", TYPE_FLOAT}, + { "SHADE_PARAM", TYPE_FLOAT}, + { "LIGHT", TYPE_VEC3}, + { "POINT_COORD", TYPE_VEC2}, +// { "SCREEN_POS", TYPE_VEC2}, +// { "SCREEN_TEXEL_SIZE", TYPE_VEC2}, + { "TIME", TYPE_FLOAT}, + { NULL, TYPE_VOID} + +}; + const ShaderLanguage::BuiltinsDef ShaderLanguage::postprocess_fragment_builtins_defs[]={ { "IN_COLOR", TYPE_VEC3}, @@ -2286,6 +2320,13 @@ Error ShaderLanguage::parse(const Vector& p_tokens,ShaderType p_type,Comp idx++; } } break; + case SHADER_MATERIAL_LIGHT: { + int idx=0; + while (light_builtins_defs[idx].name) { + parser.program->builtin_variables[light_builtins_defs[idx].name]=light_builtins_defs[idx].type; + idx++; + } + } break; case SHADER_POST_PROCESS: { int idx=0; while (postprocess_fragment_builtins_defs[idx].name) { @@ -2306,8 +2347,9 @@ Error ShaderLanguage::parse(const Vector& p_tokens,ShaderType p_type,Comp t = OS::get_singleton()->get_ticks_usec(); - if (p_compile_func) - p_compile_func(p_userdata,parser.program); + if (p_compile_func) { + err = p_compile_func(p_userdata,parser.program); + } tf = (OS::get_singleton()->get_ticks_usec()-t)/1000.0; //print_line("compile time: "+rtos(tf)); @@ -2318,7 +2360,7 @@ Error ShaderLanguage::parse(const Vector& p_tokens,ShaderType p_type,Comp memdelete( parser.nodegc.front()->get() ); parser.nodegc.pop_front(); } - return OK; + return err; } Error ShaderLanguage::compile(const String& p_code,ShaderType p_type,CompileFunc p_compile_func,void *p_userdata,String *r_error,int *r_err_line,int *r_err_column) { @@ -2372,6 +2414,13 @@ void ShaderLanguage::get_keyword_list(ShaderType p_type, List *p_keyword idx++; } } break; + case SHADER_MATERIAL_LIGHT: { + idx=0; + while (light_builtins_defs[idx].name) { + p_keywords->push_back(light_builtins_defs[idx].name); + idx++; + } + } break; case SHADER_POST_PROCESS: { idx=0; while (postprocess_fragment_builtins_defs[idx].name) { diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index 9455e677cf7..36f5bd64c74 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -46,6 +46,7 @@ public: enum ShaderType { SHADER_MATERIAL_VERTEX, SHADER_MATERIAL_FRAGMENT, + SHADER_MATERIAL_LIGHT, SHADER_POST_PROCESS, }; @@ -215,7 +216,7 @@ public: ProgramNode() { type=TYPE_PROGRAM; } }; - typedef void (*CompileFunc)(void*,ProgramNode*); + typedef Error (*CompileFunc)(void*,ProgramNode*); struct VarInfo { @@ -360,6 +361,7 @@ private: static const BuiltinsDef vertex_builtins_defs[]; static const BuiltinsDef fragment_builtins_defs[]; + static const BuiltinsDef light_builtins_defs[]; static const BuiltinsDef postprocess_fragment_builtins_defs[]; static DataType get_token_datatype(TokenType p_type); diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 4e14e8b26cb..f171b47e9c2 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -130,10 +130,10 @@ VisualServer::ShaderMode VisualServerRaster::shader_get_mode(RID p_shader) const } -void VisualServerRaster::shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,int p_vertex_ofs,int p_fragment_ofs) { +void VisualServerRaster::shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,const String& p_light,int p_vertex_ofs,int p_fragment_ofs,int p_light_ofs) { VS_CHANGED; - rasterizer->shader_set_code(p_shader,p_vertex,p_fragment,p_vertex_ofs,p_fragment_ofs); + rasterizer->shader_set_code(p_shader,p_vertex,p_fragment,p_light,p_vertex_ofs,p_fragment_ofs,p_light_ofs); } String VisualServerRaster::shader_get_vertex_code(RID p_shader) const{ @@ -146,6 +146,11 @@ String VisualServerRaster::shader_get_fragment_code(RID p_shader) const{ return rasterizer->shader_get_fragment_code(p_shader); } +String VisualServerRaster::shader_get_light_code(RID p_shader) const{ + + return rasterizer->shader_get_fragment_code(p_shader); +} + void VisualServerRaster::shader_get_param_list(RID p_shader, List *p_param_list) const { return rasterizer->shader_get_param_list(p_shader,p_param_list); @@ -187,27 +192,16 @@ void VisualServerRaster::material_set_flag(RID p_material, MaterialFlag p_flag,b rasterizer->material_set_flag(p_material,p_flag,p_enabled); } -void VisualServerRaster::material_set_hint(RID p_material, MaterialHint p_hint,bool p_enabled) { +void VisualServerRaster::material_set_depth_draw_mode(RID p_material, MaterialDepthDrawMode p_mode) { VS_CHANGED; - rasterizer->material_set_hint(p_material,p_hint,p_enabled); -} - -bool VisualServerRaster::material_get_hint(RID p_material,MaterialHint p_hint) const { - - return rasterizer->material_get_hint(p_material,p_hint); + rasterizer->material_set_depth_draw_mode(p_material,p_mode); } -void VisualServerRaster::material_set_shade_model(RID p_material, MaterialShadeModel p_model) { - VS_CHANGED; - rasterizer->material_set_shade_model(p_material,p_model); -} - -VisualServer::MaterialShadeModel VisualServerRaster::material_get_shade_model(RID p_material) const { - - return rasterizer->material_get_shade_model(p_material); +VS::MaterialDepthDrawMode VisualServerRaster::material_get_depth_draw_mode(RID p_material) const { + return rasterizer->material_get_depth_draw_mode(p_material); } @@ -273,17 +267,6 @@ RID VisualServerRaster::fixed_material_get_texture(RID p_material,FixedMaterialP } -void VisualServerRaster::fixed_material_set_detail_blend_mode(RID p_material,MaterialBlendMode p_mode) { - VS_CHANGED; - rasterizer->fixed_material_set_detail_blend_mode(p_material,p_mode); -} - -VS::MaterialBlendMode VisualServerRaster::fixed_material_get_detail_blend_mode(RID p_material) const { - - return rasterizer->fixed_material_get_detail_blend_mode(p_material); -} - - void VisualServerRaster::fixed_material_set_texcoord_mode(RID p_material,FixedMaterialParam p_parameter, FixedMaterialTexCoordMode p_mode) { @@ -318,6 +301,18 @@ Transform VisualServerRaster::fixed_material_get_uv_transform(RID p_material) co return rasterizer->fixed_material_get_uv_transform(p_material); } +void VisualServerRaster::fixed_material_set_light_shader(RID p_material,FixedMaterialLightShader p_shader) { + + VS_CHANGED; + rasterizer->fixed_material_set_light_shader(p_material,p_shader); + +} + +VisualServerRaster::FixedMaterialLightShader VisualServerRaster::fixed_material_get_light_shader(RID p_material) const{ + + return rasterizer->fixed_material_get_light_shader(p_material); +} + /* MESH API */ diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index ddc30bb2eed..0368780bfb0 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -691,9 +691,10 @@ public: virtual void shader_set_mode(RID p_shader,ShaderMode p_mode); virtual ShaderMode shader_get_mode(RID p_shader) const; - virtual void shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,int p_vertex_ofs=0,int p_fragment_ofs=0); + virtual void shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,const String& p_light,int p_vertex_ofs=0,int p_fragment_ofs=0,int p_light_ofs=0); virtual String shader_get_vertex_code(RID p_shader) const; virtual String shader_get_fragment_code(RID p_shader) const; + virtual String shader_get_light_code(RID p_shader) const; virtual void shader_get_param_list(RID p_shader, List *p_param_list) const; @@ -710,11 +711,8 @@ public: virtual void material_set_flag(RID p_material, MaterialFlag p_flag,bool p_enabled); virtual bool material_get_flag(RID p_material,MaterialFlag p_flag) const; - virtual void material_set_hint(RID p_material, MaterialHint p_hint,bool p_enabled); - virtual bool material_get_hint(RID p_material,MaterialHint p_hint) const; - - virtual void material_set_shade_model(RID p_material, MaterialShadeModel p_model); - virtual MaterialShadeModel material_get_shade_model(RID p_material) const; + virtual void material_set_depth_draw_mode(RID p_material, MaterialDepthDrawMode p_mode); + virtual MaterialDepthDrawMode material_get_depth_draw_mode(RID p_material) const; virtual void material_set_blend_mode(RID p_material,MaterialBlendMode p_mode); virtual MaterialBlendMode material_get_blend_mode(RID p_material) const; @@ -736,16 +734,16 @@ public: virtual void fixed_material_set_texture(RID p_material,FixedMaterialParam p_parameter, RID p_texture); virtual RID fixed_material_get_texture(RID p_material,FixedMaterialParam p_parameter) const; - virtual void fixed_material_set_detail_blend_mode(RID p_material,MaterialBlendMode p_mode); - virtual MaterialBlendMode fixed_material_get_detail_blend_mode(RID p_material) const; - - virtual void fixed_material_set_texcoord_mode(RID p_material,FixedMaterialParam p_parameter, FixedMaterialTexCoordMode p_mode); virtual FixedMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,FixedMaterialParam p_parameter) const; + virtual void fixed_material_set_uv_transform(RID p_material,const Transform& p_transform); virtual Transform fixed_material_get_uv_transform(RID p_material) const; + virtual void fixed_material_set_light_shader(RID p_material,FixedMaterialLightShader p_shader); + virtual FixedMaterialLightShader fixed_material_get_light_shader(RID p_material) const; + virtual void fixed_material_set_point_size(RID p_material,float p_size); virtual float fixed_material_get_point_size(RID p_material) const; diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index f807a4b3a9e..d577ca0c593 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -647,9 +647,10 @@ public: FUNC1R(RID,shader_create,ShaderMode); FUNC2(shader_set_mode,RID,ShaderMode); FUNC1RC(ShaderMode,shader_get_mode,RID); - FUNC5(shader_set_code,RID,const String&,const String&,int,int); + FUNC7(shader_set_code,RID,const String&,const String&,const String&,int,int,int); FUNC1RC(String,shader_get_vertex_code,RID); FUNC1RC(String,shader_get_fragment_code,RID); + FUNC1RC(String,shader_get_light_code,RID); FUNC2SC(shader_get_param_list,RID,List*); /*virtual void shader_get_param_list(RID p_shader, List *p_param_list) { @@ -675,11 +676,8 @@ public: FUNC3(material_set_flag,RID,MaterialFlag,bool); FUNC2RC(bool,material_get_flag,RID,MaterialFlag); - FUNC3(material_set_hint,RID,MaterialHint,bool); - FUNC2RC(bool,material_get_hint,RID,MaterialHint); - - FUNC2(material_set_shade_model,RID,MaterialShadeModel); - FUNC1RC(MaterialShadeModel,material_get_shade_model,RID); + FUNC2(material_set_depth_draw_mode,RID,MaterialDepthDrawMode); + FUNC1RC(MaterialDepthDrawMode,material_get_depth_draw_mode,RID); FUNC2(material_set_blend_mode,RID,MaterialBlendMode); FUNC1RC(MaterialBlendMode,material_get_blend_mode,RID); @@ -701,13 +699,14 @@ public: FUNC3(fixed_material_set_texture,RID ,FixedMaterialParam, RID ); FUNC2RC(RID, fixed_material_get_texture,RID,FixedMaterialParam); - FUNC2(fixed_material_set_detail_blend_mode,RID ,MaterialBlendMode ); - FUNC1RC(MaterialBlendMode, fixed_material_get_detail_blend_mode,RID); FUNC3(fixed_material_set_texcoord_mode,RID,FixedMaterialParam, FixedMaterialTexCoordMode ); FUNC2RC(FixedMaterialTexCoordMode, fixed_material_get_texcoord_mode,RID,FixedMaterialParam); + FUNC2(fixed_material_set_light_shader,RID,FixedMaterialLightShader); + FUNC1RC(FixedMaterialLightShader, fixed_material_get_light_shader,RID); + FUNC2(fixed_material_set_uv_transform,RID,const Transform&); FUNC1RC(Transform, fixed_material_get_uv_transform,RID); diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index d2b55092d6c..8dfcb186a99 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -298,7 +298,7 @@ RID VisualServer::material_2d_get(bool p_shaded, bool p_transparent, bool p_cut_ fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_DISCARD_ALPHA,p_cut_alpha); material_set_flag(material_2d[version],MATERIAL_FLAG_UNSHADED,!p_shaded); material_set_flag(material_2d[version],MATERIAL_FLAG_DOUBLE_SIDED,true); - material_set_hint(material_2d[version],MATERIAL_HINT_OPAQUE_PRE_PASS,p_opaque_prepass); + material_set_depth_draw_mode(material_2d[version],p_opaque_prepass?MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA:MATERIAL_DEPTH_DRAW_OPAQUE_ONLY); fixed_material_set_texture(material_2d[version],FIXED_MATERIAL_PARAM_DIFFUSE,get_white_texture()); //material cut alpha? return material_2d[version]; @@ -568,8 +568,6 @@ void VisualServer::_bind_methods() { BIND_CONSTANT( MATERIAL_FLAG_INVERT_FACES ); BIND_CONSTANT( MATERIAL_FLAG_UNSHADED ); BIND_CONSTANT( MATERIAL_FLAG_ONTOP ); - BIND_CONSTANT( MATERIAL_FLAG_WIREFRAME ); - BIND_CONSTANT( MATERIAL_FLAG_BILLBOARD ); BIND_CONSTANT( MATERIAL_FLAG_MAX ); BIND_CONSTANT( MATERIAL_BLEND_MODE_MIX ); @@ -642,7 +640,7 @@ void VisualServer::_bind_methods() { BIND_CONSTANT( LIGHT_OMNI ); BIND_CONSTANT( LIGHT_SPOT ); - BIND_CONSTANT( LIGHT_COLOR_AMBIENT ); + BIND_CONSTANT( LIGHT_COLOR_DIFFUSE ); BIND_CONSTANT( LIGHT_COLOR_SPECULAR ); diff --git a/servers/visual_server.h b/servers/visual_server.h index fa4090d39e5..9cad173903e 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -142,9 +142,10 @@ public: virtual void shader_set_mode(RID p_shader,ShaderMode p_mode)=0; virtual ShaderMode shader_get_mode(RID p_shader) const=0; - virtual void shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,int p_vertex_ofs=0,int p_fragment_ofs=0)=0; + virtual void shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,const String& p_light, int p_vertex_ofs=0,int p_fragment_ofs=0,int p_light_ofs=0)=0; virtual String shader_get_fragment_code(RID p_shader) const=0; virtual String shader_get_vertex_code(RID p_shader) const=0; + virtual String shader_get_light_code(RID p_shader) const=0; virtual void shader_get_param_list(RID p_shader, List *p_param_list) const=0; @@ -164,39 +165,22 @@ public: MATERIAL_FLAG_INVERT_FACES, ///< Invert front/back of the object MATERIAL_FLAG_UNSHADED, MATERIAL_FLAG_ONTOP, - MATERIAL_FLAG_WIREFRAME, - MATERIAL_FLAG_BILLBOARD, + MATERIAL_FLAG_LIGHTMAP_ON_UV2, MATERIAL_FLAG_MAX, }; virtual void material_set_flag(RID p_material, MaterialFlag p_flag,bool p_enabled)=0; virtual bool material_get_flag(RID p_material,MaterialFlag p_flag) const=0; - enum MaterialShadeModel { - MATERIAL_SHADE_MODEL_LAMBERT, - MATERIAL_SHADE_MODEL_LAMBERT_WRAP, - MATERIAL_SHADE_MODEL_TOON + enum MaterialDepthDrawMode { + MATERIAL_DEPTH_DRAW_ALWAYS, + MATERIAL_DEPTH_DRAW_OPAQUE_ONLY, + MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA, + MATERIAL_DEPTH_DRAW_NEVER }; - /* FIXED MATERIAL */ - - - - virtual void material_set_shade_model(RID p_material, MaterialShadeModel p_model)=0; - virtual MaterialShadeModel material_get_shade_model(RID p_material) const=0; - - enum MaterialHint { - - MATERIAL_HINT_DECAL, - MATERIAL_HINT_OPAQUE_PRE_PASS, - MATERIAL_HINT_NO_SHADOW, - MATERIAL_HINT_NO_DEPTH_DRAW, - MATERIAL_HINT_NO_DEPTH_DRAW_FOR_ALPHA, - MATERIAL_HINT_MAX - }; - - virtual void material_set_hint(RID p_material, MaterialHint p_hint,bool p_enabled)=0; - virtual bool material_get_hint(RID p_material,MaterialHint p_hint) const=0; + virtual void material_set_depth_draw_mode(RID p_material, MaterialDepthDrawMode p_mode)=0; + virtual MaterialDepthDrawMode material_get_depth_draw_mode(RID p_material) const=0; enum MaterialBlendMode { MATERIAL_BLEND_MODE_MIX, //default @@ -258,8 +242,19 @@ public: virtual void fixed_material_set_texture(RID p_material,FixedMaterialParam p_parameter, RID p_texture)=0; virtual RID fixed_material_get_texture(RID p_material,FixedMaterialParam p_parameter) const=0; - virtual void fixed_material_set_detail_blend_mode(RID p_material,MaterialBlendMode p_mode)=0; - virtual MaterialBlendMode fixed_material_get_detail_blend_mode(RID p_material) const=0; + + enum FixedMaterialLightShader { + + FIXED_MATERIAL_LIGHT_SHADER_LAMBERT, + FIXED_MATERIAL_LIGHT_SHADER_WRAP, + FIXED_MATERIAL_LIGHT_SHADER_VELVET, + FIXED_MATERIAL_LIGHT_SHADER_TOON, + + }; + + + virtual void fixed_material_set_light_shader(RID p_material,FixedMaterialLightShader p_shader)=0; + virtual FixedMaterialLightShader fixed_material_get_light_shader(RID p_material) const=0; virtual void fixed_material_set_texcoord_mode(RID p_material,FixedMaterialParam p_parameter, FixedMaterialTexCoordMode p_mode)=0; virtual FixedMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,FixedMaterialParam p_parameter) const=0; @@ -464,9 +459,7 @@ public: LIGHT_SPOT }; - enum LightColor { - - LIGHT_COLOR_AMBIENT, + enum LightColor { LIGHT_COLOR_DIFFUSE, LIGHT_COLOR_SPECULAR }; @@ -724,6 +717,7 @@ public: virtual Variant environment_get_background_param(RID p_env,EnvironmentBGParam p_param) const=0; enum EnvironmentFx { + ENV_FX_AMBIENT_LIGHT, ENV_FX_FXAA, ENV_FX_GLOW, ENV_FX_DOF_BLUR, @@ -745,7 +739,16 @@ public: ENV_FX_BLUR_BLEND_MODE_SOFTLIGHT, }; + enum EnvironmentFxHDRToneMapper { + ENV_FX_HDR_TONE_MAPPER_LINEAR, + ENV_FX_HDR_TONE_MAPPER_LOG, + ENV_FX_HDR_TONE_MAPPER_REINHARDT, + ENV_FX_HDR_TONE_MAPPER_REINHARDT_AUTOWHITE, + }; + enum EnvironmentFxParam { + ENV_FX_PARAM_AMBIENT_LIGHT_COLOR, + ENV_FX_PARAM_AMBIENT_LIGHT_ENERGY, ENV_FX_PARAM_GLOW_BLUR_PASSES, ENV_FX_PARAM_GLOW_BLUR_SCALE, ENV_FX_PARAM_GLOW_BLUR_STRENGTH, @@ -755,8 +758,9 @@ public: ENV_FX_PARAM_DOF_BLUR_PASSES, ENV_FX_PARAM_DOF_BLUR_BEGIN, ENV_FX_PARAM_DOF_BLUR_RANGE, + ENV_FX_PARAM_HDR_TONEMAPPER, ENV_FX_PARAM_HDR_EXPOSURE, - ENV_FX_PARAM_HDR_SCALAR, + ENV_FX_PARAM_HDR_WHITE, ENV_FX_PARAM_HDR_GLOW_TRESHOLD, ENV_FX_PARAM_HDR_GLOW_SCALE, ENV_FX_PARAM_HDR_MIN_LUMINANCE, diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index afd5ee66c5d..9132abcb6e1 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -734,6 +734,7 @@ void EditorNode::_save_scene(String p_file) { flg|=ResourceSaver::FLAG_COMPRESS; if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative")) flg|=ResourceSaver::FLAG_RELATIVE_PATHS; + flg|=ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; err = ResourceSaver::save(p_file,sdata,flg); diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp index 6cd6170bb64..5b4f9960a36 100644 --- a/tools/editor/io_plugins/editor_import_collada.cpp +++ b/tools/editor/io_plugins/editor_import_collada.cpp @@ -199,7 +199,7 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) { return OK; //well, it's an ambient light.. Light *l = memnew( DirectionalLight ); - l->set_color(Light::COLOR_AMBIENT,ld.color); +// l->set_color(Light::COLOR_AMBIENT,ld.color); l->set_color(Light::COLOR_DIFFUSE,Color(0,0,0)); l->set_color(Light::COLOR_SPECULAR,Color(0,0,0)); node = l; @@ -208,8 +208,8 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) { //well, it's an ambient light.. Light *l = memnew( DirectionalLight ); - if (found_ambient) //use it here - l->set_color(Light::COLOR_AMBIENT,ambient); + //if (found_ambient) //use it here + // l->set_color(Light::COLOR_AMBIENT,ambient); l->set_color(Light::COLOR_DIFFUSE,ld.color); l->set_color(Light::COLOR_SPECULAR,Color(1,1,1)); @@ -661,7 +661,7 @@ Error ColladaImport::_create_mesh_surfaces(Ref& p_mesh,const Mapconnect("pressed", this,"_browse"); hbc = memnew( HBoxContainer ); - vbc->add_margin_child("Target Scene:",hbc); + vbc->add_margin_child("Target Path:",hbc); save_path = memnew( LineEdit ); save_path->set_h_size_flags(SIZE_EXPAND_FILL); @@ -1024,7 +1024,7 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map if (fm.is_valid()) { fm->set_flag(Material::FLAG_UNSHADED,true); fm->set_flag(Material::FLAG_DOUBLE_SIDED,true); - fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true); + fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true); } } @@ -1129,7 +1129,7 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map if (fm.is_valid()) { fm->set_flag(Material::FLAG_UNSHADED,true); fm->set_flag(Material::FLAG_DOUBLE_SIDED,true); - fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true); + fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true); } } @@ -1501,6 +1501,37 @@ void EditorSceneImportPlugin::_merge_existing_node(Node *p_node,Node *p_imported room_node->set_room( room_imported->get_room() ); + } else if (p_node->get_type()=="Skeleton") { + //for paths, overwrite path + + Skeleton *skeleton_imported =imported_node->cast_to(); + Skeleton *skeleton_node =p_node->cast_to(); + + //use imported bones, obviously + skeleton_node->clear_bones(); + for(int i=0;iget_bone_count();i++) { + + skeleton_node->add_bone(skeleton_imported->get_bone_name(i)); + skeleton_node->set_bone_parent(i,skeleton_imported->get_bone_parent(i)); + skeleton_node->set_bone_rest(i,skeleton_imported->get_bone_rest(i)); + skeleton_node->set_bone_pose(i,skeleton_imported->get_bone_pose(i)); + } + } else if (p_node->get_type()=="AnimationPlayer") { + //for paths, overwrite path + + AnimationPlayer *aplayer_imported =imported_node->cast_to(); + AnimationPlayer *aplayer_node =p_node->cast_to(); + + //use imported bones, obviously + List anims; + aplayer_imported->get_animation_list(&anims); + //use imported animations, could merge some stuff though + for (List::Element *E=anims.front();E;E=E->next()) { + + + aplayer_node->add_animation(E->get(),aplayer_imported->get_animation(E->get())); + } + } else if (p_node->get_type()=="CollisionShape") { //for paths, overwrite path @@ -1877,14 +1908,14 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c if (merge) { - print_line("MERGING?????"); + progress.step("Merging..",103); FileAccess *fa = FileAccess::create(FileAccess::ACCESS_RESOURCES); - print_line("OPEN IN FS: "+p_dest_path); + if (fa->file_exists(p_dest_path)) { - print_line("TRY REALLY TO MERGE?"); + //try to merge Ref s = ResourceLoader::load(p_dest_path); @@ -1915,7 +1946,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c packer->set_import_metadata(from); print_line("SAVING TO: "+p_dest_path); - err = ResourceSaver::save(p_dest_path,packer); + err = ResourceSaver::save(p_dest_path,packer,ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS); //EditorFileSystem::get_singleton()->update_resource(packer); diff --git a/tools/editor/plugins/shader_editor_plugin.cpp b/tools/editor/plugins/shader_editor_plugin.cpp index 9b6b07dc2e0..73b62658193 100644 --- a/tools/editor/plugins/shader_editor_plugin.cpp +++ b/tools/editor/plugins/shader_editor_plugin.cpp @@ -57,7 +57,9 @@ void ShaderTextEditor::set_edited_shader(const Ref& p_shader,ShaderLangu _load_theme_settings(); - if (p_type==ShaderLanguage::SHADER_MATERIAL_VERTEX) + if (p_type==ShaderLanguage::SHADER_MATERIAL_LIGHT) + get_text_edit()->set_text(shader->get_light_code()); + else if (p_type==ShaderLanguage::SHADER_MATERIAL_VERTEX) get_text_edit()->set_text(shader->get_vertex_code()); else get_text_edit()->set_text(shader->get_fragment_code()); @@ -129,7 +131,9 @@ void ShaderTextEditor::_validate_script() { int line,col; String code; - if (type==ShaderLanguage::SHADER_MATERIAL_VERTEX) + if (type==ShaderLanguage::SHADER_MATERIAL_LIGHT) + code=get_text_edit()->get_text(); + else if (type==ShaderLanguage::SHADER_MATERIAL_VERTEX) code=get_text_edit()->get_text(); else code=get_text_edit()->get_text(); @@ -364,6 +368,7 @@ void ShaderEditor::_params_changed() { fragment_editor->_validate_script(); vertex_editor->_validate_script(); + light_editor->_validate_script(); } @@ -400,6 +405,7 @@ void ShaderEditor::edit(const Ref& p_shader) { if (shader->get_mode()==Shader::MODE_MATERIAL) { fragment_editor->set_edited_shader(p_shader,ShaderLanguage::SHADER_MATERIAL_FRAGMENT); + light_editor->set_edited_shader(shader,ShaderLanguage::SHADER_MATERIAL_LIGHT); settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_MATERIAL_MODE), true); settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_POST_PROCESS_MODE), false); } else { @@ -431,7 +437,7 @@ void ShaderEditor::apply_shaders() { if (shader.is_valid()) - shader->set_code(vertex_editor->get_text_edit()->get_text(),fragment_editor->get_text_edit()->get_text(),0,0); + shader->set_code(vertex_editor->get_text_edit()->get_text(),fragment_editor->get_text_edit()->get_text(),light_editor->get_text_edit()->get_text(),0,0); } void ShaderEditor::_close_callback() { @@ -514,11 +520,16 @@ ShaderEditor::ShaderEditor() { tab_container->add_child(fragment_editor); fragment_editor->set_name("Fragment"); + light_editor = memnew( ShaderTextEditor ); + tab_container->add_child(light_editor); + light_editor->set_name("Lighting"); + tab_container->set_current_tab(1); vertex_editor->connect("script_changed", this,"apply_shaders"); fragment_editor->connect("script_changed", this,"apply_shaders"); + light_editor->connect("script_changed", this,"apply_shaders"); } diff --git a/tools/editor/plugins/shader_editor_plugin.h b/tools/editor/plugins/shader_editor_plugin.h index 8d5f2dae427..49caee5da6f 100644 --- a/tools/editor/plugins/shader_editor_plugin.h +++ b/tools/editor/plugins/shader_editor_plugin.h @@ -99,6 +99,7 @@ class ShaderEditor : public Control { ShaderTextEditor *vertex_editor; ShaderTextEditor *fragment_editor; + ShaderTextEditor *light_editor; void _tab_changed(int p_which); void _menu_option(int p_optin); diff --git a/tools/editor/resources_dock.cpp b/tools/editor/resources_dock.cpp index eb2e526d713..d0284056bbd 100644 --- a/tools/editor/resources_dock.cpp +++ b/tools/editor/resources_dock.cpp @@ -158,7 +158,7 @@ void ResourcesDock::save_resource(const String& p_path,const Ref& p_re flg|=ResourceSaver::FLAG_RELATIVE_PATHS; String path = Globals::get_singleton()->localize_path(p_path); - Error err = ResourceSaver::save(path,p_resource,flg); + Error err = ResourceSaver::save(path,p_resource,flg|ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS); if (err!=OK) { accept->set_text("Error saving resource!"); diff --git a/tools/editor/spatial_editor_gizmos.cpp b/tools/editor/spatial_editor_gizmos.cpp index 71a5ae3d3c5..83efb48bd35 100644 --- a/tools/editor/spatial_editor_gizmos.cpp +++ b/tools/editor/spatial_editor_gizmos.cpp @@ -2232,7 +2232,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() { light_material_omni_icon = Ref( memnew( FixedMaterial )); light_material_omni_icon->set_flag(Material::FLAG_UNSHADED, true); light_material_omni_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); - light_material_omni_icon->set_hint(Material::HINT_NO_DEPTH_DRAW, true); + light_material_omni_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); light_material_omni_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); light_material_omni_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); light_material_omni_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoLight","EditorIcons")); @@ -2241,7 +2241,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() { light_material_directional_icon = Ref( memnew( FixedMaterial )); light_material_directional_icon->set_flag(Material::FLAG_UNSHADED, true); light_material_directional_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); - light_material_directional_icon->set_hint(Material::HINT_NO_DEPTH_DRAW, true); + light_material_directional_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); light_material_directional_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); light_material_directional_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); light_material_directional_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight","EditorIcons")); @@ -2253,7 +2253,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() { skeleton_material->set_flag(Material::FLAG_DOUBLE_SIDED,true); skeleton_material->set_flag(Material::FLAG_UNSHADED,true); skeleton_material->set_flag(Material::FLAG_ONTOP,true); - skeleton_material->set_hint(Material::HINT_NO_DEPTH_DRAW,true); + skeleton_material->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); //position 3D Shared mesh @@ -2293,7 +2293,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() { sample_player_icon = Ref( memnew( FixedMaterial )); sample_player_icon->set_flag(Material::FLAG_UNSHADED, true); sample_player_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); - sample_player_icon->set_hint(Material::HINT_NO_DEPTH_DRAW, true); + sample_player_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); sample_player_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); sample_player_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); sample_player_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoSpatialSamplePlayer","EditorIcons")); @@ -2307,7 +2307,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() { stream_player_icon = Ref( memnew( FixedMaterial )); stream_player_icon->set_flag(Material::FLAG_UNSHADED, true); stream_player_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); - stream_player_icon->set_hint(Material::HINT_NO_DEPTH_DRAW, true); + stream_player_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); stream_player_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); stream_player_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); stream_player_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoSpatialStreamPlayer","EditorIcons")); @@ -2315,7 +2315,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() { visibility_notifier_icon = Ref( memnew( FixedMaterial )); visibility_notifier_icon->set_flag(Material::FLAG_UNSHADED, true); visibility_notifier_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); - visibility_notifier_icon->set_hint(Material::HINT_NO_DEPTH_DRAW, true); + visibility_notifier_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); visibility_notifier_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); visibility_notifier_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); visibility_notifier_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("Visible","EditorIcons"));