Jelajahi Sumber

-Fixed a few bugs in Viewport
-Made a few demos using Viewport to show it's true power!
-Fixed some start-up error messages.

Juan Linietsky 11 tahun lalu
induk
melakukan
7ea3e8267a
66 mengubah file dengan 1113 tambahan dan 84 penghapusan
  1. 1 1
      core/object_type_db.cpp
  2. 13 0
      core/variant.cpp
  3. 1 1
      core/variant_call.cpp
  4. TEMPAT SAMPAH
      demos/viewport/2d_in_3d/ball.png
  5. 22 0
      demos/viewport/2d_in_3d/engine.cfg
  6. TEMPAT SAMPAH
      demos/viewport/2d_in_3d/icon.png
  7. TEMPAT SAMPAH
      demos/viewport/2d_in_3d/left_pallete.png
  8. 73 0
      demos/viewport/2d_in_3d/pong.gd
  9. 183 0
      demos/viewport/2d_in_3d/pong.xml
  10. 14 0
      demos/viewport/2d_in_3d/pong3d.gd
  11. TEMPAT SAMPAH
      demos/viewport/2d_in_3d/pong3d.scn
  12. TEMPAT SAMPAH
      demos/viewport/2d_in_3d/right_pallete.png
  13. TEMPAT SAMPAH
      demos/viewport/2d_in_3d/separator.png
  14. 4 0
      demos/viewport/3d_in_2d/engine.cfg
  15. TEMPAT SAMPAH
      demos/viewport/3d_in_2d/main.scn
  16. TEMPAT SAMPAH
      demos/viewport/3d_in_2d/player.scn
  17. 101 0
      demos/viewport/3d_in_2d/player.xml
  18. TEMPAT SAMPAH
      demos/viewport/3d_in_2d/player_2d.scn
  19. TEMPAT SAMPAH
      demos/viewport/3d_in_2d/player_3d.scn
  20. TEMPAT SAMPAH
      demos/viewport/3d_in_2d/robot_demo.png
  21. 4 0
      demos/viewport/gui_in_3d/engine.cfg
  22. TEMPAT SAMPAH
      demos/viewport/gui_in_3d/gui.scn
  23. 44 0
      demos/viewport/gui_in_3d/gui_3d.gd
  24. TEMPAT SAMPAH
      demos/viewport/gui_in_3d/gui_3d.scn
  25. 1 1
      drivers/gles1/rasterizer_gles1.cpp
  26. 1 1
      drivers/gles1/rasterizer_gles1.h
  27. 29 4
      drivers/gles2/rasterizer_gles2.cpp
  28. 3 1
      drivers/gles2/rasterizer_gles2.h
  29. 0 2
      main/main.cpp
  30. 3 3
      platform/iphone/app_delegate.mm
  31. 1 1
      platform/iphone/detect.py
  32. 17 3
      platform/iphone/in_app_store.mm
  33. 0 2
      platform/x11/os_x11.cpp
  34. 12 23
      scene/2d/canvas_item.cpp
  35. 2 2
      scene/2d/canvas_item.h
  36. 201 0
      scene/2d/sprite.cpp
  37. 40 0
      scene/2d/sprite.h
  38. 1 0
      scene/3d/quad.h
  39. 2 2
      scene/gui/control.cpp
  40. 54 0
      scene/gui/file_dialog.cpp
  41. 1 0
      scene/gui/file_dialog.h
  42. 1 1
      scene/gui/menu_button.cpp
  43. 61 6
      scene/main/node.cpp
  44. 9 0
      scene/main/node.h
  45. 13 6
      scene/main/scene_main_loop.cpp
  46. 2 0
      scene/main/scene_main_loop.h
  47. 134 3
      scene/main/viewport.cpp
  48. 17 2
      scene/main/viewport.h
  49. 1 0
      scene/register_scene_types.cpp
  50. 1 1
      scene/resources/default_theme/default_theme.cpp
  51. 1 1
      servers/audio/audio_server_sw.cpp
  52. 1 1
      servers/visual/rasterizer.h
  53. 1 1
      servers/visual/rasterizer_dummy.cpp
  54. 1 1
      servers/visual/rasterizer_dummy.h
  55. 23 1
      servers/visual/visual_server_raster.cpp
  56. 4 2
      servers/visual/visual_server_raster.h
  57. 3 0
      servers/visual/visual_server_wrap_mt.h
  58. 3 0
      servers/visual_server.h
  59. 3 3
      tools/editor/editor_file_system.cpp
  60. 1 1
      tools/editor/editor_help.cpp
  61. 0 2
      tools/editor/editor_node.cpp
  62. 1 1
      tools/editor/editor_settings.cpp
  63. 1 1
      tools/editor/plugins/canvas_item_editor_plugin.cpp
  64. 1 1
      tools/editor/plugins/shader_editor_plugin.cpp
  65. 1 1
      tools/editor/plugins/spatial_editor_plugin.cpp
  66. 1 1
      tools/editor/scene_tree_dock.cpp

+ 1 - 1
core/object_type_db.cpp

@@ -408,7 +408,7 @@ void ObjectTypeDB::add_signal(StringName p_type,const MethodInfo& p_signal) {
 
 
 	while(check) {
 	while(check) {
 		if (check->signal_map.has(sname)) {
 		if (check->signal_map.has(sname)) {
-			ERR_EXPLAIN("Type already has signal");
+			ERR_EXPLAIN("Type "+String(p_type)+" already has signal: "+String(sname));
 			ERR_FAIL();
 			ERR_FAIL();
 		}
 		}
 		check=check->inherits_ptr;
 		check=check->inherits_ptr;

+ 13 - 0
core/variant.cpp

@@ -298,6 +298,19 @@ bool Variant::can_convert(Variant::Type p_type_from,Variant::Type p_type_to) {
 			valid_types=valid;
 			valid_types=valid;
 
 
 		} break;		
 		} break;		
+
+		case COLOR: {
+
+			static const Type valid[] = {
+				STRING,
+				INT,
+				NIL,
+			};
+
+			valid_types = valid;
+
+		} break;
+
 		case _RID: {
 		case _RID: {
 
 
 			static const Type valid[]={
 			static const Type valid[]={

+ 1 - 1
core/variant_call.cpp

@@ -977,7 +977,7 @@ Variant Variant::construct(const Variant::Type p_type,const Variant** p_args,int
 			case TRANSFORM: return (Transform(p_args[0]->operator Transform()));
 			case TRANSFORM: return (Transform(p_args[0]->operator Transform()));
 
 
 			// misc types
 			// misc types
-			case COLOR: return (Color(*p_args[0]));
+			case COLOR: return p_args[0]->type == Variant::STRING ? Color::html(*p_args[0]) : Color::hex(*p_args[0]);
 			case IMAGE: return (Image(*p_args[0]));
 			case IMAGE: return (Image(*p_args[0]));
 			case NODE_PATH: return (NodePath(p_args[0]->operator NodePath()));		// 15
 			case NODE_PATH: return (NodePath(p_args[0]->operator NodePath()));		// 15
 			case _RID: return (RID(*p_args[0]));
 			case _RID: return (RID(*p_args[0]));

TEMPAT SAMPAH
demos/viewport/2d_in_3d/ball.png


+ 22 - 0
demos/viewport/2d_in_3d/engine.cfg

@@ -0,0 +1,22 @@
+[application]
+
+name="Pong 2D in 3D"
+main_scene="res://pong3d.scn"
+icon="res://icon.png"
+
+[display]
+
+width=640
+height=400
+stretch_2d=true
+
+[input]
+
+left_move_up=[key(A)]
+left_move_down=[key(Z)]
+right_move_up=[key(Up)]
+right_move_down=[key(Down)]
+
+[render]
+
+default_clear_color=#ff000000

TEMPAT SAMPAH
demos/viewport/2d_in_3d/icon.png


TEMPAT SAMPAH
demos/viewport/2d_in_3d/left_pallete.png


+ 73 - 0
demos/viewport/2d_in_3d/pong.gd

@@ -0,0 +1,73 @@
+
+extends Node2D
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+const INITIAL_BALL_SPEED = 80
+var ball_speed = INITIAL_BALL_SPEED
+var screen_size = Vector2(640,400)
+#default ball direction
+var direction = Vector2(-1,0)
+var pad_size = Vector2(8,32)
+const PAD_SPEED = 150
+
+
+func _process(delta):
+
+
+	# get ball positio and pad rectangles
+	var ball_pos = get_node("ball").get_pos()
+	var left_rect = Rect2( get_node("left").get_pos() - pad_size*0.5, pad_size )
+	var right_rect = Rect2( get_node("right").get_pos() - pad_size*0.5, pad_size )
+	
+	#integrate new ball postion
+	ball_pos+=direction*ball_speed*delta
+	
+	#flip when touching roof or floor
+	if ( (ball_pos.y<0 and direction.y <0) or (ball_pos.y>screen_size.y and direction.y>0)):
+		direction.y = -direction.y
+		
+	#flip, change direction and increase speed when touching pads	
+	if ( (left_rect.has_point(ball_pos) and direction.x < 0) or (right_rect.has_point(ball_pos) and direction.x > 0)):
+		direction.x=-direction.x
+		ball_speed*=1.1
+		direction.y=randf()*2.0-1
+		direction = direction.normalized()
+
+	#check gameover
+	if (ball_pos.x<0 or ball_pos.x>screen_size.x):
+		ball_pos=screen_size*0.5
+		ball_speed=INITIAL_BALL_SPEED
+		direction=Vector2(-1,0)
+			
+						
+	get_node("ball").set_pos(ball_pos)
+
+	#move left pad	
+	var left_pos = get_node("left").get_pos()
+	
+	if (left_pos.y > 0 and Input.is_action_pressed("left_move_up")):
+		left_pos.y+=-PAD_SPEED*delta
+	if (left_pos.y < screen_size.y and Input.is_action_pressed("left_move_down")):
+		left_pos.y+=PAD_SPEED*delta
+		
+	get_node("left").set_pos(left_pos)
+		
+	#move right pad	
+	var right_pos = get_node("right").get_pos()
+	
+	if (right_pos.y > 0 and Input.is_action_pressed("right_move_up")):
+		right_pos.y+=-PAD_SPEED*delta
+	if (right_pos.y < screen_size.y and Input.is_action_pressed("right_move_down")):
+		right_pos.y+=PAD_SPEED*delta
+		
+	get_node("right").set_pos(right_pos)
+	
+	 
+
+func _ready():
+	screen_size = get_viewport_rect().size # get actual size
+	pad_size = get_node("left").get_texture().get_size()
+	set_process(true)
+

+ 183 - 0
demos/viewport/2d_in_3d/pong.xml

@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<resource_file type="PackedScene" subresource_count="6" version="0.99" version_name="Godot Engine v0.99.3735-pre-beta">
+	<ext_resource path="res://pong.*" type="GDScript"></ext_resource>
+	<ext_resource path="res://separator.*" type="ImageTexture"></ext_resource>
+	<ext_resource path="res://left_pallete.*" type="ImageTexture"></ext_resource>
+	<ext_resource path="res://right_pallete.*" type="ImageTexture"></ext_resource>
+	<ext_resource path="res://ball.*" type="ImageTexture"></ext_resource>
+	<main_resource>
+		<dictionary name="_bundled" shared="false">
+			<string> "names" </string>
+			<string_array  len="27">
+				<string> "game" </string>
+				<string> "Node2D" </string>
+				<string> "visibility/visible" </string>
+				<string> "visibility/opacity" </string>
+				<string> "visibility/self_opacity" </string>
+				<string> "visibility/on_top" </string>
+				<string> "transform/pos" </string>
+				<string> "transform/rot" </string>
+				<string> "transform/scale" </string>
+				<string> "script/script" </string>
+				<string> "__meta__" </string>
+				<string> "left" </string>
+				<string> "Sprite" </string>
+				<string> "texture" </string>
+				<string> "centered" </string>
+				<string> "offset" </string>
+				<string> "flip_h" </string>
+				<string> "flip_v" </string>
+				<string> "vframes" </string>
+				<string> "hframes" </string>
+				<string> "frame" </string>
+				<string> "modulate" </string>
+				<string> "region" </string>
+				<string> "region_rect" </string>
+				<string> "right" </string>
+				<string> "separator" </string>
+				<string> "ball" </string>
+			</string_array>
+			<string> "version" </string>
+			<int> 1 </int>
+			<string> "conn_count" </string>
+			<int> 0 </int>
+			<string> "node_count" </string>
+			<int> 5 </int>
+			<string> "variants" </string>
+			<array  len="20" shared="false">
+				<bool> True </bool>
+				<real> 1 </real>
+				<vector2> 0, 0 </vector2>
+				<real> 0 </real>
+				<vector2> 1, 1 </vector2>
+				<resource  resource_type="GDScript" path="res://pong.*">  </resource>
+				<dictionary  shared="false">
+					<string> "__editor_plugin_states__" </string>
+					<dictionary  shared="false">
+						<string> "Script" </string>
+						<dictionary  shared="false">
+							<string> "current" </string>
+							<int> 0 </int>
+							<string> "sources" </string>
+							<array  len="1" shared="false">
+								<string> "res://pong.gd" </string>
+							</array>
+						</dictionary>
+						<string> "2D" </string>
+						<dictionary  shared="false">
+							<string> "pixel_snap" </string>
+							<bool> True </bool>
+							<string> "zoom" </string>
+							<real> 1.108033 </real>
+							<string> "ofs" </string>
+							<vector2> -54.59, -36.0052 </vector2>
+						</dictionary>
+						<string> "3D" </string>
+						<dictionary  shared="false">
+							<string> "zfar" </string>
+							<real> 500 </real>
+							<string> "fov" </string>
+							<real> 45 </real>
+							<string> "viewports" </string>
+							<array  len="4" shared="false">
+								<dictionary  shared="false">
+									<string> "distance" </string>
+									<real> 4 </real>
+									<string> "x_rot" </string>
+									<real> 0 </real>
+									<string> "y_rot" </string>
+									<real> 0 </real>
+									<string> "use_orthogonal" </string>
+									<bool> False </bool>
+									<string> "use_environment" </string>
+									<bool> False </bool>
+									<string> "pos" </string>
+									<vector3> 0, 0, 0 </vector3>
+								</dictionary>
+								<dictionary  shared="false">
+									<string> "distance" </string>
+									<real> 4 </real>
+									<string> "x_rot" </string>
+									<real> 0 </real>
+									<string> "y_rot" </string>
+									<real> 0 </real>
+									<string> "use_orthogonal" </string>
+									<bool> False </bool>
+									<string> "use_environment" </string>
+									<bool> False </bool>
+									<string> "pos" </string>
+									<vector3> 0, 0, 0 </vector3>
+								</dictionary>
+								<dictionary  shared="false">
+									<string> "distance" </string>
+									<real> 4 </real>
+									<string> "x_rot" </string>
+									<real> 0 </real>
+									<string> "y_rot" </string>
+									<real> 0 </real>
+									<string> "use_orthogonal" </string>
+									<bool> False </bool>
+									<string> "use_environment" </string>
+									<bool> False </bool>
+									<string> "pos" </string>
+									<vector3> 0, 0, 0 </vector3>
+								</dictionary>
+								<dictionary  shared="false">
+									<string> "distance" </string>
+									<real> 4 </real>
+									<string> "x_rot" </string>
+									<real> 0 </real>
+									<string> "y_rot" </string>
+									<real> 0 </real>
+									<string> "use_orthogonal" </string>
+									<bool> False </bool>
+									<string> "use_environment" </string>
+									<bool> False </bool>
+									<string> "pos" </string>
+									<vector3> 0, 0, 0 </vector3>
+								</dictionary>
+							</array>
+							<string> "viewport_mode" </string>
+							<int> 1 </int>
+							<string> "default_light" </string>
+							<bool> True </bool>
+							<string> "show_grid" </string>
+							<bool> True </bool>
+							<string> "show_origin" </string>
+							<bool> True </bool>
+							<string> "znear" </string>
+							<real> 0.1 </real>
+						</dictionary>
+					</dictionary>
+					<string> "__editor_run_settings__" </string>
+					<dictionary  shared="false">
+						<string> "custom_args" </string>
+						<string> "-l $scene" </string>
+						<string> "run_mode" </string>
+						<int> 0 </int>
+					</dictionary>
+					<string> "__editor_plugin_screen__" </string>
+					<string> "Script" </string>
+				</dictionary>
+				<vector2> 67.6875, 183.208 </vector2>
+				<resource  resource_type="ImageTexture" path="res://left_pallete.*">  </resource>
+				<bool> False </bool>
+				<int> 1 </int>
+				<int> 0 </int>
+				<color> 1, 1, 1, 1 </color>
+				<rect2> 0, 0, 0, 0 </rect2>
+				<vector2> 577, 187 </vector2>
+				<resource  resource_type="ImageTexture" path="res://right_pallete.*">  </resource>
+				<vector2> 320, 200 </vector2>
+				<resource  resource_type="ImageTexture" path="res://separator.*">  </resource>
+				<vector2> 320.283, 188 </vector2>
+				<resource  resource_type="ImageTexture" path="res://ball.*">  </resource>
+			</array>
+			<string> "nodes" </string>
+			<int_array  len="197"> 				-1, -1, 1, 0, -1, 9, 2, 0, 3, 1, 4, 1, 5, 0, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 0, 0, 0, 12, 11, -1, 18, 2, 0, 3, 1, 4, 1, 5, 0, 6, 7, 7, 3, 8, 4, 13, 8, 14, 0, 15, 2, 16, 9, 17, 9, 18, 10, 19, 10, 20, 11, 21, 12, 22, 9, 23, 13, 0, 0, 0, 12, 24, -1, 18, 2, 0, 3, 1, 4, 1, 5, 0, 6, 14, 7, 3, 8, 4, 13, 15, 14, 0, 15, 2, 16, 9, 17, 9, 18, 10, 19, 10, 20, 11, 21, 12, 22, 9, 23, 13, 0, 0, 0, 12, 25, -1, 18, 2, 0, 3, 1, 4, 1, 5, 0, 6, 16, 7, 3, 8, 4, 13, 17, 14, 0, 15, 2, 16, 9, 17, 9, 18, 10, 19, 10, 20, 11, 21, 12, 22, 9, 23, 13, 0, 0, 0, 12, 26, -1, 18, 2, 0, 3, 1, 4, 1, 5, 0, 6, 18, 7, 3, 8, 4, 13, 19, 14, 0, 15, 2, 16, 9, 17, 9, 18, 10, 19, 10, 20, 11, 21, 12, 22, 9, 23, 13, 0 </int_array>
+			<string> "conns" </string>
+			<int_array  len="0"> 				 </int_array>
+		</dictionary>
+
+	</main_resource>
+</resource_file>

+ 14 - 0
demos/viewport/2d_in_3d/pong3d.gd

@@ -0,0 +1,14 @@
+
+extends Spatial
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+
+func _ready():
+	# Initalization here
+	var tex = get_node("Viewport").get_render_target_texture()
+	get_node("Quad").get_material_override().set_texture(FixedMaterial.PARAM_DIFFUSE,tex)
+	pass
+
+

TEMPAT SAMPAH
demos/viewport/2d_in_3d/pong3d.scn


TEMPAT SAMPAH
demos/viewport/2d_in_3d/right_pallete.png


TEMPAT SAMPAH
demos/viewport/2d_in_3d/separator.png


+ 4 - 0
demos/viewport/3d_in_2d/engine.cfg

@@ -0,0 +1,4 @@
+[application]
+
+name="3D in 2D"
+main_scene="res://main.scn"

TEMPAT SAMPAH
demos/viewport/3d_in_2d/main.scn


TEMPAT SAMPAH
demos/viewport/3d_in_2d/player.scn


File diff ditekan karena terlalu besar
+ 101 - 0
demos/viewport/3d_in_2d/player.xml


TEMPAT SAMPAH
demos/viewport/3d_in_2d/player_2d.scn


TEMPAT SAMPAH
demos/viewport/3d_in_2d/player_3d.scn


TEMPAT SAMPAH
demos/viewport/3d_in_2d/robot_demo.png


+ 4 - 0
demos/viewport/gui_in_3d/engine.cfg

@@ -0,0 +1,4 @@
+[application]
+
+name="GUI in 3D"
+main_scene="res://gui_3d.scn"

TEMPAT SAMPAH
demos/viewport/gui_in_3d/gui.scn


+ 44 - 0
demos/viewport/gui_in_3d/gui_3d.gd

@@ -0,0 +1,44 @@
+
+extends Spatial
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+
+var prev_pos=null
+
+func _input(ev):
+	if (ev.type in [InputEvent.MOUSE_BUTTON,InputEvent.MOUSE_MOTION]):
+		var pos = ev.pos
+		var rfrom = get_node("camera").project_ray_origin(pos)
+		var rnorm = get_node("camera").project_ray_normal(pos)
+		
+		#simple collision test against aligned plane
+		#for game UIs of this kind consider more complex collision against plane
+		var p = Plane(Vector3(0,0,1),0).intersects_ray(rfrom,rnorm)
+		if (p==null):
+			return
+			
+		pos.x=(p.x+1.5)*100
+		pos.y=(-p.y+0.75)*100
+		ev.pos=pos
+		ev.global_pos=pos
+		if (prev_pos==null):
+			prev_pos=pos
+		if (ev.type==InputEvent.MOUSE_MOTION):
+			ev.relative_pos=pos-prev_pos
+		prev_pos=pos
+		
+	get_node("viewport").input(ev)
+		
+		
+	
+
+func _ready():
+	# Initalization here
+	get_node("quad").get_material_override().set_texture(FixedMaterial.PARAM_DIFFUSE, get_node("viewport").get_render_target_texture() )
+	set_process_input(true)
+	
+	pass
+
+

TEMPAT SAMPAH
demos/viewport/gui_in_3d/gui_3d.scn


+ 1 - 1
drivers/gles1/rasterizer_gles1.cpp

@@ -2885,7 +2885,7 @@ void RasterizerGLES1::set_viewport(const VS::ViewportRect& p_viewport) {
 	glViewport( viewport.x, window_size.height-(viewport.height+viewport.y), viewport.width,viewport.height );
 	glViewport( viewport.x, window_size.height-(viewport.height+viewport.y), viewport.width,viewport.height );
 }
 }
 
 
-void RasterizerGLES1::set_render_target(RID p_render_target) {
+void RasterizerGLES1::set_render_target(RID p_render_target, bool p_transparent_bg, bool p_vflip) {
 
 
 
 
 }
 }

+ 1 - 1
drivers/gles1/rasterizer_gles1.h

@@ -1101,7 +1101,7 @@ public:
 	virtual void begin_frame();
 	virtual void begin_frame();
 
 
 	virtual void set_viewport(const VS::ViewportRect& p_viewport);
 	virtual void set_viewport(const VS::ViewportRect& p_viewport);
-	virtual void set_render_target(RID p_render_target);
+	virtual void set_render_target(RID p_render_target,bool p_transparent_bg=false,bool p_vflip=false);
 	virtual void clear_viewport(const Color& p_color);
 	virtual void clear_viewport(const Color& p_color);
 	virtual void capture_viewport(Image* r_capture);
 	virtual void capture_viewport(Image* r_capture);
 
 

+ 29 - 4
drivers/gles2/rasterizer_gles2.cpp

@@ -3320,6 +3320,7 @@ void RasterizerGLES2::render_target_set_size(RID p_render_target,int p_width,int
 	if (p_width==0 || p_height==0)
 	if (p_width==0 || p_height==0)
 		return;
 		return;
 
 
+
 	rt->width=p_width;
 	rt->width=p_width;
 	rt->height=p_height;
 	rt->height=p_height;
 
 
@@ -3560,11 +3561,14 @@ void RasterizerGLES2::clear_viewport(const Color& p_color) {
 };
 };
 
 
 
 
-void RasterizerGLES2::set_render_target(RID p_render_target) {
+void RasterizerGLES2::set_render_target(RID p_render_target, bool p_transparent_bg, bool p_vflip) {
+
+
 
 
 	if (!p_render_target.is_valid()) {
 	if (!p_render_target.is_valid()) {
 		glBindFramebuffer(GL_FRAMEBUFFER,base_framebuffer);
 		glBindFramebuffer(GL_FRAMEBUFFER,base_framebuffer);
 		current_rt=NULL;
 		current_rt=NULL;
+		current_rt_vflip=false;
 
 
 	} else {
 	} else {
 		RenderTarget *rt = render_target_owner.get(p_render_target);
 		RenderTarget *rt = render_target_owner.get(p_render_target);
@@ -3572,6 +3576,8 @@ void RasterizerGLES2::set_render_target(RID p_render_target) {
 		ERR_FAIL_COND(rt->fbo==0);
 		ERR_FAIL_COND(rt->fbo==0);
 		glBindFramebuffer(GL_FRAMEBUFFER,rt->fbo);
 		glBindFramebuffer(GL_FRAMEBUFFER,rt->fbo);
 		current_rt=rt;
 		current_rt=rt;
+		current_rt_transparent=p_transparent_bg;
+		current_rt_vflip=!p_vflip;
 	}
 	}
 
 
 }
 }
@@ -3637,6 +3643,9 @@ void RasterizerGLES2::begin_shadow_map( RID p_light_instance, int p_shadow_pass
 void RasterizerGLES2::set_camera(const Transform& p_world,const CameraMatrix& p_projection) {
 void RasterizerGLES2::set_camera(const Transform& p_world,const CameraMatrix& p_projection) {
 
 
 	camera_transform=p_world;
 	camera_transform=p_world;
+	if (current_rt && current_rt_vflip) {
+		camera_transform.basis.set_axis(1,-camera_transform.basis.get_axis(1));
+	}
 	camera_transform_inverse=camera_transform.inverse();
 	camera_transform_inverse=camera_transform.inverse();
 	camera_projection=p_projection;
 	camera_projection=p_projection;
 	camera_plane = Plane( camera_transform.origin, camera_transform.basis.get_axis(2) );
 	camera_plane = Plane( camera_transform.origin, camera_transform.basis.get_axis(2) );
@@ -3741,7 +3750,7 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
 	}
 	}
 
 
 	//print_line("compiled fragment: "+fragment_code);
 	//print_line("compiled fragment: "+fragment_code);
-	//print_line("compiled fragment globals: "+fragment_globals);
+	//	("compiled fragment globals: "+fragment_globals);
 
 
 	//print_line("UCF: "+itos(p_shader->uniforms.size()));
 	//print_line("UCF: "+itos(p_shader->uniforms.size()));
 
 
@@ -5090,6 +5099,12 @@ void RasterizerGLES2::_setup_skeleton(const Skeleton *p_skeleton) {
 
 
 void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Transform& p_view_transform, const Transform& p_view_transform_inverse,const CameraMatrix& p_projection,bool p_reverse_cull,bool p_fragment_light,bool p_alpha_pass) {
 void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Transform& p_view_transform, const Transform& p_view_transform_inverse,const CameraMatrix& p_projection,bool p_reverse_cull,bool p_fragment_light,bool p_alpha_pass) {
 
 
+	if (current_rt && current_rt_vflip) {
+		p_reverse_cull=!p_reverse_cull;
+		glFrontFace(GL_CCW);
+
+	}
+
 	const Material *prev_material=NULL;
 	const Material *prev_material=NULL;
 	uint16_t prev_light=0x777E;
 	uint16_t prev_light=0x777E;
 	const Geometry *prev_geometry_cmp=NULL;
 	const Geometry *prev_geometry_cmp=NULL;
@@ -5349,6 +5364,9 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
 	//print_line("shaderchanges: "+itos(p_alpha_pass)+": "+itos(_rinfo.shader_change_count));
 	//print_line("shaderchanges: "+itos(p_alpha_pass)+": "+itos(_rinfo.shader_change_count));
 
 
 
 
+	if (current_rt && current_rt_vflip) {
+		glFrontFace(GL_CW);
+	}
 
 
 };
 };
 
 
@@ -5755,6 +5773,10 @@ void RasterizerGLES2::end_scene() {
 
 
 		glClearColor(0,0,0,1);
 		glClearColor(0,0,0,1);
 		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+	} else if (current_rt && current_rt_transparent) {
+
+		glClearColor(0,0,0,0);
+		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 
 
 	} else if (current_env) {
 	} else if (current_env) {
 
 
@@ -6266,13 +6288,16 @@ void RasterizerGLES2::canvas_begin() {
 	_set_color_attrib(Color(1,1,1));
 	_set_color_attrib(Color(1,1,1));
 	Transform canvas_transform;
 	Transform canvas_transform;
 	canvas_transform.translate(-(viewport.width / 2.0f), -(viewport.height / 2.0f), 0.0f);
 	canvas_transform.translate(-(viewport.width / 2.0f), -(viewport.height / 2.0f), 0.0f);
-	canvas_transform.scale( Vector3( 2.0f / viewport.width, -2.0f / viewport.height, 1.0f ) );
+	float csy = 1.0;
+	if (current_rt && current_rt_vflip)
+		csy = -1.0;
+
+	canvas_transform.scale( Vector3( 2.0f / viewport.width, csy * -2.0f / viewport.height, 1.0f ) );
 	canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform);
 	canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform);
 	canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,Matrix32());
 	canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,Matrix32());
 	canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX,Matrix32());
 	canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX,Matrix32());
 
 
 	canvas_opacity=1.0;
 	canvas_opacity=1.0;
-
 	canvas_blend_mode=VS::MATERIAL_BLEND_MODE_MIX;
 	canvas_blend_mode=VS::MATERIAL_BLEND_MODE_MIX;
 
 
 
 

+ 3 - 1
drivers/gles2/rasterizer_gles2.h

@@ -1047,6 +1047,8 @@ class RasterizerGLES2 : public Rasterizer {
 
 
 
 
 	RenderTarget *current_rt;
 	RenderTarget *current_rt;
+	bool current_rt_transparent;
+	bool current_rt_vflip;
 	ViewportData *current_vd;
 	ViewportData *current_vd;
 
 
 
 
@@ -1344,7 +1346,7 @@ public:
 
 
 
 
 	virtual void set_viewport(const VS::ViewportRect& p_viewport);
 	virtual void set_viewport(const VS::ViewportRect& p_viewport);
-	virtual void set_render_target(RID p_render_target);
+	virtual void set_render_target(RID p_render_target,bool p_transparent_bg=false,bool p_vflip=false);
 	virtual void clear_viewport(const Color& p_color);
 	virtual void clear_viewport(const Color& p_color);
 	virtual void capture_viewport(Image* r_capture);
 	virtual void capture_viewport(Image* r_capture);
 
 

+ 0 - 2
main/main.cpp

@@ -874,8 +874,6 @@ bool Main::start() {
 		}
 		}
 	}
 	}
 
 
-	print_line("editor: "+itos(editor));
-
 	if (editor)
 	if (editor)
 		Globals::get_singleton()->set("editor_active",true);
 		Globals::get_singleton()->set("editor_active",true);
 
 

+ 3 - 3
platform/iphone/app_delegate.mm

@@ -33,7 +33,7 @@
 #include "core/globals.h"
 #include "core/globals.h"
 #include "main/main.h"
 #include "main/main.h"
 
 
-#ifdef FACEBOOK_ENABLED
+#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
 #include "modules/FacebookScorer_ios/FacebookScorer.h"
 #include "modules/FacebookScorer_ios/FacebookScorer.h"
 #endif
 #endif
 
 
@@ -250,7 +250,7 @@ static int frame_count = 0;
 }
 }
 
 
 - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
 - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
-#ifdef FACEBOOK_ENABLED
+#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
 	return [[[FacebookScorer sharedInstance] facebook] handleOpenURL:url];
 	return [[[FacebookScorer sharedInstance] facebook] handleOpenURL:url];
 #else
 #else
 	return false;
 	return false;
@@ -259,7 +259,7 @@ static int frame_count = 0;
 
 
 // For 4.2+ support
 // For 4.2+ support
 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
-#ifdef FACEBOOK_ENABLED
+#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
 	return [[[FacebookScorer sharedInstance] facebook] handleOpenURL:url];
 	return [[[FacebookScorer sharedInstance] facebook] handleOpenURL:url];
 #else
 #else
 	return false;
 	return false;

+ 1 - 1
platform/iphone/detect.py

@@ -81,7 +81,7 @@ def configure(env):
 							'-framework', 'AudioToolbox',
 							'-framework', 'AudioToolbox',
 							'-framework', 'SystemConfiguration',
 							'-framework', 'SystemConfiguration',
 							'-framework', 'Security',
 							'-framework', 'Security',
-							#'-framework', 'AdSupport',
+							'-framework', 'AdSupport',
 							'-framework', 'MediaPlayer',
 							'-framework', 'MediaPlayer',
 							])
 							])
 
 

+ 17 - 3
platform/iphone/in_app_store.mm

@@ -168,6 +168,9 @@ Error InAppStore::request_product_info(Variant p_params) {
 			ret["result"] = "ok";
 			ret["result"] = "ok";
 			ret["product_id"] = pid;
 			ret["product_id"] = pid;
             
             
+            NSData* receipt = nil;
+            int sdk_version = 6;
+            
             if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0){
             if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0){
                 
                 
                 NSURL *receiptFileURL = nil;
                 NSURL *receiptFileURL = nil;
@@ -178,19 +181,30 @@ Error InAppStore::request_product_info(Variant p_params) {
                     receiptFileURL = [bundle appStoreReceiptURL];
                     receiptFileURL = [bundle appStoreReceiptURL];
                     
                     
                     // Read in the contents of the transaction file.
                     // Read in the contents of the transaction file.
-                    ret["receipt"] = receiptFileURL;
+                    receipt = [NSData dataWithContentsOfURL:receiptFileURL];
+                    sdk_version = 7;
                     
                     
                 } else {
                 } else {
                     // Fall back to deprecated transaction receipt,
                     // Fall back to deprecated transaction receipt,
                     // which is still available in iOS 7.
                     // which is still available in iOS 7.
                     
                     
                     // Use SKPaymentTransaction's transactionReceipt.
                     // Use SKPaymentTransaction's transactionReceipt.
-                    ret["receipt"] = transaction.transactionReceipt;
+                    receipt = transaction.transactionReceipt;
                 }
                 }
                 
                 
             }else{
             }else{
-                ret["receipt"] = transaction.transactionReceipt;
+                receipt = transaction.transactionReceipt;
+            }
+            
+            NSString* receipt_to_send = nil;
+            if (receipt != nil)
+            {
+                receipt_to_send = [receipt description];
             }
             }
+            Dictionary receipt_ret;
+            receipt_ret["receipt"] = String::utf8([receipt_to_send UTF8String]);
+            receipt_ret["sdk"] = sdk_version;
+            ret["receipt"] = receipt_ret;
             
             
 			InAppStore::get_singleton()->_post_event(ret);
 			InAppStore::get_singleton()->_post_event(ret);
 			[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
 			[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

+ 0 - 2
platform/x11/os_x11.cpp

@@ -1227,8 +1227,6 @@ void OS_X11::set_icon(const Image& p_icon) {
 
 
 		pd.resize(2+w*h);
 		pd.resize(2+w*h);
 
 
-		print_line("***** SET ICON ***** "+itos(w)+"  "+itos(h));
-
 		pd[0]=w;
 		pd[0]=w;
 		pd[1]=h;
 		pd[1]=h;
 
 

+ 12 - 23
scene/2d/canvas_item.cpp

@@ -255,7 +255,7 @@ void CanvasItem::_enter_canvas() {
 	if ((!get_parent() || !get_parent()->cast_to<CanvasItem>()) || toplevel) {
 	if ((!get_parent() || !get_parent()->cast_to<CanvasItem>()) || toplevel) {
 
 
 		Node *n = this;
 		Node *n = this;
-		viewport=NULL;
+		Viewport *viewport=NULL;
 		canvas_layer=NULL;
 		canvas_layer=NULL;
 
 
 		while(n) {
 		while(n) {
@@ -288,15 +288,10 @@ void CanvasItem::_enter_canvas() {
 	} else {
 	} else {
 
 
 		CanvasItem *parent = get_parent_item();
 		CanvasItem *parent = get_parent_item();
-		viewport=parent->viewport;
 		VisualServer::get_singleton()->canvas_item_set_parent(canvas_item,parent->get_canvas_item());
 		VisualServer::get_singleton()->canvas_item_set_parent(canvas_item,parent->get_canvas_item());
 		parent->_queue_sort_children();
 		parent->_queue_sort_children();
 	}
 	}
 
 
-	if (!viewport) {
-
-		print_line("no viewport wtf!");
-	}
 	pending_update=false;
 	pending_update=false;
 	update();
 	update();
 
 
@@ -308,7 +303,6 @@ void CanvasItem::_exit_canvas() {
 
 
 	notification(NOTIFICATION_EXIT_CANVAS,true); //reverse the notification
 	notification(NOTIFICATION_EXIT_CANVAS,true); //reverse the notification
 	VisualServer::get_singleton()->canvas_item_set_parent(canvas_item,RID());
 	VisualServer::get_singleton()->canvas_item_set_parent(canvas_item,RID());
-	viewport=NULL;
 	canvas_layer=NULL;
 	canvas_layer=NULL;
 	group="";
 	group="";
 
 
@@ -655,7 +649,7 @@ void CanvasItem::_notify_transform(CanvasItem *p_node) {
 Rect2 CanvasItem::get_viewport_rect() const {
 Rect2 CanvasItem::get_viewport_rect() const {
 
 
 	ERR_FAIL_COND_V(!is_inside_scene(),Rect2());
 	ERR_FAIL_COND_V(!is_inside_scene(),Rect2());
-	return viewport->get_visible_rect();
+	return get_viewport()->get_visible_rect();
 }
 }
 
 
 RID CanvasItem::get_canvas() const {
 RID CanvasItem::get_canvas() const {
@@ -665,7 +659,7 @@ RID CanvasItem::get_canvas() const {
 	if (canvas_layer)
 	if (canvas_layer)
 		return canvas_layer->get_world_2d()->get_canvas();
 		return canvas_layer->get_world_2d()->get_canvas();
 	else
 	else
-		return viewport->find_world_2d()->get_canvas();
+		return get_viewport()->find_world_2d()->get_canvas();
 
 
 
 
 }
 }
@@ -680,11 +674,6 @@ CanvasItem *CanvasItem::get_toplevel() const {
 	return ci;
 	return ci;
 }
 }
 
 
-Viewport *CanvasItem::get_viewport() const {
-
-	return viewport;
-}
-
 
 
 Ref<World2D> CanvasItem::get_world_2d() const {
 Ref<World2D> CanvasItem::get_world_2d() const {
 
 
@@ -694,8 +683,8 @@ Ref<World2D> CanvasItem::get_world_2d() const {
 
 
 	if (tl->canvas_layer) {
 	if (tl->canvas_layer) {
 		return tl->canvas_layer->get_world_2d();
 		return tl->canvas_layer->get_world_2d();
-	} else if (tl->viewport) {
-		return tl->viewport->find_world_2d();
+	} else if (tl->get_viewport()) {
+		return tl->get_viewport()->find_world_2d();
 	} else {
 	} else {
 		return Ref<World2D>();
 		return Ref<World2D>();
 	}
 	}
@@ -705,7 +694,7 @@ Ref<World2D> CanvasItem::get_world_2d() const {
 RID CanvasItem::get_viewport_rid() const {
 RID CanvasItem::get_viewport_rid() const {
 
 
 	ERR_FAIL_COND_V(!is_inside_scene(),RID());
 	ERR_FAIL_COND_V(!is_inside_scene(),RID());
-	return viewport->get_viewport();
+	return get_viewport()->get_viewport();
 }
 }
 
 
 void CanvasItem::set_block_transform_notify(bool p_enable) {
 void CanvasItem::set_block_transform_notify(bool p_enable) {
@@ -795,7 +784,7 @@ void CanvasItem::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("get_viewport_rect"),&CanvasItem::get_viewport_rect);
 	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_canvas"),&CanvasItem::get_canvas);
 	ObjectTypeDB::bind_method(_MD("get_world_2d"),&CanvasItem::get_world_2d);
 	ObjectTypeDB::bind_method(_MD("get_world_2d"),&CanvasItem::get_world_2d);
-	ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasItem::get_viewport);
+	//ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasItem::get_viewport);
 
 
 	BIND_VMETHOD(MethodInfo("_draw"));
 	BIND_VMETHOD(MethodInfo("_draw"));
 
 
@@ -838,14 +827,14 @@ Matrix32 CanvasItem::get_viewport_transform() const {
 
 
 	if (canvas_layer) {
 	if (canvas_layer) {
 
 
-		if (viewport) {
-			return viewport->get_final_transform() * canvas_layer->get_transform();
+		if (get_viewport()) {
+			return get_viewport()->get_final_transform() * canvas_layer->get_transform();
 		} else {
 		} else {
 			return canvas_layer->get_transform();
 			return canvas_layer->get_transform();
 		}
 		}
 
 
-	} else if (viewport) {
-		return viewport->get_final_transform() * viewport->get_canvas_transform();
+	} else if (get_viewport()) {
+		return get_viewport()->get_final_transform() * get_viewport()->get_canvas_transform();
 	}
 	}
 
 
 	return Matrix32();
 	return Matrix32();
@@ -868,7 +857,7 @@ CanvasItem::CanvasItem() : xform_change(this) {
 	drawing=false;
 	drawing=false;
 	behind=false;
 	behind=false;
 	block_transform_notify=false;
 	block_transform_notify=false;
-	viewport=NULL;
+//	viewport=NULL;
 	canvas_layer=NULL;
 	canvas_layer=NULL;
 	global_invalid=true;
 	global_invalid=true;
 
 

+ 2 - 2
scene/2d/canvas_item.h

@@ -59,7 +59,7 @@ private:
 	RID canvas_item;
 	RID canvas_item;
 	String group;
 	String group;
 
 
-	Viewport *viewport;
+
 	CanvasLayer *canvas_layer;
 	CanvasLayer *canvas_layer;
 
 
 	float opacity;
 	float opacity;
@@ -200,7 +200,7 @@ public:
 	RID get_viewport_rid() const;
 	RID get_viewport_rid() const;
 	RID get_canvas() const;
 	RID get_canvas() const;
 	Ref<World2D> get_world_2d() const;
 	Ref<World2D> get_world_2d() const;
-	Viewport *get_viewport() const;
+
 
 
 
 
 	CanvasItem();
 	CanvasItem();

+ 201 - 0
scene/2d/sprite.cpp

@@ -29,6 +29,8 @@
 #include "sprite.h"
 #include "sprite.h"
 #include "core/core_string_names.h"
 #include "core/core_string_names.h"
 #include "scene/scene_string_names.h"
 #include "scene/scene_string_names.h"
+#include "scene/main/viewport.h"
+
 void Sprite::edit_set_pivot(const Point2& p_pivot) {
 void Sprite::edit_set_pivot(const Point2& p_pivot) {
 
 
 	set_offset(p_pivot);
 	set_offset(p_pivot);
@@ -335,3 +337,202 @@ Sprite::Sprite() {
 
 
 
 
 }
 }
+
+
+
+
+//////////////////////////// VPSPRITE
+///
+///
+///
+
+
+void ViewportSprite::edit_set_pivot(const Point2& p_pivot) {
+
+	set_offset(p_pivot);
+}
+
+Point2 ViewportSprite::edit_get_pivot() const {
+
+	return get_offset();
+}
+bool ViewportSprite::edit_has_pivot() const {
+
+	return true;
+}
+
+void ViewportSprite::_notification(int p_what) {
+
+	switch(p_what) {
+
+		case NOTIFICATION_ENTER_SCENE: {
+
+			if (!viewport_path.is_empty()) {
+
+				Node *n = get_node(viewport_path);
+				ERR_FAIL_COND(!n);
+				Viewport *vp=n->cast_to<Viewport>();
+				ERR_FAIL_COND(!vp);
+
+				Ref<RenderTargetTexture> rtt = vp->get_render_target_texture();
+				texture=rtt;
+				texture->connect("changed",this,"update");
+				item_rect_changed();
+			}
+		} break;
+		case NOTIFICATION_EXIT_SCENE: {
+
+			if (texture.is_valid()) {
+
+				texture->disconnect("changed",this,"update");
+				texture=Ref<Texture>();
+			}
+		} break;
+		case NOTIFICATION_DRAW: {
+
+			if (texture.is_null())
+				return;
+
+			RID ci = get_canvas_item();
+
+			/*
+			texture->draw(ci,Point2());
+			break;
+			*/
+
+			Size2i s;
+			Rect2i src_rect;
+
+			s = texture->get_size();
+
+			src_rect.size=s;
+
+			Point2i ofs=offset;
+			if (centered)
+				ofs-=s/2;
+
+			Rect2i dst_rect(ofs,s);
+			texture->draw_rect_region(ci,dst_rect,src_rect,modulate);
+
+		} break;
+	}
+}
+
+void ViewportSprite::set_viewport_path(const NodePath& p_viewport) {
+
+	viewport_path=p_viewport;
+	update();
+	if (!is_inside_scene())
+		return;
+
+	if (texture.is_valid()) {
+		texture->disconnect("changed",this,"update");
+		texture=Ref<Texture>();
+	}
+
+	if (viewport_path.is_empty())
+		return;
+
+
+	Node *n = get_node(viewport_path);
+	ERR_FAIL_COND(!n);
+	Viewport *vp=n->cast_to<Viewport>();
+	ERR_FAIL_COND(!vp);
+
+	Ref<RenderTargetTexture> rtt = vp->get_render_target_texture();
+	texture=rtt;
+
+	if (texture.is_valid()) {
+		texture->connect("changed",this,"update");
+	}
+
+	item_rect_changed();
+
+}
+
+NodePath ViewportSprite::get_viewport_path() const {
+
+	return viewport_path;
+}
+
+void ViewportSprite::set_centered(bool p_center) {
+
+	centered=p_center;
+	update();
+	item_rect_changed();
+}
+
+bool ViewportSprite::is_centered() const {
+
+	return centered;
+}
+
+void ViewportSprite::set_offset(const Point2& p_offset) {
+
+	offset=p_offset;
+	update();
+	item_rect_changed();
+}
+Point2 ViewportSprite::get_offset() const {
+
+	return offset;
+}
+void ViewportSprite::set_modulate(const Color& p_color) {
+
+	modulate=p_color;
+	update();
+}
+
+Color ViewportSprite::get_modulate() const{
+
+	return modulate;
+}
+
+
+Rect2 ViewportSprite::get_item_rect() const {
+
+	if (texture.is_null())
+		return Rect2(0,0,1,1);
+	//if (texture.is_null())
+	//	return CanvasItem::get_item_rect();
+
+	Size2i s;
+
+	s = texture->get_size();
+	Point2i ofs=offset;
+	if (centered)
+		ofs-=s/2;
+
+	if (s==Size2(0,0))
+		s=Size2(1,1);
+
+	return Rect2(ofs,s);
+}
+
+
+void ViewportSprite::_bind_methods() {
+
+	ObjectTypeDB::bind_method(_MD("set_viewport_path","path"),&ViewportSprite::set_viewport_path);
+	ObjectTypeDB::bind_method(_MD("get_viewport_path"),&ViewportSprite::get_viewport_path);
+
+	ObjectTypeDB::bind_method(_MD("set_centered","centered"),&ViewportSprite::set_centered);
+	ObjectTypeDB::bind_method(_MD("is_centered"),&ViewportSprite::is_centered);
+
+	ObjectTypeDB::bind_method(_MD("set_offset","offset"),&ViewportSprite::set_offset);
+	ObjectTypeDB::bind_method(_MD("get_offset"),&ViewportSprite::get_offset);
+
+	ObjectTypeDB::bind_method(_MD("set_modulate","modulate"),&ViewportSprite::set_modulate);
+	ObjectTypeDB::bind_method(_MD("get_modulate"),&ViewportSprite::get_modulate);
+
+	ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "viewport"), _SCS("set_viewport_path"),_SCS("get_viewport_path"));
+	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered"));
+	ADD_PROPERTY( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset"));
+	ADD_PROPERTY( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate"));
+
+}
+
+ViewportSprite::ViewportSprite() {
+
+	centered=true;
+	modulate=Color(1,1,1,1);
+}

+ 40 - 0
scene/2d/sprite.h

@@ -105,4 +105,44 @@ public:
 	Sprite();
 	Sprite();
 };
 };
 
 
+class ViewportSprite : public Node2D {
+
+	OBJ_TYPE( ViewportSprite, Node2D );
+
+	Ref<Texture> texture;
+	NodePath viewport_path;
+
+	bool centered;
+	Point2 offset;
+	Color modulate;
+
+protected:
+
+	void _notification(int p_what);
+
+	static void _bind_methods();;
+
+public:
+
+	virtual void edit_set_pivot(const Point2& p_pivot);
+	virtual Point2 edit_get_pivot() const;
+	virtual bool edit_has_pivot() const;
+
+	void set_viewport_path(const NodePath& p_viewport);
+	NodePath get_viewport_path() const;
+
+	void set_centered(bool p_center);
+	bool is_centered() const;
+
+	void set_offset(const Point2& p_offset);
+	Point2 get_offset() const;
+
+	void set_modulate(const Color& p_color);
+	Color get_modulate() const;
+
+	virtual Rect2 get_item_rect() const;
+
+	ViewportSprite();
+};
+
 #endif // SPRITE_H
 #endif // SPRITE_H

+ 1 - 0
scene/3d/quad.h

@@ -73,4 +73,5 @@ public:
 	Quad();
 	Quad();
 };
 };
 
 
+
 #endif // QUAD_H
 #endif // QUAD_H

+ 2 - 2
scene/gui/control.cpp

@@ -346,7 +346,7 @@ void Control::_notification(int p_notification) {
 			if (data.window==this) {
 			if (data.window==this) {
 
 
 				window = memnew( Window );
 				window = memnew( Window );
-				add_to_group("_gui_input");
+				add_to_group("_vp_gui_input"+itos(get_viewport()->get_instance_ID()));
 				add_to_group("windows");
 				add_to_group("windows");
 
 
 				window->tooltip_timer = memnew( Timer );
 				window->tooltip_timer = memnew( Timer );
@@ -401,7 +401,7 @@ void Control::_notification(int p_notification) {
 
 
 			if (window) {
 			if (window) {
 
 
-				remove_from_group("_gui_input");
+				remove_from_group("_vp_gui_input"+itos(get_viewport()->get_instance_ID()));
 				remove_from_group("windows");
 				remove_from_group("windows");
 				if (window->tooltip_timer)
 				if (window->tooltip_timer)
 					memdelete(window->tooltip_timer);
 					memdelete(window->tooltip_timer);

+ 54 - 0
scene/gui/file_dialog.cpp

@@ -156,11 +156,61 @@ void FileDialog::_action_pressed() {
 
 
 	if (mode==MODE_SAVE_FILE) {
 	if (mode==MODE_SAVE_FILE) {
 		
 		
+		String ext = f.extension();
+		bool valid=false;
+
+		if (filter->get_selected()==filter->get_item_count()-1) {
+			valid=true; //match none
+		} else if (filters.size()>1 && filter->get_selected()==0) {
+			// match all filters
+			for (int i=0;i<filters.size();i++) {
+
+				String flt=filters[i].get_slice(";",0);
+				for (int j=0;j<flt.get_slice_count(",");j++) {
+
+					String str = flt.get_slice(",",j).strip_edges();
+					if (f.match(str)) {
+						valid=true;
+						break;
+					}
+				}
+				if (valid)
+					break;
+			}
+		} else {
+			int idx=filter->get_selected();
+			if (filters.size()>1)
+				idx--;
+			if (idx>=0 && idx<filters.size()) {
+
+				String flt=filters[idx].get_slice(";",0);
+				for (int j=0;j<flt.get_slice_count(",");j++) {
+
+					String str = (flt.get_slice(",",j).strip_edges());
+					if (f.match(str)) {
+						valid=true;
+						break;
+					}
+				}
+			} else {
+				valid=true;
+			}
+		}
+
+
+		if (!valid) {
+
+			exterr->popup_centered_minsize(Size2(250,80));
+			return;
+
+		}
+
 		if (dir_access->file_exists(f)) {
 		if (dir_access->file_exists(f)) {
 			confirm_save->set_text("File Exists, Overwrite?");
 			confirm_save->set_text("File Exists, Overwrite?");
 			confirm_save->popup_centered(Size2(200,80));
 			confirm_save->popup_centered(Size2(200,80));
 		} else {
 		} else {
 			
 			
+
 			emit_signal("file_selected",f);
 			emit_signal("file_selected",f);
 			hide();
 			hide();
 		}
 		}
@@ -682,6 +732,10 @@ FileDialog::FileDialog() {
 	mkdirerr->set_text("Could not create folder.");
 	mkdirerr->set_text("Could not create folder.");
 	add_child(mkdirerr);
 	add_child(mkdirerr);
 
 
+	exterr = memnew( AcceptDialog );
+	exterr->set_text("Must use a valid extension.");
+	add_child(exterr);
+
 
 
 	//update_file_list();
 	//update_file_list();
 	update_filters();
 	update_filters();

+ 1 - 0
scene/gui/file_dialog.h

@@ -82,6 +82,7 @@ private:
 	Tree *tree;
 	Tree *tree;
 	LineEdit *file;
 	LineEdit *file;
 	AcceptDialog *mkdirerr;
 	AcceptDialog *mkdirerr;
+	AcceptDialog *exterr;
 	OptionButton *filter;
 	OptionButton *filter;
 	DirAccess *dir_access;
 	DirAccess *dir_access;
 	ConfirmationDialog *confirm_save;
 	ConfirmationDialog *confirm_save;

+ 1 - 1
scene/gui/menu_button.cpp

@@ -141,7 +141,7 @@ MenuButton::MenuButton() {
 	popup->hide();
 	popup->hide();
 	add_child(popup);
 	add_child(popup);
 	popup->set_as_toplevel(true);
 	popup->set_as_toplevel(true);
-	add_to_group("unhandled_key_input");
+	set_process_unhandled_key_input(true);
 	set_click_on_press(true);
 	set_click_on_press(true);
 }
 }
 
 

+ 61 - 6
scene/main/node.cpp

@@ -33,6 +33,7 @@
 #include "scene/scene_string_names.h"
 #include "scene/scene_string_names.h"
 #include "scene/resources/packed_scene.h"
 #include "scene/resources/packed_scene.h"
 #include "io/resource_loader.h"
 #include "io/resource_loader.h"
+#include "viewport.h"
 
 
 VARIANT_ENUM_CAST(Node::PauseMode);
 VARIANT_ENUM_CAST(Node::PauseMode);
 
 
@@ -76,12 +77,25 @@ void Node::_notification(int p_notification) {
 				data.pause_owner=this;
 				data.pause_owner=this;
 			}
 			}
 
 
+			if (data.input)
+				add_to_group("_vp_input"+itos(get_viewport()->get_instance_ID()));
+			if (data.unhandled_input)
+				add_to_group("_vp_unhandled_input"+itos(get_viewport()->get_instance_ID()));
+			if (data.unhandled_key_input)
+				add_to_group("_vp_unhandled_key_input"+itos(get_viewport()->get_instance_ID()));
+
 			get_scene()->node_count++;
 			get_scene()->node_count++;
 
 
 		} break;
 		} break;
 		case NOTIFICATION_EXIT_SCENE: {
 		case NOTIFICATION_EXIT_SCENE: {
 
 
 			get_scene()->node_count--;
 			get_scene()->node_count--;
+			if (data.input)
+				remove_from_group("_vp_input"+itos(get_viewport()->get_instance_ID()));
+			if (data.unhandled_input)
+				remove_from_group("_vp_unhandled_input"+itos(get_viewport()->get_instance_ID()));
+			if (data.unhandled_key_input)
+				remove_from_group("_vp_unhandled_key_input"+itos(get_viewport()->get_instance_ID()));
 
 
 		} break;
 		} break;
 		case NOTIFICATION_READY: {
 		case NOTIFICATION_READY: {
@@ -148,6 +162,9 @@ void Node::_propagate_enter_scene() {
 		data.depth=1;
 		data.depth=1;
 	}
 	}
 	
 	
+	data.viewport = cast_to<Viewport>();
+	if (!data.viewport)
+		data.viewport = data.parent->data.viewport;
 
 
 	data.inside_scene=true;
 	data.inside_scene=true;
 
 
@@ -158,6 +175,7 @@ void Node::_propagate_enter_scene() {
 		data.scene->add_to_group(*K,this);
 		data.scene->add_to_group(*K,this);
 	}
 	}
 
 
+
 	notification(NOTIFICATION_ENTER_SCENE);
 	notification(NOTIFICATION_ENTER_SCENE);
 
 
 	if (get_script_instance()) {
 	if (get_script_instance()) {
@@ -216,6 +234,8 @@ void Node::_propagate_exit_scene() {
 		data.scene->remove_from_group(*K,this);
 		data.scene->remove_from_group(*K,this);
 	}
 	}
 
 
+	data.viewport = NULL;
+
 	if (data.scene)
 	if (data.scene)
 		data.scene->tree_changed();
 		data.scene->tree_changed();
 
 
@@ -324,7 +344,7 @@ void Node::set_pause_mode(PauseMode p_mode) {
 	if (data.pause_mode==PAUSE_MODE_INHERIT) {
 	if (data.pause_mode==PAUSE_MODE_INHERIT) {
 
 
 		if (data.parent)
 		if (data.parent)
-			data.parent->data.pause_owner;
+			owner=data.parent->data.pause_owner;
 	} else {
 	} else {
 		owner=this;
 		owner=this;
 	}
 	}
@@ -421,11 +441,17 @@ void Node::set_process_input(bool p_enable) {
 
 
 	if (p_enable==data.input)
 	if (p_enable==data.input)
 		return;
 		return;
+
 	data.input=p_enable;
 	data.input=p_enable;
+	if (!is_inside_scene())
+		return;
+
 	if (p_enable)
 	if (p_enable)
-		add_to_group("input");
+		add_to_group("_vp_input"+itos(get_viewport()->get_instance_ID()));
 	else
 	else
-		remove_from_group("input");
+		remove_from_group("_vp_input"+itos(get_viewport()->get_instance_ID()));
+
+
 }
 }
 
 
 bool Node::is_processing_input() const {
 bool Node::is_processing_input() const {
@@ -437,18 +463,41 @@ void Node::set_process_unhandled_input(bool p_enable) {
 	if (p_enable==data.unhandled_input)
 	if (p_enable==data.unhandled_input)
 		return;
 		return;
 	data.unhandled_input=p_enable;
 	data.unhandled_input=p_enable;
+	if (!is_inside_scene())
+		return;
 
 
 	if (p_enable)
 	if (p_enable)
-		add_to_group("unhandled_input");
+		add_to_group("_vp_unhandled_input"+itos(get_viewport()->get_instance_ID()));
 	else
 	else
-		remove_from_group("unhandled_input");
+		remove_from_group("_vp_unhandled_input"+itos(get_viewport()->get_instance_ID()));
 }
 }
 
 
+
 bool Node::is_processing_unhandled_input() const {
 bool Node::is_processing_unhandled_input() const {
 	return data.unhandled_input;
 	return data.unhandled_input;
 }
 }
 
 
 
 
+void Node::set_process_unhandled_key_input(bool p_enable) {
+
+	if (p_enable==data.unhandled_key_input)
+		return;
+	data.unhandled_key_input=p_enable;
+	if (!is_inside_scene())
+		return;
+
+	if (p_enable)
+		add_to_group("_vp_unhandled_key_input"+itos(get_viewport()->get_instance_ID()));
+	else
+		remove_from_group("_vp_unhandled_key_input"+itos(get_viewport()->get_instance_ID()));
+}
+
+
+bool Node::is_processing_unhandled_key_input() const {
+	return data.unhandled_key_input;
+}
+
+
 StringName Node::get_name() const {
 StringName Node::get_name() const {
 	
 	
 	return data.name;
 	return data.name;
@@ -1682,6 +1731,8 @@ void Node::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("is_processing_input"),&Node::is_processing_input);
 	ObjectTypeDB::bind_method(_MD("is_processing_input"),&Node::is_processing_input);
 	ObjectTypeDB::bind_method(_MD("set_process_unhandled_input","enable"),&Node::set_process_unhandled_input);
 	ObjectTypeDB::bind_method(_MD("set_process_unhandled_input","enable"),&Node::set_process_unhandled_input);
 	ObjectTypeDB::bind_method(_MD("is_processing_unhandled_input"),&Node::is_processing_unhandled_input);
 	ObjectTypeDB::bind_method(_MD("is_processing_unhandled_input"),&Node::is_processing_unhandled_input);
+	ObjectTypeDB::bind_method(_MD("set_process_unhandled_key_input","enable"),&Node::set_process_unhandled_key_input);
+	ObjectTypeDB::bind_method(_MD("is_processing_unhandled_key_input"),&Node::is_processing_unhandled_key_input);
 	ObjectTypeDB::bind_method(_MD("set_pause_mode","mode"),&Node::set_pause_mode);
 	ObjectTypeDB::bind_method(_MD("set_pause_mode","mode"),&Node::set_pause_mode);
 	ObjectTypeDB::bind_method(_MD("get_pause_mode"),&Node::get_pause_mode);
 	ObjectTypeDB::bind_method(_MD("get_pause_mode"),&Node::get_pause_mode);
 	ObjectTypeDB::bind_method(_MD("can_process"),&Node::can_process);
 	ObjectTypeDB::bind_method(_MD("can_process"),&Node::can_process);
@@ -1693,6 +1744,8 @@ void Node::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("duplicate:Node"),&Node::duplicate);
 	ObjectTypeDB::bind_method(_MD("duplicate:Node"),&Node::duplicate);
 	ObjectTypeDB::bind_method(_MD("replace_by","node:Node","keep_data"),&Node::replace_by,DEFVAL(false));
 	ObjectTypeDB::bind_method(_MD("replace_by","node:Node","keep_data"),&Node::replace_by,DEFVAL(false));
 
 
+	ObjectTypeDB::bind_method(_MD("get_viewport"),&Node::get_viewport);
+
 	ObjectTypeDB::bind_method(_MD("queue_free"),&Node::queue_delete);
 	ObjectTypeDB::bind_method(_MD("queue_free"),&Node::queue_delete);
 
 
 	BIND_CONSTANT( NOTIFICATION_ENTER_SCENE );
 	BIND_CONSTANT( NOTIFICATION_ENTER_SCENE );
@@ -1748,13 +1801,15 @@ Node::Node() {
 	data.inside_scene=false;
 	data.inside_scene=false;
 
 
 	data.owner=NULL;
 	data.owner=NULL;
-	data.OW=false;
+	data.OW=NULL;
 	data.input=false;
 	data.input=false;
 	data.unhandled_input=false;
 	data.unhandled_input=false;
+	data.unhandled_key_input=false;
 	data.pause_mode=PAUSE_MODE_INHERIT;
 	data.pause_mode=PAUSE_MODE_INHERIT;
 	data.pause_owner=NULL;
 	data.pause_owner=NULL;
 	data.parent_owned=false;
 	data.parent_owned=false;
 	data.in_constructor=true;
 	data.in_constructor=true;
+	data.viewport=NULL;
 }
 }
 
 
 Node::~Node() {
 Node::~Node() {

+ 9 - 0
scene/main/node.h

@@ -37,6 +37,7 @@
 #include "scene/main/scene_main_loop.h"
 #include "scene/main/scene_main_loop.h"
 
 
 
 
+class Viewport;
 class Node : public Object {
 class Node : public Object {
 
 
 	OBJ_TYPE( Node, Object );
 	OBJ_TYPE( Node, Object );
@@ -82,6 +83,8 @@ private:
 		SceneMainLoop *scene;
 		SceneMainLoop *scene;
 		bool inside_scene;
 		bool inside_scene;
 
 
+		Viewport *viewport;
+
 				
 				
 		HashMap< StringName, GroupData,StringNameHasher>  grouped;
 		HashMap< StringName, GroupData,StringNameHasher>  grouped;
 		List<Node*>::Element *OW; // owned element
 		List<Node*>::Element *OW; // owned element
@@ -95,6 +98,7 @@ private:
 
 
 		bool input;
 		bool input;
 		bool unhandled_input;
 		bool unhandled_input;
+		bool unhandled_key_input;
 
 
 		bool parent_owned;
 		bool parent_owned;
 		bool in_constructor;
 		bool in_constructor;
@@ -237,6 +241,9 @@ public:
 	void set_process_unhandled_input(bool p_enable);
 	void set_process_unhandled_input(bool p_enable);
 	bool is_processing_unhandled_input() const;
 	bool is_processing_unhandled_input() const;
 
 
+	void set_process_unhandled_key_input(bool p_enable);
+	bool is_processing_unhandled_key_input() const;
+
 	int get_position_in_parent() const;
 	int get_position_in_parent() const;
 
 
 	Node *duplicate() const;
 	Node *duplicate() const;
@@ -266,6 +273,8 @@ public:
 
 
 	void force_parent_owned() { data.parent_owned=true; } //hack to avoid duplicate nodes
 	void force_parent_owned() { data.parent_owned=true; } //hack to avoid duplicate nodes
 
 
+	_FORCE_INLINE_ Viewport *get_viewport() const { return data.viewport; }
+
 	/* CANVAS */
 	/* CANVAS */
 
 
 	Node();
 	Node();

+ 13 - 6
scene/main/scene_main_loop.cpp

@@ -340,7 +340,7 @@ void SceneMainLoop::input_event( const InputEvent& p_event ) {
 
 
 
 
 	InputEvent ev = p_event;
 	InputEvent ev = p_event;
-
+#if 0
 	switch(ev.type) {
 	switch(ev.type) {
 
 
 		case InputEvent::MOUSE_BUTTON: {
 		case InputEvent::MOUSE_BUTTON: {
@@ -391,15 +391,12 @@ void SceneMainLoop::input_event( const InputEvent& p_event ) {
 		} break;
 		} break;
 	}
 	}
 
 
-
+#endif
 
 
 	MainLoop::input_event(p_event);
 	MainLoop::input_event(p_event);
-
+#if 0
 	_call_input_pause("input","_input",ev);
 	_call_input_pause("input","_input",ev);
 
 
-
-
-
 	call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"_gui_input","_gui_input",p_event); //special one for GUI, as controls use their own process check
 	call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"_gui_input","_gui_input",p_event); //special one for GUI, as controls use their own process check
 
 
 	//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"input","_input",ev);
 	//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"input","_input",ev);
@@ -416,7 +413,11 @@ void SceneMainLoop::input_event( const InputEvent& p_event ) {
 	//}
 	//}
 
 
 	//transform for the rest
 	//transform for the rest
+#else
+
+	call_group(GROUP_CALL_REALTIME,"_viewports","_vp_input",p_event); //special one for GUI, as controls use their own process check
 
 
+#endif
 	if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_remote() && ev.type==InputEvent::KEY && ev.key.pressed && !ev.key.echo && ev.key.scancode==KEY_F8) {
 	if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_remote() && ev.type==InputEvent::KEY && ev.key.pressed && !ev.key.echo && ev.key.scancode==KEY_F8) {
 
 
 		ScriptDebugger::get_singleton()->request_quit();
 		ScriptDebugger::get_singleton()->request_quit();
@@ -429,13 +430,19 @@ void SceneMainLoop::input_event( const InputEvent& p_event ) {
 	root_lock++;
 	root_lock++;
 
 
 	if (!input_handled) {
 	if (!input_handled) {
+
+#if 0
 		_call_input_pause("unhandled_input","_unhandled_input",ev);
 		_call_input_pause("unhandled_input","_unhandled_input",ev);
 		//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_input","_unhandled_input",ev);
 		//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_input","_unhandled_input",ev);
 		if (!input_handled && ev.type==InputEvent::KEY) {
 		if (!input_handled && ev.type==InputEvent::KEY) {
 			_call_input_pause("unhandled_key_input","_unhandled_key_input",ev);
 			_call_input_pause("unhandled_key_input","_unhandled_key_input",ev);
 			//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_key_input","_unhandled_key_input",ev);
 			//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_key_input","_unhandled_key_input",ev);
 		}
 		}
+#else
+
+		call_group(GROUP_CALL_REALTIME,"_viewports","_vp_unhandled_input",p_event); //special one for GUI, as controls use their own process check
 
 
+#endif
 		input_handled=true;
 		input_handled=true;
 		_flush_ugc();
 		_flush_ugc();
 		root_lock--;
 		root_lock--;

+ 2 - 0
scene/main/scene_main_loop.h

@@ -129,6 +129,8 @@ friend class Node;
 //optimization
 //optimization
 friend class CanvasItem;
 friend class CanvasItem;
 friend class Spatial;
 friend class Spatial;
+friend class Viewport;
+
 	SelfList<Node>::List xform_change_list;
 	SelfList<Node>::List xform_change_list;
 
 
 protected:
 protected:

+ 134 - 3
scene/main/viewport.cpp

@@ -129,6 +129,9 @@ void Viewport::_update_rect() {
 	}
 	}
 
 
 	emit_signal("size_changed");
 	emit_signal("size_changed");
+	render_target_texture->emit_changed();
+
+
 }
 }
 
 
 void Viewport::_parent_resized() {
 void Viewport::_parent_resized() {
@@ -658,6 +661,7 @@ void Viewport::set_size_override(bool p_enable, const Size2& p_size, const Vecto
 	_update_rect();
 	_update_rect();
 	_update_stretch_transform();
 	_update_stretch_transform();
 
 
+
 }
 }
 
 
 Size2 Viewport::get_size_override() const {
 Size2 Viewport::get_size_override() const {
@@ -711,6 +715,8 @@ void Viewport::set_as_render_target(bool p_enable){
 
 
 		render_target_texture_rid=RID();
 		render_target_texture_rid=RID();
 	}
 	}
+
+	render_target_texture->emit_changed();
 }
 }
 
 
 bool Viewport::is_set_as_render_target() const{
 bool Viewport::is_set_as_render_target() const{
@@ -743,6 +749,120 @@ Ref<RenderTargetTexture> Viewport::get_render_target_texture() const {
 	return render_target_texture;
 	return render_target_texture;
 }
 }
 
 
+void Viewport::set_render_target_vflip(bool p_enable) {
+
+	render_target_vflip=p_enable;
+	VisualServer::get_singleton()->viewport_set_render_target_vflip(viewport,p_enable);
+}
+
+bool Viewport::get_render_target_vflip() const{
+
+	return render_target_vflip;
+}
+
+
+void Viewport::_make_input_local(InputEvent& ev) {
+
+	switch(ev.type) {
+
+		case InputEvent::MOUSE_BUTTON: {
+
+			Matrix32 ai = get_final_transform().affine_inverse();
+			Vector2 g = ai.xform(Vector2(ev.mouse_button.global_x,ev.mouse_button.global_y));
+			Vector2 l = ai.xform(Vector2(ev.mouse_button.x,ev.mouse_button.y));
+			ev.mouse_button.x=l.x;
+			ev.mouse_button.y=l.y;
+			ev.mouse_button.global_x=g.x;
+			ev.mouse_button.global_y=g.y;
+
+		} break;
+		case InputEvent::MOUSE_MOTION: {
+
+			Matrix32 ai = get_final_transform().affine_inverse();
+			Vector2 g = ai.xform(Vector2(ev.mouse_motion.global_x,ev.mouse_motion.global_y));
+			Vector2 l = ai.xform(Vector2(ev.mouse_motion.x,ev.mouse_motion.y));
+			Vector2 r = ai.xform(Vector2(ev.mouse_motion.relative_x,ev.mouse_motion.relative_y));
+			ev.mouse_motion.x=l.x;
+			ev.mouse_motion.y=l.y;
+			ev.mouse_motion.global_x=g.x;
+			ev.mouse_motion.global_y=g.y;
+			ev.mouse_motion.relative_x=r.x;
+			ev.mouse_motion.relative_y=r.y;
+
+		} break;
+		case InputEvent::SCREEN_TOUCH: {
+
+			Matrix32 ai = get_final_transform().affine_inverse();
+			Vector2 t = ai.xform(Vector2(ev.screen_touch.x,ev.screen_touch.y));
+			ev.screen_touch.x=t.x;
+			ev.screen_touch.y=t.y;
+
+		} break;
+		case InputEvent::SCREEN_DRAG: {
+
+			Matrix32 ai = get_final_transform().affine_inverse();
+			Vector2 t = ai.xform(Vector2(ev.screen_drag.x,ev.screen_drag.y));
+			Vector2 r = ai.xform(Vector2(ev.screen_drag.relative_x,ev.screen_drag.relative_y));
+			Vector2 s = ai.xform(Vector2(ev.screen_drag.speed_x,ev.screen_drag.speed_y));
+			ev.screen_drag.x=t.x;
+			ev.screen_drag.y=t.y;
+			ev.screen_drag.relative_x=r.x;
+			ev.screen_drag.relative_y=r.y;
+			ev.screen_drag.speed_x=s.x;
+			ev.screen_drag.speed_y=s.y;
+		} break;
+	}
+
+}
+
+
+void Viewport::_vp_input(const InputEvent& p_ev) {
+
+	if (render_target)
+		return; //if render target, can't get input events
+
+	//this one handles system input, p_ev are in system coordinates
+	//they are converted to viewport coordinates
+
+	InputEvent ev = p_ev;
+	_make_input_local(ev);
+	input(ev);
+
+}
+
+void Viewport::_vp_unhandled_input(const InputEvent& p_ev) {
+
+	if (render_target)
+		return; //if render target, can't get input events
+
+	//this one handles system input, p_ev are in system coordinates
+	//they are converted to viewport coordinates
+
+	InputEvent ev = p_ev;
+	_make_input_local(ev);
+	unhandled_input(ev);
+
+}
+
+void Viewport::input(const InputEvent& p_event) {
+
+	ERR_FAIL_COND(!is_inside_scene());
+	get_scene()->_call_input_pause(input_group,"_input",p_event);
+	get_scene()->call_group(SceneMainLoop::GROUP_CALL_REVERSE|SceneMainLoop::GROUP_CALL_REALTIME|SceneMainLoop::GROUP_CALL_MULIILEVEL,gui_input_group,"_gui_input",p_event); //special one for GUI, as controls use their own process check
+}
+
+void Viewport::unhandled_input(const InputEvent& p_event) {
+
+	ERR_FAIL_COND(!is_inside_scene());
+
+	get_scene()->_call_input_pause(unhandled_input_group,"_unhandled_input",p_event);
+	//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_input","_unhandled_input",ev);
+	if (!get_scene()->input_handled && p_event.type==InputEvent::KEY) {
+		get_scene()->_call_input_pause(unhandled_key_input_group,"_unhandled_key_input",p_event);
+		//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_key_input","_unhandled_key_input",ev);
+	}
+}
+
 
 
 void Viewport::_bind_methods() {
 void Viewport::_bind_methods() {
 
 
@@ -770,6 +890,8 @@ void Viewport::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("_parent_visibility_changed"), &Viewport::_parent_visibility_changed);
 	ObjectTypeDB::bind_method(_MD("_parent_visibility_changed"), &Viewport::_parent_visibility_changed);
 
 
 	ObjectTypeDB::bind_method(_MD("_parent_resized"), &Viewport::_parent_resized);
 	ObjectTypeDB::bind_method(_MD("_parent_resized"), &Viewport::_parent_resized);
+	ObjectTypeDB::bind_method(_MD("_vp_input"), &Viewport::_vp_input);
+	ObjectTypeDB::bind_method(_MD("_vp_unhandled_input"), &Viewport::_vp_unhandled_input);
 
 
 	ObjectTypeDB::bind_method(_MD("set_size_override","enable","size","margin"), &Viewport::set_size_override,DEFVAL(Size2(-1,-1)),DEFVAL(Size2(0,0)));
 	ObjectTypeDB::bind_method(_MD("set_size_override","enable","size","margin"), &Viewport::set_size_override,DEFVAL(Size2(-1,-1)),DEFVAL(Size2(0,0)));
 	ObjectTypeDB::bind_method(_MD("get_size_override"), &Viewport::get_size_override);
 	ObjectTypeDB::bind_method(_MD("get_size_override"), &Viewport::get_size_override);
@@ -782,14 +904,17 @@ void Viewport::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_as_render_target","enable"), &Viewport::set_as_render_target);
 	ObjectTypeDB::bind_method(_MD("set_as_render_target","enable"), &Viewport::set_as_render_target);
 	ObjectTypeDB::bind_method(_MD("is_set_as_render_target"), &Viewport::is_set_as_render_target);
 	ObjectTypeDB::bind_method(_MD("is_set_as_render_target"), &Viewport::is_set_as_render_target);
 
 
+	ObjectTypeDB::bind_method(_MD("set_render_target_vflip","enable"), &Viewport::set_render_target_vflip);
+	ObjectTypeDB::bind_method(_MD("get_render_target_vflip"), &Viewport::get_render_target_vflip);
+
 	ObjectTypeDB::bind_method(_MD("set_render_target_update_mode","mode"), &Viewport::set_render_target_update_mode);
 	ObjectTypeDB::bind_method(_MD("set_render_target_update_mode","mode"), &Viewport::set_render_target_update_mode);
 	ObjectTypeDB::bind_method(_MD("get_render_target_update_mode"), &Viewport::get_render_target_update_mode);
 	ObjectTypeDB::bind_method(_MD("get_render_target_update_mode"), &Viewport::get_render_target_update_mode);
 
 
 	ObjectTypeDB::bind_method(_MD("get_render_target_texture:RenderTargetTexture"), &Viewport::get_render_target_texture);
 	ObjectTypeDB::bind_method(_MD("get_render_target_texture:RenderTargetTexture"), &Viewport::get_render_target_texture);
 
 
-
 	ObjectTypeDB::bind_method(_MD("get_viewport"), &Viewport::get_viewport);
 	ObjectTypeDB::bind_method(_MD("get_viewport"), &Viewport::get_viewport);
-
+	ObjectTypeDB::bind_method(_MD("input","local_event"), &Viewport::input);
+	ObjectTypeDB::bind_method(_MD("unhandled_input","local_event"), &Viewport::unhandled_input);
 
 
 	ObjectTypeDB::bind_method(_MD("update_worlds"), &Viewport::update_worlds);
 	ObjectTypeDB::bind_method(_MD("update_worlds"), &Viewport::update_worlds);
 
 
@@ -806,6 +931,7 @@ void Viewport::_bind_methods() {
 //	ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"world_2d",PROPERTY_HINT_RESOURCE_TYPE,"World2D"), _SCS("set_world_2d"), _SCS("get_world_2d") );
 //	ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"world_2d",PROPERTY_HINT_RESOURCE_TYPE,"World2D"), _SCS("set_world_2d"), _SCS("get_world_2d") );
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transparent_bg"), _SCS("set_transparent_background"), _SCS("has_transparent_background") );
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transparent_bg"), _SCS("set_transparent_background"), _SCS("has_transparent_background") );
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/enabled"), _SCS("set_as_render_target"), _SCS("is_set_as_render_target") );
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/enabled"), _SCS("set_as_render_target"), _SCS("is_set_as_render_target") );
+	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/v_flip"), _SCS("set_render_target_vflip"), _SCS("get_render_target_vflip") );
 	ADD_PROPERTY( PropertyInfo(Variant::INT,"render_target/update_mode",PROPERTY_HINT_ENUM,"Disabled,Once,When Visible,Always"), _SCS("set_render_target_update_mode"), _SCS("get_render_target_update_mode") );
 	ADD_PROPERTY( PropertyInfo(Variant::INT,"render_target/update_mode",PROPERTY_HINT_ENUM,"Disabled,Once,When Visible,Always"), _SCS("set_render_target_update_mode"), _SCS("get_render_target_update_mode") );
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"audio_listener/enable_2d"), _SCS("set_as_audio_listener_2d"), _SCS("is_audio_listener_2d") );
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"audio_listener/enable_2d"), _SCS("set_as_audio_listener_2d"), _SCS("is_audio_listener_2d") );
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"audio_listener/enable_3d"), _SCS("set_as_audio_listener"), _SCS("is_audio_listener") );
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"audio_listener/enable_3d"), _SCS("set_as_audio_listener"), _SCS("is_audio_listener") );
@@ -839,10 +965,15 @@ Viewport::Viewport() {
 	size_override_stretch=false;
 	size_override_stretch=false;
 	size_override_size=Size2(1,1);
 	size_override_size=Size2(1,1);
 	render_target=false;
 	render_target=false;
+	render_target_vflip=false;
 	render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE;
 	render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE;
 	render_target_texture = Ref<RenderTargetTexture>( memnew( RenderTargetTexture(this) ) );
 	render_target_texture = Ref<RenderTargetTexture>( memnew( RenderTargetTexture(this) ) );
 
 
-
+	String id=itos(get_instance_ID());
+	input_group = "_vp_input"+id;
+	gui_input_group = "_vp_gui_input"+id;
+	unhandled_input_group = "_vp_unhandled_input"+id;
+	unhandled_key_input_group = "_vp_unhandled_key_input"+id;
 
 
 
 
 }
 }

+ 17 - 2
scene/main/viewport.h

@@ -110,6 +110,7 @@ friend class RenderTargetTexture;
 
 
 
 
 	bool transparent_bg;
 	bool transparent_bg;
+	bool render_target_vflip;
 
 
 	void _update_rect();
 	void _update_rect();
 
 
@@ -120,6 +121,11 @@ friend class RenderTargetTexture;
 	Ref<World2D> world_2d;
 	Ref<World2D> world_2d;
 	Ref<World> world;
 	Ref<World> world;
 
 
+	StringName input_group;
+	StringName gui_input_group;
+	StringName unhandled_input_group;
+	StringName unhandled_key_input_group;
+
 	void _update_listener();
 	void _update_listener();
 	void _update_listener_2d();
 	void _update_listener_2d();
 
 
@@ -142,6 +148,10 @@ friend class RenderTargetTexture;
 	void _vp_enter_scene();
 	void _vp_enter_scene();
 	void _vp_exit_scene();
 	void _vp_exit_scene();
 
 
+	void _vp_input(const InputEvent& p_ev);
+	void _vp_unhandled_input(const InputEvent& p_ev);
+	void _make_input_local(InputEvent& ev);
+
 friend class Camera;
 friend class Camera;
 	void _camera_transform_changed_notify();
 	void _camera_transform_changed_notify();
 	void _set_camera(Camera* p_camera);
 	void _set_camera(Camera* p_camera);
@@ -190,10 +200,12 @@ public:
 	void set_size_override_stretch(bool p_enable);
 	void set_size_override_stretch(bool p_enable);
 	bool is_size_override_stretch_enabled() const;
 	bool is_size_override_stretch_enabled() const;
 
 
-
-
 	void set_as_render_target(bool p_enable);
 	void set_as_render_target(bool p_enable);
 	bool is_set_as_render_target() const;
 	bool is_set_as_render_target() const;
+
+	void set_render_target_vflip(bool p_enable);
+	bool get_render_target_vflip() const;
+
 	void set_render_target_update_mode(RenderTargetUpdateMode p_mode);
 	void set_render_target_update_mode(RenderTargetUpdateMode p_mode);
 	RenderTargetUpdateMode get_render_target_update_mode() const;
 	RenderTargetUpdateMode get_render_target_update_mode() const;
 	Ref<RenderTargetTexture> get_render_target_texture() const;
 	Ref<RenderTargetTexture> get_render_target_texture() const;
@@ -201,6 +213,9 @@ public:
 	void queue_screen_capture();
 	void queue_screen_capture();
 	Image get_screen_capture() const;
 	Image get_screen_capture() const;
 
 
+	void input(const InputEvent& p_event);
+	void unhandled_input(const InputEvent& p_event);
+
 	Viewport();	
 	Viewport();	
 	~Viewport();
 	~Viewport();
 
 

+ 1 - 0
scene/register_scene_types.cpp

@@ -446,6 +446,7 @@ void register_scene_types() {
 	ObjectTypeDB::register_type<Particles2D>();
 	ObjectTypeDB::register_type<Particles2D>();
 	ObjectTypeDB::register_type<ParticleAttractor2D>();
 	ObjectTypeDB::register_type<ParticleAttractor2D>();
 	ObjectTypeDB::register_type<Sprite>();
 	ObjectTypeDB::register_type<Sprite>();
+	ObjectTypeDB::register_type<ViewportSprite>();
 	ObjectTypeDB::register_type<SpriteFrames>();
 	ObjectTypeDB::register_type<SpriteFrames>();
 	ObjectTypeDB::register_type<AnimatedSprite>();
 	ObjectTypeDB::register_type<AnimatedSprite>();
 	ObjectTypeDB::register_type<Position2D>();
 	ObjectTypeDB::register_type<Position2D>();

+ 1 - 1
scene/resources/default_theme/default_theme.cpp

@@ -583,7 +583,7 @@ void make_default_theme() {
 
 
 	t->set_stylebox("panel","PanelContainer", tc_sb );
 	t->set_stylebox("panel","PanelContainer", tc_sb );
 
 
-	t->set_stylebox( "logo","Icons", make_icon(logo_png) );
+	t->set_icon( "logo","Icons", make_icon(logo_png) );
 
 
 	Theme::set_default( t );
 	Theme::set_default( t );
 	Theme::set_default_icon( make_icon(error_icon_png) );
 	Theme::set_default_icon( make_icon(error_icon_png) );

+ 1 - 1
servers/audio/audio_server_sw.cpp

@@ -927,7 +927,7 @@ AudioServerSW::AudioServerSW(SampleManagerSW *p_sample_manager) {
 
 
 	sample_manager=p_sample_manager;
 	sample_manager=p_sample_manager;
 	String interp = GLOBAL_DEF("audio/mixer_interp","linear");
 	String interp = GLOBAL_DEF("audio/mixer_interp","linear");
-	Globals::get_singleton()->set_custom_property_info("audio/mixer",PropertyInfo(Variant::STRING,"audio/mixer",PROPERTY_HINT_ENUM,"raw,linear,cubic"));
+	Globals::get_singleton()->set_custom_property_info("audio/mixer_interp",PropertyInfo(Variant::STRING,"audio/mixer_interp",PROPERTY_HINT_ENUM,"raw,linear,cubic"));
 	if (interp=="raw")
 	if (interp=="raw")
 		mixer_interp=AudioMixerSW::INTERPOLATION_RAW;
 		mixer_interp=AudioMixerSW::INTERPOLATION_RAW;
 	else if (interp=="cubic")
 	else if (interp=="cubic")

+ 1 - 1
servers/visual/rasterizer.h

@@ -444,7 +444,7 @@ public:
 	virtual void begin_frame()=0;
 	virtual void begin_frame()=0;
 	
 	
 	virtual void set_viewport(const VS::ViewportRect& p_viewport)=0;
 	virtual void set_viewport(const VS::ViewportRect& p_viewport)=0;
-	virtual void set_render_target(RID p_render_target)=0;
+	virtual void set_render_target(RID p_render_target,bool p_transparent_bg=false,bool p_vflip=false)=0;
 	virtual void clear_viewport(const Color& p_color)=0;
 	virtual void clear_viewport(const Color& p_color)=0;
 	virtual void capture_viewport(Image* r_capture)=0;
 	virtual void capture_viewport(Image* r_capture)=0;
 	
 	

+ 1 - 1
servers/visual/rasterizer_dummy.cpp

@@ -1384,7 +1384,7 @@ void RasterizerDummy::set_viewport(const VS::ViewportRect& p_viewport) {
 
 
 }
 }
 
 
-void RasterizerDummy::set_render_target(RID p_render_target) {
+void RasterizerDummy::set_render_target(RID p_render_target,bool p_transparent_bg) {
 
 
 
 
 }
 }

+ 1 - 1
servers/visual/rasterizer_dummy.h

@@ -627,7 +627,7 @@ public:
 	virtual void begin_frame();
 	virtual void begin_frame();
 
 
 	virtual void set_viewport(const VS::ViewportRect& p_viewport);
 	virtual void set_viewport(const VS::ViewportRect& p_viewport);
-	virtual void set_render_target(RID p_render_target);
+	virtual void set_render_target(RID p_render_target,bool p_transparent_bg=false);
 	virtual void clear_viewport(const Color& p_color);
 	virtual void clear_viewport(const Color& p_color);
 	virtual void capture_viewport(Image* r_capture);
 	virtual void capture_viewport(Image* r_capture);
 
 

+ 23 - 1
servers/visual/visual_server_raster.cpp

@@ -1136,6 +1136,25 @@ RID VisualServerRaster::viewport_get_render_target_texture(RID p_viewport) const
 
 
 }
 }
 
 
+void VisualServerRaster::viewport_set_render_target_vflip(RID p_viewport,bool p_enable) {
+
+	Viewport *viewport = viewport_owner.get( p_viewport );
+	ERR_FAIL_COND(!viewport);
+
+	viewport->render_target_vflip=p_enable;
+
+}
+
+bool VisualServerRaster::viewport_get_render_target_vflip(RID p_viewport) const{
+
+	const Viewport *viewport = viewport_owner.get( p_viewport );
+	ERR_FAIL_COND_V(!viewport,false);
+
+	return viewport->render_target_vflip;
+
+}
+
+
 void VisualServerRaster::viewport_queue_screen_capture(RID p_viewport) {
 void VisualServerRaster::viewport_queue_screen_capture(RID p_viewport) {
 
 
 	VS_CHANGED;
 	VS_CHANGED;
@@ -1164,6 +1183,9 @@ void VisualServerRaster::viewport_set_rect(RID p_viewport,const ViewportRect& p_
 	ERR_FAIL_COND(!viewport);
 	ERR_FAIL_COND(!viewport);
 	
 	
 	viewport->rect=p_rect;
 	viewport->rect=p_rect;
+	if (viewport->render_target.is_valid()) {
+		rasterizer->render_target_set_size(viewport->render_target,viewport->rect.width,viewport->rect.height);
+	}
 }
 }
 
 
 
 
@@ -5450,7 +5472,7 @@ void VisualServerRaster::_draw_viewports() {
 			continue;
 			continue;
 		}
 		}
 
 
-		rasterizer->set_render_target(vp->render_target);
+		rasterizer->set_render_target(vp->render_target,vp->transparent_bg,vp->render_target_vflip);
 		_draw_viewport(vp,0,0,vp->rect.width,vp->rect.height);
 		_draw_viewport(vp,0,0,vp->rect.width,vp->rect.height);
 
 
 		if ( (vp->queue_capture && vp->render_target_update_mode==RENDER_TARGET_UPDATE_DISABLED) || vp->render_target_update_mode==RENDER_TARGET_UPDATE_ONCE) {
 		if ( (vp->queue_capture && vp->render_target_update_mode==RENDER_TARGET_UPDATE_DISABLED) || vp->render_target_update_mode==RENDER_TARGET_UPDATE_ONCE) {

+ 4 - 2
servers/visual/visual_server_raster.h

@@ -484,8 +484,8 @@ class VisualServerRaster : public VisualServer {
 		bool hide_scenario;
 		bool hide_scenario;
 		bool hide_canvas;
 		bool hide_canvas;
 		bool transparent_bg;
 		bool transparent_bg;
-
 		bool queue_capture;
 		bool queue_capture;
+		bool render_target_vflip;
 		Image capture;
 		Image capture;
 
 
 		bool rendered_in_prev_frame;
 		bool rendered_in_prev_frame;
@@ -512,7 +512,7 @@ class VisualServerRaster : public VisualServer {
 
 
 		SelfList<Viewport> update_list;
 		SelfList<Viewport> 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;}
+		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;}
 	};
 	};
 
 
 	SelfList<Viewport>::List viewport_update_list;
 	SelfList<Viewport>::List viewport_update_list;
@@ -911,6 +911,8 @@ public:
 	virtual void viewport_set_render_target_update_mode(RID p_viewport,RenderTargetUpdateMode p_mode);
 	virtual void viewport_set_render_target_update_mode(RID p_viewport,RenderTargetUpdateMode p_mode);
 	virtual RenderTargetUpdateMode viewport_get_render_target_update_mode(RID p_viewport) const;
 	virtual RenderTargetUpdateMode viewport_get_render_target_update_mode(RID p_viewport) const;
 	virtual RID viewport_get_render_target_texture(RID p_viewport) const;
 	virtual RID viewport_get_render_target_texture(RID p_viewport) const;
+	virtual void viewport_set_render_target_vflip(RID p_viewport,bool p_enable);
+	virtual bool viewport_get_render_target_vflip(RID p_viewport) const;
 
 
 	virtual void viewport_queue_screen_capture(RID p_viewport);
 	virtual void viewport_queue_screen_capture(RID p_viewport);
 	virtual Image viewport_get_screen_capture(RID p_viewport) const;
 	virtual Image viewport_get_screen_capture(RID p_viewport) const;

+ 3 - 0
servers/visual/visual_server_wrap_mt.h

@@ -889,6 +889,9 @@ public:
 	FUNC1RC(RenderTargetUpdateMode,viewport_get_render_target_update_mode,RID);
 	FUNC1RC(RenderTargetUpdateMode,viewport_get_render_target_update_mode,RID);
 	FUNC1RC(RID,viewport_get_render_target_texture,RID);
 	FUNC1RC(RID,viewport_get_render_target_texture,RID);
 
 
+	FUNC2(viewport_set_render_target_vflip,RID,bool);
+	FUNC1RC(bool,viewport_get_render_target_vflip,RID);
+
 	FUNC1(viewport_queue_screen_capture,RID);
 	FUNC1(viewport_queue_screen_capture,RID);
 	FUNC1RC(Image,viewport_get_screen_capture,RID);
 	FUNC1RC(Image,viewport_get_screen_capture,RID);
 
 

+ 3 - 0
servers/visual_server.h

@@ -600,10 +600,13 @@ public:
 		RENDER_TARGET_UPDATE_ALWAYS
 		RENDER_TARGET_UPDATE_ALWAYS
 	};
 	};
 
 
+
 	virtual void viewport_set_as_render_target(RID p_viewport,bool p_enable)=0;
 	virtual void viewport_set_as_render_target(RID p_viewport,bool p_enable)=0;
 	virtual void viewport_set_render_target_update_mode(RID p_viewport,RenderTargetUpdateMode p_mode)=0;
 	virtual void viewport_set_render_target_update_mode(RID p_viewport,RenderTargetUpdateMode p_mode)=0;
 	virtual RenderTargetUpdateMode viewport_get_render_target_update_mode(RID p_viewport) const=0;
 	virtual RenderTargetUpdateMode viewport_get_render_target_update_mode(RID p_viewport) const=0;
 	virtual RID viewport_get_render_target_texture(RID p_viewport) const=0;
 	virtual RID viewport_get_render_target_texture(RID p_viewport) const=0;
+	virtual void viewport_set_render_target_vflip(RID p_viewport,bool p_enable)=0;
+	virtual bool viewport_get_render_target_vflip(RID p_viewport) const=0;
 
 
 	virtual void viewport_queue_screen_capture(RID p_viewport)=0;
 	virtual void viewport_queue_screen_capture(RID p_viewport)=0;
 	virtual Image viewport_get_screen_capture(RID p_viewport) const=0;
 	virtual Image viewport_get_screen_capture(RID p_viewport) const=0;

+ 3 - 3
tools/editor/editor_file_system.cpp

@@ -630,7 +630,7 @@ void EditorFileSystem::scan_sources() {
 		s.priority=Thread::PRIORITY_LOW;
 		s.priority=Thread::PRIORITY_LOW;
 		thread_sources = Thread::create(_thread_func_sources,this,s);
 		thread_sources = Thread::create(_thread_func_sources,this,s);
 		//tree->hide();
 		//tree->hide();
-		print_line("SCAN BEGIN!");
+		//print_line("SCAN BEGIN!");
 		//progress->show();
 		//progress->show();
 	}
 	}
 
 
@@ -724,7 +724,7 @@ void EditorFileSystem::_notification(int p_what) {
 						Thread::wait_to_finish(thread_sources);
 						Thread::wait_to_finish(thread_sources);
 						memdelete(thread_sources);
 						memdelete(thread_sources);
 						thread_sources=NULL;
 						thread_sources=NULL;
-						print_line("sources changed: "+itos(sources_changed.size()));
+						//print_line("sources changed: "+itos(sources_changed.size()));
 						emit_signal("sources_changed",sources_changed.size()>0);
 						emit_signal("sources_changed",sources_changed.size()>0);
 					}
 					}
 				} else if (!scanning) {
 				} else if (!scanning) {
@@ -748,7 +748,7 @@ void EditorFileSystem::_notification(int p_what) {
 					thread=NULL;
 					thread=NULL;
 					emit_signal("filesystem_changed");
 					emit_signal("filesystem_changed");
 					emit_signal("sources_changed",sources_changed.size()>0);
 					emit_signal("sources_changed",sources_changed.size()>0);
-					print_line("initial sources changed: "+itos(sources_changed.size()));
+					//print_line("initial sources changed: "+itos(sources_changed.size()));
 
 
 
 
 
 

+ 1 - 1
tools/editor/editor_help.cpp

@@ -1333,7 +1333,7 @@ EditorHelp::EditorHelp(EditorNode *p_editor) {
 	history_pos=0;
 	history_pos=0;
 	scroll_locked=false;
 	scroll_locked=false;
 	select_locked=false;
 	select_locked=false;
-	add_to_group("unhandled_key_input");
+	set_process_unhandled_key_input(true);
 	h_split->set_split_offset(200);
 	h_split->set_split_offset(200);
 	class_list->connect("cell_selected",this,"_tree_item_selected");
 	class_list->connect("cell_selected",this,"_tree_item_selected");
 	class_desc->hide();
 	class_desc->hide();

+ 0 - 2
tools/editor/editor_node.cpp

@@ -2708,8 +2708,6 @@ Error EditorNode::load_scene(const String& p_scene) {
 		return ERR_FILE_NOT_FOUND;
 		return ERR_FILE_NOT_FOUND;
 	}
 	}
 
 
-	print_line("OPEN FILENAME: "+new_scene->get_filename());
-
 	/*
 	/*
 	Node *old_scene = edited_scene;
 	Node *old_scene = edited_scene;
 	_hide_top_editors();
 	_hide_top_editors();

+ 1 - 1
tools/editor/editor_settings.cpp

@@ -321,7 +321,7 @@ void EditorSettings::scan_plugins() {
 	d->list_dir_begin();
 	d->list_dir_begin();
 
 
 	String base = d->get_current_dir();
 	String base = d->get_current_dir();
-	print_line("list diring on: "+base);
+	//print_line("list diring on: "+base);
 	while(true) {
 	while(true) {
 		String p = d->get_next();
 		String p = d->get_next();
 		if (p=="")
 		if (p=="")

+ 1 - 1
tools/editor/plugins/canvas_item_editor_plugin.cpp

@@ -2245,7 +2245,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	//zoom=0.5;
 	//zoom=0.5;
 	singleton=this;
 	singleton=this;
 	editor->get_animation_editor()->connect("keying_changed",this,"_keying_changed");
 	editor->get_animation_editor()->connect("keying_changed",this,"_keying_changed");
-	add_to_group("unhandled_key_input");
+	set_process_unhandled_key_input(true);
 	can_move_pivot=false;
 	can_move_pivot=false;
 	pixel_snap=false;
 	pixel_snap=false;
 	drag=DRAG_NONE;
 	drag=DRAG_NONE;

+ 1 - 1
tools/editor/plugins/shader_editor_plugin.cpp

@@ -153,7 +153,7 @@ void ShaderTextEditor::_validate_script() {
 void ShaderTextEditor::_bind_methods() {
 void ShaderTextEditor::_bind_methods() {
 
 
 
 
-	ADD_SIGNAL( MethodInfo("script_changed") );
+	//ADD_SIGNAL( MethodInfo("script_changed") );
 
 
 }
 }
 
 

+ 1 - 1
tools/editor/plugins/spatial_editor_plugin.cpp

@@ -3334,7 +3334,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
 	scenario_debug=VisualServer::SCENARIO_DEBUG_DISABLED;
 	scenario_debug=VisualServer::SCENARIO_DEBUG_DISABLED;
 
 
 
 
-	add_to_group("unhandled_key_input");
+	set_process_unhandled_key_input(true);
 	add_to_group("_spatial_editor_group");
 	add_to_group("_spatial_editor_group");
 }
 }
 
 

+ 1 - 1
tools/editor/scene_tree_dock.cpp

@@ -1196,7 +1196,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec
 	file = memnew( FileDialog );
 	file = memnew( FileDialog );
 	add_child(file);
 	add_child(file);
 	file->connect("file_selected",this,"instance");
 	file->connect("file_selected",this,"instance");
-	add_to_group("unhandled_key_input");
+	set_process_unhandled_key_input(true);
 
 
 	delete_dialog = memnew( ConfirmationDialog );
 	delete_dialog = memnew( ConfirmationDialog );
 	add_child(delete_dialog);
 	add_child(delete_dialog);

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini