Merge branch 'master' of github.com:okamstudio/godot
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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 ),
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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; ///<
|
||||
|
||||
|
24
core/os/os.h
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
BIN
demos/2d/area_input/box_area.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
demos/2d/area_input/circle_area.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
4
demos/2d/area_input/engine.cfg
Normal file
@ -0,0 +1,4 @@
|
||||
[application]
|
||||
|
||||
name="Area 2D Input Events"
|
||||
main_scene="res://input.scn"
|
16
demos/2d/area_input/input.gd
Normal 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("")
|
||||
|
||||
|
||||
|
BIN
demos/2d/area_input/input.scn
Normal file
11
demos/2d/fog_of_war/.fscache
Normal 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::
|
12
demos/2d/fog_of_war/engine.cfg
Normal 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)]
|
BIN
demos/2d/fog_of_war/floor.png
Normal file
After Width: | Height: | Size: 572 B |
86
demos/2d/fog_of_war/fog.gd
Normal 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
After Width: | Height: | Size: 31 KiB |
BIN
demos/2d/fog_of_war/fog.scn
Normal file
29
demos/2d/fog_of_war/fog.xml
Normal 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>
|
BIN
demos/2d/fog_of_war/icon.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
1
demos/2d/fog_of_war/icon.png.flags
Normal file
@ -0,0 +1 @@
|
||||
gen_mipmaps=true
|
BIN
demos/2d/fog_of_war/tile_edit.scn
Normal file
43
demos/2d/fog_of_war/troll.gd
Normal 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
|
||||
|
||||
|
BIN
demos/2d/fog_of_war/troll.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
demos/2d/fog_of_war/troll.scn
Normal file
26
demos/2d/hdr/beach_cave.gd
Normal 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
13
demos/2d/hdr/engine.cfg
Normal 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
|
BIN
demos/2d/hdr/ocean_beach.png
Normal file
After Width: | Height: | Size: 433 KiB |
1
demos/2d/hdr/ocean_beach.png.flags
Normal file
@ -0,0 +1 @@
|
||||
tolinear=true
|
BIN
demos/2d/hdr/ocean_cave.png
Normal file
After Width: | Height: | Size: 728 KiB |
1
demos/2d/hdr/ocean_cave.png.flags
Normal file
@ -0,0 +1 @@
|
||||
tolinear=true
|
@ -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
|
||||
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 1.2 KiB |
BIN
demos/2d/light_mask/burano.png
Normal file
After Width: | Height: | Size: 952 KiB |
8
demos/2d/light_mask/engine.cfg
Normal file
@ -0,0 +1,8 @@
|
||||
[application]
|
||||
|
||||
name="Using Lights As Mask"
|
||||
main_scene="res://lightmask.scn"
|
||||
|
||||
[rasterizer]
|
||||
|
||||
shadow_filter=3
|
BIN
demos/2d/light_mask/lightmask.scn
Normal file
BIN
demos/2d/light_mask/splat.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
demos/2d/lights_shadows/bg.png
Normal file
After Width: | Height: | Size: 294 B |
BIN
demos/2d/lights_shadows/caster.png
Normal file
After Width: | Height: | Size: 122 B |
8
demos/2d/lights_shadows/engine.cfg
Normal file
@ -0,0 +1,8 @@
|
||||
[application]
|
||||
|
||||
name="2D Lighting"
|
||||
main_scene="res://light_shadows.scn"
|
||||
|
||||
[rasterizer]
|
||||
|
||||
shadow_filter=2
|
BIN
demos/2d/lights_shadows/light.png
Normal file
After Width: | Height: | Size: 238 KiB |
BIN
demos/2d/lights_shadows/light_shadows.scn
Normal file
BIN
demos/2d/lights_shadows/spot.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
demos/2d/normalmaps/diffuse.jpg
Normal file
After Width: | Height: | Size: 523 KiB |
BIN
demos/2d/normalmaps/diffuse.png
Normal file
After Width: | Height: | Size: 2.3 MiB |
4
demos/2d/normalmaps/engine.cfg
Normal file
@ -0,0 +1,4 @@
|
||||
[application]
|
||||
|
||||
name="2D Normal Mapping"
|
||||
main_scene="res://normalmap.scn"
|
BIN
demos/2d/normalmaps/light.png
Normal file
After Width: | Height: | Size: 238 KiB |
BIN
demos/2d/normalmaps/normal.png
Normal file
After Width: | Height: | Size: 2.2 MiB |
BIN
demos/2d/normalmaps/normal_material.res
Normal file
BIN
demos/2d/normalmaps/normalmap.scn
Normal file
BIN
demos/2d/sdf_font/KaushanScript-Regular.otf
Normal file
4
demos/2d/sdf_font/engine.cfg
Normal 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
BIN
demos/2d/sdf_font/sdf.scn
Normal file
BIN
demos/2d/sprite_shaders/cubio.png
Normal file
After Width: | Height: | Size: 26 KiB |
4
demos/2d/sprite_shaders/engine.cfg
Normal file
@ -0,0 +1,4 @@
|
||||
[application]
|
||||
|
||||
name="2D Shaders for Sprites"
|
||||
main_scene="res://sprite_shaders.scn"
|
BIN
demos/2d/sprite_shaders/sprite_shaders.scn
Normal file
BIN
demos/2d/texscreen/OpenCV_Chessboard.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
demos/2d/texscreen/bubble.png
Normal file
After Width: | Height: | Size: 18 KiB |
17
demos/2d/texscreen/bubbles.gd
Normal 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
|
||||
|
||||
|
BIN
demos/2d/texscreen/bubbles.scn
Normal file
BIN
demos/2d/texscreen/burano.png
Normal file
After Width: | Height: | Size: 952 KiB |
4
demos/2d/texscreen/engine.cfg
Normal file
@ -0,0 +1,4 @@
|
||||
[application]
|
||||
|
||||
name="Glass Bubbles (Texscreen)"
|
||||
main_scene="res://bubbles.scn"
|
37
demos/2d/texscreen/lens.gd
Normal 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
BIN
demos/gui/drag_and_drop/drag_and_drop.scn
Normal file
24
demos/gui/drag_and_drop/drag_drop_script.gd
Normal 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)
|
||||
|
||||
|
4
demos/gui/drag_and_drop/engine.cfg
Normal file
@ -0,0 +1,4 @@
|
||||
[application]
|
||||
|
||||
name="Drag & Drop (GUI)"
|
||||
main_scene="res://drag_and_drop.scn"
|
177
demos/misc/window_management/control.gd
Normal 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
|
19
demos/misc/window_management/engine.cfg
Normal 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)]
|
BIN
demos/misc/window_management/icon.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
1
demos/misc/window_management/icon.png.flags
Normal file
@ -0,0 +1 @@
|
||||
gen_mipmaps=false
|
79
demos/misc/window_management/observer/observer.gd
Normal 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
|
||||
|
BIN
demos/misc/window_management/observer/observer.scn
Normal file
BIN
demos/misc/window_management/window_management.scn
Normal 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
|
||||
|
||||
|
||||
|
@ -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" >
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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";
|
||||
|
||||
}
|
||||
|