From 97d290e466bfdf1bb0fa68d828c3a3cb13f138de Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sat, 10 Jan 2015 15:47:34 +0800 Subject: x11-fullscreen support through GDScript( OS.set_fullscreen(bool) ) --- platform/x11/os_x11.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ platform/x11/os_x11.h | 3 +++ 2 files changed, 52 insertions(+) (limited to 'platform') diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index aa9e4c63c..bf0bef15d 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -521,6 +521,55 @@ void OS_X11::get_fullscreen_mode_list(List *p_list,int p_screen) cons } +void OS_X11::set_fullscreen(bool p_fullscreen) { + + long wm_action; + + if(p_fullscreen) { + current_videomode.fullscreen = True; + wm_action = 1; + } else { + current_videomode.fullscreen = False; + wm_action = 0; + } + + /* + // MSC: Disabled until I can test it with lxde + // + // needed for lxde/openbox, possibly others + Hints hints; + Atom property; + hints.flags = 2; + hints.decorations = 0; + property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); + XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); + XMapRaised(x11_display, x11_window); + XWindowAttributes xwa; + XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa); + XMoveResizeWindow(x11_display, x11_window, 0, 0, xwa.width, xwa.height); + */ + + // code for netwm-compliants + XEvent xev; + Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); + Atom wm_fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False); + + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = x11_window; + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = wm_action; + xev.xclient.data.l[1] = wm_fullscreen; + xev.xclient.data.l[2] = 0; + + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); + + visual_server->init(); +} + +bool OS_X11::is_fullscreen() const { +} InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) { diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index dd2476ec1..e92bd6e08 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -213,6 +213,9 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const; virtual void get_fullscreen_mode_list(List *p_list,int p_screen=0) const; + virtual void set_fullscreen(bool p_fullscreen); + virtual bool is_fullscreen() const; + virtual void move_window_to_foreground(); void run(); -- cgit v1.2.3-70-g09d2 From cd90215ceca03b456aad761da935c92058b0da6a Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sat, 10 Jan 2015 16:01:01 +0800 Subject: Make GDScript-Function ( bool OS.is_fullscreen() ) work --- platform/x11/os_x11.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'platform') diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index bf0bef15d..79051b2ac 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -569,6 +569,7 @@ void OS_X11::set_fullscreen(bool p_fullscreen) { } bool OS_X11::is_fullscreen() const { + return current_videomode.fullscreen; } InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) { -- cgit v1.2.3-70-g09d2 From 0d2ec19082e9ebff07ab1ab8e365e2db9ee3268b Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sat, 10 Jan 2015 18:38:30 +0800 Subject: API change to set_fullscreen(enabled,screen) --- core/bind/core_bind.cpp | 6 +++--- core/bind/core_bind.h | 2 +- core/os/os.h | 2 +- platform/x11/os_x11.cpp | 4 ++-- platform/x11/os_x11.h | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) (limited to 'platform') diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 0d24486e9..62d93745a 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -176,8 +176,8 @@ bool _OS::is_video_mode_fullscreen(int p_screen) const { } -void _OS::set_fullscreen(bool p_fullscreen) { - OS::get_singleton()->set_fullscreen(p_fullscreen); +void _OS::set_fullscreen(bool p_enabled,int p_screen) { + OS::get_singleton()->set_fullscreen(p_enabled, p_screen); } bool _OS::is_fullscreen() const { @@ -641,7 +641,7 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_fullscreen_mode_list","screen"),&_OS::get_fullscreen_mode_list,DEFVAL(0)); //MSC - ObjectTypeDB::bind_method(_MD("set_fullscreen","fullscreen"),&_OS::set_fullscreen); + ObjectTypeDB::bind_method(_MD("set_fullscreen","enabled","screen"),&_OS::set_fullscreen,DEFVAL(0)); ObjectTypeDB::bind_method(_MD("is_fullscreen"),&_OS::is_fullscreen); ObjectTypeDB::bind_method(_MD("set_iterations_per_second","iterations_per_second"),&_OS::set_iterations_per_second); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 97aff87bc..fedd03c3a 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -109,7 +109,7 @@ public: Array get_fullscreen_mode_list(int p_screen=0) const; //MSC - void set_fullscreen(bool p_fullscreen); + void set_fullscreen(bool p_enabled, int p_screen=0); bool is_fullscreen() const; Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track); diff --git a/core/os/os.h b/core/os/os.h index e8de28e86..b86b12262 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -151,7 +151,7 @@ public: virtual void get_fullscreen_mode_list(List *p_list,int p_screen=0) const=0; //MSC - virtual void set_fullscreen(bool fullscreen)=0; + virtual void set_fullscreen(bool p_enabled,int p_screen=0)=0; virtual bool is_fullscreen() const=0; virtual void set_iterations_per_second(int p_ips); diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 79051b2ac..6dd2d7426 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -521,11 +521,11 @@ void OS_X11::get_fullscreen_mode_list(List *p_list,int p_screen) cons } -void OS_X11::set_fullscreen(bool p_fullscreen) { +void OS_X11::set_fullscreen(bool p_enabled,int p_screen) { long wm_action; - if(p_fullscreen) { + if(p_enabled) { current_videomode.fullscreen = True; wm_action = 1; } else { diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index e92bd6e08..f382e21ed 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -166,8 +166,8 @@ protected: virtual const char * get_video_driver_name(int p_driver) const; virtual VideoMode get_default_video_mode() const; - virtual int get_audio_driver_count() const; - virtual const char * get_audio_driver_name(int p_driver) const; + virtual int get_audio_driver_count() const; + virtual const char * get_audio_driver_name(int p_driver) const; virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver); virtual void finalize(); @@ -213,7 +213,7 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const; virtual void get_fullscreen_mode_list(List *p_list,int p_screen=0) const; - virtual void set_fullscreen(bool p_fullscreen); + virtual void set_fullscreen(bool p_enabled,int p_screen=0); virtual bool is_fullscreen() const; virtual void move_window_to_foreground(); -- cgit v1.2.3-70-g09d2 From 5d9de48d8d35961835135a7310840cdc9cbacb63 Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sat, 10 Jan 2015 21:50:31 +0800 Subject: Make fullscreen-switching is working with LXDE/Openbox --- platform/x11/os_x11.cpp | 90 +++++++++++++++++++++++-------------------------- platform/x11/os_x11.h | 4 +++ 2 files changed, 46 insertions(+), 48 deletions(-) (limited to 'platform') diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 6dd2d7426..707868ccb 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -182,33 +182,8 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi // borderless fullscreen window mode if (current_videomode.fullscreen) { - // needed for lxde/openbox, possibly others - Hints hints; - Atom property; - hints.flags = 2; - hints.decorations = 0; - property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); - XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); - XMapRaised(x11_display, x11_window); - XWindowAttributes xwa; - XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa); - XMoveResizeWindow(x11_display, x11_window, 0, 0, xwa.width, xwa.height); - - // code for netwm-compliants - XEvent xev; - Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); - Atom fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False); - - memset(&xev, 0, sizeof(xev)); - xev.type = ClientMessage; - xev.xclient.window = x11_window; - xev.xclient.message_type = wm_state; - xev.xclient.format = 32; - xev.xclient.data.l[0] = 1; - xev.xclient.data.l[1] = fullscreen; - xev.xclient.data.l[2] = 0; - - XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); + set_wm_border(false); + set_wm_fullscreen(true); } // disable resizeable window @@ -521,34 +496,19 @@ void OS_X11::get_fullscreen_mode_list(List *p_list,int p_screen) cons } -void OS_X11::set_fullscreen(bool p_enabled,int p_screen) { - - long wm_action; - - if(p_enabled) { - current_videomode.fullscreen = True; - wm_action = 1; - } else { - current_videomode.fullscreen = False; - wm_action = 0; - } - - /* - // MSC: Disabled until I can test it with lxde - // +void OS_X11::set_wm_border(bool p_enabled) { // needed for lxde/openbox, possibly others Hints hints; Atom property; hints.flags = 2; - hints.decorations = 0; + hints.decorations = p_enabled ? 1L : 0L;; property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); XMapRaised(x11_display, x11_window); - XWindowAttributes xwa; - XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa); - XMoveResizeWindow(x11_display, x11_window, 0, 0, xwa.width, xwa.height); - */ + XMoveResizeWindow(x11_display, x11_window, 0, 0, current_videomode.width, current_videomode.height); +} +void OS_X11::set_wm_fullscreen(bool p_enabled) { // code for netwm-compliants XEvent xev; Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); @@ -559,11 +519,45 @@ void OS_X11::set_fullscreen(bool p_enabled,int p_screen) { xev.xclient.window = x11_window; xev.xclient.message_type = wm_state; xev.xclient.format = 32; - xev.xclient.data.l[0] = wm_action; + xev.xclient.data.l[0] = p_enabled ? 1L : 0L; xev.xclient.data.l[1] = wm_fullscreen; xev.xclient.data.l[2] = 0; XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); +} + +void OS_X11::set_fullscreen(bool p_enabled,int p_screen) { + + long wm_action; + long wm_decoration; + + if(p_enabled) { + wm_action = 1L; + wm_decoration = 0L; // Removes all decorations + + pre_videomode = current_videomode; + + // Get Desktop resolutuion + XWindowAttributes xwa; + XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa); + + current_videomode.fullscreen = True; + current_videomode.width = xwa.width; + current_videomode.height = xwa.height; + + set_wm_border(false); + set_wm_fullscreen(true); + } else { + wm_action = 0L; + wm_decoration = 1L; // MWM_DECORE_ALL (1L << 0) + + current_videomode.fullscreen = False; + current_videomode.width = pre_videomode.width; + current_videomode.height = pre_videomode.height; + + set_wm_fullscreen(false); + set_wm_border(true); + } visual_server->init(); } diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index f382e21ed..11842ace8 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -73,6 +73,7 @@ class OS_X11 : public OS_Unix { Rasterizer *rasterizer; VisualServer *visual_server; VideoMode current_videomode; + VideoMode pre_videomode; List args; Window x11_window; MainLoop *main_loop; @@ -159,6 +160,8 @@ class OS_X11 : public OS_Unix { int joystick_count; Joystick joysticks[JOYSTICKS_MAX]; + void set_wm_border(bool p_enabled); + void set_wm_fullscreen(bool p_enabled); protected: @@ -178,6 +181,7 @@ protected: void process_joysticks(); void close_joystick(int p_id = -1); + public: virtual String get_name(); -- cgit v1.2.3-70-g09d2 From a8e3c5c0b7fb202bcceb06b9373b5b6a4ff8f9b8 Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sun, 11 Jan 2015 01:07:23 +0800 Subject: First attempt of restoring the window at the old position --- core/os/os.h | 5 +++-- main/main.cpp | 7 ++++++- platform/x11/os_x11.cpp | 40 +++++++++++++++++++++++++++++----------- 3 files changed, 38 insertions(+), 14 deletions(-) (limited to 'platform') diff --git a/core/os/os.h b/core/os/os.h index b86b12262..9de2e3556 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -69,11 +69,12 @@ public: }; struct VideoMode { - int width,height; + int x,y,width,height; 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_x=0, int p_y=0,int p_width=640,int p_height=480,bool p_fullscreen=false, bool p_resizable = true) + { x=p_x; y=p_y; width=p_width; height=p_height; fullscreen=p_fullscreen; resizable = p_resizable; } }; protected: friend class Main; diff --git a/main/main.cpp b/main/main.cpp index f0e376a04..b6638a3ad 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -609,6 +609,10 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas if (video_driver=="") // specified in engine.cfg video_driver=_GLOBAL_DEF("display/driver",Variant((const char*)OS::get_singleton()->get_video_driver_name(0))); + if (!force_res && use_custom_res && globals->has("display/x")) + video_mode.width=globals->get("display/y"); + if (!force_res && use_custom_res && globals->has("display/width")) + video_mode.width=globals->get("display/width"); if (!force_res && use_custom_res && globals->has("display/width")) video_mode.width=globals->get("display/width"); if (!force_res &&use_custom_res && globals->has("display/height")) @@ -627,7 +631,8 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas } } - + GLOBAL_DEF("display/x",video_mode.x); + GLOBAL_DEF("display/y",video_mode.y); GLOBAL_DEF("display/width",video_mode.width); GLOBAL_DEF("display/height",video_mode.height); GLOBAL_DEF("display/fullscreen",video_mode.fullscreen); diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 707868ccb..9e02f54dd 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -71,7 +71,7 @@ const char * OS_X11::get_video_driver_name(int p_driver) const { } OS::VideoMode OS_X11::get_default_video_mode() const { - return OS::VideoMode(800,600,false); + return OS::VideoMode(0,0,800,600,false); } int OS_X11::get_audio_driver_count() const { @@ -163,6 +163,18 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi // maybe contextgl wants to be in charge of creating the window //print_line("def videomode "+itos(current_videomode.width)+","+itos(current_videomode.height)); #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) + if( current_videomode.x > current_videomode.width || + current_videomode.y > current_videomode.height || + current_videomode.width==0 || + current_videomode.height==0) { + + current_videomode.x = 0; + current_videomode.y = 0; + current_videomode.width = 640; + current_videomode.height = 480; + } + + context_gl = memnew( ContextGL_X11( x11_display, x11_window,current_videomode, false ) ); context_gl->initialize(); @@ -505,7 +517,7 @@ void OS_X11::set_wm_border(bool p_enabled) { property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); XMapRaised(x11_display, x11_window); - XMoveResizeWindow(x11_display, x11_window, 0, 0, current_videomode.width, current_videomode.height); + XMoveResizeWindow(x11_display, x11_window, current_videomode.x, current_videomode.y, current_videomode.width, current_videomode.height); } void OS_X11::set_wm_fullscreen(bool p_enabled) { @@ -528,17 +540,24 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) { void OS_X11::set_fullscreen(bool p_enabled,int p_screen) { - long wm_action; - long wm_decoration; - if(p_enabled) { - wm_action = 1L; - wm_decoration = 0L; // Removes all decorations + XWindowAttributes xwa; + XGetWindowAttributes(x11_display, x11_window, &xwa); + + print_line(itos(xwa.x)); + print_line(itos(xwa.y)); + print_line(itos(xwa.width)); + print_line(itos(xwa.height)); + + current_videomode.x = xwa.x; + current_videomode.y = xwa.y; + current_videomode.width = xwa.width; + current_videomode.height = xwa.height; + pre_videomode = current_videomode; // Get Desktop resolutuion - XWindowAttributes xwa; XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa); current_videomode.fullscreen = True; @@ -548,10 +567,9 @@ void OS_X11::set_fullscreen(bool p_enabled,int p_screen) { set_wm_border(false); set_wm_fullscreen(true); } else { - wm_action = 0L; - wm_decoration = 1L; // MWM_DECORE_ALL (1L << 0) - current_videomode.fullscreen = False; + current_videomode.x = pre_videomode.x; + current_videomode.y = pre_videomode.y; current_videomode.width = pre_videomode.width; current_videomode.height = pre_videomode.height; -- cgit v1.2.3-70-g09d2 From ac558c15eaeb45b3e7ae2604e26ca1dffb60b779 Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sun, 11 Jan 2015 15:47:27 +0800 Subject: get_window_position() + set_window_position() added --- core/bind/core_bind.cpp | 10 ++++++ core/bind/core_bind.h | 2 ++ core/os/os.h | 7 ++-- main/main.cpp | 6 ---- platform/x11/os_x11.cpp | 86 ++++++++++++++++++++++++++++++++----------------- platform/x11/os_x11.h | 2 ++ 6 files changed, 74 insertions(+), 39 deletions(-) (limited to 'platform') diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 62d93745a..3109b8bc8 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -176,6 +176,14 @@ bool _OS::is_video_mode_fullscreen(int p_screen) const { } +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); +} + void _OS::set_fullscreen(bool p_enabled,int p_screen) { OS::get_singleton()->set_fullscreen(p_enabled, p_screen); } @@ -641,6 +649,8 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_fullscreen_mode_list","screen"),&_OS::get_fullscreen_mode_list,DEFVAL(0)); //MSC + 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("set_fullscreen","enabled","screen"),&_OS::set_fullscreen,DEFVAL(0)); ObjectTypeDB::bind_method(_MD("is_fullscreen"),&_OS::is_fullscreen); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index fedd03c3a..92056aa0d 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -109,6 +109,8 @@ public: Array get_fullscreen_mode_list(int p_screen=0) const; //MSC + virtual Point2 get_window_position() const; + virtual void set_window_position(const Point2& p_position); void set_fullscreen(bool p_enabled, int p_screen=0); bool is_fullscreen() const; diff --git a/core/os/os.h b/core/os/os.h index 9de2e3556..9089e7de7 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -69,12 +69,11 @@ public: }; struct VideoMode { - int x,y,width,height; + int width,height; bool fullscreen; bool resizable; float get_aspect() const { return (float)width/(float)height; } - VideoMode(int p_x=0, int p_y=0,int p_width=640,int p_height=480,bool p_fullscreen=false, bool p_resizable = true) - { x=p_x; y=p_y; 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; @@ -152,6 +151,8 @@ public: virtual void get_fullscreen_mode_list(List *p_list,int p_screen=0) const=0; //MSC + virtual Point2 get_window_position() const=0; + virtual void set_window_position(const Point2& p_position)=0; virtual void set_fullscreen(bool p_enabled,int p_screen=0)=0; virtual bool is_fullscreen() const=0; diff --git a/main/main.cpp b/main/main.cpp index b6638a3ad..27d7d97e8 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -609,10 +609,6 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas if (video_driver=="") // specified in engine.cfg video_driver=_GLOBAL_DEF("display/driver",Variant((const char*)OS::get_singleton()->get_video_driver_name(0))); - if (!force_res && use_custom_res && globals->has("display/x")) - video_mode.width=globals->get("display/y"); - if (!force_res && use_custom_res && globals->has("display/width")) - video_mode.width=globals->get("display/width"); if (!force_res && use_custom_res && globals->has("display/width")) video_mode.width=globals->get("display/width"); if (!force_res &&use_custom_res && globals->has("display/height")) @@ -631,8 +627,6 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas } } - GLOBAL_DEF("display/x",video_mode.x); - GLOBAL_DEF("display/y",video_mode.y); GLOBAL_DEF("display/width",video_mode.width); GLOBAL_DEF("display/height",video_mode.height); GLOBAL_DEF("display/fullscreen",video_mode.fullscreen); diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 5a0545591..502d510f5 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -70,7 +70,7 @@ const char * OS_X11::get_video_driver_name(int p_driver) const { } OS::VideoMode OS_X11::get_default_video_mode() const { - return OS::VideoMode(0,0,800,600,false); + return OS::VideoMode(800,600,false); } int OS_X11::get_audio_driver_count() const { @@ -162,17 +162,6 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi // maybe contextgl wants to be in charge of creating the window //print_line("def videomode "+itos(current_videomode.width)+","+itos(current_videomode.height)); #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) - if( current_videomode.x > current_videomode.width || - current_videomode.y > current_videomode.height || - current_videomode.width==0 || - current_videomode.height==0) { - - current_videomode.x = 0; - current_videomode.y = 0; - current_videomode.width = 640; - current_videomode.height = 480; - } - context_gl = memnew( ContextGL_X11( x11_display, x11_window,current_videomode, false ) ); context_gl->initialize(); @@ -516,7 +505,7 @@ void OS_X11::set_wm_border(bool p_enabled) { property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); XMapRaised(x11_display, x11_window); - XMoveResizeWindow(x11_display, x11_window, current_videomode.x, current_videomode.y, current_videomode.width, current_videomode.height); + XMoveResizeWindow(x11_display, x11_window, 0, 0, current_videomode.width, current_videomode.height); } void OS_X11::set_wm_fullscreen(bool p_enabled) { @@ -537,26 +526,65 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) { XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); } -void OS_X11::set_fullscreen(bool p_enabled,int p_screen) { +Point2 OS_X11::get_window_position() const { + int x,y; + XWindowAttributes xwa; + Window child; + XTranslateCoordinates( x11_display, x11_window, DefaultRootWindow(x11_display), 0, 0, &x, &y, &child); + XGetWindowAttributes(x11_display, x11_window, &xwa); - if(p_enabled) { - XWindowAttributes xwa; - XGetWindowAttributes(x11_display, x11_window, &xwa); + return Point2i(x,y); +} - print_line(itos(xwa.x)); - print_line(itos(xwa.y)); - print_line(itos(xwa.width)); - print_line(itos(xwa.height)); - - current_videomode.x = xwa.x; - current_videomode.y = xwa.y; - current_videomode.width = xwa.width; - current_videomode.height = xwa.height; - +void OS_X11::set_window_position(const Point2& p_position) { + // _NET_FRAME_EXTENTS + Atom property = XInternAtom(x11_display,"_NET_FRAME_EXTENTS", True); + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = NULL; + //long *extends; + int result; + + result = XGetWindowProperty( + x11_display, + x11_window, + property, + 0, + 32, + False, + AnyPropertyType, + &type, + &format, + &len, + &remaining, + &data + ); + + long left = 0L; + long top = 0L; + + if( result == Success ) { + long *extends = (long *) data; + + left = extends[0]; + top = extends[2]; + + XFree(data); + data = NULL; + } + + XMoveWindow(x11_display,x11_window,p_position.x - left,p_position.y - top); +} + +void OS_X11::set_fullscreen(bool p_enabled,int p_screen) { + + if(p_enabled) { pre_videomode = current_videomode; - // Get Desktop resolutuion + XWindowAttributes xwa; XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa); current_videomode.fullscreen = True; @@ -567,8 +595,6 @@ void OS_X11::set_fullscreen(bool p_enabled,int p_screen) { set_wm_fullscreen(true); } else { current_videomode.fullscreen = False; - current_videomode.x = pre_videomode.x; - current_videomode.y = pre_videomode.y; current_videomode.width = pre_videomode.width; current_videomode.height = pre_videomode.height; diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 11842ace8..ad7364f99 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -217,6 +217,8 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const; virtual void get_fullscreen_mode_list(List *p_list,int p_screen=0) const; + virtual Point2 get_window_position() const; + virtual void set_window_position(const Point2& p_position); virtual void set_fullscreen(bool p_enabled,int p_screen=0); virtual bool is_fullscreen() const; -- cgit v1.2.3-70-g09d2 From 466e251abecf3686f0caac40ab886155e43cc0a6 Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sun, 11 Jan 2015 17:36:56 +0800 Subject: get_window_size() + set_window_size() added --- core/bind/core_bind.cpp | 11 ++++++++++- core/bind/core_bind.h | 3 ++- core/os/os.h | 3 ++- platform/x11/os_x11.cpp | 18 +++++++++++++++++- platform/x11/os_x11.h | 2 ++ 5 files changed, 33 insertions(+), 4 deletions(-) (limited to 'platform') diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 3109b8bc8..2b4e2e123 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -184,6 +184,14 @@ 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_fullscreen(bool p_enabled,int p_screen) { OS::get_singleton()->set_fullscreen(p_enabled, p_screen); } @@ -648,9 +656,10 @@ 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)); - //MSC 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_fullscreen","enabled","screen"),&_OS::set_fullscreen,DEFVAL(0)); ObjectTypeDB::bind_method(_MD("is_fullscreen"),&_OS::is_fullscreen); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 92056aa0d..e60bb5e66 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -108,9 +108,10 @@ public: bool is_video_mode_resizable(int p_screen=0) const; Array get_fullscreen_mode_list(int p_screen=0) const; - //MSC 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); void set_fullscreen(bool p_enabled, int p_screen=0); bool is_fullscreen() const; diff --git a/core/os/os.h b/core/os/os.h index 9089e7de7..7e9fdcc57 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -150,9 +150,10 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const=0; virtual void get_fullscreen_mode_list(List *p_list,int p_screen=0) const=0; - //MSC virtual Point2 get_window_position() const=0; virtual void set_window_position(const Point2& p_position)=0; + virtual Size2 get_window_size() const=0; + virtual void set_window_size(const Size2 p_size)=0; virtual void set_fullscreen(bool p_enabled,int p_screen=0)=0; virtual bool is_fullscreen() const=0; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 502d510f5..f21ea4c9a 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -537,8 +537,11 @@ Point2 OS_X11::get_window_position() const { } void OS_X11::set_window_position(const Point2& p_position) { - // _NET_FRAME_EXTENTS + if( current_videomode.fullscreen ) + return; + + // _NET_FRAME_EXTENTS Atom property = XInternAtom(x11_display,"_NET_FRAME_EXTENTS", True); Atom type; int format; @@ -579,6 +582,19 @@ void OS_X11::set_window_position(const Point2& p_position) { XMoveWindow(x11_display,x11_window,p_position.x - left,p_position.y - top); } +Size2 OS_X11::get_window_size() const { + XWindowAttributes xwa; + XGetWindowAttributes(x11_display, x11_window, &xwa); + return Size2i(xwa.width, xwa.height); +} + +void OS_X11::set_window_size(const Size2 p_size) { + if( current_videomode.fullscreen ) + return; + + XResizeWindow(x11_display, x11_window, p_size.x, p_size.y); +} + void OS_X11::set_fullscreen(bool p_enabled,int p_screen) { if(p_enabled) { diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index ad7364f99..1cedea422 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -219,6 +219,8 @@ public: 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_fullscreen(bool p_enabled,int p_screen=0); virtual bool is_fullscreen() const; -- cgit v1.2.3-70-g09d2 From 3c8b047b111cf20b3823851e298ce42bdf941871 Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sun, 11 Jan 2015 18:52:42 +0800 Subject: get_screen_count() added --- core/bind/core_bind.cpp | 5 +++++ core/bind/core_bind.h | 1 + core/os/os.h | 1 + platform/x11/os_x11.cpp | 7 +++++++ platform/x11/os_x11.h | 1 + 5 files changed, 15 insertions(+) (limited to 'platform') diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 2b4e2e123..3f86efc87 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -176,6 +176,10 @@ bool _OS::is_video_mode_fullscreen(int p_screen) const { } +int _OS::get_screen_count() const { + return OS::get_singleton()->get_screen_count(); +} + Point2 _OS::get_window_position() const { return OS::get_singleton()->get_window_position(); } @@ -656,6 +660,7 @@ 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_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); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index e60bb5e66..cb9a5da47 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -108,6 +108,7 @@ 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 Point2 get_window_position() const; virtual void set_window_position(const Point2& p_position); virtual Size2 get_window_size() const; diff --git a/core/os/os.h b/core/os/os.h index 7e9fdcc57..68769e7ad 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -150,6 +150,7 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const=0; virtual void get_fullscreen_mode_list(List *p_list,int p_screen=0) const=0; + virtual int get_screen_count() const=0; virtual Point2 get_window_position() const=0; virtual void set_window_position(const Point2& p_position)=0; virtual Size2 get_window_size() const=0; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index f21ea4c9a..c37358139 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -526,6 +526,10 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) { XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); } +int OS_X11::get_screen_count() const { + return XScreenCount(x11_display); +} + Point2 OS_X11::get_window_position() const { int x,y; XWindowAttributes xwa; @@ -597,6 +601,9 @@ void OS_X11::set_window_size(const Size2 p_size) { void OS_X11::set_fullscreen(bool p_enabled,int p_screen) { + if(p_enabled && current_videomode.fullscreen) + return; + if(p_enabled) { pre_videomode = current_videomode; diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 1cedea422..f55b7dc0e 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -217,6 +217,7 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const; virtual void get_fullscreen_mode_list(List *p_list,int p_screen=0) const; + virtual int get_screen_count() const; virtual Point2 get_window_position() const; virtual void set_window_position(const Point2& p_position); virtual Size2 get_window_size() const; -- cgit v1.2.3-70-g09d2 From f9d0de0d2a82456f3553499fcbc1c487b59fed1c Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sun, 11 Jan 2015 19:35:53 +0800 Subject: get_screen_size() added --- core/bind/core_bind.cpp | 5 +++++ core/bind/core_bind.h | 1 + core/os/os.h | 1 + platform/x11/os_x11.cpp | 8 ++++++++ platform/x11/os_x11.h | 1 + 5 files changed, 16 insertions(+) (limited to 'platform') diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 3f86efc87..47bfba1cb 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -180,6 +180,10 @@ int _OS::get_screen_count() const { return OS::get_singleton()->get_screen_count(); } +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(); } @@ -661,6 +665,7 @@ void _OS::_bind_methods() { 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_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); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index cb9a5da47..2a87f85ec 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -109,6 +109,7 @@ public: Array get_fullscreen_mode_list(int p_screen=0) const; virtual int get_screen_count() 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; diff --git a/core/os/os.h b/core/os/os.h index 68769e7ad..edb5d57c5 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -151,6 +151,7 @@ public: virtual void get_fullscreen_mode_list(List *p_list,int p_screen=0) const=0; virtual int get_screen_count() const=0; + virtual Size2 get_screen_size(int p_screen=0) const=0; virtual Point2 get_window_position() const=0; virtual void set_window_position(const Point2& p_position)=0; virtual Size2 get_window_size() const=0; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index c37358139..063fb17c2 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -530,6 +530,14 @@ int OS_X11::get_screen_count() const { return XScreenCount(x11_display); } +Size2 OS_X11::get_screen_size(int p_screen) const { + Window root = XRootWindow(x11_display, p_screen); + XWindowAttributes xwa; + XGetWindowAttributes(x11_display, root, &xwa); + return Size2i(xwa.width, xwa.height); +} + + Point2 OS_X11::get_window_position() const { int x,y; XWindowAttributes xwa; diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index f55b7dc0e..a38d51100 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -218,6 +218,7 @@ public: virtual void get_fullscreen_mode_list(List *p_list,int p_screen=0) const; virtual int get_screen_count() 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; -- cgit v1.2.3-70-g09d2 From c0d363266755de3ac87f61600f23921d881d99e2 Mon Sep 17 00:00:00 2001 From: hurikhan Date: Tue, 13 Jan 2015 15:44:39 +0800 Subject: introduced the scons experimental_wm_api switch: ================================================ Usage: scons p=x11 experimental_wm_api=yes --- core/bind/core_bind.cpp | 4 ++++ core/bind/core_bind.h | 2 ++ core/os/os.h | 4 +++- platform/x11/detect.py | 4 ++++ platform/x11/os_x11.cpp | 32 ++++++++++++++++++++++++++++++++ platform/x11/os_x11.h | 7 +++++-- 6 files changed, 50 insertions(+), 3 deletions(-) (limited to 'platform') diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 47bfba1cb..b8fc63dc4 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -176,6 +176,7 @@ bool _OS::is_video_mode_fullscreen(int p_screen) const { } +#ifdef EXPERIMENTAL_WM_API int _OS::get_screen_count() const { return OS::get_singleton()->get_screen_count(); } @@ -207,6 +208,7 @@ void _OS::set_fullscreen(bool p_enabled,int p_screen) { bool _OS::is_fullscreen() const { return OS::get_singleton()->is_fullscreen(); } +#endif void _OS::set_use_file_access_save_and_swap(bool p_enable) { @@ -664,6 +666,7 @@ 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)); +#ifdef EXPERIMENTAL_WM_API ObjectTypeDB::bind_method(_MD("get_screen_count"),&_OS::get_screen_count); ObjectTypeDB::bind_method(_MD("get_screen_size"),&_OS::get_screen_size,DEFVAL(0)); ObjectTypeDB::bind_method(_MD("get_window_position"),&_OS::get_window_position); @@ -672,6 +675,7 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_window_size"),&_OS::set_window_size); ObjectTypeDB::bind_method(_MD("set_fullscreen","enabled","screen"),&_OS::set_fullscreen,DEFVAL(0)); ObjectTypeDB::bind_method(_MD("is_fullscreen"),&_OS::is_fullscreen); +#endif 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); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 2a87f85ec..62f991355 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -108,6 +108,7 @@ public: bool is_video_mode_resizable(int p_screen=0) const; Array get_fullscreen_mode_list(int p_screen=0) const; +#ifdef EXPERIMENTAL_WM_API virtual int get_screen_count() const; virtual Size2 get_screen_size(int p_screen=0) const; virtual Point2 get_window_position() const; @@ -116,6 +117,7 @@ public: virtual void set_window_size(const Size2& p_size); void set_fullscreen(bool p_enabled, int p_screen=0); bool is_fullscreen() const; +#endif Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track); bool native_video_is_playing(); diff --git a/core/os/os.h b/core/os/os.h index edb5d57c5..c2534287b 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -150,6 +150,7 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const=0; virtual void get_fullscreen_mode_list(List *p_list,int p_screen=0) const=0; +#ifdef EXPERIMENTAL_WM_API virtual int get_screen_count() const=0; virtual Size2 get_screen_size(int p_screen=0) const=0; virtual Point2 get_window_position() const=0; @@ -158,7 +159,8 @@ public: virtual void set_window_size(const Size2 p_size)=0; virtual void set_fullscreen(bool p_enabled,int p_screen=0)=0; virtual bool is_fullscreen() const=0; - +#endif + virtual void set_iterations_per_second(int p_ips); virtual int get_iterations_per_second() const; diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 621a0c66a..954e5270e 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -47,6 +47,7 @@ def get_opts(): return [ ('use_llvm','Use llvm compiler','no'), ('use_sanitizer','Use llvm compiler sanitize address','no'), + ('experimental_wm_api', 'Use experimental window management API','no'), ] def get_flags(): @@ -148,3 +149,6 @@ def configure(env): env.Append( BUILDERS = { 'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl') } ) #env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } ) + if(env["experimental_wm_api"]=="yes"): + env.Append(CPPFLAGS=['-DEXPERIMENTAL_WM_API']) + diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 063fb17c2..e20d0731e 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -182,8 +182,38 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi // borderless fullscreen window mode if (current_videomode.fullscreen) { +#ifndef EXPERIMENTAL_WM_API + // needed for lxde/openbox, possibly others + Hints hints; + Atom property; + hints.flags = 2; + hints.decorations = 0; + property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); + XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); + XMapRaised(x11_display, x11_window); + XWindowAttributes xwa; + XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa); + XMoveResizeWindow(x11_display, x11_window, 0, 0, xwa.width, xwa.height); + + // code for netwm-compliants + XEvent xev; + Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); + Atom fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False); + + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = x11_window; + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = 1; + xev.xclient.data.l[1] = fullscreen; + xev.xclient.data.l[2] = 0; + + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); +#else set_wm_border(false); set_wm_fullscreen(true); +#endif } // disable resizeable window @@ -496,6 +526,7 @@ void OS_X11::get_fullscreen_mode_list(List *p_list,int p_screen) cons } +#ifdef EXPERIMENTAL_WM_API void OS_X11::set_wm_border(bool p_enabled) { // needed for lxde/openbox, possibly others Hints hints; @@ -639,6 +670,7 @@ void OS_X11::set_fullscreen(bool p_enabled,int p_screen) { bool OS_X11::is_fullscreen() const { return current_videomode.fullscreen; } +#endif InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) { diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index a38d51100..4aca996fd 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -73,7 +73,6 @@ class OS_X11 : public OS_Unix { Rasterizer *rasterizer; VisualServer *visual_server; VideoMode current_videomode; - VideoMode pre_videomode; List args; Window x11_window; MainLoop *main_loop; @@ -160,8 +159,11 @@ class OS_X11 : public OS_Unix { int joystick_count; Joystick joysticks[JOYSTICKS_MAX]; +#ifdef EXPERIMENTAL_WM_API + VideoMode pre_videomode; void set_wm_border(bool p_enabled); void set_wm_fullscreen(bool p_enabled); +#endif protected: @@ -217,6 +219,7 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const; virtual void get_fullscreen_mode_list(List *p_list,int p_screen=0) const; +#ifdef EXPERIMENTAL_WM_API virtual int get_screen_count() const; virtual Size2 get_screen_size(int p_screen=0) const; virtual Point2 get_window_position() const; @@ -225,7 +228,7 @@ public: virtual void set_window_size(const Size2 p_size); virtual void set_fullscreen(bool p_enabled,int p_screen=0); virtual bool is_fullscreen() const; - +#endif virtual void move_window_to_foreground(); void run(); -- cgit v1.2.3-70-g09d2 From ce7c7a862ebe37fada7708c342c07d70fa80465a Mon Sep 17 00:00:00 2001 From: hurikhan Date: Tue, 13 Jan 2015 17:25:50 +0800 Subject: get_screen_position() added --- core/bind/core_bind.cpp | 5 +++++ core/bind/core_bind.h | 1 + core/os/os.h | 1 + demos/misc/window_management/control.gd | 11 ++++++++--- demos/misc/window_management/window_management.scn | Bin 3276 -> 3582 bytes platform/x11/os_x11.cpp | 12 ++++++++++++ platform/x11/os_x11.h | 1 + 7 files changed, 28 insertions(+), 3 deletions(-) (limited to 'platform') diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index b8fc63dc4..a2aca7e11 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -181,6 +181,10 @@ int _OS::get_screen_count() const { return OS::get_singleton()->get_screen_count(); } +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); } @@ -668,6 +672,7 @@ void _OS::_bind_methods() { #ifdef EXPERIMENTAL_WM_API ObjectTypeDB::bind_method(_MD("get_screen_count"),&_OS::get_screen_count); + 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); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 62f991355..9d9f25691 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -110,6 +110,7 @@ public: #ifdef EXPERIMENTAL_WM_API virtual int get_screen_count() const; + 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); diff --git a/core/os/os.h b/core/os/os.h index c2534287b..1ef05e45c 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -152,6 +152,7 @@ public: #ifdef EXPERIMENTAL_WM_API virtual int get_screen_count() const=0; + virtual Point2 get_screen_position(int p_screen=0) const=0; virtual Size2 get_screen_size(int p_screen=0) const=0; virtual Point2 get_window_position() const=0; virtual void set_window_position(const Point2& p_position)=0; diff --git a/demos/misc/window_management/control.gd b/demos/misc/window_management/control.gd index 3e74f24e4..ad15a7473 100644 --- a/demos/misc/window_management/control.gd +++ b/demos/misc/window_management/control.gd @@ -15,11 +15,16 @@ func _fixed_process(delta): 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("Label_Screen1_Resolution").show() - get_node("Label_Screen1_Resolution").set_text( str("Screen0 Resolution:\n", OS.get_screen_size(1) ) ) - - + get_node("Label_Screen1_Resolution").set_text( str("Screen1 Resolution:\n", OS.get_screen_size(1) ) ) + get_node("Label_Screen1_Position").show() + get_node("Label_Screen1_Position").set_text( str("Screen1 Position:\n", OS.get_screen_size(1) ) ) + else: + get_node("Label_Screen1_Resolution").hide() + get_node("Label_Screen1_Position").hide() func _ready(): set_fixed_process(true) diff --git a/demos/misc/window_management/window_management.scn b/demos/misc/window_management/window_management.scn index 6eaf62ff9..3a6426f3e 100644 Binary files a/demos/misc/window_management/window_management.scn and b/demos/misc/window_management/window_management.scn differ diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index e20d0731e..01d62f333 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -561,7 +561,19 @@ int OS_X11::get_screen_count() const { return XScreenCount(x11_display); } +Point2 OS_X11::get_screen_position(int p_screen) const { + if( p_screen >= XScreenCount(x11_display) ) + return Point2i(0,0); + + Window root = XRootWindow(x11_display, p_screen); + XWindowAttributes xwa; + XGetWindowAttributes(x11_display, root, &xwa); + return Point2i(xwa.x, xwa.y); +} + Size2 OS_X11::get_screen_size(int p_screen) const { + if( p_screen >= XScreenCount(x11_display) ) + return Size2i(0,0); Window root = XRootWindow(x11_display, p_screen); XWindowAttributes xwa; XGetWindowAttributes(x11_display, root, &xwa); diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 4aca996fd..ca35bf2c0 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -221,6 +221,7 @@ public: #ifdef EXPERIMENTAL_WM_API virtual int get_screen_count() const; + 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); -- cgit v1.2.3-70-g09d2 From f55c0e928580de63af55ac22f045bb4380a1df2e Mon Sep 17 00:00:00 2001 From: hurikhan Date: Tue, 13 Jan 2015 21:01:24 +0800 Subject: Using Xinerama extension for getting screen info --- demos/misc/window_management/control.gd | 2 +- platform/x11/detect.py | 6 +++++ platform/x11/os_x11.cpp | 42 ++++++++++++++++++++++----------- 3 files changed, 35 insertions(+), 15 deletions(-) (limited to 'platform') diff --git a/demos/misc/window_management/control.gd b/demos/misc/window_management/control.gd index ad15a7473..34df5dd92 100644 --- a/demos/misc/window_management/control.gd +++ b/demos/misc/window_management/control.gd @@ -21,7 +21,7 @@ func _fixed_process(delta): get_node("Label_Screen1_Resolution").show() get_node("Label_Screen1_Resolution").set_text( str("Screen1 Resolution:\n", OS.get_screen_size(1) ) ) get_node("Label_Screen1_Position").show() - get_node("Label_Screen1_Position").set_text( str("Screen1 Position:\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("Label_Screen1_Resolution").hide() get_node("Label_Screen1_Position").hide() diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 954e5270e..1eb615893 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -38,6 +38,11 @@ def can_build(): if (x11_error): print("xcursor not found.. x11 disabled.") return False + + x11_error=os.system("pkg-config xinerama --modversion > /dev/null ") + if (x11_error): + print("xinerama not found.. x11 disabled.") + return False return True # X11 enabled @@ -151,4 +156,5 @@ def configure(env): if(env["experimental_wm_api"]=="yes"): env.Append(CPPFLAGS=['-DEXPERIMENTAL_WM_API']) + env.ParseConfig('pkg-config xinerama --cflags --libs') diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 01d62f333..533e57d5c 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -36,6 +36,9 @@ #include "servers/physics/physics_server_sw.h" #include "X11/Xutil.h" +#ifdef EXPERIMENTAL_WM_API +#include "X11/extensions/Xinerama.h" +#endif #include "main/main.h" @@ -558,26 +561,37 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) { } int OS_X11::get_screen_count() const { - return XScreenCount(x11_display); + int event_base, error_base; + const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); + if( !ext_okay ) return 0; + int count; + XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); + XFree(xsi); + return count; } Point2 OS_X11::get_screen_position(int p_screen) const { - if( p_screen >= XScreenCount(x11_display) ) - return Point2i(0,0); - - Window root = XRootWindow(x11_display, p_screen); - XWindowAttributes xwa; - XGetWindowAttributes(x11_display, root, &xwa); - return Point2i(xwa.x, xwa.y); + int event_base, error_base; + const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); + if( !ext_okay ) return Point2i(0,0); + int count; + XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); + if( p_screen >= count ) return Point2i(0,0); + Point2i position = Point2i(xsi[p_screen].x_org, xsi[p_screen].y_org); + XFree(xsi); + return position; } Size2 OS_X11::get_screen_size(int p_screen) const { - if( p_screen >= XScreenCount(x11_display) ) - return Size2i(0,0); - Window root = XRootWindow(x11_display, p_screen); - XWindowAttributes xwa; - XGetWindowAttributes(x11_display, root, &xwa); - return Size2i(xwa.width, xwa.height); + int event_base, error_base; + const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); + if( !ext_okay ) return Size2i(0,0); + int count; + XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); + if( p_screen >= count ) return Size2i(0,0); + Size2i size = Point2i(xsi[p_screen].width, xsi[p_screen].height); + XFree(xsi); + return size; } -- cgit v1.2.3-70-g09d2 From 790d8ecbb9a0a0ac67520b84fc621c34f910d817 Mon Sep 17 00:00:00 2001 From: hurikhan Date: Wed, 14 Jan 2015 12:02:59 +0800 Subject: get_screen() + set_screen() added --- core/bind/core_bind.cpp | 16 ++++- core/bind/core_bind.h | 4 +- core/os/os.h | 4 +- demos/misc/window_management/control.gd | 27 +++++++- demos/misc/window_management/engine.cfg | 4 ++ demos/misc/window_management/window_management.scn | Bin 3582 -> 3787 bytes platform/x11/os_x11.cpp | 71 ++++++++++++++++----- platform/x11/os_x11.h | 7 +- 8 files changed, 109 insertions(+), 24 deletions(-) (limited to 'platform') diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index a2aca7e11..48cd43ccd 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -181,6 +181,14 @@ int _OS::get_screen_count() const { return OS::get_singleton()->get_screen_count(); } +int _OS::get_screen() const { + return OS::get_singleton()->get_screen(); +} + +void _OS::set_screen(int p_screen) { + OS::get_singleton()->set_screen(p_screen); +} + Point2 _OS::get_screen_position(int p_screen) const { return OS::get_singleton()->get_screen_position(p_screen); } @@ -205,8 +213,8 @@ void _OS::set_window_size(const Size2& p_size) { OS::get_singleton()->set_window_size(p_size); } -void _OS::set_fullscreen(bool p_enabled,int p_screen) { - OS::get_singleton()->set_fullscreen(p_enabled, p_screen); +void _OS::set_fullscreen(bool p_enabled) { + OS::get_singleton()->set_fullscreen(p_enabled); } bool _OS::is_fullscreen() const { @@ -672,13 +680,15 @@ void _OS::_bind_methods() { #ifdef EXPERIMENTAL_WM_API ObjectTypeDB::bind_method(_MD("get_screen_count"),&_OS::get_screen_count); + ObjectTypeDB::bind_method(_MD("get_screen"),&_OS::get_screen); + ObjectTypeDB::bind_method(_MD("set_screen"),&_OS::set_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_fullscreen","enabled","screen"),&_OS::set_fullscreen,DEFVAL(0)); + ObjectTypeDB::bind_method(_MD("set_fullscreen","enabled"),&_OS::set_fullscreen); ObjectTypeDB::bind_method(_MD("is_fullscreen"),&_OS::is_fullscreen); #endif diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 9d9f25691..99ecb765c 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -110,13 +110,15 @@ public: #ifdef EXPERIMENTAL_WM_API virtual int get_screen_count() const; + virtual int get_screen() const; + virtual void set_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); - void set_fullscreen(bool p_enabled, int p_screen=0); + void set_fullscreen(bool p_enabled); bool is_fullscreen() const; #endif diff --git a/core/os/os.h b/core/os/os.h index 1ef05e45c..2d4e93797 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -152,13 +152,15 @@ public: #ifdef EXPERIMENTAL_WM_API virtual int get_screen_count() const=0; + virtual int get_screen() const=0; + virtual void set_screen(int p_screen)=0; virtual Point2 get_screen_position(int p_screen=0) const=0; virtual Size2 get_screen_size(int p_screen=0) const=0; virtual Point2 get_window_position() const=0; virtual void set_window_position(const Point2& p_position)=0; virtual Size2 get_window_size() const=0; virtual void set_window_size(const Size2 p_size)=0; - virtual void set_fullscreen(bool p_enabled,int p_screen=0)=0; + virtual void set_fullscreen(bool p_enabled)=0; virtual bool is_fullscreen() const=0; #endif diff --git a/demos/misc/window_management/control.gd b/demos/misc/window_management/control.gd index 34df5dd92..ce17db6b0 100644 --- a/demos/misc/window_management/control.gd +++ b/demos/misc/window_management/control.gd @@ -13,18 +13,35 @@ func _fixed_process(delta): get_node("Label_Screen_Count").set_text( str("Screens:\n", OS.get_screen_count() ) ) + get_node("Label_Screen_Current").set_text( str("Current:\n", OS.get_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_Screen1").show() get_node("Label_Screen1_Resolution").show() - get_node("Label_Screen1_Resolution").set_text( str("Screen1 Resolution:\n", OS.get_screen_size(1) ) ) 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_Screen1").hide() get_node("Label_Screen1_Resolution").hide() get_node("Label_Screen1_Position").hide() + + if( Input.is_action_pressed("ui_right")): + OS.set_screen(1) + + if( Input.is_action_pressed("ui_left")): + OS.set_screen(0) + + if( Input.is_action_pressed("ui_up")): + OS.set_fullscreen(true) + + if( Input.is_action_pressed("ui_down")): + OS.set_fullscreen(false) + func _ready(): set_fixed_process(true) @@ -42,3 +59,11 @@ func _on_Button_MoveTo_pressed(): func _on_Button_Resize_pressed(): OS.set_window_size( Vector2(1024,768) ) + + +func _on_Button_Screen0_pressed(): + OS.set_screen(0) + + +func _on_Button_Screen1_pressed(): + OS.set_screen(1) diff --git a/demos/misc/window_management/engine.cfg b/demos/misc/window_management/engine.cfg index 7b6dddce9..44ad30ea1 100644 --- a/demos/misc/window_management/engine.cfg +++ b/demos/misc/window_management/engine.cfg @@ -3,3 +3,7 @@ name="window_management" main_scene="res://window_management.scn" icon="icon.png" + +[display] + +fullscreen=true diff --git a/demos/misc/window_management/window_management.scn b/demos/misc/window_management/window_management.scn index 3a6426f3e..9d55174dc 100644 Binary files a/demos/misc/window_management/window_management.scn and b/demos/misc/window_management/window_management.scn differ diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 533e57d5c..0ed8c8016 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -214,6 +214,10 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); #else + old_window_position.x = 0; + old_window_position.y = 0; + old_window_size.width = 800; + old_window_size.height = 600; set_wm_border(false); set_wm_fullscreen(true); #endif @@ -539,7 +543,7 @@ void OS_X11::set_wm_border(bool p_enabled) { property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); XMapRaised(x11_display, x11_window); - XMoveResizeWindow(x11_display, x11_window, 0, 0, current_videomode.width, current_videomode.height); + //XMoveResizeWindow(x11_display, x11_window, 0, 0, 800, 800); } void OS_X11::set_wm_fullscreen(bool p_enabled) { @@ -564,19 +568,55 @@ int OS_X11::get_screen_count() const { int event_base, error_base; const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); if( !ext_okay ) return 0; + int count; XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); XFree(xsi); return count; } +int OS_X11::get_screen() const { + int x,y; + Window child; + XTranslateCoordinates( x11_display, x11_window, DefaultRootWindow(x11_display), 0, 0, &x, &y, &child); + + int count = get_screen_count(); + for(int i=0; i= pos.x && x = pos.y && y < pos.y + size.height) ) + return i; + } + return 0; +} + +void OS_X11::set_screen(int p_screen) { + int count = get_screen_count(); + if(p_screen >= count) return; + + if( current_videomode.fullscreen ) { + Point2i position = get_screen_position(p_screen); + Size2i size = get_screen_size(p_screen); + + XMoveResizeWindow(x11_display, x11_window, position.x, position.y, size.x, size.y); + } + else { + if( p_screen != get_screen() ) { + Point2i position = get_screen_position(p_screen); + XMoveWindow(x11_display, x11_window, position.x, position.y); + } + } +} + Point2 OS_X11::get_screen_position(int p_screen) const { int event_base, error_base; const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); if( !ext_okay ) return Point2i(0,0); + int count; XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); if( p_screen >= count ) return Point2i(0,0); + Point2i position = Point2i(xsi[p_screen].x_org, xsi[p_screen].y_org); XFree(xsi); return position; @@ -586,9 +626,11 @@ Size2 OS_X11::get_screen_size(int p_screen) const { int event_base, error_base; const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); if( !ext_okay ) return Size2i(0,0); + int count; XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count); if( p_screen >= count ) return Size2i(0,0); + Size2i size = Point2i(xsi[p_screen].width, xsi[p_screen].height); XFree(xsi); return size; @@ -597,11 +639,8 @@ Size2 OS_X11::get_screen_size(int p_screen) const { Point2 OS_X11::get_window_position() const { int x,y; - XWindowAttributes xwa; Window child; XTranslateCoordinates( x11_display, x11_window, DefaultRootWindow(x11_display), 0, 0, &x, &y, &child); - XGetWindowAttributes(x11_display, x11_window, &xwa); - return Point2i(x,y); } @@ -664,30 +703,30 @@ void OS_X11::set_window_size(const Size2 p_size) { XResizeWindow(x11_display, x11_window, p_size.x, p_size.y); } -void OS_X11::set_fullscreen(bool p_enabled,int p_screen) { +void OS_X11::set_fullscreen(bool p_enabled) { if(p_enabled && current_videomode.fullscreen) return; if(p_enabled) { - pre_videomode = current_videomode; + old_window_size = get_window_size(); + old_window_position = get_window_position(); - XWindowAttributes xwa; - XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa); - - current_videomode.fullscreen = True; - current_videomode.width = xwa.width; - current_videomode.height = xwa.height; + int screen = get_screen(); + Size2i size = get_screen_size(screen); + Point2i position = get_screen_position(screen); set_wm_border(false); set_wm_fullscreen(true); - } else { - current_videomode.fullscreen = False; - current_videomode.width = pre_videomode.width; - current_videomode.height = pre_videomode.height; + XMoveResizeWindow(x11_display, x11_window, position.x, position.y, size.x, size.y); + current_videomode.fullscreen = True; + } else { set_wm_fullscreen(false); set_wm_border(true); + XMoveResizeWindow(x11_display, x11_window, old_window_position.x, old_window_position.y, old_window_size.width, old_window_size.height); + + current_videomode.fullscreen = False; } visual_server->init(); diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index ca35bf2c0..bb0fd3838 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -160,7 +160,8 @@ class OS_X11 : public OS_Unix { Joystick joysticks[JOYSTICKS_MAX]; #ifdef EXPERIMENTAL_WM_API - VideoMode pre_videomode; + Point2i old_window_position; + Size2i old_window_size; void set_wm_border(bool p_enabled); void set_wm_fullscreen(bool p_enabled); #endif @@ -221,13 +222,15 @@ public: #ifdef EXPERIMENTAL_WM_API virtual int get_screen_count() const; + virtual int get_screen() const; + virtual void set_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_fullscreen(bool p_enabled,int p_screen=0); + virtual void set_fullscreen(bool p_enabled); virtual bool is_fullscreen() const; #endif virtual void move_window_to_foreground(); -- cgit v1.2.3-70-g09d2 From 7222e195e549cc9a08c06fb30fb4d3d9051c818e Mon Sep 17 00:00:00 2001 From: hurikhan Date: Wed, 14 Jan 2015 13:19:27 +0800 Subject: minor cleanup --- platform/x11/os_x11.cpp | 24 ++++++++++++++---------- platform/x11/os_x11.h | 6 ++++-- 2 files changed, 18 insertions(+), 12 deletions(-) (limited to 'platform') diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 0ed8c8016..d395e9921 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -214,10 +214,10 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); #else - old_window_position.x = 0; - old_window_position.y = 0; - old_window_size.width = 800; - old_window_size.height = 600; + window_data.position.x = 0; + window_data.position.y = 0; + window_data.size.width = 800; + window_data.size.height = 600; set_wm_border(false); set_wm_fullscreen(true); #endif @@ -709,8 +709,8 @@ void OS_X11::set_fullscreen(bool p_enabled) { return; if(p_enabled) { - old_window_size = get_window_size(); - old_window_position = get_window_position(); + window_data.size = get_window_size(); + window_data.position = get_window_position(); int screen = get_screen(); Size2i size = get_screen_size(screen); @@ -724,7 +724,11 @@ void OS_X11::set_fullscreen(bool p_enabled) { } else { set_wm_fullscreen(false); set_wm_border(true); - XMoveResizeWindow(x11_display, x11_window, old_window_position.x, old_window_position.y, old_window_size.width, old_window_size.height); + XMoveResizeWindow(x11_display, x11_window, + window_data.position.x, + window_data.position.y, + window_data.size.width, + window_data.size.height); current_videomode.fullscreen = False; } @@ -1072,7 +1076,7 @@ void OS_X11::process_xevents() { if (mouse_mode==MOUSE_MODE_CAPTURED) { #if 1 - Vector2 c = Point2i(current_videomode.width/2,current_videomode.height/2); + //Vector2 c = Point2i(current_videomode.width/2,current_videomode.height/2); if (pos==Point2i(current_videomode.width/2,current_videomode.height/2)) { //this sucks, it's a hack, etc and is a little inaccurate, etc. //but nothing I can do, X11 sucks. @@ -1081,9 +1085,9 @@ void OS_X11::process_xevents() { break; } - Point2i ncenter = pos; + Point2i new_center = pos; pos = last_mouse_pos + ( pos-center ); - center=ncenter; + center=new_center; do_mouse_warp=true; #else //Dear X11, thanks for making my life miserable diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index bb0fd3838..72d212c13 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -160,8 +160,10 @@ class OS_X11 : public OS_Unix { Joystick joysticks[JOYSTICKS_MAX]; #ifdef EXPERIMENTAL_WM_API - Point2i old_window_position; - Size2i old_window_size; + struct { + Point2i position; + Size2i size; + } window_data; void set_wm_border(bool p_enabled); void set_wm_fullscreen(bool p_enabled); #endif -- cgit v1.2.3-70-g09d2 From d269344bbd19d9653fff3c2a230261b8fa00d7f6 Mon Sep 17 00:00:00 2001 From: hurikhan Date: Thu, 15 Jan 2015 22:50:23 +0900 Subject: WIP -- set_resizable() + is_resizable added --- core/bind/core_bind.cpp | 11 +++- core/bind/core_bind.h | 2 + core/os/os.h | 2 + demos/misc/window_management/control.gd | 28 +++++++++- demos/misc/window_management/window_management.scn | Bin 3787 -> 3897 bytes platform/x11/os_x11.cpp | 57 ++++++++++++++++----- platform/x11/os_x11.h | 9 +++- 7 files changed, 91 insertions(+), 18 deletions(-) (limited to 'platform') diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 48cd43ccd..1fb6f96e7 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -220,6 +220,14 @@ void _OS::set_fullscreen(bool p_enabled) { bool _OS::is_fullscreen() const { return OS::get_singleton()->is_fullscreen(); } + +void _OS::set_resizable(bool p_enabled) { + OS::get_singleton()->set_resizable(p_enabled); +} + +bool _OS::is_resizable() const { + return OS::get_singleton()->is_resizable(); +} #endif void _OS::set_use_file_access_save_and_swap(bool p_enable) { @@ -232,7 +240,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 { @@ -690,6 +697,8 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_window_size"),&_OS::set_window_size); ObjectTypeDB::bind_method(_MD("set_fullscreen","enabled"),&_OS::set_fullscreen); ObjectTypeDB::bind_method(_MD("is_fullscreen"),&_OS::is_fullscreen); + ObjectTypeDB::bind_method(_MD("set_resizable","enabled"),&_OS::set_resizable); + ObjectTypeDB::bind_method(_MD("is_resizable"),&_OS::is_resizable); #endif ObjectTypeDB::bind_method(_MD("set_iterations_per_second","iterations_per_second"),&_OS::set_iterations_per_second); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 99ecb765c..7ffd7e9e7 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -120,6 +120,8 @@ public: virtual void set_window_size(const Size2& p_size); void set_fullscreen(bool p_enabled); bool is_fullscreen() const; + void set_resizable(bool p_enabled); + bool is_resizable() const; #endif Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track); diff --git a/core/os/os.h b/core/os/os.h index 2d4e93797..f1a9de1ed 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -162,6 +162,8 @@ public: virtual void set_window_size(const Size2 p_size)=0; virtual void set_fullscreen(bool p_enabled)=0; virtual bool is_fullscreen() const=0; + virtual void set_resizable(bool p_enabled)=0; + virtual bool is_resizable() const=0; #endif virtual void set_iterations_per_second(int p_ips); diff --git a/demos/misc/window_management/control.gd b/demos/misc/window_management/control.gd index ce17db6b0..c867bd21d 100644 --- a/demos/misc/window_management/control.gd +++ b/demos/misc/window_management/control.gd @@ -2,10 +2,18 @@ extends Control func _fixed_process(delta): + + var modetext = "Mode:\n" + if(OS.is_fullscreen()): - get_node("Label_Fullscreen").set_text("Mode:\nFullscreen") + modetext += "Fullscreen\n" else: - get_node("Label_Fullscreen").set_text("Mode:\nWindowed") + modetext += "Windowed\n" + + if(!OS.is_resizable()): + modetext += "FixedSize\n" + + get_node("Label_Mode").set_text(modetext) get_node("Label_Position").set_text( str("Position:\n", OS.get_window_position() ) ) @@ -19,6 +27,7 @@ func _fixed_process(delta): get_node("Label_Screen0_Position").set_text(str("Screen0 Position:\n",OS.get_screen_position())) + if(OS.get_screen_count() > 1): get_node("Button_Screen1").show() get_node("Label_Screen1_Resolution").show() @@ -42,6 +51,9 @@ func _fixed_process(delta): if( Input.is_action_pressed("ui_down")): OS.set_fullscreen(false) + get_node("Button_FixedSize").set_pressed( !OS.is_resizable() ) + + func _ready(): set_fixed_process(true) @@ -67,3 +79,15 @@ func _on_Button_Screen0_pressed(): func _on_Button_Screen1_pressed(): OS.set_screen(1) + + + + + +func _on_Button_FixedSize_pressed(): + if(OS.is_resizable()): + OS.set_resizable(false) + else: + OS.set_resizable(true) + + diff --git a/demos/misc/window_management/window_management.scn b/demos/misc/window_management/window_management.scn index 9d55174dc..befc177b5 100644 Binary files a/demos/misc/window_management/window_management.scn and b/demos/misc/window_management/window_management.scn differ diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index d395e9921..f33c2556b 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -223,7 +223,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi #endif } - // disable resizeable window + // disable resizable window if (!current_videomode.resizable) { XSizeHints *xsh; xsh = XAllocSizeHints(); @@ -239,7 +239,9 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi xsh->min_height = xwa.height; xsh->max_height = xwa.height; XSetWMNormalHints(x11_display, x11_window, xsh); + XFree(xsh); } + current_videomode.resizable; AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton(); @@ -277,19 +279,19 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi XChangeWindowAttributes(x11_display, x11_window,CWEventMask,&new_attr); - XClassHint* classHint; + XClassHint* classHint; - /* set the titlebar name */ - XStoreName(x11_display, x11_window, "Godot"); + /* set the titlebar name */ + XStoreName(x11_display, x11_window, "Godot"); - /* set the name and class hints for the window manager to use */ - classHint = XAllocClassHint(); - if (classHint) { - classHint->res_name = "Godot"; - classHint->res_class = "Godot"; - } - XSetClassHint(x11_display, x11_window, classHint); - XFree(classHint); + /* set the name and class hints for the window manager to use */ + classHint = XAllocClassHint(); + if (classHint) { + classHint->res_name = "Godot"; + classHint->res_class = "Godot"; + } + XSetClassHint(x11_display, x11_window, classHint); + XFree(classHint); wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true); XSetWMProtocols(x11_display, x11_window, &wm_delete, 1); @@ -708,6 +710,9 @@ void OS_X11::set_fullscreen(bool p_enabled) { if(p_enabled && current_videomode.fullscreen) return; + if(!current_videomode.resizable) + set_resizable(true); + if(p_enabled) { window_data.size = get_window_size(); window_data.position = get_window_position(); @@ -734,11 +739,37 @@ void OS_X11::set_fullscreen(bool p_enabled) { } visual_server->init(); + } bool OS_X11::is_fullscreen() const { return current_videomode.fullscreen; } + +void OS_X11::set_resizable(bool p_enabled) { + + if(!current_videomode.fullscreen) { + XSizeHints *xsh; + xsh = XAllocSizeHints(); + xsh->flags = p_enabled ? 0L : PMinSize | PMaxSize; + if(!p_enabled) { + XWindowAttributes xwa; + XGetWindowAttributes(x11_display,x11_window,&xwa); + xsh->min_width = xwa.width; + xsh->max_width = xwa.width; + xsh->min_height = xwa.height; + xsh->max_height = xwa.height; + printf("%d %d\n", xwa.width, xwa.height); + } + XSetWMNormalHints(x11_display, x11_window, xsh); + XFree(xsh); + current_videomode.resizable = p_enabled; + } +} + +bool OS_X11::is_resizable() const { + return current_videomode.resizable; +} #endif InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) { @@ -1688,6 +1719,4 @@ OS_X11::OS_X11() { minimized = false; xim_style=NULL; mouse_mode=MOUSE_MODE_VISIBLE; - - }; diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 72d212c13..d286efe7b 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -160,10 +160,15 @@ class OS_X11 : public OS_Unix { Joystick joysticks[JOYSTICKS_MAX]; #ifdef EXPERIMENTAL_WM_API + // This struct saves the values of the window before going fullscreen + // to be able to restore the same state after leaving fullscreen struct { + bool resizable; Point2i position; Size2i size; - } window_data; + } window_data; + + bool maximized; void set_wm_border(bool p_enabled); void set_wm_fullscreen(bool p_enabled); #endif @@ -234,6 +239,8 @@ public: virtual void set_window_size(const Size2 p_size); virtual void set_fullscreen(bool p_enabled); virtual bool is_fullscreen() const; + virtual void set_resizable(bool p_enabled); + virtual bool is_resizable() const; #endif virtual void move_window_to_foreground(); -- cgit v1.2.3-70-g09d2 From f1b9953d0b321a5564109e11b5326efa4624c70c Mon Sep 17 00:00:00 2001 From: hurikhan Date: Fri, 16 Jan 2015 14:44:41 +0900 Subject: fixing the warnings in os_x11.cpp --- platform/x11/os_x11.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'platform') diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index f33c2556b..c6fdc2476 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -59,7 +59,7 @@ #include -#include "os/pc_joystick_map.h" +//#include "os/pc_joystick_map.h" #undef CursorShape @@ -120,10 +120,10 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi if (xim == NULL) { WARN_PRINT("XOpenIM failed"); - xim_style=NULL; + xim_style=0L; } else { ::XIMStyles *xim_styles=NULL; - xim_style=0; + xim_style=0L; char *imvalret=NULL; imvalret = XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL); if (imvalret != NULL || xim_styles == NULL) { @@ -131,7 +131,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi } if (xim_styles) { - xim_style = 0; + xim_style = 0L; for (int i=0;icount_styles;i++) { if (xim_styles->supported_styles[i] == @@ -241,7 +241,6 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi XSetWMNormalHints(x11_display, x11_window, xsh); XFree(xsh); } - current_videomode.resizable; AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton(); @@ -287,8 +286,9 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi /* set the name and class hints for the window manager to use */ classHint = XAllocClassHint(); if (classHint) { - classHint->res_name = "Godot"; - classHint->res_class = "Godot"; + char wmclass[] = "Godot"; + classHint->res_name = wmclass; + classHint->res_class = wmclass; } XSetClassHint(x11_display, x11_window, classHint); XFree(classHint); @@ -845,11 +845,9 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { KeySym keysym_keycode=0; // keysym used to find a keycode KeySym keysym_unicode=0; // keysym used to find unicode - int nbytes=0; // bytes the string takes - // XLookupString returns keysyms usable as nice scancodes/ char str[256+1]; - nbytes=XLookupString(xkeyevent, str, 256, &keysym_keycode, NULL); + XLookupString(xkeyevent, str, 256, &keysym_keycode, NULL); // Meanwhile, XLookupString returns keysyms useful for unicode. @@ -946,7 +944,7 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { ::Time tresh=ABS(peek_event.xkey.time-xkeyevent->time); if (peek_event.type == KeyPress && tresh<5 ) { KeySym rk; - nbytes=XLookupString((XKeyEvent*)&peek_event, str, 256, &rk, NULL); + XLookupString((XKeyEvent*)&peek_event, str, 256, &rk, NULL); if (rk==keysym_keycode) { XEvent event; XNextEvent(x11_display, &event); //erase next event @@ -1605,6 +1603,7 @@ void OS_X11::process_joysticks() { #endif }; + void OS_X11::set_cursor_shape(CursorShape p_shape) { ERR_FAIL_INDEX(p_shape,CURSOR_MAX); @@ -1717,6 +1716,7 @@ OS_X11::OS_X11() { #endif minimized = false; - xim_style=NULL; + xim_style=0L; mouse_mode=MOUSE_MODE_VISIBLE; }; + -- cgit v1.2.3-70-g09d2 From 716971655eb9ab7909447e2f5d4911b6f45164bb Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sat, 17 Jan 2015 00:18:45 +0900 Subject: added the following methods: * set_minimized(bool) * bool is_minimized() * set_maximized(bool) * bool is_maximized() --- core/bind/core_bind.cpp | 22 +++- core/bind/core_bind.h | 12 +- core/os/os.h | 4 + demos/misc/window_management/control.gd | 33 +++-- demos/misc/window_management/window_management.scn | Bin 3931 -> 4111 bytes platform/x11/os_x11.cpp | 137 ++++++++++++++++++++- platform/x11/os_x11.h | 4 + 7 files changed, 194 insertions(+), 18 deletions(-) (limited to 'platform') diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 1fb6f96e7..6919c70a5 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -228,6 +228,22 @@ void _OS::set_resizable(bool p_enabled) { bool _OS::is_resizable() const { return OS::get_singleton()->is_resizable(); } + +void _OS::set_minimized(bool p_enabled) { + OS::get_singleton()->set_minimized(p_enabled); +} + +bool _OS::is_minimized() const { + return OS::get_singleton()->is_minimized(); +} + +void _OS::set_maximized(bool p_enabled) { + OS::get_singleton()->set_maximized(p_enabled); +} + +bool _OS::is_maximized() const { + return OS::get_singleton()->is_maximized(); +} #endif void _OS::set_use_file_access_save_and_swap(bool p_enable) { @@ -698,7 +714,11 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_fullscreen","enabled"),&_OS::set_fullscreen); ObjectTypeDB::bind_method(_MD("is_fullscreen"),&_OS::is_fullscreen); ObjectTypeDB::bind_method(_MD("set_resizable","enabled"),&_OS::set_resizable); - ObjectTypeDB::bind_method(_MD("is_resizable"),&_OS::is_resizable); + ObjectTypeDB::bind_method(_MD("is_resizable"),&_OS::is_resizable); + ObjectTypeDB::bind_method(_MD("set_minimized", "enabled"),&_OS::set_minimized); + ObjectTypeDB::bind_method(_MD("is_minimized"),&_OS::is_minimized); + ObjectTypeDB::bind_method(_MD("set_maximized", "enabled"),&_OS::set_maximized); + ObjectTypeDB::bind_method(_MD("is_maximized"),&_OS::is_maximized); #endif ObjectTypeDB::bind_method(_MD("set_iterations_per_second","iterations_per_second"),&_OS::set_iterations_per_second); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 7ffd7e9e7..b6f4f8eef 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -118,10 +118,14 @@ public: virtual void set_window_position(const Point2& p_position); virtual Size2 get_window_size() const; virtual void set_window_size(const Size2& p_size); - void set_fullscreen(bool p_enabled); - bool is_fullscreen() const; - void set_resizable(bool p_enabled); - bool is_resizable() const; + virtual void set_fullscreen(bool p_enabled); + virtual bool is_fullscreen() const; + virtual void set_resizable(bool p_enabled); + virtual bool is_resizable() const; + virtual void set_minimized(bool p_enabled); + virtual bool is_minimized() const; + virtual void set_maximized(bool p_enabled); + virtual bool is_maximized() const; #endif Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track); diff --git a/core/os/os.h b/core/os/os.h index f1a9de1ed..c04a91e30 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -164,6 +164,10 @@ public: virtual bool is_fullscreen() const=0; virtual void set_resizable(bool p_enabled)=0; virtual bool is_resizable() const=0; + virtual void set_minimized(bool p_enabled)=0; + virtual bool is_minimized() const=0; + virtual void set_maximized(bool p_enabled)=0; + virtual bool is_maximized() const=0; #endif virtual void set_iterations_per_second(int p_ips); diff --git a/demos/misc/window_management/control.gd b/demos/misc/window_management/control.gd index 043db8d48..fd746cf03 100644 --- a/demos/misc/window_management/control.gd +++ b/demos/misc/window_management/control.gd @@ -13,17 +13,25 @@ func _fixed_process(delta): if(!OS.is_resizable()): modetext += "FixedSize\n" + if(OS.is_minimized()): + modetext += "Minimized\n" + + if(OS.is_maximized()): + modetext += "Maximized\n" + 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_Screen_Info").set_text( str("Screens:\n", OS.get_screen_count(),"\n\nCurrent:\n", OS.get_screen() ) ) + get_node("Label_Screen_Count").set_text( str("Screens:\n", OS.get_screen_count() ) ) + + get_node("Label_Screen_Current").set_text( str("Current:\n", OS.get_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())) + get_node("Label_Screen0_Position").set_text(str("Screen0 Position:\n",OS.get_screen_position() ) ) if(OS.get_screen_count() > 1): @@ -50,8 +58,9 @@ func _fixed_process(delta): OS.set_fullscreen(false) get_node("Button_FixedSize").set_pressed( !OS.is_resizable() ) - - + get_node("Button_Minimized").set_pressed( OS.is_minimized() ) + get_node("Button_Maximized").set_pressed( OS.is_maximized() ) + func _ready(): set_fixed_process(true) @@ -79,9 +88,6 @@ func _on_Button_Screen1_pressed(): OS.set_screen(1) - - - func _on_Button_FixedSize_pressed(): if(OS.is_resizable()): OS.set_resizable(false) @@ -89,3 +95,16 @@ func _on_Button_FixedSize_pressed(): OS.set_resizable(true) + +func _on_Button_Minimized_pressed(): + if(OS.is_minimized()): + OS.set_minimized(false) + else: + OS.set_minimized(true) + + +func _on_Button_Maximized_pressed(): + if(OS.is_maximized()): + OS.set_maximized(false) + else: + OS.set_maximized(true) diff --git a/demos/misc/window_management/window_management.scn b/demos/misc/window_management/window_management.scn index a83897f9a..635f6f6f2 100644 Binary files a/demos/misc/window_management/window_management.scn and b/demos/misc/window_management/window_management.scn differ diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index c6fdc2476..ef92d190c 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -37,7 +37,16 @@ #include "X11/Xutil.h" #ifdef EXPERIMENTAL_WM_API +#include "X11/Xatom.h" #include "X11/extensions/Xinerama.h" +// ICCCM +#define WM_NormalState 1L // window normal state +#define WM_IconicState 3L // window minimized + +// EWMH +#define _NET_WM_STATE_REMOVE 0L // remove/unset property +#define _NET_WM_STATE_ADD 1L // add/set property +#define _NET_WM_STATE_TOGGLE 2L // toggle property #endif #include "main/main.h" @@ -214,6 +223,8 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); #else + minimized = false; + minimized = false; window_data.position.x = 0; window_data.position.y = 0; window_data.size.width = 800; @@ -549,7 +560,7 @@ void OS_X11::set_wm_border(bool p_enabled) { } void OS_X11::set_wm_fullscreen(bool p_enabled) { - // code for netwm-compliants + // Using EWMH -- Extened Window Manager Hints XEvent xev; Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); Atom wm_fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False); @@ -559,7 +570,7 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) { xev.xclient.window = x11_window; xev.xclient.message_type = wm_state; xev.xclient.format = 32; - xev.xclient.data.l[0] = p_enabled ? 1L : 0L; + xev.xclient.data.l[0] = p_enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; xev.xclient.data.l[1] = wm_fullscreen; xev.xclient.data.l[2] = 0; @@ -567,6 +578,7 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) { } int OS_X11::get_screen_count() const { + // Using Xinerama Extension int event_base, error_base; const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); if( !ext_okay ) return 0; @@ -611,6 +623,7 @@ void OS_X11::set_screen(int p_screen) { } Point2 OS_X11::get_screen_position(int p_screen) const { + // Using Xinerama Extension int event_base, error_base; const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); if( !ext_okay ) return Point2i(0,0); @@ -625,6 +638,7 @@ Point2 OS_X11::get_screen_position(int p_screen) const { } Size2 OS_X11::get_screen_size(int p_screen) const { + // Using Xinerama Extension int event_base, error_base; const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base); if( !ext_okay ) return Size2i(0,0); @@ -651,14 +665,14 @@ void OS_X11::set_window_position(const Point2& p_position) { if( current_videomode.fullscreen ) return; - // _NET_FRAME_EXTENTS + // Using EWMH -- Extended Window Manager Hints + // to get the size of the decoration Atom property = XInternAtom(x11_display,"_NET_FRAME_EXTENTS", True); Atom type; int format; unsigned long len; unsigned long remaining; unsigned char *data = NULL; - //long *extends; int result; result = XGetWindowProperty( @@ -759,7 +773,6 @@ void OS_X11::set_resizable(bool p_enabled) { xsh->max_width = xwa.width; xsh->min_height = xwa.height; xsh->max_height = xwa.height; - printf("%d %d\n", xwa.width, xwa.height); } XSetWMNormalHints(x11_display, x11_window, xsh); XFree(xsh); @@ -770,6 +783,119 @@ void OS_X11::set_resizable(bool p_enabled) { bool OS_X11::is_resizable() const { return current_videomode.resizable; } + +void OS_X11::set_minimized(bool p_enabled) { + // Using ICCCM -- Inter-Client Communication Conventions Manual + XEvent xev; + Atom wm_change = XInternAtom(x11_display, "WM_CHANGE_STATE", False); + + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = x11_window; + xev.xclient.message_type = wm_change; + xev.xclient.format = 32; + xev.xclient.data.l[0] = p_enabled ? WM_IconicState : WM_NormalState; + + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); +} + +bool OS_X11::is_minimized() const { + // Using ICCCM -- Inter-Client Communication Conventions Manual + Atom property = XInternAtom(x11_display,"WM_STATE", True); + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = NULL; + + int result = XGetWindowProperty( + x11_display, + x11_window, + property, + 0, + 32, + False, + AnyPropertyType, + &type, + &format, + &len, + &remaining, + &data + ); + + if( result == Success ) { + long *state = (long *) data; + if( state[0] == 3L ) + return true; + } + return false; +} + +void OS_X11::set_maximized(bool p_enabled) { + // Using EWMH -- Extended Window Manager Hints + XEvent xev; + Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); + Atom wm_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); + Atom wm_max_vert = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False); + + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = x11_window; + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = p_enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + xev.xclient.data.l[1] = wm_max_horz; + xev.xclient.data.l[2] = wm_max_vert; + + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); + + maximized = p_enabled; +} + +bool OS_X11::is_maximized() const { + // Using EWMH -- Extended Window Manager Hints + Atom property = XInternAtom(x11_display,"_NET_WM_STATE",False ); + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = NULL; + + int result = XGetWindowProperty( + x11_display, + x11_window, + property, + 0, + 1024, + False, + XA_ATOM, + &type, + &format, + &len, + &remaining, + &data + ); + + if(result == Success) { + Atom *atoms = (Atom*) data; + Atom wm_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); + Atom wm_max_vert = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False); + bool found_wm_max_horz = false; + bool found_wm_max_vert = false; + + for( unsigned int i=0; i < len; i++ ) { + if( atoms[i] == wm_max_horz ) + found_wm_max_horz = true; + if( atoms[i] == wm_max_vert ) + found_wm_max_vert = true; + + if( found_wm_max_horz && found_wm_max_vert ) + return true; + } + } + + return false; +} #endif InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) { @@ -1719,4 +1845,3 @@ OS_X11::OS_X11() { xim_style=0L; mouse_mode=MOUSE_MODE_VISIBLE; }; - diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index d286efe7b..557052ab6 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -241,6 +241,10 @@ public: virtual bool is_fullscreen() const; virtual void set_resizable(bool p_enabled); virtual bool is_resizable() const; + virtual void set_minimized(bool p_enabled); + virtual bool is_minimized() const; + virtual void set_maximized(bool p_enabled); + virtual bool is_maximized() const; #endif virtual void move_window_to_foreground(); -- cgit v1.2.3-70-g09d2 From 6185949f6a4f6eae78d8afca2dd787dbf063d675 Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sat, 17 Jan 2015 02:36:07 +0900 Subject: Make it set_minimized() + set_maximized() work in both worlds: Unity and LXDE --- platform/x11/os_x11.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'platform') diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index ef92d190c..fd2470a37 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -552,7 +552,7 @@ void OS_X11::set_wm_border(bool p_enabled) { Hints hints; Atom property; hints.flags = 2; - hints.decorations = p_enabled ? 1L : 0L;; + hints.decorations = p_enabled ? 1L : 0L; property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); XMapRaised(x11_display, x11_window); @@ -700,7 +700,6 @@ void OS_X11::set_window_position(const Point2& p_position) { top = extends[2]; XFree(data); - data = NULL; } XMoveWindow(x11_display,x11_window,p_position.x - left,p_position.y - top); @@ -785,6 +784,10 @@ bool OS_X11::is_resizable() const { } void OS_X11::set_minimized(bool p_enabled) { + + if( is_fullscreen() ) + set_fullscreen(false); + // Using ICCCM -- Inter-Client Communication Conventions Manual XEvent xev; Atom wm_change = XInternAtom(x11_display, "WM_CHANGE_STATE", False); @@ -797,6 +800,20 @@ void OS_X11::set_minimized(bool p_enabled) { xev.xclient.data.l[0] = p_enabled ? WM_IconicState : WM_NormalState; XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); + + //XEvent xev; + Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); + Atom wm_hidden = XInternAtom(x11_display, "_NET_WM_STATE_HIDDEN", False); + + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = x11_window; + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = _NET_WM_STATE_ADD; + xev.xclient.data.l[1] = wm_hidden; + + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); } bool OS_X11::is_minimized() const { @@ -825,7 +842,7 @@ bool OS_X11::is_minimized() const { if( result == Success ) { long *state = (long *) data; - if( state[0] == 3L ) + if( state[0] == WM_IconicState ) return true; } return false; @@ -847,7 +864,7 @@ void OS_X11::set_maximized(bool p_enabled) { xev.xclient.data.l[1] = wm_max_horz; xev.xclient.data.l[2] = wm_max_vert; - XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); maximized = p_enabled; } @@ -892,6 +909,7 @@ bool OS_X11::is_maximized() const { if( found_wm_max_horz && found_wm_max_vert ) return true; } + XFree(atoms); } return false; -- cgit v1.2.3-70-g09d2 From f1dc00e380439078c93d00af2f85d138a9400b2e Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sat, 17 Jan 2015 19:43:12 +0900 Subject: * cleanup window state handling * first attemps in handling ALT+TABa (WIP) --- demos/misc/window_management/control.gd | 28 ++++++---- demos/misc/window_management/window_management.scn | Bin 4111 -> 4052 bytes platform/x11/os_x11.cpp | 62 ++++++++++----------- 3 files changed, 47 insertions(+), 43 deletions(-) (limited to 'platform') diff --git a/demos/misc/window_management/control.gd b/demos/misc/window_management/control.gd index fd746cf03..4929b1376 100644 --- a/demos/misc/window_management/control.gd +++ b/demos/misc/window_management/control.gd @@ -25,9 +25,9 @@ func _fixed_process(delta): get_node("Label_Size").set_text(str("Size:\n", OS.get_window_size() ) ) - get_node("Label_Screen_Count").set_text( str("Screens:\n", OS.get_screen_count() ) ) + get_node("Label_Screen_Count").set_text( str("Screen_Count:\n", OS.get_screen_count() ) ) - get_node("Label_Screen_Current").set_text( str("Current:\n", OS.get_screen() ) ) + get_node("Label_Screen_Current").set_text( str("Screen:\n", OS.get_screen() ) ) get_node("Label_Screen0_Resolution").set_text( str("Screen0 Resolution:\n", OS.get_screen_size() ) ) @@ -35,12 +35,14 @@ func _fixed_process(delta): 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() @@ -57,19 +59,14 @@ func _fixed_process(delta): if( Input.is_action_pressed("ui_down")): OS.set_fullscreen(false) + get_node("Button_Fullscreen").set_pressed( OS.is_fullscreen() ) get_node("Button_FixedSize").set_pressed( !OS.is_resizable() ) get_node("Button_Minimized").set_pressed( OS.is_minimized() ) get_node("Button_Maximized").set_pressed( OS.is_maximized() ) - -func _ready(): - set_fixed_process(true) -func _on_Fullscreen_toggled( pressed ): - if(pressed): - OS.set_fullscreen(true) - else: - OS.set_fullscreen(false) +func _ready(): + set_fixed_process(true) func _on_Button_MoveTo_pressed(): @@ -88,12 +85,18 @@ func _on_Button_Screen1_pressed(): OS.set_screen(1) +func _on_Button_Fullscreen_pressed(): + if(OS.is_fullscreen()): + OS.set_fullscreen(false) + else: + OS.set_fullscreen(true) + + func _on_Button_FixedSize_pressed(): if(OS.is_resizable()): OS.set_resizable(false) else: OS.set_resizable(true) - func _on_Button_Minimized_pressed(): @@ -108,3 +111,6 @@ func _on_Button_Maximized_pressed(): OS.set_maximized(false) else: OS.set_maximized(true) + + + diff --git a/demos/misc/window_management/window_management.scn b/demos/misc/window_management/window_management.scn index 635f6f6f2..3d62d4ecc 100644 Binary files a/demos/misc/window_management/window_management.scn and b/demos/misc/window_management/window_management.scn differ diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index fd2470a37..d4328d9da 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -229,7 +229,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi window_data.position.y = 0; window_data.size.width = 800; window_data.size.height = 600; - set_wm_border(false); + //set_wm_border(false); set_wm_fullscreen(true); #endif } @@ -574,7 +574,7 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) { xev.xclient.data.l[1] = wm_fullscreen; xev.xclient.data.l[2] = 0; - XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); } int OS_X11::get_screen_count() const { @@ -661,10 +661,6 @@ Point2 OS_X11::get_window_position() const { } void OS_X11::set_window_position(const Point2& p_position) { - - if( current_videomode.fullscreen ) - return; - // Using EWMH -- Extended Window Manager Hints // to get the size of the decoration Atom property = XInternAtom(x11_display,"_NET_FRAME_EXTENTS", True); @@ -712,14 +708,12 @@ Size2 OS_X11::get_window_size() const { } void OS_X11::set_window_size(const Size2 p_size) { - if( current_videomode.fullscreen ) - return; - XResizeWindow(x11_display, x11_window, p_size.x, p_size.y); } void OS_X11::set_fullscreen(bool p_enabled) { +#if 0 if(p_enabled && current_videomode.fullscreen) return; @@ -750,6 +744,9 @@ void OS_X11::set_fullscreen(bool p_enabled) { current_videomode.fullscreen = False; } +#endif + set_wm_fullscreen(p_enabled); + current_videomode.fullscreen = p_enabled; visual_server->init(); @@ -760,23 +757,20 @@ bool OS_X11::is_fullscreen() const { } void OS_X11::set_resizable(bool p_enabled) { - - if(!current_videomode.fullscreen) { - XSizeHints *xsh; - xsh = XAllocSizeHints(); - xsh->flags = p_enabled ? 0L : PMinSize | PMaxSize; - if(!p_enabled) { - XWindowAttributes xwa; - XGetWindowAttributes(x11_display,x11_window,&xwa); - xsh->min_width = xwa.width; - xsh->max_width = xwa.width; - xsh->min_height = xwa.height; - xsh->max_height = xwa.height; - } - XSetWMNormalHints(x11_display, x11_window, xsh); - XFree(xsh); - current_videomode.resizable = p_enabled; + XSizeHints *xsh; + xsh = XAllocSizeHints(); + xsh->flags = p_enabled ? 0L : PMinSize | PMaxSize; + if(!p_enabled) { + XWindowAttributes xwa; + XGetWindowAttributes(x11_display,x11_window,&xwa); + xsh->min_width = xwa.width; + xsh->max_width = xwa.width; + xsh->min_height = xwa.height; + xsh->max_height = xwa.height; } + XSetWMNormalHints(x11_display, x11_window, xsh); + XFree(xsh); + current_videomode.resizable = p_enabled; } bool OS_X11::is_resizable() const { @@ -784,10 +778,6 @@ bool OS_X11::is_resizable() const { } void OS_X11::set_minimized(bool p_enabled) { - - if( is_fullscreen() ) - set_fullscreen(false); - // Using ICCCM -- Inter-Client Communication Conventions Manual XEvent xev; Atom wm_change = XInternAtom(x11_display, "WM_CHANGE_STATE", False); @@ -799,7 +789,7 @@ void OS_X11::set_minimized(bool p_enabled) { xev.xclient.format = 32; xev.xclient.data.l[0] = p_enabled ? WM_IconicState : WM_NormalState; - XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); //XEvent xev; Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); @@ -1152,13 +1142,16 @@ void OS_X11::process_xevents() { break; case VisibilityNotify: { - XVisibilityEvent * visibility = (XVisibilityEvent *)&event; minimized = (visibility->state == VisibilityFullyObscured); - } break; case FocusIn: + if(current_videomode.fullscreen) { + set_minimized(false); + set_wm_fullscreen(true); + visual_server->init(); + } main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); if (mouse_mode==MOUSE_MODE_CAPTURED) { XGrabPointer(x11_display, x11_window, True, @@ -1169,6 +1162,11 @@ void OS_X11::process_xevents() { break; case FocusOut: + if(current_videomode.fullscreen) { + set_wm_fullscreen(false); + set_minimized(true); + visual_server->init(); + } main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); if (mouse_mode==MOUSE_MODE_CAPTURED) { //dear X11, I try, I really try, but you never work, you do whathever you want. -- cgit v1.2.3-70-g09d2 From dfb5a1d5e1318d91f26c0f7663afe861005104c8 Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sun, 18 Jan 2015 00:28:04 +0900 Subject: * multi_screen testing + bugfixes * ALT-TAB is working * tested on Ubuntu 14.10 Unity + LXDE * minor cleanup --- demos/misc/window_management/engine.cfg | 2 + demos/misc/window_management/window_management.scn | Bin 4052 -> 4030 bytes platform/x11/os_x11.cpp | 48 ++++++++++++++------- platform/x11/os_x11.h | 10 +---- 4 files changed, 35 insertions(+), 25 deletions(-) (limited to 'platform') diff --git a/demos/misc/window_management/engine.cfg b/demos/misc/window_management/engine.cfg index 2accafe43..6ce3d51ae 100644 --- a/demos/misc/window_management/engine.cfg +++ b/demos/misc/window_management/engine.cfg @@ -8,3 +8,5 @@ icon="icon.png" fullscreen=false resizable=true +width=800 +height=600 diff --git a/demos/misc/window_management/window_management.scn b/demos/misc/window_management/window_management.scn index 3d62d4ecc..baf03bdfd 100644 Binary files a/demos/misc/window_management/window_management.scn and b/demos/misc/window_management/window_management.scn differ diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index d4328d9da..d711cea42 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -42,7 +42,6 @@ // ICCCM #define WM_NormalState 1L // window normal state #define WM_IconicState 3L // window minimized - // EWMH #define _NET_WM_STATE_REMOVE 0L // remove/unset property #define _NET_WM_STATE_ADD 1L // add/set property @@ -192,9 +191,9 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD)); } +#ifndef EXPERIMENTAL_WM_API // borderless fullscreen window mode if (current_videomode.fullscreen) { -#ifndef EXPERIMENTAL_WM_API // needed for lxde/openbox, possibly others Hints hints; Atom property; @@ -222,16 +221,6 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi xev.xclient.data.l[2] = 0; XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); -#else - minimized = false; - minimized = false; - window_data.position.x = 0; - window_data.position.y = 0; - window_data.size.width = 800; - window_data.size.height = 600; - //set_wm_border(false); - set_wm_fullscreen(true); -#endif } // disable resizable window @@ -252,6 +241,21 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi XSetWMNormalHints(x11_display, x11_window, xsh); XFree(xsh); } +#else + if (current_videomode.fullscreen) { + minimized = false; + maximized = false; + //set_wm_border(false); + set_wm_fullscreen(true); + } + if (!current_videomode.resizable) { + int screen = get_screen(); + Size2i screen_size = get_screen_size(screen); + set_window_size(screen_size); + set_resizable(false); + } +#endif + AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton(); @@ -519,7 +523,6 @@ OS::MouseMode OS_X11::get_mouse_mode() const { int OS_X11::get_mouse_button_state() const { - return last_button_state; } @@ -547,6 +550,8 @@ void OS_X11::get_fullscreen_mode_list(List *p_list,int p_screen) cons } #ifdef EXPERIMENTAL_WM_API +#if 0 +// Just now not needed. Can be used for a possible OS.set_border(bool) method void OS_X11::set_wm_border(bool p_enabled) { // needed for lxde/openbox, possibly others Hints hints; @@ -558,6 +563,7 @@ void OS_X11::set_wm_border(bool p_enabled) { XMapRaised(x11_display, x11_window); //XMoveResizeWindow(x11_display, x11_window, 0, 0, 800, 800); } +#endif void OS_X11::set_wm_fullscreen(bool p_enabled) { // Using EWMH -- Extened Window Manager Hints @@ -657,7 +663,11 @@ Point2 OS_X11::get_window_position() const { int x,y; Window child; XTranslateCoordinates( x11_display, x11_window, DefaultRootWindow(x11_display), 0, 0, &x, &y, &child); - return Point2i(x,y); + + int screen = get_screen(); + Point2i screen_position = get_screen_position(screen); + + return Point2i(x-screen_position.x, y-screen_position.y); } void OS_X11::set_window_position(const Point2& p_position) { @@ -698,6 +708,12 @@ void OS_X11::set_window_position(const Point2& p_position) { XFree(data); } + int screen = get_screen(); + Point2i screen_position = get_screen_position(screen); + + left -= screen_position.x; + top -= screen_position.y; + XMoveWindow(x11_display,x11_window,p_position.x - left,p_position.y - top); } @@ -1146,9 +1162,9 @@ void OS_X11::process_xevents() { minimized = (visibility->state == VisibilityFullyObscured); } break; - case FocusIn: + case FocusIn: + minimized = false; if(current_videomode.fullscreen) { - set_minimized(false); set_wm_fullscreen(true); visual_server->init(); } diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 557052ab6..b47c5db06 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -160,16 +160,8 @@ class OS_X11 : public OS_Unix { Joystick joysticks[JOYSTICKS_MAX]; #ifdef EXPERIMENTAL_WM_API - // This struct saves the values of the window before going fullscreen - // to be able to restore the same state after leaving fullscreen - struct { - bool resizable; - Point2i position; - Size2i size; - } window_data; - bool maximized; - void set_wm_border(bool p_enabled); + //void set_wm_border(bool p_enabled); void set_wm_fullscreen(bool p_enabled); #endif -- cgit v1.2.3-70-g09d2 From 94d94a08558c83fb6e447c3e1ed858cf39c0e1ba Mon Sep 17 00:00:00 2001 From: hurikhan Date: Thu, 22 Jan 2015 01:14:50 +0900 Subject: * fix compilation without scons experimental_wm_api=yes * Extended the demo with an addional MouseGrab Test --- demos/misc/window_management/control.gd | 6 ++++-- demos/misc/window_management/engine.cfg | 7 +++++++ demos/misc/window_management/window_management.scn | Bin 4030 -> 4268 bytes platform/x11/os_x11.cpp | 10 +++++----- 4 files changed, 16 insertions(+), 7 deletions(-) (limited to 'platform') diff --git a/demos/misc/window_management/control.gd b/demos/misc/window_management/control.gd index 4929b1376..6dc928214 100644 --- a/demos/misc/window_management/control.gd +++ b/demos/misc/window_management/control.gd @@ -33,7 +33,6 @@ func _fixed_process(delta): 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() @@ -63,6 +62,7 @@ func _fixed_process(delta): get_node("Button_FixedSize").set_pressed( !OS.is_resizable() ) get_node("Button_Minimized").set_pressed( OS.is_minimized() ) get_node("Button_Maximized").set_pressed( OS.is_maximized() ) + get_node("Button_Mouse_Grab").set_pressed( Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED ) func _ready(): @@ -113,4 +113,6 @@ func _on_Button_Maximized_pressed(): OS.set_maximized(true) - +func _on_Button_Mouse_Grab_pressed(): + var observer = get_node("../Observer") + observer.state = observer.STATE_GRAB diff --git a/demos/misc/window_management/engine.cfg b/demos/misc/window_management/engine.cfg index 6ce3d51ae..c53bd45fb 100644 --- a/demos/misc/window_management/engine.cfg +++ b/demos/misc/window_management/engine.cfg @@ -10,3 +10,10 @@ 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)] diff --git a/demos/misc/window_management/window_management.scn b/demos/misc/window_management/window_management.scn index baf03bdfd..40e6e64ce 100644 Binary files a/demos/misc/window_management/window_management.scn and b/demos/misc/window_management/window_management.scn differ diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index d711cea42..fa3701aee 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -177,11 +177,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi context_gl = memnew( ContextGL_X11( x11_display, x11_window,current_videomode, false ) ); context_gl->initialize(); - if (true) { - rasterizer = memnew( RasterizerGLES2 ); - } else { - //rasterizer = memnew( RasterizerGLES1 ); - }; + rasterizer = memnew( RasterizerGLES2 ); #endif visual_server = memnew( VisualServerRaster(rasterizer) ); @@ -1164,10 +1160,12 @@ void OS_X11::process_xevents() { case FocusIn: minimized = false; +#ifdef EXPERIMENTAL_WM_API if(current_videomode.fullscreen) { set_wm_fullscreen(true); visual_server->init(); } +#endif main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); if (mouse_mode==MOUSE_MODE_CAPTURED) { XGrabPointer(x11_display, x11_window, True, @@ -1178,11 +1176,13 @@ void OS_X11::process_xevents() { break; case FocusOut: +#ifdef EXPERIMENTAL_WM_API if(current_videomode.fullscreen) { set_wm_fullscreen(false); set_minimized(true); visual_server->init(); } +#endif main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); if (mouse_mode==MOUSE_MODE_CAPTURED) { //dear X11, I try, I really try, but you never work, you do whathever you want. -- cgit v1.2.3-70-g09d2 From df7d26ff5b89ce9852813abd370d1357aab1501b Mon Sep 17 00:00:00 2001 From: hurikhan Date: Thu, 12 Feb 2015 15:58:00 +0100 Subject: cleanup + MouseGrab --- demos/misc/window_management/control.gd | 2 + demos/misc/window_management/window_management.scn | Bin 4744 -> 4850 bytes platform/x11/os_x11.cpp | 81 +++++++++------------ platform/x11/os_x11.h | 1 + 4 files changed, 36 insertions(+), 48 deletions(-) (limited to 'platform') diff --git a/demos/misc/window_management/control.gd b/demos/misc/window_management/control.gd index d329237ae..50fc3a376 100644 --- a/demos/misc/window_management/control.gd +++ b/demos/misc/window_management/control.gd @@ -28,6 +28,8 @@ func _fixed_process(delta): 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_screen() ) ) diff --git a/demos/misc/window_management/window_management.scn b/demos/misc/window_management/window_management.scn index bf7a0871e..14d0da041 100644 Binary files a/demos/misc/window_management/window_management.scn and b/demos/misc/window_management/window_management.scn differ diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index fa3701aee..9fb2a4c64 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -238,9 +238,11 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi XFree(xsh); } #else + capture_idle = 0; + minimized = false; + maximized = false; + if (current_videomode.fullscreen) { - minimized = false; - maximized = false; //set_wm_border(false); set_wm_fullscreen(true); } @@ -494,8 +496,9 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) { center.y = current_videomode.height/2; XWarpPointer(x11_display, None, x11_window, 0,0,0,0, (int)center.x, (int)center.y); - } + input->set_mouse_pos(center); + } } void OS_X11::warp_mouse_pos(const Point2& p_to) { @@ -724,44 +727,10 @@ void OS_X11::set_window_size(const Size2 p_size) { } void OS_X11::set_fullscreen(bool p_enabled) { - -#if 0 - if(p_enabled && current_videomode.fullscreen) - return; - - if(!current_videomode.resizable) - set_resizable(true); - - if(p_enabled) { - window_data.size = get_window_size(); - window_data.position = get_window_position(); - - int screen = get_screen(); - Size2i size = get_screen_size(screen); - Point2i position = get_screen_position(screen); - - set_wm_border(false); - set_wm_fullscreen(true); - XMoveResizeWindow(x11_display, x11_window, position.x, position.y, size.x, size.y); - - current_videomode.fullscreen = True; - } else { - set_wm_fullscreen(false); - set_wm_border(true); - XMoveResizeWindow(x11_display, x11_window, - window_data.position.x, - window_data.position.y, - window_data.size.width, - window_data.size.height); - - current_videomode.fullscreen = False; - } -#endif set_wm_fullscreen(p_enabled); current_videomode.fullscreen = p_enabled; visual_server->init(); - } bool OS_X11::is_fullscreen() const { @@ -1209,7 +1178,7 @@ void OS_X11::process_xevents() { event.xbutton.x=last_mouse_pos.x; event.xbutton.y=last_mouse_pos.y; } - + InputEvent mouse_event; mouse_event.ID=++event_id; mouse_event.type = InputEvent::MOUSE_BUTTON; @@ -1244,7 +1213,7 @@ void OS_X11::process_xevents() { last_click_ms+=diff; last_click_pos = Point2(event.xbutton.x,event.xbutton.y); } - } + } input->parse_input_event( mouse_event); @@ -1254,11 +1223,10 @@ void OS_X11::process_xevents() { last_timestamp=event.xmotion.time; - + // Motion is also simple. // A little hack is in order // to be able to send relative motion events. - Point2i pos( event.xmotion.x, event.xmotion.y ); if (mouse_mode==MOUSE_MODE_CAPTURED) { @@ -1273,7 +1241,7 @@ void OS_X11::process_xevents() { } Point2i new_center = pos; - pos = last_mouse_pos + ( pos-center ); + pos = last_mouse_pos + ( pos - center ); center=new_center; do_mouse_warp=true; #else @@ -1287,9 +1255,7 @@ void OS_X11::process_xevents() { XWarpPointer(x11_display, None, x11_window, 0,0,0,0, (int)center.x, (int)center.y); #endif - } - if (!last_mouse_pos_valid) { @@ -1298,7 +1264,14 @@ void OS_X11::process_xevents() { } Point2i rel = pos - last_mouse_pos; - + +#ifdef EXPERIMENTAL_WM_API + if (mouse_mode==MOUSE_MODE_CAPTURED) { + pos.x = current_videomode.width / 2; + pos.y = current_videomode.height / 2; + } +#endif + InputEvent motion_event; motion_event.ID=++event_id; motion_event.type=InputEvent::MOUSE_MOTION; @@ -1309,7 +1282,7 @@ void OS_X11::process_xevents() { motion_event.mouse_motion.x=pos.x; motion_event.mouse_motion.y=pos.y; input->set_mouse_pos(pos); - motion_event.mouse_motion.global_x=pos.x; + motion_event.mouse_motion.global_x=pos.y; motion_event.mouse_motion.global_y=pos.y; motion_event.mouse_motion.speed_x=input->get_mouse_speed().x; motion_event.mouse_motion.speed_y=input->get_mouse_speed().y; @@ -1318,6 +1291,8 @@ void OS_X11::process_xevents() { motion_event.mouse_motion.relative_y=rel.y; last_mouse_pos=pos; + + // printf("rel: %d,%d\n", rel.x, rel.y ); input->parse_input_event( motion_event); @@ -1392,8 +1367,18 @@ void OS_X11::process_xevents() { if (do_mouse_warp) { XWarpPointer(x11_display, None, x11_window, - 0,0,0,0, (int)current_videomode.width/2, (int)current_videomode.height/2); - + 0,0,0,0, (int)current_videomode.width/2, (int)current_videomode.height/2); + + /* + Window root, child; + int root_x, root_y; + int win_x, win_y; + unsigned int mask; + XQueryPointer( x11_display, x11_window, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask ); + + printf("Root: %d,%d\n", root_x, root_y); + printf("Win: %d,%d\n", win_x, win_y); + */ } } diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index b47c5db06..7518c9356 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -160,6 +160,7 @@ class OS_X11 : public OS_Unix { Joystick joysticks[JOYSTICKS_MAX]; #ifdef EXPERIMENTAL_WM_API + unsigned int capture_idle; bool maximized; //void set_wm_border(bool p_enabled); void set_wm_fullscreen(bool p_enabled); -- cgit v1.2.3-70-g09d2 From f5d2e1f42cca1c5b078073133fccda63c556a0da Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sun, 15 Feb 2015 18:26:49 +0800 Subject: Renamed EXPERIMENTAL_WM_API to NEW_WM_API --- core/bind/core_bind.cpp | 4 ++-- core/bind/core_bind.h | 2 +- core/os/os.h | 2 +- platform/x11/detect.py | 6 +++--- platform/x11/os_x11.cpp | 12 ++++++------ platform/x11/os_x11.h | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) (limited to 'platform') diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 39c5761d6..858f5cec2 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -176,7 +176,7 @@ bool _OS::is_video_mode_fullscreen(int p_screen) const { } -#ifdef EXPERIMENTAL_WM_API +#ifdef NEW_WM_API int _OS::get_screen_count() const { return OS::get_singleton()->get_screen_count(); } @@ -706,7 +706,7 @@ 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)); -#ifdef EXPERIMENTAL_WM_API +#ifdef NEW_WM_API ObjectTypeDB::bind_method(_MD("get_screen_count"),&_OS::get_screen_count); ObjectTypeDB::bind_method(_MD("get_screen"),&_OS::get_screen); ObjectTypeDB::bind_method(_MD("set_screen"),&_OS::set_screen); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index e77ed9e40..1a80e3522 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -108,7 +108,7 @@ public: bool is_video_mode_resizable(int p_screen=0) const; Array get_fullscreen_mode_list(int p_screen=0) const; -#ifdef EXPERIMENTAL_WM_API +#ifdef NEW_WM_API virtual int get_screen_count() const; virtual int get_screen() const; virtual void set_screen(int p_screen); diff --git a/core/os/os.h b/core/os/os.h index c04a91e30..6301bd495 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -150,7 +150,7 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const=0; virtual void get_fullscreen_mode_list(List *p_list,int p_screen=0) const=0; -#ifdef EXPERIMENTAL_WM_API +#ifdef NEW_WM_API virtual int get_screen_count() const=0; virtual int get_screen() const=0; virtual void set_screen(int p_screen)=0; diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 0601c5998..2519dd6fd 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -53,7 +53,7 @@ def get_opts(): ('use_llvm','Use llvm compiler','no'), ('use_sanitizer','Use llvm compiler sanitize address','no'), ('pulseaudio','Detect & Use pulseaudio','yes'), - ('experimental_wm_api', 'Use experimental window management API','no'), + ('new_wm_api', 'Use experimental window management API','no'), ] def get_flags(): @@ -153,7 +153,7 @@ def configure(env): env.Append( BUILDERS = { 'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl') } ) #env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } ) - if(env["experimental_wm_api"]=="yes"): - env.Append(CPPFLAGS=['-DEXPERIMENTAL_WM_API']) + if(env["new_wm_api"]=="yes"): + env.Append(CPPFLAGS=['-DNEW_WM_API']) env.ParseConfig('pkg-config xinerama --cflags --libs') diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 4c86f5a82..8def56456 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -36,7 +36,7 @@ #include "servers/physics/physics_server_sw.h" #include "X11/Xutil.h" -#ifdef EXPERIMENTAL_WM_API +#ifdef NEW_WM_API #include "X11/Xatom.h" #include "X11/extensions/Xinerama.h" // ICCCM @@ -187,7 +187,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD)); } -#ifndef EXPERIMENTAL_WM_API +#ifndef NEW_WM_API // borderless fullscreen window mode if (current_videomode.fullscreen) { // needed for lxde/openbox, possibly others @@ -552,7 +552,7 @@ void OS_X11::get_fullscreen_mode_list(List *p_list,int p_screen) cons } -#ifdef EXPERIMENTAL_WM_API +#ifdef NEW_WM_API #if 0 // Just now not needed. Can be used for a possible OS.set_border(bool) method void OS_X11::set_wm_border(bool p_enabled) { @@ -1133,7 +1133,7 @@ void OS_X11::process_xevents() { case FocusIn: minimized = false; -#ifdef EXPERIMENTAL_WM_API +#ifdef NEW_WM_API if(current_videomode.fullscreen) { set_wm_fullscreen(true); visual_server->init(); @@ -1149,7 +1149,7 @@ void OS_X11::process_xevents() { break; case FocusOut: -#ifdef EXPERIMENTAL_WM_API +#ifdef NEW_WM_API if(current_videomode.fullscreen) { set_wm_fullscreen(false); set_minimized(true); @@ -1269,7 +1269,7 @@ void OS_X11::process_xevents() { Point2i rel = pos - last_mouse_pos; -#ifdef EXPERIMENTAL_WM_API +#ifdef NEW_WM_API if (mouse_mode==MOUSE_MODE_CAPTURED) { pos.x = current_videomode.width / 2; pos.y = current_videomode.height / 2; diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 7518c9356..ffa1ce00b 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -159,7 +159,7 @@ class OS_X11 : public OS_Unix { int joystick_count; Joystick joysticks[JOYSTICKS_MAX]; -#ifdef EXPERIMENTAL_WM_API +#ifdef NEW_WM_API unsigned int capture_idle; bool maximized; //void set_wm_border(bool p_enabled); @@ -220,7 +220,7 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const; virtual void get_fullscreen_mode_list(List *p_list,int p_screen=0) const; -#ifdef EXPERIMENTAL_WM_API +#ifdef NEW_WM_API virtual int get_screen_count() const; virtual int get_screen() const; virtual void set_screen(int p_screen); -- cgit v1.2.3-70-g09d2 From 84905809a159e4f04b166f06a5807560c4c7d538 Mon Sep 17 00:00:00 2001 From: UsernameIsAReservedWord Date: Tue, 24 Feb 2015 22:28:51 +0100 Subject: fixes platform/windows/detect.py - fixes issue #1298 : under windows, too long `ar` command lines are split into several smaller command lines. - fixes issue #1285 : under linux, cross compiling with Mingw-w64 now generates actual 64bits EXE. - `MINGW32_PREFIX` and `MINGW64_PREFIX` environment variables are also available for Windows. - started to clean-up the remains of previous hacks and workarounds. - added some documentation into the script.--- platform/windows/detect.py | 208 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 162 insertions(+), 46 deletions(-) (limited to 'platform') diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 16dd695c5..b07882f55 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -1,4 +1,90 @@ - +# +# tested on | Windows native | Linux cross-compilation +# ------------------------+-------------------+--------------------------- +# MSVS C++ 2010 Express | WORKS | n/a +# Mingw-w64 | WORKS | WORKS +# Mingw-w32 | WORKS | WORKS +# MinGW | WORKS | untested +# +##### +# Notes about MSVS C++ : +# +# - MSVC2010-Express compiles to 32bits only. +# +##### +# Notes about Mingw-w64 and Mingw-w32 under Windows : +# +# - both can be installed using the official installer : +# http://mingw-w64.sourceforge.net/download.php#mingw-builds +# +# - if you want to compile both 32bits and 64bits, don't forget to +# run the installer twice to install them both. +# +# - install them into a path that does not contain spaces +# ( example : "C:/Mingw-w32", "C:/Mingw-w64" ) +# +# - if you want to compile faster using the "-j" option, don't forget +# to install the appropriate version of the Pywin32 python extension +# available from : http://sourceforge.net/projects/pywin32/files/ +# +# - before running scons, you must add into the environment path +# the path to the "/bin" directory of the Mingw version you want +# to use : +# +# set PATH=C:/Mingw-w32/bin;%PATH% +# +# - then, scons should be able to detect gcc. +# - Mingw-w32 only compiles 32bits. +# - Mingw-w64 only compiles 64bits. +# +# - it is possible to add them both at the same time into the PATH env, +# if you also define the MINGW32_PREFIX and MINGW64_PREFIX environment +# variables. +# For instance, you could store that set of commands into a .bat script +# that you would run just before scons : +# +# set PATH=C:\mingw-w64\bin;%PATH% +# set PATH=C:\mingw-w64\bin;%PATH% +# set MINGW32_PREFIX=C:\mingw-w64\bin\ +# set MINGW64_PREFIX=C:\mingw-w64\bin\ +# +##### +# Notes about Mingw, Mingw-w64 and Mingw-w32 under Linux : +# +# - default toolchain prefixes are : +# "i586-mingw32msvc-" for MinGW +# "i686-w64-mingw32-" for Mingw-w32 +# "x86_64-w64-mingw32-" for Mingw-w64 +# +# - if both MinGW and Mingw-w32 are installed on your system +# Mingw-w32 should take the priority over MinGW. +# +# - it is possible to manually override prefixes by defining +# the MINGW32_PREFIX and MINGW64_PREFIX environment variables. +# +##### +# Notes about Mingw under Windows : +# +# - this is the MinGW version from http://mingw.org/ +# - install it into a path that does not contain spaces +# ( example : "C:/MinGW" ) +# - several DirectX headers might be missing. You can copy them into +# the C:/MinGW/include" directory from this page : +# https://code.google.com/p/mingw-lib/source/browse/trunk/working/avcodec_to_widget_5/directx_include/ +# - before running scons, add the path to the "/bin" directory : +# set PATH=C:/MinGW/bin;%PATH% +# - scons should be able to detect gcc. +# + +##### +# TODO : +# +# - finish to cleanup this script to remove all the remains of previous hacks and workarounds +# - make it work with the Windows7 SDK that is supposed to enable 64bits compilation for MSVC2010-Express +# - confirm it works well with other Visual Studio versions. +# - update the wiki about the pywin32 extension required for the "-j" option under Windows. +# - update the wiki to document MINGW32_PREFIX and MINGW64_PREFIX +# import os @@ -13,50 +99,70 @@ def get_name(): def can_build(): - if (os.name=="nt"): #building natively on windows! if (os.getenv("VSINSTALLDIR")): return True else: - print("MSVC Not detected, attempting mingw.") + print("\nMSVC not detected, attempting Mingw.") + mingw32 = "" + mingw64 = "" + if ( os.getenv("MINGW32_PREFIX") ) : + mingw32 = os.getenv("MINGW32_PREFIX") + if ( os.getenv("MINGW64_PREFIX") ) : + mingw64 = os.getenv("MINGW64_PREFIX") + + test = "gcc --version > NUL 2>&1" + if os.system(test)!= 0 and os.system(mingw32+test)!=0 and os.system(mingw64+test)!=0 : + print("- could not detect gcc.") + print("Please, make sure a path to a Mingw /bin directory is accessible into the environment PATH.\n") + return False + else: + print("- gcc detected.") + return True - - if (os.name=="posix"): mingw = "i586-mingw32msvc-" - mingw64 = "i686-w64-mingw32-" + mingw64 = "x86_64-w64-mingw32-" + mingw32 = "i686-w64-mingw32-" + if (os.getenv("MINGW32_PREFIX")): - mingw=os.getenv("MINGW32_PREFIX") + mingw32=os.getenv("MINGW32_PREFIX") + mingw = mingw32 if (os.getenv("MINGW64_PREFIX")): mingw64=os.getenv("MINGW64_PREFIX") - - if os.system(mingw+"gcc --version >/dev/null") == 0 or os.system(mingw64+"gcc --version >/dev/null") ==0: + + test = "gcc --version >/dev/null" + if os.system(mingw+test) == 0 or os.system(mingw64+test) ==0 or os.system(mingw32+test) ==0 : return True - - return False def get_opts(): mingw="" + mingw32="" mingw64="" - if (os.name!="nt"): + if ( os.name == "posix" ): mingw = "i586-mingw32msvc-" - mingw64 = "i686-w64-mingw32-" - if (os.getenv("MINGW32_PREFIX")): - mingw=os.getenv("MINGW32_PREFIX") - if (os.getenv("MINGW64_PREFIX")): - mingw64=os.getenv("MINGW64_PREFIX") + mingw32 = "i686-w64-mingw32-" + mingw64 = "x86_64-w64-mingw32-" + + if os.system(mingw32+"gcc --version >/dev/null") != 0 : + mingw32 = mingw + + if (os.getenv("MINGW32_PREFIX")): + mingw32=os.getenv("MINGW32_PREFIX") + mingw = mingw32 + if (os.getenv("MINGW64_PREFIX")): + mingw64=os.getenv("MINGW64_PREFIX") return [ - ('mingw_prefix','Mingw Prefix',mingw), + ('mingw_prefix','Mingw Prefix',mingw32), ('mingw_prefix_64','Mingw Prefix 64 bits',mingw64), - ('mingw64_for_32','Use Mingw 64 for 32 Bits Build',"no"), ] def get_flags(): @@ -140,13 +246,13 @@ def configure(env): # http://www.scons.org/wiki/LongCmdLinesOnWin32 if (os.name=="nt"): import subprocess - def mySpawn(sh, escape, cmd, args, env): - newargs = ' '.join(args[1:]) - cmdline = cmd + " " + newargs + + def mySubProcess(cmdline,env): + #print "SPAWNED : " + cmdline startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env) + stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env) data, err = proc.communicate() rv = proc.wait() if rv: @@ -154,35 +260,45 @@ def configure(env): print err print "=====" return rv + + def mySpawn(sh, escape, cmd, args, env): + + newargs = ' '.join(args[1:]) + cmdline = cmd + " " + newargs + + rv=0 + if len(cmdline) > 32000 and cmd.endswith("ar") : + cmdline = cmd + " " + args[1] + " " + args[2] + " " + for i in range(3,len(args)) : + rv = mySubProcess( cmdline + args[i], env ) + if rv : + break + else: + rv = mySubProcess( cmdline, env ) + + return rv + env['SPAWN'] = mySpawn #build using mingw if (os.name=="nt"): env['ENV']['TMP'] = os.environ['TMP'] #way to go scons, you can be so stupid sometimes else: - env["PROGSUFFIX"]=env["PROGSUFFIX"]+".exe" + env["PROGSUFFIX"]=env["PROGSUFFIX"]+".exe" # for linux cross-compilation mingw_prefix="" if (env["bits"]=="default"): env["bits"]="32" - use64=False if (env["bits"]=="32"): - - if (env["mingw64_for_32"]=="yes"): - env.Append(CCFLAGS=['-m32']) - env.Append(LINKFLAGS=['-m32']) - env.Append(LINKFLAGS=['-static-libgcc']) - env.Append(LINKFLAGS=['-static-libstdc++']) - mingw_prefix=env["mingw_prefix_64"]; - else: - mingw_prefix=env["mingw_prefix"]; - - + env.Append(LINKFLAGS=['-static']) + env.Append(LINKFLAGS=['-static-libgcc']) + env.Append(LINKFLAGS=['-static-libstdc++']) + mingw_prefix=env["mingw_prefix"]; else: - mingw_prefix=env["mingw_prefix_64"]; env.Append(LINKFLAGS=['-static']) + mingw_prefix=env["mingw_prefix_64"]; nulstr="" @@ -193,10 +309,10 @@ def configure(env): - if os.system(mingw_prefix+"gcc --version"+nulstr)!=0: - #not really super consistent but.. - print("Can't find Windows compiler: "+mingw_prefix) - sys.exit(255) + # if os.system(mingw_prefix+"gcc --version"+nulstr)!=0: + # #not really super consistent but.. + # print("Can't find Windows compiler: "+mingw_prefix) + # sys.exit(255) if (env["target"]=="release"): @@ -231,11 +347,11 @@ def configure(env): env.Append(CCFLAGS=['-DGLES2_ENABLED','-DGLEW_ENABLED']) env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','iphlpapi','wsock32','kernel32']) - if (env["bits"]=="32" and env["mingw64_for_32"]!="yes"): -# env.Append(LIBS=['gcc_s']) - #--with-arch=i686 - env.Append(CPPFLAGS=['-march=i686']) - env.Append(LINKFLAGS=['-march=i686']) + # if (env["bits"]=="32"): +# # env.Append(LIBS=['gcc_s']) + # #--with-arch=i686 + # env.Append(CPPFLAGS=['-march=i686']) + # env.Append(LINKFLAGS=['-march=i686']) -- cgit v1.2.3-70-g09d2 From fde7f11a559065af87dc345d34694f64eaa45e91 Mon Sep 17 00:00:00 2001 From: UsernameIsAReservedWord Date: Tue, 24 Feb 2015 22:31:18 +0100 Subject: Update detect.py --- platform/windows/detect.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'platform') diff --git a/platform/windows/detect.py b/platform/windows/detect.py index b07882f55..94e0b9853 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -45,7 +45,7 @@ # # set PATH=C:\mingw-w64\bin;%PATH% # set PATH=C:\mingw-w64\bin;%PATH% -# set MINGW32_PREFIX=C:\mingw-w64\bin\ +# set MINGW32_PREFIX=C:\mingw-w32\bin\ # set MINGW64_PREFIX=C:\mingw-w64\bin\ # ##### -- cgit v1.2.3-70-g09d2 From b3976ec14c0239faeed564ca105b2d27f5ac5ad7 Mon Sep 17 00:00:00 2001 From: UsernameIsAReservedWord Date: Tue, 24 Feb 2015 22:38:49 +0100 Subject: Update detect.py --- platform/windows/detect.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'platform') diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 94e0b9853..efd2e79ca 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -43,7 +43,7 @@ # For instance, you could store that set of commands into a .bat script # that you would run just before scons : # -# set PATH=C:\mingw-w64\bin;%PATH% +# set PATH=C:\mingw-w32\bin;%PATH% # set PATH=C:\mingw-w64\bin;%PATH% # set MINGW32_PREFIX=C:\mingw-w32\bin\ # set MINGW64_PREFIX=C:\mingw-w64\bin\ -- cgit v1.2.3-70-g09d2 From 9229d9d1bbc3bb850839e022b8c8d37609839edd Mon Sep 17 00:00:00 2001 From: Hinsbart Date: Wed, 25 Feb 2015 16:33:08 +0100 Subject: fix get joystick name from registry on some systems --- platform/windows/os_windows.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'platform') diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 13f2c32e7..e392a56aa 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -715,9 +715,14 @@ String OS_Windows::get_joystick_name(int id, JOYCAPS jcaps) return ""; _snprintf( buffer, sizeof(buffer), "%s\\%s", REGSTR_PATH_JOYOEM, OEM); - res = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey); - if (res != ERROR_SUCCESS) - return ""; + res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey); + if (res != ERROR_SUCCESS) + { + res = RegOpenKeyEx(HKEY_CURRENT_USER, buffer, 0, KEY_QUERY_VALUE, &hKey); + if (res != ERROR_SUCCESS) + return ""; + } + sz = sizeof(buffer); res = RegQueryValueEx(hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, (LPBYTE) buffer, -- cgit v1.2.3-70-g09d2 From a1f715a4da71fbc2b7d6fad68624bf8b22c6da17 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Mon, 2 Mar 2015 00:54:10 -0300 Subject: support for 2D shadow casters Added support for 2D shadow casters. *DANGER* Shaders in CanvasItem CHANGED, if you are using shader in a CanvasItem and pull this, you will lose them. Shaders now work through a 2D material system similar to 3D. If you don't want to lose the 2D shader code, save the shader as a .shd, then create a material in CanvasItem and re-assign the shader. --- core/io/resource_format_binary.cpp | 10 + core/io/resource_format_xml.cpp | 5 + core/math/camera_matrix.cpp | 19 +- core/variant_op.cpp | 3 + demos/3d/kinematic_char/cubelib.res | Bin 11431 -> 11530 bytes demos/3d/kinematic_char/level.scn | Bin 15323 -> 15556 bytes drivers/SCsub | 1 - drivers/gles2/rasterizer_gles2.cpp | 598 ++++++++++++++++++++- drivers/gles2/rasterizer_gles2.h | 62 ++- drivers/gles2/shaders/SCsub | 1 + drivers/gles2/shaders/canvas.glsl | 123 ++++- drivers/gles2/shaders/canvas_shadow.glsl | 62 +++ drivers/windows/file_access_windows.cpp | 20 +- modules/gdscript/gd_script.cpp | 5 +- platform/android/audio_driver_opensl.cpp | 8 + platform/android/os_android.cpp | 2 +- platform/windows/detect.py | 4 +- scene/2d/canvas_item.cpp | 309 +++++++---- scene/2d/canvas_item.h | 59 +- scene/2d/light_2d.cpp | 49 +- scene/2d/light_2d.h | 8 + scene/2d/light_occluder_2d.cpp | 201 +++++++ scene/2d/light_occluder_2d.h | 73 +++ scene/3d/camera.cpp | 6 +- scene/3d/visual_instance.cpp | 15 + scene/3d/visual_instance.h | 4 + scene/register_scene_types.cpp | 4 + scene/scene_string_names.cpp | 1 + scene/scene_string_names.h | 1 + servers/visual/rasterizer.h | 67 ++- servers/visual/visual_server_raster.cpp | 377 +++++++++++-- servers/visual/visual_server_raster.h | 61 ++- servers/visual/visual_server_wrap_mt.h | 30 +- servers/visual_server.h | 33 +- tools/editor/editor_node.cpp | 2 + tools/editor/icons/icon_canvas_item_material.png | Bin 0 -> 835 bytes tools/editor/icons/icon_canvas_modulate.png | Bin 0 -> 441 bytes tools/editor/icons/icon_light_occluder_2d.png | Bin 0 -> 516 bytes tools/editor/icons/icon_occluder_polygon_2d.png | Bin 0 -> 581 bytes .../plugins/collision_polygon_2d_editor_plugin.cpp | 1 + .../plugins/light_occluder_2d_editor_plugin.cpp | 500 +++++++++++++++++ .../plugins/light_occluder_2d_editor_plugin.h | 87 +++ tools/editor/property_editor.cpp | 40 +- 43 files changed, 2583 insertions(+), 268 deletions(-) create mode 100644 drivers/gles2/shaders/canvas_shadow.glsl create mode 100644 scene/2d/light_occluder_2d.cpp create mode 100644 scene/2d/light_occluder_2d.h create mode 100644 tools/editor/icons/icon_canvas_item_material.png create mode 100644 tools/editor/icons/icon_canvas_modulate.png create mode 100644 tools/editor/icons/icon_light_occluder_2d.png create mode 100644 tools/editor/icons/icon_occluder_polygon_2d.png create mode 100644 tools/editor/plugins/light_occluder_2d_editor_plugin.cpp create mode 100644 tools/editor/plugins/light_occluder_2d_editor_plugin.h (limited to 'platform') diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index e2371fe24..ead698465 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1778,6 +1778,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_ f->store_32(VERSION_MINOR); f->store_32(FORMAT_VERSION); + if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) { + f->close(); + return ERR_CANT_CREATE; + } + //f->store_32(saved_resources.size()+external_resources.size()); // load steps -not needed save_unicode_string(p_resource->get_type()); uint64_t md_at = f->get_pos(); @@ -1910,6 +1915,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_ f->store_buffer((const uint8_t*)"RSRC",4); //magic at end + if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) { + f->close(); + return ERR_CANT_CREATE; + } + f->close(); diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp index 75384d4ab..033b4d5e5 100644 --- a/core/io/resource_format_xml.cpp +++ b/core/io/resource_format_xml.cpp @@ -2592,6 +2592,11 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res } exit_tag("resource_file"); + if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) { + f->close(); + return ERR_CANT_CREATE; + } + f->close(); //memdelete(f); diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index a60dea737..fbe5f8c74 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -121,7 +121,7 @@ void CameraMatrix::set_orthogonal(float p_size, float p_aspect, float p_znear, f void CameraMatrix::set_frustum(float p_left, float p_right, float p_bottom, float p_top, float p_near, float p_far) { - +#if 0 ///@TODO, give a check to this. I'm not sure if it's working. set_identity(); @@ -133,10 +133,27 @@ void CameraMatrix::set_frustum(float p_left, float p_right, float p_bottom, floa matrix[2][3]=-(2*p_far*p_near) / (p_far-p_near); matrix[3][2]=-1; matrix[3][3]=0; +#else + float *te = &matrix[0][0]; + float x = 2 * p_near / ( p_right - p_left ); + float y = 2 * p_near / ( p_top - p_bottom ); + + float a = ( p_right + p_left ) / ( p_right - p_left ); + float b = ( p_top + p_bottom ) / ( p_top - p_bottom ); + float c = - ( p_far + p_near ) / ( p_far - p_near ); + float d = - 2 * p_far * p_near / ( p_far - p_near ); + + te[0] = x; te[4] = 0; te[8] = a; te[12] = 0; + te[1] = 0; te[5] = y; te[9] = b; te[13] = 0; + te[2] = 0; te[6] = 0; te[10] = c; te[14] = d; + te[3] = 0; te[7] = 0; te[11] = - 1; te[15] = 0; + +#endif } + float CameraMatrix::get_z_far() const { const float * matrix = (const float*)this->matrix; diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 21bbc8c7e..d6129e150 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -552,6 +552,9 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant& if (p_b.type==MATRIX32) { _RETURN( *p_a._data._matrix32 * *p_b._data._matrix32 ); }; + if (p_b.type==VECTOR2) { + _RETURN( p_a._data._matrix32->xform( *(const Vector2*)p_b._data._mem) ); + }; r_valid=false; return; } break; diff --git a/demos/3d/kinematic_char/cubelib.res b/demos/3d/kinematic_char/cubelib.res index 66b999d78..27f2b9b3b 100644 Binary files a/demos/3d/kinematic_char/cubelib.res and b/demos/3d/kinematic_char/cubelib.res differ diff --git a/demos/3d/kinematic_char/level.scn b/demos/3d/kinematic_char/level.scn index a276fe22e..7ccb2430c 100644 Binary files a/demos/3d/kinematic_char/level.scn and b/demos/3d/kinematic_char/level.scn differ diff --git a/drivers/SCsub b/drivers/SCsub index 46334468b..a1a2191cb 100644 --- a/drivers/SCsub +++ b/drivers/SCsub @@ -10,7 +10,6 @@ SConscript('alsa/SCsub'); SConscript('pulseaudio/SCsub'); SConscript('windows/SCsub'); SConscript('gles2/SCsub'); -SConscript('gles1/SCsub'); SConscript('gl_context/SCsub'); SConscript('openssl/SCsub'); diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index aba0b5ca9..aa7bad0b8 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -971,7 +971,7 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu - if ((!texture->flags&VS::TEXTURE_FLAG_VIDEO_SURFACE) && img.detect_alpha()==Image::ALPHA_BLEND) { + if (!(texture->flags&VS::TEXTURE_FLAG_VIDEO_SURFACE) && img.detect_alpha()==Image::ALPHA_BLEND) { texture->has_alpha=true; } @@ -2525,7 +2525,7 @@ Error RasterizerGLES2::_surface_set_arrays(Surface *p_surface, uint8_t *p_mem,ui void RasterizerGLES2::mesh_add_custom_surface(RID p_mesh,const Variant& p_dat) { ERR_EXPLAIN("OpenGL Rasterizer does not support custom surfaces. Running on wrong platform?"); - ERR_FAIL_V(); + ERR_FAIL(); } Array RasterizerGLES2::mesh_get_surface_arrays(RID p_mesh,int p_surface) const { @@ -4116,6 +4116,10 @@ void RasterizerGLES2::begin_frame() { shadow_filter=ShadowFilterTechnique(int(Globals::get_singleton()->get("rasterizer/shadow_filter"))); #endif + canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_PCF5,shadow_filter==SHADOW_FILTER_PCF5); + canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_PCF13,shadow_filter==SHADOW_FILTER_PCF13); + canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_ESM,shadow_filter==SHADOW_FILTER_ESM); + window_size = Size2( OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height ); double time = (OS::get_singleton()->get_ticks_usec()/1000); // get msec @@ -7874,7 +7878,8 @@ void RasterizerGLES2::canvas_begin() { canvas_blend_mode=VS::MATERIAL_BLEND_MODE_MIX; canvas_texscreen_used=false; uses_texpixel_size=false; - canvas_last_shader=RID(); + + canvas_last_material=NULL; } @@ -8364,6 +8369,476 @@ void RasterizerGLES2::canvas_set_transform(const Matrix32& p_transform) { //canvas_transform = Variant(p_transform); } +RID RasterizerGLES2::canvas_light_occluder_create() { + + CanvasOccluder *co = memnew( CanvasOccluder ); + co->index_id=0; + co->vertex_id=0; + co->len=0; + + return canvas_occluder_owner.make_rid(co); +} + +void RasterizerGLES2::canvas_light_occluder_set_polylines(RID p_occluder, const DVector& p_lines) { + + CanvasOccluder *co = canvas_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!co); + + co->lines=p_lines; + + if (p_lines.size()!=co->len) { + + if (co->index_id) + glDeleteBuffers(1,&co->index_id); + if (co->vertex_id) + glDeleteBuffers(1,&co->vertex_id); + + co->index_id=0; + co->vertex_id=0; + co->len=0; + + } + + if (p_lines.size()) { + + + + DVector geometry; + DVector indices; + int lc = p_lines.size(); + + geometry.resize(lc*6); + indices.resize(lc*3); + + DVector::Write vw=geometry.write(); + DVector::Write iw=indices.write(); + + + DVector::Read lr=p_lines.read(); + + const int POLY_HEIGHT = 16384; + + for(int i=0;ivertex_id) { + glGenBuffers(1,&co->vertex_id); + glBindBuffer(GL_ARRAY_BUFFER,co->vertex_id); + glBufferData(GL_ARRAY_BUFFER,lc*6*sizeof(real_t),vw.ptr(),GL_STATIC_DRAW); + } else { + + glBindBuffer(GL_ARRAY_BUFFER,co->vertex_id); + glBufferSubData(GL_ARRAY_BUFFER,0,lc*6*sizeof(real_t),vw.ptr()); + + } + + glBindBuffer(GL_ARRAY_BUFFER,0); //unbind + + if (!co->index_id) { + + glGenBuffers(1,&co->index_id); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,co->index_id); + glBufferData(GL_ELEMENT_ARRAY_BUFFER,lc*3*sizeof(uint16_t),iw.ptr(),GL_STATIC_DRAW); + } else { + + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,co->index_id); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,0,lc*3*sizeof(uint16_t),iw.ptr()); + } + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); //unbind + + co->len=lc; + + } + + + +} + +RID RasterizerGLES2::canvas_light_shadow_buffer_create(int p_width) { + + CanvasLightShadow *cls = memnew( CanvasLightShadow ); + if (p_width>max_texture_size) + p_width=max_texture_size; + + cls->size=p_width; + glActiveTexture(GL_TEXTURE0); + + glGenFramebuffers(1, &cls->fbo); + glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo); + + // Create a render buffer + glGenRenderbuffers(1, &cls->rbo); + glBindRenderbuffer(GL_RENDERBUFFER, cls->rbo); + + // Create a texture for storing the depth + glGenTextures(1, &cls->depth); + glBindTexture(GL_TEXTURE_2D, cls->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); + + cls->height=16; + + //print_line("ERROR? "+itos(glGetError())); + if ( read_depth_supported ) { + + // We'll use a depth texture to store the depths in the shadow map + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, cls->size, cls->height, 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, cls->depth, 0); + +#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, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + // Attach the RGBA texture to FBO color attachment point + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, cls->depth, 0); + + // Allocate 16-bit depth buffer + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, cls->size, cls->height); + + // Attach the render buffer as depth buffer - will be ignored + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, cls->rbo); + + + } + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + //printf("errnum: %x\n",status); +#ifdef GLEW_ENABLED + if (read_depth_supported) { + glDrawBuffer(GL_BACK); + } +#endif + glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer); + DEBUG_TEST_ERROR("2D Shadow Buffer Init"); + ERR_FAIL_COND_V( status != GL_FRAMEBUFFER_COMPLETE, RID() ); + +#ifdef GLEW_ENABLED + if (read_depth_supported) { + glDrawBuffer(GL_BACK); + } +#endif + + return canvas_light_shadow_owner.make_rid(cls); +} + +void RasterizerGLES2::canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, CanvasLightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache) { + + CanvasLightShadow *cls = canvas_light_shadow_owner.get(p_buffer); + ERR_FAIL_COND(!cls); + + + glDisable(GL_BLEND); + glDisable(GL_SCISSOR_TEST); + glDisable(GL_DITHER); + glDisable(GL_CULL_FACE); + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + glDepthMask(true); + + glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo); + + if (!use_rgba_shadowmaps) + glColorMask(0, 0, 0, 0); + + glEnableVertexAttribArray(VS::ARRAY_VERTEX); + canvas_shadow_shader.bind(); + + const int vp_height = 10; + + glViewport(0, 0, cls->size,cls->height); + _glClearDepth(1.0f); + glClearColor(1,1,1,1); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + VS::CanvasOccluderPolygonCullMode cull=VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; + + + for(int i=0;i<4;i++) { + + //make sure it remains orthogonal, makes easy to read angle later + + Transform light; + light.origin[0]=p_light_xform[2][0]; + light.origin[1]=p_light_xform[2][1]; + light.basis[0][0]=p_light_xform[0][0]; + light.basis[0][1]=p_light_xform[1][0]; + light.basis[1][0]=p_light_xform[0][1]; + light.basis[1][1]=p_light_xform[1][1]; + + //light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1)); + + /// p_near=1; + CameraMatrix projection; + { + real_t fov = 90; + real_t near = p_near; + real_t far = p_far; + real_t aspect = 1.0; + + real_t ymax = near * Math::tan( Math::deg2rad( fov * 0.5 ) ); + real_t ymin = - ymax; + real_t xmin = ymin * aspect; + real_t xmax = ymax * aspect; + + projection.set_frustum( xmin, xmax, ymin, ymax, near, far ); + } + + Vector3 cam_target=Matrix3(Vector3(0,0,Math_PI*2*(i/4.0))).xform(Vector3(0,1,0)); + projection = projection * CameraMatrix(Transform().looking_at(cam_target,Vector3(0,0,-1)).affine_inverse()); + + //print_line("near: "+rtos(p_near)); + //print_line("far: "+rtos(p_far)); + //projection.set_perspective(60,size/float(vp_height),p_near,p_far); + + // CameraMatrix light_mat = projection * CameraMatrix(camera); + + canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::PROJECTION_MATRIX,projection); + canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::LIGHT_MATRIX,light); + + if (i==0) + *p_xform_cache=projection; + + glViewport(0, (cls->height/4)*i, cls->size,cls->height/4); + + CanvasLightOccluderInstance *instance=p_occluders; + + while(instance) { + + CanvasOccluder *cc = canvas_occluder_owner.get(instance->polygon_buffer); + if (!cc || cc->len==0 || !(p_light_mask&instance->light_mask)) { + + instance=instance->next; + continue; + } + + canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::WORLD_MATRIX,instance->xform_cache); + if (cull!=instance->cull_cache) { + + cull=instance->cull_cache; + switch(cull) { + case VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED: { + + glDisable(GL_CULL_FACE); + + } break; + case VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE: { + + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + } break; + case VS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE: { + + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + } break; + } + } +/* + if (i==0) { + for(int i=0;ilines.size();i++) { + Vector2 p = instance->xform_cache.xform(cc->lines.get(i)); + Plane pp(Vector3(p.x,p.y,0),1); + pp.normal = light.xform(pp.normal); + pp = projection.xform4(pp); + print_line(itos(i)+": "+pp.normal/pp.d); + //pp=light_mat.xform4(pp); + //print_line(itos(i)+": "+pp.normal/pp.d); + } + } +*/ + glBindBuffer(GL_ARRAY_BUFFER,cc->vertex_id); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,cc->index_id); + glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false, 0, 0); + glDrawElements(GL_TRIANGLES,cc->len*3,GL_UNSIGNED_SHORT,0); + + + instance=instance->next; + } + + + } + + glDisableVertexAttribArray(VS::ARRAY_VERTEX); + glBindBuffer(GL_ARRAY_BUFFER,0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); + + if (shadow_filter==SHADOW_FILTER_ESM) { + //blur the buffer +#if 0 + //this is ignord, it did not make any difference.. + if (read_depth_supported) { + glDepthFunc(GL_ALWAYS); + } else { + glDisable(GL_DEPTH_TEST); + glDepthMask(false); + } + glDisable(GL_CULL_FACE); + glViewport(0, 0, cls->size,cls->height); + + int passes=1; + CanvasLightShadow *blur = canvas_light_shadow_owner.get(canvas_shadow_blur); + + copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_H_PASS,true); + copy_shader.bind(); + copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SCALE,1); + copy_shader.set_uniform(CopyShaderGLES2::BLUR_MAGNITUDE,1); + glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE),0); + + for(int i=0;ifbo); + glActiveTexture(GL_TEXTURE0); + + if (read_depth_supported) + glBindTexture(GL_TEXTURE_2D,cls->depth); + else + glBindTexture(GL_TEXTURE_2D,cls->rgba); + + + { + Vector2 src_sb_uv[4]={ + Vector2( 0, 1), + Vector2( 1, 1), + Vector2( 1, 0), + Vector2( 0, 0) + }; + static const Vector2 dst_pos[4]={ + Vector2(-1, 1), + Vector2( 1, 1), + Vector2( 1,-1), + Vector2(-1,-1) + }; + + + + copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE,Vector2(1.0,1.0)/cls->size); + _draw_gui_primitive(4,dst_pos,NULL,src_sb_uv); + } + + glActiveTexture(GL_TEXTURE0); + if (read_depth_supported) + glBindTexture(GL_TEXTURE_2D,blur->depth); + else + glBindTexture(GL_TEXTURE_2D,blur->rgba); + + glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo); + + { + float hlimit = float(cls->size) / blur->size; + //hlimit*=2.0; + Vector2 src_sb_uv[4]={ + Vector2( 0, 1), + Vector2( hlimit, 1), + Vector2( hlimit, 0), + Vector2( 0, 0) + }; + static const Vector2 dst_pos[4]={ + Vector2(-1, 1), + Vector2( 1, 1), + Vector2( 1,-1), + Vector2(-1,-1) + }; + + + copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE,Vector2(1.0,1.0)/blur->size); + _draw_gui_primitive(4,dst_pos,NULL,src_sb_uv); + } + + } + copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_H_PASS,false); + glDepthFunc(GL_LEQUAL); +#endif + } + + glBindFramebuffer(GL_FRAMEBUFFER, current_rt?current_rt->fbo:base_framebuffer); + glColorMask(1, 1, 1, 1); + + + +} + + +void RasterizerGLES2::canvas_debug_viewport_shadows(CanvasLight* p_lights_with_shadow) { + + CanvasLight* light=p_lights_with_shadow; + + canvas_begin(); //reset + + int h = 10; + int w = viewport.width; + int ofs = h; + while(light) { + + if (light->shadow_buffer.is_valid()) { + + CanvasLightShadow * sb = canvas_light_shadow_owner.get(light->shadow_buffer); + if (sb) { + glActiveTexture(GL_TEXTURE0); + if (read_depth_supported) + glBindTexture(GL_TEXTURE_2D,sb->depth); + else + glBindTexture(GL_TEXTURE_2D,sb->rgba); + _draw_textured_quad(Rect2(h,ofs,w-h*2,h),Rect2(0,0,sb->size,10),Size2(sb->size,10),false,false); + ofs+=h*2; + + } + } + + light=light->shadows_next_ptr; + } + +} + void RasterizerGLES2::_canvas_normal_set_flip(const Vector2& p_flip) { if (p_flip==normal_flip) @@ -8508,14 +8983,14 @@ void RasterizerGLES2::_canvas_item_render_commands(CanvasItem *p_item,CanvasItem } -void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItem *shader_owner,Shader* shader) { +void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItemMaterial *material,Shader* shader) { if (canvas_shader.bind()) rebind_texpixel_size=true; - if (shader_owner->shader_version!=shader->version) { + if (material->shader_version!=shader->version) { //todo optimize uniforms - shader_owner->shader_version=shader->version; + material->shader_version=shader->version; } if (shader->has_texscreen && framebuffer.active) { @@ -8558,14 +9033,14 @@ void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItem *shader_owner, } -void RasterizerGLES2::_canvas_item_setup_shader_uniforms(CanvasItem *shader_owner,Shader* shader) { +void RasterizerGLES2::_canvas_item_setup_shader_uniforms(CanvasItemMaterial *material,Shader* shader) { //this can be optimized.. int tex_id=1; int idx=0; for(Map::Element *E=shader->uniforms.front();E;E=E->next()) { - Map::Element *F=shader_owner->shader_param.find(E->key()); + Map::Element *F=material->shader_param.find(E->key()); if ((E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP)) { @@ -8623,6 +9098,8 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_modulate=p_modulate; canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate); + bool reset_modulate=false; + while(p_item_list) { CanvasItem *ci=p_item_list; @@ -8632,12 +9109,13 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const draw_viewport_func(ci->vp_render->owner,ci->vp_render->udata,ci->vp_render->rect); } memdelete(ci->vp_render); - ci->vp_render=NULL; - canvas_last_shader=RID(); + ci->vp_render=NULL; + canvas_last_material=NULL; canvas_use_modulate=p_modulate!=Color(1,1,1,1); canvas_modulate=p_modulate; canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate); rebind_shader=true; + reset_modulate=true; } @@ -8660,13 +9138,14 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const //begin rect - CanvasItem *shader_owner = ci->shader_owner?ci->shader_owner:ci; + CanvasItem *material_owner = ci->material_owner?ci->material_owner:ci; + CanvasItemMaterial *material = material_owner->material; - if (shader_owner->shader!=canvas_last_shader || rebind_shader) { + if (material!=canvas_last_material || rebind_shader) { Shader *shader = NULL; - if (shader_owner->shader.is_valid()) { - shader = this->shader_owner.get(shader_owner->shader); + if (material && material->shader.is_valid()) { + shader = shader_owner.get(material->shader); if (shader && !shader->valid) { shader=NULL; } @@ -8676,7 +9155,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const if (shader) { canvas_shader.set_custom_shader(shader->custom_code_id); - _canvas_item_setup_shader_params(shader_owner,shader); + _canvas_item_setup_shader_params(material,shader); } else { shader_cache=NULL; canvas_shader.set_custom_shader(0); @@ -8688,16 +9167,26 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform); if (canvas_use_modulate) - canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,canvas_modulate); - canvas_last_shader=shader_owner->shader; + reset_modulate=true; + canvas_last_material=material; rebind_shader=false; } - if (shader_cache) { + if (material && shader_cache) { + + _canvas_item_setup_shader_uniforms(material,shader_cache); + } - _canvas_item_setup_shader_uniforms(shader_owner,shader_cache); + if (material && material->unshaded) { + canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,Color(1,1,1,1)); + reset_modulate=true; + } else if (reset_modulate) { + canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,canvas_modulate); + reset_modulate=false; } + + canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform); canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX,Matrix32()); @@ -8747,7 +9236,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const _canvas_item_render_commands(ci,current_clip,reclip); - if (canvas_blend_mode==VS::MATERIAL_BLEND_MODE_MIX && p_light) { + if (canvas_blend_mode==VS::MATERIAL_BLEND_MODE_MIX && p_light && (!material || !material->unshaded)) { CanvasLight *light = p_light; bool light_used=false; @@ -8785,13 +9274,15 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const normal_flip=Vector2(1,1); } + canvas_shader.set_conditional(CanvasShaderGLES2::USE_SHADOWS,light->shadow_buffer.is_valid()); + bool light_rebind = canvas_shader.bind(); if (light_rebind) { - if (shader_owner && shader_cache) { - _canvas_item_setup_shader_params(shader_owner,shader_cache); - _canvas_item_setup_shader_uniforms(shader_owner,shader_cache); + if (material && shader_cache) { + _canvas_item_setup_shader_params(material,shader_cache); + _canvas_item_setup_shader_uniforms(material,shader_cache); } canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform); @@ -8800,6 +9291,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const if (canvas_use_modulate) canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,canvas_modulate); canvas_shader.set_uniform(CanvasShaderGLES2::NORMAL_FLIP,Vector2(1,1)); + canvas_shader.set_uniform(CanvasShaderGLES2::SHADOWPIXEL_SIZE,1.0/light->shadow_buffer_size); } @@ -8808,6 +9300,23 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const 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_HEIGHT,light->height); + if (light->shadow_buffer.is_valid()) { + + CanvasLightShadow *cls = canvas_light_shadow_owner.get(light->shadow_buffer); + glActiveTexture(GL_TEXTURE0+max_texture_units-3); + if (read_depth_supported) + glBindTexture(GL_TEXTURE_2D,cls->depth); + else + glBindTexture(GL_TEXTURE_2D,cls->rgba); + + canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_TEXTURE,max_texture_units-3); + canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_MATRIX,light->shadow_matrix_cache); + canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_LOCAL_MATRIX,light->xform_cache.affine_inverse()); + canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_ESM_MULTIPLIER,light->shadow_esm_mult); + + } + + glActiveTexture(GL_TEXTURE0+max_texture_units-2); canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_TEXTURE,max_texture_units-2); Texture *t = texture_owner.get(light->texture); @@ -8831,12 +9340,13 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const canvas_shader.set_conditional(CanvasShaderGLES2::USE_LIGHTING,false); canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate); + canvas_shader.set_conditional(CanvasShaderGLES2::USE_SHADOWS,false); canvas_shader.bind(); - if (shader_owner && shader_cache) { - _canvas_item_setup_shader_params(shader_owner,shader_cache); - _canvas_item_setup_shader_uniforms(shader_owner,shader_cache); + if (material && shader_cache) { + _canvas_item_setup_shader_params(material,shader_cache); + _canvas_item_setup_shader_uniforms(material,shader_cache); } canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform); @@ -9067,6 +9577,11 @@ bool RasterizerGLES2::is_environment(const RID& p_rid) const { } bool RasterizerGLES2::is_shader(const RID& p_rid) const { + return shader_owner.owns(p_rid); +} + +bool RasterizerGLES2::is_canvas_light_occluder(const RID& p_rid) const { + return false; } @@ -9244,7 +9759,30 @@ void RasterizerGLES2::free(const RID& p_rid) { glDeleteTextures(1,&sampled_light->texture); sampled_light_owner.free(p_rid); memdelete( sampled_light ); + } else if (canvas_occluder_owner.owns(p_rid)) { + + CanvasOccluder *co = canvas_occluder_owner.get(p_rid); + if (co->index_id) + glDeleteBuffers(1,&co->index_id); + if (co->vertex_id) + glDeleteBuffers(1,&co->vertex_id); + + canvas_occluder_owner.free(p_rid); + memdelete(co); + + } else if (canvas_light_shadow_owner.owns(p_rid)) { + + CanvasLightShadow *cls = canvas_light_shadow_owner.get(p_rid); + glDeleteFramebuffers(1,&cls->fbo); + glDeleteRenderbuffers(1,&cls->rbo); + glDeleteTextures(1,&cls->depth); + if (!read_depth_supported) { + glDeleteTextures(1,&cls->rgba); + } + + canvas_light_shadow_owner.free(p_rid); + memdelete(cls); }; } @@ -9779,10 +10317,12 @@ void RasterizerGLES2::init() { material_shader.init(); canvas_shader.init(); copy_shader.init(); + canvas_shadow_shader.init(); #ifdef GLEW_ENABLED material_shader.set_conditional(MaterialShaderGLES2::USE_GLES_OVER_GL,true); canvas_shader.set_conditional(CanvasShaderGLES2::USE_GLES_OVER_GL,true); + canvas_shadow_shader.set_conditional(CanvasShadowShaderGLES2::USE_GLES_OVER_GL,true); copy_shader.set_conditional(CopyShaderGLES2::USE_GLES_OVER_GL,true); #endif @@ -9923,8 +10463,11 @@ void RasterizerGLES2::init() { glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_units); + glGetIntegerv(GL_MAX_TEXTURE_SIZE,&max_texture_size); //read_depth_supported=false; + canvas_shadow_blur = canvas_light_shadow_buffer_create(max_texture_size); + { //shadowmaps OS::VideoMode vm=OS::get_singleton()->get_video_mode(); @@ -9946,6 +10489,7 @@ void RasterizerGLES2::init() { //material_shader material_shader.set_conditional(MaterialShaderGLES2::USE_DEPTH_SHADOWS,!use_rgba_shadowmaps); + canvas_shadow_shader.set_conditional(CanvasShadowShaderGLES2::USE_DEPTH_SHADOWS,!use_rgba_shadowmaps); } @@ -9978,7 +10522,7 @@ void RasterizerGLES2::init() { void RasterizerGLES2::finish() { - + free(canvas_shadow_blur); } int RasterizerGLES2::get_render_info(VS::RenderInfo p_info) { diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index 173ca1418..f09714f50 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -51,6 +51,7 @@ #include "drivers/gles2/shaders/material.glsl.h" #include "drivers/gles2/shaders/canvas.glsl.h" +#include "drivers/gles2/shaders/canvas_shadow.glsl.h" #include "drivers/gles2/shaders/blur.glsl.h" #include "drivers/gles2/shaders/copy.glsl.h" #include "drivers/gles2/shader_compiler_gles2.h" @@ -816,6 +817,7 @@ class RasterizerGLES2 : public Rasterizer { bool current_depth_mask; VS::MaterialBlendMode current_blend_mode; bool use_fast_texture_filter; + int max_texture_size; bool fragment_lighting; RID shadow_material; @@ -1160,6 +1162,7 @@ class RasterizerGLES2 : public Rasterizer { void _process_glow_and_bloom(); //void _update_blur_buffer(); + /*********/ /* FRAME */ /*********/ @@ -1178,6 +1181,45 @@ class RasterizerGLES2 : public Rasterizer { } _rinfo; + /*******************/ + /* CANVAS OCCLUDER */ + /*******************/ + + + struct CanvasOccluder { + + GLuint vertex_id; // 0 means, unconfigured + GLuint index_id; // 0 means, unconfigured + DVector lines; + int len; + }; + + RID_Owner canvas_occluder_owner; + + /***********************/ + /* CANVAS LIGHT SHADOW */ + /***********************/ + + + struct CanvasLightShadow { + + int size; + int height; + GLuint fbo; + GLuint rbo; + GLuint depth; + GLuint rgba; //for older devices + + GLuint blur; + + }; + + RID_Owner canvas_light_shadow_owner; + + RID canvas_shadow_blur; + + /* ETC */ + RenderTarget *current_rt; bool current_rt_transparent; bool current_rt_vflip; @@ -1192,7 +1234,7 @@ class RasterizerGLES2 : public Rasterizer { bool uses_texpixel_size; bool rebind_texpixel_size; Transform canvas_transform; - RID canvas_last_shader; + CanvasItemMaterial *canvas_last_material; bool canvas_texscreen_used; Vector2 normal_flip; _FORCE_INLINE_ void _canvas_normal_set_flip(const Vector2& p_flip); @@ -1227,10 +1269,12 @@ class RasterizerGLES2 : public Rasterizer { VS::ScenarioDebugMode current_debug; RID overdraw_material; + mutable MaterialShaderGLES2 material_shader; mutable CanvasShaderGLES2 canvas_shader; BlurShaderGLES2 blur_shader; CopyShaderGLES2 copy_shader; + mutable CanvasShadowShaderGLES2 canvas_shadow_shader; mutable ShaderCompilerGLES2 shader_precompiler; @@ -1254,8 +1298,8 @@ class RasterizerGLES2 : public Rasterizer { template _FORCE_INLINE_ void _canvas_item_render_commands(CanvasItem *p_item,CanvasItem *current_clip,bool &reclip); - _FORCE_INLINE_ void _canvas_item_setup_shader_params(CanvasItem *shader_owner,Shader* p_shader); - _FORCE_INLINE_ void _canvas_item_setup_shader_uniforms(CanvasItem *shader_owner,Shader* p_shader); + _FORCE_INLINE_ void _canvas_item_setup_shader_params(CanvasItemMaterial *material,Shader* p_shader); + _FORCE_INLINE_ void _canvas_item_setup_shader_uniforms(CanvasItemMaterial *material,Shader* p_shader); public: /* TEXTURE API */ @@ -1572,7 +1616,17 @@ public: virtual void canvas_set_transform(const Matrix32& p_transform); virtual void canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light); + virtual void canvas_debug_viewport_shadows(CanvasLight* p_lights_with_shadow); + /* CANVAS LIGHT SHADOW */ + + //buffer + virtual RID canvas_light_shadow_buffer_create(int p_width); + virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, CanvasLightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache); + + //occluder + virtual RID canvas_light_occluder_create(); + virtual void canvas_light_occluder_set_polylines(RID p_occluder, const DVector& p_lines); /* ENVIRONMENT */ @@ -1611,6 +1665,8 @@ public: virtual bool is_environment(const RID& p_rid) const; virtual bool is_shader(const RID& p_rid) const; + virtual bool is_canvas_light_occluder(const RID& p_rid) const; + virtual void free(const RID& p_rid); virtual void init(); diff --git a/drivers/gles2/shaders/SCsub b/drivers/gles2/shaders/SCsub index c665cf903..9679223b1 100644 --- a/drivers/gles2/shaders/SCsub +++ b/drivers/gles2/shaders/SCsub @@ -3,6 +3,7 @@ Import('env') if env['BUILDERS'].has_key('GLSL120GLES'): env.GLSL120GLES('material.glsl'); env.GLSL120GLES('canvas.glsl'); + env.GLSL120GLES('canvas_shadow.glsl'); env.GLSL120GLES('blur.glsl'); env.GLSL120GLES('copy.glsl'); diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index 227a8b7bd..9022f30d7 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -34,6 +34,10 @@ varying vec4 local_rot; uniform vec2 normal_flip; #endif +#ifdef USE_SHADOWS +highp varying vec2 pos; +#endif + #endif #if defined(ENABLE_VAR1_INTERP) @@ -63,6 +67,8 @@ VERTEX_SHADER_CODE outvec = modelview_matrix * outvec; #endif + + #ifdef USE_PIXEL_SNAP outvec.xy=floor(outvec.xy+0.5); @@ -75,6 +81,9 @@ VERTEX_SHADER_CODE light_uv_interp.xy = (light_matrix * outvec).xy; light_uv_interp.zw = outvec.xy-light_pos; +#ifdef USE_SHADOWS + pos=outvec.xy; +#endif #if defined(NORMAL_USED) local_rot.xy=normalize( (modelview_matrix * ( extra_matrix * vec4(1.0,0.0,0.0,0.0) )).xy )*normal_flip.x; @@ -154,6 +163,15 @@ varying vec4 local_rot; uniform sampler2D shadow_texture; uniform float shadow_attenuation; +uniform highp mat4 shadow_matrix; +uniform highp mat4 light_local_matrix; +highp varying vec2 pos; +uniform float shadowpixel_size; + +#ifdef SHADOW_ESM +uniform float shadow_esm_multiplier; +#endif + #endif #endif @@ -173,10 +191,6 @@ void main() { vec3 normal = vec3(0,0,1); #endif -#ifdef USE_MODULATE - - color*=modulate; -#endif color *= texture2D( texture, uv_interp ); #if defined(ENABLE_SCREEN_UV) @@ -191,6 +205,12 @@ FRAGMENT_SHADER_CODE color = vec4(vec3(enc32),1.0); #endif +#ifdef USE_MODULATE + + color*=modulate; +#endif + + #ifdef USE_LIGHTING #if defined(NORMAL_USED) @@ -201,13 +221,96 @@ FRAGMENT_SHADER_CODE vec4 light = texture2D(light_texture,light_uv_interp.xy) * light_color; #ifdef USE_SHADOWS - //this might not be that great on mobile? - float light_dist = length(light_texture.zw); - float light_angle = atan2(light_texture.x,light_texture.z) + 1.0 * 0.5; - float shadow_dist = texture2D(shadow_texture,vec2(light_angle,0)); - if (light_dist>shadow_dist) { - light*=shadow_attenuation; + + + vec2 lpos = (light_local_matrix * vec4(pos,0.0,1.0)).xy; + float angle_to_light = -atan(lpos.x,lpos.y); + float PI = 3.14159265358979323846264; + /*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays + float ang*/ + + float su,sz; + + float abs_angle = abs(angle_to_light); + vec2 point; + float sh; + if (abs_angle<45.0*PI/180.0) { + point = lpos; + sh=0+(1.0/8.0); + } else if (abs_angle>135.0*PI/180.0) { + point = -lpos; + sh = 0.5+(1.0/8.0); + } else if (angle_to_light>0) { + + point = vec2(lpos.y,-lpos.x); + sh = 0.25+(1.0/8.0); + } else { + + point = vec2(-lpos.y,lpos.x); + sh = 0.75+(1.0/8.0); + + } + + + vec4 s = shadow_matrix * vec4(point,0.0,1.0); + s.xyz/=s.w; + su=s.x*0.5+0.5; + sz=s.z*0.5+0.5; + + float shadow_attenuation; + +#ifdef SHADOW_PCF5 + + shadow_attenuation=0.0; + shadow_attenuation += texture2D(shadow_texture,vec2(su,sh)).z +#include "Shlwapi.h" #include "file_access_windows.h" + #include #include #include #include #include "print_string.h" + #ifdef _MSC_VER #define S_ISREG(m) ((m)&_S_IFREG) #endif @@ -111,10 +115,20 @@ void FileAccessWindows::close() { //unlink(save_path.utf8().get_data()); //print_line("renaming.."); - _wunlink(save_path.c_str()); //unlink if exists - int rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str()); + //_wunlink(save_path.c_str()); //unlink if exists + //int rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str()); + + + bool rename_error; + if (!PathFileExistsW(save_path.c_str())) { + //creating new file + rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str())!=0; + } else { + //atomic replace for existing file + rename_error = !ReplaceFileW(save_path.c_str(), (save_path+".tmp").c_str(), NULL, 2|4, NULL, NULL); + } save_path=""; - ERR_FAIL_COND( rename_error != 0); + ERR_FAIL_COND( rename_error ); } diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index 0aa115ffb..d3a9abf4b 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -2696,7 +2696,10 @@ Error ResourceFormatSaverGDScript::save(const String &p_path,const RES& p_resour } file->store_string(source); - + if (file->get_error()!=OK && file->get_error()!=ERR_FILE_EOF) { + memdelete(file); + return ERR_CANT_CREATE; + } file->close(); memdelete(file); return OK; diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp index 857d1a4a5..4c0c095e1 100644 --- a/platform/android/audio_driver_opensl.cpp +++ b/platform/android/audio_driver_opensl.cpp @@ -396,6 +396,14 @@ void AudioDriverOpenSL::finish(){ void AudioDriverOpenSL::set_pause(bool p_pause) { pause=p_pause; + + if (active) { + if (pause) { + (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PAUSED); + } else { + (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING); + } + } } diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 6f1c03b59..6b91c01df 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -151,7 +151,7 @@ void OS_Android::initialize(const VideoMode& p_desired,int p_video_driver,int p_ sample_manager = memnew( SampleManagerMallocSW ); audio_server = memnew( AudioServerSW(sample_manager) ); - audio_server->set_mixer_params(AudioMixerSW::INTERPOLATION_LINEAR,false); + audio_server->set_mixer_params(AudioMixerSW::INTERPOLATION_LINEAR,true); audio_server->init(); spatial_sound_server = memnew( SpatialSoundServerSW ); diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 16dd695c5..62bab00f7 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -115,7 +115,7 @@ def configure(env): env.Append(CCFLAGS=['/DGLES2_ENABLED']) env.Append(CCFLAGS=['/DGLEW_ENABLED']) - LIBS=['winmm','opengl32','dsound','kernel32','ole32','user32','gdi32', 'IPHLPAPI', 'wsock32', 'shell32','advapi32'] + LIBS=['winmm','opengl32','dsound','kernel32','ole32','user32','gdi32', 'IPHLPAPI','Shlwapi', 'wsock32', 'shell32','advapi32'] env.Append(LINKFLAGS=[p+env["LIBSUFFIX"] for p in LIBS]) env.Append(LIBPATH=[os.getenv("WindowsSdkDir")+"/Lib"]) @@ -229,7 +229,7 @@ def configure(env): env.Append(CCFLAGS=['-DWINDOWS_ENABLED','-mwindows']) env.Append(CPPFLAGS=['-DRTAUDIO_ENABLED']) env.Append(CCFLAGS=['-DGLES2_ENABLED','-DGLEW_ENABLED']) - env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','iphlpapi','wsock32','kernel32']) + env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','iphlpapi','shlwapi','wsock32','kernel32']) if (env["bits"]=="32" and env["mingw64_for_32"]!="yes"): # env.Append(LIBS=['gcc_s']) diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 223adaf9b..4a1842100 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -36,6 +36,192 @@ #include "scene/resources/texture.h" #include "scene/resources/style_box.h" + +bool CanvasItemMaterial::_set(const StringName& p_name, const Variant& p_value) { + + if (p_name==SceneStringNames::get_singleton()->shader_shader) { + set_shader(p_value); + return true; + } else if (p_name==SceneStringNames::get_singleton()->shader_unshaded) { + set_unshaded(p_value); + print_line("set unshaded"); + return true; + } else { + + if (shader.is_valid()) { + + + StringName pr = shader->remap_param(p_name); + if (!pr) { + String n = p_name; + if (n.find("param/")==0) { //backwards compatibility + pr = n.substr(6,n.length()); + } + } + if (pr) { + VisualServer::get_singleton()->canvas_item_material_set_shader_param(material,pr,p_value); + return true; + } + } + } + + return false; +} + +bool CanvasItemMaterial::_get(const StringName& p_name,Variant &r_ret) const { + + + if (p_name==SceneStringNames::get_singleton()->shader_shader) { + + r_ret=get_shader(); + return true; + } else if (p_name==SceneStringNames::get_singleton()->shader_unshaded) { + + + r_ret=unshaded; + return true; + } else { + + if (shader.is_valid()) { + + StringName pr = shader->remap_param(p_name); + if (pr) { + r_ret=VisualServer::get_singleton()->canvas_item_material_get_shader_param(material,pr); + return true; + } + } + + } + + + return false; +} + + +void CanvasItemMaterial::_get_property_list( List *p_list) const { + + p_list->push_back( PropertyInfo( Variant::OBJECT, "shader/shader", PROPERTY_HINT_RESOURCE_TYPE,"CanvasItemShader,CanvasItemShaderGraph" ) ); + p_list->push_back( PropertyInfo( Variant::BOOL, "shader/unshaded") ); + + if (!shader.is_null()) { + + shader->get_param_list(p_list); + } + +} + +void CanvasItemMaterial::set_shader(const Ref& p_shader) { + + ERR_FAIL_COND(p_shader.is_valid() && p_shader->get_mode()!=Shader::MODE_CANVAS_ITEM); +#ifdef TOOLS_ENABLED + + if (shader.is_valid()) { + shader->disconnect("changed",this,"_shader_changed"); + } +#endif + shader=p_shader; + +#ifdef TOOLS_ENABLED + + if (shader.is_valid()) { + shader->connect("changed",this,"_shader_changed"); + } +#endif + + RID rid; + if (shader.is_valid()) + rid=shader->get_rid(); + + VS::get_singleton()->canvas_item_material_set_shader(material,rid); + _change_notify(); //properties for shader exposed + emit_changed(); +} + +Ref CanvasItemMaterial::get_shader() const{ + + return shader; +} + +void CanvasItemMaterial::set_shader_param(const StringName& p_param,const Variant& p_value){ + + VS::get_singleton()->canvas_item_material_set_shader_param(material,p_param,p_value); +} + +Variant CanvasItemMaterial::get_shader_param(const StringName& p_param) const{ + + return VS::get_singleton()->canvas_item_material_get_shader_param(material,p_param); +} + +void CanvasItemMaterial::_shader_changed() { + + +} + +RID CanvasItemMaterial::get_rid() const { + + return material; +} + +void CanvasItemMaterial::set_unshaded(bool p_unshaded) { + + unshaded=p_unshaded; + VS::get_singleton()->canvas_item_material_set_unshaded(material,p_unshaded); +} + +bool CanvasItemMaterial::is_unshaded() const{ + + return unshaded; +} + +void CanvasItemMaterial::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_shader","shader:Shader"),&CanvasItemMaterial::set_shader); + ObjectTypeDB::bind_method(_MD("get_shader:Shader"),&CanvasItemMaterial::get_shader); + ObjectTypeDB::bind_method(_MD("set_shader_param","param","value"),&CanvasItemMaterial::set_shader_param); + ObjectTypeDB::bind_method(_MD("get_shader_param","param"),&CanvasItemMaterial::get_shader_param); + ObjectTypeDB::bind_method(_MD("set_unshaded","unshaded"),&CanvasItemMaterial::set_unshaded); + ObjectTypeDB::bind_method(_MD("is_unshaded"),&CanvasItemMaterial::is_unshaded); + +} + +void CanvasItemMaterial::get_argument_options(const StringName& p_function,int p_idx,List*r_options) const { + + String f = p_function.operator String(); + if ((f=="get_shader_param" || f=="set_shader_param") && p_idx==0) { + + if (shader.is_valid()) { + List pl; + shader->get_param_list(&pl); + for (List::Element *E=pl.front();E;E=E->next()) { + r_options->push_back("\""+E->get().name.replace_first("shader_param/","")+"\""); + } + } + } + Resource::get_argument_options(p_function,p_idx,r_options); +} + +CanvasItemMaterial::CanvasItemMaterial() { + + material=VS::get_singleton()->canvas_item_material_create(); + unshaded=false; +} + +CanvasItemMaterial::~CanvasItemMaterial(){ + + VS::get_singleton()->free(material); +} + + + + + + + + +/////////////////////////////////////////////////////////////////// + + + bool CanvasItem::is_visible() const { if (!is_inside_tree()) @@ -730,111 +916,35 @@ bool CanvasItem::is_draw_behind_parent_enabled() const{ return behind; } -void CanvasItem::set_shader(const Ref& p_shader) { - - ERR_FAIL_COND(p_shader.is_valid() && p_shader->get_mode()!=Shader::MODE_CANVAS_ITEM); - -#ifdef TOOLS_ENABLED - - if (shader.is_valid()) { - shader->disconnect("changed",this,"_shader_changed"); - } -#endif - shader=p_shader; - -#ifdef TOOLS_ENABLED +void CanvasItem::set_material(const Ref& p_material) { - if (shader.is_valid()) { - shader->connect("changed",this,"_shader_changed"); - } -#endif + material=p_material; RID rid; - if (shader.is_valid()) - rid=shader->get_rid(); - VS::get_singleton()->canvas_item_set_shader(canvas_item,rid); - _change_notify(); //properties for shader exposed -} - -void CanvasItem::set_use_parent_shader(bool p_use_parent_shader) { - - use_parent_shader=p_use_parent_shader; - VS::get_singleton()->canvas_item_set_use_parent_shader(canvas_item,p_use_parent_shader); + if (material.is_valid()) + rid=material->get_rid(); + VS::get_singleton()->canvas_item_set_material(canvas_item,rid); + _change_notify(); //properties for material exposed } -bool CanvasItem::get_use_parent_shader() const{ +void CanvasItem::set_use_parent_material(bool p_use_parent_material) { - return use_parent_shader; + use_parent_material=p_use_parent_material; + VS::get_singleton()->canvas_item_set_use_parent_material(canvas_item,p_use_parent_material); } -Ref CanvasItem::get_shader() const{ +bool CanvasItem::get_use_parent_material() const{ - return shader; + return use_parent_material; } -void CanvasItem::set_shader_param(const StringName& p_param,const Variant& p_value) { +Ref CanvasItem::get_material() const{ - VS::get_singleton()->canvas_item_set_shader_param(canvas_item,p_param,p_value); + return material; } -Variant CanvasItem::get_shader_param(const StringName& p_param) const { - - return VS::get_singleton()->canvas_item_get_shader_param(canvas_item,p_param); -} - -bool CanvasItem::_set(const StringName& p_name, const Variant& p_value) { - - if (shader.is_valid()) { - StringName pr = shader->remap_param(p_name); - if (pr) { - set_shader_param(pr,p_value); - return true; - } - } - return false; -} -bool CanvasItem::_get(const StringName& p_name,Variant &r_ret) const{ - if (shader.is_valid()) { - StringName pr = shader->remap_param(p_name); - if (pr) { - r_ret=get_shader_param(pr); - return true; - } - } - return false; - -} -void CanvasItem::_get_property_list( List *p_list) const{ - - if (shader.is_valid()) { - shader->get_param_list(p_list); - } -} - -#ifdef TOOLS_ENABLED -void CanvasItem::_shader_changed() { - - _change_notify(); -} -#endif - -void CanvasItem::get_argument_options(const StringName& p_function,int p_idx,List*r_options) const { - - if (p_idx==0 && shader.is_valid() && (p_function.operator String()=="get_shader_param" || p_function.operator String()=="set_shader_param")) { - - List pl; - shader->get_param_list(&pl); - for(List::Element *E=pl.front();E;E=E->next()) { - r_options->push_back("\""+E->get().name.replace_first("shader_param/","")+"\""); - } - - return; - } - - Node::get_argument_options(p_function,p_idx,r_options); -} void CanvasItem::_bind_methods() { @@ -880,9 +990,6 @@ void CanvasItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("_set_on_top","on_top"),&CanvasItem::_set_on_top); ObjectTypeDB::bind_method(_MD("_is_on_top"),&CanvasItem::_is_on_top); -#ifdef TOOLS_ENABLED - ObjectTypeDB::bind_method(_MD("_shader_changed"),&CanvasItem::_shader_changed); -#endif //ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform); ObjectTypeDB::bind_method(_MD("draw_line","from","to","color","width"),&CanvasItem::draw_line,DEFVAL(1.0)); @@ -901,20 +1008,18 @@ void CanvasItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("draw_set_transform","pos","rot","scale"),&CanvasItem::draw_set_transform); ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform); ObjectTypeDB::bind_method(_MD("get_global_transform"),&CanvasItem::get_global_transform); + ObjectTypeDB::bind_method(_MD("get_global_transform_with_canvas"),&CanvasItem::get_global_transform_with_canvas); ObjectTypeDB::bind_method(_MD("get_viewport_transform"),&CanvasItem::get_viewport_transform); ObjectTypeDB::bind_method(_MD("get_viewport_rect"),&CanvasItem::get_viewport_rect); ObjectTypeDB::bind_method(_MD("get_canvas"),&CanvasItem::get_canvas); ObjectTypeDB::bind_method(_MD("get_world_2d"),&CanvasItem::get_world_2d); //ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasItem::get_viewport); - ObjectTypeDB::bind_method(_MD("set_shader","shader"),&CanvasItem::set_shader); - ObjectTypeDB::bind_method(_MD("get_shader"),&CanvasItem::get_shader); - ObjectTypeDB::bind_method(_MD("set_use_parent_shader","enable"),&CanvasItem::set_use_parent_shader); - ObjectTypeDB::bind_method(_MD("get_use_parent_shader"),&CanvasItem::get_use_parent_shader); - - ObjectTypeDB::bind_method(_MD("set_shader_param","param","value"),&CanvasItem::set_shader_param); - ObjectTypeDB::bind_method(_MD("get_shader_param","param"),&CanvasItem::get_shader_param); + ObjectTypeDB::bind_method(_MD("set_material","material:CanvasItemMaterial"),&CanvasItem::set_material); + ObjectTypeDB::bind_method(_MD("get_material:CanvasItemMaterial"),&CanvasItem::get_material); + ObjectTypeDB::bind_method(_MD("set_use_parent_material","enable"),&CanvasItem::set_use_parent_material); + ObjectTypeDB::bind_method(_MD("get_use_parent_material"),&CanvasItem::get_use_parent_material); BIND_VMETHOD(MethodInfo("_draw")); @@ -926,8 +1031,8 @@ void CanvasItem::_bind_methods() { ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,PMAlpha"), _SCS("set_blend_mode"),_SCS("get_blend_mode") ); ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/light_mask",PROPERTY_HINT_ALL_FLAGS), _SCS("set_light_mask"),_SCS("get_light_mask") ); - ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"shader/shader",PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemShader,CanvasItemShaderGraph"), _SCS("set_shader"),_SCS("get_shader") ); - ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"shader/use_parent"), _SCS("set_use_parent_shader"),_SCS("get_use_parent_shader") ); + ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"material/material",PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial"), _SCS("set_material"),_SCS("get_material") ); + ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"material/use_parent"), _SCS("set_use_parent_material"),_SCS("get_use_parent_material") ); //exporting these two things doesn't really make much sense i think //ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transform/toplevel"), _SCS("set_as_toplevel"),_SCS("is_set_as_toplevel") ); //ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),_SCS("set_transform_notify"),_SCS("is_transform_notify_enabled")); @@ -1004,7 +1109,7 @@ CanvasItem::CanvasItem() : xform_change(this) { block_transform_notify=false; // viewport=NULL; canvas_layer=NULL; - use_parent_shader=false; + use_parent_material=false; global_invalid=true; light_mask=1; diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 2441d205c..0c7be261a 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -40,6 +40,41 @@ class Font; class StyleBox; +class CanvasItemMaterial : public Resource{ + + OBJ_TYPE(CanvasItemMaterial,Resource); + RID material; + Ref shader; + bool unshaded; + +protected: + + bool _set(const StringName& p_name, const Variant& p_value); + bool _get(const StringName& p_name,Variant &r_ret) const; + void _get_property_list( List *p_list) const; + + void _shader_changed(); + static void _bind_methods(); + + void get_argument_options(const StringName& p_function,int p_idx,List*r_options) const; + +public: + + void set_shader(const Ref& p_shader); + Ref get_shader() const; + + void set_shader_param(const StringName& p_param,const Variant& p_value); + Variant get_shader_param(const StringName& p_param) const; + + void set_unshaded(bool p_unshaded); + bool is_unshaded() const; + + virtual RID get_rid() const; + CanvasItemMaterial(); + ~CanvasItemMaterial(); +}; + + class CanvasItem : public Node { OBJ_TYPE( CanvasItem, Node ); @@ -81,9 +116,9 @@ private: bool drawing; bool block_transform_notify; bool behind; - bool use_parent_shader; + bool use_parent_material; - Ref shader; + Ref material; mutable Matrix32 global_transform; mutable bool global_invalid; @@ -104,9 +139,6 @@ private: void _queue_sort_children(); void _sort_children(); -#ifdef TOOLS_ENABLED - void _shader_changed(); -#endif void _notify_transform(CanvasItem *p_node); void _set_on_top(bool p_on_top) { set_draw_behind_parent(!p_on_top); } @@ -114,11 +146,6 @@ private: protected: - bool _set(const StringName& p_name, const Variant& p_value); - bool _get(const StringName& p_name,Variant &r_ret) const; - void _get_property_list( List *p_list) const; - - _FORCE_INLINE_ void _notify_transform() { if (!is_inside_tree()) return; _notify_transform(this); if (!block_transform_notify) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); } void item_rect_changed(); @@ -216,16 +243,12 @@ public: RID get_canvas() const; Ref get_world_2d() const; - void set_shader(const Ref& p_shader); - Ref get_shader() const; + void set_material(const Ref& p_material); + Ref get_material() const; - void set_use_parent_shader(bool p_use_parent_shader); - bool get_use_parent_shader() const; + void set_use_parent_material(bool p_use_parent_material); + bool get_use_parent_material() const; - void set_shader_param(const StringName& p_param,const Variant& p_value); - Variant get_shader_param(const StringName& p_param) const; - - void get_argument_options(const StringName& p_function,int p_idx,List*r_options) const; CanvasItem(); ~CanvasItem(); diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index cea8c06d3..93be0c397 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -170,6 +170,29 @@ bool Light2D::is_shadow_enabled() const { return shadow; } +void Light2D::set_shadow_buffer_size( int p_size ) { + + shadow_buffer_size=p_size; + VS::get_singleton()->canvas_light_set_shadow_buffer_size(canvas_light,shadow_buffer_size); +} + +int Light2D::get_shadow_buffer_size() const { + + return shadow_buffer_size; +} + +void Light2D::set_shadow_esm_multiplier( float p_multiplier) { + + shadow_esm_multiplier=p_multiplier; + VS::get_singleton()->canvas_light_set_shadow_esm_multiplier(canvas_light,p_multiplier); +} + +float Light2D::get_shadow_esm_multiplier() const{ + + return shadow_esm_multiplier; +} + + void Light2D::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { @@ -229,18 +252,26 @@ void Light2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_shadow_enabled","enabled"),&Light2D::set_shadow_enabled); ObjectTypeDB::bind_method(_MD("is_shadow_enabled"),&Light2D::is_shadow_enabled); + ObjectTypeDB::bind_method(_MD("set_shadow_buffer_size","size"),&Light2D::set_shadow_buffer_size); + ObjectTypeDB::bind_method(_MD("get_shadow_buffer_size"),&Light2D::get_shadow_buffer_size); + + ObjectTypeDB::bind_method(_MD("set_shadow_esm_multiplier","multiplier"),&Light2D::set_shadow_esm_multiplier); + ObjectTypeDB::bind_method(_MD("get_shadow_esm_multiplier"),&Light2D::get_shadow_esm_multiplier); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled")); ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture")); - ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"texture_offset"),_SCS("set_texture_offset"),_SCS("get_texture_offset")); + ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"offset"),_SCS("set_texture_offset"),_SCS("get_texture_offset")); ADD_PROPERTY( PropertyInfo(Variant::COLOR,"color"),_SCS("set_color"),_SCS("get_color")); - ADD_PROPERTY( PropertyInfo(Variant::REAL,"height"),_SCS("set_height"),_SCS("get_height")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"z_range_min",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_min"),_SCS("get_z_range_min")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"z_range_max",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_max"),_SCS("get_z_range_max")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"layer_range_min",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_min"),_SCS("get_layer_range_min")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"layer_range_max",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_max"),_SCS("get_layer_range_max")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_mask"),_SCS("get_item_mask")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"subtract"),_SCS("set_subtract_mode"),_SCS("get_subtract_mode")); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"shadow_enabled"),_SCS("set_shadow_enabled"),_SCS("is_shadow_enabled")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"range/height"),_SCS("set_height"),_SCS("get_height")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"range/z_min",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_min"),_SCS("get_z_range_min")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"range/z_max",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_max"),_SCS("get_z_range_max")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"range/layer_min",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_min"),_SCS("get_layer_range_min")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"range/layer_max",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_max"),_SCS("get_layer_range_max")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"range/item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_mask"),_SCS("get_item_mask")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"shadow/enabled"),_SCS("set_shadow_enabled"),_SCS("is_shadow_enabled")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/buffer_size",PROPERTY_HINT_RANGE,"32,16384,1"),_SCS("set_shadow_buffer_size"),_SCS("get_shadow_buffer_size")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"shadow/esm_multiplier",PROPERTY_HINT_RANGE,"1,4096,0.1"),_SCS("set_shadow_esm_multiplier"),_SCS("get_shadow_esm_multiplier")); } @@ -258,6 +289,8 @@ Light2D::Light2D() { layer_max=0; item_mask=1; subtract_mode=false; + shadow_buffer_size=2048; + shadow_esm_multiplier=80; } diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index dbfd233d3..89f351c3c 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -17,6 +17,8 @@ private: int layer_min; int layer_max; int item_mask; + int shadow_buffer_size; + float shadow_esm_multiplier; bool subtract_mode; Ref texture; Vector2 texture_offset; @@ -68,6 +70,12 @@ public: void set_shadow_enabled( bool p_enabled); bool is_shadow_enabled() const; + void set_shadow_buffer_size( int p_size ); + int get_shadow_buffer_size() const; + + void set_shadow_esm_multiplier( float p_multiplier); + float get_shadow_esm_multiplier() const; + virtual Rect2 get_item_rect() const; Light2D(); diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp new file mode 100644 index 000000000..186ea2e24 --- /dev/null +++ b/scene/2d/light_occluder_2d.cpp @@ -0,0 +1,201 @@ +#include "light_occluder_2d.h" + + +void OccluderPolygon2D::set_polygon(const DVector& p_polygon) { + + polygon=p_polygon; + VS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon,p_polygon,closed); + emit_changed(); +} + +DVector OccluderPolygon2D::get_polygon() const{ + + return polygon; +} + +void OccluderPolygon2D::set_closed(bool p_closed) { + + if (closed==p_closed) + return; + closed=p_closed; + VS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon,polygon,closed); + emit_changed(); +} + +bool OccluderPolygon2D::is_closed() const{ + + return closed; +} + +void OccluderPolygon2D::set_cull_mode(CullMode p_mode){ + + cull=p_mode; + VS::get_singleton()->canvas_occluder_polygon_set_cull_mode(occ_polygon,VS::CanvasOccluderPolygonCullMode(p_mode)); +} + +OccluderPolygon2D::CullMode OccluderPolygon2D::get_cull_mode() const{ + + return cull; +} + + +RID OccluderPolygon2D::get_rid() const { + + return occ_polygon; +} + +void OccluderPolygon2D::_bind_methods() { + + + ObjectTypeDB::bind_method(_MD("set_closed","closed"),&OccluderPolygon2D::set_closed); + ObjectTypeDB::bind_method(_MD("is_closed"),&OccluderPolygon2D::is_closed); + + ObjectTypeDB::bind_method(_MD("set_cull_mode","cull_mode"),&OccluderPolygon2D::set_cull_mode); + ObjectTypeDB::bind_method(_MD("get_cull_mode"),&OccluderPolygon2D::get_cull_mode); + + ObjectTypeDB::bind_method(_MD("set_polygon","polygon"),&OccluderPolygon2D::set_polygon); + ObjectTypeDB::bind_method(_MD("get_polygon"),&OccluderPolygon2D::get_polygon); + + ADD_PROPERTY( PropertyInfo(Variant::VECTOR2_ARRAY,"polygon"),_SCS("set_polygon"),_SCS("get_polygon")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"closed"),_SCS("set_closed"),_SCS("is_closed")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"cull_mode",PROPERTY_HINT_ENUM,"Disabled,ClockWise,CounterClockWise"),_SCS("set_cull_mode"),_SCS("get_cull_mode")); + + BIND_CONSTANT(CULL_DISABLED); + BIND_CONSTANT(CULL_CLOCKWISE); + BIND_CONSTANT(CULL_COUNTER_CLOCKWISE); +} + + +OccluderPolygon2D::OccluderPolygon2D() { + + occ_polygon=VS::get_singleton()->canvas_occluder_polygon_create(); + closed=true; + cull=CULL_DISABLED; +} + +OccluderPolygon2D::~OccluderPolygon2D() { + + VS::get_singleton()->free(occ_polygon); +} + +#ifdef DEBUG_ENABLED +void LightOccluder2D::_poly_changed() { + + update(); +} +#endif + + +void LightOccluder2D::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_CANVAS) { + + VS::get_singleton()->canvas_light_occluder_attach_to_canvas(occluder,get_canvas()); + VS::get_singleton()->canvas_light_occluder_set_transform(occluder,get_global_transform()); + + } + if (p_what==NOTIFICATION_TRANSFORM_CHANGED) { + + VS::get_singleton()->canvas_light_occluder_set_transform(occluder,get_global_transform()); + } + + if (p_what==NOTIFICATION_DRAW) { + + if (get_tree()->is_editor_hint()) { + + if (occluder_polygon.is_valid()) { + + DVector poly = occluder_polygon->get_polygon(); + + if (poly.size()) { + if (occluder_polygon->is_closed()) { + Vector color; + color.push_back(Color(0,0,0,0.6)); + draw_polygon(Variant(poly),color); + } else { + + int ps=poly.size(); + DVector::Read r = poly.read(); + for(int i=0;icanvas_light_occluder_attach_to_canvas(occluder,RID()); + } + + +} + +void LightOccluder2D::set_occluder_polygon(const Ref& p_polygon) { + +#ifdef DEBUG_ENABLED + if (occluder_polygon.is_valid()) + occluder_polygon->disconnect("changed",this,"_poly_changed"); +#endif + occluder_polygon=p_polygon; + + if (occluder_polygon.is_valid()) + VS::get_singleton()->canvas_light_occluder_set_polygon(occluder,occluder_polygon->get_rid()); + else + VS::get_singleton()->canvas_light_occluder_set_polygon(occluder,RID()); + +#ifdef DEBUG_ENABLED + if (occluder_polygon.is_valid()) + occluder_polygon->connect("changed",this,"_poly_changed"); + update(); +#endif + +} + +Ref LightOccluder2D::get_occluder_polygon() const { + + return occluder_polygon; +} + +void LightOccluder2D::set_occluder_light_mask(int p_mask) { + + mask=p_mask; + VS::get_singleton()->canvas_light_occluder_set_light_mask(occluder,mask); +} + +int LightOccluder2D::get_occluder_light_mask() const{ + + return mask; +} + +void LightOccluder2D::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_occluder_polygon","polygon:OccluderPolygon2D"),&LightOccluder2D::set_occluder_polygon); + ObjectTypeDB::bind_method(_MD("get_occluder_polygon:OccluderPolygon2D"),&LightOccluder2D::get_occluder_polygon); + + ObjectTypeDB::bind_method(_MD("set_occluder_light_mask","mask"),&LightOccluder2D::set_occluder_light_mask); + ObjectTypeDB::bind_method(_MD("get_occluder_light_mask"),&LightOccluder2D::get_occluder_light_mask); + +#ifdef DEBUG_ENABLED + ObjectTypeDB::bind_method("_poly_changed",&LightOccluder2D::_poly_changed); +#endif + + ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"occluder",PROPERTY_HINT_RESOURCE_TYPE,"OccluderPolygon2D"),_SCS("set_occluder_polygon"),_SCS("get_occluder_polygon")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"light_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_occluder_light_mask"),_SCS("get_occluder_light_mask")); +} + +LightOccluder2D::LightOccluder2D() { + + occluder=VS::get_singleton()->canvas_light_occluder_create(); + mask=1; +} + +LightOccluder2D::~LightOccluder2D() { + + VS::get_singleton()->free(occluder); +} + diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h new file mode 100644 index 000000000..0343e3697 --- /dev/null +++ b/scene/2d/light_occluder_2d.h @@ -0,0 +1,73 @@ +#ifndef LIGHTOCCLUDER2D_H +#define LIGHTOCCLUDER2D_H + +#include "scene/2d/node_2d.h" + +class OccluderPolygon2D : public Resource { + + OBJ_TYPE(OccluderPolygon2D,Resource); +public: + + enum CullMode { + CULL_DISABLED, + CULL_CLOCKWISE, + CULL_COUNTER_CLOCKWISE + }; +private: + + + RID occ_polygon; + DVector polygon; + bool closed; + CullMode cull; + +protected: + + static void _bind_methods(); +public: + + void set_polygon(const DVector& p_polygon); + DVector get_polygon() const; + + void set_closed(bool p_closed); + bool is_closed() const; + + void set_cull_mode(CullMode p_mode); + CullMode get_cull_mode() const; + + virtual RID get_rid() const; + OccluderPolygon2D(); + ~OccluderPolygon2D(); + +}; + +VARIANT_ENUM_CAST(OccluderPolygon2D::CullMode); + +class LightOccluder2D : public Node2D { + OBJ_TYPE(LightOccluder2D,Node2D); + + RID occluder; + bool enabled; + int mask; + Ref occluder_polygon; + +#ifdef DEBUG_ENABLED + void _poly_changed(); +#endif + +protected: + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_occluder_polygon(const Ref& p_polygon); + Ref get_occluder_polygon() const; + + void set_occluder_light_mask(int p_mask); + int get_occluder_light_mask() const; + + LightOccluder2D(); + ~LightOccluder2D(); +}; + +#endif // LIGHTOCCLUDER2D_H diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index 95eafa0df..110913918 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -152,11 +152,11 @@ void Camera::_get_property_list( List *p_list) const { case PROJECTION_PERSPECTIVE: { - p_list->push_back( PropertyInfo( Variant::REAL, "fov" , PROPERTY_HINT_RANGE, "1,89,0.1",PROPERTY_USAGE_NOEDITOR) ); + p_list->push_back( PropertyInfo( Variant::REAL, "fov" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_NOEDITOR) ); if (keep_aspect==KEEP_WIDTH) - p_list->push_back( PropertyInfo( Variant::REAL, "fovx" , PROPERTY_HINT_RANGE, "1,89,0.1",PROPERTY_USAGE_EDITOR) ); + p_list->push_back( PropertyInfo( Variant::REAL, "fovx" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_EDITOR) ); else - p_list->push_back( PropertyInfo( Variant::REAL, "fovy" , PROPERTY_HINT_RANGE, "1,89,0.1",PROPERTY_USAGE_EDITOR) ); + p_list->push_back( PropertyInfo( Variant::REAL, "fovy" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_EDITOR) ); } break; diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp index a82c69e67..45c7fa912 100644 --- a/scene/3d/visual_instance.cpp +++ b/scene/3d/visual_instance.cpp @@ -310,6 +310,17 @@ int GeometryInstance::get_baked_light_texture_id() const{ return baked_light_texture_id; } +void GeometryInstance::set_extra_cull_margin(float p_margin) { + + ERR_FAIL_COND(p_margin<0); + extra_cull_margin=p_margin; + VS::get_singleton()->instance_set_extra_visibility_margin(get_instance(),extra_cull_margin); +} + +float GeometryInstance::get_extra_cull_margin() const{ + + return extra_cull_margin; +} void GeometryInstance::_bind_methods() { @@ -328,6 +339,9 @@ void GeometryInstance::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_baked_light_texture_id","id"), &GeometryInstance::set_baked_light_texture_id); ObjectTypeDB::bind_method(_MD("get_baked_light_texture_id"), &GeometryInstance::get_baked_light_texture_id); + ObjectTypeDB::bind_method(_MD("set_extra_cull_margin","margin"), &GeometryInstance::set_extra_cull_margin); + ObjectTypeDB::bind_method(_MD("get_extra_cull_margin"), &GeometryInstance::get_extra_cull_margin); + ObjectTypeDB::bind_method(_MD("_baked_light_changed"), &GeometryInstance::_baked_light_changed); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/visible"), _SCS("set_flag"), _SCS("get_flag"),FLAG_VISIBLE); @@ -336,6 +350,7 @@ void GeometryInstance::_bind_methods() { ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/receive_shadows"), _SCS("set_flag"), _SCS("get_flag"),FLAG_RECEIVE_SHADOWS); ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/range_begin",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_draw_range_begin"), _SCS("get_draw_range_begin")); ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/range_end",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_draw_range_end"), _SCS("get_draw_range_end")); + ADD_PROPERTY( PropertyInfo( Variant::REAL, "geometry/extra_cull_margin",PROPERTY_HINT_RANGE,"0,16384,0"), _SCS("set_extra_cull_margin"), _SCS("get_extra_cull_margin")); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/billboard"), _SCS("set_flag"), _SCS("get_flag"),FLAG_BILLBOARD); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/billboard_y"), _SCS("set_flag"), _SCS("get_flag"),FLAG_BILLBOARD_FIX_Y); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/depth_scale"), _SCS("set_flag"), _SCS("get_flag"),FLAG_DEPH_SCALE); diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h index e9fefe1ba..e08acbe9a 100644 --- a/scene/3d/visual_instance.h +++ b/scene/3d/visual_instance.h @@ -108,6 +108,7 @@ private: void _find_baked_light(); BakedLightInstance *baked_light_instance; int baked_light_texture_id; + float extra_cull_margin; void _baked_light_changed(); void _update_visibility(); @@ -132,6 +133,9 @@ public: void set_baked_light_texture_id(int p_id); int get_baked_light_texture_id() const; + void set_extra_cull_margin(float p_margin); + float get_extra_cull_margin() const; + GeometryInstance(); }; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index ff525203b..f90db4261 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -80,6 +80,7 @@ #include "scene/2d/particles_2d.h" #include "scene/2d/path_2d.h" #include "scene/2d/light_2d.h" +#include "scene/2d/light_occluder_2d.h" #include "scene/2d/canvas_item.h" #include "scene/2d/sprite.h" @@ -454,6 +455,7 @@ void register_scene_types() { //ObjectTypeDB::set_type_enabled("BodyVolumeCylinder",false); //ObjectTypeDB::set_type_enabled("BodyVolumeConvexPolygon",false); + ObjectTypeDB::register_type(); ObjectTypeDB::register_virtual_type(); ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); @@ -476,6 +478,8 @@ void register_scene_types() { ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); ObjectTypeDB::set_type_enabled("CollisionShape2D",false); diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index af5e6d416..c30ff0044 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -41,6 +41,7 @@ SceneStringNames::SceneStringNames() { visibility_changed=StaticCString::create("visibility_changed"); input_event=StaticCString::create("input_event"); shader_shader=StaticCString::create("shader/shader"); + shader_unshaded=StaticCString::create("shader/unshaded"); enter_tree=StaticCString::create("enter_tree"); exit_tree=StaticCString::create("exit_tree"); item_rect_changed=StaticCString::create("item_rect_changed"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 14e5e83b8..184cbe347 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -56,6 +56,7 @@ public: StringName _input_event; StringName item_rect_changed; StringName shader_shader; + StringName shader_unshaded; StringName enter_tree; StringName exit_tree; StringName size_flags_changed; diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 4c9d0491b..62ab8b3c5 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -572,8 +572,8 @@ public: struct CanvasLight { + bool enabled; - bool shadow; Color color; Matrix32 xform; float height; @@ -586,21 +586,26 @@ public: RID texture; Vector2 texture_offset; RID canvas; + RID shadow_buffer; + int shadow_buffer_size; + float shadow_esm_mult; void *texture_cache; // implementation dependent Rect2 rect_cache; Matrix32 xform_cache; + float radius_cache; //used for shadow far plane + CameraMatrix shadow_matrix_cache; Matrix32 light_shader_xform; Vector2 light_shader_pos; + CanvasLight *shadows_next_ptr; CanvasLight *filter_next_ptr; CanvasLight *next_ptr; CanvasLight() { - enabled=true; - shadow=false; + enabled=true; color=Color(1,1,1); height=0; z_min=-1024; @@ -612,9 +617,24 @@ public: texture_cache=NULL; next_ptr=NULL; filter_next_ptr=NULL; + shadow_buffer_size=2048; + shadow_esm_mult=80; + } }; + struct CanvasItem; + + struct CanvasItemMaterial { + + RID shader; + Map shader_param; + uint32_t shader_version; + Set owners; + bool unshaded; + + CanvasItemMaterial() {unshaded=false; shader_version=0; } + }; struct CanvasItem { @@ -744,16 +764,14 @@ public: mutable bool rect_dirty; mutable Rect2 rect; CanvasItem*next; - RID shader; - Map shader_param; - uint32_t shader_version; + CanvasItemMaterial* material; float final_opacity; Matrix32 final_transform; Rect2 final_clip_rect; CanvasItem* final_clip_owner; - CanvasItem* shader_owner; + CanvasItem* material_owner; ViewportRender *vp_render; Rect2 global_rect_cache; @@ -881,8 +899,8 @@ public: return rect; } - void clear() { for (int i=0;i& p_lines)=0; + + + virtual RID canvas_light_shadow_buffer_create(int p_width)=0; + struct CanvasLightOccluderInstance { + + + bool enabled; + RID canvas; + RID polygon; + RID polygon_buffer; + Rect2 aabb_cache; + Matrix32 xform; + Matrix32 xform_cache; + int light_mask; + VS::CanvasOccluderPolygonCullMode cull_cache; + + CanvasLightOccluderInstance *next; + + CanvasLightOccluderInstance() { enabled=true; next=NULL; light_mask=1; cull_cache=VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; } + }; + + + + virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, CanvasLightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache)=0; /* ENVIRONMENT */ @@ -945,6 +992,8 @@ public: virtual bool is_environment(const RID& p_rid) const=0; virtual bool is_shader(const RID& p_rid) const=0; + virtual bool is_canvas_light_occluder(const RID& p_rid) const=0; + virtual void free(const RID& p_rid)=0; virtual void init()=0; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index feb14d8a9..3bcf0b8a3 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -3765,55 +3765,32 @@ void VisualServerRaster::canvas_item_set_z_as_relative_to_parent(RID p_item, boo } -void VisualServerRaster::canvas_item_set_use_parent_shader(RID p_item, bool p_enable) { +void VisualServerRaster::canvas_item_set_use_parent_material(RID p_item, bool p_enable) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); - canvas_item->use_parent_shader=p_enable; + canvas_item->use_parent_material=p_enable; } -void VisualServerRaster::canvas_item_set_shader(RID p_item, RID p_shader) { +void VisualServerRaster::canvas_item_set_material(RID p_item, RID p_material) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); - canvas_item->shader=p_shader; -} - -RID VisualServerRaster::canvas_item_get_shader(RID p_item) const{ - - CanvasItem *canvas_item = canvas_item_owner.get( p_item ); - ERR_FAIL_COND_V(!canvas_item,RID()); - return canvas_item->shader; -} + if (canvas_item->material) + canvas_item->material->owners.erase(canvas_item); -void VisualServerRaster::canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value){ + canvas_item->material=NULL; - VS_CHANGED; - CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item ); - ERR_FAIL_COND(!canvas_item); - if (p_value.get_type()==Variant::NIL) - canvas_item->shader_param.erase(p_param); - else - canvas_item->shader_param[p_param]=p_value; - -} -Variant VisualServerRaster::canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const{ - - CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item ); - ERR_FAIL_COND_V(!canvas_item,Variant()); - if (!canvas_item->shader_param.has(p_param)) { - ERR_FAIL_COND_V(!canvas_item->shader.is_valid(),Variant()); - return rasterizer->shader_get_default_param(canvas_item->shader,p_param); + if (canvas_item_material_owner.owns(p_material)) { + canvas_item->material=canvas_item_material_owner.get(p_material); + canvas_item->material->owners.insert(canvas_item); } - - return canvas_item->shader_param[p_param]; } - void VisualServerRaster::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) { VS_CHANGED; @@ -3989,19 +3966,41 @@ void VisualServerRaster::canvas_light_set_shadow_enabled(RID p_light, bool p_ena Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); - clight->shadow=p_enabled; + + if (clight->shadow_buffer.is_valid()==p_enabled) + return; + if (p_enabled) { + clight->shadow_buffer=rasterizer->canvas_light_shadow_buffer_create(clight->shadow_buffer_size); + } else { + rasterizer->free(clight->shadow_buffer); + clight->shadow_buffer=RID(); + + } } + void VisualServerRaster::canvas_light_set_shadow_buffer_size(RID p_light, int p_size){ Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); + ERR_FAIL_COND(p_size<32 || p_size>16384); + + clight->shadow_buffer_size=nearest_power_of_2(p_size); + + + if (clight->shadow_buffer.is_valid()) { + rasterizer->free(clight->shadow_buffer); + clight->shadow_buffer=rasterizer->canvas_light_shadow_buffer_create(clight->shadow_buffer_size); + } + } -void VisualServerRaster::canvas_light_set_shadow_filter(RID p_light, int p_size){ + +void VisualServerRaster::canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier) { Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); + clight->shadow_esm_mult=p_multiplier; } @@ -4009,26 +4008,217 @@ void VisualServerRaster::canvas_light_set_shadow_filter(RID p_light, int p_size) RID VisualServerRaster::canvas_light_occluder_create() { - return RID(); + Rasterizer::CanvasLightOccluderInstance *occluder = memnew( Rasterizer::CanvasLightOccluderInstance ); + + return canvas_light_occluder_owner.make_rid( occluder ); + } void VisualServerRaster::canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas) { + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + if (occluder->canvas.is_valid()) { + + Canvas *canvas = canvas_owner.get(occluder->canvas); + canvas->occluders.erase(occluder); + } + + if (!canvas_owner.owns(p_canvas)) + p_canvas=RID(); + + occluder->canvas=p_canvas; + if (occluder->canvas.is_valid()) { + + Canvas *canvas = canvas_owner.get(occluder->canvas); + canvas->occluders.insert(occluder); + } } void VisualServerRaster::canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled){ + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + occluder->enabled=p_enabled; } -void VisualServerRaster::canvas_light_occluder_set_shape(RID p_occluder,const DVector& p_shape){ +void VisualServerRaster::canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + if (occluder->polygon.is_valid()) { + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_polygon); + if (occluder_poly) { + occluder_poly->owners.erase(occluder); + } + } + occluder->polygon=p_polygon; + occluder->polygon_buffer=RID(); + + if (occluder->polygon.is_valid()) { + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_polygon); + if (!occluder_poly) + occluder->polygon=RID(); + ERR_FAIL_COND(!occluder_poly); + occluder_poly->owners.insert(occluder); + occluder->polygon_buffer=occluder_poly->occluder; + occluder->aabb_cache=occluder_poly->aabb; + occluder->cull_cache=occluder_poly->cull_mode; + } } + +void VisualServerRaster::canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + occluder->xform=p_xform; + +} + +void VisualServerRaster::canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + occluder->light_mask=p_mask; + +} + + +RID VisualServerRaster::canvas_occluder_polygon_create() { + + CanvasLightOccluderPolygon * occluder_poly = memnew( CanvasLightOccluderPolygon ); + occluder_poly->occluder=rasterizer->canvas_light_occluder_create(); + return canvas_light_occluder_polygon_owner.make_rid(occluder_poly); + +} + +void VisualServerRaster::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const DVector& p_shape, bool p_close){ + + if (p_shape.size()<3) { + canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon,p_shape); + return; + } + + DVector lines; + int lc = p_shape.size()*2; + + lines.resize(lc-(p_close?0:2)); + { + DVector::Write w = lines.write(); + DVector::Read r = p_shape.read(); + + int max=lc/2; + if (!p_close) { + max--; + } + for(int i=0;i& p_shape) { + + CanvasLightOccluderPolygon * occluder_poly = canvas_light_occluder_polygon_owner.get(p_occluder_polygon); + ERR_FAIL_COND(!occluder_poly); + ERR_FAIL_COND(p_shape.size()&1); + + int lc = p_shape.size(); + occluder_poly->aabb=Rect2(); + { + DVector::Read r = p_shape.read(); + for(int i=0;iaabb.pos=r[i]; + else + occluder_poly->aabb.expand_to(r[i]); + } + } + + rasterizer->canvas_light_occluder_set_polylines(occluder_poly->occluder,p_shape); + for( Set::Element *E=occluder_poly->owners.front();E;E=E->next()) { + E->get()->aabb_cache=occluder_poly->aabb; + } +} + +void VisualServerRaster::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode) { + + CanvasLightOccluderPolygon * occluder_poly = canvas_light_occluder_polygon_owner.get(p_occluder_polygon); + ERR_FAIL_COND(!occluder_poly); + occluder_poly->cull_mode=p_mode; + for( Set::Element *E=occluder_poly->owners.front();E;E=E->next()) { + E->get()->cull_cache=p_mode; + } + +} + +RID VisualServerRaster::canvas_item_material_create() { + + Rasterizer::CanvasItemMaterial *material = memnew( Rasterizer::CanvasItemMaterial ); + return canvas_item_material_owner.make_rid(material); + +} + +void VisualServerRaster::canvas_item_material_set_shader(RID p_material, RID p_shader){ + + VS_CHANGED; + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND(!material); + material->shader=p_shader; + +} +void VisualServerRaster::canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value){ + + VS_CHANGED; + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND(!material); + if (p_value.get_type()==Variant::NIL) + material->shader_param.erase(p_param); + else + material->shader_param[p_param]=p_value; + + +} +Variant VisualServerRaster::canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const{ + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND_V(!material,Variant()); + if (!material->shader_param.has(p_param)) { + ERR_FAIL_COND_V(!material->shader.is_valid(),Variant()); + return rasterizer->shader_get_default_param(material->shader,p_param); + } + + return material->shader_param[p_param]; +} + +void VisualServerRaster::canvas_item_material_set_unshaded(RID p_material, bool p_unshaded){ + + VS_CHANGED; + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND(!material); + material->unshaded=p_unshaded; + +} + + /******** CANVAS *********/ @@ -4285,6 +4475,10 @@ void VisualServerRaster::free( RID p_rid ) { E->get()->canvas=RID(); } + for (Set::Element *E=canvas->occluders.front();E;E=E->next()) { + + E->get()->canvas=RID(); + } canvas_owner.free( p_rid ); @@ -4314,10 +4508,26 @@ void VisualServerRaster::free( RID p_rid ) { canvas_item->child_items[i]->parent=RID(); } + if (canvas_item->material) { + canvas_item->material->owners.erase(canvas_item); + } + canvas_item_owner.free( p_rid ); memdelete( canvas_item ); + } else if (canvas_item_material_owner.owns(p_rid)) { + + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get(p_rid); + ERR_FAIL_COND(!material); + for(Set::Element *E=material->owners.front();E;E=E->next()) { + + E->get()->material=NULL; + } + + canvas_item_material_owner.free(p_rid); + memdelete(material); + } else if (canvas_light_owner.owns(p_rid)) { Rasterizer::CanvasLight *canvas_light = canvas_light_owner.get(p_rid); @@ -4329,9 +4539,44 @@ void VisualServerRaster::free( RID p_rid ) { canvas->lights.erase(canvas_light); } + if (canvas_light->shadow_buffer.is_valid()) + rasterizer->free(canvas_light->shadow_buffer); + canvas_light_owner.free( p_rid ); memdelete( canvas_light ); + } else if (canvas_light_occluder_owner.owns(p_rid)) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_rid); + ERR_FAIL_COND(!occluder); + + if (occluder->polygon.is_valid()) { + + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(occluder->polygon); + if (occluder_poly) { + occluder_poly->owners.erase(occluder); + } + + } + + canvas_light_occluder_owner.free( p_rid ); + memdelete(occluder); + + } else if (canvas_light_occluder_polygon_owner.owns(p_rid)) { + + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_rid); + ERR_FAIL_COND(!occluder_poly); + rasterizer->free(occluder_poly->occluder); + + while(occluder_poly->owners.size()) { + + occluder_poly->owners.front()->get()->polygon=RID(); + occluder_poly->owners.erase( occluder_poly->owners.front() ); + } + + canvas_light_occluder_polygon_owner.free( p_rid ); + memdelete(occluder_poly); + } else if (scenario_owner.owns(p_rid)) { Scenario *scenario=scenario_owner.get(p_rid); @@ -6410,7 +6655,7 @@ void VisualServerRaster::_render_canvas_item_viewport(VisualServer* p_self,void } -void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner) { +void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_material_owner) { CanvasItem *ci = p_canvas_item; @@ -6455,11 +6700,11 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat ci->vp_render=NULL; } - if (ci->use_parent_shader && p_shader_owner) - ci->shader_owner=p_shader_owner; + if (ci->use_parent_material && p_material_owner) + ci->material_owner=p_material_owner; else { - p_shader_owner=ci; - ci->shader_owner=NULL; + p_material_owner=ci; + ci->material_owner=NULL; } @@ -6493,7 +6738,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat if (child_items[i]->ontop) continue; - _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner); + _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_material_owner); } @@ -6524,7 +6769,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat if (!child_items[i]->ontop) continue; - _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner); + _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_material_owner); } } @@ -6658,6 +6903,8 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ Rect2 clip_rect(0,0,viewport_rect.width,viewport_rect.height); Rasterizer::CanvasLight *lights=NULL; + Rasterizer::CanvasLight *lights_with_shadow=NULL; + Rect2 shadow_rect; for (Map::Element *E=p_viewport->canvas_map.front();E;E=E->next()) { @@ -6676,6 +6923,7 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ cl->rect_cache=Rect2(-offset+cl->texture_offset,tsize); cl->xform_cache=xf * cl->xform; + if (clip_rect.intersects_transformed(cl->xform_cache,cl->rect_cache)) { cl->filter_next_ptr=lights; lights=cl; @@ -6685,16 +6933,55 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ scale.elements[2]=cl->rect_cache.pos; cl->light_shader_xform = (cl->xform_cache * scale).affine_inverse(); cl->light_shader_pos=cl->xform_cache[2]; + if (cl->shadow_buffer.is_valid()) { + cl->shadows_next_ptr=lights_with_shadow; + if (lights_with_shadow==NULL) { + shadow_rect = cl->xform_cache.xform(cl->rect_cache); + } else { + shadow_rect=shadow_rect.merge( cl->xform_cache.xform(cl->rect_cache) ); + } + lights_with_shadow=cl; + cl->radius_cache=cl->rect_cache.size.length(); + + } } + } + } + + canvas_map[ Viewport::CanvasKey( E->key(), E->get().layer) ]=&E->get(); + } + + if (lights_with_shadow) { + //update shadows if any + + Rasterizer::CanvasLightOccluderInstance * occluders=NULL; + + //make list of occluders + for (Map::Element *E=p_viewport->canvas_map.front();E;E=E->next()) { + + Matrix32 xf = p_viewport->global_transform * E->get().transform; + for(Set::Element *F=E->get().canvas->occluders.front();F;F=F->next()) { + F->get()->xform_cache = xf * F->get()->xform; + if (shadow_rect.intersects_transformed(F->get()->xform_cache,F->get()->aabb_cache)) { + F->get()->next=occluders; + occluders=F->get(); + + } } } + //update the light shadowmaps with them + Rasterizer::CanvasLight *light=lights_with_shadow; + while(light) { - canvas_map[ Viewport::CanvasKey( E->key(), E->get().layer) ]=&E->get(); + rasterizer->canvas_light_shadow_buffer_update(light->shadow_buffer,light->xform_cache.affine_inverse(),light->item_mask,light->radius_cache/1000.0,light->radius_cache*1.1,occluders,&light->shadow_matrix_cache); + light=light->shadows_next_ptr; + } + rasterizer->set_viewport(viewport_rect); //must reset viewport afterwards } for (Map::Element *E=canvas_map.front();E;E=E->next()) { @@ -6719,6 +7006,8 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ i++; } + + rasterizer->canvas_debug_viewport_shadows(lights_with_shadow); } //capture diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 9b2b0c9c1..b9a3f8336 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -371,7 +371,7 @@ class VisualServerRaster : public VisualServer { - + mutable RID_Owner canvas_item_material_owner; struct CanvasItem : public Rasterizer::CanvasItem { @@ -384,7 +384,7 @@ class VisualServerRaster : public VisualServer { bool sort_y; float opacity; float self_opacity; - bool use_parent_shader; + bool use_parent_material; Vector child_items; @@ -396,7 +396,7 @@ class VisualServerRaster : public VisualServer { opacity=1; self_opacity=1; sort_y=false; - use_parent_shader=false; + use_parent_material=false; z_relative=true; } }; @@ -410,6 +410,24 @@ class VisualServerRaster : public VisualServer { } }; + struct CanvasLightOccluder; + + struct CanvasLightOccluderPolygon { + + bool active; + Rect2 aabb; + CanvasOccluderPolygonCullMode cull_mode; + RID occluder; + Set owners; + + CanvasLightOccluderPolygon() { active=false; cull_mode=CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; } + }; + + + RID_Owner canvas_light_occluder_polygon_owner; + + RID_Owner canvas_light_occluder_owner; + struct CanvasLight; struct Canvas { @@ -422,6 +440,7 @@ class VisualServerRaster : public VisualServer { }; Set lights; + Set occluders; Vector child_items; Color modulate; @@ -610,7 +629,7 @@ class VisualServerRaster : public VisualServer { void _render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario); static void _render_canvas_item_viewport(VisualServer* p_self,void *p_vp,const Rect2& p_rect); void _render_canvas_item_tree(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, const Color &p_modulate, Rasterizer::CanvasLight *p_lights); - void _render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner); + void _render_canvas_item(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, float p_opacity, int p_z, Rasterizer::CanvasItem **z_list, Rasterizer::CanvasItem **z_last_list, CanvasItem *p_canvas_clip, CanvasItem *p_material_owner); void _render_canvas(Canvas *p_canvas, const Matrix32 &p_transform, Rasterizer::CanvasLight *p_lights); Vector _camera_generate_endpoints(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max); Vector _camera_generate_orthogonal_planes(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max); @@ -1131,15 +1150,8 @@ public: virtual void canvas_item_set_z(RID p_item, int p_z); virtual void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable); - virtual void canvas_item_set_shader(RID p_item, RID p_shader); - virtual RID canvas_item_get_shader(RID p_item) const; - - virtual void canvas_item_set_use_parent_shader(RID p_item, bool p_enable); - - - - virtual void canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value); - virtual Variant canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const; + virtual void canvas_item_set_material(RID p_item, RID p_material); + virtual void canvas_item_set_use_parent_material(RID p_item, bool p_enable); virtual RID canvas_light_create(); virtual void canvas_light_attach_to_canvas(RID p_light,RID p_canvas); @@ -1156,17 +1168,36 @@ public: virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable); virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled); virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size); - virtual void canvas_light_set_shadow_filter(RID p_light, int p_size); + virtual void canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier); virtual RID canvas_light_occluder_create(); virtual void canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas); virtual void canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled); - virtual void canvas_light_occluder_set_shape(RID p_occluder,const DVector& p_shape); + virtual void canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon); + virtual void canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform); + virtual void canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask); + + + virtual RID canvas_occluder_polygon_create(); + virtual void canvas_occluder_polygon_set_shape(RID p_occluder_polygon,const DVector& p_shape,bool p_close); + virtual void canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector& p_shape); + virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode); + + virtual void canvas_item_clear(RID p_item); virtual void canvas_item_raise(RID p_item); + /* CANVAS ITEM MATERIAL */ + + virtual RID canvas_item_material_create(); + virtual void canvas_item_material_set_shader(RID p_material, RID p_shader); + virtual void canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value); + virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const; + virtual void canvas_item_material_set_unshaded(RID p_material, bool p_unshaded); + + /* CURSOR */ virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0); // radians virtual void cursor_set_texture(RID p_texture, const Point2 &p_center_offset, int p_cursor=0); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 6c95b6ed5..1890f7b76 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -1139,14 +1139,9 @@ public: FUNC2(canvas_item_set_z,RID,int); FUNC2(canvas_item_set_z_as_relative_to_parent,RID,bool); - FUNC2(canvas_item_set_shader,RID, RID ); - FUNC1RC(RID,canvas_item_get_shader,RID ); + FUNC2(canvas_item_set_material,RID, RID ); - FUNC2(canvas_item_set_use_parent_shader,RID, bool ); - - - FUNC3(canvas_item_set_shader_param,RID,const StringName&,const Variant&); - FUNC2RC(Variant,canvas_item_get_shader_param,RID,const StringName&); + FUNC2(canvas_item_set_use_parent_material,RID, bool ); FUNC1(canvas_item_clear,RID); FUNC1(canvas_item_raise,RID); @@ -1167,14 +1162,31 @@ public: FUNC2(canvas_light_set_subtract_mode,RID,bool); FUNC2(canvas_light_set_shadow_enabled,RID,bool); FUNC2(canvas_light_set_shadow_buffer_size,RID,int); - FUNC2(canvas_light_set_shadow_filter,RID,int); + FUNC2(canvas_light_set_shadow_esm_multiplier,RID,float); + /* CANVAS OCCLUDER */ FUNC0R(RID,canvas_light_occluder_create); FUNC2(canvas_light_occluder_attach_to_canvas,RID,RID); FUNC2(canvas_light_occluder_set_enabled,RID,bool); - FUNC2(canvas_light_occluder_set_shape,RID,const DVector&); + FUNC2(canvas_light_occluder_set_polygon,RID,RID); + FUNC2(canvas_light_occluder_set_transform,RID,const Matrix32&); + FUNC2(canvas_light_occluder_set_light_mask,RID,int); + + + FUNC0R(RID,canvas_occluder_polygon_create); + FUNC3(canvas_occluder_polygon_set_shape,RID,const DVector&,bool); + FUNC2(canvas_occluder_polygon_set_shape_as_lines,RID,const DVector&); + FUNC2(canvas_occluder_polygon_set_cull_mode,RID,CanvasOccluderPolygonCullMode); + + /* CANVAS MATERIAL */ + + FUNC0R(RID,canvas_item_material_create); + FUNC2(canvas_item_material_set_shader,RID,RID); + FUNC3(canvas_item_material_set_shader_param,RID,const StringName&,const Variant&); + FUNC2RC(Variant,canvas_item_material_get_shader_param,RID,const StringName&); + FUNC2(canvas_item_material_set_unshaded,RID,bool); /* CURSOR */ FUNC2(cursor_set_rotation,float , int ); // radians diff --git a/servers/visual_server.h b/servers/visual_server.h index 37368e32f..ccf6978ae 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -998,13 +998,9 @@ public: virtual void canvas_item_clear(RID p_item)=0; virtual void canvas_item_raise(RID p_item)=0; - virtual void canvas_item_set_shader(RID p_item, RID p_shader)=0; - virtual RID canvas_item_get_shader(RID p_item) const=0; + virtual void canvas_item_set_material(RID p_item, RID p_material)=0; - virtual void canvas_item_set_use_parent_shader(RID p_item, bool p_enable)=0; - - virtual void canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value)=0; - virtual Variant canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const=0; + virtual void canvas_item_set_use_parent_material(RID p_item, bool p_enable)=0; virtual RID canvas_light_create()=0; virtual void canvas_light_attach_to_canvas(RID p_light,RID p_canvas)=0; @@ -1021,13 +1017,34 @@ public: virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable)=0; virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled)=0; virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size)=0; - virtual void canvas_light_set_shadow_filter(RID p_light, int p_size)=0; + virtual void canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier)=0; + virtual RID canvas_light_occluder_create()=0; virtual void canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas)=0; virtual void canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled)=0; - virtual void canvas_light_occluder_set_shape(RID p_occluder,const DVector& p_shape)=0; + virtual void canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon)=0; + virtual void canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform)=0; + virtual void canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask)=0; + + virtual RID canvas_occluder_polygon_create()=0; + virtual void canvas_occluder_polygon_set_shape(RID p_occluder_polygon,const DVector& p_shape,bool p_closed)=0; + virtual void canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector& p_shape)=0; + enum CanvasOccluderPolygonCullMode { + CANVAS_OCCLUDER_POLYGON_CULL_DISABLED, + CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE, + CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE, + }; + virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode)=0; + + /* CANVAS ITEM MATERIAL */ + + virtual RID canvas_item_material_create()=0; + virtual void canvas_item_material_set_shader(RID p_material, RID p_shader)=0; + virtual void canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value)=0; + virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const=0; + virtual void canvas_item_material_set_unshaded(RID p_material, bool p_unshaded)=0; /* CURSOR */ virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0)=0; // radians diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index cc1a05f7d..3d42867d9 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -90,6 +90,7 @@ #include "plugins/baked_light_editor_plugin.h" #include "plugins/polygon_2d_editor_plugin.h" #include "plugins/navigation_polygon_editor_plugin.h" +#include "plugins/light_occluder_2d_editor_plugin.h" // end #include "tools/editor/io_plugins/editor_texture_import_plugin.h" #include "tools/editor/io_plugins/editor_scene_import_plugin.h" @@ -4115,6 +4116,7 @@ EditorNode::EditorNode() { add_editor_plugin( memnew( PathEditorPlugin(this) ) ); add_editor_plugin( memnew( BakedLightEditorPlugin(this) ) ); add_editor_plugin( memnew( Polygon2DEditorPlugin(this) ) ); + add_editor_plugin( memnew( LightOccluder2DEditorPlugin(this) ) ); add_editor_plugin( memnew( NavigationPolygonEditorPlugin(this) ) ); for(int i=0;iset_icon( get_icon("Edit","EditorIcons")); + button_edit->set_icon( get_icon("MovePoint","EditorIcons")); + button_edit->set_pressed(true); + get_tree()->connect("node_removed",this,"_node_removed"); + create_poly->connect("confirmed",this,"_create_poly"); + + } break; + case NOTIFICATION_FIXED_PROCESS: { + + + } break; + } + +} +void LightOccluder2DEditor::_node_removed(Node *p_node) { + + if(p_node==node) { + node=NULL; + hide(); + canvas_item_editor->get_viewport_control()->update(); + } + +} + + +Vector2 LightOccluder2DEditor::snap_point(const Vector2& p_point) const { + + if (canvas_item_editor->is_snap_active()) { + + return p_point.snapped(Vector2(1,1)*canvas_item_editor->get_snap()); + + } else { + return p_point; + } +} + +void LightOccluder2DEditor::_menu_option(int p_option) { + + switch(p_option) { + + case MODE_CREATE: { + + mode=MODE_CREATE; + button_create->set_pressed(true); + button_edit->set_pressed(false); + } break; + case MODE_EDIT: { + + mode=MODE_EDIT; + button_create->set_pressed(false); + button_edit->set_pressed(true); + } break; + + } +} + +void LightOccluder2DEditor::_wip_close(bool p_closed) { + + undo_redo->create_action("Create Poly"); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",node->get_occluder_polygon()->get_polygon()); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",wip); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_closed",node->get_occluder_polygon()->is_closed()); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_closed",p_closed); + + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + wip.clear(); + wip_active=false; + mode=MODE_EDIT; + button_edit->set_pressed(true); + button_create->set_pressed(false); + edited_point=-1; +} + +bool LightOccluder2DEditor::forward_input_event(const InputEvent& p_event) { + + + if (!node) + return false; + + if (node->get_occluder_polygon().is_null()) { + if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { + create_poly->set_text("No OccluderPolygon2D resource on this node.\nCreate and assign one?"); + create_poly->popup_centered_minsize(); + } + return false; + } + switch(p_event.type) { + + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &mb=p_event.mouse_button; + + Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + + + Vector2 gpoint = Point2(mb.x,mb.y); + Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); + cpoint=snap_point(cpoint); + cpoint = node->get_global_transform().affine_inverse().xform(cpoint); + + Vector poly = Variant(node->get_occluder_polygon()->get_polygon()); + + //first check if a point is to be added (segment split) + real_t grab_treshold=EDITOR_DEF("poly_editor/point_grab_radius",8); + + switch(mode) { + + + case MODE_CREATE: { + + if (mb.button_index==BUTTON_LEFT && mb.pressed) { + + + if (!wip_active) { + + wip.clear(); + wip.push_back( cpoint ); + wip_active=true; + edited_point_pos=cpoint; + canvas_item_editor->get_viewport_control()->update(); + edited_point=1; + return true; + } else { + + + if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)1 && xform.xform(wip[wip.size()-1]).distance_to(gpoint)get_viewport_control()->update(); + return true; + + //add wip point + } + } + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { + _wip_close(true); + } + + + + } break; + + case MODE_EDIT: { + + if (mb.button_index==BUTTON_LEFT) { + if (mb.pressed) { + + if (mb.mod.control) { + + + if (poly.size() < 3) { + + undo_redo->create_action("Edit Poly"); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + poly.push_back(cpoint); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + return true; + } + + //search edges + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i=0) { + + pre_move_edit=poly; + poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos)); + edited_point=closest_idx+1; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + node->get_occluder_polygon()->set_polygon(Variant(poly)); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } else { + + //look for points to move + + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i=0) { + + pre_move_edit=poly; + edited_point=closest_idx; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } + } else { + + if (edited_point!=-1) { + + //apply + + ERR_FAIL_INDEX_V(edited_point,poly.size(),false); + poly[edited_point]=edited_point_pos; + undo_redo->create_action("Edit Poly"); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",pre_move_edit); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + + edited_point=-1; + return true; + } + } + } if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { + + + + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i=0) { + + + undo_redo->create_action("Edit Poly (Remove Point)"); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + poly.remove(closest_idx); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + return true; + } + + } + + + + } break; + } + + + + } break; + case InputEvent::MOUSE_MOTION: { + + const InputEventMouseMotion &mm=p_event.mouse_motion; + + if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { + + Vector2 gpoint = Point2(mm.x,mm.y); + Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); + cpoint=snap_point(cpoint); + edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint); + + canvas_item_editor->get_viewport_control()->update(); + + } + + } break; + } + + return false; +} +void LightOccluder2DEditor::_canvas_draw() { + + if (!node || !node->get_occluder_polygon().is_valid()) + return; + + Control *vpc = canvas_item_editor->get_viewport_control(); + + Vector poly; + + if (wip_active) + poly=wip; + else + poly=Variant(node->get_occluder_polygon()->get_polygon()); + + + Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + Ref handle= get_icon("EditorHandle","EditorIcons"); + + int len = poly.size(); + + for(int i=0;iget_occluder_polygon()->is_closed() || wip_active)) { + + } else { + vpc->draw_line(point,next_point,col,2); + } + vpc->draw_texture(handle,point-handle->get_size()*0.5); + } +} + + + +void LightOccluder2DEditor::edit(Node *p_collision_polygon) { + + if (!canvas_item_editor) { + canvas_item_editor=CanvasItemEditor::get_singleton(); + } + + if (p_collision_polygon) { + + node=p_collision_polygon->cast_to(); + if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw"); + wip.clear(); + wip_active=false; + edited_point=-1; + + } else { + node=NULL; + + if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw"); + + } + +} + +void LightOccluder2DEditor::_create_poly() { + + undo_redo->create_action("Create Occluder Polygon"); + undo_redo->add_do_method(node,"set_occluder_polygon",Ref(memnew( OccluderPolygon2D))); + undo_redo->add_undo_method(node,"set_occluder_polygon",Variant(REF())); + undo_redo->commit_action(); +} + +void LightOccluder2DEditor::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("_menu_option"),&LightOccluder2DEditor::_menu_option); + ObjectTypeDB::bind_method(_MD("_canvas_draw"),&LightOccluder2DEditor::_canvas_draw); + ObjectTypeDB::bind_method(_MD("_node_removed"),&LightOccluder2DEditor::_node_removed); + ObjectTypeDB::bind_method(_MD("_create_poly"),&LightOccluder2DEditor::_create_poly); + +} + + +LightOccluder2DEditor::LightOccluder2DEditor(EditorNode *p_editor) { + + canvas_item_editor=NULL; + editor=p_editor; + undo_redo = editor->get_undo_redo(); + + add_child( memnew( VSeparator )); + button_create = memnew( ToolButton ); + add_child(button_create); + button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE)); + button_create->set_toggle_mode(true); + button_create->set_tooltip("Create a new polygon from scratch"); + + button_edit = memnew( ToolButton ); + add_child(button_edit); + button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT)); + button_edit->set_toggle_mode(true); + button_edit->set_tooltip("Edit existing polygon:\nLMB: Move Point.\nCtrl+LMB: Split Segment.\nRMB: Erase Point."); + + create_poly = memnew( ConfirmationDialog ); + add_child(create_poly); + create_poly->get_ok()->set_text("Create"); + + + //add_constant_override("separation",0); + +#if 0 + options = memnew( MenuButton ); + add_child(options); + options->set_area_as_parent_rect(); + options->set_text("Polygon"); + //options->get_popup()->add_item("Parse BBCODE",PARSE_BBCODE); + options->get_popup()->connect("item_pressed", this,"_menu_option"); +#endif + + mode = MODE_EDIT; + wip_active=false; + +} + + +void LightOccluder2DEditorPlugin::edit(Object *p_object) { + + collision_polygon_editor->edit(p_object->cast_to()); +} + +bool LightOccluder2DEditorPlugin::handles(Object *p_object) const { + + return p_object->is_type("LightOccluder2D"); +} + +void LightOccluder2DEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + collision_polygon_editor->show(); + } else { + + collision_polygon_editor->hide(); + collision_polygon_editor->edit(NULL); + } + +} + +LightOccluder2DEditorPlugin::LightOccluder2DEditorPlugin(EditorNode *p_node) { + + editor=p_node; + collision_polygon_editor = memnew( LightOccluder2DEditor(p_node) ); + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); + + collision_polygon_editor->hide(); + + + +} + + +LightOccluder2DEditorPlugin::~LightOccluder2DEditorPlugin() +{ +} + diff --git a/tools/editor/plugins/light_occluder_2d_editor_plugin.h b/tools/editor/plugins/light_occluder_2d_editor_plugin.h new file mode 100644 index 000000000..5fb5631d0 --- /dev/null +++ b/tools/editor/plugins/light_occluder_2d_editor_plugin.h @@ -0,0 +1,87 @@ +#ifndef LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H +#define LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H + + + +#include "tools/editor/editor_plugin.h" +#include "tools/editor/editor_node.h" +#include "scene/2d/light_occluder_2d.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/button_group.h" + +/** + @author Juan Linietsky +*/ +class CanvasItemEditor; + +class LightOccluder2DEditor : public HBoxContainer { + + OBJ_TYPE(LightOccluder2DEditor, HBoxContainer ); + + UndoRedo *undo_redo; + enum Mode { + + MODE_CREATE, + MODE_EDIT, + + }; + + Mode mode; + + ToolButton *button_create; + ToolButton *button_edit; + + CanvasItemEditor *canvas_item_editor; + EditorNode *editor; + Panel *panel; + LightOccluder2D *node; + MenuButton *options; + + int edited_point; + Vector2 edited_point_pos; + Vector pre_move_edit; + Vector wip; + bool wip_active; + + ConfirmationDialog *create_poly; + + void _wip_close(bool p_closed); + void _canvas_draw(); + void _menu_option(int p_option); + void _create_poly(); + +protected: + void _notification(int p_what); + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + Vector2 snap_point(const Vector2& p_point) const; + bool forward_input_event(const InputEvent& p_event); + void edit(Node *p_collision_polygon); + LightOccluder2DEditor(EditorNode *p_editor); +}; + +class LightOccluder2DEditorPlugin : public EditorPlugin { + + OBJ_TYPE( LightOccluder2DEditorPlugin, EditorPlugin ); + + LightOccluder2DEditor *collision_polygon_editor; + EditorNode *editor; + +public: + + virtual bool forward_input_event(const InputEvent& p_event) { return collision_polygon_editor->forward_input_event(p_event); } + + virtual String get_name() const { return "LightOccluder2D"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + LightOccluder2DEditorPlugin(EditorNode *p_node); + ~LightOccluder2DEditorPlugin(); + +}; + +#endif // LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index a60068309..25c39b317 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -1857,8 +1857,33 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p } else { p_item->set_text(1,"<"+res->get_type()+">"); }; + + if (has_icon(res->get_type(),"EditorIcons")) { + + p_item->set_icon(1,get_icon(res->get_type(),"EditorIcons")); + } else { + + Dictionary d = p_item->get_metadata(0); + int hint=d.has("hint")?d["hint"].operator int():-1; + String hint_text=d.has("hint_text")?d["hint_text"]:""; + if (hint==PROPERTY_HINT_RESOURCE_TYPE) { + + if (has_icon(hint_text,"EditorIcons")) { + + p_item->set_icon(1,get_icon(hint_text,"EditorIcons")); + + } else { + p_item->set_icon(1,get_icon("Object","EditorIcons")); + + } + } + } + + + } + } break; default: {}; } @@ -2529,7 +2554,10 @@ void PropertyEditor::update_tree() { item->set_editable( 1, !read_only ); item->add_button(1,get_icon("EditResource","EditorIcons")); String type; + if (p.hint==PROPERTY_HINT_RESOURCE_TYPE) + type=p.hint_string; bool notnil=false; + if (obj->get( p.name ).get_type() == Variant::NIL || obj->get( p.name ).operator RefPtr().is_null()) { item->set_text(1,""); @@ -2553,12 +2581,18 @@ void PropertyEditor::update_tree() { }; notnil=true; + if (has_icon(res->get_type(),"EditorIcons")) { + type=res->get_type(); + } } - if (p.hint==PROPERTY_HINT_RESOURCE_TYPE) { + + if (type!=String()) { + if (type.find(",")!=-1) + type=type.get_slice(",",0); //printf("prop %s , type %s\n",p.name.ascii().get_data(),p.hint_string.ascii().get_data()); - if (has_icon(p.hint_string,"EditorIcons")) - item->set_icon( 0, get_icon(p.hint_string,"EditorIcons") ); + if (has_icon(type,"EditorIcons")) + item->set_icon( 0, get_icon(type,"EditorIcons") ); else item->set_icon( 0, get_icon("Object","EditorIcons") ); } -- cgit v1.2.3-70-g09d2 From 4d2198110b4af7f203eeef95697255569e49bce7 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 3 Mar 2015 14:39:13 -0300 Subject: merges from okam repo --- SConstruct | 4 + core/object.cpp | 8 + core/object.h | 1 + doc/base/classes.xml | 3 +- drivers/gles2/rasterizer_gles2.cpp | 24 ++- methods.py | 8 + modules/gdscript/gd_tokenizer.cpp | 4 +- modules/gridmap/grid_map.cpp | 3 +- platform/android/AndroidManifest.xml.template | 3 +- platform/android/SCsub | 2 + platform/android/java_glue.cpp | 113 ++++++++++--- platform/bb10/SCsub | 10 +- platform/bb10/bar/bar-descriptor.xml | 30 ++-- platform/bb10/detect.py | 2 - platform/bb10/export/export.cpp | 79 ++++----- platform/bb10/os_bb10.cpp | 2 +- platform/iphone/gl_view.h | 2 + platform/iphone/gl_view.mm | 52 ++++++ scene/2d/camera_2d.cpp | 11 ++ scene/2d/camera_2d.h | 189 +++++++++++----------- scene/resources/shader_graph.h | 2 + servers/visual/shader_language.cpp | 4 +- tools/collada/collada.cpp | 2 +- tools/collada/collada.h | 18 +++ tools/editor/editor_import_export.cpp | 30 +++- tools/editor/editor_import_export.h | 3 +- tools/editor/io_plugins/editor_import_collada.cpp | 11 +- tools/export/blender25/io_scene_dae/export_dae.py | 71 ++++++-- 28 files changed, 458 insertions(+), 233 deletions(-) (limited to 'platform') diff --git a/SConstruct b/SConstruct index c68ca3989..2dc9fa1e7 100644 --- a/SConstruct +++ b/SConstruct @@ -67,12 +67,16 @@ env_base.android_source_modules=[] env_base.android_source_files=[] env_base.android_module_libraries=[] env_base.android_manifest_chunk="" +env_base.android_permission_chunk="" +env_base.android_appattributes_chunk="" env_base.disabled_modules=[] env_base.__class__.android_module_source = methods.android_module_source env_base.__class__.android_module_library = methods.android_module_library env_base.__class__.android_module_file = methods.android_module_file env_base.__class__.android_module_manifest = methods.android_module_manifest +env_base.__class__.android_module_permission = methods.android_module_permission +env_base.__class__.android_module_attribute = methods.android_module_attribute env_base.__class__.disable_module = methods.disable_module env_base.__class__.add_source_files = methods.add_source_files diff --git a/core/object.cpp b/core/object.cpp index 82144ab4b..2b83f728d 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1033,6 +1033,13 @@ void Object::add_user_signal(const MethodInfo& p_signal) { signal_map[p_signal.name]=s; } +bool Object::_has_user_signal(const StringName& p_name) const { + + if (!signal_map.has(p_name)) + return false; + return signal_map[p_name].user.name.length()>0; +} + struct _ObjectSignalDisconnectData { StringName signal; @@ -1431,6 +1438,7 @@ void Object::_bind_methods() { // ObjectTypeDB::bind_method(_MD("call_deferred","method","arg1","arg2","arg3","arg4"),&Object::_call_deferred_bind,DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant())); ObjectTypeDB::bind_method(_MD("add_user_signal","signal","arguments"),&Object::_add_user_signal,DEFVAL(Array())); + ObjectTypeDB::bind_method(_MD("has_user_signal","signal"),&Object::_has_user_signal); // ObjectTypeDB::bind_method(_MD("emit_signal","signal","arguments"),&Object::_emit_signal,DEFVAL(Array())); diff --git a/core/object.h b/core/object.h index 97ca50cb1..eb885f5d2 100644 --- a/core/object.h +++ b/core/object.h @@ -386,6 +386,7 @@ friend void postinitialize_handler(Object*); Dictionary metadata; void _add_user_signal(const String& p_name, const Array& p_pargs=Array()); + bool _has_user_signal(const StringName& p_name) const; Variant _emit_signal(const Variant** p_args, int p_argcount, Variant::CallError& r_error); Array _get_signal_list() const; Array _get_signal_connection_list(const String& p_signal) const; diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 35de0106b..e5bdcfbc6 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -18902,7 +18902,8 @@ collider_id: collider id of the object agaisnt which the ray was stopped[br] collider: collider object agaisnt which the ray was stopped[br] rid: [RID] of the object agaisnt which the ray was stopped[br] - If the ray did not intersect anything, then null is returned instead of a [Dictionary]. + If the ray did not intersect anything, then an empty + dictionary (dir.empty()==true) is returned instead. diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 9375532f0..9cee702c0 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -4954,12 +4954,26 @@ _FORCE_INLINE_ void RasterizerGLES2::_update_material_shader_params(Material *p_ Material::UniformData ud; bool keep=true; //keep material value - bool has_old = old_mparams.has(E->key()); + + Map::Element *OLD=old_mparams.find(E->key()); + bool has_old = OLD; bool old_inuse=has_old && old_mparams[E->key()].inuse; - if (!has_old || !old_inuse) + ud.istexture=(E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP); + + if (!has_old || !old_inuse) { keep=false; - else if (old_mparams[E->key()].value.get_type()!=E->value().default_value.get_type()) { + } + else if (OLD->get().value.get_type()!=E->value().default_value.get_type()) { + + if (OLD->get().value.get_type()==Variant::INT && E->get().type==ShaderLanguage::TYPE_FLOAT) { + //handle common mistake using shaders (feeding ints instead of float) + OLD->get().value=float(OLD->get().value); + keep=true; + } else if (!ud.istexture && E->value().default_value.get_type()!=Variant::NIL) { + + keep=false; + } //type changed between old and new /* if (old_mparams[E->key()].value.get_type()==Variant::OBJECT) { if (E->value().default_value.get_type()!=Variant::_RID) //hackfor textures @@ -4968,11 +4982,9 @@ _FORCE_INLINE_ void RasterizerGLES2::_update_material_shader_params(Material *p_ keep=false;*/ //value is invalid because type differs and default is not null - if (E->value().default_value.get_type()!=Variant::NIL) - keep=false; + ; } - ud.istexture=(E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP); if (keep) { ud.value=old_mparams[E->key()].value; diff --git a/methods.py b/methods.py index da1491e3f..9608b1b61 100755 --- a/methods.py +++ b/methods.py @@ -1291,6 +1291,14 @@ def android_module_manifest(self,file): base_path = self.Dir(".").abspath+"/modules/"+self.current_module+"/"+file f = open(base_path,"rb") self.android_manifest_chunk+=f.read() +def android_module_permission(self,file): + base_path = self.Dir(".").abspath+"/modules/"+self.current_module+"/"+file + f = open(base_path,"rb") + self.android_permission_chunk+=f.read() +def android_module_attribute(self,file): + base_path = self.Dir(".").abspath+"/modules/"+self.current_module+"/"+file + f = open(base_path,"rb") + self.android_appattributes_chunk+=f.read() def disable_module(self): self.disabled_modules.append(self.current_module) diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp index 6f968f208..71dbf81fb 100644 --- a/modules/gdscript/gd_tokenizer.cpp +++ b/modules/gdscript/gd_tokenizer.cpp @@ -538,9 +538,11 @@ void GDTokenizerText::_advance() { is_node_path=true; case '\'': - string_mode=STRING_SINGLE_QUOTE; case '"': { + if (GETCHAR(0)=='\'') + string_mode=STRING_SINGLE_QUOTE; + int i=1; if (string_mode==STRING_DOUBLE_QUOTE && GETCHAR(i)=='"' && GETCHAR(i+1)=='"') { i+=2; diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 7c344e1e9..441b274e3 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -122,7 +122,7 @@ bool GridMap::_set(const StringName& p_name, const Variant& p_value) { Octant &g = *octant_map[ok]; g.baked=b; - g.bake_instance=VS::get_singleton()->instance_create();; + g.bake_instance=VS::get_singleton()->instance_create();; VS::get_singleton()->instance_set_base(g.bake_instance,g.baked->get_rid()); VS::get_singleton()->instance_geometry_set_baked_light(g.bake_instance,baked_light_instance?baked_light_instance->get_baked_light_instance():RID()); } @@ -418,6 +418,7 @@ void GridMap::set_cell_item(int p_x,int p_y,int p_z, int p_item,int p_rot){ Octant *g = memnew( Octant ); g->dirty=true; g->static_body = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC); + PhysicsServer::get_singleton()->body_attach_object_instance_ID(g->static_body,get_instance_ID()); if (is_inside_world()) PhysicsServer::get_singleton()->body_set_space(g->static_body,get_world()->get_space()); diff --git a/platform/android/AndroidManifest.xml.template b/platform/android/AndroidManifest.xml.template index 60861db60..d31bdbfa5 100644 --- a/platform/android/AndroidManifest.xml.template +++ b/platform/android/AndroidManifest.xml.template @@ -10,7 +10,7 @@ android:largeScreens="true" android:xlargeScreens="true"/> - + +$$ADD_PERMISSION_CHUNKS$$ diff --git a/platform/android/SCsub b/platform/android/SCsub index cffec5ae9..6feeb8b36 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -56,6 +56,8 @@ pp_basein = open(abspath+"/AndroidManifest.xml.template","rb") pp_baseout = open(abspath+"/java/AndroidManifest.xml","wb") manifest = pp_basein.read() manifest = manifest.replace("$$ADD_APPLICATION_CHUNKS$$",env.android_manifest_chunk) +manifest = manifest.replace("$$ADD_PERMISSION_CHUNKS$$",env.android_permission_chunk) +manifest = manifest.replace("$$ADD_APPATTRIBUTE_CHUNKS$$",env.android_appattributes_chunk) pp_baseout.write( manifest ) diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 0312d1364..349db08e3 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -45,9 +45,18 @@ static JavaClassWrapper *java_class_wrapper=NULL; static OS_Android *os_android=NULL; -jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_arg, bool force_jobject = false) { +struct jvalret { - jvalue v; + jobject obj; + jvalue val; + jvalret() { obj=NULL; } + + +}; + +jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_arg, bool force_jobject = false) { + + jvalret v; switch(p_type) { @@ -59,9 +68,12 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jvalue val; val.z = (bool)(*p_arg); jobject obj = env->NewObjectA(bclass, ctor, &val); - v.l = obj; + v.val.l = obj; + v.obj=obj; + env->DeleteLocalRef(bclass); } else { - v.z=*p_arg; + v.val.z=*p_arg; + }; } break; case Variant::INT: { @@ -73,10 +85,13 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jvalue val; val.i = (int)(*p_arg); jobject obj = env->NewObjectA(bclass, ctor, &val); - v.l = obj; + v.val.l = obj; + v.obj=obj; + env->DeleteLocalRef(bclass); } else { - v.i=*p_arg; + v.val.i=*p_arg; + }; } break; case Variant::REAL: { @@ -88,17 +103,20 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jvalue val; val.d = (double)(*p_arg); jobject obj = env->NewObjectA(bclass, ctor, &val); - v.l = obj; + v.val.l = obj; + v.obj=obj; + env->DeleteLocalRef(bclass); } else { - v.f=*p_arg; + v.val.f=*p_arg; }; } break; case Variant::STRING: { String s = *p_arg; jstring jStr = env->NewStringUTF(s.utf8().get_data()); - v.l=jStr; + v.val.l=jStr; + v.obj=jStr; } break; case Variant::STRING_ARRAY: { @@ -107,9 +125,12 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar for(int j=0;jSetObjectArrayElement(arr,j,env->NewStringUTF( sarray[j].utf8().get_data() )); + jstring str = env->NewStringUTF( sarray[j].utf8().get_data() ); + env->SetObjectArrayElement(arr,j,str); + env->DeleteLocalRef(str); } - v.l=arr; + v.val.l=arr; + v.obj=arr; } break; @@ -124,27 +145,36 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jobjectArray jkeys = env->NewObjectArray(keys.size(), env->FindClass("java/lang/String"), env->NewStringUTF("")); for (int j=0; jSetObjectArrayElement(jkeys, j, env->NewStringUTF(String(keys[j]).utf8().get_data())); + jstring str = env->NewStringUTF(String(keys[j]).utf8().get_data()); + env->SetObjectArrayElement(jkeys, j, str); + env->DeleteLocalRef(str); }; jmethodID set_keys = env->GetMethodID(dclass, "set_keys", "([Ljava/lang/String;)V"); jvalue val; val.l = jkeys; env->CallVoidMethodA(jdict, set_keys, &val); + env->DeleteLocalRef(jkeys); jobjectArray jvalues = env->NewObjectArray(keys.size(), env->FindClass("java/lang/Object"), NULL); for (int j=0; jSetObjectArrayElement(jvalues, j, val.l); + jvalret v = _variant_to_jvalue(env, var.get_type(), &var, true); + env->SetObjectArrayElement(jvalues, j, v.val.l); + if (v.obj) { + env->DeleteLocalRef(v.obj); + } }; jmethodID set_values = env->GetMethodID(dclass, "set_values", "([Ljava/lang/Object;)V"); val.l = jvalues; env->CallVoidMethodA(jdict, set_values, &val); + env->DeleteLocalRef(jvalues); + env->DeleteLocalRef(dclass); - v.l = jdict; + v.val.l = jdict; + v.obj=jdict; } break; case Variant::INT_ARRAY: { @@ -153,7 +183,8 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jintArray arr = env->NewIntArray(array.size()); DVector::Read r = array.read(); env->SetIntArrayRegion(arr,0,array.size(),r.ptr()); - v.l=arr; + v.val.l=arr; + v.obj=arr; } break; case Variant::RAW_ARRAY: { @@ -161,7 +192,8 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jbyteArray arr = env->NewByteArray(array.size()); DVector::Read r = array.read(); env->SetByteArrayRegion(arr,0,array.size(),reinterpret_cast(r.ptr())); - v.l=arr; + v.val.l=arr; + v.obj=arr; } break; case Variant::REAL_ARRAY: { @@ -170,12 +202,13 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jfloatArray arr = env->NewFloatArray(array.size()); DVector::Read r = array.read(); env->SetFloatArrayRegion(arr,0,array.size(),r.ptr()); - v.l=arr; + v.val.l=arr; + v.obj=arr; } break; default: { - v.i = 0; + v.val.i = 0; } break; } @@ -193,8 +226,11 @@ String _get_class_name(JNIEnv * env, jclass cls, bool* array) { jboolean isarr = env->CallBooleanMethod(cls, isArray); (*array) = isarr ? true : false; } + String name = env->GetStringUTFChars( clsName, NULL ); + env->DeleteLocalRef(clsName); + + return name; - return env->GetStringUTFChars( clsName, NULL ); }; @@ -223,6 +259,8 @@ Variant _jobject_to_variant(JNIEnv * env, jobject obj) { jstring string = (jstring) env->GetObjectArrayElement(arr, i); const char *rawString = env->GetStringUTFChars(string, 0); sarr.push_back(String(rawString)); + env->DeleteLocalRef(string); + } return sarr; @@ -321,30 +359,34 @@ Variant _jobject_to_variant(JNIEnv * env, jobject obj) { jobjectArray arr = (jobjectArray)obj; int objCount = env->GetArrayLength(arr); - Array varr; + Array varr(true); for (int i=0; iGetObjectArrayElement(arr, i); Variant v = _jobject_to_variant(env, jobj); varr.push_back(v); + env->DeleteLocalRef(jobj); + } return varr; }; - if (name == "com.android.godot.Dictionary") { + if (name == "java.util.HashMap" || name == "com.android.godot.Dictionary") { - Dictionary ret; + Dictionary ret(true); jclass oclass = c; jmethodID get_keys = env->GetMethodID(oclass, "get_keys", "()[Ljava/lang/String;"); jobjectArray arr = (jobjectArray)env->CallObjectMethod(obj, get_keys); StringArray keys = _jobject_to_variant(env, arr); + env->DeleteLocalRef(arr); jmethodID get_values = env->GetMethodID(oclass, "get_values", "()[Ljava/lang/Object;"); arr = (jobjectArray)env->CallObjectMethod(obj, get_values); Array vals = _jobject_to_variant(env, arr); + env->DeleteLocalRef(arr); //print_line("adding " + String::num(keys.size()) + " to Dictionary!"); for (int i=0; iDeleteLocalRef(c); + return Variant(); }; @@ -432,9 +477,13 @@ public: JNIEnv *env = ThreadAndroid::get_env(); //print_line("argcount "+String::num(p_argcount)); + List to_erase; for(int i=0;iget().argtypes[i], p_args[i]); + jvalret vr = _variant_to_jvalue(env, E->get().argtypes[i], p_args[i]); + v[i] = vr.val; + if (vr.obj) + to_erase.push_back(vr.obj); } //print_line("calling method!!"); @@ -468,6 +517,7 @@ public: jobject o = env->CallObjectMethodA(instance,E->get().method,v); String str = env->GetStringUTFChars((jstring)o, NULL ); ret=str; + env->DeleteLocalRef(o); } break; case Variant::STRING_ARRAY: { @@ -475,6 +525,7 @@ public: ret = _jobject_to_variant(env, arr); + env->DeleteLocalRef(arr); } break; case Variant::INT_ARRAY: { @@ -488,6 +539,7 @@ public: env->GetIntArrayRegion(arr,0,fCount,w.ptr()); w = DVector::Write(); ret=sarr; + env->DeleteLocalRef(arr); } break; case Variant::REAL_ARRAY: { @@ -501,6 +553,7 @@ public: env->GetFloatArrayRegion(arr,0,fCount,w.ptr()); w = DVector::Write(); ret=sarr; + env->DeleteLocalRef(arr); } break; case Variant::DICTIONARY: { @@ -508,6 +561,7 @@ public: //print_line("call dictionary"); jobject obj = env->CallObjectMethodA(instance, E->get().method, v); ret = _jobject_to_variant(env, obj); + env->DeleteLocalRef(obj); } break; default: { @@ -518,6 +572,10 @@ public: } break; } + while (to_erase.size()) { + env->DeleteLocalRef(to_erase.front()->get()); + to_erase.pop_front(); + } //print_line("success"); return ret; @@ -872,6 +930,7 @@ static void _initialize_java_modules() { String modules = Globals::get_singleton()->get("android/modules"); Vector mods = modules.split(",",false); + print_line("ANDROID MODULES : " + modules); __android_log_print(ANDROID_LOG_INFO,"godot","mod count: %i",mods.size()); if (mods.size()) { @@ -1571,6 +1630,8 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_callobject(JNIEnv * env, memnew_placement(&vlist[i], Variant); vlist[i] = v; vptr[i] = &vlist[i]; + env->DeleteLocalRef(obj); + }; Variant::CallError err; @@ -1588,13 +1649,15 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_calldeferred(JNIEnv * env int count = env->GetArrayLength(params); Variant args[VARIANT_ARG_MAX]; -// print_line("Java->GD call: "+obj->get_type()+"::"+str_method+" argc "+itos(count)); + //print_line("Java->GD call: "+obj->get_type()+"::"+str_method+" argc "+itos(count)); for (int i=0; iGetObjectArrayElement(params, i); if (obj) args[i] = _jobject_to_variant(env, obj); + env->DeleteLocalRef(obj); + // print_line("\targ"+itos(i)+": "+Variant::get_type_name(args[i].get_type())); }; diff --git a/platform/bb10/SCsub b/platform/bb10/SCsub index 2e8ef4700..24f2b5d24 100644 --- a/platform/bb10/SCsub +++ b/platform/bb10/SCsub @@ -18,13 +18,5 @@ if env['bb10_lgles_override'] == "yes": prog = None -if env["target"]=="release": - prog = env_bps.Program('#platform/bb10/godot_bb10_opt', bb10_lib) -else: - prog = env_bps.Program('#platform/bb10/godot_bb10', bb10_lib) - -import os -fname = os.path.basename(str(prog[0])) - -env.Command('#bin/'+fname, prog, Copy('bin/'+fname, prog[0])) +prog = env_bps.Program('#bin/godot', bb10_lib) diff --git a/platform/bb10/bar/bar-descriptor.xml b/platform/bb10/bar/bar-descriptor.xml index df5d34e07..0ba70b718 100644 --- a/platform/bb10/bar/bar-descriptor.xml +++ b/platform/bb10/bar/bar-descriptor.xml @@ -1,65 +1,53 @@ - + - - - com.godot.game - Godot Game - 0.0.1 - 0 - Game made with Godot Engine - You Name or Company authorIDherePlease - - landscape false none false - core.games read_device_identifying_information access_internet - assets + data.pck - armle-v7 - godot_bb10.qnx.armle + armle-v7 + godot.bb10.debug.qnx.armle - armle-v7 - godot_bb10_opt.qnx.armle + armle-v7 + godot.bb10.opt.qnx.armle - icon.png + icon.png - - - + diff --git a/platform/bb10/detect.py b/platform/bb10/detect.py index 3ddb7a445..f134a9df1 100644 --- a/platform/bb10/detect.py +++ b/platform/bb10/detect.py @@ -81,8 +81,6 @@ def configure(env): if (env["target"]=="release"): env.Append(CCFLAGS=['-O3','-DRELEASE_BUILD']) - env['OBJSUFFIX'] = "_opt"+env['OBJSUFFIX'] - env['LIBSUFFIX'] = "_opt"+env['LIBSUFFIX'] elif (env["target"]=="debug"): diff --git a/platform/bb10/export/export.cpp b/platform/bb10/export/export.cpp index d40cb82cd..7862ecd49 100644 --- a/platform/bb10/export/export.cpp +++ b/platform/bb10/export/export.cpp @@ -321,12 +321,29 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu //BE SUPER CAREFUL WITH THIS PLEASE!!! //BLACKBERRY THIS IS YOUR FAULT FOR NOT MAKING A BETTER WAY!! - if (bar_dir.ends_with("bb10_export")) { - Error err = da->erase_contents_recursive(); - if (err!=OK) { + bool berr = bar_dir.ends_with("bb10_export"); + if (berr) { + if (da->list_dir_begin()) { EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir); - ERR_FAIL_COND_V(err!=OK,err); - } + ERR_FAIL_COND_V(berr,FAILED); + }; + + String f = da->get_next(); + while (f != "") { + + if (f == "." || f == "..") { + f = da->get_next(); + continue; + }; + Error err = da->remove(bar_dir + "/" + f); + if (err != OK) { + EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir); + ERR_FAIL_COND_V(err!=OK,err); + }; + f = da->get_next(); + }; + + da->list_dir_end(); } else { print_line("ARE YOU CRAZY??? THIS IS A SERIOUS BUG HERE!!!"); @@ -405,52 +422,23 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu ret = unzGoToNextFile(pkg); } - ep.step("Finding Files..",1); - - Vector files=get_dependencies(false); - ep.step("Adding Files..",2); - da->change_dir(bar_dir); - da->make_dir("assets"); - Error err = da->change_dir("assets"); - ERR_FAIL_COND_V(err,err); - - String asset_dir=da->get_current_dir(); - if (!asset_dir.ends_with("/")) - asset_dir+="/"; - - for(int i=0;i data = get_exported_file(fname); - /* - FileAccess *f=FileAccess::open(files[i],FileAccess::READ); - if (!f) { - EditorNode::add_io_error("Couldn't read: "+String(files[i])); - } - ERR_CONTINUE(!f); - data.resize(f->get_len()); - f->get_buffer(data.ptr(),data.size()); -*/ - String dst_path=fname; - dst_path=dst_path.replace_first("res://",asset_dir); - - da->make_dir_recursive(dst_path.get_base_dir()); - - ep.step("Adding File: "+String(files[i]).get_file(),3+i*100/files.size()); - - FileAccessRef fr = FileAccess::open(dst_path,FileAccess::WRITE); - fr->store_buffer(data.ptr(),data.size()); + FileAccess* dst = FileAccess::open(bar_dir+"/data.pck", FileAccess::WRITE); + if (!dst) { + EditorNode::add_io_error("Can't copy executable file to:\n "+p_path); + return ERR_FILE_CANT_WRITE; } - + save_pack(dst, false, 1024); + dst->close(); + memdelete(dst); ep.step("Creating BAR Package..",104); String bb_packager=EditorSettings::get_singleton()->get("blackberry/host_tools"); bb_packager=bb_packager.plus_file("blackberry-nativepackager"); if (OS::get_singleton()->get_name()=="Windows") - bb_packager+=".exe"; + bb_packager+=".bat"; if (!FileAccess::exists(bb_packager)) { @@ -482,7 +470,7 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu int ec; - err = OS::get_singleton()->execute(bb_packager,args,true,NULL,NULL,&ec); + Error err = OS::get_singleton()->execute(bb_packager,args,true,NULL,NULL,&ec); if (err!=OK) return err; @@ -493,7 +481,6 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu } - bool EditorExportPlatformBB10::poll_devices() { bool dc=devices_changed; @@ -537,7 +524,7 @@ void EditorExportPlatformBB10::_device_poll_thread(void *ud) { bb_deploy=bb_deploy.plus_file("blackberry-deploy"); bool windows = OS::get_singleton()->get_name()=="Windows"; if (windows) - bb_deploy+=".exe"; + bb_deploy+=".bat"; if (!FileAccess::exists(bb_deploy)) { OS::get_singleton()->delay_usec(3000000); @@ -639,7 +626,7 @@ Error EditorExportPlatformBB10::run(int p_device, bool p_dumb) { String bb_deploy=EditorSettings::get_singleton()->get("blackberry/host_tools"); bb_deploy=bb_deploy.plus_file("blackberry-deploy"); if (OS::get_singleton()->get_name()=="Windows") - bb_deploy+=".exe"; + bb_deploy+=".bat"; if (!FileAccess::exists(bb_deploy)) { EditorNode::add_io_error("Blackberry Deploy not found:\n"+bb_deploy); diff --git a/platform/bb10/os_bb10.cpp b/platform/bb10/os_bb10.cpp index ff43a68b1..d89033b1d 100644 --- a/platform/bb10/os_bb10.cpp +++ b/platform/bb10/os_bb10.cpp @@ -619,7 +619,7 @@ OSBB10::OSBB10() { printf("godot bb10!\n"); getcwd(launch_dir, sizeof(launch_dir)); printf("launch dir %s\n", launch_dir); - chdir("app/native/assets"); + chdir("app/native"); launch_dir_ptr = launch_dir; } diff --git a/platform/iphone/gl_view.h b/platform/iphone/gl_view.h index 8ae7c2f87..8eb96e7e9 100755 --- a/platform/iphone/gl_view.h +++ b/platform/iphone/gl_view.h @@ -93,6 +93,8 @@ - (BOOL)createFramebuffer; - (void)destroyFramebuffer; +- (void)audioRouteChangeListenerCallback:(NSNotification*)notification; + @property NSTimeInterval animationInterval; @end diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm index bee01d3c7..7d33c1131 100755 --- a/platform/iphone/gl_view.mm +++ b/platform/iphone/gl_view.mm @@ -119,6 +119,8 @@ bool _play_video(String p_path, float p_volume, String p_audio_track, String p_s name:AVPlayerItemDidPlayToEndTimeNotification object:[_instance.avPlayer currentItem]]; + [_instance.avPlayer addObserver:_instance forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:0]; + [_instance.avPlayerLayer setFrame:_instance.bounds]; [_instance.layer addSublayer:_instance.avPlayerLayer]; [_instance.avPlayer play]; @@ -578,6 +580,39 @@ static void clear_touches() { printf("inserting text with character %i\n", character[0]); }; +- (void)audioRouteChangeListenerCallback:(NSNotification*)notification +{ + printf("*********** route changed!%i\n"); + NSDictionary *interuptionDict = notification.userInfo; + + NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue]; + + switch (routeChangeReason) { + + case AVAudioSessionRouteChangeReasonNewDeviceAvailable: + NSLog(@"AVAudioSessionRouteChangeReasonNewDeviceAvailable"); + NSLog(@"Headphone/Line plugged in"); + break; + + case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: + NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable"); + NSLog(@"Headphone/Line was pulled. Resuming video play...."); + if (_is_video_playing) { + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ + [_instance.avPlayer play]; // NOTE: change this line according your current player implementation + NSLog(@"resumed play"); + }); + }; + break; + + case AVAudioSessionRouteChangeReasonCategoryChange: + // called at start - also when other audio wants to play + NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange"); + break; + } +} + // When created via code however, we get initWithFrame -(id)initWithFrame:(CGRect)frame @@ -593,6 +628,11 @@ static void clear_touches() { init_touches(); self. multipleTouchEnabled = YES; + printf("******** adding observer for sound routing changes\n"); + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:) + name:AVAudioSessionRouteChangeNotification + object:nil]; + //self.autoresizesSubviews = YES; //[self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth]; @@ -642,6 +682,18 @@ static void clear_touches() { video_current_time = kCMTimeZero; } } + + if (object == _instance.avPlayer && [keyPath isEqualToString:@"rate"]) { + NSLog(@"Player playback rate changed: %.5f", _instance.avPlayer.rate); + if (_is_video_playing() && _instance.avPlayer.rate == 0.0 && !_instance.avPlayer.error) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ + [_instance.avPlayer play]; // NOTE: change this line according your current player implementation + NSLog(@"resumed play"); + }); + + NSLog(@" . . . PAUSED (or just started)"); + } + } } - (void)playerItemDidReachEnd:(NSNotification *)notification { diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index b3897010b..b2d74b4ad 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -323,6 +323,16 @@ void Camera2D::make_current() { } } +void Camera2D::clear_current() { + + current=false; + if (is_inside_tree()) { + get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,group_name,"_make_current",(Object*)(NULL)); + } + +} + + void Camera2D::set_limit(Margin p_margin,int p_limit) { ERR_FAIL_INDEX(p_margin,4); @@ -435,6 +445,7 @@ void Camera2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("is_rotating"),&Camera2D::is_rotating); ObjectTypeDB::bind_method(_MD("make_current"),&Camera2D::make_current); + ObjectTypeDB::bind_method(_MD("clear_current"),&Camera2D::clear_current); ObjectTypeDB::bind_method(_MD("_make_current"),&Camera2D::_make_current); ObjectTypeDB::bind_method(_MD("_update_scroll"),&Camera2D::_update_scroll); diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 116169cac..515f9711b 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -26,97 +26,98 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CAMERA_2D_H -#define CAMERA_2D_H - -#include "scene/2d/node_2d.h" -#include "scene/main/viewport.h" - - -class Camera2D : public Node2D { - - OBJ_TYPE( Camera2D, Node2D ); - -protected: - Point2 camera_pos; - Point2 smoothed_camera_pos; - bool first; - - Viewport *viewport; - - StringName group_name; - StringName canvas_group_name; - RID canvas; - Vector2 offset; - Vector2 zoom; - bool centered; - bool rotating; - bool current; - float smoothing; - int limit[4]; - float drag_margin[4]; - - bool h_drag_enabled; - bool v_drag_enabled; - float h_ofs; - float v_ofs; - - - Point2 camera_screen_center; - void _update_scroll(); - - void _make_current(Object *p_which); - void _set_current(bool p_current); -protected: - - virtual Matrix32 get_camera_transform(); - void _notification(int p_what); - static void _bind_methods(); -public: - - void set_offset(const Vector2& p_offset); - Vector2 get_offset() const; - - void set_centered(bool p_centered); - bool is_centered() const; - - void set_rotating(bool p_rotating); - bool is_rotating() const; - - void set_limit(Margin p_margin,int p_limit); - int get_limit(Margin p_margin) const; - - - void set_h_drag_enabled(bool p_enabled); - bool is_h_drag_enabled() const; - - void set_v_drag_enabled(bool p_enabled); - bool is_v_drag_enabled() const; - - void set_drag_margin(Margin p_margin,float p_drag_margin); - float get_drag_margin(Margin p_margin) const; - - void set_v_offset(float p_offset); - float get_v_offset() const; - - void set_h_offset(float p_offset); - float get_h_offset() const; - - void set_follow_smoothing(float p_speed); - float get_follow_smoothing() const; - - void make_current(); - bool is_current() const; - - void set_zoom(const Vector2& p_zoom); - Vector2 get_zoom() const; - - Point2 get_camera_screen_center() const; - - Vector2 get_camera_pos() const; - void force_update_scroll(); - - Camera2D(); -}; - -#endif // CAMERA_2D_H +#ifndef CAMERA_2D_H +#define CAMERA_2D_H + +#include "scene/2d/node_2d.h" +#include "scene/main/viewport.h" + + +class Camera2D : public Node2D { + + OBJ_TYPE( Camera2D, Node2D ); + +protected: + Point2 camera_pos; + Point2 smoothed_camera_pos; + bool first; + + Viewport *viewport; + + StringName group_name; + StringName canvas_group_name; + RID canvas; + Vector2 offset; + Vector2 zoom; + bool centered; + bool rotating; + bool current; + float smoothing; + int limit[4]; + float drag_margin[4]; + + bool h_drag_enabled; + bool v_drag_enabled; + float h_ofs; + float v_ofs; + + + Point2 camera_screen_center; + void _update_scroll(); + + void _make_current(Object *p_which); + void _set_current(bool p_current); +protected: + + virtual Matrix32 get_camera_transform(); + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_offset(const Vector2& p_offset); + Vector2 get_offset() const; + + void set_centered(bool p_centered); + bool is_centered() const; + + void set_rotating(bool p_rotating); + bool is_rotating() const; + + void set_limit(Margin p_margin,int p_limit); + int get_limit(Margin p_margin) const; + + + void set_h_drag_enabled(bool p_enabled); + bool is_h_drag_enabled() const; + + void set_v_drag_enabled(bool p_enabled); + bool is_v_drag_enabled() const; + + void set_drag_margin(Margin p_margin,float p_drag_margin); + float get_drag_margin(Margin p_margin) const; + + void set_v_offset(float p_offset); + float get_v_offset() const; + + void set_h_offset(float p_offset); + float get_h_offset() const; + + void set_follow_smoothing(float p_speed); + float get_follow_smoothing() const; + + void make_current(); + void clear_current(); + bool is_current() const; + + void set_zoom(const Vector2& p_zoom); + Vector2 get_zoom() const; + + Point2 get_camera_screen_center() const; + + Vector2 get_camera_pos() const; + void force_update_scroll(); + + Camera2D(); +}; + +#endif // CAMERA_2D_H diff --git a/scene/resources/shader_graph.h b/scene/resources/shader_graph.h index 55d09b4c3..c515f6e10 100644 --- a/scene/resources/shader_graph.h +++ b/scene/resources/shader_graph.h @@ -66,6 +66,8 @@ public: NODE_VEC_TO_XFORM, // 3 vec input, 1 xform output NODE_SCALAR_INTERP, // scalar interpolation (with optional curve) NODE_VEC_INTERP, // vec3 interpolation (with optional curve) + /*NODE_SCALAR_CURVE_REMAP, + NODE_VEC_CURVE_REMAP,*/ NODE_SCALAR_INPUT, // scalar uniform (assignable in material) NODE_VEC_INPUT, // vec3 uniform (assignable in material) NODE_RGB_INPUT, // color uniform (assignable in material) diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 9a76a009a..30499ca21 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -2058,7 +2058,9 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex at+=get_datatype_name(compute_node_type(op->arguments[i])); } - parser.set_error("Invalid arguments to operator "+String(token_names[op->op])+": "+at); + static const char *op_names[OP_MAX]={"=","+","-","*","/","+=","-=","*=","/=","-","!","==","!=","<=",">=","<",">","||","&&","call","()"}; + + parser.set_error("Invalid arguments to operator "+String(op_names[op->op])+": "+at); return ERR_PARSE_ERROR; } expression.remove(next_op); diff --git a/tools/collada/collada.cpp b/tools/collada/collada.cpp index 97e9f5c36..b55edde80 100644 --- a/tools/collada/collada.cpp +++ b/tools/collada/collada.cpp @@ -817,7 +817,7 @@ void Collada::_parse_camera(XMLParser& parser) { if (name=="perspective") { camera.mode=CameraData::MODE_PERSPECTIVE; - } else if (name=="orthogonal") { + } else if (name=="orthographic") { camera.mode=CameraData::MODE_ORTHOGONAL; } else if (name=="xfov") { diff --git a/tools/collada/collada.h b/tools/collada/collada.h index f523d24e0..7691d90c0 100644 --- a/tools/collada/collada.h +++ b/tools/collada/collada.h @@ -337,6 +337,24 @@ public: if(normal==p_vert.normal) { if(uv==p_vert.uv) { if(uv2==p_vert.uv2) { + + if (!weights.empty() || !p_vert.weights.empty()) { + + if (weights.size()==p_vert.weights.size()) { + + for(int i=0;i 0) { + pad = p_alignment - rest; + }; + + return pad; +}; Error EditorExportPlatform::save_pack_file(void *p_userdata,const String& p_path, const Vector& p_data,int p_file,int p_total) { @@ -930,11 +940,19 @@ Error EditorExportPlatform::save_pack_file(void *p_userdata,const String& p_path pd->ep->step("Storing File: "+p_path,2+p_file*100/p_total); pd->count++; pd->ftmp->store_buffer(p_data.ptr(),p_data.size()); + if (pd->alignment > 1) { + + int pad = _get_pad(pd->alignment, pd->ftmp->get_pos()); + for (int i=0; iftmp->store_8(0); + }; + }; return OK; } -Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles) { +Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles, int p_alignment) { EditorProgress ep("savepack","Packing",102); @@ -952,7 +970,6 @@ Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles) { dst->store_32(0); } - size_t fcountpos = dst->get_pos(); dst->store_32(0); @@ -961,11 +978,20 @@ Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles) { pd.f=dst; pd.ftmp=tmp; pd.count=0; + pd.alignment = p_alignment; Error err = export_project_files(save_pack_file,&pd,p_make_bundles); memdelete(tmp); if (err) return err; + if (p_alignment > 1) { + int pad = _get_pad(p_alignment, dst->get_pos()); + for (int i=0; istore_8(0); + }; + }; + size_t ofsplus = dst->get_pos(); //append file diff --git a/tools/editor/editor_import_export.h b/tools/editor/editor_import_export.h index 8305e3c88..b97dde12f 100644 --- a/tools/editor/editor_import_export.h +++ b/tools/editor/editor_import_export.h @@ -100,6 +100,7 @@ protected: Vector file_ofs; EditorProgress *ep; int count; + int alignment; }; @@ -121,7 +122,7 @@ public: Error export_project_files(EditorExportSaveFunction p_func, void* p_udata,bool p_make_bundles); - Error save_pack(FileAccess *p_where, bool p_make_bundles=false); + Error save_pack(FileAccess *p_where, bool p_make_bundles=false, int p_alignment = 1); virtual String get_name() const =0; virtual ImageCompression get_image_compression() const=0; virtual Ref get_logo() const =0; diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp index 529ed3374..6dd46843c 100644 --- a/tools/editor/io_plugins/editor_import_collada.cpp +++ b/tools/editor/io_plugins/editor_import_collada.cpp @@ -285,13 +285,16 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) { case Collada::CameraData::MODE_ORTHOGONAL: { - if (cd.orthogonal.x_mag) { + if (cd.orthogonal.y_mag) { - camera->set_orthogonal(cd.orthogonal.x_mag,cd.z_near,cd.z_far); + camera->set_keep_aspect_mode(Camera::KEEP_HEIGHT); + camera->set_orthogonal(cd.orthogonal.y_mag*2.0 ,cd.z_near,cd.z_far); - } else if (!cd.orthogonal.x_mag && cd.orthogonal.y_mag) { + } else if (!cd.orthogonal.y_mag && cd.orthogonal.x_mag) { - camera->set_orthogonal(cd.orthogonal.y_mag * cd.aspect,cd.z_near,cd.z_far); + + camera->set_keep_aspect_mode(Camera::KEEP_WIDTH); + camera->set_orthogonal(cd.orthogonal.x_mag*2.0,cd.z_near,cd.z_far); } } break; diff --git a/tools/export/blender25/io_scene_dae/export_dae.py b/tools/export/blender25/io_scene_dae/export_dae.py index 8161f05bf..5e5febfb1 100644 --- a/tools/export/blender25/io_scene_dae/export_dae.py +++ b/tools/export/blender25/io_scene_dae/export_dae.py @@ -94,8 +94,6 @@ def strarr(arr): s+=" " return s - - class DaeExporter: def validate_id(self,d): @@ -132,10 +130,10 @@ class DaeExporter: tup = tup + (self.tangent.x,self.tangent.y,self.tangent.z) if (self.bitangent!=None): tup = tup + (self.bitangent.x,self.bitangent.y,self.bitangent.z) - #for t in self.bones: - # tup = tup + (t) - #for t in self.weights: - # tup = tup + (t) + for t in self.bones: + tup = tup + (float(t),) + for t in self.weights: + tup = tup + (float(t),) return tup @@ -212,8 +210,8 @@ class DaeExporter: imgid = self.new_id("image") if (not os.path.isfile(imgpath)): - if img_tmp_path.endswith((".bmp",".rgb",".png",".jpeg",".jpg",".jp2",".tga",".cin",".dpx",".exr",".hdr",".tif")): - imgpath="images/"+os.path.basename(img_tmp_path) + if imgpath.endswith((".bmp",".rgb",".png",".jpeg",".jpg",".jp2",".tga",".cin",".dpx",".exr",".hdr",".tif")): + imgpath="images/"+os.path.basename(imgpath) else: imgpath="images/"+image.name+".png" @@ -512,12 +510,12 @@ class DaeExporter: mat_assign=[] uv_layer_count=len(mesh.uv_textures) - if (len(mesh.uv_textures)): + if (has_tangents and len(mesh.uv_textures)): try: mesh.calc_tangents() except: - print("Warning, blender API is fucked up, not exporting UVs for this object.") - uv_layer_count=0 + self.operator.report({'WARNING'},'CalcTangets failed for mesh "'+mesh.name+'", no tangets will be exported.') + #uv_layer_count=0 mesh.calc_normals_split() has_tangents=False @@ -591,16 +589,30 @@ class DaeExporter: if (armature!=None): wsum=0.0 + zero_bones=[] + for vg in mv.groups: if vg.group >= len(node.vertex_groups): continue; name = node.vertex_groups[vg.group].name + if (name in si["bone_index"]): #could still put the weight as 0.0001 maybe if (vg.weight>0.001): #blender has a lot of zero weight stuff v.bones.append(si["bone_index"][name]) v.weights.append(vg.weight) wsum+=vg.weight + if (wsum==0.0): + if not self.wrongvtx_report: + self.operator.report({'WARNING'},'Mesh for object "'+node.name+'" has unassigned weights. This may look wrong in exported model.') + self.wrongvtx_report=True + + #blender can have bones assigned that weight zero so they remain local + #this is the best it can be done? + v.bones.append(0) + v.weights.append(1) + + tup = v.get_tup() @@ -889,6 +901,15 @@ class DaeExporter: if (node.parent!=None): if (node.parent.type=="ARMATURE"): armature=node.parent + armcount=0 + for n in node.modifiers: + if (n.type=="ARMATURE"): + armcount+=1 + if (armcount>1): + self.operator.report({'WARNING'},'Object "'+node.name+'" refers to more than one armature! This is unsopported.') + + + if (node.data.shape_keys!=None): sk = node.data.shape_keys @@ -940,6 +961,12 @@ class DaeExporter: boneidx = si["bone_count"] si["bone_count"]+=1 bonesid = si["id"]+"-"+str(boneidx) + if (bone.name in self.used_bones): + if (self.config["use_anim_action_all"]): + self.operator.report({'WARNING'},'Bone name "'+bone.name+'" used in more than one skeleton. Actions might export wrong.') + else: + self.used_bones.append(bone.name) + si["bone_index"][bone.name]=boneidx si["bone_ids"][bone]=boneid si["bone_names"].append(bonesid) @@ -1002,12 +1029,12 @@ class DaeExporter: self.writel(S_CAMS,5,' '+str(camera.clip_end)+' ') self.writel(S_CAMS,4,'') else: - self.writel(S_CAMS,4,'') - self.writel(S_CAMS,5,' '+str(camera.ortho_scale)+' ') # I think? + self.writel(S_CAMS,4,'') + self.writel(S_CAMS,5,' '+str(camera.ortho_scale*0.5)+' ') # I think? self.writel(S_CAMS,5,' '+str(self.scene.render.resolution_x / self.scene.render.resolution_y)+' ') self.writel(S_CAMS,5,' '+str(camera.clip_start)+' ') self.writel(S_CAMS,5,' '+str(camera.clip_end)+' ') - self.writel(S_CAMS,4,'') + self.writel(S_CAMS,4,'') self.writel(S_CAMS,3,'') self.writel(S_CAMS,2,'') @@ -1534,10 +1561,14 @@ class DaeExporter: for z in tcn: self.writel(S_ANIM_CLIPS,2,'') self.writel(S_ANIM_CLIPS,1,'') + if (len(tcn)==0): + self.operator.report({'WARNING'},'Animation clip "'+x.name+'" contains no tracks.') + self.writel(S_ANIM_CLIPS,0,'') + for i,s in enumerate(self.skeletons): if (s.animation_data==None): continue @@ -1547,6 +1578,7 @@ class DaeExporter: s.animation_data.action = None for j,bone in enumerate(s.pose.bones): bone.matrix_basis = tmp_mat[i][1][j] + else: self.export_animation(self.scene.frame_start,self.scene.frame_end) @@ -1617,7 +1649,8 @@ class DaeExporter: f.write(bytes('\n',"UTF-8")) return True - def __init__(self,path,kwargs): + def __init__(self,path,kwargs,operator): + self.operator=operator self.scene=bpy.context.scene self.last_id=0 self.scene_name=self.new_id("scene") @@ -1631,6 +1664,10 @@ class DaeExporter: self.config=kwargs self.valid_nodes=[] self.armature_for_morph={} + self.used_bones=[] + self.wrongvtx_report=False + + @@ -1642,9 +1679,11 @@ def save(operator, context, **kwargs ): - exp = DaeExporter(filepath,kwargs) + exp = DaeExporter(filepath,kwargs,operator) exp.export() + + return {'FINISHED'} # so the script wont run after we have batch exported. -- cgit v1.2.3-70-g09d2 From 52a4e8495c6b9324f3c61f85c3ed3708c3e93213 Mon Sep 17 00:00:00 2001 From: hurikhan Date: Sun, 8 Mar 2015 04:24:21 -0500 Subject: fix introduced bug --- platform/x11/os_x11.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'platform') diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 8def56456..819628173 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -1286,7 +1286,7 @@ void OS_X11::process_xevents() { motion_event.mouse_motion.x=pos.x; motion_event.mouse_motion.y=pos.y; input->set_mouse_pos(pos); - motion_event.mouse_motion.global_x=pos.y; + motion_event.mouse_motion.global_x=pos.x; motion_event.mouse_motion.global_y=pos.y; motion_event.mouse_motion.speed_x=input->get_mouse_speed().x; motion_event.mouse_motion.speed_y=input->get_mouse_speed().y; -- cgit v1.2.3-70-g09d2 From 53e1694e1e2b76026d862e84c1de88f62601cbc3 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Mon, 16 Mar 2015 00:47:37 -0300 Subject: New option to send canvas to render buffer allows to use 3D environment effects for post processing such as Glow, Bloom, HDR, etc. in 2D. --- demos/2d/hdr/beach_cave.gd | 26 +++++++++ demos/2d/hdr/beach_cave.scn | Bin 0 -> 2972 bytes demos/2d/hdr/engine.cfg | 13 +++++ demos/2d/hdr/ocean_beach.png | Bin 0 -> 443558 bytes demos/2d/hdr/ocean_beach.png.flags | 1 + demos/2d/hdr/ocean_cave.png | Bin 0 -> 745215 bytes demos/2d/hdr/ocean_cave.png.flags | 1 + demos/2d/isometric_light/map.scn | Bin 8565 -> 8535 bytes demos/2d/platformer/stage.xml | 35 ++++++------ drivers/gles2/rasterizer_gles2.cpp | 50 +++++++++++------ drivers/gles2/rasterizer_gles2.h | 4 ++ platform/windows/os_windows.cpp | 1 + scene/gui/text_edit.cpp | 4 +- scene/resources/environment.cpp | 7 ++- scene/resources/environment.h | 6 +- servers/visual/rasterizer.h | 1 + servers/visual/visual_server_raster.cpp | 96 ++++++++++++++++++++++++++++++-- servers/visual/visual_server_raster.h | 8 ++- servers/visual/visual_server_wrap_mt.h | 1 + servers/visual_server.h | 5 +- tools/editor/editor_node.cpp | 5 ++ tools/editor/property_editor.cpp | 24 ++++++++ 22 files changed, 238 insertions(+), 50 deletions(-) create mode 100644 demos/2d/hdr/beach_cave.gd create mode 100644 demos/2d/hdr/beach_cave.scn create mode 100644 demos/2d/hdr/engine.cfg create mode 100644 demos/2d/hdr/ocean_beach.png create mode 100644 demos/2d/hdr/ocean_beach.png.flags create mode 100644 demos/2d/hdr/ocean_cave.png create mode 100644 demos/2d/hdr/ocean_cave.png.flags (limited to 'platform') diff --git a/demos/2d/hdr/beach_cave.gd b/demos/2d/hdr/beach_cave.gd new file mode 100644 index 000000000..9dffbc466 --- /dev/null +++ b/demos/2d/hdr/beach_cave.gd @@ -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 + + diff --git a/demos/2d/hdr/beach_cave.scn b/demos/2d/hdr/beach_cave.scn new file mode 100644 index 000000000..4147a130a Binary files /dev/null and b/demos/2d/hdr/beach_cave.scn differ diff --git a/demos/2d/hdr/engine.cfg b/demos/2d/hdr/engine.cfg new file mode 100644 index 000000000..3d8b4222d --- /dev/null +++ b/demos/2d/hdr/engine.cfg @@ -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 diff --git a/demos/2d/hdr/ocean_beach.png b/demos/2d/hdr/ocean_beach.png new file mode 100644 index 000000000..a873d4f61 Binary files /dev/null and b/demos/2d/hdr/ocean_beach.png differ diff --git a/demos/2d/hdr/ocean_beach.png.flags b/demos/2d/hdr/ocean_beach.png.flags new file mode 100644 index 000000000..82127bd7d --- /dev/null +++ b/demos/2d/hdr/ocean_beach.png.flags @@ -0,0 +1 @@ +tolinear=true diff --git a/demos/2d/hdr/ocean_cave.png b/demos/2d/hdr/ocean_cave.png new file mode 100644 index 000000000..8875499df Binary files /dev/null and b/demos/2d/hdr/ocean_cave.png differ diff --git a/demos/2d/hdr/ocean_cave.png.flags b/demos/2d/hdr/ocean_cave.png.flags new file mode 100644 index 000000000..82127bd7d --- /dev/null +++ b/demos/2d/hdr/ocean_cave.png.flags @@ -0,0 +1 @@ +tolinear=true diff --git a/demos/2d/isometric_light/map.scn b/demos/2d/isometric_light/map.scn index fb2f3a215..c939a4b39 100644 Binary files a/demos/2d/isometric_light/map.scn and b/demos/2d/isometric_light/map.scn differ diff --git a/demos/2d/platformer/stage.xml b/demos/2d/platformer/stage.xml index 35517f747..610057183 100644 --- a/demos/2d/platformer/stage.xml +++ b/demos/2d/platformer/stage.xml @@ -2,16 +2,16 @@ - - + + + - "names" - + "stage" "Node" "_import_path" @@ -21,6 +21,7 @@ "visibility/visible" "visibility/opacity" "visibility/self_opacity" + "visibility/light_mask" "transform/pos" "transform/rot" "transform/scale" @@ -32,7 +33,9 @@ "cell/quadrant_size" "cell/custom_transform" "cell/half_offset" - "collision/body_mode" + "cell/tile_origin" + "cell/y_sort" + "collision/use_kinematic" "collision/friction" "collision/bounce" "collision/layers" @@ -172,10 +175,10 @@ 0.814506 "use_snap" False + "snap_vec" + 10, 10 "ofs" - -121.031, 464.121 - "snap" - 10 + 177.488, 709.633 "3D" @@ -278,10 +281,11 @@ 0 "__editor_plugin_screen__" - "2D" + "3D" True 1 + 1 0, 0 0 1, 1 @@ -291,7 +295,7 @@ 8 1, 0, 0, 1, 0, 0 2 - 1 + False 0, 2, 70, 536870914, 71, 10, 72, 10, 73, 10, 74, 10, 75, 10, 76, 10, 77, 10, 78, 10, 65536, 2, 65606, 536870914, 65607, 10, 65608, 10, 65609, 10, 65610, 10, 65611, 10, 65612, 10, 65613, 10, 65614, 10, 131072, 2, 131142, 536870914, 131143, 10, 131144, 10, 131145, 10, 131146, 10, 131147, 10, 131148, 10, 131149, 10, 131150, 10, 196608, 2, 196626, 9, 196678, 536870914, 196679, 10, 196680, 10, 196681, 10, 196682, 10, 196683, 10, 196684, 10, 196685, 10, 196686, 10, 262144, 2, 262162, 8, 262214, 536870914, 262215, 10, 262216, 10, 262217, 10, 262218, 10, 262219, 10, 262220, 10, 262221, 10, 262222, 10, 327680, 2, 327697, 536870921, 327698, 7, 327733, 9, 327750, 536870914, 327751, 10, 327752, 10, 327753, 10, 327754, 10, 327755, 10, 327756, 10, 327757, 10, 327758, 10, 393216, 2, 393233, 536870920, 393234, 7, 393257, 9, 393269, 7, 393286, 536870914, 393287, 10, 393288, 10, 393289, 10, 393290, 10, 393291, 10, 393292, 10, 393293, 10, 393294, 10, 458752, 2, 458769, 7, 458770, 8, 458790, 9, 458793, 8, 458805, 8, 458822, 536870914, 458823, 10, 458824, 10, 458825, 10, 458826, 10, 458827, 10, 458828, 10, 458829, 10, 458830, 10, 524288, 4, 524289, 1, 524304, 536870913, 524305, 536870918, 524306, 6, 524307, 5, 524308, 1, 524326, 8, 524329, 7, 524341, 7, 524358, 536870914, 524359, 10, 524360, 10, 524361, 10, 524362, 10, 524363, 10, 524364, 10, 524365, 10, 524366, 10, 589824, 10, 589825, 13, 589840, 536870914, 589841, 10, 589842, 10, 589843, 10, 589844, 2, 589862, 7, 589865, 7, 589876, 536870913, 589877, 6, 589878, 1, 589894, 536870914, 589895, 10, 589896, 10, 589897, 10, 589898, 10, 589899, 10, 589900, 10, 589901, 10, 589902, 10, 655360, 2, 655376, 536870914, 655377, 10, 655378, 10, 655379, 10, 655380, 2, 655398, 7, 655401, 8, 655412, 536870925, 655413, 11, 655414, 13, 655430, 536870914, 655431, 10, 655432, 10, 655433, 10, 655434, 10, 655435, 10, 655436, 10, 655437, 10, 655438, 10, 720896, 2, 720912, 536870914, 720913, 10, 720914, 10, 720915, 10, 720916, 2, 720934, 8, 720937, 7, 720958, 536870913, 720959, 5, 720960, 536870917, 720961, 5, 720962, 5, 720963, 536870917, 720964, 5, 720965, 0, 720966, 536870916, 720967, 10, 720968, 10, 720969, 10, 720970, 10, 720971, 10, 720972, 10, 720973, 10, 720974, 10, 786432, 2, 786437, 9, 786448, 536870914, 786449, 10, 786450, 10, 786451, 10, 786452, 2, 786464, 536870913, 786465, 1, 786470, 7, 786473, 7, 786474, 536870924, 786475, 1, 786494, 536870914, 786495, 10, 786496, 10, 786497, 10, 786498, 10, 786499, 10, 786500, 10, 786501, 10, 786502, 10, 786503, 10, 786504, 10, 786505, 10, 786506, 10, 786507, 10, 786508, 10, 786509, 10, 851968, 2, 851973, 7, 851984, 536870914, 851985, 10, 851986, 10, 851987, 10, 851988, 2, 851996, 536870913, 851997, 1, 852000, 536870914, 852001, 3, 852006, 7, 852009, 536870913, 852011, 2, 852030, 536870914, 852031, 10, 852032, 10, 852033, 10, 852034, 10, 852035, 10, 852036, 10, 852037, 10, 852038, 10, 852039, 10, 852040, 10, 852041, 10, 852042, 10, 852043, 10, 852044, 10, 852045, 10, 917504, 2, 917506, 9, 917509, 7, 917512, 536870921, 917520, 536870925, 917521, 11, 917522, 11, 917523, 11, 917524, 13, 917532, 536870925, 917533, 13, 917536, 536870914, 917537, 4, 917538, 1, 917540, 536870913, 917541, 0, 917542, 1, 917545, 536870914, 917546, 10, 917547, 4, 917548, 1, 917566, 536870914, 917567, 10, 917568, 10, 917569, 10, 917570, 10, 917571, 10, 917572, 10, 917573, 10, 917574, 10, 917575, 10, 917576, 10, 917577, 10, 917578, 10, 917579, 10, 917580, 10, 917581, 10, 983040, 2, 983042, 7, 983045, 7, 983048, 536870920, 983050, 536870913, 983051, 1, 983064, 536870913, 983065, 1, 983072, 536870914, 983073, 10, 983074, 4, 983075, 0, 983076, 536870916, 983077, 10, 983078, 4, 983079, 536870912, 983080, 536870912, 983081, 536870916, 983082, 10, 983083, 10, 983084, 2, 983095, 9, 983102, 536870914, 983103, 10, 983104, 10, 983105, 10, 983106, 10, 983107, 10, 983108, 10, 983109, 10, 983110, 10, 983111, 10, 983112, 10, 983113, 10, 983114, 10, 983115, 10, 983116, 10, 983117, 10, 1048576, 2, 1048578, 8, 1048581, 8, 1048584, 536870919, 1048586, 536870925, 1048587, 13, 1048600, 536870925, 1048601, 13, 1048604, 9, 1048608, 536870925, 1048609, 536870923, 1048610, 536870923, 1048611, 536870923, 1048612, 10, 1048613, 10, 1048614, 10, 1048615, 10, 1048616, 10, 1048617, 10, 1048618, 10, 1048619, 10, 1048620, 4, 1048621, 1, 1048630, 536870921, 1048631, 8, 1048638, 536870914, 1048639, 10, 1048640, 10, 1048641, 10, 1048642, 10, 1048643, 10, 1048644, 10, 1048645, 10, 1048646, 10, 1048647, 10, 1048648, 10, 1048649, 10, 1048650, 10, 1048651, 10, 1048652, 10, 1048653, 10, 1114112, 4, 1114113, 0, 1114114, 6, 1114115, 0, 1114116, 0, 1114117, 6, 1114118, 1, 1114120, 536870920, 1114128, 536870913, 1114129, 5, 1114130, 536870917, 1114131, 5, 1114132, 0, 1114133, 1, 1114140, 7, 1114141, 536870921, 1114148, 536870914, 1114149, 10, 1114150, 10, 1114151, 10, 1114152, 10, 1114153, 10, 1114154, 10, 1114155, 10, 1114156, 10, 1114157, 2, 1114166, 536870920, 1114167, 8, 1114174, 536870914, 1114175, 10, 1114176, 10, 1114177, 10, 1114178, 10, 1114179, 10, 1114180, 10, 1114181, 10, 1114182, 10, 1114183, 10, 1114184, 10, 1114185, 10, 1114186, 10, 1114187, 10, 1114188, 10, 1179648, 10, 1179649, 10, 1179650, 10, 1179651, 10, 1179652, 10, 1179653, 10, 1179654, 2, 1179656, 536870919, 1179663, 536870915, 1179665, 10, 1179666, 10, 1179667, 10, 1179668, 10, 1179669, 4, 1179670, 12, 1179675, 9, 1179676, 8, 1179677, 8, 1179684, 536870914, 1179685, 10, 1179686, 10, 1179687, 10, 1179688, 10, 1179689, 10, 1179690, 10, 1179691, 10, 1179692, 10, 1179693, 4, 1179694, 1, 1179701, 9, 1179702, 536870919, 1179703, 7, 1179710, 536870914, 1179711, 10, 1179712, 10, 1179713, 10, 1179714, 10, 1179715, 10, 1179716, 10, 1179717, 10, 1179718, 10, 1179719, 10, 1179720, 10, 1179721, 10, 1179722, 10, 1245184, 10, 1245185, 10, 1245186, 10, 1245187, 10, 1245188, 10, 1245189, 10, 1245190, 2, 1245192, 536870919, 1245199, 536870913, 1245200, 536870916, 1245201, 10, 1245202, 10, 1245203, 10, 1245204, 10, 1245205, 10, 1245207, 1, 1245211, 7, 1245212, 7, 1245213, 536870920, 1245220, 536870914, 1245221, 10, 1245222, 10, 1245223, 10, 1245224, 10, 1245225, 10, 1245226, 10, 1245227, 10, 1245228, 10, 1245229, 10, 1245230, 2, 1245237, 8, 1245238, 536870919, 1245239, 8, 1245240, 536870921, 1245246, 536870914, 1245247, 10, 1245248, 10, 1245249, 10, 1245250, 10, 1245251, 10, 1245252, 10, 1245253, 10, 1245254, 10, 1245255, 10, 1245256, 10, 1245257, 10, 1245258, 10, 1310720, 10, 1310721, 10, 1310722, 10, 1310723, 10, 1310724, 10, 1310725, 10, 1310726, 2, 1310728, 536870920, 1310730, 536870913, 1310731, 1, 1310734, 536870913, 1310735, 536870916, 1310736, 10, 1310737, 10, 1310738, 10, 1310739, 10, 1310740, 10, 1310741, 10, 1310742, 10, 1310743, 4, 1310744, 1, 1310747, 8, 1310748, 7, 1310749, 536870919, 1310756, 536870914, 1310757, 10, 1310758, 10, 1310759, 10, 1310760, 10, 1310761, 10, 1310762, 10, 1310763, 10, 1310764, 10, 1310765, 10, 1310766, 4, 1310767, 5, 1310768, 12, 1310773, 7, 1310774, 536870919, 1310775, 7, 1310776, 536870919, 1310782, 536870914, 1310783, 10, 1310784, 10, 1310785, 10, 1310786, 10, 1310787, 10, 1310788, 10, 1310789, 10, 1310790, 10, 1310791, 10, 1310792, 10, 1310793, 10, 1376256, 10, 1376257, 10, 1376258, 10, 1376259, 10, 1376260, 10, 1376261, 10, 1376262, 4, 1376263, 0, 1376264, 0, 1376265, 0, 1376266, 536870916, 1376267, 4, 1376268, 0, 1376269, 0, 1376270, 536870916, 1376271, 10, 1376272, 10, 1376273, 10, 1376274, 10, 1376275, 10, 1376276, 10, 1376277, 10, 1376278, 10, 1376279, 10, 1376280, 4, 1376281, 12, 1376283, 8, 1376284, 8, 1376285, 536870920, 1376287, 536870924, 1376288, 0, 1376289, 5, 1376290, 536870917, 1376291, 0, 1376292, 536870916, 1376293, 10, 1376294, 10, 1376295, 10, 1376296, 10, 1376297, 10, 1376298, 10, 1376299, 10, 1376300, 10, 1376301, 10, 1376302, 10, 1376303, 10, 1376305, 12, 1376309, 7, 1376310, 536870920, 1376311, 7, 1376312, 536870920, 1376318, 536870914, 1376319, 10, 1376320, 10, 1376321, 10, 1376322, 10, 1376323, 10, 1376324, 10, 1376325, 10, 1376326, 10, 1376327, 10, 1376328, 10, 1441792, 10, 1441793, 10, 1441794, 10, 1441795, 10, 1441796, 10, 1441797, 10, 1441798, 10, 1441799, 10, 1441800, 10, 1441801, 10, 1441802, 10, 1441803, 10, 1441804, 10, 1441805, 10, 1441806, 10, 1441807, 10, 1441808, 10, 1441809, 10, 1441810, 10, 1441811, 10, 1441812, 10, 1441813, 10, 1441814, 10, 1441815, 10, 1441816, 10, 1441818, 0, 1441819, 6, 1441820, 6, 1441821, 536870918, 1441822, 5, 1441824, 10, 1441825, 10, 1441826, 10, 1441827, 10, 1441828, 10, 1441829, 10, 1441830, 10, 1441831, 10, 1441832, 10, 1441833, 10, 1441834, 10, 1441835, 10, 1441836, 10, 1441837, 10, 1441838, 10, 1441839, 10, 1441840, 10, 1441842, 0, 1441843, 0, 1441844, 0, 1441845, 6, 1441846, 536870918, 1441847, 6, 1441848, 536870918, 1441849, 0, 1441850, 5, 1441851, 536870917, 1441852, 5, 1441853, 0, 1441854, 536870916, 1441855, 10, 1441856, 10, 1441857, 10, 1441858, 10, 1441859, 10, 1441860, 10, 1441861, 10, 1441862, 10, 1441863, 10, 1507328, 10, 1507329, 10, 1507330, 10, 1507331, 10, 1507332, 10, 1507333, 10, 1507334, 10, 1507335, 10, 1507336, 10, 1507337, 10, 1507338, 10, 1507339, 10, 1507340, 10, 1507341, 10, 1507342, 10, 1507343, 10, 1507344, 10, 1507345, 10, 1507346, 10, 1507347, 10, 1507348, 10, 1507349, 10, 1507350, 10, 1507351, 10, 1507352, 10, 1507353, 10, 1507354, 10, 1507355, 10, 1507356, 10, 1507357, 10, 1507358, 10, 1507359, 10, 1507360, 10, 1507361, 10, 1507362, 10, 1507363, 10, 1507364, 10, 1507365, 10, 1507366, 10, 1507367, 10, 1507368, 10, 1507369, 10, 1507370, 10, 1507371, 10, 1507372, 10, 1507373, 10, 1507374, 10, 1507375, 10, 1507376, 10, 1507377, 10, 1507378, 10, 1507379, 10, 1507380, 10, 1507381, 10, 1507382, 10, 1507383, 10, 1507384, 10, 1507385, 10, 1507386, 10, 1507387, 10, 1507388, 10, 1507389, 10, 1507390, 10, 1507391, 10, 1507392, 10, 1507393, 10, 1507394, 10, 1507395, 10, 1507396, 10, 1507397, 10, 1507398, 10, 1507399, 10, 1572864, 10, 1572865, 10, 1572866, 10, 1572867, 10, 1572868, 10, 1572869, 10, 1572870, 10, 1572871, 10, 1572872, 10, 1572873, 10, 1572874, 10, 1572875, 10, 1572876, 10, 1572877, 10, 1572878, 10, 1572879, 10, 1572880, 10, 1572881, 10, 1572882, 10, 1572883, 10, 1572884, 10, 1572885, 10, 1572886, 10, 1572887, 10, 1572888, 10, 1572889, 10, 1572890, 10, 1572891, 10, 1572892, 10, 1572893, 10, 1572894, 10, 1572895, 10, 1572896, 10, 1572897, 10, 1572898, 10, 1572899, 10, 1572900, 10, 1572901, 10, 1572902, 10, 1572903, 10, 1572904, 10, 1572905, 10, 1572906, 10, 1572907, 10, 1572908, 10, 1572909, 10, 1572910, 10, 1572911, 10, 1572912, 10, 1572913, 10, 1572914, 10, 1572915, 10, 1572916, 10, 1572917, 10, 1572918, 10, 1572919, 10, 1572920, 10, 1572921, 10, 1572922, 10, 1572923, 10, 1572924, 10, 1572925, 10, 1572926, 10, 1572927, 10, 1572928, 10, 1572929, 10, 1572930, 10, 1572931, 10, 1572932, 10, 1572933, 10, 1572934, 10, 1572935, 10, 1638400, 10, 1638401, 10, 1638402, 10, 1638403, 10, 1638404, 10, 1638405, 10, 1638406, 10, 1638407, 10, 1638408, 10, 1638409, 10, 1638410, 10, 1638411, 10, 1638412, 10, 1638413, 10, 1638414, 10, 1638415, 10, 1638416, 10, 1638417, 10, 1638418, 10, 1638419, 10, 1638420, 10, 1638421, 10, 1638422, 10, 1638423, 10, 1638424, 10, 1638425, 10, 1638426, 10, 1638427, 10, 1638428, 10, 1638429, 10, 1638430, 10, 1638431, 10, 1638432, 10, 1638433, 10, 1638434, 10, 1638435, 10, 1638436, 10, 1638437, 10, 1638438, 10, 1638439, 10, 1638440, 10, 1638441, 10, 1638442, 10, 1638443, 10, 1638444, 10, 1638445, 10, 1638446, 10, 1638447, 10, 1638448, 10, 1638449, 10, 1638450, 10, 1638451, 10, 1638452, 10, 1638453, 10, 1638454, 10, 1638455, 10, 1638456, 10, 1638457, 10, 1638458, 10, 1638459, 10, 1638460, 10, 1638461, 10, 1638462, 10, 1638463, 10, 1638464, 10, 1638465, 10, 1638466, 10, 1638467, 10, 1638468, 10, 1638469, 10, 1638470, 10, 1638471, 10, 1703952, 10, 1703953, 10, 1703954, 10, 1703955, 10, 1703956, 10, 1703957, 10, 1703958, 10, 1703959, 10, 1703960, 10, 1703961, 10, 1703962, 10, 1703963, 10, 1703964, 10, 1703965, 10, 1703966, 10, 1703967, 10, 1703968, 10, 1703969, 10, 1703970, 10, 1703971, 10, 1703972, 10, 1703973, 10, 1703974, 10, 1703975, 10, 1703976, 10, 1703977, 10, 1703978, 10, 1703979, 10, 1703980, 10, 1703981, 10, 1703982, 10, 1703983, 10, 1703984, 10, 1703985, 10, 1703986, 10, 1703987, 10, 1703988, 10, 1703989, 10, 1703990, 10, 1703991, 10, 1703992, 10, 1703993, 10, 1703994, 10, 1703995, 10, 1703996, 10, 1703997, 10, 1703998, 10, 1703999, 10, 1704000, 10, 1704001, 10, 1704002, 10, 1704003, 10, 1704004, 10, 1704005, 10, 1704006, 10, 1704007, 10, 1769488, 10, 1769489, 10, 1769490, 10, 1769491, 10, 1769492, 10, 1769493, 10, 1769494, 10, 1769495, 10, 1769496, 10, 1769497, 10, 1769498, 10, 1769499, 10, 1769500, 10, 1769501, 10, 1769502, 10, 1769503, 10, 1769504, 10, 1769505, 10, 1769506, 10, 1769507, 10, 1769508, 10, 1769509, 10, 1769510, 10, 1769511, 10, 1769512, 10, 1769513, 10, 1769514, 10, 1769515, 10, 1769516, 10, 1769517, 10, 1769518, 10, 1769519, 10, 1769520, 10, 1769521, 10, 1769522, 10, 1769523, 10, 1769524, 10, 1769525, 10, 1769526, 10, 1769527, 10, 1769528, 10, 1769529, 10, 1769530, 10, 1769531, 10, 1769532, 10, 1769533, 10, 1769534, 10, 1769535, 10, 1769536, 10, 1769537, 10, 1769538, 10, 1769539, 10, 1769540, 10, 1769541, 10 "_edit_lock_" @@ -483,12 +487,10 @@ "3D" - "deflight_rot_y" - 0.628319 - "zfar" - 500 "fov" 45 + "zfar" + 500 "viewports" @@ -556,6 +558,8 @@ 0, 0, 0 + "deflight_rot_y" + 0.628319 "default_light" True "viewport_mode" @@ -806,7 +810,6 @@ "2D" - False 2 834.664, 1309.6 @@ -1000,7 +1003,7 @@ -1 "nodes" - -1, -1, 1, 0, -1, 2, 2, 0, 3, 1, 0, 0, 0, 5, 4, -1, 21, 2, 0, 6, 2, 7, 3, 8, 3, 9, 4, 10, 5, 11, 6, 12, 7, 13, 2, 14, 7, 15, 8, 16, 9, 17, 10, 18, 11, 19, 12, 20, 7, 21, 3, 22, 5, 23, 13, 24, 14, 3, 15, 0, 0, 0, 1, 25, -1, 2, 2, 0, 3, 16, 0, 2, 0, 27, 26, 17, 3, 2, 0, 9, 18, 3, 19, 0, 2, 0, 27, 28, 17, 3, 2, 0, 9, 20, 3, 19, 0, 2, 0, 27, 29, 17, 3, 2, 0, 9, 21, 3, 19, 0, 2, 0, 27, 30, 17, 3, 2, 0, 9, 22, 3, 19, 0, 2, 0, 27, 31, 17, 3, 2, 0, 9, 23, 3, 19, 0, 2, 0, 27, 32, 17, 3, 2, 0, 9, 24, 3, 19, 0, 2, 0, 27, 33, 17, 3, 2, 0, 9, 25, 3, 19, 0, 2, 0, 27, 34, 17, 3, 2, 0, 9, 26, 3, 19, 0, 2, 0, 27, 35, 17, 3, 2, 0, 9, 27, 3, 19, 0, 2, 0, 27, 36, 17, 3, 2, 0, 9, 28, 3, 19, 0, 2, 0, 27, 37, 17, 3, 2, 0, 9, 29, 3, 19, 0, 2, 0, 27, 38, 17, 3, 2, 0, 9, 30, 3, 19, 0, 2, 0, 27, 39, 17, 3, 2, 0, 9, 31, 3, 19, 0, 2, 0, 27, 40, 17, 3, 2, 0, 9, 32, 3, 19, 0, 2, 0, 27, 41, 17, 3, 2, 0, 9, 33, 3, 19, 0, 2, 0, 27, 42, 17, 3, 2, 0, 9, 34, 3, 19, 0, 2, 0, 27, 43, 17, 3, 2, 0, 9, 35, 3, 19, 0, 2, 0, 27, 44, 17, 3, 2, 0, 9, 36, 3, 19, 0, 2, 0, 27, 45, 17, 3, 2, 0, 9, 37, 3, 19, 0, 2, 0, 27, 46, 17, 3, 2, 0, 9, 38, 3, 19, 0, 2, 0, 27, 47, 17, 3, 2, 0, 9, 39, 3, 19, 0, 2, 0, 27, 48, 17, 3, 2, 0, 9, 40, 3, 19, 0, 2, 0, 27, 49, 17, 3, 2, 0, 9, 41, 3, 19, 0, 2, 0, 27, 50, 17, 3, 2, 0, 9, 42, 3, 19, 0, 2, 0, 27, 51, 17, 3, 2, 0, 9, 43, 3, 19, 0, 2, 0, 27, 52, 17, 3, 2, 0, 9, 44, 3, 19, 0, 2, 0, 27, 53, 17, 3, 2, 0, 9, 45, 3, 19, 0, 2, 0, 27, 54, 17, 3, 2, 0, 9, 46, 3, 19, 0, 2, 0, 27, 55, 17, 3, 2, 0, 9, 47, 3, 19, 0, 2, 0, 27, 56, 17, 3, 2, 0, 9, 48, 3, 19, 0, 2, 0, 27, 57, 17, 3, 2, 0, 9, 49, 3, 19, 0, 2, 0, 27, 58, 17, 3, 2, 0, 9, 50, 3, 19, 0, 2, 0, 27, 59, 17, 3, 2, 0, 9, 51, 3, 19, 0, 2, 0, 27, 60, 17, 3, 2, 0, 9, 52, 3, 19, 0, 2, 0, 27, 61, 17, 3, 2, 0, 9, 53, 3, 19, 0, 2, 0, 27, 62, 17, 3, 2, 0, 9, 54, 3, 19, 0, 2, 0, 27, 63, 17, 3, 2, 0, 9, 55, 3, 19, 0, 2, 0, 27, 64, 17, 3, 2, 0, 9, 56, 3, 19, 0, 2, 0, 27, 65, 17, 3, 2, 0, 9, 57, 3, 19, 0, 2, 0, 27, 66, 17, 3, 2, 0, 9, 58, 3, 19, 0, 2, 0, 27, 67, 17, 3, 2, 0, 9, 59, 3, 19, 0, 2, 0, 27, 68, 17, 3, 2, 0, 9, 60, 3, 19, 0, 0, 0, 70, 69, 61, 3, 2, 0, 9, 62, 3, 63, 0, 0, 0, 1, 71, -1, 1, 2, 0, 0, 46, 0, 73, 72, 64, 5, 2, 0, 9, 65, 3, 66, 74, 67, 75, 68, 0, 46, 0, 73, 76, 64, 5, 2, 0, 9, 69, 3, 66, 74, 70, 75, 71, 0, 46, 0, 73, 77, 64, 5, 2, 0, 9, 72, 3, 66, 74, 73, 75, 71, 0, 46, 0, 73, 78, 74, 3, 2, 0, 9, 75, 3, 76, 0, 0, 0, 80, 79, -1, 7, 2, 0, 81, 77, 82, 78, 83, 2, 84, 79, 85, 2, 86, 78, 0, 0, 0, 1, 87, -1, 1, 2, 0, 0, 52, 0, 70, 88, 80, 3, 2, 0, 9, 81, 3, 82, 0, 52, 0, 70, 89, 80, 3, 2, 0, 9, 83, 3, 82, 0, 52, 0, 70, 90, 80, 3, 2, 0, 9, 84, 3, 82, 0, 52, 0, 70, 91, 80, 3, 2, 0, 9, 85, 3, 82, 0, 52, 0, 70, 92, 80, 3, 2, 0, 9, 86, 3, 82, 0, 52, 0, 70, 93, 80, 3, 2, 0, 9, 87, 3, 82, 0, 52, 0, 70, 94, 80, 3, 2, 0, 9, 88, 3, 82, 0, 52, 0, 70, 95, 80, 3, 2, 0, 9, 89, 3, 82, 0, 52, 0, 70, 96, 80, 3, 2, 0, 9, 90, 3, 82, 0, 52, 0, 70, 97, 80, 3, 2, 0, 9, 91, 3, 82, 0, 52, 0, 70, 98, 80, 3, 2, 0, 9, 92, 3, 82, 0, 0, 0, 100, 99, 93, 2, 2, 0, 3, 94, 0, 0, 0, 101, 101, -1, 29, 2, 0, 6, 2, 7, 3, 8, 3, 102, 95, 103, 96, 104, 97, 105, 98, 106, 0, 107, 0, 108, 0, 109, 0, 110, 2, 111, 2, 112, 12, 113, 3, 114, 5, 115, 99, 116, 3, 117, 100, 118, 5, 119, 78, 120, 78, 121, 101, 122, 7, 123, 7, 124, 2, 125, 78, 126, 102, 0 + -1, -1, 1, 0, -1, 2, 2, 0, 3, 1, 0, 0, 0, 5, 4, -1, 24, 2, 0, 6, 2, 7, 3, 8, 3, 9, 4, 10, 5, 11, 6, 12, 7, 13, 8, 14, 2, 15, 8, 16, 9, 17, 10, 18, 11, 19, 12, 20, 13, 21, 8, 22, 14, 23, 14, 24, 3, 25, 6, 26, 4, 27, 15, 3, 16, 0, 0, 0, 1, 28, -1, 2, 2, 0, 3, 17, 0, 2, 0, 30, 29, 18, 3, 2, 0, 10, 19, 3, 20, 0, 2, 0, 30, 31, 18, 3, 2, 0, 10, 21, 3, 20, 0, 2, 0, 30, 32, 18, 3, 2, 0, 10, 22, 3, 20, 0, 2, 0, 30, 33, 18, 3, 2, 0, 10, 23, 3, 20, 0, 2, 0, 30, 34, 18, 3, 2, 0, 10, 24, 3, 20, 0, 2, 0, 30, 35, 18, 3, 2, 0, 10, 25, 3, 20, 0, 2, 0, 30, 36, 18, 3, 2, 0, 10, 26, 3, 20, 0, 2, 0, 30, 37, 18, 3, 2, 0, 10, 27, 3, 20, 0, 2, 0, 30, 38, 18, 3, 2, 0, 10, 28, 3, 20, 0, 2, 0, 30, 39, 18, 3, 2, 0, 10, 29, 3, 20, 0, 2, 0, 30, 40, 18, 3, 2, 0, 10, 30, 3, 20, 0, 2, 0, 30, 41, 18, 3, 2, 0, 10, 31, 3, 20, 0, 2, 0, 30, 42, 18, 3, 2, 0, 10, 32, 3, 20, 0, 2, 0, 30, 43, 18, 3, 2, 0, 10, 33, 3, 20, 0, 2, 0, 30, 44, 18, 3, 2, 0, 10, 34, 3, 20, 0, 2, 0, 30, 45, 18, 3, 2, 0, 10, 35, 3, 20, 0, 2, 0, 30, 46, 18, 3, 2, 0, 10, 36, 3, 20, 0, 2, 0, 30, 47, 18, 3, 2, 0, 10, 37, 3, 20, 0, 2, 0, 30, 48, 18, 3, 2, 0, 10, 38, 3, 20, 0, 2, 0, 30, 49, 18, 3, 2, 0, 10, 39, 3, 20, 0, 2, 0, 30, 50, 18, 3, 2, 0, 10, 40, 3, 20, 0, 2, 0, 30, 51, 18, 3, 2, 0, 10, 41, 3, 20, 0, 2, 0, 30, 52, 18, 3, 2, 0, 10, 42, 3, 20, 0, 2, 0, 30, 53, 18, 3, 2, 0, 10, 43, 3, 20, 0, 2, 0, 30, 54, 18, 3, 2, 0, 10, 44, 3, 20, 0, 2, 0, 30, 55, 18, 3, 2, 0, 10, 45, 3, 20, 0, 2, 0, 30, 56, 18, 3, 2, 0, 10, 46, 3, 20, 0, 2, 0, 30, 57, 18, 3, 2, 0, 10, 47, 3, 20, 0, 2, 0, 30, 58, 18, 3, 2, 0, 10, 48, 3, 20, 0, 2, 0, 30, 59, 18, 3, 2, 0, 10, 49, 3, 20, 0, 2, 0, 30, 60, 18, 3, 2, 0, 10, 50, 3, 20, 0, 2, 0, 30, 61, 18, 3, 2, 0, 10, 51, 3, 20, 0, 2, 0, 30, 62, 18, 3, 2, 0, 10, 52, 3, 20, 0, 2, 0, 30, 63, 18, 3, 2, 0, 10, 53, 3, 20, 0, 2, 0, 30, 64, 18, 3, 2, 0, 10, 54, 3, 20, 0, 2, 0, 30, 65, 18, 3, 2, 0, 10, 55, 3, 20, 0, 2, 0, 30, 66, 18, 3, 2, 0, 10, 56, 3, 20, 0, 2, 0, 30, 67, 18, 3, 2, 0, 10, 57, 3, 20, 0, 2, 0, 30, 68, 18, 3, 2, 0, 10, 58, 3, 20, 0, 2, 0, 30, 69, 18, 3, 2, 0, 10, 59, 3, 20, 0, 2, 0, 30, 70, 18, 3, 2, 0, 10, 60, 3, 20, 0, 2, 0, 30, 71, 18, 3, 2, 0, 10, 61, 3, 20, 0, 0, 0, 73, 72, 62, 3, 2, 0, 10, 63, 3, 64, 0, 0, 0, 1, 74, -1, 1, 2, 0, 0, 46, 0, 76, 75, 65, 5, 2, 0, 10, 66, 3, 67, 77, 68, 78, 69, 0, 46, 0, 76, 79, 65, 5, 2, 0, 10, 70, 3, 67, 77, 71, 78, 72, 0, 46, 0, 76, 80, 65, 5, 2, 0, 10, 73, 3, 67, 77, 74, 78, 72, 0, 46, 0, 76, 81, 75, 3, 2, 0, 10, 76, 3, 77, 0, 0, 0, 83, 82, -1, 7, 2, 0, 84, 78, 85, 14, 86, 2, 87, 79, 88, 2, 89, 14, 0, 0, 0, 1, 90, -1, 1, 2, 0, 0, 52, 0, 73, 91, 80, 3, 2, 0, 10, 81, 3, 82, 0, 52, 0, 73, 92, 80, 3, 2, 0, 10, 83, 3, 82, 0, 52, 0, 73, 93, 80, 3, 2, 0, 10, 84, 3, 82, 0, 52, 0, 73, 94, 80, 3, 2, 0, 10, 85, 3, 82, 0, 52, 0, 73, 95, 80, 3, 2, 0, 10, 86, 3, 82, 0, 52, 0, 73, 96, 80, 3, 2, 0, 10, 87, 3, 82, 0, 52, 0, 73, 97, 80, 3, 2, 0, 10, 88, 3, 82, 0, 52, 0, 73, 98, 80, 3, 2, 0, 10, 89, 3, 82, 0, 52, 0, 73, 99, 80, 3, 2, 0, 10, 90, 3, 82, 0, 52, 0, 73, 100, 80, 3, 2, 0, 10, 91, 3, 82, 0, 52, 0, 73, 101, 80, 3, 2, 0, 10, 92, 3, 82, 0, 0, 0, 103, 102, 93, 2, 2, 0, 3, 94, 0, 0, 0, 104, 104, -1, 30, 2, 0, 6, 2, 7, 3, 8, 3, 9, 4, 105, 95, 106, 96, 107, 97, 108, 98, 109, 0, 110, 0, 111, 0, 112, 0, 113, 2, 114, 2, 115, 13, 116, 3, 117, 6, 118, 99, 119, 3, 120, 100, 121, 6, 122, 14, 123, 14, 124, 101, 125, 8, 126, 8, 127, 2, 128, 14, 129, 102, 0 "conns" diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 49fae098a..a21b0775e 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -4288,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 { @@ -6944,7 +6944,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]; @@ -6961,25 +6961,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); @@ -7006,7 +7001,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 @@ -7076,7 +7071,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; @@ -7128,6 +7123,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); @@ -7140,7 +7136,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); @@ -7148,9 +7144,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); @@ -7369,8 +7363,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() { @@ -7839,8 +7837,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); @@ -10567,7 +10583,7 @@ void RasterizerGLES2::init() { glBindBuffer(GL_ARRAY_BUFFER,0); //unbind - + using_canvas_bg=false; _update_framebuffer(); DEBUG_TEST_ERROR("Initializing"); } diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index f09714f50..b7895ad82 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -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;i0) { completion_index=0; completion_current=completion_options[completion_index]; @@ -1354,7 +1354,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { return; } - if (k.scancode==KEY_END) { + if (k.scancode==KEY_END && completion_indexdisable_environment=p_disable; + +} + void VisualServerRaster::viewport_attach_camera(RID p_viewport,RID p_camera) { VS_CHANGED; @@ -6267,6 +6278,20 @@ void VisualServerRaster::_process_sampled_light(const Transform& p_camera,Instan } +void VisualServerRaster::_render_no_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario) { + RID environment; + if (p_scenario->environment.is_valid()) + environment=p_scenario->environment; + else + environment=p_scenario->fallback_environment; + + rasterizer->set_camera(Transform(),CameraMatrix()); + rasterizer->begin_scene(p_viewport->viewport_data,environment,p_scenario->debug); + rasterizer->set_viewport(viewport_rect); + rasterizer->end_scene(); +} + + void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario) { @@ -6889,6 +6914,23 @@ void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_trans } +void VisualServerRaster::_draw_viewport_camera(Viewport *p_viewport,bool p_ignore_camera) { + + + Camera *camera=NULL; + if (camera_owner.owns( p_viewport->camera )) + camera=camera_owner.get( p_viewport->camera ); + Scenario *scenario = scenario_owner.get( p_viewport->scenario ); + + _update_instances(); // check dirty instances before rendering + + if (p_ignore_camera) + _render_no_camera(p_viewport, camera,scenario ); + else + _render_camera(p_viewport, camera,scenario ); + +} + void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ofs_y,int p_parent_w,int p_parent_h) { ViewportRect desired_rect=p_viewport->rect; @@ -6923,14 +6965,31 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ /* Camera should always be BEFORE any other 3D */ - if (!p_viewport->hide_scenario && camera_owner.owns(p_viewport->camera) && scenario_owner.owns(p_viewport->scenario)) { + bool scenario_draw_canvas_bg=false; + int scenario_canvas_max_layer=0; - Camera *camera = camera_owner.get( p_viewport->camera ); - Scenario *scenario = scenario_owner.get( p_viewport->scenario ); + if (!p_viewport->hide_canvas && !p_viewport->disable_environment && scenario_owner.owns(p_viewport->scenario)) { - _update_instances(); // check dirty instances before rendering + Scenario *scenario=scenario_owner.get(p_viewport->scenario); + if (scenario->environment.is_valid()) { + if (rasterizer->is_environment(scenario->environment)) { + scenario_draw_canvas_bg=rasterizer->environment_get_background(scenario->environment)==VS::ENV_BG_CANVAS; + scenario_canvas_max_layer=rasterizer->environment_get_background_param(scenario->environment,VS::ENV_BG_PARAM_CANVAS_MAX_LAYER); + } + } + } + + bool can_draw_3d=!p_viewport->hide_scenario && camera_owner.owns(p_viewport->camera) && scenario_owner.owns(p_viewport->scenario); - _render_camera(p_viewport, camera,scenario ); + + if (scenario_draw_canvas_bg) { + + rasterizer->begin_canvas_bg(); + } + + if (!scenario_draw_canvas_bg && can_draw_3d) { + + _draw_viewport_camera(p_viewport,false); } else if (true /*|| !p_viewport->canvas_list.empty()*/){ @@ -6940,7 +6999,10 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ rasterizer->clear_viewport(Color(0,0,0,0)); } else { - rasterizer->clear_viewport(clear_color); + Color cc=clear_color; + if (scenario_draw_canvas_bg) + cc.a=0; + rasterizer->clear_viewport(cc); } p_viewport->render_target_clear=false; } @@ -7040,6 +7102,16 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ rasterizer->set_viewport(viewport_rect); //must reset viewport afterwards } + + + + if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer>scenario_canvas_max_layer) { + + _draw_viewport_camera(p_viewport,!can_draw_3d); + scenario_draw_canvas_bg=false; + + } + for (Map::Element *E=canvas_map.front();E;E=E->next()) { @@ -7061,8 +7133,20 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ _render_canvas( E->get()->canvas,xform,canvas_lights ); i++; + if (scenario_draw_canvas_bg && E->key().layer>=scenario_canvas_max_layer) { + _draw_viewport_camera(p_viewport,!can_draw_3d); + scenario_draw_canvas_bg=false; + } + + } + if (scenario_draw_canvas_bg) { + _draw_viewport_camera(p_viewport,!can_draw_3d); + scenario_draw_canvas_bg=false; + } + + //rasterizer->canvas_debug_viewport_shadows(lights_with_shadow); } diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 5c0d48645..b1970c55b 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -489,6 +489,8 @@ class VisualServerRaster : public VisualServer { bool render_target_vflip; bool render_target_clear_on_new_frame; bool render_target_clear; + bool disable_environment; + Image capture; bool rendered_in_prev_frame; @@ -515,7 +517,7 @@ class VisualServerRaster : public VisualServer { SelfList update_list; - Viewport() : update_list(this) { transparent_bg=false; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; queue_capture=false; rendered_in_prev_frame=false; render_target_vflip=false; render_target_clear_on_new_frame=true; render_target_clear=true;} + Viewport() : update_list(this) { transparent_bg=false; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; queue_capture=false; rendered_in_prev_frame=false; render_target_vflip=false; render_target_clear_on_new_frame=true; render_target_clear=true; disable_environment=false; } }; SelfList::List viewport_update_list; @@ -626,6 +628,7 @@ class VisualServerRaster : public VisualServer { void _cull_room(Camera *p_camera, Instance *p_room,Instance *p_from_portal=NULL); void _process_sampled_light(const Transform &p_camera, Instance *p_sampled_light, bool p_linear_colorspace); + void _render_no_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario); void _render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario); static void _render_canvas_item_viewport(VisualServer* p_self,void *p_vp,const Rect2& p_rect); void _render_canvas_item_tree(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, const Color &p_modulate, Rasterizer::CanvasLight *p_lights); @@ -643,6 +646,7 @@ class VisualServerRaster : public VisualServer { int changes; bool draw_extra_frame; + void _draw_viewport_camera(Viewport *p_viewport, bool p_ignore_camera); void _draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ofs_y,int p_parent_w,int p_parent_h); void _draw_viewports(); void _draw_cursors_and_margins(); @@ -983,6 +987,7 @@ public: virtual void viewport_render_target_clear(RID p_viewport); virtual void viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect); + virtual void viewport_queue_screen_capture(RID p_viewport); virtual Image viewport_get_screen_capture(RID p_viewport) const; @@ -991,6 +996,7 @@ public: virtual void viewport_set_hide_scenario(RID p_viewport,bool p_hide); virtual void viewport_set_hide_canvas(RID p_viewport,bool p_hide); + virtual void viewport_set_disable_environment(RID p_viewport,bool p_disable); virtual void viewport_attach_camera(RID p_viewport,RID p_camera); virtual void viewport_set_scenario(RID p_viewport,RID p_scenario); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 684807582..562b9ffeb 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -982,6 +982,7 @@ public: FUNC2(viewport_set_hide_canvas,RID,bool ); FUNC2(viewport_attach_camera,RID,RID ); FUNC2(viewport_set_scenario,RID,RID ); + FUNC2(viewport_set_disable_environment,RID,bool ); FUNC1RC(RID,viewport_get_attached_camera,RID); FUNC1RC(RID,viewport_get_scenario,RID ); diff --git a/servers/visual_server.h b/servers/visual_server.h index f4896f984..c748839d1 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -704,6 +704,7 @@ public: virtual void viewport_set_hide_scenario(RID p_viewport,bool p_hide)=0; virtual void viewport_set_hide_canvas(RID p_viewport,bool p_hide)=0; + virtual void viewport_set_disable_environment(RID p_viewport,bool p_disable)=0; virtual void viewport_attach_camera(RID p_viewport,RID p_camera)=0; virtual void viewport_set_scenario(RID p_viewport,RID p_scenario)=0; @@ -734,8 +735,7 @@ public: ENV_BG_COLOR, ENV_BG_TEXTURE, ENV_BG_CUBEMAP, - ENV_BG_TEXTURE_RGBE, - ENV_BG_CUBEMAP_RGBE, + ENV_BG_CANVAS, ENV_BG_MAX }; @@ -744,6 +744,7 @@ public: enum EnvironmentBGParam { + ENV_BG_PARAM_CANVAS_MAX_LAYER, ENV_BG_PARAM_COLOR, ENV_BG_PARAM_TEXTURE, ENV_BG_PARAM_CUBEMAP, diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 3d42867d9..5e571373e 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -218,6 +218,7 @@ void EditorNode::_notification(int p_what) { } if (p_what==NOTIFICATION_ENTER_TREE) { + //MessageQueue::get_singleton()->push_call(this,"_get_scene_metadata"); get_tree()->set_editor_hint(true); get_tree()->get_root()->set_as_audio_listener(false); @@ -231,6 +232,8 @@ void EditorNode::_notification(int p_what) { VisualServer::get_singleton()->viewport_set_hide_scenario(get_scene_root()->get_viewport(),true); VisualServer::get_singleton()->viewport_set_hide_canvas(get_scene_root()->get_viewport(),true); + VisualServer::get_singleton()->viewport_set_disable_environment(get_viewport()->get_viewport_rid(),true); + _editor_select(1); if (defer_load_scene!="") { @@ -3412,6 +3415,8 @@ EditorNode::EditorNode() { scene_root = memnew( Viewport ); + + //scene_root_base->add_child(scene_root); scene_root->set_meta("_editor_disable_input",true); VisualServer::get_singleton()->viewport_set_hide_scenario(scene_root->get_viewport(),true); diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index f760ab1cb..078a177ca 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -651,6 +651,8 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty if (!RES(v).is_null()) { + + menu->add_icon_item(get_icon("EditResource","EditorIcons"),"Edit",OBJ_MENU_EDIT); menu->add_icon_item(get_icon("Del","EditorIcons"),"Clear",OBJ_MENU_CLEAR); menu->add_icon_item(get_icon("Duplicate","EditorIcons"),"Make Unique",OBJ_MENU_MAKE_UNIQUE); @@ -659,6 +661,13 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty menu->add_separator(); menu->add_icon_item(get_icon("Reload","EditorIcons"),"Re-Import",OBJ_MENU_REIMPORT); } + /*if (r.is_valid() && r->get_path().is_resource_file()) { + menu->set_item_tooltip(1,r->get_path()); + } else if (r.is_valid()) { + menu->set_item_tooltip(1,r->get_name()+" ("+r->get_type()+")"); + }*/ + } else { + } @@ -1858,6 +1867,14 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p p_item->set_text(1,"<"+res->get_type()+">"); }; + + if (res.is_valid() && res->get_path().is_resource_file()) { + p_item->set_tooltip(1,res->get_path()); + } else if (res.is_valid()) { + p_item->set_tooltip(1,res->get_name()+" ("+res->get_type()+")"); + } + + if (has_icon(res->get_type(),"EditorIcons")) { p_item->set_icon(0,get_icon(res->get_type(),"EditorIcons")); @@ -2584,6 +2601,13 @@ void PropertyEditor::update_tree() { if (has_icon(res->get_type(),"EditorIcons")) { type=res->get_type(); } + + if (res.is_valid() && res->get_path().is_resource_file()) { + item->set_tooltip(1,res->get_path()); + } else if (res.is_valid()) { + item->set_tooltip(1,res->get_name()+" ("+res->get_type()+")"); + } + } -- cgit v1.2.3-70-g09d2 From db0a71fc58137da99137e9fbea3ee982679c9afd Mon Sep 17 00:00:00 2001 From: rollenrolm Date: Sat, 21 Mar 2015 18:33:32 +0100 Subject: New option to show/hide hidden files --- core/io/file_access_pack.cpp | 4 ++++ core/io/file_access_pack.h | 1 + core/os/dir_access.h | 1 + drivers/unix/dir_access_unix.cpp | 6 ++++++ drivers/unix/dir_access_unix.h | 2 ++ drivers/windows/dir_access_windows.cpp | 9 +++++++++ drivers/windows/dir_access_windows.h | 1 + platform/android/dir_access_android.cpp | 3 +++ platform/android/dir_access_android.h | 1 + platform/android/dir_access_jandroid.cpp | 3 +++ scene/gui/file_dialog.cpp | 19 ++++++++++++++----- tools/editor/editor_dir_dialog.cpp | 22 +++++++++++++++++----- tools/editor/editor_settings.cpp | 1 + 13 files changed, 63 insertions(+), 10 deletions(-) (limited to 'platform') diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index 6e03819aa..afbd7e3d4 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -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(); diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index 5fcc79aaf..2d0cf5b32 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -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(); diff --git a/core/os/dir_access.h b/core/os/dir_access.h index d8672218b..dc56f2308 100644 --- a/core/os/dir_access.h +++ b/core/os/dir_access.h @@ -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; ///< diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index 452d791d9..5f5186543 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -161,6 +161,7 @@ String DirAccessUnix::get_next() { } + _cishidden=(fname!="." && fname!=".." && fname.begins_with(".")); @@ -173,6 +174,11 @@ bool DirAccessUnix::current_is_dir() const { return _cisdir; } +bool DirAccessUnix::current_is_hidden() const { + + return _cishidden; +} + void DirAccessUnix::list_dir_end() { diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h index 119cb5c3f..f6089ccfe 100644 --- a/drivers/unix/dir_access_unix.h +++ b/drivers/unix/dir_access_unix.h @@ -50,12 +50,14 @@ class DirAccessUnix : public DirAccess { String current_dir; bool _cisdir; + bool _cishidden; public: virtual bool list_dir_begin(); ///< This starts dir listing virtual String get_next(); virtual bool current_is_dir() const; + virtual bool current_is_hidden() const; virtual void list_dir_end(); ///< diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index d1e976610..64df801b1 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/drivers/windows/dir_access_windows.cpp @@ -68,6 +68,7 @@ struct DirAccessWindowsPrivate { bool DirAccessWindows::list_dir_begin() { _cisdir=false; + _cishidden=false; if (unicode) { list_dir_end(); @@ -95,6 +96,8 @@ String DirAccessWindows::get_next() { if (unicode) { _cisdir=(p->fu.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); + _cishidden=(p->fu.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN); + String name=p->fu.cFileName; if (FindNextFileW(p->h, &p->fu) == 0) { @@ -108,6 +111,7 @@ String DirAccessWindows::get_next() { #ifndef WINRT_ENABLED _cisdir=(p->fu.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); + _cishidden=(p->fu.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN); String name=p->f.cFileName; @@ -128,6 +132,11 @@ bool DirAccessWindows::current_is_dir() const { return _cisdir; } +bool DirAccessWindows::current_is_hidden() const { + + return _cishidden; +} + void DirAccessWindows::list_dir_end() { if (p->h!=INVALID_HANDLE_VALUE) { diff --git a/drivers/windows/dir_access_windows.h b/drivers/windows/dir_access_windows.h index 36530ba9b..906ce0d06 100644 --- a/drivers/windows/dir_access_windows.h +++ b/drivers/windows/dir_access_windows.h @@ -58,6 +58,7 @@ class DirAccessWindows : public DirAccess { bool unicode; bool _cisdir; + bool _cishidden; public: diff --git a/platform/android/dir_access_android.cpp b/platform/android/dir_access_android.cpp index 60bde61fc..80311e5a0 100644 --- a/platform/android/dir_access_android.cpp +++ b/platform/android/dir_access_android.cpp @@ -79,6 +79,9 @@ bool DirAccessAndroid::current_is_dir() const{ return false; } +bool DirAccessAndroid::current_is_hidden() const{ + return current!="." && current!=".." && current.begins_with("."); +} void DirAccessAndroid::list_dir_end(){ if (aad==NULL) diff --git a/platform/android/dir_access_android.h b/platform/android/dir_access_android.h index a6aead6eb..57683542f 100644 --- a/platform/android/dir_access_android.h +++ b/platform/android/dir_access_android.h @@ -52,6 +52,7 @@ public: virtual bool list_dir_begin(); ///< This starts dir listing 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(); diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp index f32e16e7d..fda4ca735 100644 --- a/platform/android/dir_access_jandroid.cpp +++ b/platform/android/dir_access_jandroid.cpp @@ -105,6 +105,9 @@ bool DirAccessJAndroid::current_is_dir() const{ return true; } +bool DirAccessAndroid::current_is_hidden() const{ + return current!="." && current!=".." && current.begins_with("."); +} void DirAccessJAndroid::list_dir_end(){ if (id==0) diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index fbcfdb69b..47f862a58 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -29,6 +29,8 @@ #include "file_dialog.h" #include "scene/gui/label.h" #include "print_string.h" +#include "os/keyboard.h" +#include "tools/editor/editor_settings.h" FileDialog::GetIconFunc FileDialog::get_icon_func=NULL; @@ -278,13 +280,20 @@ void FileDialog::update_file_list() { List dirs; bool isdir; + bool ishidden; + bool show_hidden = EditorSettings::get_singleton()->get("file_dialog/show_hidden_files"); String item; + while ((item=dir_access->get_next(&isdir))!="") { - - if (!isdir) - files.push_back(item); - else - dirs.push_back(item); + + ishidden = dir_access->current_is_hidden(); + + if (show_hidden || !ishidden) { + if (!isdir) + files.push_back(item); + else + dirs.push_back(item); + } } dirs.sort_custom(); diff --git a/tools/editor/editor_dir_dialog.cpp b/tools/editor/editor_dir_dialog.cpp index eee4125e9..eec452ab7 100644 --- a/tools/editor/editor_dir_dialog.cpp +++ b/tools/editor/editor_dir_dialog.cpp @@ -28,6 +28,9 @@ /*************************************************************************/ #include "editor_dir_dialog.h" #include "os/os.h" +#include "os/keyboard.h" +#include "tools/editor/editor_settings.h" + void EditorDirDialog::_update_dir(TreeItem* p_item) { @@ -39,12 +42,21 @@ void EditorDirDialog::_update_dir(TreeItem* p_item) { da->change_dir(cdir); da->list_dir_begin(); String p=da->get_next(); + + bool ishidden; + bool show_hidden = EditorSettings::get_singleton()->get("file_dialog/show_hidden_files"); + while(p!="") { - if (da->current_is_dir() && !p.begins_with(".")) { - TreeItem *ti = tree->create_item(p_item); - ti->set_text(0,p); - ti->set_icon(0,get_icon("Folder","EditorIcons")); - ti->set_collapsed(true); + + ishidden = da->current_is_hidden(); + + if (show_hidden || !ishidden) { + if (da->current_is_dir() && !p.begins_with(".")) { + TreeItem *ti = tree->create_item(p_item); + ti->set_text(0,p); + ti->set_icon(0,get_icon("Folder","EditorIcons")); + ti->set_collapsed(true); + } } p=da->get_next(); diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index 24699ac87..deb5d86a2 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -446,6 +446,7 @@ void EditorSettings::_load_defaults() { set("text_editor/create_signal_callbacks",true); + set("file_dialog/show_hidden_files", false); set("animation/autorename_animation_tracks",true); set("animation/confirm_insert_track",true); -- cgit v1.2.3-70-g09d2