diff options
127 files changed, 3440 insertions, 884 deletions
diff --git a/.gitignore b/.gitignore index 32c7fe51c1..45bf531311 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ drivers/gles2/shaders/*.h modules/register_module_types.cpp core/version.h core/method_bind.inc +core/script_encryption_key.cpp core/global_defaults.cpp tools/editor/register_exporters.cpp tools/editor/doc_data_compressed.h @@ -22,9 +23,16 @@ tools/editor/editor_icons.cpp platform/android/java/local.properties platform/android/java/project.properties platform/android/java/AndroidManifest.xml -platform/android/java/bin/ -platform/android/java/gen/ +platform/android/java/bin/* +platform/android/java/libs/* +platform/android/java/gen/* platform/android/java/assets +platform/android/libs/apk_expansion/bin/* +platform/android/libs/apk_expansion/gen/* +platform/android/libs/google_play_services/bin/* +platform/android/libs/google_play_services/gen/* +platform/android/libs/play_licensing/bin/* +platform/android/libs/play_licensing/gen/* # General c++ generated files *.lib diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..73b07acb7f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: cpp +compiler: + - gcc +before_install: + + +before_script: + - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y + - sudo apt-get update -qq + - sudo apt-get install -qq scons pkg-config libx11-dev libxcursor-dev build-essential libasound2-dev libfreetype6-dev libgl1-mesa-dev libglu-dev + - if [ "$CXX" = "g++" ]; then sudo apt-get install -qq g++-4.8; fi + - if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi + +script: scons bin/godot diff --git a/bin/tests/test_detailer.cpp b/bin/tests/test_detailer.cpp index 7eac6755d7..4cb927411a 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_gui.cpp b/bin/tests/test_gui.cpp index f45fe358a6..f814b0282b 100644 --- a/bin/tests/test_gui.cpp +++ b/bin/tests/test_gui.cpp @@ -305,7 +305,7 @@ public: richtext->push_color(Color(1,0.5,0.5)); richtext->add_text("leprechauns"); richtext->pop(); -#if 0 + richtext->add_text(" and "); richtext->push_color(Color(0,1.0,0.5)); richtext->add_text("faeries.\n"); @@ -329,7 +329,7 @@ public: richtext->pop(); richtext->add_text("of the rich text label for huge text (not like this text will really be huge but, you know).\nAs long as it is so long that it will work nicely for a test/demo, then it's welcomed in my book...\nChanging subject, the day is cloudy today and I'm wondering if I'll get che chance to travel somewhere nice. Sometimes, watching the clouds from satellite images may give a nice insight about how pressure zones in our planet work, althogh it also makes it pretty obvious to see why most weather forecasts get it wrong so often.\nClouds are so difficult to predict!\nBut it's pretty cool how our civilization has adapted to having water falling from the sky each time it rains..."); //richtext->add_text("Hello!\nGorgeous.."); -#endif + //richtext->push_meta("http://www.scrollingcapabilities.xz"); ///richtext->add_text("Hello!\n"); diff --git a/bin/tests/test_misc.cpp b/bin/tests/test_misc.cpp index 32d1bbf090..819afc0d06 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 f6f526fb21..2ccbb31017 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 b45b356ee3..cad3658d84 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 3ee32fe1aa..059781b64c 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/bind/core_bind.cpp b/core/bind/core_bind.cpp index 4f5358591a..64b31d6fdd 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -235,7 +235,7 @@ Error _OS::shell_open(String p_uri) { }; -int _OS::execute(const String& p_path, const Vector<String> & p_arguments,bool p_blocking) { +int _OS::execute(const String& p_path, const Vector<String> & p_arguments, bool p_blocking, Array p_output) { OS::ProcessID pid; List<String> args; @@ -243,6 +243,8 @@ int _OS::execute(const String& p_path, const Vector<String> & p_arguments,bool p args.push_back(p_arguments[i]); String pipe; Error err = OS::get_singleton()->execute(p_path,args,p_blocking,&pid, &pipe); + p_output.clear(); + p_output.push_back(pipe); if (err != OK) return -1; else @@ -616,7 +618,7 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_processor_count"),&_OS::get_processor_count); ObjectTypeDB::bind_method(_MD("get_executable_path"),&_OS::get_executable_path); - ObjectTypeDB::bind_method(_MD("execute","path","arguments","blocking"),&_OS::execute); + ObjectTypeDB::bind_method(_MD("execute","path","arguments","blocking","output"),&_OS::execute,DEFVAL(Array())); ObjectTypeDB::bind_method(_MD("kill","pid"),&_OS::kill); ObjectTypeDB::bind_method(_MD("shell_open","uri"),&_OS::shell_open); ObjectTypeDB::bind_method(_MD("get_process_ID"),&_OS::get_process_ID); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 02fe3e8874..20a33fa013 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -123,7 +123,8 @@ public: bool is_in_low_processor_usage_mode() const; String get_executable_path() const; - int execute(const String& p_path, const Vector<String> & p_arguments,bool p_blocking); + int execute(const String& p_path, const Vector<String> & p_arguments,bool p_blocking,Array p_output=Array()); + Error kill(int p_pid); Error shell_open(String p_uri); diff --git a/core/globals.cpp b/core/globals.cpp index 7df7680827..3a04becef4 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 b8dc3f9367..580fd0fecd 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<String>& p_ignore_masks=Set<String>()); Error save(); diff --git a/core/image.cpp b/core/image.cpp index e5489c06fa..d9ba6c1594 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -1399,10 +1399,344 @@ int Image::get_format_pallete_size(Format p_format) { } + + +Error Image::_decompress_bc() { + + print_line("decompressing bc"); + + int mm; + int size = _get_dst_image_size(width,height,FORMAT_RGBA,mm,mipmaps); + + DVector<uint8_t> newdata; + newdata.resize(size); + + DVector<uint8_t>::Write w = newdata.write(); + DVector<uint8_t>::Read r = data.read(); + + int rofs=0; + int wofs=0; + int wd=width,ht=height; + + for(int i=0;i<=mm;i++) { + + switch(format) { + + case FORMAT_BC1: { + + int len = (wd*ht)/16; + uint8_t* dst=&w[wofs]; + + uint32_t ofs_table[16]; + for(int x=0;x<4;x++) { + + for(int y=0;y<4;y++) { + + ofs_table[15-(y*4+(3-x))]=(x+y*wd)*4; + } + } + + + for(int j=0;j<len;j++) { + + const uint8_t* src=&r[rofs+j*8]; + uint16_t col_a=src[1]; + col_a<<=8; + col_a|=src[0]; + uint16_t col_b=src[3]; + col_b<<=8; + col_b|=src[2]; + + uint8_t table[4][4]={ + { (col_a>>11)<<3, ((col_a>>5)&0x3f)<<2, ((col_a)&0x1f)<<3, 255 }, + { (col_b>>11)<<3, ((col_b>>5)&0x3f)<<2, ((col_b)&0x1f)<<3, 255 }, + {0,0,0,255}, + {0,0,0,255} + }; + + if (col_a<col_b) { + //punchrough + table[2][0]=(int(table[0][0])+int(table[1][0]))>>1; + table[2][1]=(int(table[0][1])+int(table[1][1]))>>1; + table[2][2]=(int(table[0][2])+int(table[1][2]))>>1; + table[3][3]=0; //premul alpha black + } else { + //gradient + table[2][0]=(int(table[0][0])*2+int(table[1][0]))/3; + table[2][1]=(int(table[0][1])*2+int(table[1][1]))/3; + table[2][2]=(int(table[0][2])*2+int(table[1][2]))/3; + table[3][0]=(int(table[0][0])+int(table[1][0])*2)/3; + table[3][1]=(int(table[0][1])+int(table[1][1])*2)/3; + table[3][2]=(int(table[0][2])+int(table[1][2])*2)/3; + } + + uint32_t block=src[4]; + block<<=8; + block|=src[5]; + block<<=8; + block|=src[6]; + block<<=8; + block|=src[7]; + + int y = (j/(wd/4))*4; + int x = (j%(wd/4))*4; + int pixofs = (y*wd+x)*4; + + for(int k=0;k<16;k++) { + int idx = pixofs+ofs_table[k]; + dst[idx+0]=table[block&0x3][0]; + dst[idx+1]=table[block&0x3][1]; + dst[idx+2]=table[block&0x3][2]; + dst[idx+3]=table[block&0x3][3]; + block>>=2; + } + + } + + rofs+=len*8; + wofs+=wd*ht*4; + + + wd/=2; + ht/=2; + + } break; + case FORMAT_BC2: { + + int len = (wd*ht)/16; + uint8_t* dst=&w[wofs]; + + uint32_t ofs_table[16]; + for(int x=0;x<4;x++) { + + for(int y=0;y<4;y++) { + + ofs_table[15-(y*4+(3-x))]=(x+y*wd)*4; + } + } + + + for(int j=0;j<len;j++) { + + const uint8_t* src=&r[rofs+j*16]; + + uint64_t ablock=src[1]; + ablock<<=8; + ablock|=src[0]; + ablock<<=8; + ablock|=src[3]; + ablock<<=8; + ablock|=src[2]; + ablock<<=8; + ablock|=src[5]; + ablock<<=8; + ablock|=src[4]; + ablock<<=8; + ablock|=src[7]; + ablock<<=8; + ablock|=src[6]; + + + uint16_t col_a=src[8+1]; + col_a<<=8; + col_a|=src[8+0]; + uint16_t col_b=src[8+3]; + col_b<<=8; + col_b|=src[8+2]; + + uint8_t table[4][4]={ + { (col_a>>11)<<3, ((col_a>>5)&0x3f)<<2, ((col_a)&0x1f)<<3, 255 }, + { (col_b>>11)<<3, ((col_b>>5)&0x3f)<<2, ((col_b)&0x1f)<<3, 255 }, + {0,0,0,255}, + {0,0,0,255} + }; + + //always gradient + table[2][0]=(int(table[0][0])*2+int(table[1][0]))/3; + table[2][1]=(int(table[0][1])*2+int(table[1][1]))/3; + table[2][2]=(int(table[0][2])*2+int(table[1][2]))/3; + table[3][0]=(int(table[0][0])+int(table[1][0])*2)/3; + table[3][1]=(int(table[0][1])+int(table[1][1])*2)/3; + table[3][2]=(int(table[0][2])+int(table[1][2])*2)/3; + + uint32_t block=src[4+8]; + block<<=8; + block|=src[5+8]; + block<<=8; + block|=src[6+8]; + block<<=8; + block|=src[7+8]; + + int y = (j/(wd/4))*4; + int x = (j%(wd/4))*4; + int pixofs = (y*wd+x)*4; + + for(int k=0;k<16;k++) { + uint8_t alpha = ablock&0xf; + alpha=int(alpha)*255/15; //right way for alpha + int idx = pixofs+ofs_table[k]; + dst[idx+0]=table[block&0x3][0]; + dst[idx+1]=table[block&0x3][1]; + dst[idx+2]=table[block&0x3][2]; + dst[idx+3]=alpha; + block>>=2; + ablock>>=4; + } + + } + + rofs+=len*16; + wofs+=wd*ht*4; + + + wd/=2; + ht/=2; + + } break; + case FORMAT_BC3: { + + int len = (wd*ht)/16; + uint8_t* dst=&w[wofs]; + + uint32_t ofs_table[16]; + for(int x=0;x<4;x++) { + + for(int y=0;y<4;y++) { + + ofs_table[15-(y*4+(3-x))]=(x+y*wd)*4; + } + } + + + + for(int j=0;j<len;j++) { + + const uint8_t* src=&r[rofs+j*16]; + + uint8_t a_start=src[1]; + uint8_t a_end=src[0]; + + uint64_t ablock=src[3]; + ablock<<=8; + ablock|=src[2]; + ablock<<=8; + ablock|=src[5]; + ablock<<=8; + ablock|=src[4]; + ablock<<=8; + ablock|=src[7]; + ablock<<=8; + ablock|=src[6]; + + uint8_t atable[8]; + + if (a_start>a_end) { + + atable[0]=(int(a_start)*7+int(a_end)*0)/7; + atable[1]=(int(a_start)*6+int(a_end)*1)/7; + atable[2]=(int(a_start)*5+int(a_end)*2)/7; + atable[3]=(int(a_start)*4+int(a_end)*3)/7; + atable[4]=(int(a_start)*3+int(a_end)*4)/7; + atable[5]=(int(a_start)*2+int(a_end)*5)/7; + atable[6]=(int(a_start)*1+int(a_end)*6)/7; + atable[7]=(int(a_start)*0+int(a_end)*7)/7; + } else { + + atable[0]=(int(a_start)*5+int(a_end)*0)/5; + atable[1]=(int(a_start)*4+int(a_end)*1)/5; + atable[2]=(int(a_start)*3+int(a_end)*2)/5; + atable[3]=(int(a_start)*2+int(a_end)*3)/5; + atable[4]=(int(a_start)*1+int(a_end)*4)/5; + atable[5]=(int(a_start)*0+int(a_end)*5)/5; + atable[6]=0; + atable[7]=255; + + } + + + uint16_t col_a=src[8+1]; + col_a<<=8; + col_a|=src[8+0]; + uint16_t col_b=src[8+3]; + col_b<<=8; + col_b|=src[8+2]; + + uint8_t table[4][4]={ + { (col_a>>11)<<3, ((col_a>>5)&0x3f)<<2, ((col_a)&0x1f)<<3, 255 }, + { (col_b>>11)<<3, ((col_b>>5)&0x3f)<<2, ((col_b)&0x1f)<<3, 255 }, + {0,0,0,255}, + {0,0,0,255} + }; + + //always gradient + table[2][0]=(int(table[0][0])*2+int(table[1][0]))/3; + table[2][1]=(int(table[0][1])*2+int(table[1][1]))/3; + table[2][2]=(int(table[0][2])*2+int(table[1][2]))/3; + table[3][0]=(int(table[0][0])+int(table[1][0])*2)/3; + table[3][1]=(int(table[0][1])+int(table[1][1])*2)/3; + table[3][2]=(int(table[0][2])+int(table[1][2])*2)/3; + + + uint32_t block=src[4+8]; + block<<=8; + block|=src[5+8]; + block<<=8; + block|=src[6+8]; + block<<=8; + block|=src[7+8]; + + int y = (j/(wd/4))*4; + int x = (j%(wd/4))*4; + int pixofs = (y*wd+x)*4; + + + + for(int k=0;k<16;k++) { + uint8_t alpha = ablock&0x7; + int idx = pixofs+ofs_table[k]; + dst[idx+0]=table[block&0x3][0]; + dst[idx+1]=table[block&0x3][1]; + dst[idx+2]=table[block&0x3][2]; + dst[idx+3]=atable[alpha]; + block>>=2; + ablock>>=3; + } + + } + + rofs+=len*16; + wofs+=wd*ht*4; + + + wd/=2; + ht/=2; + + } break; + } + + } + + w=DVector<uint8_t>::Write(); + r=DVector<uint8_t>::Read(); + + data=newdata; + format=FORMAT_RGBA; + + return OK; +} + + +Image Image::decompressed() const { + + Image img=*this; + img.decompress(); + return img; +} + Error Image::decompress() { - if (format>=FORMAT_BC1 && format<=FORMAT_BC5 && _image_decompress_bc) - _image_decompress_bc(this); + if (format>=FORMAT_BC1 && format<=FORMAT_BC5 ) + _decompress_bc();//_image_decompress_bc(this); else if (format>=FORMAT_PVRTC2 && format<=FORMAT_PVRTC4_ALPHA && _image_decompress_pvrtc) _image_decompress_pvrtc(this); else if (format==FORMAT_ETC && _image_decompress_etc) diff --git a/core/image.h b/core/image.h index ce189f330d..7a6ee1e4b0 100644 --- a/core/image.h +++ b/core/image.h @@ -99,6 +99,8 @@ public: static void (*_image_decompress_bc)(Image *); static void (*_image_decompress_etc)(Image *); + Error _decompress_bc(); + static DVector<uint8_t> (*lossy_packer)(const Image& p_image,float p_quality); static Image (*lossy_unpacker)(const DVector<uint8_t>& p_buffer); static DVector<uint8_t> (*lossless_packer)(const Image& p_image); @@ -318,6 +320,7 @@ public: Error compress(CompressMode p_mode=COMPRESS_BC); Image compressed(int p_mode); /* from the Image::CompressMode enum */ Error decompress(); + Image decompressed() const; void fix_alpha_edges(); void premultiply_alpha(); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 33f4cafedd..e2371fe24f 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<RES>::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 bd33fee82c..cc26357bfb 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 dae95097d3..e6eede7de6 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 cfa4744915..40aaa01451 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 fd4575c872..e307668721 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 f07c37fb06..987bd772b0 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!="") { @@ -236,9 +245,21 @@ Ref<Resource> Resource::duplicate(bool p_subresources) { } +void Resource::_set_path(const String& p_path) { + + set_path(p_path,false); +} + +void Resource::_take_over_path(const String& p_path) { + + set_path(p_path,true); +} + + void Resource::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_path","path"),&Resource::set_path); + ObjectTypeDB::bind_method(_MD("set_path","path"),&Resource::_set_path); + ObjectTypeDB::bind_method(_MD("take_over_path","path"),&Resource::_take_over_path); ObjectTypeDB::bind_method(_MD("get_path"),&Resource::get_path); ObjectTypeDB::bind_method(_MD("set_name","name"),&Resource::set_name); ObjectTypeDB::bind_method(_MD("get_name"),&Resource::get_name); diff --git a/core/resource.h b/core/resource.h index 8d2c72d120..8a637e7996 100644 --- a/core/resource.h +++ b/core/resource.h @@ -115,6 +115,9 @@ protected: virtual void _resource_path_changed(); static void _bind_methods(); + + void _set_path(const String& p_path); + void _take_over_path(const String& p_path); public: virtual bool can_reload_from_file(); @@ -126,7 +129,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<Resource> duplicate(bool p_subresources=false); diff --git a/core/ucaps.h b/core/ucaps.h index 855a946c21..9c07828006 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/core/variant_call.cpp b/core/variant_call.cpp index c245e01ee0..8cdfce1b0a 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -539,6 +539,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_PTR3(Image,brush_transfer); VCALL_PTR1R(Image,get_rect); VCALL_PTR1R(Image,compressed); + VCALL_PTR0R(Image,decompressed); VCALL_PTR3R(Image, resized); VCALL_PTR0R(Image, get_data); VCALL_PTR3(Image, blit_rect); @@ -1266,6 +1267,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC0(IMAGE, RECT2, Image, get_used_rect, varray(0)); ADDFUNC1(IMAGE, IMAGE, Image, get_rect, RECT2, "area", varray(0)); ADDFUNC1(IMAGE, IMAGE, Image, compressed, INT, "format", varray(0)); + ADDFUNC0(IMAGE, IMAGE, Image, decompressed, varray(0)); ADDFUNC3(IMAGE, IMAGE, Image, resized, INT, "x", INT, "y", INT, "interpolation", varray(((int)Image::INTERPOLATE_BILINEAR))); ADDFUNC0(IMAGE, RAW_ARRAY, Image, get_data, varray()); ADDFUNC3(IMAGE, NIL, Image, blit_rect, IMAGE, "src", RECT2, "src_rect", VECTOR2, "dest", varray(0)); diff --git a/demos/3d/platformer/engine.cfg b/demos/3d/platformer/engine.cfg index f4b380f4db..793ac36364 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 25722cbc71..f3a5caffa9 100644 --- a/demos/3d/platformer/stage.xml +++ b/demos/3d/platformer/stage.xml @@ -1,11 +1,14 @@ <?xml version="1.0" encoding="UTF-8" ?> <resource_file type="PackedScene" subresource_count="7" version="1.0" version_name="Godot Engine v1.0.3917-beta1"> - <ext_resource path="res://enemy.scn" type="PackedScene"></ext_resource> - <ext_resource path="res://player.xml" type="PackedScene"></ext_resource> <ext_resource path="res://sb.cube" type="CubeMap"></ext_resource> <ext_resource path="res://tiles.res" type="MeshLibrary"></ext_resource> + <ext_resource path="res://enemy.scn" type="PackedScene"></ext_resource> <ext_resource path="res://coin.scn" type="PackedScene"></ext_resource> + <ext_resource path="res://player.xml" type="PackedScene"></ext_resource> <resource type="Environment" path="local://1"> + <bool name="ambient_light/enabled"> True </bool> + <color name="ambient_light/color"> 0, 0.409429, 0.596681, 1 </color> + <real name="ambient_light/energy"> 1 </real> <bool name="fxaa/enabled"> False </bool> <int name="background/mode"> 4 </int> <color name="background/color"> 0, 0, 0, 1 </color> @@ -43,16 +46,17 @@ <real name="bcs/brightness"> 1 </real> <real name="bcs/contrast"> 1 </real> <real name="bcs/saturation"> 1.608 </real> - <bool name="gamma/enabled"> False </bool> - <real name="gamma/gamma"> 1.414214 </real> + <bool name="srgb/enabled"> False </bool> </resource> <main_resource> <dictionary name="_bundled" shared="false"> <string> "names" </string> - <string_array len="89"> + <string_array len="92"> <string> "world" </string> <string> "Spatial" </string> + <string> "_import_path" </string> + <string> "_import_transform" </string> <string> "__meta__" </string> <string> "GridMap" </string> <string> "theme/theme" </string> @@ -71,13 +75,14 @@ <string> "params/enabled" </string> <string> "params/bake_mode" </string> <string> "params/energy" </string> - <string> "colors/ambient" </string> <string> "colors/diffuse" </string> <string> "colors/specular" </string> <string> "shadow/shadow" </string> <string> "shadow/darkening" </string> <string> "shadow/z_offset" </string> <string> "shadow/z_slope_scale" </string> + <string> "shadow/esm_multiplier" </string> + <string> "shadow/blur_passes" </string> <string> "projector" </string> <string> "operator" </string> <string> "shadow/mode" </string> @@ -148,7 +153,9 @@ <string> "node_count" </string> <int> 55 </int> <string> "variants" </string> - <array len="76" shared="false"> + <array len="79" shared="false"> + <node_path> "" </node_path> + <transform> 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 </transform> <dictionary shared="false"> <string> "__editor_plugin_states__" </string> <dictionary shared="false"> @@ -175,17 +182,17 @@ <array len="4" shared="false"> <dictionary shared="false"> <string> "distance" </string> - <real> 4.173348 </real> + <real> 0.261354 </real> <string> "x_rot" </string> - <real> 0.558294 </real> + <real> 0.458294 </real> <string> "y_rot" </string> - <real> 1.049999 </real> + <real> -1.2 </real> <string> "use_orthogonal" </string> <bool> False </bool> <string> "use_environment" </string> <bool> False </bool> <string> "pos" </string> - <vector3> 13.4293, 5.68289, 13.9717 </vector3> + <vector3> 13.4535, 5.75047, 13.8175 </vector3> </dictionary> <dictionary shared="false"> <string> "distance" </string> @@ -272,11 +279,12 @@ <int> 1 </int> <int> 0 </int> <real> 1.5 </real> - <color> 0.159092, 0.219774, 0.52093, 1 </color> <color> 1, 1, 1, 1 </color> <real> 0 </real> <real> 0.08 </real> <real> 0.5 </real> + <real> 60 </real> + <real> 1 </real> <resource name=""></resource> <int> 2 </int> <real> 40 </real> <real> 0.410558 </real> @@ -339,7 +347,7 @@ <transform> 0.0160676, 0, -0.999871, 0, 1, 0, 0.999871, 0, 0.0160676, 8.50167, 4.15811, 15.9334 </transform> </array> <string> "nodes" </string> - <int_array len="547"> -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 </int_array> + <int_array len="569"> -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 </int_array> <string> "conns" </string> <int_array len="0"> </int_array> </dictionary> diff --git a/demos/3d/platformer/texture.tex b/demos/3d/platformer/texture.tex Binary files differindex 439a007d26..24c4607ab1 100644 --- a/demos/3d/platformer/texture.tex +++ b/demos/3d/platformer/texture.tex diff --git a/demos/3d/platformer/tiles.res b/demos/3d/platformer/tiles.res Binary files differindex e7e810f23f..53534788a1 100644 --- a/demos/3d/platformer/tiles.res +++ b/demos/3d/platformer/tiles.res diff --git a/drivers/gles1/rasterizer_gles1.cpp b/drivers/gles1/rasterizer_gles1.cpp index 9a6c928711..ad0c8e3c7f 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<PropertyInfo> *p_param_list) const { @@ -1099,38 +1110,20 @@ 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]; - -} - -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; -}; + ERR_FAIL_COND_V(!material,VS::MATERIAL_DEPTH_DRAW_ALWAYS); + return material->depth_draw_mode; +} 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 10b2d7694d..e7937f43c3 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<StringName,Variant> 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<VS::MATERIAL_FLAG_MAX;i++) flags[i]=false; flags[VS::MATERIAL_FLAG_VISIBLE]=true; - for(int i=0;i<VS::MATERIAL_HINT_MAX;i++) - hints[i]=false; parameters[VS::FIXED_MATERIAL_PARAM_DIFFUSE] = Color(0.8, 0.8, 0.8); parameters[VS::FIXED_MATERIAL_PARAM_SPECULAR_EXP] = 12; @@ -188,7 +187,7 @@ class RasterizerGLES1 : public Rasterizer { for (int i=0; i<VisualServer::FIXED_MATERIAL_PARAM_MAX; i++) { texcoord_mode[i] = VS::FIXED_MATERIAL_TEXCOORD_UV; }; - detail_blend_mode = VS::MATERIAL_BLEND_MODE_MIX; + depth_draw_mode=VS::MATERIAL_DEPTH_DRAW_OPAQUE_ONLY; line_width=1; has_alpha=false; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; @@ -433,7 +432,7 @@ class RasterizerGLES1 : public Rasterizer { vars[VS::LIGHT_PARAM_ENERGY]=1.0; vars[VS::LIGHT_PARAM_RADIUS]=1.0; vars[VS::LIGHT_PARAM_SHADOW_Z_OFFSET]=0.05; - colors[VS::LIGHT_COLOR_AMBIENT]=Color(0,0,0); + colors[VS::LIGHT_COLOR_DIFFUSE]=Color(1,1,1); colors[VS::LIGHT_COLOR_SPECULAR]=Color(1,1,1); shadow_enabled=false; @@ -468,7 +467,7 @@ class RasterizerGLES1 : public Rasterizer { fx_param[VS::ENV_FX_PARAM_DOF_BLUR_BEGIN]=100.0; fx_param[VS::ENV_FX_PARAM_DOF_BLUR_RANGE]=10.0; fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE]=0.4; - fx_param[VS::ENV_FX_PARAM_HDR_SCALAR]=1.0; + fx_param[VS::ENV_FX_PARAM_HDR_WHITE]=1.0; fx_param[VS::ENV_FX_PARAM_HDR_GLOW_TRESHOLD]=0.95; fx_param[VS::ENV_FX_PARAM_HDR_GLOW_SCALE]=0.2; fx_param[VS::ENV_FX_PARAM_HDR_MIN_LUMINANCE]=0.4; @@ -862,9 +861,10 @@ public: virtual void shader_set_mode(RID p_shader,VS::ShaderMode p_mode); virtual VS::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_fragment_code(RID p_shader) const; virtual String shader_get_vertex_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<PropertyInfo> *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 307db4b762..dd690435ec 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -49,6 +49,12 @@ #define _GL_R16F_EXT 0x822D #define _GL_R32F_EXT 0x822E + +#define _GL_RED_EXT 0x1903 +#define _GL_RG_EXT 0x8227 +#define _GL_R8_EXT 0x8229 +#define _GL_RG8_EXT 0x822B + #define _DEPTH_COMPONENT24_OES 0x81A6 #ifdef GLEW_ENABLED @@ -1126,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); } @@ -1160,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()) @@ -1328,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) { @@ -3449,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); @@ -3928,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 } @@ -3944,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); @@ -3969,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<const char*> 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++; } @@ -4056,7 +4083,6 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD } - LightInstance *lights[RenderList::MAX_LIGHTS]; RenderList *render_list=NULL; @@ -4067,10 +4093,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) { @@ -4153,7 +4179,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(); @@ -4170,26 +4196,36 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD e->light_type=0x7F; //unshaded is zero } else { - //setup lights - uint16_t light_count=0; - uint16_t sort_key[4]; - uint8_t light_types[4]; + bool duplicate=false; - int dlc = MIN(directional_light_count,RenderList::MAX_LIGHTS);; - light_count=dlc; - for(int i=0;i<dlc;i++) { - sort_key[i]=directional_lights[i]->sort_key; - light_types[i]=VS::LIGHT_DIRECTIONAL; + for(int i=0;i<directional_light_count;i++) { + uint16_t sort_key = directional_lights[i]->sort_key; + uint8_t light_type = VS::LIGHT_DIRECTIONAL; if (directional_lights[i]->base->shadow_enabled) { - light_types[i]|=0x8; + light_type|=0x8; if (directional_lights[i]->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) - light_types[i]|=0x10; + light_type|=0x10; else if (directional_lights[i]->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) - light_types[i]|=0x30; + light_type|=0x30; + + } + + RenderList::Element *ec; + if (duplicate) { + ec = render_list->add_element(); + memcpy(ec,e,sizeof(RenderList::Element)); + } else { + + ec=e; + duplicate=true; } + ec->light_type=light_type; + ec->light=sort_key; + ec->additive_ptr=&e->additive; + } @@ -4200,37 +4236,34 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD for(int i=0;i<ilc;i++) { - if (light_count>=RenderList::MAX_LIGHTS) - break; - LightInstance *li=light_instance_owner.get( liptr[i] ); if (!li || li->last_pass!=scene_pass) //lit by light not in visible scene continue; - light_types[light_count]=li->base->type; - if (li->base->shadow_enabled) - light_types[light_count]|=0x8; - sort_key[light_count++]=li->sort_key; - - - } - - for(int i=0;i<light_count;i++) { + uint8_t light_type=li->base->type|0x40; //penalty to ensure directionals always go first + if (li->base->shadow_enabled) { + light_type|=0x8; + } + uint16_t sort_key =li->sort_key; RenderList::Element *ec; - if (i>0) { + if (duplicate) { ec = render_list->add_element(); memcpy(ec,e,sizeof(RenderList::Element)); } else { + duplicate=true; ec=e; } - ec->light_type=light_types[i]; - ec->light=sort_key[i]; + ec->light_type=light_type; + ec->light=sort_key; ec->additive_ptr=&e->additive; + } + + } DEBUG_TEST_ERROR("Add Geometry"); @@ -4405,7 +4438,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 { @@ -4417,7 +4450,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; @@ -4565,7 +4599,7 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material material_shader.set_uniform(MaterialShaderGLES2::FOG_COLOR_END,Vector3(col_end.r,col_end.g,col_end.b)); } - material_shader.set_uniform(MaterialShaderGLES2::CONST_LIGHT_MULT,p_no_const_light?0.0:1.0); + //material_shader.set_uniform(MaterialShaderGLES2::TIME,Math::fmod(last_time,300.0)); //if uses TIME - draw_next_frame=true @@ -4588,7 +4622,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 @@ -4599,7 +4632,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, }; @@ -4611,12 +4643,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]; } @@ -5524,6 +5554,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans bool stores_glow = !shadow && (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) && !p_alpha_pass; + bool prev_blend=false; glDisable(GL_BLEND); for (int i=0;i<p_render_list->element_count;i++) { @@ -5596,6 +5627,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans additive=true; } + if (stores_glow) material_shader.set_conditional(MaterialShaderGLES2::USE_GLOW,!additive); @@ -5637,7 +5669,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans case VS::MATERIAL_BLEND_MODE_ADD: { glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA,GL_ONE); + glBlendFunc(p_alpha_pass?GL_SRC_ALPHA:GL_ONE,GL_ONE); } break; case VS::MATERIAL_BLEND_MODE_SUB: { @@ -5728,7 +5760,8 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans if (i==0 || light!=prev_light || rebind) { if (e->light!=0xFFFF) { - _setup_light(e->light&0x3); + _setup_light(e->light); + } } @@ -5739,6 +5772,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LATTICE_DIVIDE, baked_light->octree_lattice_divide); material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_STEPS, baked_light->octree_steps); material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_TEX,5); + material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_MULTIPLIER,baked_light->texture_multiplier); material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_PIX_SIZE,baked_light->octree_tex_pixel_size); @@ -5754,6 +5788,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++; } @@ -5788,6 +5833,9 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans material_shader.set_uniform(MaterialShaderGLES2::WORLD_TRANSFORM, e->instance->transform); } + material_shader.set_uniform(MaterialShaderGLES2::NORMAL_MULT, e->mirror?-1.0:1.0); + material_shader.set_uniform(MaterialShaderGLES2::CONST_LIGHT_MULT,additive?0.0:1.0); + _render(e->geometry, material, skeleton,e->owner,e->instance->transform); DEBUG_TEST_ERROR("Rendering"); @@ -5901,6 +5949,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])); @@ -5980,7 +6030,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(); @@ -6048,6 +6098,9 @@ void RasterizerGLES2::_draw_tex_bg() { glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + glColorMask(1,1,1,1); + RID texture; @@ -6083,6 +6136,7 @@ void RasterizerGLES2::_draw_tex_bg() { copy_shader.set_conditional(CopyShaderGLES2::USE_CUSTOM_ALPHA,true); + copy_shader.bind(); if (current_env->bg_mode==VS::ENV_BG_TEXTURE || current_env->bg_mode==VS::ENV_BG_TEXTURE_RGBE) { @@ -6301,6 +6355,7 @@ void RasterizerGLES2::end_scene() { _render_list_forward(&opaque_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting); if (draw_tex_background) { + //most 3D vendors recommend drawing a texture bg or skybox here, //after opaque geometry has been drawn //so the zbuffer can get rid of most pixels @@ -6344,6 +6399,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]) { @@ -6393,6 +6470,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])); } @@ -6423,6 +6501,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); @@ -6437,6 +6518,7 @@ void RasterizerGLES2::end_scene() { if (GLOBAL_DEF("rasterizer/debug_shadow_maps",false)) { _debug_shadows(); } +// _debug_luminances(); } @@ -6806,7 +6888,7 @@ void RasterizerGLES2::_debug_draw_shadows_type(Vector<ShadowBuffer>& 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(); @@ -6814,10 +6896,17 @@ void RasterizerGLES2::_debug_luminances() { Size2 debug_size(128,128); Size2 ofs; - for (int i=0;i<framebuffer.luminance.size();i++) { - _debug_draw_shadow(framebuffer.luminance[i].color, Rect2( ofs, debug_size )); - ofs.x+=debug_size.x; + for (int i=0;i<=framebuffer.luminance.size();i++) { + + if (i==framebuffer.luminance.size()) { + if (!current_vd) + break; + _debug_draw_shadow(current_vd->lum_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; @@ -7873,6 +7962,7 @@ void RasterizerGLES2::_update_framebuffer() { glDeleteFramebuffers(1,&framebuffer.luminance[i].fbo); } + for(int i=0;i<3;i++) { glDeleteTextures(1,&framebuffer.blur[i].color); @@ -7924,12 +8014,20 @@ void RasterizerGLES2::_update_framebuffer() { #endif //color - GLuint format_rgba = use_fp16_fb?_GL_RGBA16F_EXT:GL_RGBA; +// GLuint format_rgba = use_fp16_fb?_GL_RGBA16F_EXT:GL_RGBA; + 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_R32F_EXT:GL_RGBA; - GLuint format_luminance_type = use_fp16_fb?GL_FLOAT:GL_UNSIGNED_BYTE; - GLuint format_luminance_components = use_fp16_fb?GL_RED: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_RG_EXT:GL_RGBA; + + + glGenTextures(1, &framebuffer.color); glBindTexture(GL_TEXTURE_2D, framebuffer.color); @@ -8071,8 +8169,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, @@ -8084,10 +8182,12 @@ void RasterizerGLES2::_update_framebuffer() { GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); glBindFramebuffer(GL_FRAMEBUFFER, 0); + + base_size/=3; + DEBUG_TEST_ERROR("Shadow Buffer Init"); ERR_CONTINUE( status != GL_FRAMEBUFFER_COMPLETE ); - base_size/=3; framebuffer.luminance.push_back(lb); } @@ -8238,6 +8338,7 @@ void RasterizerGLES2::init() { // use_attribute_instancing=true; use_texture_instancing=false; use_attribute_instancing=true; + full_float_fb_supported=true; #ifdef OSX_ENABLED use_rgba_shadowmaps=true; use_fp16_fb=false; @@ -8290,9 +8391,11 @@ void RasterizerGLES2::init() { } if (use_fp16_fb) { - use_fp16_fb=extensions.has("GL_OES_texture_half_float") && extensions.has("GL_EXT_color_buffer_half_float"); + use_fp16_fb=extensions.has("GL_OES_texture_half_float") && extensions.has("GL_EXT_color_buffer_half_float") && extensions.has("GL_EXT_texture_rg"); } + full_float_fb_supported=extensions.has("GL_EXT_color_buffer_float"); + //etc_supported=false; use_hw_skeleton_xform=false; diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index dce096b29e..83365f2feb 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -79,6 +79,7 @@ class RasterizerGLES2 : public Rasterizer { bool npo2_textures_available; bool read_depth_supported; bool use_framebuffers; + bool full_float_fb_supported; bool use_shadow_mapping; bool use_fp16_fb; ShadowFilterTechnique shadow_filter; @@ -90,6 +91,7 @@ class RasterizerGLES2 : public Rasterizer { bool use_texture_instancing; bool use_attribute_instancing; bool use_rgba_shadowmaps; + bool use_half_float; @@ -161,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; @@ -191,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; @@ -209,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; @@ -239,12 +243,10 @@ class RasterizerGLES2 : public Rasterizer { for(int i=0;i<VS::MATERIAL_FLAG_MAX;i++) flags[i]=false; flags[VS::MATERIAL_FLAG_VISIBLE]=true; - for(int i=0;i<VS::MATERIAL_HINT_MAX;i++) - hints[i]=false; - hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW_FOR_ALPHA]=true; line_width=1; has_alpha=false; + depth_draw_mode=VS::MATERIAL_DEPTH_DRAW_OPAQUE_ONLY; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; last_pass = 0; shader_version=0; @@ -588,7 +590,6 @@ class RasterizerGLES2 : public Rasterizer { vars[VS::LIGHT_PARAM_SHADOW_Z_SLOPE_SCALE]=1.4; vars[VS::LIGHT_PARAM_SHADOW_ESM_MULTIPLIER]=60.0; vars[VS::LIGHT_PARAM_SHADOW_BLUR_PASSES]=1; - colors[VS::LIGHT_COLOR_AMBIENT]=Color(0,0,0); colors[VS::LIGHT_COLOR_DIFFUSE]=Color(1,1,1); colors[VS::LIGHT_COLOR_SPECULAR]=Color(1,1,1); shadow_enabled=false; @@ -633,8 +634,9 @@ class RasterizerGLES2 : public Rasterizer { fx_param[VS::ENV_FX_PARAM_DOF_BLUR_PASSES]=1; fx_param[VS::ENV_FX_PARAM_DOF_BLUR_BEGIN]=100.0; fx_param[VS::ENV_FX_PARAM_DOF_BLUR_RANGE]=10.0; + fx_param[VS::ENV_FX_PARAM_HDR_TONEMAPPER]=VS::ENV_FX_HDR_TONE_MAPPER_LINEAR; fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE]=0.4; - fx_param[VS::ENV_FX_PARAM_HDR_SCALAR]=1.0; + fx_param[VS::ENV_FX_PARAM_HDR_WHITE]=1.0; fx_param[VS::ENV_FX_PARAM_HDR_GLOW_TRESHOLD]=0.95; fx_param[VS::ENV_FX_PARAM_HDR_GLOW_SCALE]=0.2; fx_param[VS::ENV_FX_PARAM_HDR_MIN_LUMINANCE]=0.4; @@ -779,9 +781,22 @@ class RasterizerGLES2 : public Rasterizer { bool *additive_ptr; bool additive; bool mirror; - uint16_t light; - uint8_t light_type; - uint8_t sort_flags; + union { +#ifdef BIG_ENDIAN_ENABLED + struct { + uint8_t sort_flags; + uint8_t light_type; + uint16_t light; + }; +#else + struct { + uint16_t light; + uint8_t light_type; + uint8_t sort_flags; + }; +#endif + uint32_t sort_key; + }; }; @@ -894,27 +909,22 @@ class RasterizerGLES2 : public Rasterizer { _FORCE_INLINE_ bool operator()(const Element* A, const Element* B ) const { - if (A->sort_flags == B->sort_flags) { - if (A->light_type == B->light_type) { - if (A->material->shader_cache == B->material->shader_cache) { - if (A->material == B->material) { - - return (A->geometry_cmp < B->geometry_cmp); - } else { + if (A->sort_key == B->sort_key) { + if (A->material->shader_cache == B->material->shader_cache) { + if (A->material == B->material) { - return (A->material < B->material); - } + return (A->geometry_cmp < B->geometry_cmp); } else { - return (A->material->shader_cache < B->material->shader_cache); + return (A->material < B->material); } } else { - return A->light_type < B->light_type; + return (A->material->shader_cache < B->material->shader_cache); } } else { - return A->sort_flags < B->sort_flags; //one is null and one is not + return A->sort_key < B->sort_key; //one is null and one is not } } }; @@ -1170,9 +1180,11 @@ public: virtual void shader_set_mode(RID p_shader,VS::ShaderMode p_mode); virtual VS::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_fragment_code(RID p_shader) const; virtual String shader_get_vertex_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<PropertyInfo> *p_param_list) const; @@ -1190,11 +1202,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 db63c3aeba..dfab3ea3d1 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -182,6 +182,13 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a } } + 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<StringName,SL::Uniform>::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 d683f5b4f3..d63915a2b6 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<StringName,ShaderLanguage::Uniform> *uniforms; @@ -73,7 +75,7 @@ private: String replace_string(const StringName& p_string); - Map<StringName,StringName> mode_replace_table[2]; + Map<StringName,StringName> mode_replace_table[3]; Map<StringName,StringName> 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<StringName,ShaderLanguage::Uniform> *r_uniforms=NULL); diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp index bcd3e6ad4b..dc68ee489a 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<strings.size();i++) { @@ -630,6 +639,7 @@ void ShaderGLES2::setup(const char** p_conditional_defines, int p_conditional_co { String globals_tag="\nFRAGMENT_SHADER_GLOBALS"; String code_tag="\nFRAGMENT_SHADER_CODE"; + String light_code_tag="\nLIGHT_SHADER_CODE"; String code = fragment_code; int cpos = code.find(globals_tag); if (cpos==-1) { @@ -645,7 +655,16 @@ void ShaderGLES2::setup(const char** p_conditional_defines, int p_conditional_co } else { fragment_code1=code.substr(0,cpos).ascii(); - fragment_code2=code.substr(cpos+code_tag.length(),code.length()).ascii(); + String code2 = code.substr(cpos+code_tag.length(),code.length()); + + cpos = code2.find(light_code_tag); + if (cpos==-1) { + fragment_code2=code2.ascii(); + } else { + + fragment_code2=code2.substr(0,cpos).ascii(); + fragment_code3 = code2.substr(cpos+light_code_tag.length(),code2.length()).ascii(); + } } } } @@ -696,7 +715,7 @@ uint32_t ShaderGLES2::create_custom_shader() { return last_custom_code++; } -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_fragment_globals,const Vector<StringName>& p_uniforms,const Vector<const char*> &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<StringName>& p_uniforms,const Vector<const char*> &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 17d893e349..9cd6142eb0 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<StringName> custom_uniforms; Vector<const char*> 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<StringName>& p_uniforms,const Vector<const char*> &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<StringName>& p_uniforms,const Vector<const char*> &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 6d78c69e50..d8fb03f3a3 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,25 +453,37 @@ 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 - highp float vd_lum=texture2D( source_vd_lum, vec2(0.0) ); + highp float vd_lum=texture2D( source_vd_lum, vec2(0.0) ).r; lum_accum = clamp( vd_lum + (lum_accum-vd_lum)*hdr_time_delta*hdr_exp_adj_speed,min_luminance,max_luminance); #endif @@ -451,12 +494,20 @@ void main() { 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 #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 3aed9820ed..17365ea264 100644 --- a/drivers/gles2/shaders/material.glsl +++ b/drivers/gles2/shaders/material.glsl @@ -31,6 +31,8 @@ attribute vec4 color_attrib; // attrib:3 attribute vec2 uv_attrib; // attrib:4 attribute vec2 uv2_attrib; // attrib:5 +uniform float normal_mult; + #ifdef USE_SKELETON attribute vec4 bone_indices; // attrib:6 attribute vec4 bone_weights; // attrib:7 @@ -115,7 +117,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 +133,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) @@ -232,8 +234,10 @@ void main() { #endif highp vec4 vertex_in = vertex_attrib; // vec4(vertex_attrib.xyz * data_attrib.x,1.0); vec3 normal_in = normal_attrib; + normal_in*=normal_mult; #if defined(ENABLE_TANGENT_INTERP) vec3 tangent_in = tangent_attrib.xyz; + tangent_in*=normal_mult; #endif #ifdef USE_SKELETON @@ -404,7 +408,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,27 +514,15 @@ 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; - -#ifdef USE_FRAGMENT_LIGHTING - +uniform vec3 ambient_light; -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) { +#ifdef USE_FRAGMENT_LIGHTING - 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 @@ -548,6 +540,7 @@ uniform highp float ambient_octree_lattice_size; uniform highp vec2 ambient_octree_pix_size; uniform highp float ambient_octree_lattice_divide; uniform highp sampler2D ambient_octree_tex; +uniform float ambient_octree_multiplier; uniform int ambient_octree_steps; #endif @@ -769,9 +762,12 @@ void main() { bool discard_=false; #endif +{ + FRAGMENT_SHADER_CODE +} #if defined(ENABLE_DISCARD) if (discard_) { @@ -824,7 +820,7 @@ FRAGMENT_SHADER_CODE vec3 col_up=texture2D(ambient_octree_tex,octant_uv).rgb; octant_uv.y+=ambient_octree_pix_size.y*2.0; vec3 col_down=texture2D(ambient_octree_tex,octant_uv).rgb; - ambientmap_color=mix(col_up,col_down,sub.z); + ambientmap_color=mix(col_up,col_down,sub.z)*ambient_octree_multiplier; ambientmap_color*=diffuse.rgb; @@ -1008,9 +1004,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 @@ -1022,7 +1017,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 @@ -1039,11 +1033,52 @@ 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 = const_light_mult * ambient_light *diffuse.rgb + light * attenuation * shadow_attenuation; + +#ifdef USE_FOG + + diffuse.rgb = mix(diffuse.rgb,fog_interp.rgb,fog_interp.a); + +# if defined(LIGHT_TYPE_OMNI) || defined (LIGHT_TYPE_SPOT) + diffuse.rgb = mix(mix(vec3(0.0),diffuse.rgb,attenuation),diffuse.rgb,const_light_mult); +# endif + #endif + } + + +# endif + # if !defined(LIGHT_TYPE_DIRECTIONAL) && !defined(LIGHT_TYPE_OMNI) && !defined (LIGHT_TYPE_SPOT) //none #ifndef SHADELESS @@ -1061,9 +1096,10 @@ FRAGMENT_SHADER_CODE #ifdef USE_VERTEX_LIGHTING - vec3 ambient = light_ambient*diffuse.rgb; + vec3 ambient = const_light_mult*ambient_light*diffuse.rgb; # if defined(LIGHT_TYPE_OMNI) || defined (LIGHT_TYPE_SPOT) ambient*=diffuse_interp.a; //attenuation affects ambient too + # endif // diffuse.rgb=(diffuse.rgb * diffuse_interp.rgb + specular * specular_interp)*shadow_attenuation + ambient; @@ -1071,6 +1107,16 @@ FRAGMENT_SHADER_CODE diffuse.rgb=(diffuse.rgb * diffuse_interp.rgb + specular * specular_interp)*shadow_attenuation + ambient; diffuse.rgb+=emission * const_light_mult; +#ifdef USE_FOG + + diffuse.rgb = mix(diffuse.rgb,fog_interp.rgb,fog_interp.a); + +# if defined(LIGHT_TYPE_OMNI) || defined (LIGHT_TYPE_SPOT) + diffuse.rgb = mix(mix(vec3(0.0),diffuse.rgb,diffuse_interp.a),diffuse.rgb,const_light_mult); +# endif + +#endif + #endif @@ -1097,10 +1143,7 @@ FRAGMENT_SHADER_CODE #else -#ifdef USE_FOG - diffuse.rgb = mix(diffuse.rgb,fog_interp.rgb,fog_interp.a); -#endif #ifdef USE_GLOW diff --git a/main/main.cpp b/main/main.cpp index 0d9e94346e..f5b5953ff4 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 5f5de8b5db..a98b07ab92 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 2829132d99..40c262c503 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<Resource> res = ResourceLoader::load(path); - if (!res.is_valid()) { - _set_error("Can't preload resource at path: "+path); - return NULL; + Ref<Resource> 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<uint8_t> &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 825bd954d1..ae43a26f5a 100644 --- a/modules/gdscript/gd_parser.h +++ b/modules/gdscript/gd_parser.h @@ -356,6 +356,7 @@ private: template<class T> 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<uint8_t> &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 d1ee7087e7..f47ff4ed50 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<PropertyInfo> *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<String> cl = cmdline.strip_edges().split(" "); + for(int i=0;i<cl.size();i++) { + if (cl[i].strip_edges().length()==0) { + cl.remove(i); + i--; + } + } if (p_dumb) { @@ -1123,12 +1136,12 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d } err = save_pack(pf); memdelete(pf); - cl.push_back("-main_pack"); - cl.push_back(apkfname); - cl.push_back("-main_pack_md5"); + + cl.push_back("-use_apk_expansion"); + cl.push_back("-apk_expansion_md5"); cl.push_back(FileAccess::get_md5(fullpath)); - cl.push_back("-main_pack_cfg"); - cl.push_back(apk_expansion_salt+","+apk_expansion_pkey); + cl.push_back("-apk_expansion_key"); + cl.push_back(apk_expansion_pkey.strip_edges()); } else { @@ -1562,10 +1575,10 @@ bool EditorExportPlatformAndroid::can_export(String *r_error) const { if (apk_expansion) { - if (apk_expansion_salt=="") { - valid=false; - err+="Invalid SALT for apk expansion.\n"; - } + //if (apk_expansion_salt=="") { + // valid=false; + // err+="Invalid SALT for apk expansion.\n"; + //} if (apk_expansion_pkey=="") { valid=false; err+="Invalid public key for apk expansion.\n"; diff --git a/platform/android/globals/global_defaults.cpp b/platform/android/globals/global_defaults.cpp index 9bde79e63c..84a586d22d 100644 --- a/platform/android/globals/global_defaults.cpp +++ b/platform/android/globals/global_defaults.cpp @@ -6,6 +6,7 @@ void register_android_global_defaults() { GLOBAL_DEF("rasterizer.Android/use_fragment_lighting",false); + GLOBAL_DEF("rasterizer.Android/fp16_framebuffer",false); GLOBAL_DEF("display.Android/driver","GLES2"); // GLOBAL_DEF("rasterizer.Android/trilinear_mipmap_filter",false); diff --git a/platform/android/java/src/com/android/godot/Godot.java b/platform/android/java/src/com/android/godot/Godot.java index 9cadeb4231..11fb894545 100644 --- a/platform/android/java/src/com/android/godot/Godot.java +++ b/platform/android/java/src/com/android/godot/Godot.java @@ -63,6 +63,10 @@ import com.android.godot.input.*; import java.io.InputStream; import javax.microedition.khronos.opengles.GL10; +import java.security.MessageDigest; +import java.io.File; +import java.io.FileInputStream; +import java.util.LinkedList; public class Godot extends Activity implements SensorEventListener { @@ -138,7 +142,11 @@ public class Godot extends Activity implements SensorEventListener */ + private String[] command_line; + public GodotView mView; + private boolean godot_initialized=false; + private SensorManager mSensorManager; private Sensor mAccelerometer; @@ -190,9 +198,9 @@ public class Godot extends Activity implements SensorEventListener // GodotEditText layout GodotEditText edittext = new GodotEditText(this); - edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT)); + edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT)); // ...add to FrameLayout - layout.addView(edittext); + layout.addView(edittext); mView = new GodotView(getApplication(),io,use_gl2, this); layout.addView(mView,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); @@ -216,71 +224,206 @@ public class Godot extends Activity implements SensorEventListener private String[] getCommandLine() { - - InputStream is; - try { - is = getAssets().open("/_cl_"); - byte[] len = new byte[4]; - int r = is.read(len); - if (r<4) { - System.out.printf("**ERROR** Wrong cmdline length.\n"); - return new String[0]; - } - 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;i<argc;i++) { - r = is.read(len); - if (r<4) { - System.out.printf("**ERROR** Wrong cmdline param lenght.\n"); - return new String[0]; - } - int strlen=((int)(len[3])<<24) | ((int)(len[2])<<16) | ((int)(len[1])<<8) | ((int)(len[0])); - if (strlen>65535) { - 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"); - } - + InputStream is; + try { + is = getAssets().open("_cl_"); + byte[] len = new byte[4]; + int r = is.read(len); + if (r<4) { + System.out.printf("**ERROR** Wrong cmdline length.\n"); + Log.d("GODOT", "**ERROR** Wrong cmdline length.\n"); + return new String[0]; + } + int argc=((int)(len[3]&0xFF)<<24) | ((int)(len[2]&0xFF)<<16) | ((int)(len[1]&0xFF)<<8) | ((int)(len[0]&0xFF)); + String[] cmdline = new String[argc]; + + for(int i=0;i<argc;i++) { + r = is.read(len); + if (r<4) { + + Log.d("GODOT", "**ERROR** Wrong cmdline param lenght.\n"); + return new String[0]; + } + int strlen=((int)(len[3]&0xFF)<<24) | ((int)(len[2]&0xFF)<<16) | ((int)(len[1]&0xFF)<<8) | ((int)(len[0]&0xFF)); + if (strlen>65535) { + 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"); + } } - 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]; } } - @Override protected void onCreate(Bundle icicle) { - System.out.printf("** GODOT ACTIVITY CREATED HERE ***\n"); + String expansion_pack_path; - super.onCreate(icicle); - _self = this; - Window window = getWindow(); - window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON - | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + 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<command_line.length;i++) { + new_cmdline[i]=command_line[i]; + } + } else { + new_cmdline = new String[ 2 ]; + } + + new_cmdline[cll]="-main_pack"; + new_cmdline[cll+1]=expansion_pack_path; + command_line=new_cmdline; + } io = new GodotIO(this); io.unique_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID); GodotLib.io=io; - GodotLib.initialize(this,io.needsReloadHooks(),getCommandLine()); + GodotLib.initialize(this,io.needsReloadHooks(),command_line); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); result_callback = null; - + mPaymentsManager = PaymentsManager.createManager(this).initService(); + godot_initialized=true; + + } + + + @Override protected void onCreate(Bundle icicle) { + + System.out.printf("** GODOT ACTIVITY CREATED HERE ***\n"); + + super.onCreate(icicle); + _self = this; + Window window = getWindow(); + window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON + | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + //check for apk expansion API + if (true) { + command_line = getCommandLine(); + boolean use_apk_expansion=false; + String main_pack_md5=null; + String main_pack_key=null; + + List<String> new_args = new LinkedList<String>(); + + + for(int i=0;i<command_line.length;i++) { + + boolean has_extra = i< command_line.length -1; + if (command_line[i].equals("-use_apk_expansion")) { + use_apk_expansion=true; + } else if (has_extra && command_line[i].equals("-apk_expansion_md5")) { + main_pack_md5=command_line[i+1]; + i++; + } else if (has_extra && command_line[i].equals("-apk_expansion_key")) { + main_pack_key=command_line[i+1]; + i++; + } else if (command_line[i].trim().length()!=0){ + new_args.add(command_line[i]); + } + } + + if (new_args.isEmpty()) + command_line=null; + else + command_line = new_args.toArray(new String[new_args.size()]); + + if (use_apk_expansion && main_pack_md5!=null && main_pack_key!=null) { + //check that environment is ok! + if (!Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED )) { + Log.d("GODOT", "**ERROR! No media mounted!"); + //show popup and die + } + + // Build the full path to the app's expansion files + try { + expansion_pack_path = Environment.getExternalStorageDirectory().toString() + "/Android/obb/"+this.getPackageName(); + expansion_pack_path+="/"+"main."+getPackageManager().getPackageInfo(getPackageName(), 0).versionCode+"."+this.getPackageName()+".obb"; + } catch (Exception e) { + e.printStackTrace(); + } + + File f = new File(expansion_pack_path); + + boolean pack_valid = true; + Log.d("GODOT","**PACK** - Path "+expansion_pack_path); + + if (!f.exists()) { + + pack_valid=false; + Log.d("GODOT","**PACK** - File does not exist"); + + } else { + try { + + InputStream fis = new FileInputStream(expansion_pack_path); + + // Create MD5 Hash + byte[] buffer = new byte[16384]; + + MessageDigest complete = MessageDigest.getInstance("MD5"); + int numRead; + do { + numRead = fis.read(buffer); + if (numRead > 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<messageDigest.length; i++) + hexString.append(Integer.toHexString(0xFF & messageDigest[i])); + String md5str = hexString.toString(); + + Log.d("GODOT","**PACK** - My MD5: "+hexString+" - APK md5: "+main_pack_md5); + if (!hexString.equals(main_pack_md5)) { + pack_valid=false; + } + } catch (Exception e) { + e.printStackTrace(); + Log.d("GODOT","**PACK FAIL**"); + pack_valid=false; + } + + + } + + if (!pack_valid) { + + + + } + + } + } + + initializeGodot(); // instanceSingleton( new GodotFacebook(this) ); @@ -299,6 +442,8 @@ public class Godot extends Activity implements SensorEventListener @Override protected void onPause() { super.onPause(); + if (!godot_initialized) + return; mView.onPause(); mSensorManager.unregisterListener(this); GodotLib.focusout(); @@ -310,6 +455,9 @@ public class Godot extends Activity implements SensorEventListener @Override protected void onResume() { super.onResume(); + if (!godot_initialized) + return; + mView.onResume(); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); GodotLib.focusin(); @@ -350,6 +498,7 @@ public class Godot extends Activity implements SensorEventListener @Override public void onBackPressed() { + System.out.printf("** BACK REQUEST!\n"); GodotLib.quit(); } diff --git a/platform/android/java/src/com/android/godot/GodotDownloaderAlarmReceiver.java b/platform/android/java/src/com/android/godot/GodotDownloaderAlarmReceiver.java new file mode 100644 index 0000000000..d945a8b192 --- /dev/null +++ b/platform/android/java/src/com/android/godot/GodotDownloaderAlarmReceiver.java @@ -0,0 +1,27 @@ +package com.android.godot; + +import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager.NameNotFoundException; + +/** + * You should start your derived downloader class when this receiver gets the message + * from the alarm service using the provided service helper function within the + * DownloaderClientMarshaller. This class must be then registered in your AndroidManifest.xml + * file with a section like this: + * <receiver android:name=".GodotDownloaderAlarmReceiver"/> + */ +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 0000000000..e0fe95ad96 --- /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/src/com/android/godot/GodotLib.java b/platform/android/java/src/com/android/godot/GodotLib.java index ad803f8e8d..6e2462b4f1 100644 --- a/platform/android/java/src/com/android/godot/GodotLib.java +++ b/platform/android/java/src/com/android/godot/GodotLib.java @@ -52,6 +52,8 @@ public class GodotLib { public static native void touch(int what,int pointer,int howmany, int[] arr); public static native void accelerometer(float x, float y, float z); public static native void key(int p_scancode, int p_unicode_char, boolean p_pressed); + public static native void joybutton(int p_device, int p_but, boolean p_pressed); + public static native void joyaxis(int p_device, int p_axis, float p_value); public static native void focusin(); public static native void focusout(); public static native void audio(); diff --git a/platform/android/java/src/com/android/godot/GodotView.java b/platform/android/java/src/com/android/godot/GodotView.java index f02cc00c28..f62431b94b 100644 --- a/platform/android/java/src/com/android/godot/GodotView.java +++ b/platform/android/java/src/com/android/godot/GodotView.java @@ -35,6 +35,7 @@ import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.content.ContextWrapper; +import android.view.InputDevice; import java.io.File; import javax.microedition.khronos.egl.EGL10; @@ -99,22 +100,251 @@ public class GodotView extends GLSurfaceView { return activity.gotTouchEvent(event); }; + public int get_godot_button(int keyCode) { + + int button = 0; + switch (keyCode) { + case KeyEvent.KEYCODE_BUTTON_A: // Android A is SNES B + button = 0; + break; + case KeyEvent.KEYCODE_BUTTON_B: + button = 1; + break; + case KeyEvent.KEYCODE_BUTTON_X: // Android X is SNES Y + button = 2; + break; + case KeyEvent.KEYCODE_BUTTON_Y: + button = 3; + break; + case KeyEvent.KEYCODE_BUTTON_L1: + button = 4; + break; + case KeyEvent.KEYCODE_BUTTON_L2: + button = 6; + break; + case KeyEvent.KEYCODE_BUTTON_R1: + button = 5; + break; + case KeyEvent.KEYCODE_BUTTON_R2: + button = 7; + break; + case KeyEvent.KEYCODE_BUTTON_SELECT: + button = 10; + break; + case KeyEvent.KEYCODE_BUTTON_START: + button = 11; + break; + case KeyEvent.KEYCODE_BUTTON_THUMBL: + button = 8; + break; + case KeyEvent.KEYCODE_BUTTON_THUMBR: + button = 9; + break; + case KeyEvent.KEYCODE_DPAD_UP: + button = 12; + break; + case KeyEvent.KEYCODE_DPAD_DOWN: + button = 13; + break; + case KeyEvent.KEYCODE_DPAD_LEFT: + button = 14; + break; + case KeyEvent.KEYCODE_DPAD_RIGHT: + button = 15; + break; + + default: + button = keyCode - KeyEvent.KEYCODE_BUTTON_1; + break; + }; + + return button; + }; + @Override public boolean onKeyUp(int keyCode, KeyEvent event) { - GodotLib.key(keyCode, event.getUnicodeChar(0), false); + + if (keyCode == KeyEvent.KEYCODE_BACK) { + return true; + } + + if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { + return super.onKeyUp(keyCode, event); + }; + + int source = event.getSource(); + if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) { + + int button = get_godot_button(keyCode); + int device = event.getDeviceId(); + + GodotLib.joybutton(device, button, false); + return true; + } else { + + GodotLib.key(keyCode, event.getUnicodeChar(0), false); + }; return super.onKeyUp(keyCode, event); }; @Override public boolean onKeyDown(int keyCode, KeyEvent event) { - GodotLib.key(keyCode, event.getUnicodeChar(0), true); + if (keyCode == KeyEvent.KEYCODE_BACK) { + GodotLib.quit(); // press 'back' button should not terminate program // normal handle 'back' event in game logic return true; } + + if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { + return super.onKeyDown(keyCode, event); + }; + + int source = event.getSource(); + //Log.e(TAG, String.format("Key down! source %d, device %d, joystick %d, %d, %d", event.getDeviceId(), source, (source & InputDevice.SOURCE_JOYSTICK), (source & InputDevice.SOURCE_DPAD), (source & InputDevice.SOURCE_GAMEPAD))); + + if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) { + + if (event.getRepeatCount() > 0) // ignore key echo + return true; + int button = get_godot_button(keyCode); + int device = event.getDeviceId(); + //Log.e(TAG, String.format("joy button down! button %x, %d, device %d", keyCode, button, device)); + + GodotLib.joybutton(device, button, true); + return true; + + } else { + GodotLib.key(keyCode, event.getUnicodeChar(0), true); + }; return super.onKeyDown(keyCode, event); } - private void init(boolean translucent, int depth, int stencil) { + public float axis_value(MotionEvent p_event, InputDevice p_device, int p_axis, int p_pos) { + + final InputDevice.MotionRange range = p_device.getMotionRange(p_axis, p_event.getSource()); + if (range == null) + return 0; + + //Log.e(TAG, String.format("axis ranges %f, %f, %f", range.getRange(), range.getMin(), range.getMax())); + + final float flat = range.getFlat(); + final float value = + p_pos < 0 ? p_event.getAxisValue(p_axis): + p_event.getHistoricalAxisValue(p_axis, p_pos); + + final float absval = Math.abs(value); + if (absval <= flat) { + return 0; + }; + + final float ret = (value - range.getMin()) / range.getRange() * 2 - 1.0f; + + return ret; + }; + + float[] last_axis_values = { 0, 0, 0, 0, -1, -1 }; + boolean[] last_axis_buttons = { false, false, false, false, false, false }; // dpad up down left right, ltrigger, rtrigger + + public void process_axis_state(MotionEvent p_event, int p_pos) { + + int device_id = p_event.getDeviceId(); + InputDevice device = p_event.getDevice(); + float val; + + val = axis_value(p_event, device, MotionEvent.AXIS_X, p_pos); + if (val != last_axis_values[0]) { + last_axis_values[0] = val; + //Log.e(TAG, String.format("axis moved! axis %d, value %f", 0, val)); + GodotLib.joyaxis(device_id, 0, val); + }; + + val = axis_value(p_event, device, MotionEvent.AXIS_Y, p_pos); + if (val != last_axis_values[1]) { + last_axis_values[1] = val; + //Log.e(TAG, String.format("axis moved! axis %d, value %f", 1, val)); + GodotLib.joyaxis(device_id, 1, val); + }; + + val = axis_value(p_event, device, MotionEvent.AXIS_Z, p_pos); + if (val != last_axis_values[2]) { + last_axis_values[2] = val; + //Log.e(TAG, String.format("axis moved! axis %d, value %f", 2, val)); + GodotLib.joyaxis(device_id, 2, val); + }; + + val = axis_value(p_event, device, MotionEvent.AXIS_RZ, p_pos); + if (val != last_axis_values[3]) { + last_axis_values[3] = val; + //Log.e(TAG, String.format("axis moved! axis %d, value %f", 3, val)); + GodotLib.joyaxis(device_id, 3, val); + }; + + val = axis_value(p_event, device, MotionEvent.AXIS_LTRIGGER, p_pos); + if (val != last_axis_values[4]) { + last_axis_values[4] = val; + if ((val != 0) != (last_axis_buttons[4])) { + last_axis_buttons[4] = (val != 0); + GodotLib.joybutton(device_id, 6, (val != 0)); + }; + }; + + val = axis_value(p_event, device, MotionEvent.AXIS_RTRIGGER, p_pos); + if (val != last_axis_values[5]) { + last_axis_values[5] = val; + if ((val != 0) != (last_axis_buttons[5])) { + last_axis_buttons[5] = (val != 0); + GodotLib.joybutton(device_id, 7, (val != 0)); + }; + }; + + val = axis_value(p_event, device, MotionEvent.AXIS_HAT_Y, p_pos); + + if (last_axis_buttons[0] != (val > 0)) { + last_axis_buttons[0] = val > 0; + GodotLib.joybutton(device_id, 12, val > 0); + }; + if (last_axis_buttons[1] != (val < 0)) { + last_axis_buttons[1] = val < 0; + GodotLib.joybutton(device_id, 13, val > 0); + }; + + val = axis_value(p_event, device, MotionEvent.AXIS_HAT_X, p_pos); + if (last_axis_buttons[2] != (val < 0)) { + last_axis_buttons[2] = val < 0; + GodotLib.joybutton(device_id, 14, val < 0); + }; + if (last_axis_buttons[3] != (val > 0)) { + last_axis_buttons[3] = val > 0; + GodotLib.joybutton(device_id, 15, val > 0); + }; + }; + + @Override public boolean onGenericMotionEvent(MotionEvent event) { + + if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) { + + // Process all historical movement samples in the batch + final int historySize = event.getHistorySize(); + + // Process the movements starting from the + // earliest historical position in the batch + for (int i = 0; i < historySize; i++) { + // Process the event at historical position i + process_axis_state(event, i); + } + + // Process the current movement sample in the batch (position -1) + process_axis_state(event, -1); + return true; + + + }; + + return super.onGenericMotionEvent(event); + }; + + + private void init(boolean translucent, int depth, int stencil) { this.setFocusableInTouchMode(true); /* By default, GLSurfaceView() creates a RGB_565 opaque surface. diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index b11994eef0..5c39cdbacc 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -581,6 +581,8 @@ static Vector3 accelerometer; static HashMap<String,JNISingleton*> jni_singletons; static jobject godot_io; +static Vector<int> joy_device_ids; + typedef void (*GFXInitFunc)(void *ud,bool gl2); static jmethodID _on_video_init=0; @@ -747,8 +749,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; + + for (int i=0; i<cmdlen; i++) { + + jstring string = (jstring) env->GetObjectArrayElement(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); + 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 +787,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; i<cmdlen; i++) { - - jstring string = (jstring) env->GetObjectArrayElement(p_cmdline, i); - const char *rawString = env->GetStringUTFChars(string, 0); - cmdline[i]=rawString; - } #if 0 char *args[]={"-test","render",NULL}; @@ -833,6 +851,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(); } @@ -1262,6 +1281,49 @@ static unsigned int android_get_keysym(unsigned int p_code) { return KEY_UNKNOWN; } +static int find_device(int p_device) { + + for (int i=0; i<joy_device_ids.size(); i++) { + + if (joy_device_ids[i] == p_device) { + //print_line("found device at "+String::num(i)); + return i; + }; + }; + + //print_line("adding a device at" + String::num(joy_device_ids.size())); + joy_device_ids.push_back(p_device); + + return joy_device_ids.size() - 1; +}; + +JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_joybutton(JNIEnv * env, jobject obj, jint p_device, jint p_button, jboolean p_pressed) { + + InputEvent ievent; + ievent.type = InputEvent::JOYSTICK_BUTTON; + ievent.device = find_device(p_device); + ievent.joy_button.button_index = p_button; + ievent.joy_button.pressed = p_pressed; + + input_mutex->lock(); + key_events.push_back(ievent); + input_mutex->unlock(); +}; + +JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_joyaxis(JNIEnv * env, jobject obj, jint p_device, jint p_axis, jfloat p_value) { + + InputEvent ievent; + ievent.type = InputEvent::JOYSTICK_MOTION; + ievent.device = find_device(p_device); + ievent.joy_motion.axis = p_axis; + ievent.joy_motion.axis_value = p_value; + + input_mutex->lock(); + key_events.push_back(ievent); + input_mutex->unlock(); +}; + + JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_key(JNIEnv * env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed) { InputEvent ievent; @@ -1289,7 +1351,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 +1455,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/java_glue.h b/platform/android/java_glue.h index 6dc89418b5..379718a23e 100644 --- a/platform/android/java_glue.h +++ b/platform/android/java_glue.h @@ -43,6 +43,8 @@ extern "C" { JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_quit(JNIEnv * env, jobject obj); JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_touch(JNIEnv * env, jobject obj, jint ev,jint pointer, jint count, jintArray positions); JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_key(JNIEnv * env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed); + JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_joybutton(JNIEnv * env, jobject obj, jint p_device, jint p_button, jboolean p_pressed); + JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_joyaxis(JNIEnv * env, jobject obj, jint p_device, jint p_axis, jfloat p_value); JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_audio(JNIEnv * env, jobject obj); JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_accelerometer(JNIEnv * env, jobject obj, jfloat x, jfloat y, jfloat z); JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_focusin(JNIEnv * env, jobject obj); diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 5bc433e85f..5fad4386fa 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<FileAccessBufferedFA<FileAccessJAndroid> >(FileAccess::ACCESS_RESOURCES); + if (use_apk_expansion) + FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES); + else + FileAccess::make_default<FileAccessBufferedFA<FileAccessJAndroid> >(FileAccess::ACCESS_RESOURCES); FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA); FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_FILESYSTEM); //FileAccessBufferedFA<FileAccessUnix>::make_default(); - DirAccess::make_default<DirAccessJAndroid>(DirAccess::ACCESS_RESOURCES); + if (use_apk_expansion) + DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_RESOURCES); + else + DirAccess::make_default<DirAccessJAndroid>(DirAccess::ACCESS_RESOURCES); DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_USERDATA); DirAccess::make_default<DirAccessUnix>(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 e6d0f7eded..bc52a43002 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/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm index c5ac5d9263..9ba95ff0c5 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/iphone/app_delegate.mm @@ -37,6 +37,12 @@ #include "modules/FacebookScorer_ios/FacebookScorer.h" #endif +#ifdef MODULE_GAME_ANALYTICS_ENABLED +#import "modules/game_analytics/ios/MobileAppTracker.framework/Headers/MobileAppTracker.h" +//#import "modules/game_analytics/ios/MobileAppTracker.h" +#import <AdSupport/AdSupport.h> +#endif + #define kFilteringFactor 0.1 #define kRenderingFrequency 60 #define kAccelerometerFrequency 100.0 // Hz @@ -210,7 +216,36 @@ static int frame_count = 0; //OSIPhone::screen_width = rect.size.width - rect.origin.x; //OSIPhone::screen_height = rect.size.height - rect.origin.y; - mainViewController = view_controller; + mainViewController = view_controller; + +#ifdef MODULE_GAME_ANALYTICS_ENABLED + printf("********************* didFinishLaunchingWithOptions\n"); + if(!Globals::get_singleton()->has("mobileapptracker/advertiser_id")) + { + return; + } + if(!Globals::get_singleton()->has("mobileapptracker/conversion_key")) + { + return; + } + + String adid = GLOBAL_DEF("mobileapptracker/advertiser_id",""); + String convkey = GLOBAL_DEF("mobileapptracker/conversion_key",""); + + NSString * advertiser_id = [NSString stringWithUTF8String:adid.utf8().get_data()]; + NSString * conversion_key = [NSString stringWithUTF8String:convkey.utf8().get_data()]; + + // Account Configuration info - must be set + [MobileAppTracker initializeWithMATAdvertiserId:advertiser_id + MATConversionKey:conversion_key]; + + // Used to pass us the IFA, enables highly accurate 1-to-1 attribution. + // Required for many advertising networks. + [MobileAppTracker setAppleAdvertisingIdentifier:[[ASIdentifierManager sharedManager] advertisingIdentifier] + advertisingTrackingEnabled:[[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]]; + +#endif + }; - (void)applicationWillTerminate:(UIApplication*)application { @@ -240,6 +275,10 @@ static int frame_count = 0; - (void) applicationDidBecomeActive:(UIApplication *)application { printf("********************* did become active\n"); +#ifdef MODULE_GAME_ANALYTICS_ENABLED + printf("********************* mobile app tracker found\n"); + [MobileAppTracker measureSession]; +#endif [view_controller.view startAnimation]; // FIXME: resume seems to be recommended elsewhere } diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index b9e381d6ec..5b203f1560 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -98,7 +98,7 @@ public: id context; CursorShape cursor_shape; - + MouseMode mouse_mode; protected: virtual int get_video_driver_count() const; @@ -159,6 +159,8 @@ public: void run(); + void set_mouse_mode(MouseMode p_mode); + MouseMode get_mouse_mode() const; OS_OSX(); }; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index dda3527618..12f98cebe2 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -384,15 +384,10 @@ static int button_mask=0; ev.mouse_motion.y=mouse_y; ev.mouse_motion.global_x=mouse_x; ev.mouse_motion.global_y=mouse_y; - ev.mouse_motion.relative_x=mouse_x - prev_mouse_x; - ev.mouse_motion.relative_y=mouse_y - prev_mouse_y; + ev.mouse_motion.relative_x=[event deltaX] * [[event window] backingScaleFactor]; + ev.mouse_motion.relative_y=[event deltaY] * [[event window] backingScaleFactor]; ev.mouse_motion.mod = translateFlags([event modifierFlags]); - -// ev.mouse_motion.relative_x=[event deltaX]; -// ev.mouse_motion.relative_y=[event deltaY]; - - OS_OSX::singleton->input->set_mouse_pos(Point2(mouse_x,mouse_y)); OS_OSX::singleton->push_input(ev); @@ -1280,6 +1275,32 @@ void OS_OSX::run() { main_loop->finish(); } +void OS_OSX::set_mouse_mode(MouseMode p_mode) { + + if (p_mode==mouse_mode) + return; + + if (p_mode==MOUSE_MODE_CAPTURED) { + // Apple Docs state that the display parameter is not used. + // "This parameter is not used. By default, you may pass kCGDirectMainDisplay." + // https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/Quartz_Services_Ref/Reference/reference.html + CGDisplayHideCursor(kCGDirectMainDisplay); + CGAssociateMouseAndMouseCursorPosition(false); + } else if (p_mode==MOUSE_MODE_HIDDEN) { + CGDisplayHideCursor(kCGDirectMainDisplay); + CGAssociateMouseAndMouseCursorPosition(true); + } else { + CGDisplayShowCursor(kCGDirectMainDisplay); + CGAssociateMouseAndMouseCursorPosition(true); + } + + mouse_mode=p_mode; +} + +OS::MouseMode OS_OSX::get_mouse_mode() const { + + return mouse_mode; +} OS_OSX* OS_OSX::singleton=NULL; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 6fe8b8c4c2..c4879cf065 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -316,6 +316,9 @@ Map<TileMap::PosKey,TileMap::Quadrant>::Element *TileMap::_create_quadrant(const VisualServer::get_singleton()->canvas_item_set_transform( q.canvas_item, xform ); q.static_body=Physics2DServer::get_singleton()->body_create(Physics2DServer::BODY_MODE_STATIC); Physics2DServer::get_singleton()->body_set_layer_mask(q.static_body,collision_layer); + Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_FRICTION,friction); + Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_BOUNCE,bounce); + if (is_inside_scene()) { xform = get_global_transform() * xform; RID space = get_world_2d()->get_space(); @@ -556,6 +559,38 @@ void TileMap::set_collision_layer_mask(uint32_t p_layer) { } } +void TileMap::set_collision_friction(float p_friction) { + + friction=p_friction; + for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) { + + Quadrant &q=E->get(); + Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_FRICTION,p_friction); + } + +} + +float TileMap::get_collision_friction() const{ + + return friction; +} + +void TileMap::set_collision_bounce(float p_bounce){ + + bounce=p_bounce; + for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) { + + Quadrant &q=E->get(); + Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_BOUNCE,p_bounce); + } + +} +float TileMap::get_collision_bounce() const{ + + return bounce; +} + + uint32_t TileMap::get_collision_layer_mask() const { return collision_layer; @@ -584,6 +619,12 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_collision_layer_mask","mask"),&TileMap::set_collision_layer_mask); ObjectTypeDB::bind_method(_MD("get_collision_layer_mask"),&TileMap::get_collision_layer_mask); + ObjectTypeDB::bind_method(_MD("set_collision_friction","value"),&TileMap::set_collision_friction); + ObjectTypeDB::bind_method(_MD("get_collision_friction"),&TileMap::get_collision_friction); + + ObjectTypeDB::bind_method(_MD("set_collision_bounce","value"),&TileMap::set_collision_bounce); + ObjectTypeDB::bind_method(_MD("get_collision_bounce"),&TileMap::get_collision_bounce); + ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false)); ObjectTypeDB::bind_method(_MD("get_cell","x","y"),&TileMap::get_cell); ObjectTypeDB::bind_method(_MD("is_cell_x_flipped","x","y"),&TileMap::is_cell_x_flipped); @@ -602,7 +643,9 @@ void TileMap::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::INT,"quadrant_size",PROPERTY_HINT_RANGE,"1,128,1"),_SCS("set_quadrant_size"),_SCS("get_quadrant_size")); ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_set",PROPERTY_HINT_RESOURCE_TYPE,"TileSet"),_SCS("set_tileset"),_SCS("get_tileset")); ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_tile_data"),_SCS("_get_tile_data")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"collision_layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_friction"),_SCS("get_collision_friction")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_bounce"),_SCS("get_collision_bounce")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask")); ADD_SIGNAL(MethodInfo("settings_changed")); @@ -620,6 +663,8 @@ TileMap::TileMap() { center_x=false; center_y=false; collision_layer=1; + friction=1; + bounce=0; fp_adjust=0.01; fp_adjust=0.01; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 9265a7b55e..4b4d948923 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -98,6 +98,8 @@ class TileMap : public Node2D { Rect2 rect_cache; bool rect_cache_dirty; float fp_adjust; + float friction; + float bounce; uint32_t collision_layer; @@ -149,6 +151,12 @@ public: void set_collision_layer_mask(uint32_t p_layer); uint32_t get_collision_layer_mask() const; + void set_collision_friction(float p_friction); + float get_collision_friction() const; + + void set_collision_bounce(float p_bounce); + float get_collision_bounce() const; + void clear(); TileMap(); diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index ecdfc8a7f9..56fbf358bc 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 20a1654b92..e7ced6c2ba 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 b79fd8617f..25f3b3d3a5 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<FixedMaterial> 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 f090ae5782..6b1ea2d455 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 d74768f0ab..b47f1644e3 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 12b9dc4b7a..fe627c2cc0 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 0f390c15af..fa1d3ecf6b 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 b77a4e0fe3..323bfa4dc4 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.cpp b/scene/3d/spatial.cpp index de1fd7e8c0..c52503870f 100644 --- a/scene/3d/spatial.cpp +++ b/scene/3d/spatial.cpp @@ -494,6 +494,17 @@ Ref<World> Spatial::get_world() const { } +#ifdef TOOLS_ENABLED +void Spatial::set_import_transform(const Transform& p_transform) { + data.import_transform=p_transform; +} + +Transform Spatial::get_import_transform() const { + + return data.import_transform; +} +#endif + void Spatial::_bind_methods() { @@ -517,6 +528,9 @@ void Spatial::_bind_methods() { #ifdef TOOLS_ENABLED ObjectTypeDB::bind_method(_MD("_update_gizmo"), &Spatial::_update_gizmo); + ObjectTypeDB::bind_method(_MD("_set_import_transform"), &Spatial::set_import_transform); + ObjectTypeDB::bind_method(_MD("_get_import_transform"), &Spatial::get_import_transform); + ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM,"_import_transform",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_import_transform"),_SCS("_get_import_transform")); #endif ObjectTypeDB::bind_method(_MD("update_gizmo"), &Spatial::update_gizmo); diff --git a/scene/3d/spatial.h b/scene/3d/spatial.h index e10629f7de..e1119be515 100644 --- a/scene/3d/spatial.h +++ b/scene/3d/spatial.h @@ -95,6 +95,7 @@ class Spatial : public Node { Ref<SpatialGizmo> gizmo; bool gizmo_disabled; bool gizmo_dirty; + Transform import_transform; #endif } data; @@ -158,6 +159,11 @@ public: Transform get_relative_transform(const Node *p_parent) const; +#ifdef TOOLS_ENABLED + void set_import_transform(const Transform& p_transform) ; + Transform get_import_transform() const; +#endif + Spatial(); ~Spatial(); diff --git a/scene/3d/spatial_player.cpp b/scene/3d/spatial_player.cpp index 0847598356..8e3a0d30ea 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/gui/base_button.cpp b/scene/gui/base_button.cpp index 2e03871063..ac2417d539 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -276,6 +276,10 @@ bool BaseButton::is_pressed() const { return toggle_mode?status.pressed:status.press_attempt; } +bool BaseButton::is_hovered() const { + + return status.hovering; +} BaseButton::DrawMode BaseButton::get_draw_mode() const { @@ -337,6 +341,7 @@ void BaseButton::_bind_methods() { ObjectTypeDB::bind_method(_MD("_input_event"),&BaseButton::_input_event); ObjectTypeDB::bind_method(_MD("set_pressed","pressed"),&BaseButton::set_pressed); ObjectTypeDB::bind_method(_MD("is_pressed"),&BaseButton::is_pressed); + ObjectTypeDB::bind_method(_MD("is_hovered"),&BaseButton::is_hovered); ObjectTypeDB::bind_method(_MD("set_toggle_mode","enabled"),&BaseButton::set_toggle_mode); ObjectTypeDB::bind_method(_MD("is_toggle_mode"),&BaseButton::is_toggle_mode); ObjectTypeDB::bind_method(_MD("set_disabled","disabled"),&BaseButton::set_disabled); diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index 65563ddc03..a2c640b9cf 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -83,6 +83,8 @@ public: bool is_pressed() const; ///< return wether button is pressed (toggled in) bool is_pressing() const; ///< return wether button is pressed (toggled in) + bool is_hovered() const; + void set_pressed(bool p_pressed); ///only works in toggle mode void set_toggle_mode(bool p_on); bool is_toggle_mode() const; diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 4b4b4b3c73..6878793360 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1002,7 +1002,7 @@ void Control::_window_input_event(InputEvent p_event) { } - p_event.mouse_button.global_x = pos.x; + p_event.mouse_button.global_x = pos.x; p_event.mouse_button.global_y = pos.y; pos = window->focus_inv_xform.xform(pos); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 241d66fce4..94df42fc8f 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1561,8 +1561,9 @@ RichTextLabel::RichTextLabel() { scroll_active=true; scroll_w=0; - vscroll = memnew( VScrollBar ); + vscroll = memnew( VScrollBar ); add_child(vscroll); + vscroll->set_drag_slave(String("..")); vscroll->set_step(1); vscroll->set_anchor_and_margin( MARGIN_TOP, ANCHOR_BEGIN, 0); vscroll->set_anchor_and_margin( MARGIN_BOTTOM, ANCHOR_END, 0); diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index fdd30c5f60..c661a804b3 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -29,7 +29,7 @@ #include "scroll_bar.h" #include "os/keyboard.h" #include "print_string.h" - +#include "os/os.h" bool ScrollBar::focus_by_default=false; @@ -293,6 +293,117 @@ void ScrollBar::_notification(int p_what) { } + if (p_what==NOTIFICATION_ENTER_SCENE) { + + + if (has_node(drag_slave_path)) { + Node *n = get_node(drag_slave_path); + drag_slave=n->cast_to<Control>(); + } + + if (drag_slave) { + drag_slave->connect("input_event",this,"_drag_slave_input"); + drag_slave->connect("exit_scene",this,"_drag_slave_exit",varray(),CONNECT_ONESHOT); + } + + + } + if (p_what==NOTIFICATION_EXIT_SCENE) { + + if (drag_slave) { + drag_slave->disconnect("input_event",this,"_drag_slave_input"); + drag_slave->disconnect("exit_scene",this,"_drag_slave_exit"); + } + + drag_slave=NULL; + + } + + if (p_what==NOTIFICATION_FIXED_PROCESS) { + + if (drag_slave_touching) { + + if (drag_slave_touching_deaccel) { + + Vector2 pos = Vector2(orientation==HORIZONTAL?get_val():0,orientation==VERTICAL?get_val():0); + pos+=drag_slave_speed*get_fixed_process_delta_time(); + + bool turnoff=false; + + if (orientation==HORIZONTAL) { + + if (pos.x<0) { + pos.x=0; + turnoff=true; + } + + if (pos.x > (get_max()-get_page())) { + pos.x=get_max()-get_page(); + turnoff=true; + } + + set_val(pos.x); + + float sgn_x = drag_slave_speed.x<0? -1 : 1; + float val_x = Math::abs(drag_slave_speed.x); + val_x-=1000*get_fixed_process_delta_time(); + + if (val_x<0) { + turnoff=true; + } + + drag_slave_speed.x=sgn_x*val_x; + + } else { + + + if (pos.y<0) { + pos.y=0; + turnoff=true; + } + + if (pos.y > (get_max()-get_page())) { + pos.y=get_max()-get_page(); + turnoff=true; + } + + set_val(pos.y); + + float sgn_y = drag_slave_speed.y<0? -1 : 1; + float val_y = Math::abs(drag_slave_speed.y); + val_y-=1000*get_fixed_process_delta_time(); + + if (val_y<0) { + turnoff=true; + } + drag_slave_speed.y=sgn_y*val_y; + } + + + if (turnoff) { + set_fixed_process(false); + drag_slave_touching=false; + drag_slave_touching_deaccel=false; + } + + + } else { + + + if (time_since_motion==0 || time_since_motion>0.1) { + + Vector2 diff = drag_slave_accum - last_drag_slave_accum; + last_drag_slave_accum=drag_slave_accum; + drag_slave_speed=diff/get_fixed_process_delta_time(); + } + + time_since_motion+=get_fixed_process_delta_time(); + } + } + + + } + if (p_what==NOTIFICATION_MOUSE_EXIT) { hilite=HILITE_NONE; @@ -432,6 +543,131 @@ float ScrollBar::get_custom_step() const { } +void ScrollBar::_drag_slave_exit() { + + if (drag_slave) { + drag_slave->disconnect("input_event",this,"_drag_slave_input"); + } + drag_slave=NULL; +} + + +void ScrollBar::_drag_slave_input(const InputEvent& p_input) { + + switch(p_input.type) { + + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &mb=p_input.mouse_button; + + if (mb.button_index!=1) + break; + + if (mb.pressed) { + + if (drag_slave_touching) { + set_fixed_process(false); + drag_slave_touching_deaccel=false; + drag_slave_touching=false; + drag_slave_speed=Vector2(); + drag_slave_accum=Vector2(); + last_drag_slave_accum=Vector2(); + drag_slave_from=Vector2(); + } + + if (true) { + drag_slave_speed=Vector2(); + drag_slave_accum=Vector2(); + last_drag_slave_accum=Vector2(); + //drag_slave_from=Vector2(h_scroll->get_val(),v_scroll->get_val()); + drag_slave_from= Vector2(orientation==HORIZONTAL?get_val():0,orientation==VERTICAL?get_val():0); + + drag_slave_touching=OS::get_singleton()->has_touchscreen_ui_hint(); + drag_slave_touching_deaccel=false; + time_since_motion=0; + if (drag_slave_touching) { + set_fixed_process(true); + time_since_motion=0; + + } + } + + } else { + + if (drag_slave_touching) { + + if (drag_slave_speed==Vector2()) { + drag_slave_touching_deaccel=false; + drag_slave_touching=false; + set_fixed_process(false); + } else { + + drag_slave_touching_deaccel=true; + } + } + } + } break; + case InputEvent::MOUSE_MOTION: { + + const InputEventMouseMotion &mm=p_input.mouse_motion; + + if (drag_slave_touching && ! drag_slave_touching_deaccel) { + + Vector2 motion = Vector2(mm.relative_x,mm.relative_y); + + drag_slave_accum-=motion; + Vector2 diff = drag_slave_from+drag_slave_accum; + + if (orientation==HORIZONTAL) + set_val(diff.x); + //else + // drag_slave_accum.x=0; + if (orientation==VERTICAL) + set_val(diff.y); + //else + // drag_slave_accum.y=0; + time_since_motion=0; + } + + } break; + } +} + +void ScrollBar::set_drag_slave(const NodePath& p_path) { + + if (is_inside_scene()) { + + if (drag_slave) { + drag_slave->disconnect("input_event",this,"_drag_slave_input"); + drag_slave->disconnect("exit_scene",this,"_drag_slave_exit"); + } + } + + drag_slave=NULL; + drag_slave_path=p_path; + + if (is_inside_scene()) { + + if (has_node(p_path)) { + Node *n = get_node(p_path); + drag_slave=n->cast_to<Control>(); + } + + if (drag_slave) { + drag_slave->connect("input_event",this,"_drag_slave_input"); + drag_slave->connect("exit_scene",this,"_drag_slave_exit",varray(),CONNECT_ONESHOT); + } + } +} + +NodePath ScrollBar::get_drag_slave() const{ + + + return drag_slave_path; +} + + + #if 0 void ScrollBar::mouse_button(const Point2& p_pos, int b.button_index,bool b.pressed,int p_modifier_mask) { @@ -571,6 +807,8 @@ void ScrollBar::_bind_methods() { ObjectTypeDB::bind_method(_MD("_input_event"),&ScrollBar::_input_event); ObjectTypeDB::bind_method(_MD("set_custom_step","step"),&ScrollBar::set_custom_step); ObjectTypeDB::bind_method(_MD("get_custom_step"),&ScrollBar::get_custom_step); + ObjectTypeDB::bind_method(_MD("_drag_slave_input"),&ScrollBar::_drag_slave_input); + ObjectTypeDB::bind_method(_MD("_drag_slave_exit"),&ScrollBar::_drag_slave_exit); ADD_PROPERTY( PropertyInfo(Variant::REAL,"custom_step",PROPERTY_HINT_RANGE,"-1,4096"), _SCS("set_custom_step"),_SCS("get_custom_step")); @@ -584,9 +822,14 @@ ScrollBar::ScrollBar(Orientation p_orientation) orientation=p_orientation; hilite=HILITE_NONE; custom_step=-1; + drag_slave=NULL; drag.active=false; - + + drag_slave_speed=Vector2(); + drag_slave_touching=false; + drag_slave_touching_deaccel=false; + if (focus_by_default) set_focus_mode( FOCUS_ALL ); diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h index 663d3ecd85..ad3d1a7f58 100644 --- a/scene/gui/scroll_bar.h +++ b/scene/gui/scroll_bar.h @@ -70,7 +70,22 @@ class ScrollBar : public Range { double get_grabber_offset() const; static void set_can_focus_by_default(bool p_can_focus); - + + Node* drag_slave; + NodePath drag_slave_path; + + Vector2 drag_slave_speed; + Vector2 drag_slave_accum; + Vector2 drag_slave_from; + Vector2 last_drag_slave_accum; + float last_drag_slave_time; + float time_since_motion; + bool drag_slave_touching; + bool drag_slave_touching_deaccel; + bool click_handled; + + void _drag_slave_exit(); + void _drag_slave_input(const InputEvent& p_input); void _input_event(InputEvent p_event); protected: @@ -83,6 +98,9 @@ public: void set_custom_step(float p_custom_step); float get_custom_step() const; + void set_drag_slave(const NodePath& p_path); + NodePath get_drag_slave() const; + virtual Size2 get_minimum_size() const; ScrollBar(Orientation p_orientation=VERTICAL); ~ScrollBar(); diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 817833083e..c8f9ed16b5 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -235,7 +235,7 @@ void ScrollContainer::_notification(int p_what) { } if (pos.y<0) { - pos.x=0; + pos.y=0; turnoff_v=true; } if (pos.y > (v_scroll->get_max()-v_scroll->get_page())) { diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 042666988a..b90fd489b3 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1698,6 +1698,20 @@ Array Node::_get_children() const { return arr; } +#ifdef TOOLS_ENABLED +void Node::set_import_path(const NodePath& p_import_path) { + + + data.import_path=p_import_path; +} + +NodePath Node::get_import_path() const { + + return data.import_path; +} + +#endif + void Node::_bind_methods() { @@ -1760,6 +1774,12 @@ void Node::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_viewport"),&Node::get_viewport); ObjectTypeDB::bind_method(_MD("queue_free"),&Node::queue_delete); +#ifdef TOOLS_ENABLED + ObjectTypeDB::bind_method(_MD("_set_import_path","import_path"),&Node::set_import_path); + ObjectTypeDB::bind_method(_MD("_get_import_path"),&Node::get_import_path); + ADD_PROPERTY( PropertyInfo(Variant::NODE_PATH,"_import_path",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_import_path"),_SCS("_get_import_path")); + +#endif BIND_CONSTANT( NOTIFICATION_ENTER_SCENE ); BIND_CONSTANT( NOTIFICATION_EXIT_SCENE ); diff --git a/scene/main/node.h b/scene/main/node.h index 32c5d8ef38..f1ecf497e0 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -82,6 +82,9 @@ private: StringName name; SceneMainLoop *scene; bool inside_scene; +#ifdef TOOLS_ENABLED + NodePath import_path; //path used when imported, used by scene editors to keep tracking +#endif Viewport *viewport; @@ -269,11 +272,18 @@ public: void queue_delete(); +//shitty hacks for speed static void set_human_readable_collision_renaming(bool p_enabled); static void init_node_hrcr(); void force_parent_owned() { data.parent_owned=true; } //hack to avoid duplicate nodes +#ifdef TOOLS_ENABLED + void set_import_path(const NodePath& p_import_path); //path used when imported, used by scene editors to keep tracking + NodePath get_import_path() const; +#endif + + _FORCE_INLINE_ Viewport *get_viewport() const { return data.viewport; } /* CANVAS */ diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h index 8b9ea0b585..493644d2bc 100644 --- a/scene/main/scene_main_loop.h +++ b/scene/main/scene_main_loop.h @@ -45,6 +45,7 @@ class SceneMainLoop; class Node; class Viewport; + class SceneMainLoop : public MainLoop { _THREAD_SAFE_CLASS_ diff --git a/scene/resources/baked_light.cpp b/scene/resources/baked_light.cpp index b3de7143ee..725ac1c946 100644 --- a/scene/resources/baked_light.cpp +++ b/scene/resources/baked_light.cpp @@ -201,6 +201,16 @@ bool BakedLight::get_bake_flag(BakeFlags p_flags) const{ return flags[p_flags]; } +void BakedLight::set_format(Format p_format) { + + format=p_format; + +} + +BakedLight::Format BakedLight::get_format() const{ + + return format; +} void BakedLight::_bind_methods(){ @@ -240,6 +250,10 @@ void BakedLight::_bind_methods(){ ObjectTypeDB::bind_method(_MD("set_normal_damp","normal_damp"),&BakedLight::set_normal_damp); ObjectTypeDB::bind_method(_MD("get_normal_damp"),&BakedLight::get_normal_damp); + ObjectTypeDB::bind_method(_MD("set_format","format"),&BakedLight::set_format); + ObjectTypeDB::bind_method(_MD("get_format"),&BakedLight::get_format); + + ObjectTypeDB::bind_method(_MD("set_energy_multiplier","energy_multiplier"),&BakedLight::set_energy_multiplier); ObjectTypeDB::bind_method(_MD("get_energy_multiplier"),&BakedLight::get_energy_multiplier); @@ -251,6 +265,7 @@ void BakedLight::_bind_methods(){ ADD_PROPERTY( PropertyInfo(Variant::INT,"mode/mode",PROPERTY_HINT_ENUM,"Octree,Lightmaps"),_SCS("set_mode"),_SCS("get_mode")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/format",PROPERTY_HINT_ENUM,"RGB,HDR8,HDR16"),_SCS("set_format"),_SCS("get_format")); ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/cell_subdiv",PROPERTY_HINT_RANGE,"4,14,1"),_SCS("set_cell_subdivision"),_SCS("get_cell_subdivision")); ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/lattice_subdiv",PROPERTY_HINT_RANGE,"1,5,1"),_SCS("set_initial_lattice_subdiv"),_SCS("get_initial_lattice_subdiv")); ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/light_bounces",PROPERTY_HINT_RANGE,"0,3,1"),_SCS("set_bounces"),_SCS("get_bounces")); @@ -292,6 +307,7 @@ BakedLight::BakedLight() { cell_extra_margin=0.05; edge_damp=0.0; normal_damp=0.0; + format=FORMAT_RGB; flags[BAKE_DIFFUSE]=true; flags[BAKE_SPECULAR]=false; diff --git a/scene/resources/baked_light.h b/scene/resources/baked_light.h index 8b50f6e0d3..df86f98c08 100644 --- a/scene/resources/baked_light.h +++ b/scene/resources/baked_light.h @@ -14,6 +14,13 @@ public: MODE_LIGHTMAPS }; + enum Format { + + FORMAT_RGB, + FORMAT_HDR8, + FORMAT_HDR16 + }; + enum BakeFlags { BAKE_DIFFUSE, BAKE_SPECULAR, @@ -38,6 +45,7 @@ private: float edge_damp; float normal_damp; int bounces; + Format format; bool flags[BAKE_MAX]; @@ -80,6 +88,8 @@ public: void set_bake_flag(BakeFlags p_flags,bool p_enable); bool get_bake_flag(BakeFlags p_flags) const; + void set_format(Format p_margin); + Format get_format() const; void set_mode(Mode p_mode); Mode get_mode() const; @@ -100,6 +110,7 @@ public: }; +VARIANT_ENUM_CAST(BakedLight::Format); VARIANT_ENUM_CAST(BakedLight::Mode); VARIANT_ENUM_CAST(BakedLight::BakeFlags); diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 5c1d190b2e..df18e4f0f5 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;i<FX_MAX;i++) set_enable_fx(Fx(i),false); + fx_set_param(FX_PARAM_AMBIENT_LIGHT_COLOR,Color(0,0,0)); + fx_set_param(FX_PARAM_AMBIENT_LIGHT_ENERGY,1.0); fx_set_param(FX_PARAM_GLOW_BLUR_PASSES,1); fx_set_param(FX_PARAM_GLOW_BLUR_SCALE,1); fx_set_param(FX_PARAM_GLOW_BLUR_STRENGTH,1); @@ -253,8 +270,9 @@ Environment::Environment() { fx_set_param(FX_PARAM_DOF_BLUR_PASSES,1); fx_set_param(FX_PARAM_DOF_BLUR_BEGIN,100.0); fx_set_param(FX_PARAM_DOF_BLUR_RANGE,10.0); + fx_set_param(FX_PARAM_HDR_TONEMAPPER,FX_HDR_TONE_MAPPER_LINEAR); fx_set_param(FX_PARAM_HDR_EXPOSURE,0.4); - fx_set_param(FX_PARAM_HDR_SCALAR,1.0); + fx_set_param(FX_PARAM_HDR_WHITE,1.0); fx_set_param(FX_PARAM_HDR_GLOW_TRESHOLD,0.95); fx_set_param(FX_PARAM_HDR_GLOW_SCALE,0.2); fx_set_param(FX_PARAM_HDR_MIN_LUMINANCE,0.4); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index b72d6d74be..a9e2f422b9 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -61,6 +61,7 @@ public: }; enum Fx { + FX_AMBIENT_LIGHT=VS::ENV_FX_AMBIENT_LIGHT, FX_FXAA=VS::ENV_FX_FXAA, FX_GLOW=VS::ENV_FX_GLOW, FX_DOF_BLUR=VS::ENV_FX_DOF_BLUR, @@ -77,7 +78,16 @@ public: FX_BLUR_BLEND_MODE_SOFTLIGHT, }; + enum FxHDRToneMapper { + FX_HDR_TONE_MAPPER_LINEAR, + FX_HDR_TONE_MAPPER_LOG, + FX_HDR_TONE_MAPPER_REINHARDT, + FX_HDR_TONE_MAPPER_REINHARDT_AUTOWHITE, + }; + enum FxParam { + FX_PARAM_AMBIENT_LIGHT_COLOR=VS::ENV_FX_PARAM_AMBIENT_LIGHT_COLOR, + FX_PARAM_AMBIENT_LIGHT_ENERGY=VS::ENV_FX_PARAM_AMBIENT_LIGHT_ENERGY, FX_PARAM_GLOW_BLUR_PASSES=VS::ENV_FX_PARAM_GLOW_BLUR_PASSES, FX_PARAM_GLOW_BLUR_SCALE=VS::ENV_FX_PARAM_GLOW_BLUR_SCALE, FX_PARAM_GLOW_BLUR_STRENGTH=VS::ENV_FX_PARAM_GLOW_BLUR_STRENGTH, @@ -88,7 +98,8 @@ public: FX_PARAM_DOF_BLUR_BEGIN=VS::ENV_FX_PARAM_DOF_BLUR_BEGIN, FX_PARAM_DOF_BLUR_RANGE=VS::ENV_FX_PARAM_DOF_BLUR_RANGE, FX_PARAM_HDR_EXPOSURE=VS::ENV_FX_PARAM_HDR_EXPOSURE, - FX_PARAM_HDR_SCALAR=VS::ENV_FX_PARAM_HDR_SCALAR, + FX_PARAM_HDR_TONEMAPPER=VS::ENV_FX_PARAM_HDR_TONEMAPPER, + 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, diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 091a46d4ab..2314926b2b 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -36,17 +36,9 @@ static const char*_flag_names[Material::FLAG_MAX]={ "invert_faces", "unshaded", "on_top", - "wireframe", - "billboard_sw", + "lightmap_on_uv2" }; -static const char*_hint_names[Material::HINT_MAX]={ - "decal", - "opaque_pre_zpass", - "no_shadow", - "no_depth_draw", - "no_alpha_depth_draw", -}; static const Material::Flag _flag_indices[Material::FLAG_MAX]={ Material::FLAG_VISIBLE, @@ -54,15 +46,7 @@ static const Material::Flag _flag_indices[Material::FLAG_MAX]={ Material::FLAG_INVERT_FACES, Material::FLAG_UNSHADED, Material::FLAG_ONTOP, - Material::FLAG_WIREFRAME, - Material::FLAG_BILLBOARD_TOGGLE -}; - -static const Material::Hint _hint_indices[Material::HINT_MAX]={ - Material::HINT_DECAL, - Material::HINT_OPAQUE_PRE_PASS, - Material::HINT_NO_SHADOW, - Material::HINT_NO_DEPTH_DRAW, + Material::FLAG_LIGHTMAP_ON_UV2 }; @@ -80,20 +64,6 @@ void Material::set_flag(Flag p_flag,bool p_enabled) { } -void Material::set_hint(Hint p_hint,bool p_enabled) { - - ERR_FAIL_INDEX(p_hint,HINT_MAX); - hints[p_hint]=p_enabled; - VisualServer::get_singleton()->material_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;i<FLAG_MAX;i++) ADD_PROPERTYI( PropertyInfo( Variant::BOOL, String()+"flags/"+_flag_names[i] ),_SCS("set_flag"),_SCS("get_flag"),_flag_indices[i]); - for(int i=0;i<HINT_MAX;i++) - ADD_PROPERTYI( PropertyInfo( Variant::BOOL, String()+"hints/"+_hint_names[i] ),_SCS("set_hint"),_SCS("get_hint"),_hint_indices[i]); ADD_PROPERTY( PropertyInfo( Variant::INT, "params/blend_mode",PROPERTY_HINT_ENUM,"Mix,Add,Sub,PMAlpha" ), _SCS("set_blend_mode"),_SCS("get_blend_mode")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "params/depth_draw",PROPERTY_HINT_ENUM,"Always,Opaque Only,Pre-Pass Alpha,Never" ), _SCS("set_depth_draw_mode"),_SCS("get_depth_draw_mode")); ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/line_width",PROPERTY_HINT_RANGE,"0.1,32.0,0.1" ), _SCS("set_line_width"),_SCS("get_line_width")); - BIND_CONSTANT( FLAG_VISIBLE ); BIND_CONSTANT( FLAG_DOUBLE_SIDED ); BIND_CONSTANT( FLAG_INVERT_FACES ); BIND_CONSTANT( FLAG_UNSHADED ); BIND_CONSTANT( FLAG_ONTOP ); - BIND_CONSTANT( FLAG_WIREFRAME ); - BIND_CONSTANT( FLAG_BILLBOARD_TOGGLE ); BIND_CONSTANT( FLAG_MAX ); - BIND_CONSTANT( HINT_DECAL ); - BIND_CONSTANT( HINT_OPAQUE_PRE_PASS ); - BIND_CONSTANT( HINT_NO_SHADOW ); - BIND_CONSTANT( HINT_NO_DEPTH_DRAW ); - BIND_CONSTANT( HINT_NO_DEPTH_DRAW_FOR_ALPHA ); - BIND_CONSTANT( HINT_MAX ); - - BIND_CONSTANT( SHADE_MODEL_LAMBERT ); - BIND_CONSTANT( SHADE_MODEL_LAMBERT_WRAP ); - BIND_CONSTANT( SHADE_MODEL_FRESNEL ); - BIND_CONSTANT( SHADE_MODEL_TOON ); - BIND_CONSTANT( SHADE_MODEL_CUSTOM_0 ); - BIND_CONSTANT( SHADE_MODEL_CUSTOM_1 ); - BIND_CONSTANT( SHADE_MODEL_CUSTOM_2 ); - BIND_CONSTANT( SHADE_MODEL_CUSTOM_3 ); + BIND_CONSTANT( DEPTH_DRAW_ALWAYS ); + BIND_CONSTANT( DEPTH_DRAW_OPAQUE_ONLY ); + BIND_CONSTANT( DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA ); + BIND_CONSTANT( DEPTH_DRAW_NEVER ); BIND_CONSTANT( BLEND_MODE_MIX ); BIND_CONSTANT( BLEND_MODE_ADD ); @@ -205,15 +156,11 @@ Material::Material(const RID& p_material) { flags[FLAG_INVERT_FACES]=false; flags[FLAG_UNSHADED]=false; flags[FLAG_ONTOP]=false; - flags[FLAG_WIREFRAME]=false; - flags[FLAG_BILLBOARD_TOGGLE]=false; - for(int i=0;i<HINT_MAX;i++) - hints[i]=false; - hints[HINT_NO_DEPTH_DRAW_FOR_ALPHA]=true; + depth_draw_mode=DEPTH_DRAW_OPAQUE_ONLY; blend_mode=BLEND_MODE_MIX; - shade_model = SHADE_MODEL_LAMBERT; + } Material::~Material() { @@ -340,6 +287,17 @@ FixedMaterial::TexCoordMode FixedMaterial::get_texcoord_mode(Parameter p_paramet return texture_texcoord[p_parameter]; } +void FixedMaterial::set_light_shader(LightShader p_shader) { + + light_shader=p_shader; + VS::get_singleton()->fixed_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 2057b3cac9..23ecb18fac 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> 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 9f7b6d5b9e..afb0ae1815 100644 --- a/scene/resources/polygon_path_finder.cpp +++ b/scene/resources/polygon_path_finder.cpp @@ -2,7 +2,7 @@ #include "geometry.h" -bool PolygonPathFinder::_is_point_inside(const Vector2& p_point) { +bool PolygonPathFinder::_is_point_inside(const Vector2& p_point) const { int crosses=0; @@ -36,13 +36,21 @@ void PolygonPathFinder::setup(const Vector<Vector2>& p_points, const Vector<int> int point_count=p_points.size(); points.resize(point_count+2); + bounds=Rect2(); for(int i=0;i<p_points.size();i++) { points[i].pos=p_points[i]; + points[i].penalty=0; outside_point.x = i==0?p_points[0].x:(MAX( p_points[i].x, outside_point.x )); outside_point.y = i==0?p_points[0].y:(MAX( p_points[i].y, outside_point.y )); + + if (i==0) { + bounds.pos=points[i].pos; + } else { + bounds.expand_to(points[i].pos); + } } outside_point.x+=20.451+Math::randf()*10.2039; @@ -108,10 +116,63 @@ void PolygonPathFinder::setup(const Vector<Vector2>& p_points, const Vector<int> Vector<Vector2> PolygonPathFinder::find_path(const Vector2& p_from, const Vector2& p_to) { Vector<Vector2> path; - if (!_is_point_inside(p_from)) - return path; - if (!_is_point_inside(p_to)) - 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<Edge>::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 (d<closest_dist) { + ignore_from_edge=E->get(); + closest_dist=d; + } + } + + from=closest_point; + }; + + + if (!_is_point_inside(to)) { + float closest_dist=1e20; + Vector2 closest_point; + + for (Set<Edge>::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 (d<closest_dist) { + ignore_to_edge=E->get(); + closest_dist=d; + } + } + + to=closest_point; + }; //test direct connection { @@ -121,11 +182,16 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2& p_from, const Vector for (Set<Edge>::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; } @@ -134,8 +200,8 @@ Vector<Vector2> 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; } } @@ -144,12 +210,15 @@ Vector<Vector2> 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].distance=0; - points[bidx].distance=0; + 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<points.size()-2;i++) { @@ -160,6 +229,18 @@ Vector<Vector2> 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<Edge>::Element *E=edges.front();E;E=E->next()) { const Edge& e=E->get(); @@ -167,28 +248,45 @@ Vector<Vector2> 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) - continue; + break; + } + if (valid_a) { points[i].connections.insert(aidx); points[aidx].connections.insert(i); @@ -209,7 +307,7 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2& p_from, const Vector for(Set<int>::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; } @@ -220,6 +318,7 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2& p_from, const Vector while(true) { if (open_list.size()==0) { + printf("open list empty\n"); break; } //check open list @@ -232,7 +331,9 @@ Vector<Vector2> 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 (cost<least_cost) { least_cost_point=E->get(); @@ -315,6 +416,7 @@ void PolygonPathFinder::_set_data(const Dictionary& p_data) { ERR_FAIL_COND(!p_data.has("points")); ERR_FAIL_COND(!p_data.has("connections")); ERR_FAIL_COND(!p_data.has("segments")); + ERR_FAIL_COND(!p_data.has("bounds")); DVector<Vector2> p=p_data["points"]; Array c=p_data["connections"]; @@ -339,6 +441,17 @@ void PolygonPathFinder::_set_data(const Dictionary& p_data) { } + if (p_data.has("penalties")) { + + DVector<float> penalties=p_data["penalties"]; + if (penalties.size()==pc) { + DVector<float>::Read pr = penalties.read(); + for(int i=0;i<pc;i++) { + points[i].penalty=pr[i]; + } + } + } + DVector<int> segs=p_data["segments"]; int sc=segs.size(); ERR_FAIL_COND(sc&1); @@ -348,6 +461,7 @@ void PolygonPathFinder::_set_data(const Dictionary& p_data) { Edge e(sr[i],sr[i+1]); edges.insert(e); } + bounds=p_data["bounds"]; } @@ -360,10 +474,15 @@ Dictionary PolygonPathFinder::_get_data() const{ p.resize(points.size()-2); connections.resize(points.size()-2); ind.resize(edges.size()*2); + DVector<float> penalties; + penalties.resize(points.size()-2); { DVector<Vector2>::Write wp=p.write(); + DVector<float>::Write pw=penalties.write(); + for(int i=0;i<points.size()-2;i++) { wp[i]=points[i].pos; + pw[i]=points[i].penalty; DVector<int> c; c.resize(points[i].connections.size()); { @@ -387,7 +506,9 @@ Dictionary PolygonPathFinder::_get_data() const{ } + d["bounds"]=bounds; d["points"]=p; + d["penalties"]=penalties; d["connections"]=connections; d["segments"]=ind; @@ -395,10 +516,79 @@ Dictionary PolygonPathFinder::_get_data() const{ } +bool PolygonPathFinder::is_point_inside(const Vector2& p_point) const { + + return _is_point_inside(p_point); +} + +Vector2 PolygonPathFinder::get_closest_point(const Vector2& p_point) const { + + int closest_idx=-1; + float closest_dist=1e20; + for(int i=0;i<points.size()-2;i++) { + + float d = p_point.distance_squared_to(points[i].pos); + if (d<closest_dist) { + d=closest_dist; + closest_idx=i; + } + + } + + ERR_FAIL_COND_V(closest_idx==-1,Vector2()); + + return points[closest_idx].pos; +} + + +Vector<Vector2> PolygonPathFinder::get_intersections(const Vector2& p_from, const Vector2& p_to) const { + + Vector<Vector2> inters; + + for (Set<Edge>::Element *E=edges.front();E;E=E->next()) { + Vector2 a = points[E->get().points[0]].pos; + Vector2 b = points[E->get().points[1]].pos; + + Vector2 res; + if (Geometry::segment_intersects_segment_2d(a,b,p_from,p_to,&res)) { + inters.push_back(res); + } + } + + return inters; + +} + +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() { ObjectTypeDB::bind_method(_MD("setup","points","connections"),&PolygonPathFinder::setup); ObjectTypeDB::bind_method(_MD("find_path","from","to"),&PolygonPathFinder::find_path); + 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 31253e3177..2cbe3e949d 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<int> connections; float distance; + float penalty; int prev; }; @@ -31,15 +32,18 @@ class PolygonPathFinder : public Resource { if (a>b) { SWAP(a,b); } + points[0] = a; + points[1] = b; } }; Vector2 outside_point; + Rect2 bounds; Vector<Point> points; Set<Edge> edges; - bool _is_point_inside(const Vector2& p_point); + bool _is_point_inside(const Vector2& p_point) const; void _set_data(const Dictionary& p_data); Dictionary _get_data() const; @@ -52,6 +56,15 @@ public: void setup(const Vector<Vector2>& p_points, const Vector<int>& p_connections); Vector<Vector2> 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<Vector2> get_intersections(const Vector2& p_from, const Vector2& p_to) const; + Rect2 get_bounds() const; + + PolygonPathFinder(); }; diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index ffdd92c2d1..6d65da3782 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 d04774dada..fff6f1d28a 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<PropertyInfo> *p_params) const; bool has_param(const StringName& p_param) const; diff --git a/servers/visual/rasterizer.cpp b/servers/visual/rasterizer.cpp index e21848eac2..610e9a6a1b 100644 --- a/servers/visual/rasterizer.cpp +++ b/servers/visual/rasterizer.cpp @@ -60,7 +60,7 @@ RID Rasterizer::_create_shader(const FixedMaterialShaderKey& p_key) { int texcoords_used=0; String code; - static const char* _uv_str[4]={"UV","UV2","uv_xform","uv_sphere"}; + static const char* _uv_str[4]={"UV","uv_xform","UV2","uv_sphere"}; #define _TEXUVSTR(m_idx) String( _uv_str[(p_key.texcoord_mask>>(m_idx*2))&0x3] ) @@ -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<<VS::FIXED_MATERIAL_PARAM_SHADE_PARAM)) { + + String scode; + scode+="uniform texture fmp_shade_param_tex;\n"; + scode+="SHADE_PARAM=tex( fmp_shade_param_tex,"+_TEXUVSTR(VS::FIXED_MATERIAL_PARAM_SHADE_PARAM)+").r;\n"; + code+=scode; + } else { + + String scode; + scode+="uniform float fmp_shade_param;\n"; + scode+="SHADE_PARAM=fmp_shade_param;\n"; + code+=scode; + + } + + //print_line("**FRAGMENT SHADER GENERATED code: \n"+code); String vcode; @@ -235,12 +236,58 @@ RID Rasterizer::_create_shader(const FixedMaterialShaderKey& p_key) { // vcode+="POINT_SIZE=10.0;\n"; } + String lcode; + + switch(p_key.light_shader) { + + case VS::FIXED_MATERIAL_LIGHT_SHADER_LAMBERT: { + //do nothing + + } break; + case VS::FIXED_MATERIAL_LIGHT_SHADER_WRAP: { + + lcode+="float NdotL = max(0.0,((dot( NORMAL, LIGHT_DIR )+SHADE_PARAM)/(1.0+SHADE_PARAM)));"; + lcode+="vec3 half_vec = normalize(LIGHT_DIR + EYE_VEC);"; + lcode+="float eye_light = max(dot(NORMAL, half_vec),0.0);"; + lcode+="LIGHT = LIGHT_DIFFUSE * DIFFUSE * NdotL;"; + lcode+="if (NdotL > 0.0) {"; + lcode+="\tLIGHT+=LIGHT_SPECULAR * SPECULAR * pow( eye_light, SPECULAR_EXP );"; + lcode+="};"; + + } break; + case VS::FIXED_MATERIAL_LIGHT_SHADER_VELVET: { + lcode+="float NdotL = max(0.0,dot( NORMAL, LIGHT_DIR ));"; + lcode+="vec3 half_vec = normalize(LIGHT_DIR + EYE_VEC);"; + lcode+="float eye_light = max(dot(NORMAL, half_vec),0.0);"; + lcode+="LIGHT = LIGHT_DIFFUSE * DIFFUSE * NdotL;"; + lcode+="float rim = (1.0-abs(dot(NORMAL,vec3(0,0,1))))*SHADE_PARAM;"; + lcode+="LIGHT += LIGHT_DIFFUSE * DIFFUSE * rim;"; + lcode+="if (NdotL > 0.0) {"; + lcode+="\tLIGHT+=LIGHT_SPECULAR * SPECULAR * pow( eye_light, SPECULAR_EXP );"; + lcode+="};"; + + + } break; + case VS::FIXED_MATERIAL_LIGHT_SHADER_TOON: { + + lcode+="float NdotL = dot( NORMAL, LIGHT_DIR );"; + lcode+="vec3 light_ref = reflect( LIGHT_DIR, NORMAL );"; + lcode+="float eye_light = clamp( dot( light_ref, vec3(0,0,0)-EYE_VEC), 0.0, 1.0 );"; + lcode+="float NdotL_diffuse = smoothstep( max( SHADE_PARAM-0.05, 0.0-1.0), min( SHADE_PARAM+0.05, 1.0), NdotL );"; + lcode+="float spec_radius=clamp((1.0-(SPECULAR_EXP/64.0)),0.0,1.0);"; + lcode+="float NdotL_specular = smoothstep( max( spec_radius-0.05, 0.0), min( spec_radius+0.05, 1.0), eye_light )*max(NdotL,0);"; + lcode+="LIGHT = NdotL_diffuse * LIGHT_DIFFUSE*DIFFUSE + NdotL_specular * LIGHT_SPECULAR*SPECULAR;"; + + } break; + + } + //print_line("**VERTEX SHADER GENERATED code: \n"+vcode); double tf = (OS::get_singleton()->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<RID,FixedMaterial*>::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<RID,FixedMaterial*>::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<RID,FixedMaterial*>::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<RID,FixedMaterial*>::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<RID,FixedMaterial*>::Element *E = fixed_materials.find(p_material); diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 2e94f3fe9d..2b02a81a44 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<VS::FIXED_MATERIAL_PARAM_MAX;i++) { if (texture[i].is_valid()) { @@ -124,7 +124,7 @@ protected: use_pointsize=false; discard_alpha=false; point_size=1.0; - detail_blend=VS::MATERIAL_BLEND_MODE_MIX; + light_shader=VS::FIXED_MATERIAL_LIGHT_SHADER_LAMBERT; for(int i=0;i<VS::FIXED_MATERIAL_PARAM_MAX;i++) { texture_tc[i]=VS::FIXED_MATERIAL_TEXCOORD_UV; } @@ -192,9 +192,10 @@ public: virtual void shader_set_mode(RID p_shader,VS::ShaderMode p_mode)=0; virtual VS::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<PropertyInfo> *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; @@ -508,6 +506,7 @@ public: float octree_lattice_size; float octree_lattice_divide; + float texture_multiplier; int octree_steps; Vector2 octree_tex_pixel_size; }; diff --git a/servers/visual/rasterizer_dummy.cpp b/servers/visual/rasterizer_dummy.cpp index 3a04ba7504..e0c1932589 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<PropertyInfo> *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 a837d54b9b..01ae6c7644 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<StringName,Variant> 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<VS::MATERIAL_FLAG_MAX;i++) flags[i]=false; flags[VS::MATERIAL_FLAG_VISIBLE]=true; - for(int i=0;i<VS::MATERIAL_HINT_MAX;i++) - hints[i]=false; + depth_draw_mode=VS::MATERIAL_DEPTH_DRAW_OPAQUE_ONLY; line_width=1; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; point_size = 1.0; @@ -296,7 +296,7 @@ class RasterizerDummy : public Rasterizer { vars[VS::LIGHT_PARAM_ENERGY]=1.0; vars[VS::LIGHT_PARAM_RADIUS]=1.0; vars[VS::LIGHT_PARAM_SHADOW_Z_OFFSET]=0.05; - colors[VS::LIGHT_COLOR_AMBIENT]=Color(0,0,0); + colors[VS::LIGHT_COLOR_DIFFUSE]=Color(1,1,1); colors[VS::LIGHT_COLOR_SPECULAR]=Color(1,1,1); shadow_enabled=false; @@ -331,7 +331,7 @@ class RasterizerDummy : public Rasterizer { fx_param[VS::ENV_FX_PARAM_DOF_BLUR_BEGIN]=100.0; fx_param[VS::ENV_FX_PARAM_DOF_BLUR_RANGE]=10.0; fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE]=0.4; - fx_param[VS::ENV_FX_PARAM_HDR_SCALAR]=1.0; + fx_param[VS::ENV_FX_PARAM_HDR_WHITE]=1.0; fx_param[VS::ENV_FX_PARAM_HDR_GLOW_TRESHOLD]=0.95; fx_param[VS::ENV_FX_PARAM_HDR_GLOW_SCALE]=0.2; fx_param[VS::ENV_FX_PARAM_HDR_MIN_LUMINANCE]=0.4; @@ -415,9 +415,10 @@ public: virtual void shader_set_mode(RID p_shader,VS::ShaderMode p_mode); virtual VS::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_fragment_code(RID p_shader) const; virtual String shader_get_vertex_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<PropertyInfo> *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 cdc1f678e7..16a725010d 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<Token>& 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<Token>& 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<Token>& 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<String> *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 9455e677cf..36f5bd64c7 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 8f1d444185..f171b47e9c 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<PropertyInfo> *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 */ @@ -1098,6 +1093,7 @@ void VisualServerRaster::baked_light_set_octree(RID p_baked_light,const DVector< baked_light->data.octree_steps=decode_uint32(&r[16]); baked_light->data.octree_tex_pixel_size.x=1.0/tex_w; baked_light->data.octree_tex_pixel_size.y=1.0/tex_h; + baked_light->data.texture_multiplier=decode_uint32(&r[20]); baked_light->octree_aabb.pos.x=decode_float(&r[32]); diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index ddc30bb2ee..0368780bfb 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<PropertyInfo> *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 f807a4b3a9..d577ca0c59 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<PropertyInfo>*); /*virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *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 d2b55092d6..8dfcb186a9 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 fa4090d39e..9cad173903 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<PropertyInfo> *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/collada/collada.cpp b/tools/collada/collada.cpp index 0d02c32d00..9962eed1b2 100644 --- a/tools/collada/collada.cpp +++ b/tools/collada/collada.cpp @@ -378,6 +378,8 @@ void Collada::_parse_material(XMLParser& parser) { Material material; String id=parser.get_attribute_value("id"); + if (parser.has_attribute("name")) + material.name=parser.get_attribute_value("name"); if (state.version<State::Version(1,4,0)) { /* <1.4 */ @@ -775,9 +777,12 @@ void Collada::_parse_effect(XMLParser& parser) { String id=parser.get_attribute_value("id"); Effect effect; + if (parser.has_attribute("name")) + effect.name=parser.get_attribute_value("name"); _parse_effect_material(parser,effect,id); + state.effect_map[id]=effect; COLLADA_PRINT("Effect ID:"+id); diff --git a/tools/collada/collada.h b/tools/collada/collada.h index f54e8a59ff..69ed05beba 100644 --- a/tools/collada/collada.h +++ b/tools/collada/collada.h @@ -53,12 +53,14 @@ public: struct Material { + String name; String instance_effect; }; struct Effect { + String name; Map<String, Variant> params; struct Channel { diff --git a/tools/doc/doc_data.cpp b/tools/doc/doc_data.cpp index 35f1140644..319c1ad8b7 100644 --- a/tools/doc/doc_data.cpp +++ b/tools/doc/doc_data.cpp @@ -34,6 +34,7 @@ #include "script_language.h" #include "io/marshalls.h" #include "io/compression.h" +#include "scene/resources/theme.h" void DocData::merge_from(const DocData& p_data) { @@ -111,6 +112,21 @@ void DocData::merge_from(const DocData& p_data) { } } + for(int i=0;i<c.theme_properties.size();i++) { + + PropertyDoc &p = c.theme_properties[i]; + + for(int j=0;j<cf.theme_properties.size();j++) { + + if (cf.theme_properties[j].name!=p.name) + continue; + const PropertyDoc &pf = cf.theme_properties[j]; + + p.description=pf.description; + break; + } + } + } } @@ -334,6 +350,60 @@ void DocData::generate(bool p_basic_types) { c.constants.push_back(constant); } + //theme stuff + + { + List<StringName> l; + Theme::get_default()->get_constant_list(cname,&l); + for (List<StringName>::Element*E=l.front();E;E=E->next()) { + + PropertyDoc pd; + pd.name=E->get(); + pd.type="int"; + c.theme_properties.push_back(pd); + } + + l.clear(); + Theme::get_default()->get_color_list(cname,&l); + for (List<StringName>::Element*E=l.front();E;E=E->next()) { + + PropertyDoc pd; + pd.name=E->get(); + pd.type="Color"; + c.theme_properties.push_back(pd); + } + + l.clear(); + Theme::get_default()->get_icon_list(cname,&l); + for (List<StringName>::Element*E=l.front();E;E=E->next()) { + + PropertyDoc pd; + pd.name=E->get(); + pd.type="Texture"; + c.theme_properties.push_back(pd); + } + l.clear(); + Theme::get_default()->get_font_list(cname,&l); + for (List<StringName>::Element*E=l.front();E;E=E->next()) { + + PropertyDoc pd; + pd.name=E->get(); + pd.type="Font"; + c.theme_properties.push_back(pd); + } + l.clear(); + Theme::get_default()->get_stylebox_list(cname,&l); + for (List<StringName>::Element*E=l.front();E;E=E->next()) { + + PropertyDoc pd; + pd.name=E->get(); + pd.type="StyleBox"; + c.theme_properties.push_back(pd); + } + + } + + classes.pop_front(); } @@ -714,6 +784,35 @@ Error DocData::_load(Ref<XMLParser> parser) { break; //end of <constants> } + } else if (name=="theme_items") { + + while(parser->read()==OK) { + + if (parser->get_node_type() == XMLParser::NODE_ELEMENT) { + + String name = parser->get_node_name(); + + if (name=="theme_item") { + + PropertyDoc prop; + + ERR_FAIL_COND_V(!parser->has_attribute("name"),ERR_FILE_CORRUPT); + prop.name=parser->get_attribute_value("name"); + ERR_FAIL_COND_V(!parser->has_attribute("type"),ERR_FILE_CORRUPT); + prop.type=parser->get_attribute_value("type"); + parser->read(); + if (parser->get_node_type()==XMLParser::NODE_TEXT) + prop.description=parser->get_node_data().strip_edges(); + c.theme_properties.push_back(prop); + } else { + ERR_EXPLAIN("Invalid tag in doc file: "+name); + ERR_FAIL_V(ERR_FILE_CORRUPT); + } + + } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name()=="members") + break; //end of <constants> + } + } else if (name=="constants") { while(parser->read()==OK) { @@ -897,7 +996,20 @@ Error DocData::save(const String& p_path) { } _write_string(f,1,"</constants>"); - _write_string(f,0,"</class>"); + + _write_string(f,1,"<theme_items>"); + if (c.theme_properties.size()) { + for(int i=0;i<c.theme_properties.size();i++) { + + + PropertyDoc &p=c.theme_properties[i]; + _write_string(f,2,"<theme_item name=\""+p.name+"\" type=\""+p.type+"\">"); + _write_string(f,2,"</theme_item>"); + + } + } + + _write_string(f,0,"</theme_items>"); } diff --git a/tools/doc/doc_data.h b/tools/doc/doc_data.h index 59d6958aa5..018bd67aaf 100644 --- a/tools/doc/doc_data.h +++ b/tools/doc/doc_data.h @@ -77,6 +77,7 @@ public: Vector<MethodDoc> signals; Vector<ConstantDoc> constants; Vector<PropertyDoc> properties; + Vector<PropertyDoc> theme_properties; }; diff --git a/tools/editor/code_editor.cpp b/tools/editor/code_editor.cpp index d86e48f74e..281415e4b7 100644 --- a/tools/editor/code_editor.cpp +++ b/tools/editor/code_editor.cpp @@ -102,12 +102,21 @@ void FindReplaceDialog::popup_replace() { bool do_selection=(text_edit->is_selection_active() && text_edit->get_selection_from_line() < text_edit->get_selection_to_line()); set_replace_selection_only(do_selection); + if (!do_selection && text_edit->is_selection_active()) { + search_text->set_text(text_edit->get_selection_text()); + } + replace_mc->show(); replace_label->show(); replace_vb->show(); popup_centered(Point2(300,300)); - search_text->grab_focus(); - search_text->select_all(); + if (search_text->get_text()!="" && replace_text->get_text()=="") { + search_text->select(0,0); + replace_text->grab_focus(); + } else { + search_text->grab_focus(); + search_text->select_all(); + } error_label->set_text(""); if (prompt->is_pressed()) { @@ -372,7 +381,7 @@ void FindReplaceDialog::_bind_methods() { FindReplaceDialog::FindReplaceDialog() { - set_self_opacity(0.6); + set_self_opacity(0.8); VBoxContainer *vb = memnew( VBoxContainer ); add_child(vb); @@ -382,7 +391,7 @@ FindReplaceDialog::FindReplaceDialog() { search_text = memnew( LineEdit ); vb->add_margin_child("Search",search_text); search_text->connect("text_entered", this,"_search_text_entered"); - search_text->set_self_opacity(0.7); + //search_text->set_self_opacity(0.7); @@ -396,7 +405,7 @@ FindReplaceDialog::FindReplaceDialog() { replace_text->set_anchor( MARGIN_RIGHT, ANCHOR_END ); replace_text->set_begin( Point2(15,132) ); replace_text->set_end( Point2(15,135) ); - replace_text->set_self_opacity(0.7); + //replace_text->set_self_opacity(0.7); replace_mc->add_child(replace_text); diff --git a/tools/editor/editor_help.cpp b/tools/editor/editor_help.cpp index 0471d62d16..b7e708e360 100644 --- a/tools/editor/editor_help.cpp +++ b/tools/editor/editor_help.cpp @@ -168,6 +168,18 @@ void EditorHelpSearch::_update_search() { } } + for(int i=0;i<c.theme_properties.size();i++) { + + if (c.theme_properties[i].name.findn(term)!=-1) { + + TreeItem *item = search_options->create_item(root); + item->set_metadata(0,"class_theme_item:"+E->key()+":"+c.theme_properties[i].name); + item->set_text(0,E->key()+"."+c.theme_properties[i].name+" (Theme Item)"); + item->set_icon(0,cicon); + } + } + + } //same but descriptions @@ -666,7 +678,48 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v } + if (cd.theme_properties.size()) { + + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color")); + class_desc->push_font(doc_title_font); + class_desc->add_text("GUI Theme Items:"); + class_desc->pop(); + class_desc->pop(); + class_desc->add_newline(); + + class_desc->push_indent(1); + + //class_desc->add_newline(); + + for(int i=0;i<cd.theme_properties.size();i++) { + + theme_property_line[cd.theme_properties[i].name]=class_desc->get_line_count()-2; //gets overriden if description + class_desc->push_font(doc_code_font); + _add_type(cd.theme_properties[i].type); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/text_color")); + class_desc->add_text(" "+cd.theme_properties[i].name); + class_desc->pop(); + class_desc->pop(); + if (cd.theme_properties[i].description!="") { + class_desc->push_font(doc_font); + class_desc->add_text(" "); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/comment_color")); + class_desc->add_text(cd.theme_properties[i].description); + class_desc->pop(); + class_desc->pop(); + + } + + class_desc->add_newline(); + } + + class_desc->add_newline(); + class_desc->pop(); + + + } if (cd.signals.size()) { class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color")); @@ -905,6 +958,10 @@ void EditorHelp::_help_callback(const String& p_topic) { if (property_line.has(name)) line=property_line[name]; + } else if (what=="class_theme_item") { + + if (theme_property_line.has(name)) + line=theme_property_line[name]; } else if (what=="class_constant") { if (constant_line.has(name)) diff --git a/tools/editor/editor_help.h b/tools/editor/editor_help.h index 94a31ce902..1c2b704b98 100644 --- a/tools/editor/editor_help.h +++ b/tools/editor/editor_help.h @@ -107,6 +107,7 @@ class EditorHelp : public VBoxContainer { Map<String,int> method_line; Map<String,int> signal_line; Map<String,int> property_line; + Map<String,int> theme_property_line; Map<String,int> constant_line; int description_line; diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 27a5ddbeaf..a86cdbfeb5 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); @@ -2262,6 +2263,8 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { if (!E->get()->can_reload_from_file()) continue; + if (!FileAccess::exists(E->get()->get_path())) + continue; uint64_t mt = FileAccess::get_modified_time(E->get()->get_path()); if (mt!=E->get()->get_last_modified_time()) { E->get()->reload_from_file(); @@ -2727,10 +2730,10 @@ Error EditorNode::load_scene(const String& p_scene) { } */ set_edited_scene(new_scene); - scene_tree_dock->set_selected(new_scene); + _get_scene_metadata(); + scene_tree_dock->set_selected(new_scene, true); property_editor->edit(new_scene); scene_import_metadata = sdata->get_import_metadata(); - _get_scene_metadata(); editor_data.get_undo_redo().clear_history(); saved_version=editor_data.get_undo_redo().get_version(); @@ -3046,6 +3049,33 @@ void EditorNode::_load_error_notify(void* p_ud,const String& p_text) { } + +bool EditorNode::_find_scene_in_use(Node* p_node,const String& p_path) const { + + if (p_node->get_filename()==p_path) { + return true; + } + + for(int i=0;i<p_node->get_child_count();i++) { + + if (_find_scene_in_use(p_node->get_child(i),p_path)) { + return true; + } + } + + return false; +} + + +bool EditorNode::is_scene_in_use(const String& p_path) { + + Node *es = get_edited_scene(); + if (es) + return _find_scene_in_use(es,p_path); + return false; + +} + void EditorNode::register_editor_types() { ObjectTypeDB::register_type<EditorPlugin>(); @@ -3212,6 +3242,7 @@ Error EditorNode::export_platform(const String& p_platform, const String& p_path } + EditorNode::EditorNode() { EditorHelp::generate_doc(); //before any editor classes are crated diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index 8b481ac20a..2cec301cf6 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -398,6 +398,9 @@ class EditorNode : public Node { static Vector<EditorNodeInitCallback> _init_callbacks; + bool _find_scene_in_use(Node* p_node,const String& p_path) const; + + protected: void _notification(int p_what); static void _bind_methods(); @@ -485,6 +488,10 @@ public: static void progress_task_step_bg(const String& p_task,int p_step=-1); static void progress_end_task_bg(const String& p_task); + void save_scene(String p_file) { _save_scene(p_file); } + + bool is_scene_in_use(const String& p_path); + void scan_import_changes(); EditorNode(); ~EditorNode(); diff --git a/tools/editor/editor_reimport_dialog.cpp b/tools/editor/editor_reimport_dialog.cpp index 7136731846..034ac58a8e 100644 --- a/tools/editor/editor_reimport_dialog.cpp +++ b/tools/editor/editor_reimport_dialog.cpp @@ -42,6 +42,9 @@ void EditorReImportDialog::popup_reimport() { List<String> ril; EditorFileSystem::get_singleton()->get_changed_sources(&ril); + scene_must_save=false; + + TreeItem *root = tree->create_item(); for(List<String>::Element *E=ril.front();E;E=E->next()) { @@ -52,11 +55,34 @@ void EditorReImportDialog::popup_reimport() { item->set_tooltip(0,E->get()); item->set_checked(0,true); item->set_editable(0,true); - items.push_back(item); + + String name = E->get(); + + if (EditorFileSystem::get_singleton()->get_file_type(name)=="PackedScene" && EditorNode::get_singleton()->is_scene_in_use(name)) { + + scene_must_save=true; + } } + if (scene_must_save) { + if (EditorNode::get_singleton()->get_edited_scene() && EditorNode::get_singleton()->get_edited_scene()->get_filename()=="") { + + error->set_text("Current scene must be saved to re-import."); + error->popup_centered(Size2(250,100)); + get_ok()->set_text("Re-Import"); + get_ok()->set_disabled(true); + return; + + } + get_ok()->set_disabled(false); + get_ok()->set_text("Save & Re-Import"); + } else { + get_ok()->set_text("Re-Import"); + get_ok()->set_disabled(false); + } + popup_centered(Size2(600,400)); @@ -70,7 +96,17 @@ void EditorReImportDialog::ok_pressed() { error->popup_centered(Size2(250,100)); return; } + + + EditorProgress ep("reimport","Re-Importing",items.size()); + String reload_fname; + if (scene_must_save && EditorNode::get_singleton()->get_edited_scene()) { + reload_fname = EditorNode::get_singleton()->get_edited_scene()->get_filename(); + EditorNode::get_singleton()->save_scene(reload_fname); + EditorNode::get_singleton()->clear_scene(); + } + for(int i=0;i<items.size();i++) { String it = items[i]->get_metadata(0); @@ -87,6 +123,9 @@ void EditorReImportDialog::ok_pressed() { } } + if (reload_fname!="") { + EditorNode::get_singleton()->load_scene(reload_fname); + } EditorFileSystem::get_singleton()->scan_sources(); } @@ -100,5 +139,6 @@ EditorReImportDialog::EditorReImportDialog() { set_title("Re-Import Changed Resources"); error = memnew( AcceptDialog); add_child(error); + scene_must_save=false; } diff --git a/tools/editor/editor_reimport_dialog.h b/tools/editor/editor_reimport_dialog.h index fdb03cb70b..a5fac262fc 100644 --- a/tools/editor/editor_reimport_dialog.h +++ b/tools/editor/editor_reimport_dialog.h @@ -39,6 +39,7 @@ class EditorReImportDialog : public ConfirmationDialog { Tree *tree; Vector<TreeItem*> items; AcceptDialog *error; + bool scene_must_save; void ok_pressed(); public: diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp index 6cd6170bb6..a0f1626b03 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)); @@ -341,6 +341,11 @@ Error ColladaImport::_create_material(const String& p_target) { Ref<FixedMaterial> material= memnew( FixedMaterial ); + if (src_mat.name!="") + material->set_name(src_mat.name); + else if (effect.name!="") + material->set_name(effect.name); + // DIFFUSE if (effect.diffuse.texture!="") { @@ -425,6 +430,8 @@ Error ColladaImport::_create_material(const String& p_target) { material->set_parameter(FixedMaterial::PARAM_SPECULAR_EXP,effect.shininess); material->set_flag(Material::FLAG_DOUBLE_SIDED,effect.double_sided); + + material_cache[p_target]=material; return OK; } @@ -661,7 +668,7 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co const Collada::MeshData::Source *color_src=NULL; int color_ofs=0; - if (false && p.sources.has("COLOR")) { + if (p.sources.has("COLOR")) { String color_source_id = p.sources["COLOR"].source; color_ofs = p.sources["COLOR"].offset; diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp index 22a6543ab0..0b7ffd55f0 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp @@ -36,6 +36,8 @@ #include "io/resource_saver.h" #include "scene/3d/mesh_instance.h" #include "scene/3d/room_instance.h" +#include "scene/3d/body_shape.h" +#include "scene/3d/physics_body.h" #include "scene/3d/portal.h" #include "os/os.h" @@ -104,7 +106,9 @@ class EditorSceneImportDialog : public ConfirmationDialog { struct FlagInfo { int value; + const char *category; const char *text; + bool defval; }; static const FlagInfo scene_flag_names[]; @@ -169,7 +173,7 @@ public: static const char *anim_flag_names[]={ - "Detect Loop", + "Detect Loop (-loop,-cycle)", "Keep Value Tracks", "Optimize", NULL @@ -626,22 +630,24 @@ void EditorSceneImportDialog::_bind_methods() { const EditorSceneImportDialog::FlagInfo EditorSceneImportDialog::scene_flag_names[]={ - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_COLLISIONS,"Create Collisions (-col},-colonly)"}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_PORTALS,"Create Portals (-portal)"}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_ROOMS,"Create Rooms (-room)"}, - {EditorSceneImportPlugin::SCENE_FLAG_SIMPLIFY_ROOMS,"Simplify Rooms"}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_BILLBOARDS,"Create Billboards (-bb)"}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_IMPOSTORS,"Create Impostors (-imp:dist)"}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_LODS,"Create LODs (-lod:dist)"}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_CARS,"Create Cars (-car)"}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_WHEELS,"Create Car Wheels (-wheel)"}, - {EditorSceneImportPlugin::SCENE_FLAG_DETECT_ALPHA,"Set Alpha in Materials (-alpha)"}, - {EditorSceneImportPlugin::SCENE_FLAG_DETECT_VCOLOR,"Set Vert. Color in Materials (-vcol)"}, - {EditorSceneImportPlugin::SCENE_FLAG_REMOVE_NOIMP,"Remove Nodes (-noimp)"}, - {EditorSceneImportPlugin::SCENE_FLAG_IMPORT_ANIMATIONS,"Import Animations"}, - {EditorSceneImportPlugin::SCENE_FLAG_COMPRESS_GEOMETRY,"Compress Geometry"}, - {EditorSceneImportPlugin::SCENE_FLAG_GENERATE_TANGENT_ARRAYS,"Force Generation of Tangent Arrays"}, - {-1,NULL} + {EditorSceneImportPlugin::SCENE_FLAG_REMOVE_NOIMP,"Actions","Remove Nodes (-noimp)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_IMPORT_ANIMATIONS,"Actions","Import Animations",true}, + {EditorSceneImportPlugin::SCENE_FLAG_COMPRESS_GEOMETRY,"Actions","Compress Geometry",false}, + {EditorSceneImportPlugin::SCENE_FLAG_GENERATE_TANGENT_ARRAYS,"Actions","Force Generation of Tangent Arrays",false}, + {EditorSceneImportPlugin::SCENE_FLAG_DETECT_ALPHA,"Materials","Set Alpha in Materials (-alpha)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_DETECT_VCOLOR,"Materials","Set Vert. Color in Materials (-vcol)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES,"Actions","SRGB->Linear Of Diffuse Textures",false}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_COLLISIONS,"Create","Create Collisions (-col},-colonly)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_PORTALS,"Create","Create Portals (-portal)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_ROOMS,"Create","Create Rooms (-room)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_SIMPLIFY_ROOMS,"Create","Simplify Rooms",false}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_BILLBOARDS,"Create","Create Billboards (-bb)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_IMPOSTORS,"Create","Create Impostors (-imp:dist)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_LODS,"Create","Create LODs (-lod:dist)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_CARS,"Create","Create Cars (-car)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_WHEELS,"Create","Create Car Wheels (-wheel)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_NAVMESH,"Create","Create Navigation Meshes (-navmesh)",true}, + {-1,NULL,NULL,false} }; @@ -674,7 +680,7 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce import_choose->connect("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); @@ -717,19 +723,25 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce TreeItem *root = import_options->create_item(NULL); import_options->set_hide_root(true); - - - - TreeItem *importopts = import_options->create_item(root); - importopts->set_text(0,"Import:"); - const FlagInfo* fn=scene_flag_names; + Map<String,TreeItem*> categories; + while(fn->text) { - TreeItem *opt = import_options->create_item(importopts); + String cat = fn->category; + TreeItem *parent; + if (!categories.has(cat)) { + parent = import_options->create_item(root); + parent->set_text(0,cat); + categories[cat]=parent; + } else { + parent=categories[cat]; + } + + TreeItem *opt = import_options->create_item(parent); opt->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); - opt->set_checked(0,true); + opt->set_checked(0,fn->defval); opt->set_editable(0,true); opt->set_text(0,fn->text); opt->set_metadata(0,fn->value); @@ -875,7 +887,7 @@ static String _fixstr(const String& p_what,const String& p_str) { -void EditorSceneImportPlugin::_find_resources(const Variant& p_var,Set<Ref<ImageTexture> >& image_map) { +void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<ImageTexture>, bool> &image_map) { switch(p_var.get_type()) { @@ -885,9 +897,9 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var,Set<Ref<Image Ref<Resource> res = p_var; if (res.is_valid()) { - if (res->is_type("Texture")) { + if (res->is_type("Texture") && !image_map.has(res)) { - image_map.insert(res); + image_map.insert(res,false); } else { @@ -898,7 +910,17 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var,Set<Ref<Image for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { if (E->get().type==Variant::OBJECT || E->get().type==Variant::ARRAY || E->get().type==Variant::DICTIONARY) { - _find_resources(res->get(E->get().name),image_map); + if (E->get().type==Variant::OBJECT && res->cast_to<FixedMaterial>() && (E->get().name=="textures/diffuse" || E->get().name=="textures/detail" || E->get().name=="textures/emission")) { + + Ref<ImageTexture> tex =res->get(E->get().name); + if (tex.is_valid()) { + + image_map.insert(tex,true); + } + + } else { + _find_resources(res->get(E->get().name),image_map); + } } } @@ -938,7 +960,7 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var,Set<Ref<Image } -Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Set<Ref<ImageTexture> >& image_map) { +Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,bool >& image_map) { // children first.. for(int i=0;i<p_node->get_child_count();i++) { @@ -1002,7 +1024,7 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh> 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); } } @@ -1010,6 +1032,36 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh> } } + + if (p_flags&(SCENE_FLAG_DETECT_ALPHA|SCENE_FLAG_DETECT_VCOLOR) && p_node->cast_to<MeshInstance>()) { + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + Ref<Mesh> m = mi->get_mesh(); + + if (m.is_valid()) { + + for(int i=0;i<m->get_surface_count();i++) { + + Ref<FixedMaterial> mat = m->surface_get_material(i); + if (!mat.is_valid()) + continue; + + if (p_flags&SCENE_FLAG_DETECT_ALPHA && _teststr(mat->get_name(),"alpha")) { + + mat->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true); + mat->set_name(_fixstr(mat->get_name(),"alpha")); + } + if (p_flags&SCENE_FLAG_DETECT_VCOLOR && _teststr(mat->get_name(),"vcol")) { + + mat->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true); + mat->set_name(_fixstr(mat->get_name(),"vcol")); + } + + } + } + } + if (p_flags&SCENE_FLAG_REMOVE_NOIMP && p_node->cast_to<AnimationPlayer>()) { //remove animations referencing non-importable nodes AnimationPlayer *ap = p_node->cast_to<AnimationPlayer>(); @@ -1077,7 +1129,7 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh> 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); } } @@ -1141,21 +1193,42 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh> MeshInstance *mi = p_node->cast_to<MeshInstance>(); Node * col = mi->create_trimesh_collision_node(); - ERR_FAIL_COND_V(!col,NULL); + col->set_name(_fixstr(name,"colonly")); col->cast_to<Spatial>()->set_transform(mi->get_transform()); p_node->replace_by(col); memdelete(p_node); p_node=col; + StaticBody *sb = col->cast_to<StaticBody>(); + CollisionShape *colshape = memnew( CollisionShape); + colshape->set_shape(sb->get_shape(0)); + colshape->set_name("shape"); + sb->add_child(colshape); + colshape->set_owner(p_node->get_owner()); + + } else if (p_flags&SCENE_FLAG_CREATE_COLLISIONS &&_teststr(name,"col") && p_node->cast_to<MeshInstance>()) { MeshInstance *mi = p_node->cast_to<MeshInstance>(); mi->set_name(_fixstr(name,"col")); - mi->create_trimesh_collision(); + Node *col= mi->create_trimesh_collision_node(); + ERR_FAIL_COND_V(!col,NULL); + + col->set_name("col"); + p_node->add_child(col); + + + StaticBody *sb = col->cast_to<StaticBody>(); + CollisionShape *colshape = memnew( CollisionShape); + colshape->set_shape(sb->get_shape(0)); + colshape->set_name("shape"); + sb->add_child(colshape); + colshape->set_owner(p_node->get_owner()); + } else if (p_flags&SCENE_FLAG_CREATE_ROOMS && _teststr(name,"room") && p_node->cast_to<MeshInstance>()) { @@ -1346,92 +1419,153 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh> } - - return p_node; } -void EditorSceneImportPlugin::_merge_node(Node *p_node,Node*p_root,Node *p_existing,Set<Ref<Resource> >& checked_resources) { +void EditorSceneImportPlugin::_merge_existing_node(Node *p_node,Node *p_imported_scene,Set<Ref<Resource> >& checked_resources,Set<Node*> &checked_nodes) { - NodePath path = p_root->get_path_to(p_node); + NodePath path = p_node->get_import_path(); - bool valid=false; + if (!path.is_empty() && p_imported_scene->has_node(path)) { - if (p_existing->has_node(path)) { + Node *imported_node = p_imported_scene->get_node(path); - Node *existing = p_existing->get_node(path); - - if (existing->get_type()==p_node->get_type()) { + if (imported_node->get_type()==p_node->get_type()) { //same thing, check what it is - if (existing->get_type()=="MeshInstance") { + if (p_node->get_type()=="MeshInstance") { //merge mesh instance, this is a special case! - MeshInstance *mi_existing=existing->cast_to<MeshInstance>(); + MeshInstance *mi_imported=imported_node->cast_to<MeshInstance>(); MeshInstance *mi_node=p_node->cast_to<MeshInstance>(); - Ref<Mesh> mesh_existing = mi_existing->get_mesh(); + Ref<Mesh> mesh_imported = mi_imported->get_mesh(); Ref<Mesh> mesh_node = mi_node->get_mesh(); - if (mesh_existing.is_null() || checked_resources.has(mesh_node)) { - - if (mesh_node.is_valid()) - mi_existing->set_mesh(mesh_node); - } else if (mesh_node.is_valid()) { + if (mesh_node.is_null() && mesh_imported.is_valid()) { - //mesh will always be overwritten, so check materials from original + mi_node->set_mesh(mesh_imported); - for(int i=0;i<mesh_node->get_surface_count();i++) { + } else if (mesh_node.is_valid() && mesh_imported.is_valid()) { - String name = mesh_node->surface_get_name(i); + if (checked_resources.has(mesh_imported)) { - if (name!="") { + mi_node->set_mesh(mesh_imported); + } else { + //mix up meshes + //import new geometry but keep materials + for(int i=0;i<mesh_imported->get_surface_count();i++) { - for(int j=0;j<mesh_existing->get_surface_count();j++) { + String name = mesh_imported->surface_get_name(i); - Ref<Material> keep; + for(int j=0;j<mesh_node->get_surface_count();j++) { - if (name==mesh_existing->surface_get_name(j)) { + Ref<Material> mat = mesh_node->surface_get_material(j); + if (mat.is_valid() && mesh_node->surface_get_name(j)==name ) { - Ref<Material> mat = mesh_existing->surface_get_material(j); - - if (mat.is_valid()) { - if (mat->get_path()!="" && mat->get_path().begins_with("res://") && mat->get_path().find("::")==-1) { - keep=mat; //mat was loaded from file - } else if (mat->is_edited()) { - keep=mat; //mat was edited - } - } + mesh_imported->surface_set_material(i,mat); break; } - if (keep.is_valid()) - mesh_node->surface_set_material(i,keep); //kept } } + // was imported, do nothing further + checked_resources.insert(mesh_imported); + mi_node->set_mesh(mesh_imported); } - mi_existing->set_mesh(mesh_node); //always overwrite mesh - checked_resources.insert(mesh_node); + } + } else if (p_node->get_type()=="Path") { + //for paths, overwrite path + Path *path_imported =imported_node->cast_to<Path>(); + Path *path_node =p_node->cast_to<Path>(); + + if (path_imported->get_curve().is_valid()) { + path_node->set_curve(path_imported->get_curve()); } - } else if (existing->get_type()=="Path") { + } else if (p_node->get_type()=="Portal") { + //for paths, overwrite path - Path *path_existing =existing->cast_to<Path>(); - Path *path_node =p_node->cast_to<Path>(); + Portal *portal_imported =imported_node->cast_to<Portal>(); + Portal *portal_node =p_node->cast_to<Portal>(); - if (path_node->get_curve().is_valid()) { + portal_node->set_shape( portal_imported->get_shape() ); - if (!path_existing->get_curve().is_valid() || !path_existing->get_curve()->is_edited()) { - path_existing->set_curve(path_node->get_curve()); - } + } else if (p_node->get_type()=="Room") { + //for paths, overwrite path + + Room *room_imported =imported_node->cast_to<Room>(); + Room *room_node =p_node->cast_to<Room>(); + + 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 *skeleton_node =p_node->cast_to<Skeleton>(); + + //use imported bones, obviously + skeleton_node->clear_bones(); + for(int i=0;i<skeleton_imported->get_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>(); + AnimationPlayer *aplayer_node =p_node->cast_to<AnimationPlayer>(); + + //use imported bones, obviously + List<StringName> anims; + aplayer_imported->get_animation_list(&anims); + //use imported animations, could merge some stuff though + for (List<StringName>::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 + + CollisionShape *collision_imported =imported_node->cast_to<CollisionShape>(); + CollisionShape *collision_node =p_node->cast_to<CollisionShape>(); + + collision_node->set_shape( collision_imported->get_shape() ); } } - valid=true; - } else { + if (p_node->cast_to<Spatial>() && imported_node->cast_to<Spatial>()) { + //apply transform if changed + Spatial *snode = p_node->cast_to<Spatial>(); + Spatial *simp = imported_node->cast_to<Spatial>(); + + if (snode->get_import_transform() == snode->get_transform()) { + //not moved, apply new + snode->set_import_transform(simp->get_transform()); + snode->set_transform(simp->get_transform()); + } else if (snode->get_import_transform() == simp->get_import_transform()) { + //do nothing, nothing changed keep local changes + } else { + //changed both, imported and edited, merge + Transform local_xform = snode->get_import_transform().affine_inverse() * snode->get_transform(); + snode->set_import_transform(simp->get_import_transform()); + snode->set_transform(simp->get_import_transform() * local_xform); + } + } + + checked_nodes.insert(imported_node); + + } +#if 0 + else { if (p_node!=p_root && p_existing->has_node(p_root->get_path_to(p_node->get_parent()))) { @@ -1461,25 +1595,76 @@ void EditorSceneImportPlugin::_merge_node(Node *p_node,Node*p_root,Node *p_exist } } +#endif + + for(int i=0;i<p_node->get_child_count();i++) { + _merge_existing_node(p_node->get_child(i),p_imported_scene,checked_resources,checked_nodes); + } +} + + +void EditorSceneImportPlugin::_add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Set<Node*> &checked_nodes) { + + + for(int i=0;i<p_imported->get_child_count();i++) { + + + Node *imported_node = p_imported->get_child(i); + + if (imported_node->get_owner()!=p_imported_scene) + continue; //end of the road + + Vector<StringName> nn; + nn.push_back(imported_node->get_name()); + NodePath imported_path(nn,false); + + if (!p_node->has_node(imported_path) && !checked_nodes.has(imported_node)) { + //not there, re-add it + //add it.. because not existing in existing scene + Object *o = ObjectTypeDB::instance(imported_node->get_type()); + Node *n=NULL; + if (o) + n=o->cast_to<Node>(); + + if (n) { + + List<PropertyInfo> pl; + imported_node->get_property_list(&pl); + for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { + if (!(E->get().usage&PROPERTY_USAGE_STORAGE)) + continue; + n->set( E->get().name, imported_node->get(E->get().name) ); + } + + p_node->add_child(n); + } + + } + + if (p_node->has_node(imported_path)) { - if (valid) { + Node *other_node = p_node->get_node(imported_path); + + _add_new_nodes(other_node,imported_node,p_imported_scene,checked_nodes); - for(int i=0;i<p_node->get_child_count();i++) { - _merge_node(p_node->get_child(i),p_root,p_existing,checked_resources); } - } + } } -void EditorSceneImportPlugin::_merge_scenes(Node *p_existing,Node *p_new) { +void EditorSceneImportPlugin::_merge_scenes(Node *p_node,Node *p_imported) { Set<Ref<Resource> > checked_resources; - _merge_node(p_new,p_new,p_existing,checked_resources); - + Set<Node*> checked_nodes; + _merge_existing_node(p_node,p_imported,checked_resources,checked_nodes); + _add_new_nodes(p_node,p_imported,p_imported,checked_nodes); + //add existing.. ? } + + #if 0 Error EditorImport::import_scene(const String& p_path,const String& p_dest_path,const String& p_resource_path,uint32_t p_flags,ImageFormat p_image_format,ImageCompression p_image_compression,uint32_t p_image_flags,float p_quality,uint32_t animation_flags,Node **r_scene,Ref<EditorPostImport> p_post_import) { @@ -1488,6 +1673,26 @@ Error EditorImport::import_scene(const String& p_path,const String& p_dest_path, } #endif +void EditorSceneImportPlugin::_tag_import_paths(Node *p_scene,Node *p_node) { + + if (p_scene!=p_node && p_node->get_owner()!=p_scene) + return; + + NodePath path = p_scene->get_path_to(p_node); + p_node->set_import_path( path ); + + Spatial *snode=p_node->cast_to<Spatial>(); + + if (snode) { + + snode->set_import_transform(snode->get_transform()); + } + + for(int i=0;i<p_node->get_child_count();i++) { + _tag_import_paths(p_scene,p_node->get_child(i)); + } + +} Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from,Node**r_node,List<String> *r_missing) { @@ -1549,6 +1754,8 @@ Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from return err; } + _tag_import_paths(scene,scene); + *r_node=scene; return OK; } @@ -1566,6 +1773,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c bool merge = !bool(from->get_option("reimport")); + from->set_source_md5(0,FileAccess::get_md5(src_path)); from->set_editor(get_name()); @@ -1576,7 +1784,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c Ref<ResourceImportMetadata> imd = memnew(ResourceImportMetadata); - Set< Ref<ImageTexture> > imagemap; + Map< Ref<ImageTexture>,bool > imagemap; scene=_fix_node(scene,scene,collision_map,scene_flags,imagemap); @@ -1622,12 +1830,12 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c int image_flags = from->get_option("texture_flags"); float image_quality = from->get_option("texture_quality"); - for (Set< Ref<ImageTexture> >::Element *E=imagemap.front();E;E=E->next()) { + for (Map< Ref<ImageTexture>,bool >::Element *E=imagemap.front();E;E=E->next()) { //texture could be converted to something more useful for 3D, that could load individual mipmaps and stuff //but not yet.. - Ref<ImageTexture> texture = E->get(); + Ref<ImageTexture> texture = E->key(); ERR_CONTINUE(!texture.is_valid()); @@ -1657,7 +1865,10 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); print_line("flags: "+itos(image_flags)); - imd->set_option("flags",image_flags); + uint32_t flags = image_flags; + if (E->get()) + flags|=EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_TO_LINEAR; + imd->set_option("flags",flags); imd->set_option("format",image_format); imd->set_option("quality",image_quality); imd->set_option("atlas",false); @@ -1697,11 +1908,14 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c if (merge) { + progress.step("Merging..",103); - FileAccess *fa = FileAccess::create(FileAccess::ACCESS_FILESYSTEM); + FileAccess *fa = FileAccess::create(FileAccess::ACCESS_RESOURCES); + if (fa->file_exists(p_dest_path)) { + //try to merge Ref<PackedScene> s = ResourceLoader::load(p_dest_path); @@ -1711,7 +1925,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c if (existing) { - _merge_scenes(scene,existing); + _merge_scenes(existing,scene); memdelete(scene); scene=existing; @@ -1732,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/io_plugins/editor_scene_import_plugin.h b/tools/editor/io_plugins/editor_scene_import_plugin.h index 9e08f8371b..928fff2afb 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.h +++ b/tools/editor/io_plugins/editor_scene_import_plugin.h @@ -99,11 +99,14 @@ class EditorSceneImportPlugin : public EditorImportPlugin { Vector<Ref<EditorSceneImporter> > importers; - void _find_resources(const Variant& p_var,Set<Ref<ImageTexture> >& image_map); - Node* _fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Set<Ref<ImageTexture> >& image_map); - void _merge_node(Node *p_node,Node*p_root,Node *p_existing,Set<Ref<Resource> >& checked_resources); - void _merge_scenes(Node *p_existing,Node *p_new); + void _find_resources(const Variant& p_var,Map<Ref<ImageTexture>,bool >& image_map); + Node* _fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,bool >& image_map); + void _merge_existing_node(Node *p_node,Node *p_imported_scene,Set<Ref<Resource> >& checked_resources,Set<Node*> &checked_nodes); + void _add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Set<Node*> &checked_nodes); + void _merge_scenes(Node *p_node, Node *p_imported); + + void _tag_import_paths(Node *p_scene,Node *p_node); public: @@ -120,11 +123,13 @@ public: SCENE_FLAG_CREATE_WHEELS=1<<9, SCENE_FLAG_DETECT_ALPHA=1<<15, SCENE_FLAG_DETECT_VCOLOR=1<<16, + SCENE_FLAG_CREATE_NAVMESH=1<<17, SCENE_FLAG_REMOVE_NOIMP=1<<24, SCENE_FLAG_IMPORT_ANIMATIONS=1<<25, SCENE_FLAG_COMPRESS_GEOMETRY=1<<26, SCENE_FLAG_GENERATE_TANGENT_ARRAYS=1<<27, + SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES=1<<28, }; diff --git a/tools/editor/plugins/baked_light_baker.cpp b/tools/editor/plugins/baked_light_baker.cpp index 36948673a8..1fa4d8d06c 100644 --- a/tools/editor/plugins/baked_light_baker.cpp +++ b/tools/editor/plugins/baked_light_baker.cpp @@ -1498,11 +1498,16 @@ void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) { w[i+3]=0xFF; } + float multiplier=1.0; + + if (baked_light->get_format()==BakedLight::FORMAT_HDR8) + multiplier=8; encode_uint32(baked_octree_texture_w,&w[0]); encode_uint32(baked_octree_texture_h,&w[4]); encode_uint32(0,&w[8]); encode_float(1<<lattice_size,&w[12]); encode_uint32(octree_depth-lattice_size,&w[16]); + encode_uint32(multiplier,&w[20]); encode_float(octree_aabb.pos.x,&w[32]); encode_float(octree_aabb.pos.y,&w[36]); @@ -1538,6 +1543,7 @@ void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) { const double *normptr=norm_arr.ptr(); int lz=lights.size(); + mult/=multiplier; for(int i=0;i<octant_count;i++) { diff --git a/tools/editor/plugins/baked_light_editor_plugin.cpp b/tools/editor/plugins/baked_light_editor_plugin.cpp index 71f9671fd9..a1383f22fe 100644 --- a/tools/editor/plugins/baked_light_editor_plugin.cpp +++ b/tools/editor/plugins/baked_light_editor_plugin.cpp @@ -125,6 +125,8 @@ void BakedLightEditor::_notification(int p_option) { print_line("MSUPDATE: "+itos(OS::get_singleton()->get_ticks_msec()-t)); t=OS::get_singleton()->get_ticks_msec(); node->get_baked_light()->set_octree(octree_texture); + node->get_baked_light()->set_edited(true); + print_line("MSSET: "+itos(OS::get_singleton()->get_ticks_msec()-t)); diff --git a/tools/editor/plugins/shader_editor_plugin.cpp b/tools/editor/plugins/shader_editor_plugin.cpp index 9b6b07dc2e..73b6265819 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<Shader>& 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<Shader>& 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 8d5f2dae42..49caee5da6 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/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp index 2e3632f18f..1bf425f3f3 100644 --- a/tools/editor/plugins/spatial_editor_plugin.cpp +++ b/tools/editor/plugins/spatial_editor_plugin.cpp @@ -1166,7 +1166,6 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) { Transform r; r.basis.scale(Vector3(scale,scale,scale)); - List<Node*> &selection = editor_selection->get_selected_node_list(); for(List<Node*>::Element *E=selection.front();E;E=E->next()) { @@ -1519,7 +1518,13 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) { } break; case KEY_F: { - _menu_option(VIEW_CENTER_TO_SELECTION); + + if (k.pressed && k.mod.shift && k.mod.control) { + _menu_option(VIEW_ALIGN_SELECTION_WITH_VIEW); + } else if (k.pressed) { + _menu_option(VIEW_CENTER_TO_SELECTION); + } + } break; case KEY_SPACE: { @@ -1818,6 +1823,34 @@ void SpatialEditorViewport::_menu_option(int p_option) { cursor.pos=center; } break; + case VIEW_ALIGN_SELECTION_WITH_VIEW: { + + if (!get_selected_count()) + break; + + Transform camera_transform = camera->get_global_transform(); + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + undo_redo->create_action("Align with view"); + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Spatial *sp = E->get()->cast_to<Spatial>(); + if (!sp) + continue; + + SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); + if (!se) + continue; + + Vector3 original_scale = sp->get_scale(); + sp->set_global_transform(camera_transform); + sp->set_scale(original_scale); + undo_redo->add_do_method(sp,"set_global_transform",sp->get_global_transform()); + undo_redo->add_undo_method(sp,"set_global_transform",se->original); + } + undo_redo->commit_action(); + } break; case VIEW_ENVIRONMENT: { int idx = view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT); @@ -2060,7 +2093,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed view_menu->get_popup()->add_check_item("Environment",VIEW_ENVIRONMENT); view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT),true); view_menu->get_popup()->add_separator(); - view_menu->get_popup()->add_item("Selection",VIEW_CENTER_TO_SELECTION); + view_menu->get_popup()->add_item("Selection (F)",VIEW_CENTER_TO_SELECTION); + view_menu->get_popup()->add_item("Align with view (Ctrl+Shift+F)",VIEW_ALIGN_SELECTION_WITH_VIEW); view_menu->get_popup()->connect("item_pressed",this,"_menu_option"); preview_camera = memnew( Button ); diff --git a/tools/editor/plugins/spatial_editor_plugin.h b/tools/editor/plugins/spatial_editor_plugin.h index 4bc3b553ef..29719cb80c 100644 --- a/tools/editor/plugins/spatial_editor_plugin.h +++ b/tools/editor/plugins/spatial_editor_plugin.h @@ -75,6 +75,7 @@ class SpatialEditorViewport : public Control { VIEW_FRONT, VIEW_REAR, VIEW_CENTER_TO_SELECTION, + VIEW_ALIGN_SELECTION_WITH_VIEW, VIEW_PERSPECTIVE, VIEW_ENVIRONMENT, VIEW_ORTHOGONAL diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index 5983a5c32d..cd28c6da97 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -442,7 +442,7 @@ void ProjectManager::_favorite_pressed(Node *p_hb) { EditorSettings::get_singleton()->erase("favorite_projects/"+clicked); } EditorSettings::get_singleton()->save(); - _load_recent_projects(); + call_deferred("_load_recent_projects"); } diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index 2197902933..4ac2ff0594 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -1828,6 +1828,13 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p if (obj->get( p_name ).get_type() == Variant::NIL || obj->get( p_name ).operator RefPtr().is_null()) { p_item->set_text(1,"<null>"); + Dictionary d = p_item->get_metadata(0); + int hint=d.has("hint")?d["hint"].operator int():-1; + String hint_text=d.has("hint_text")?d["hint_text"]:""; + if (hint==PROPERTY_HINT_RESOURCE_TYPE && hint_text == "Texture") { + p_item->set_icon(1,NULL); + } + } else { RES res = obj->get( p_name ).operator RefPtr(); if (res->is_type("Texture")) { diff --git a/tools/editor/resources_dock.cpp b/tools/editor/resources_dock.cpp index eb2e526d71..a05fe425b3 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<Resource>& 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!"); @@ -224,6 +224,7 @@ void ResourcesDock::_file_action(const String& p_path) { save_resource(p_path,res); + _update_name(ti); } break; diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index c81374259e..c4c3a10f74 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -1038,9 +1038,9 @@ void SceneTreeDock::set_edited_scene(Node* p_scene) { edited_scene=p_scene; } -void SceneTreeDock::set_selected(Node *p_node) { +void SceneTreeDock::set_selected(Node *p_node, bool p_emit_selected ) { - scene_tree->set_selected(p_node,false); + scene_tree->set_selected(p_node,p_emit_selected); _update_tool_buttons(); } diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h index 143c49f658..99ef16e6f6 100644 --- a/tools/editor/scene_tree_dock.h +++ b/tools/editor/scene_tree_dock.h @@ -127,7 +127,7 @@ public: void import_subscene(); void set_edited_scene(Node* p_scene); Node* instance(const String& p_path); - void set_selected(Node *p_node); + void set_selected(Node *p_node, bool p_emit_selected=false); void fill_path_renames(Node* p_node, Node *p_new_parent, List<Pair<NodePath,NodePath> > *p_renames); void perform_node_renames(Node* p_base,List<Pair<NodePath,NodePath> > *p_renames, Map<Ref<Animation>, Set<int> > *r_rem_anims=NULL); diff --git a/tools/editor/scenes_dock.cpp b/tools/editor/scenes_dock.cpp index bc0d48367a..a23c9cead7 100644 --- a/tools/editor/scenes_dock.cpp +++ b/tools/editor/scenes_dock.cpp @@ -38,7 +38,7 @@ bool ScenesDock::_create_tree(TreeItem *p_parent,EditorFileSystemDirectory *p_dir) { String search_term = tree_filter->get_search_term(); - String file_filter = tree_filter->get_file_filter(); + ScenesDockFilter::FilterOption file_filter = tree_filter->get_file_filter(); TreeItem *item = tree->create_item(p_parent); item->set_text(0,p_dir->get_name()+"/"); @@ -56,15 +56,19 @@ bool ScenesDock::_create_tree(TreeItem *p_parent,EditorFileSystemDirectory *p_di for (int i=0;i<p_dir->get_file_count();i++) { String file_name = p_dir->get_file(i); - String extension = file_name.extension(); + String file_path = p_dir->get_file_path(i); - if (search_term!="" && file_name.findn(search_term)==-1) - continue; + // ScenesDockFilter::FILTER_PATH + String search_from = file_path.right(6); // trim "res://" + if (file_filter == ScenesDockFilter::FILTER_NAME) + search_from = file_name; + else if (file_filter == ScenesDockFilter::FILTER_FOLDER) + search_from = file_path.right(6).get_base_dir(); - if (file_filter!="*" && extension != file_filter ) + if (search_term!="" && search_from.findn(search_term)==-1) continue; - bool isfave = favorites.has(p_dir->get_file_path(i)); + bool isfave = favorites.has(file_path); if (button_favorite->is_pressed() && !isfave) continue; @@ -78,7 +82,7 @@ bool ScenesDock::_create_tree(TreeItem *p_parent,EditorFileSystemDirectory *p_di fitem->set_icon(0, icon ); - fitem->set_metadata(0,p_dir->get_file_path(i)); + fitem->set_metadata(0,file_path); //if (p_dir->files[i]->icon.is_valid()) { // fitem->set_icon(0,p_dir->files[i]->icon); // } @@ -289,7 +293,7 @@ ScenesDock::ScenesDock(EditorNode *p_editor) { toolbar_hbc->add_child(button_instance); tree = memnew( Tree ); - tree_filter=memnew( ScenesDockFilter(tree) ); + tree_filter=memnew( ScenesDockFilter() ); tree_filter->connect("filter_changed", this, "_update_tree"); add_child(tree_filter); add_child(tree); @@ -314,8 +318,11 @@ ScenesDock::~ScenesDock() { void ScenesDockFilter::_setup_filters() { - file_filter->clear(); - + filter_option->clear(); + filter_option->add_item("Path"); + filter_option->add_item("Name"); + filter_option->add_item("Folder"); +#if 0 List<String> extensions; ResourceLoader::get_recognized_extensions_for_type("",&extensions); @@ -336,6 +343,7 @@ void ScenesDockFilter::_setup_filters() { else file_filter->add_item("( "+flt+" )"); } +#endif } void ScenesDockFilter::_command(int p_command) { @@ -358,18 +366,26 @@ String ScenesDockFilter::get_search_term() { return search_box->get_text().strip_edges(); } -String ScenesDockFilter::get_file_filter() { +ScenesDockFilter::FilterOption ScenesDockFilter::get_file_filter() { return _current_filter; } void ScenesDockFilter::_file_filter_selected(int p_idx) { - String selected = filters[file_filter->get_selected()]; + FilterOption selected = (FilterOption)(filter_option->get_selected()); if (_current_filter != selected ) { _current_filter = selected; emit_signal("filter_changed"); } } +void ScenesDockFilter::_notification(int p_what) { + switch(p_what) { + case NOTIFICATION_ENTER_SCENE: { + clear_search_button->set_icon(get_icon("CloseHover","EditorIcons")); + } break; + } +} + void ScenesDockFilter::_bind_methods() { ObjectTypeDB::bind_method(_MD("_command"),&ScenesDockFilter::_command); @@ -379,17 +395,15 @@ void ScenesDockFilter::_bind_methods() { ADD_SIGNAL( MethodInfo("filter_changed") ); } -ScenesDockFilter::ScenesDockFilter(Tree *p_tree) { - - _current_filter = "*"; +ScenesDockFilter::ScenesDockFilter() { - tree = p_tree; + _current_filter = FILTER_PATH; - file_filter = memnew( OptionButton ); - file_filter->set_custom_minimum_size(Size2(90,10)); - file_filter->set_clip_text(true); - file_filter->connect("item_selected", this, "_file_filter_selected"); - add_child(file_filter); + filter_option = memnew( OptionButton ); + filter_option->set_custom_minimum_size(Size2(60,10)); + filter_option->set_clip_text(true); + filter_option->connect("item_selected", this, "_file_filter_selected"); + add_child(filter_option); _setup_filters(); @@ -398,8 +412,7 @@ ScenesDockFilter::ScenesDockFilter(Tree *p_tree) { search_box->set_h_size_flags(SIZE_EXPAND_FILL); add_child(search_box); - clear_search_button = memnew( Button ); - clear_search_button->set_text("clear"); + clear_search_button = memnew( ToolButton ); clear_search_button->connect("pressed",this,"_command",make_binds(CMD_CLEAR_FILTER)); add_child(clear_search_button); diff --git a/tools/editor/scenes_dock.h b/tools/editor/scenes_dock.h index cf48e2885f..9849f5ace0 100644 --- a/tools/editor/scenes_dock.h +++ b/tools/editor/scenes_dock.h @@ -33,7 +33,7 @@ #include "scene/gui/control.h" #include "scene/gui/tree.h" #include "scene/gui/label.h" -#include "scene/gui/button.h" +#include "scene/gui/tool_button.h" #include "scene/gui/option_button.h" #include "scene/gui/box_container.h" #include "os/dir_access.h" @@ -86,17 +86,25 @@ class ScenesDockFilter : public HBoxContainer { OBJ_TYPE( ScenesDockFilter, HBoxContainer ); +private: + friend class ScenesDock; + enum Command { CMD_CLEAR_FILTER, }; Tree *tree; - OptionButton *file_filter; + OptionButton *filter_option; LineEdit *search_box; - Button *clear_search_button; + ToolButton *clear_search_button; - String _current_filter; - Vector<String> filters; + enum FilterOption { + FILTER_PATH, // NAME or Folder + FILTER_NAME, + FILTER_FOLDER, + }; + FilterOption _current_filter; + //Vector<String> filters; void _command(int p_command); void _search_text_changed(const String& p_newtext); @@ -104,12 +112,13 @@ class ScenesDockFilter : public HBoxContainer { void _file_filter_selected(int p_idx); protected: + void _notification(int p_what); static void _bind_methods(); public: String get_search_term(); - String get_file_filter(); - ScenesDockFilter(Tree *p_tree); + FilterOption get_file_filter(); + ScenesDockFilter(); }; #endif // SCENES_DOCK_H diff --git a/tools/editor/spatial_editor_gizmos.cpp b/tools/editor/spatial_editor_gizmos.cpp index 71a5ae3d3c..83efb48bd3 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<FixedMaterial>( 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<FixedMaterial>( 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<FixedMaterial>( 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<FixedMaterial>( 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<FixedMaterial>( 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"));
|