Merge branch 'master' of github.com:okamstudio/godot

This commit is contained in:
Anton Yabchinskiy 2015-04-04 09:31:21 +03:00
commit 16746f157f
251 changed files with 5290 additions and 986 deletions

View File

@ -519,12 +519,13 @@ bool test_28() {
char output_format[] = "\tTest:\t%ls => %ls (%s)\n";
String format, output;
Array args;
bool error;
// %%
format = "fish %% frog";
args.clear();
output = format.sprintf(args);
success = (output == String("fish % frog"));
output = format.sprintf(args, &error);
success = (output == String("fish % frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -534,8 +535,8 @@ bool test_28() {
format = "fish %d frog";
args.clear();
args.push_back(5);
output = format.sprintf(args);
success = (output == String("fish 5 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -543,8 +544,8 @@ bool test_28() {
format = "fish %05d frog";
args.clear();
args.push_back(5);
output = format.sprintf(args);
success = (output == String("fish 00005 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 00005 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -552,8 +553,8 @@ bool test_28() {
format = "fish %5d frog";
args.clear();
args.push_back(5);
output = format.sprintf(args);
success = (output == String("fish 5 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -561,8 +562,8 @@ bool test_28() {
format = "fish %-5d frog";
args.clear();
args.push_back(5);
output = format.sprintf(args);
success = (output == String("fish 5 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -570,8 +571,8 @@ bool test_28() {
format = "fish %+d frog";
args.clear();
args.push_back(5);
output = format.sprintf(args);
success = (output == String("fish +5 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish +5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -579,8 +580,8 @@ bool test_28() {
format = "fish %d frog";
args.clear();
args.push_back(-5);
output = format.sprintf(args);
success = (output == String("fish -5 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish -5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -588,8 +589,8 @@ bool test_28() {
format = "fish %x frog";
args.clear();
args.push_back(45);
output = format.sprintf(args);
success = (output == String("fish 2d frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 2d frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -597,8 +598,8 @@ bool test_28() {
format = "fish %X frog";
args.clear();
args.push_back(45);
output = format.sprintf(args);
success = (output == String("fish 2D frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 2D frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -606,8 +607,8 @@ bool test_28() {
format = "fish %o frog";
args.clear();
args.push_back(99);
output = format.sprintf(args);
success = (output == String("fish 143 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 143 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -617,8 +618,8 @@ bool test_28() {
format = "fish %f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args);
success = (output == String("fish 99.990000 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 99.990000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -626,8 +627,8 @@ bool test_28() {
format = "fish %11f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args);
success = (output == String("fish 99.990000 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 99.990000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -635,8 +636,8 @@ bool test_28() {
format = "fish %-11f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args);
success = (output == String("fish 99.990000 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 99.990000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -644,8 +645,8 @@ bool test_28() {
format = "fish %f frog";
args.clear();
args.push_back(99);
output = format.sprintf(args);
success = (output == String("fish 99.000000 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 99.000000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -653,8 +654,8 @@ bool test_28() {
format = "fish %+f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args);
success = (output == String("fish +99.990000 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish +99.990000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -662,8 +663,8 @@ bool test_28() {
format = "fish %.1f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args);
success = (output == String("fish 100.0 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 100.0 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -671,8 +672,8 @@ bool test_28() {
format = "fish %.12f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args);
success = (output == String("fish 99.990000000000 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 99.990000000000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -680,8 +681,8 @@ bool test_28() {
format = "fish %.f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args);
success = (output == String("fish 100 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 100 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -691,8 +692,8 @@ bool test_28() {
format = "fish %s frog";
args.clear();
args.push_back("cheese");
output = format.sprintf(args);
success = (output == String("fish cheese frog"));
output = format.sprintf(args, &error);
success = (output == String("fish cheese frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -700,8 +701,8 @@ bool test_28() {
format = "fish %10s frog";
args.clear();
args.push_back("cheese");
output = format.sprintf(args);
success = (output == String("fish cheese frog"));
output = format.sprintf(args, &error);
success = (output == String("fish cheese frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -709,8 +710,8 @@ bool test_28() {
format = "fish %-10s frog";
args.clear();
args.push_back("cheese");
output = format.sprintf(args);
success = (output == String("fish cheese frog"));
output = format.sprintf(args, &error);
success = (output == String("fish cheese frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -720,8 +721,8 @@ bool test_28() {
format = "fish %c frog";
args.clear();
args.push_back("A");
output = format.sprintf(args);
success = (output == String("fish A frog"));
output = format.sprintf(args, &error);
success = (output == String("fish A frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -729,8 +730,8 @@ bool test_28() {
format = "fish %c frog";
args.clear();
args.push_back(65);
output = format.sprintf(args);
success = (output == String("fish A frog"));
output = format.sprintf(args, &error);
success = (output == String("fish A frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -741,8 +742,8 @@ bool test_28() {
args.clear();
args.push_back(10);
args.push_back("cheese");
output = format.sprintf(args);
success = (output == String("fish cheese frog"));
output = format.sprintf(args, &error);
success = (output == String("fish cheese frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -751,8 +752,8 @@ bool test_28() {
args.clear();
args.push_back(10);
args.push_back(99);
output = format.sprintf(args);
success = (output == String("fish 99 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 99 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -762,8 +763,8 @@ bool test_28() {
args.push_back(10);
args.push_back(3);
args.push_back(99.99);
output = format.sprintf(args);
success = (output == String("fish 99.990 frog"));
output = format.sprintf(args, &error);
success = (output == String("fish 99.990 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -773,8 +774,8 @@ bool test_28() {
format = "fish %s %s frog";
args.clear();
args.push_back("cheese");
output = format.sprintf(args);
success = (output == "");
output = format.sprintf(args, &error);
success = (output == "not enough arguments for format string" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -783,8 +784,8 @@ bool test_28() {
args.clear();
args.push_back("hello");
args.push_back("cheese");
output = format.sprintf(args);
success = (output == "");
output = format.sprintf(args, &error);
success = (output == "not all arguments converted during string formatting" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -792,8 +793,8 @@ bool test_28() {
format = "fish %10";
args.clear();
args.push_back("cheese");
output = format.sprintf(args);
success = (output == "");
output = format.sprintf(args, &error);
success = (output == "incomplete format" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -801,8 +802,8 @@ bool test_28() {
format = "fish %&f frog";
args.clear();
args.push_back("cheese");
output = format.sprintf(args);
success = (output == "");
output = format.sprintf(args, &error);
success = (output == "unsupported format character" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -810,8 +811,8 @@ bool test_28() {
format = "fish %2.2.2f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args);
success = (output == "");
output = format.sprintf(args, &error);
success = (output == "too many decimal points in format" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -820,8 +821,8 @@ bool test_28() {
args.clear();
args.push_back("cheese");
args.push_back(99.99);
output = format.sprintf(args);
success = (output == "");
output = format.sprintf(args, &error);
success = (output == "* wants number" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -829,8 +830,8 @@ bool test_28() {
format = "fish %c frog";
args.clear();
args.push_back("sc");
output = format.sprintf(args);
success = (output == "");
output = format.sprintf(args, &error);
success = (output == "%c requires number or single-character string" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
@ -838,8 +839,8 @@ bool test_28() {
format = "fish %c frog";
args.clear();
args.push_back(Array());
output = format.sprintf(args);
success = (output == "");
output = format.sprintf(args, &error);
success = (output == "%c requires number or single-character string" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;

View File

@ -176,6 +176,76 @@ bool _OS::is_video_mode_fullscreen(int p_screen) const {
}
int _OS::get_screen_count() const {
return OS::get_singleton()->get_screen_count();
}
int _OS::get_current_screen() const {
return OS::get_singleton()->get_current_screen();
}
void _OS::set_current_screen(int p_screen) {
OS::get_singleton()->set_current_screen(p_screen);
}
Point2 _OS::get_screen_position(int p_screen) const {
return OS::get_singleton()->get_screen_position(p_screen);
}
Size2 _OS::get_screen_size(int p_screen) const {
return OS::get_singleton()->get_screen_size(p_screen);
}
Point2 _OS::get_window_position() const {
return OS::get_singleton()->get_window_position();
}
void _OS::set_window_position(const Point2& p_position) {
OS::get_singleton()->set_window_position(p_position);
}
Size2 _OS::get_window_size() const {
return OS::get_singleton()->get_window_size();
}
void _OS::set_window_size(const Size2& p_size) {
OS::get_singleton()->set_window_size(p_size);
}
void _OS::set_window_fullscreen(bool p_enabled) {
OS::get_singleton()->set_window_fullscreen(p_enabled);
}
bool _OS::is_window_fullscreen() const {
return OS::get_singleton()->is_window_fullscreen();
}
void _OS::set_window_resizable(bool p_enabled) {
OS::get_singleton()->set_window_resizable(p_enabled);
}
bool _OS::is_window_resizable() const {
return OS::get_singleton()->is_window_resizable();
}
void _OS::set_window_minimized(bool p_enabled) {
OS::get_singleton()->set_window_minimized(p_enabled);
}
bool _OS::is_window_minimized() const {
return OS::get_singleton()->is_window_minimized();
}
void _OS::set_window_maximized(bool p_enabled) {
OS::get_singleton()->set_window_maximized(p_enabled);
}
bool _OS::is_window_maximized() const {
return OS::get_singleton()->is_window_maximized();
}
void _OS::set_use_file_access_save_and_swap(bool p_enable) {
FileAccess::set_backup_save(p_enable);
@ -186,7 +256,6 @@ bool _OS::is_video_mode_resizable(int p_screen) const {
OS::VideoMode vm;
vm = OS::get_singleton()->get_video_mode(p_screen);
return vm.resizable;
}
Array _OS::get_fullscreen_mode_list(int p_screen) const {
@ -637,6 +706,26 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("is_video_mode_resizable","screen"),&_OS::is_video_mode_resizable,DEFVAL(0));
ObjectTypeDB::bind_method(_MD("get_fullscreen_mode_list","screen"),&_OS::get_fullscreen_mode_list,DEFVAL(0));
ObjectTypeDB::bind_method(_MD("get_screen_count"),&_OS::get_screen_count);
ObjectTypeDB::bind_method(_MD("get_current_screen"),&_OS::get_current_screen);
ObjectTypeDB::bind_method(_MD("set_current_screen"),&_OS::set_current_screen);
ObjectTypeDB::bind_method(_MD("get_screen_position"),&_OS::get_screen_position,DEFVAL(0));
ObjectTypeDB::bind_method(_MD("get_screen_size"),&_OS::get_screen_size,DEFVAL(0));
ObjectTypeDB::bind_method(_MD("get_window_position"),&_OS::get_window_position);
ObjectTypeDB::bind_method(_MD("set_window_position"),&_OS::set_window_position);
ObjectTypeDB::bind_method(_MD("get_window_size"),&_OS::get_window_size);
ObjectTypeDB::bind_method(_MD("set_window_size"),&_OS::set_window_size);
ObjectTypeDB::bind_method(_MD("set_window_fullscreen","enabled"),&_OS::set_window_fullscreen);
ObjectTypeDB::bind_method(_MD("is_window_fullscreen"),&_OS::is_window_fullscreen);
ObjectTypeDB::bind_method(_MD("set_window_resizable","enabled"),&_OS::set_window_resizable);
ObjectTypeDB::bind_method(_MD("is_window_resizable"),&_OS::is_window_resizable);
ObjectTypeDB::bind_method(_MD("set_window_minimized", "enabled"),&_OS::set_window_minimized);
ObjectTypeDB::bind_method(_MD("is_window_minimized"),&_OS::is_window_minimized);
ObjectTypeDB::bind_method(_MD("set_window_maximized", "enabled"),&_OS::set_window_maximized);
ObjectTypeDB::bind_method(_MD("is_window_maximized"),&_OS::is_window_maximized);
ObjectTypeDB::bind_method(_MD("set_iterations_per_second","iterations_per_second"),&_OS::set_iterations_per_second);
ObjectTypeDB::bind_method(_MD("get_iterations_per_second"),&_OS::get_iterations_per_second);
ObjectTypeDB::bind_method(_MD("set_target_fps","target_fps"),&_OS::set_target_fps);

View File

@ -108,6 +108,26 @@ public:
bool is_video_mode_resizable(int p_screen=0) const;
Array get_fullscreen_mode_list(int p_screen=0) const;
virtual int get_screen_count() const;
virtual int get_current_screen() const;
virtual void set_current_screen(int p_screen);
virtual Point2 get_screen_position(int p_screen=0) const;
virtual Size2 get_screen_size(int p_screen=0) const;
virtual Point2 get_window_position() const;
virtual void set_window_position(const Point2& p_position);
virtual Size2 get_window_size() const;
virtual void set_window_size(const Size2& p_size);
virtual void set_window_fullscreen(bool p_enabled);
virtual bool is_window_fullscreen() const;
virtual void set_window_resizable(bool p_enabled);
virtual bool is_window_resizable() const;
virtual void set_window_minimized(bool p_enabled);
virtual bool is_window_minimized() const;
virtual void set_window_maximized(bool p_enabled);
virtual bool is_window_maximized() const;
Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
bool native_video_is_playing();
void native_video_pause();

View File

@ -56,28 +56,36 @@ Error EventQueue::push_call(uint32_t p_instance_ID, const StringName& p_method,
buffer_end+=sizeof(Event);
if (args==1) {
if (args>=1) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg1;
} else if (args==2) {
}
if (args>=2) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg2;
} else if (args==3) {
}
if (args>=3) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg3;
} else if (args==4) {
}
if (args>=4) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg4;
} else if (args==5) {
}
if (args>=5) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);

View File

@ -313,6 +313,7 @@ static _GlobalConstant _global_constants[]={
BIND_GLOBAL_CONSTANT( KEY_MASK_ALT ),
BIND_GLOBAL_CONSTANT( KEY_MASK_META ),
BIND_GLOBAL_CONSTANT( KEY_MASK_CTRL ),
BIND_GLOBAL_CONSTANT( KEY_MASK_CMD ),
BIND_GLOBAL_CONSTANT( KEY_MASK_KPAD ),
BIND_GLOBAL_CONSTANT( KEY_MASK_GROUP_SWITCH ),

View File

@ -362,6 +362,10 @@ bool DirAccessPack::current_is_dir() const{
return cdir;
}
bool DirAccessPack::current_is_hidden() const{
return false;
}
void DirAccessPack::list_dir_end() {
list_dirs.clear();

View File

@ -208,6 +208,7 @@ public:
virtual bool list_dir_begin();
virtual String get_next();
virtual bool current_is_dir() const;
virtual bool current_is_hidden() const;
virtual void list_dir_end();
virtual int get_drive_count();

View File

@ -519,9 +519,9 @@ public:
bool s_ab = (b.x-a.x)*as_y-(b.y-a.y)*as_x > 0;
if((c.x-a.x)*as_y-(c.y-a.y)*as_x > 0 == s_ab) return false;
if(((c.x-a.x)*as_y-(c.y-a.y)*as_x > 0) == s_ab) return false;
if((c.x-b.x)*(s.y-b.y)-(c.y-b.y)*(s.x-b.x) > 0 != s_ab) return false;
if(((c.x-b.x)*(s.y-b.y)-(c.y-b.y)*(s.x-b.x) > 0) != s_ab) return false;
return true;
}

View File

@ -78,6 +78,7 @@ public:
virtual String get_next(bool* p_is_dir); // compatibility
virtual String get_next()=0;
virtual bool current_is_dir() const=0;
virtual bool current_is_hidden() const=0;
virtual void list_dir_end()=0; ///<

View File

@ -73,7 +73,7 @@ public:
bool fullscreen;
bool resizable;
float get_aspect() const { return (float)width/(float)height; }
VideoMode(int p_width=640,int p_height=480,bool p_fullscreen=false, bool p_resizable = true) { width=p_width; height=p_height; fullscreen=p_fullscreen; resizable = p_resizable; }
VideoMode(int p_width=640,int p_height=480,bool p_fullscreen=false, bool p_resizable = true) {width=p_width; height=p_height; fullscreen=p_fullscreen; resizable = p_resizable; }
};
protected:
friend class Main;
@ -149,7 +149,27 @@ public:
virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0)=0;
virtual VideoMode get_video_mode(int p_screen=0) const=0;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const=0;
virtual int get_screen_count() const{ return 1; }
virtual int get_current_screen() const { return 0; }
virtual void set_current_screen(int p_screen) { }
virtual Point2 get_screen_position(int p_screen=0) { return Point2(); }
virtual Size2 get_screen_size(int p_screen=0) const { return get_window_size(); }
virtual Point2 get_window_position() const { return Vector2(); }
virtual void set_window_position(const Point2& p_position) {}
virtual Size2 get_window_size() const=0;
virtual void set_window_size(const Size2 p_size){}
virtual void set_window_fullscreen(bool p_enabled) {}
virtual bool is_window_fullscreen() const { return true; }
virtual void set_window_resizable(bool p_enabled) {}
virtual bool is_window_resizable() const { return false; }
virtual void set_window_minimized(bool p_enabled) {}
virtual bool is_window_minimized() const { return false; }
virtual void set_window_maximized(bool p_enabled) {}
virtual bool is_window_maximized() const { return true; }
virtual void set_iterations_per_second(int p_ips);
virtual int get_iterations_per_second() const;

View File

@ -3550,8 +3550,8 @@ String String::lpad(int min_length, const String& character) const {
// sprintf is implemented in GDScript via:
// "fish %s pie" % "frog"
// "fish %s %d pie" % ["frog", 12]
String String::sprintf(const Array& values) const {
// In case of an error, the string returned is the error description and "error" is true.
String String::sprintf(const Array& values, bool* error) const {
String formatted;
CharType* self = (CharType*)c_str();
int num_items = values.size();
@ -3564,6 +3564,7 @@ String String::sprintf(const Array& values) const {
bool left_justified;
bool show_sign;
*error = true;
for (; *self; self++) {
const CharType c = *self;
@ -3580,13 +3581,11 @@ String String::sprintf(const Array& values) const {
case 'x': // Hexadecimal (lowercase)
case 'X': { // Hexadecimal (uppercase)
if (value_index >= values.size()) {
ERR_EXPLAIN("not enough arguments for format string");
ERR_FAIL_V("");
return "not enough arguments for format string";
}
if (!values[value_index].is_num()) {
ERR_EXPLAIN("a number is required");
ERR_FAIL_V("");
return "a number is required";
}
int64_t value = values[value_index];
@ -3622,13 +3621,11 @@ String String::sprintf(const Array& values) const {
}
case 'f': { // Float
if (value_index >= values.size()) {
ERR_EXPLAIN("not enough arguments for format string");
ERR_FAIL_V("");
return "not enough arguments for format string";
}
if (!values[value_index].is_num()) {
ERR_EXPLAIN("a number is required");
ERR_FAIL_V("");
return "a number is required";
}
double value = values[value_index];
@ -3657,8 +3654,7 @@ String String::sprintf(const Array& values) const {
}
case 's': { // String
if (value_index >= values.size()) {
ERR_EXPLAIN("not enough arguments for format string");
ERR_FAIL_V("");
return "not enough arguments for format string";
}
String str = values[value_index];
@ -3676,8 +3672,7 @@ String String::sprintf(const Array& values) const {
}
case 'c': {
if (value_index >= values.size()) {
ERR_EXPLAIN("not enough arguments for format string");
ERR_FAIL_V("");
return "not enough arguments for format string";
}
// Convert to character.
@ -3685,22 +3680,18 @@ String String::sprintf(const Array& values) const {
if (values[value_index].is_num()) {
int value = values[value_index];
if (value < 0) {
ERR_EXPLAIN("unsigned byte integer is lower than maximum")
ERR_FAIL_V("");
return "unsigned byte integer is lower than maximum";
} else if (value > 255) {
ERR_EXPLAIN("unsigned byte integer is greater than maximum")
ERR_FAIL_V("");
return "unsigned byte integer is greater than maximum";
}
str = chr(values[value_index]);
} else if (values[value_index].get_type() == Variant::STRING) {
str = values[value_index];
if (str.length() != 1) {
ERR_EXPLAIN("%c requires number or single-character string");
ERR_FAIL_V("");
return "%c requires number or single-character string";
}
} else {
ERR_EXPLAIN("%c requires number or single-character string");
ERR_FAIL_V("");
return "%c requires number or single-character string";
}
// Padding.
@ -3741,8 +3732,7 @@ String String::sprintf(const Array& values) const {
}
case '.': { // Float separtor.
if (in_decimals) {
ERR_EXPLAIN("too many decimal points in format");
ERR_FAIL_V("");
return "too many decimal points in format";
}
in_decimals = true;
min_decimals = 0; // We want to add the value manually.
@ -3751,13 +3741,11 @@ String String::sprintf(const Array& values) const {
case '*': { // Dyanmic width, based on value.
if (value_index >= values.size()) {
ERR_EXPLAIN("not enough arguments for format string");
ERR_FAIL_V("");
return "not enough arguments for format string";
}
if (!values[value_index].is_num()) {
ERR_EXPLAIN("* wants number");
ERR_FAIL_V("");
return "* wants number";
}
int size = values[value_index];
@ -3773,8 +3761,7 @@ String String::sprintf(const Array& values) const {
}
default: {
ERR_EXPLAIN("unsupported format character");
ERR_FAIL_V("");
return "unsupported format character";
}
}
} else { // Not in format string.
@ -3796,14 +3783,13 @@ String String::sprintf(const Array& values) const {
}
if (in_format) {
ERR_EXPLAIN("incomplete format");
ERR_FAIL_V("");
return "incomplete format";
}
if (value_index != values.size()) {
ERR_EXPLAIN("not all arguments converted during string formatting");
ERR_FAIL_V("");
return "not all arguments converted during string formatting";
}
*error = false;
return formatted;
}

View File

@ -130,7 +130,7 @@ public:
String pad_zeros(int p_digits) const;
String lpad(int min_length,const String& character=" ") const;
String rpad(int min_length,const String& character=" ") const;
String sprintf(const Array& values) const;
String sprintf(const Array& values, bool* error) const;
static String num(double p_num,int p_decimals=-1);
static String num_scientific(double p_num);
static String num_real(double p_num);

View File

@ -511,7 +511,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
VCALL_LOCALMEM1(ColorArray,append_array);
#define VCALL_PTR0(m_type,m_method)\
static void _call_##m_type##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(); }
static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(); }
#define VCALL_PTR0R(m_type,m_method)\
static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { r_ret=reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(); }
#define VCALL_PTR1(m_type,m_method)\
@ -519,7 +519,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
#define VCALL_PTR1R(m_type,m_method)\
static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { r_ret=reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(*p_args[0]); }
#define VCALL_PTR2(m_type,m_method)\
static void _call_##m_type##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(*p_args[0],*p_args[1]); }
static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(*p_args[0],*p_args[1]); }
#define VCALL_PTR2R(m_type,m_method)\
static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { r_ret=reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(*p_args[0],*p_args[1]); }
#define VCALL_PTR3(m_type,m_method)\
@ -531,7 +531,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
#define VCALL_PTR4R(m_type,m_method)\
static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { r_ret=reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(*p_args[0],*p_args[1],*p_args[2],*p_args[3]); }
#define VCALL_PTR5(m_type,m_method)\
static void _call_##m_type##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(*p_args[0],*p_args[1],*p_args[2],*p_args[3],*p_args[4]); }
static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(*p_args[0],*p_args[1],*p_args[2],*p_args[3],*p_args[4]); }
#define VCALL_PTR5R(m_type,m_method)\
static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { r_ret=reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(*p_args[0],*p_args[1],*p_args[2],*p_args[3],*p_args[4]); }
@ -685,7 +685,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
VCALL_PTR0R( InputEvent, is_pressed );
VCALL_PTR1R( InputEvent, is_action );
VCALL_PTR0R( InputEvent, is_echo );
//VCALL_PTR2( InputEvent, set_as_action );
VCALL_PTR2( InputEvent, set_as_action );
struct ConstructData {
@ -1496,7 +1496,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
ADDFUNC0(INPUT_EVENT,BOOL,InputEvent,is_pressed,varray());
ADDFUNC1(INPUT_EVENT,BOOL,InputEvent,is_action,STRING,"action",varray());
ADDFUNC0(INPUT_EVENT,BOOL,InputEvent,is_echo,varray());
//ADDFUNC2(INPUT_EVENT,NIL,InputEvent,set_as_action,STRING,"action",BOOL,"pressed",varray());
ADDFUNC2(INPUT_EVENT,NIL,InputEvent,set_as_action,STRING,"action",BOOL,"pressed",varray());
/* REGISTER CONSTRUCTORS */

View File

@ -741,18 +741,22 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant&
_RETURN( p_a._data._int % p_b._data._int );
} else if (p_a.type==STRING) {
const String *str=reinterpret_cast<const String*>(p_a._data._mem);
const String* format=reinterpret_cast<const String*>(p_a._data._mem);
String result;
bool error;
if (p_b.type==ARRAY) {
// e.g. "frog %s %d" % ["fish", 12]
const Array *arr=reinterpret_cast<const Array*>(p_b._data._mem);
_RETURN(str->sprintf(*arr));
const Array* args=reinterpret_cast<const Array*>(p_b._data._mem);
result=format->sprintf(*args, &error);
} else {
// e.g. "frog %d" % 12
Array arr;
arr.push_back(p_b);
_RETURN(str->sprintf(arr));
Array args;
args.push_back(p_b);
result=format->sprintf(args, &error);
}
r_valid = !error;
_RETURN(result);
}
r_valid=false;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,4 @@
[application]
name="Area 2D Input Events"
main_scene="res://input.scn"

View File

@ -0,0 +1,16 @@
extends Area2D
#virtual from CollisionObject2D (also available as signal)
func _input_event(viewport, event, shape_idx):
#convert event to local coordinates
if (event.type==InputEvent.MOUSE_MOTION):
event = make_input_local( event )
get_node("label").set_text(str(event.pos))
#virtual from CollisionObject2D (also available as signal)
func _mouse_exit():
get_node("label").set_text("")

Binary file not shown.

View File

@ -0,0 +1,11 @@
::res://::1422910453
floor.png::ImageTexture::1422910453::
fog.gd::GDScript::1422910025::
fog.png::ImageTexture::1422908128::
fog.scn::PackedScene::1422909435::
fog.xml::TileSet::1422909324::
icon.png::ImageTexture::1422811193::
tile_edit.scn::PackedScene::1422909313::
troll.gd::GDScript::1422909940::
troll.png::ImageTexture::1418669358::
troll.scn::PackedScene::1418669358::

View File

@ -0,0 +1,12 @@
[application]
name="Fog of War"
main_scene="res://fog.scn"
icon="icon.png"
[input]
move_up=[key(Up)]
move_bottom=[key(Down)]
move_left=[key(Left)]
move_right=[key(Right)]

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 B

View File

@ -0,0 +1,86 @@
extends TileMap
# member variables here, example:
# var a=2
# var b="textvar"
# boundarys for the fog rectangle
var x_min = -20 # left start tile
var x_max = 20 # right end tile
var y_min = -20 # top start tile
var y_max = 20 # bottom end tile
var position # players position
# iteration variables
var x
var y
# variable to check if player moved
var x_old
var y_old
# array to build up the visible area like a square
# first value determines the width/height of the tip
# here it would be 2*2 + 1 = 5 tiles wide/high
# second value determines the total squares size
# here it would be 5*2 + 1 = 10 tiles wide/high
var l = range(2,5)
# process that runs in realtime
func _fixed_process(delta):
position = get_node("../troll").get_pos()
# calculate the corresponding tile
# from the players position
x = int(position.x/get_cell_size().x)
# switching from positive to negative tile positions
# causes problems because of rounding problems
if position.x < 0:
x -= 1 # correct negative values
y = int(position.y/get_cell_size().y)
if position.y < 0:
y -= 1
# check if the player moved one tile further
if (x_old != x) or (y_old != y):
# create the transparent part (visited area)
var end = l.size()-1
var start = 0
for steps in range(l.size()):
for m in range(x-l[end]-1,x+l[end]+2):
for n in range(y-l[start]-1,y+l[start]+2):
if get_cell(m,n) != 0:
set_cell(m,n,1,0,0)
end -= 1
start += 1
# create the actual and active visible part
var end = l.size()-1
var start = 0
for steps in range(l.size()):
for m in range(x-l[end],x+l[end]+1):
for n in range(y-l[start],y+l[start]+1):
set_cell(m,n,-1)
end -= 1
start += 1
x_old = x
y_old = y
pass
func _ready():
# Initalization here
# create a square filled with the 100% opaque fog
for x in range(x_min,x_max):
for y in range(y_min,y_max):
set_cell(x,y,0,0,0)
set_fixed_process(true)
pass

BIN
demos/2d/fog_of_war/fog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
demos/2d/fog_of_war/fog.scn Normal file

Binary file not shown.

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" ?>
<resource_file type="TileSet" subresource_count="3" version="1.0" version_name="Godot Engine v1.0.stable.custom_build">
<ext_resource path="res://floor.png" type="Texture"></ext_resource>
<ext_resource path="res://fog.png" type="Texture"></ext_resource>
<main_resource>
<string name="0/name"> "fog opaque" </string>
<resource name="0/texture" resource_type="Texture" path="res://fog.png"> </resource>
<vector2 name="0/tex_offset"> -48, -48 </vector2>
<vector2 name="0/shape_offset"> 0, 0 </vector2>
<rect2 name="0/region"> 0, 0, 144, 144 </rect2>
<array name="0/shapes" len="0" shared="false">
</array>
<string name="1/name"> "fog transparent" </string>
<resource name="1/texture" resource_type="Texture" path="res://fog.png"> </resource>
<vector2 name="1/tex_offset"> -48, -48 </vector2>
<vector2 name="1/shape_offset"> 0, 0 </vector2>
<rect2 name="1/region"> 144, 0, 144, 144 </rect2>
<array name="1/shapes" len="0" shared="false">
</array>
<string name="2/name"> "floor" </string>
<resource name="2/texture" resource_type="Texture" path="res://floor.png"> </resource>
<vector2 name="2/tex_offset"> 0, 0 </vector2>
<vector2 name="2/shape_offset"> 0, 0 </vector2>
<rect2 name="2/region"> 0, 0, 0, 0 </rect2>
<array name="2/shapes" len="0" shared="false">
</array>
</main_resource>
</resource_file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -0,0 +1 @@
gen_mipmaps=true

Binary file not shown.

View File

@ -0,0 +1,43 @@
extends KinematicBody2D
# This is a simple collision demo showing how
# the kinematic cotroller works.
# move() will allow to move the node, and will
# always move it to a non-colliding spot,
# as long as it starts from a non-colliding spot too.
#pixels / second
const MOTION_SPEED=160
func _fixed_process(delta):
var motion = Vector2()
if (Input.is_action_pressed("move_up")):
motion+=Vector2(0,-1)
if (Input.is_action_pressed("move_bottom")):
motion+=Vector2(0,1)
if (Input.is_action_pressed("move_left")):
motion+=Vector2(-1,0)
if (Input.is_action_pressed("move_right")):
motion+=Vector2(1,0)
motion = motion.normalized() * MOTION_SPEED * delta
motion = move(motion)
#make character slide nicely through the world
var slide_attempts = 4
while(is_colliding() and slide_attempts>0):
motion = get_collision_normal().slide(motion)
motion=move(motion)
slide_attempts-=1
func _ready():
# Initalization here
set_fixed_process(true)
pass

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

View File

@ -0,0 +1,26 @@
extends Node2D
# member variables here, example:
# var a=2
# var b="textvar"
const CAVE_LIMIT=1000
func _input(ev):
if (ev.type==InputEvent.MOUSE_MOTION and ev.button_mask&1):
var rel_x = ev.relative_x
var cavepos = get_node("cave").get_pos()
cavepos.x+=rel_x
if (cavepos.x<-CAVE_LIMIT):
cavepos.x=-CAVE_LIMIT
elif (cavepos.x>0):
cavepos.x=0
get_node("cave").set_pos(cavepos)
func _ready():
set_process_input(true)
# Initialization here
pass

BIN
demos/2d/hdr/beach_cave.scn Normal file

Binary file not shown.

13
demos/2d/hdr/engine.cfg Normal file
View File

@ -0,0 +1,13 @@
[application]
name="HDR for 2D"
main_scene="res://beach_cave.scn"
[display]
width=1080
height=720
[rasterizer]
blur_buffer_size=128

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 KiB

View File

@ -0,0 +1 @@
tolinear=true

BIN
demos/2d/hdr/ocean_cave.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 KiB

View File

@ -0,0 +1 @@
tolinear=true

Binary file not shown.

Binary file not shown.

View File

@ -9,6 +9,10 @@ down=[key(S), key(Down)]
left=[key(Left), key(A)]
right=[key(Right), key(D)]
[rasterizer]
shadow_filter=0
[render]
default_clear_color=#ff000000

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 KiB

View File

@ -0,0 +1,8 @@
[application]
name="Using Lights As Mask"
main_scene="res://lightmask.scn"
[rasterizer]
shadow_filter=3

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

View File

@ -0,0 +1,8 @@
[application]
name="2D Lighting"
main_scene="res://light_shadows.scn"
[rasterizer]
shadow_filter=2

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@ -0,0 +1,4 @@
[application]
name="2D Normal Mapping"
main_scene="res://normalmap.scn"

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1,4 @@
[application]
name="Signed Distance Field Font"
main_scene="res://sdf.scn"

BIN
demos/2d/sdf_font/font.fnt Normal file

Binary file not shown.

BIN
demos/2d/sdf_font/sdf.scn Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -0,0 +1,4 @@
[application]
name="2D Shaders for Sprites"
main_scene="res://sprite_shaders.scn"

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,17 @@
extends Control
# member variables here, example:
# var a=2
# var b="textvar"
const MAX_BUBBLES=10
func _ready():
# Initialization here
for i in range(MAX_BUBBLES):
var bubble = preload("res://lens.scn").instance()
add_child(bubble)
pass

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 KiB

View File

@ -0,0 +1,4 @@
[application]
name="Glass Bubbles (Texscreen)"
main_scene="res://bubbles.scn"

View File

@ -0,0 +1,37 @@
extends BackBufferCopy
# member variables here, example:
# var a=2
# var b="textvar"
const MOTION_SPEED=150
var vsize;
var dir;
func _process(delta):
var pos = get_pos() + dir * delta * MOTION_SPEED
if (pos.x<0):
dir.x=abs(dir.x)
elif (pos.x>vsize.x):
dir.x=-abs(dir.x)
if (pos.y<0):
dir.y=abs(dir.y)
elif (pos.y>vsize.y):
dir.y=-abs(dir.y)
set_pos(pos)
func _ready():
vsize = get_viewport_rect().size
var pos = vsize * Vector2(randf(),randf());
set_pos(pos);
dir = Vector2(randf()*2.0-1,randf()*2.0-1).normalized()
set_process(true)
# Initialization here
pass

BIN
demos/2d/texscreen/lens.scn Normal file

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,24 @@
extends ColorPickerButton
#virtual function
func get_drag_data(pos):
#use another colorpicker as drag preview
var cpb = ColorPickerButton.new()
cpb.set_color( get_color() )
cpb.set_size(Vector2(50,50))
set_drag_preview(cpb)
#return color as drag data
return get_color()
#virtual function
func can_drop_data(pos, data):
return typeof(data)==TYPE_COLOR
#virtual function
func drop_data(pos, data):
set_color(data)

View File

@ -0,0 +1,4 @@
[application]
name="Drag &amp; Drop (GUI)"
main_scene="res://drag_and_drop.scn"

View File

@ -0,0 +1,177 @@
extends Control
func _fixed_process(delta):
var modetext = "Mode:\n"
if(OS.is_window_fullscreen()):
modetext += "Fullscreen\n"
else:
modetext += "Windowed\n"
if(!OS.is_window_resizable()):
modetext += "FixedSize\n"
if(OS.is_window_minimized()):
modetext += "Minimized\n"
if(OS.is_window_maximized()):
modetext += "Maximized\n"
if(Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED):
modetext += "MouseGrab\n"
get_node("Label_MouseGrab_KeyInfo").show()
else:
get_node("Label_MouseGrab_KeyInfo").hide()
get_node("Label_Mode").set_text(modetext)
get_node("Label_Position").set_text( str("Position:\n", OS.get_window_position() ) )
get_node("Label_Size").set_text(str("Size:\n", OS.get_window_size() ) )
get_node("Label_MousePosition").set_text(str("Mouse Position:\n", Input.get_mouse_pos() ) )
get_node("Label_Screen_Count").set_text( str("Screen_Count:\n", OS.get_screen_count() ) )
get_node("Label_Screen_Current").set_text( str("Screen:\n", OS.get_current_screen() ) )
get_node("Label_Screen0_Resolution").set_text( str("Screen0 Resolution:\n", OS.get_screen_size() ) )
get_node("Label_Screen0_Position").set_text(str("Screen0 Position:\n",OS.get_screen_position() ) )
if(OS.get_screen_count() > 1):
get_node("Button_Screen0").show()
get_node("Button_Screen1").show()
get_node("Label_Screen1_Resolution").show()
get_node("Label_Screen1_Position").show()
get_node("Label_Screen1_Resolution").set_text( str("Screen1 Resolution:\n", OS.get_screen_size(1) ) )
get_node("Label_Screen1_Position").set_text( str("Screen1 Position:\n", OS.get_screen_position(1) ) )
else:
get_node("Button_Screen0").hide()
get_node("Button_Screen1").hide()
get_node("Label_Screen1_Resolution").hide()
get_node("Label_Screen1_Position").hide()
get_node("Button_Fullscreen").set_pressed( OS.is_window_fullscreen() )
get_node("Button_FixedSize").set_pressed( !OS.is_window_resizable() )
get_node("Button_Minimized").set_pressed( OS.is_window_minimized() )
get_node("Button_Maximized").set_pressed( OS.is_window_maximized() )
get_node("Button_Mouse_Grab").set_pressed( Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED )
func check_wm_api():
var s = ""
if( !OS.has_method("get_screen_count") ):
s += " - get_screen_count()\n"
if( !OS.has_method("get_current_screen") ):
s += " - get_current_screen()\n"
if( !OS.has_method("set_current_screen") ):
s += " - set_current_screen()\n"
if( !OS.has_method("get_screen_position") ):
s += " - get_screen_position()\n"
if( !OS.has_method("get_screen_size") ):
s += " - get_screen_size()\n"
if( !OS.has_method("get_window_position") ):
s += " - get_window_position()\n"
if( !OS.has_method("set_window_position") ):
s += " - set_window_position()\n"
if( !OS.has_method("get_window_size") ):
s += " - get_window_size()\n"
if( !OS.has_method("set_window_size") ):
s += " - set_window_size()\n"
if( !OS.has_method("set_window_fullscreen") ):
s += " - set_window_fullscreen()\n"
if( !OS.has_method("is_window_fullscreen") ):
s += " - is_window_fullscreen()\n"
if( !OS.has_method("set_window_resizable") ):
s += " - set_window_resizable()\n"
if( !OS.has_method("is_window_resizable") ):
s += " - is_window_resizable()\n"
if( !OS.has_method("set_window_minimized") ):
s += " - set_window_minimized()\n"
if( !OS.has_method("is_window_minimized") ):
s += " - is_window_minimized()\n"
if( !OS.has_method("set_window_maximized") ):
s += " - set_window_maximized()\n"
if( !OS.has_method("is_window_maximized") ):
s += " - is_window_maximized()\n"
if( s.length() == 0 ):
return true
else:
var text = get_node("ImplementationDialog/Text").get_text()
get_node("ImplementationDialog/Text").set_text( text + s )
get_node("ImplementationDialog").show()
return false
func _ready():
if( check_wm_api() ):
set_fixed_process(true)
func _on_Button_MoveTo_pressed():
OS.set_window_position( Vector2(100,100) )
func _on_Button_Resize_pressed():
OS.set_window_size( Vector2(1024,768) )
func _on_Button_Screen0_pressed():
OS.set_current_screen(0)
func _on_Button_Screen1_pressed():
OS.set_current_screen(1)
func _on_Button_Fullscreen_pressed():
if(OS.is_window_fullscreen()):
OS.set_window_fullscreen(false)
else:
OS.set_window_fullscreen(true)
func _on_Button_FixedSize_pressed():
if(OS.is_window_resizable()):
OS.set_window_resizable(false)
else:
OS.set_window_resizable(true)
func _on_Button_Minimized_pressed():
if(OS.is_window_minimized()):
OS.set_window_minimized(false)
else:
OS.set_window_minimized(true)
func _on_Button_Maximized_pressed():
if(OS.is_window_maximized()):
OS.set_window_maximized(false)
else:
OS.set_window_maximized(true)
func _on_Button_Mouse_Grab_pressed():
var observer = get_node("../Observer")
observer.state = observer.STATE_GRAB

View File

@ -0,0 +1,19 @@
[application]
name="window_management"
main_scene="res://window_management.scn"
icon="icon.png"
[display]
fullscreen=false
resizable=true
width=800
height=600
[input]
move_forward=[key(W)]
move_backwards=[key(S)]
move_left=[key(A)]
move_right=[key(D)]

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -0,0 +1 @@
gen_mipmaps=false

View File

@ -0,0 +1,79 @@
extends Spatial
var r_pos = Vector2()
var state
const STATE_MENU=0
const STATE_GRAB=1
func direction(vector):
var v = get_node("Camera").get_global_transform().basis * vector
v = v.normalized()
return v
func impulse(event, action):
if(event.is_action(action) && event.is_pressed() && !event.is_echo()):
return true
else:
return false
func _fixed_process(delta):
if(state != STATE_GRAB):
return
if(Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED):
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
var dir = Vector3()
var cam = get_global_transform()
var org = get_translation()
if (Input.is_action_pressed("move_forward")):
dir += direction(Vector3(0,0,-1))
if (Input.is_action_pressed("move_backwards")):
dir += direction(Vector3(0,0,1))
if (Input.is_action_pressed("move_left")):
dir += direction(Vector3(-1,0,0))
if (Input.is_action_pressed("move_right")):
dir += direction(Vector3(1,0,0))
dir = dir.normalized()
move(dir * 10 * delta)
var d = delta * 0.1
var yaw = get_transform().rotated(Vector3(0,1,0), d * r_pos.x)
set_transform(yaw)
var cam = get_node("Camera")
var pitch = cam.get_transform().rotated(Vector3(1,0,0), d * r_pos.y)
cam.set_transform(pitch)
r_pos.x = 0.0
r_pos.y = 0.0
func _input( event ):
if(event.type == InputEvent.MOUSE_MOTION):
r_pos = event.relative_pos
if(impulse(event, "ui_cancel")):
if(state == STATE_GRAB):
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
state = STATE_MENU
else:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
state = STATE_GRAB
func _ready():
set_fixed_process(true)
set_process_input(true)
state = STATE_MENU

Binary file not shown.

Binary file not shown.

View File

@ -7,38 +7,39 @@ extends Spatial
var prev_pos=null
func _input(ev):
if (ev.type in [InputEvent.MOUSE_BUTTON,InputEvent.MOUSE_MOTION]):
var pos = ev.pos
var rfrom = get_node("camera").project_ray_origin(pos)
var rnorm = get_node("camera").project_ray_normal(pos)
func _input( ev ):
#all other (non-mouse) events
if (not ev.type in [InputEvent.MOUSE_BUTTON,InputEvent.MOUSE_MOTION,InputEvent.SCREEN_DRAG,InputEvent.SCREEN_TOUCH]):
get_node("viewport").input(ev)
#simple collision test against aligned plane
#for game UIs of this kind consider more complex collision against plane
var p = Plane(Vector3(0,0,1),0).intersects_ray(rfrom,rnorm)
if (p==null):
return
pos.x=(p.x+1.5)*100
pos.y=(-p.y+0.75)*100
ev.pos=pos
ev.global_pos=pos
if (prev_pos==null):
prev_pos=pos
if (ev.type==InputEvent.MOUSE_MOTION):
ev.relative_pos=pos-prev_pos
#mouse events for area
func _on_area_input_event( camera, ev, click_pos, click_normal, shape_idx ):
#use click pos (click in 3d space, convert to area space
var pos = get_node("area").get_global_transform().affine_inverse() * click_pos
#convert to 2D
pos = Vector2(pos.x,pos.y)
#convert to viewport coordinate system
pos.x=(pos.x+1.5)*100
pos.y=(-pos.y+0.75)*100
#set to event
ev.pos=pos
ev.global_pos=pos
if (prev_pos==null):
prev_pos=pos
if (ev.type==InputEvent.MOUSE_MOTION):
ev.relative_pos=pos-prev_pos
prev_pos=pos
get_node("viewport").input(ev)
func _ready():
# Initalization here
get_node("quad").get_material_override().set_texture(FixedMaterial.PARAM_DIFFUSE, get_node("viewport").get_render_target_texture() )
get_node("area/quad").get_material_override().set_texture(FixedMaterial.PARAM_DIFFUSE, get_node("viewport").get_render_target_texture() )
set_process_input(true)
pass

Binary file not shown.

View File

@ -257,13 +257,14 @@
<method name="lerp" >
<return type="float">
</return>
<argument index="0" name="a" type="float">
<argument index="0" name="from" type="float">
</argument>
<argument index="1" name="b" type="float">
<argument index="1" name="to" type="float">
</argument>
<argument index="2" name="c" type="float">
<argument index="2" name="weight" type="float">
</argument>
<description>
Linear interpolates between two values by a normalized value.
</description>
</method>
<method name="dectime" >
@ -276,6 +277,7 @@
<argument index="2" name="step" type="float">
</argument>
<description>
Decreases time by a specified amount.
</description>
</method>
<method name="randomize" >
@ -421,6 +423,7 @@
<argument index="1" name="funcname" type="String">
</argument>
<description>
Returns a reference to the specified function
</description>
</method>
<method name="convert" >
@ -475,6 +478,7 @@
<argument index="1" name="..." type="var">
</argument>
<description>
Print one or more arguments to the console with a tab between each argument.
</description>
</method>
<method name="printerr" >
@ -499,6 +503,24 @@
Print one or more arguments to strings in the best way possible to console. No newline is added at the end.
</description>
</method>
<method name="var2str" >
<return type="String">
</return>
<argument index="0" name="var" type="var">
</argument>
<description>
Converts the value of a variable to a String.
</description>
</method>
<method name="str2var:var" >
<return type="String">
</return>
<argument index="0" name="str" type="String">
</argument>
<description>
Converts the value of a String to a variable.
</description>
</method>
<method name="range" >
<return type="Array">
</return>
@ -544,6 +566,7 @@
<argument index="0" name="var:var" type="var">
</argument>
<description>
Hashes the variable passed and returns an integer.
</description>
</method>
<method name="print_stack" >

View File

@ -2367,7 +2367,7 @@ found_perfect_match:
int dr = best_results[1].m_block_color_unscaled.r - best_results[0].m_block_color_unscaled.r;
int dg = best_results[1].m_block_color_unscaled.g - best_results[0].m_block_color_unscaled.g;
int db = best_results[1].m_block_color_unscaled.b - best_results[0].m_block_color_unscaled.b;
RG_ETC1_ASSERT(best_use_color4 || (rg_etc1::minimum(dr, dg, db) >= cETC1ColorDeltaMin) && (rg_etc1::maximum(dr, dg, db) <= cETC1ColorDeltaMax));
RG_ETC1_ASSERT(best_use_color4 || ((rg_etc1::minimum(dr, dg, db) >= cETC1ColorDeltaMin) && (rg_etc1::maximum(dr, dg, db) <= cETC1ColorDeltaMax)));
if (best_use_color4)
{

View File

@ -989,8 +989,14 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu
if (texture->flags&VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps)
glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,use_fast_texture_filter?GL_LINEAR_MIPMAP_NEAREST:GL_LINEAR_MIPMAP_LINEAR);
else
glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
else {
if (texture->flags&VS::TEXTURE_FLAG_FILTER) {
glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
} else {
glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
}
}
if (texture->flags&VS::TEXTURE_FLAG_FILTER) {
@ -1283,8 +1289,14 @@ void RasterizerGLES2::texture_set_flags(RID p_texture,uint32_t p_flags) {
if (texture->flags&VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps)
glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,use_fast_texture_filter?GL_LINEAR_MIPMAP_NEAREST:GL_LINEAR_MIPMAP_LINEAR);
else
glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
else{
if (texture->flags&VS::TEXTURE_FLAG_FILTER) {
glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
} else {
glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
}
}
if (texture->flags&VS::TEXTURE_FLAG_FILTER) {
@ -4276,7 +4288,7 @@ void RasterizerGLES2::capture_viewport(Image* r_capture) {
void RasterizerGLES2::clear_viewport(const Color& p_color) {
if (current_rt) {
if (current_rt || using_canvas_bg) {
glScissor( 0, 0, viewport.width, viewport.height );
} else {
@ -4599,6 +4611,9 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
if (fragment_flags.uses_texpixel_size) {
enablers.push_back("#define USE_TEXPIXEL_SIZE\n");
}
if (light_flags.uses_shadow_color) {
enablers.push_back("#define USE_LIGHT_SHADOW_COLOR\n");
}
if (vertex_flags.uses_worldvec) {
enablers.push_back("#define USE_WORLD_VEC\n");
@ -6932,7 +6947,7 @@ void RasterizerGLES2::_draw_tex_bg() {
RID texture;
if (current_env->bg_mode==VS::ENV_BG_TEXTURE || current_env->bg_mode==VS::ENV_BG_TEXTURE_RGBE) {
if (current_env->bg_mode==VS::ENV_BG_TEXTURE) {
texture=current_env->bg_param[VS::ENV_BG_PARAM_TEXTURE];
} else {
texture=current_env->bg_param[VS::ENV_BG_PARAM_CUBEMAP];
@ -6949,25 +6964,20 @@ void RasterizerGLES2::_draw_tex_bg() {
copy_shader.set_conditional(CopyShaderGLES2::USE_ENERGY,true);
if (current_env->bg_mode==VS::ENV_BG_TEXTURE || current_env->bg_mode==VS::ENV_BG_TEXTURE_RGBE) {
if (current_env->bg_mode==VS::ENV_BG_TEXTURE) {
copy_shader.set_conditional(CopyShaderGLES2::USE_CUBEMAP,false);
} else {
copy_shader.set_conditional(CopyShaderGLES2::USE_CUBEMAP,true);
}
if (current_env->bg_mode==VS::ENV_BG_CUBEMAP_RGBE || current_env->bg_mode==VS::ENV_BG_TEXTURE_RGBE) {
copy_shader.set_conditional(CopyShaderGLES2::USE_RGBE,true);
} else {
copy_shader.set_conditional(CopyShaderGLES2::USE_RGBE,false);
}
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) {
if (current_env->bg_mode==VS::ENV_BG_TEXTURE) {
glUniform1i( copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE),0);
} else {
glUniform1i( copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE_CUBE),0);
@ -6994,7 +7004,7 @@ void RasterizerGLES2::_draw_tex_bg() {
Vector3( 0, 0, 0)
};
if (current_env->bg_mode==VS::ENV_BG_TEXTURE || current_env->bg_mode==VS::ENV_BG_TEXTURE_RGBE) {
if (current_env->bg_mode==VS::ENV_BG_TEXTURE) {
//regular texture
//adjust aspect
@ -7064,7 +7074,7 @@ void RasterizerGLES2::end_scene() {
if (framebuffer.active) {
//detect when to use the framebuffer object
if (texscreen_used || framebuffer.scale!=1) {
if (using_canvas_bg || texscreen_used || framebuffer.scale!=1) {
use_fb=true;
} else if (current_env) {
use_fb=false;
@ -7116,6 +7126,7 @@ void RasterizerGLES2::end_scene() {
switch(current_env->bg_mode) {
case VS::ENV_BG_CANVAS:
case VS::ENV_BG_KEEP: {
//copy from framebuffer if framebuffer
glClear(GL_DEPTH_BUFFER_BIT);
@ -7128,7 +7139,7 @@ void RasterizerGLES2::end_scene() {
bgcolor = current_env->bg_param[VS::ENV_BG_PARAM_COLOR];
else
bgcolor = Globals::get_singleton()->get("render/default_clear_color");
bgcolor = _convert_color(bgcolor);
bgcolor = _convert_color(bgcolor);
float a = use_fb ? float(current_env->bg_param[VS::ENV_BG_PARAM_GLOW]) : 1.0;
glClearColor(bgcolor.r,bgcolor.g,bgcolor.b,a);
_glClearDepth(1.0);
@ -7136,9 +7147,7 @@ void RasterizerGLES2::end_scene() {
} break;
case VS::ENV_BG_TEXTURE:
case VS::ENV_BG_CUBEMAP:
case VS::ENV_BG_TEXTURE_RGBE:
case VS::ENV_BG_CUBEMAP_RGBE: {
case VS::ENV_BG_CUBEMAP: {
glClear(GL_DEPTH_BUFFER_BIT);
@ -7357,8 +7366,12 @@ void RasterizerGLES2::end_scene() {
_debug_shadows();
}
// _debug_luminances();
_debug_samplers();
// _debug_samplers();
if (using_canvas_bg) {
using_canvas_bg=false;
glColorMask(1,1,1,1); //don't touch alpha
}
}
void RasterizerGLES2::end_shadow_map() {
@ -7827,8 +7840,26 @@ void RasterizerGLES2::flush_frame() {
/* CANVAS API */
void RasterizerGLES2::begin_canvas_bg() {
if (framebuffer.active) {
using_canvas_bg=true;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.fbo);
glViewport( 0,0,viewport.width , viewport.height );
} else {
using_canvas_bg=false;
}
}
void RasterizerGLES2::canvas_begin() {
if (using_canvas_bg) {
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.fbo);
glColorMask(1,1,1,0); //don't touch alpha
}
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
@ -8531,6 +8562,7 @@ RID RasterizerGLES2::canvas_light_shadow_buffer_create(int p_width) {
#ifdef GLEW_ENABLED
glDrawBuffer(GL_NONE);
#endif
} else {
// We'll use a RGBA texture into which we pack the depth info
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cls->size, cls->height, 0,
@ -8539,6 +8571,7 @@ RID RasterizerGLES2::canvas_light_shadow_buffer_create(int p_width) {
// Attach the RGBA texture to FBO color attachment point
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, cls->depth, 0);
cls->rgba=cls->depth;
// Allocate 16-bit depth buffer
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, cls->size, cls->height);
@ -8554,7 +8587,7 @@ RID RasterizerGLES2::canvas_light_shadow_buffer_create(int p_width) {
//printf("errnum: %x\n",status);
#ifdef GLEW_ENABLED
if (read_depth_supported) {
glDrawBuffer(GL_BACK);
//glDrawBuffer(GL_BACK);
}
#endif
glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer);
@ -8563,7 +8596,7 @@ RID RasterizerGLES2::canvas_light_shadow_buffer_create(int p_width) {
#ifdef GLEW_ENABLED
if (read_depth_supported) {
glDrawBuffer(GL_BACK);
//glDrawBuffer(GL_BACK);
}
#endif
@ -8817,10 +8850,14 @@ void RasterizerGLES2::canvas_debug_viewport_shadows(CanvasLight* p_lights_with_s
int h = 10;
int w = viewport.width;
int ofs = h;
//print_line(" debug lights ");
while(light) {
// print_line("debug light");
if (light->shadow_buffer.is_valid()) {
// print_line("sb is valid");
CanvasLightShadow * sb = canvas_light_shadow_owner.get(light->shadow_buffer);
if (sb) {
glActiveTexture(GL_TEXTURE0);
@ -9099,8 +9136,11 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
canvas_use_modulate=p_modulate!=Color(1,1,1,1);
canvas_modulate=p_modulate;
canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate);
canvas_shader.set_conditional(CanvasShaderGLES2::USE_DISTANCE_FIELD,false);
bool reset_modulate=false;
bool prev_distance_field=false;
while(p_item_list) {
@ -9116,12 +9156,22 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
canvas_use_modulate=p_modulate!=Color(1,1,1,1);
canvas_modulate=p_modulate;
canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate);
canvas_shader.set_conditional(CanvasShaderGLES2::USE_DISTANCE_FIELD,false);
prev_distance_field=false;
rebind_shader=true;
reset_modulate=true;
}
if (prev_distance_field!=ci->distance_field) {
canvas_shader.set_conditional(CanvasShaderGLES2::USE_DISTANCE_FIELD,ci->distance_field);
prev_distance_field=ci->distance_field;
rebind_shader=true;
}
if (current_clip!=ci->final_clip_owner) {
current_clip=ci->final_clip_owner;
@ -9138,6 +9188,40 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
}
}
if (ci->copy_back_buffer && framebuffer.active && framebuffer.scale==1) {
Rect2 rect;
int x,y,w,h;
if (ci->copy_back_buffer->full) {
x = viewport.x;
y = window_size.height-(viewport.height+viewport.y);
w = viewport.width;
h = viewport.height;
} else {
x = viewport.x+ci->copy_back_buffer->screen_rect.pos.x;
y = window_size.height-(viewport.y+ci->copy_back_buffer->screen_rect.pos.y+ci->copy_back_buffer->screen_rect.size.y);
w = ci->copy_back_buffer->screen_rect.size.x;
h = ci->copy_back_buffer->screen_rect.size.y;
}
glActiveTexture(GL_TEXTURE0+max_texture_units-1);
glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color);
#ifdef GLEW_ENABLED
glReadBuffer(GL_COLOR_ATTACHMENT0);
#endif
glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,w,h);
// if (current_clip) {
// // print_line(" a clip ");
// }
canvas_texscreen_used=true;
glActiveTexture(GL_TEXTURE0);
}
//begin rect
CanvasItem *material_owner = ci->material_owner?ci->material_owner:ci;
@ -9179,7 +9263,9 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
_canvas_item_setup_shader_uniforms(material,shader_cache);
}
if (material && material->unshaded) {
bool unshaded = material && material->shading_mode==VS::CANVAS_ITEM_SHADING_UNSHADED;
if (unshaded) {
canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,Color(1,1,1,1));
reset_modulate=true;
} else if (reset_modulate) {
@ -9236,13 +9322,15 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
canvas_opacity = ci->final_opacity;
_canvas_item_render_commands<false>(ci,current_clip,reclip);
if (canvas_blend_mode==VS::MATERIAL_BLEND_MODE_MIX && p_light && (!material || !material->unshaded)) {
if (unshaded || (p_modulate.a>0.001 && (!material || material->shading_mode!=VS::CANVAS_ITEM_SHADING_ONLY_LIGHT)))
_canvas_item_render_commands<false>(ci,current_clip,reclip);
if (canvas_blend_mode==VS::MATERIAL_BLEND_MODE_MIX && p_light && !unshaded) {
CanvasLight *light = p_light;
bool light_used=false;
bool subtract=false;
VS::CanvasLightMode mode=VS::CANVAS_LIGHT_MODE_ADD;
while(light) {
@ -9251,21 +9339,28 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
//intersects this light
if (!light_used || subtract!=light->subtract) {
if (!light_used || mode!=light->mode) {
subtract=light->subtract;
mode=light->mode;
if (subtract) {
switch(mode) {
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
case VS::CANVAS_LIGHT_MODE_ADD: {
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
} else {
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
} break;
case VS::CANVAS_LIGHT_MODE_SUB: {
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
} break;
case VS::CANVAS_LIGHT_MODE_MIX: {
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} break;
}
}
if (!light_used) {
@ -9303,7 +9398,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_MATRIX,light->light_shader_xform);
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_POS,light->light_shader_pos);
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_COLOR,light->color);
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_COLOR,Color(light->color.r*light->energy,light->color.g*light->energy,light->color.b*light->energy,light->color.a));
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_HEIGHT,light->height);
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_LOCAL_MATRIX,light->xform_cache.affine_inverse());
@ -9783,9 +9878,9 @@ void RasterizerGLES2::free(const RID& p_rid) {
glDeleteFramebuffers(1,&cls->fbo);
glDeleteRenderbuffers(1,&cls->rbo);
glDeleteTextures(1,&cls->depth);
if (!read_depth_supported) {
glDeleteTextures(1,&cls->rgba);
}
//if (!read_depth_supported) {
// glDeleteTextures(1,&cls->rgba);
//}
canvas_light_shadow_owner.free(p_rid);
memdelete(cls);
@ -9904,7 +9999,7 @@ bool RasterizerGLES2::ShadowBuffer::init(int p_size,bool p_use_depth) {
//printf("errnum: %x\n",status);
#ifdef GLEW_ENABLED
if (p_use_depth) {
glDrawBuffer(GL_BACK);
//glDrawBuffer(GL_BACK);
}
#endif
glBindFramebuffer(GL_FRAMEBUFFER, 0);
@ -9913,7 +10008,7 @@ bool RasterizerGLES2::ShadowBuffer::init(int p_size,bool p_use_depth) {
#ifdef GLEW_ENABLED
if (p_use_depth) {
glDrawBuffer(GL_BACK);
//glDrawBuffer(GL_BACK);
}
#endif
@ -10291,6 +10386,62 @@ void RasterizerGLES2::_update_blur_buffer() {
}
#endif
bool RasterizerGLES2::_test_depth_shadow_buffer() {
int size=16;
GLuint fbo;
GLuint rbo;
GLuint depth;
glActiveTexture(GL_TEXTURE0);
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
// Create a render buffer
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
// Create a texture for storing the depth
glGenTextures(1, &depth);
glBindTexture(GL_TEXTURE_2D, depth);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Remove artifact on the edges of the shadowmap
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// We'll use a depth texture to store the depths in the shadow map
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size, size, 0,
GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
#ifdef GLEW_ENABLED
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
#endif
// Attach the depth texture to FBO depth attachment point
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, depth, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
glDeleteFramebuffers(1,&fbo);
glDeleteRenderbuffers(1,&rbo);
glDeleteTextures(1,&depth);
return status == GL_FRAMEBUFFER_COMPLETE;
}
void RasterizerGLES2::init() {
#ifdef GLEW_ENABLED
@ -10363,7 +10514,7 @@ void RasterizerGLES2::init() {
#ifdef GLEW_ENABLED
read_depth_supported=true;
pvr_supported=false;
etc_supported=false;
use_depth24 =true;
@ -10381,7 +10532,10 @@ void RasterizerGLES2::init() {
use_anisotropic_filter=true;
float_linear_supported=true;
float_supported=true;
use_rgba_shadowmaps=false;
read_depth_supported=_test_depth_shadow_buffer();
use_rgba_shadowmaps=!read_depth_supported;
//print_line("read depth support? "+itos(read_depth_supported));
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,&anisotropic_level);
anisotropic_level=MIN(anisotropic_level,float(GLOBAL_DEF("rasterizer/anisotropic_filter_level",4.0)));
@ -10504,6 +10658,7 @@ void RasterizerGLES2::init() {
shadow_mat_ptr = material_owner.get(shadow_material);
overdraw_material = create_overdraw_debug_material();
copy_shader.set_conditional(CopyShaderGLES2::USE_8BIT_HDR,!use_fp16_fb);
canvas_shader.set_conditional(CanvasShaderGLES2::USE_DEPTH_SHADOWS,read_depth_supported);
canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP,GLOBAL_DEF("rasterizer/use_pixel_snap",false));
@ -10521,7 +10676,7 @@ void RasterizerGLES2::init() {
glBindBuffer(GL_ARRAY_BUFFER,0); //unbind
using_canvas_bg=false;
_update_framebuffer();
DEBUG_TEST_ERROR("Initializing");
}

View File

@ -677,6 +677,7 @@ class RasterizerGLES2 : public Rasterizer {
bg_param[VS::ENV_BG_PARAM_ENERGY]=1.0;
bg_param[VS::ENV_BG_PARAM_SCALE]=1.0;
bg_param[VS::ENV_BG_PARAM_GLOW]=0.0;
bg_param[VS::ENV_BG_PARAM_CANVAS_MAX_LAYER]=0;
for(int i=0;i<VS::ENV_FX_MAX;i++)
fx_enabled[i]=false;
@ -1258,6 +1259,7 @@ class RasterizerGLES2 : public Rasterizer {
void _process_hdr();
void _draw_tex_bg();
bool using_canvas_bg;
Size2 window_size;
VS::ViewportRect viewport;
double last_time;
@ -1286,6 +1288,7 @@ class RasterizerGLES2 : public Rasterizer {
void _copy_screen_quad();
void _copy_to_texscreen();
bool _test_depth_shadow_buffer();
Vector3 chunk_vertex;
Vector3 chunk_normal;
@ -1600,6 +1603,8 @@ public:
/* CANVAS API */
virtual void begin_canvas_bg();
virtual void canvas_begin();
virtual void canvas_disable_blending();

View File

@ -266,6 +266,9 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
uses_normal=true;
}
if (vnode->name==vname_shadow) {
uses_shadow_color=true;
}
}
@ -616,6 +619,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
uses_texpixel_size=false;
uses_worldvec=false;
vertex_code_writes_vertex=false;
uses_shadow_color=false;
uniforms=r_uniforms;
flags=&r_flags;
r_flags.use_color_interp=false;
@ -651,6 +655,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
r_flags.uses_normal=uses_normal;
r_flags.uses_texpixel_size=uses_texpixel_size;
r_flags.uses_worldvec=uses_worldvec;
r_flags.uses_shadow_color=uses_shadow_color;
r_code_line=code;
r_globals_line=global_code;
@ -827,7 +832,9 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
mode_replace_table[5]["LIGHT_VEC"]="light_vec";
mode_replace_table[5]["LIGHT_HEIGHT"]="light_height";
mode_replace_table[5]["LIGHT_COLOR"]="light";
mode_replace_table[5]["LIGHT_UV"]="light_uv";
mode_replace_table[5]["LIGHT"]="light_out";
mode_replace_table[5]["SHADOW"]="shadow_color";
mode_replace_table[5]["SCREEN_UV"]="screen_uv";
mode_replace_table[5]["POINT_COORD"]="gl_PointCoord";
mode_replace_table[5]["TIME"]="time";
@ -857,5 +864,6 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
vname_normal="NORMAL";
vname_texpixel_size="TEXTURE_PIXEL_SIZE";
vname_world_vec="WORLD_VERTEX";
vname_shadow="SHADOW";
}

Some files were not shown because too many files have changed in this diff Show More