瀏覽代碼

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

MarianoGNU 10 年之前
父節點
當前提交
754908844a
共有 55 個文件被更改,包括 512 次插入142 次删除
  1. 33 0
      core/image.cpp
  2. 3 0
      core/image.h
  3. 4 1
      core/io/marshalls.cpp
  4. 1 2
      core/io/packet_peer.cpp
  5. 3 2
      core/io/resource_format_binary.cpp
  6. 2 2
      core/io/resource_format_xml.cpp
  7. 4 4
      core/ring_buffer.h
  8. 30 0
      core/script_debugger_remote.cpp
  9. 18 0
      core/script_debugger_remote.h
  10. 44 2
      drivers/gles2/rasterizer_gles2.cpp
  11. 5 0
      drivers/gles2/rasterizer_gles2.h
  12. 1 1
      drivers/vorbis/audio_stream_ogg_vorbis.cpp
  13. 1 1
      platform/flash/rasterizer_flash.h
  14. 2 0
      platform/iphone/app_delegate.mm
  15. 4 5
      platform/iphone/gl_view.h
  16. 38 37
      platform/iphone/gl_view.mm
  17. 1 0
      platform/iphone/globals/global_defaults.cpp
  18. 1 0
      scene/3d/spatial_stream_player.cpp
  19. 2 0
      scene/audio/stream_player.cpp
  20. 51 38
      scene/gui/tab_container.cpp
  21. 二進制
      scene/resources/default_theme/button_disabled.png
  22. 二進制
      scene/resources/default_theme/button_hover.png
  23. 二進制
      scene/resources/default_theme/button_normal.png
  24. 二進制
      scene/resources/default_theme/button_pressed.png
  25. 52 33
      scene/resources/default_theme/default_theme.cpp
  26. 二進制
      scene/resources/default_theme/focus.png
  27. 二進制
      scene/resources/default_theme/line_edit.png
  28. 二進制
      scene/resources/default_theme/line_edit_disabled.png
  29. 二進制
      scene/resources/default_theme/option_button_disabled.png
  30. 二進制
      scene/resources/default_theme/option_button_hover.png
  31. 二進制
      scene/resources/default_theme/option_button_normal.png
  32. 二進制
      scene/resources/default_theme/option_button_pressed.png
  33. 二進制
      scene/resources/default_theme/panel_bg.png
  34. 二進制
      scene/resources/default_theme/popup_bg.png
  35. 二進制
      scene/resources/default_theme/popup_window.png
  36. 二進制
      scene/resources/default_theme/tab_behind.png
  37. 二進制
      scene/resources/default_theme/tab_container_bg.png
  38. 二進制
      scene/resources/default_theme/tab_current.png
  39. 0 1
      scene/resources/default_theme/theme_data.h
  40. 二進制
      scene/resources/default_theme/tree_bg.png
  41. 20 0
      scene/resources/texture.cpp
  42. 4 1
      scene/resources/texture.h
  43. 20 0
      servers/register_server_types.cpp
  44. 4 1
      servers/visual/rasterizer.h
  45. 4 0
      servers/visual/rasterizer_dummy.h
  46. 15 0
      servers/visual/visual_server_raster.cpp
  47. 5 0
      servers/visual/visual_server_raster.h
  48. 9 0
      servers/visual/visual_server_wrap_mt.h
  49. 12 0
      servers/visual_server.h
  50. 15 6
      tools/editor/editor_node.cpp
  51. 1 0
      tools/editor/editor_node.h
  52. 16 4
      tools/editor/io_plugins/editor_texture_import_plugin.cpp
  53. 2 1
      tools/editor/scene_tree_dock.cpp
  54. 80 0
      tools/editor/script_editor_debugger.cpp
  55. 5 0
      tools/editor/script_editor_debugger.h

+ 33 - 0
core/image.cpp

@@ -34,6 +34,33 @@
 #include "print_string.h"
 #include <stdio.h>
 
+
+const char* Image::format_names[Image::FORMAT_MAX]={
+	"Grayscale",
+	"Intensity",
+	"GrayscaleAlpha",
+	"RGB",
+	"RGBA",
+	"Indexed",
+	"IndexedAlpha",
+	"YUV422",
+	"YUV444",
+	"BC1",
+	"BC2",
+	"BC3",
+	"BC4",
+	"BC5",
+	"PVRTC2",
+	"PVRTC2Alpha",
+	"PVRTC4",
+	"PVRTC4Alpha",
+	"ETC",
+	"ATC",
+	"ATCAlphaExp",
+	"ATCAlphaInterp",
+
+};
+
 SavePNGFunc Image::save_png_func = NULL;
 
 void Image::_put_pixel(int p_x,int p_y, const BColor& p_color, unsigned char *p_data) {
@@ -2355,6 +2382,12 @@ void Image::fix_alpha_edges() {
 
 }
 
+String Image::get_format_name(Format p_format) {
+
+	ERR_FAIL_INDEX_V(p_format,FORMAT_MAX,String());
+	return format_names[p_format];
+}
+
 Image::Image(const uint8_t* p_png,int p_len) {
 
 	width=0;

+ 3 - 0
core/image.h

@@ -87,6 +87,7 @@ public:
 		FORMAT_MAX
 	};
 
+	static const char* format_names[FORMAT_MAX];
 	enum Interpolation {
 	
 		INTERPOLATE_NEAREST,
@@ -352,6 +353,8 @@ public:
 	Image get_rect(const Rect2& p_area) const;
 
 	static void set_compress_bc_func(void (*p_compress_func)(Image *));
+	static String get_format_name(Format p_format);
+
 	Image(const uint8_t* p_mem_png, int p_len=-1);
 	Image(const char **p_xpm);
 	~Image();

+ 4 - 1
core/io/marshalls.cpp

@@ -36,7 +36,10 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
 	const uint8_t * buf=p_buffer;
 	int len=p_len;
 
-	ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA);
+	if (len<4) {
+
+		ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA);
+	}
 
 
 	uint32_t type=decode_uint32(buf);

+ 1 - 2
core/io/packet_peer.cpp

@@ -156,7 +156,6 @@ Error PacketPeerStream::_poll_buffer() const {
 	Error err = peer->get_partial_data(&temp_buffer[0], ring_buffer.space_left(), read);
 	if (err)
 		return err;
-
 	if (read==0)
 		return OK;
 
@@ -202,7 +201,7 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer,int &r_buffer_size)
 	uint8_t lbuf[4];
 	ring_buffer.copy(lbuf,0,4);
 	remaining-=4;
-	uint32_t len = decode_uint32(lbuf);
+	uint32_t len = decode_uint32(lbuf);	
 	ERR_FAIL_COND_V(remaining<(int)len,ERR_UNAVAILABLE);
 
 	ring_buffer.read(lbuf,4); //get rid of first 4 bytes

+ 3 - 2
core/io/resource_format_binary.cpp

@@ -2172,10 +2172,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
 
 			save_unicode_string("local://"+itos(r->get_subindex()));
 			if (takeover_paths) {
-				r->set_path(p_path+"::"+itos(ofs_pos.size()),true);
+				r->set_path(p_path+"::"+itos(r->get_subindex()),true);
 			}
-		} else
+		} else {
 			save_unicode_string(r->get_path()); //actual external
+		}
 		ofs_pos.push_back(f->get_pos());
 		f->store_64(0); //offset in 64 bits
 	}

+ 2 - 2
core/io/resource_format_xml.cpp

@@ -2056,8 +2056,8 @@ Error ResourceFormatLoaderXML::rename_dependencies(const String &p_path,const Ma
 void ResourceFormatSaverXMLInstance::escape(String& p_str) {
 
 	p_str=p_str.replace("&","&amp;");
-	p_str=p_str.replace("<","&gt;");
-	p_str=p_str.replace(">","&lt;");
+	p_str=p_str.replace("<","&lt;");
+	p_str=p_str.replace(">","&gt;");
 	p_str=p_str.replace("'","&apos;");
 	p_str=p_str.replace("\"","&quot;");
 	for (char i=1;i<32;i++) {

+ 4 - 4
core/ring_buffer.h

@@ -141,15 +141,15 @@ public:
 	inline int space_left() {
 		int left = read_pos - write_pos;
 		if (left < 0) {
-			return size() + left;
+			return size() + left - 1;
 		};
 		if (left == 0) {
-			return size();
+			return size()-1;
 		};
-		return left;
+		return left -1;
 	};
 	inline int data_left() {
-		return size() - space_left();
+		return size() - space_left() - 1;
 	};
 	
 	inline int size() {

+ 30 - 0
core/script_debugger_remote.cpp

@@ -31,6 +31,28 @@
 #include "io/ip.h"
 #include "globals.h"
 
+void ScriptDebuggerRemote::_send_video_memory() {
+
+	List<ResourceUsage> usage;
+	if (resource_usage_func)
+		resource_usage_func(&usage);
+
+	usage.sort();
+
+	packet_peer_stream->put_var("message:video_mem");
+	packet_peer_stream->put_var(usage.size()*4);
+
+
+	for(List<ResourceUsage>::Element *E=usage.front();E;E=E->next()) {
+
+		packet_peer_stream->put_var(E->get().path);
+		packet_peer_stream->put_var(E->get().type);
+		packet_peer_stream->put_var(E->get().format);
+		packet_peer_stream->put_var(E->get().vram);
+	}
+
+}
+
 Error ScriptDebuggerRemote::connect_to_host(const String& p_host,uint16_t p_port) {
 
 
@@ -248,6 +270,9 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) {
 				if (request_scene_tree)
 					request_scene_tree(request_scene_tree_ud);
 
+			} else if (command=="request_video_mem") {
+
+				_send_video_memory();
 			} else if (command=="breakpoint") {
 
 				bool set = cmd[3];
@@ -531,6 +556,9 @@ void ScriptDebuggerRemote::_poll_events() {
 
 			if (request_scene_tree)
 				request_scene_tree(request_scene_tree_ud);
+		} else if (command=="request_video_mem") {
+
+			_send_video_memory();
 		} else if (command=="breakpoint") {
 
 			bool set = cmd[3];
@@ -652,6 +680,8 @@ void ScriptDebuggerRemote::set_live_edit_funcs(LiveEditFuncs *p_funcs) {
 	live_edit_funcs=p_funcs;
 }
 
+ScriptDebuggerRemote::ResourceUsageFunc ScriptDebuggerRemote::resource_usage_func=NULL;
+
 ScriptDebuggerRemote::ScriptDebuggerRemote() {
 
 	tcp_client  = StreamPeerTCP::create_ref();

+ 18 - 0
core/script_debugger_remote.h

@@ -34,6 +34,7 @@
 #include "io/stream_peer_tcp.h"
 #include "io/packet_peer.h"
 #include "list.h"
+
 class ScriptDebuggerRemote : public ScriptDebugger {
 
 	struct Message {
@@ -42,6 +43,8 @@ class ScriptDebuggerRemote : public ScriptDebugger {
 		Array data;
 	};
 
+
+
 	Ref<StreamPeerTCP> tcp_client;
 	Ref<PacketPeerStream> packet_peer_stream;
 
@@ -90,6 +93,7 @@ class ScriptDebuggerRemote : public ScriptDebugger {
 	RequestSceneTreeMessageFunc request_scene_tree;
 	void *request_scene_tree_ud;
 
+	void _send_video_memory();
 	LiveEditFuncs *live_edit_funcs;
 
 	ErrorHandlerList eh;
@@ -98,6 +102,20 @@ class ScriptDebuggerRemote : public ScriptDebugger {
 
 public:
 
+	struct ResourceUsage {
+
+		String path;
+		String format;
+		String type;
+		RID id;
+		int vram;
+		bool operator<(const ResourceUsage& p_img) const { return vram==p_img.vram ? id<p_img.id : vram > p_img.vram; }
+	};
+
+	typedef void (*ResourceUsageFunc)(List<ResourceUsage>*);
+
+	static ResourceUsageFunc resource_usage_func;
+
 	Error connect_to_host(const String& p_host,uint16_t p_port);
 	virtual void debug(ScriptLanguage *p_script,bool p_can_continue=true);
 	virtual void idle_poll();

+ 44 - 2
drivers/gles2/rasterizer_gles2.cpp

@@ -1408,6 +1408,40 @@ GLuint RasterizerGLES2::_texture_get_name(RID p_tex) {
 	return texture->tex_id;
 };
 
+void RasterizerGLES2::texture_set_path(RID p_texture,const String& p_path) {
+	Texture * texture = texture_owner.get(p_texture);
+	ERR_FAIL_COND(!texture);
+
+	texture->path=p_path;
+
+}
+
+String RasterizerGLES2::texture_get_path(RID p_texture) const{
+
+	Texture * texture = texture_owner.get(p_texture);
+	ERR_FAIL_COND_V(!texture,String());
+	return texture->path;
+}
+void RasterizerGLES2::texture_debug_usage(List<VS::TextureInfo> *r_info){
+
+	List<RID> textures;
+	texture_owner.get_owned_list(&textures);
+
+	for (List<RID>::Element *E=textures.front();E;E=E->next()) {
+
+		Texture *t = texture_owner.get(E->get());
+		if (!t)
+			continue;
+		VS::TextureInfo tinfo;
+		tinfo.path=t->path;
+		tinfo.format=t->format;
+		tinfo.size.x=t->alloc_width;
+		tinfo.size.y=t->alloc_height;
+		tinfo.bytes=t->total_data_size;
+		r_info->push_back(tinfo);
+	}
+
+}
 
 /* SHADER API */
 
@@ -9164,7 +9198,11 @@ void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItemMaterial *mater
 		glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color);
 		if (framebuffer.scale==1 && !canvas_texscreen_used) {
 #ifdef GLEW_ENABLED
-			glReadBuffer(GL_COLOR_ATTACHMENT0);
+			if (current_rt) {
+				glReadBuffer(GL_COLOR_ATTACHMENT0);
+			} else {
+				glReadBuffer(GL_BACK);
+			}
 #endif
 			glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height);
 //			if (current_clip) {
@@ -9344,7 +9382,11 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
 			glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color);
 
 #ifdef GLEW_ENABLED
-			glReadBuffer(GL_COLOR_ATTACHMENT0);
+			if (current_rt) {
+				glReadBuffer(GL_COLOR_ATTACHMENT0);
+			} else {
+				glReadBuffer(GL_BACK);
+			}
 #endif
 			glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,w,h);
 //			if (current_clip) {

+ 5 - 0
drivers/gles2/rasterizer_gles2.h

@@ -115,6 +115,7 @@ class RasterizerGLES2 : public Rasterizer {
 
 	struct Texture {
 
+		String path;
 		uint32_t flags;
 		int width,height;
 		int alloc_width, alloc_height;
@@ -1325,6 +1326,10 @@ public:
 	virtual void texture_set_size_override(RID p_texture,int p_width, int p_height);
 	virtual void texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const;
 
+	virtual void texture_set_path(RID p_texture,const String& p_path);
+	virtual String texture_get_path(RID p_texture) const;
+	virtual void texture_debug_usage(List<VS::TextureInfo> *r_info);
+
 	GLuint _texture_get_name(RID p_tex);
 
 	/* SHADER API */

+ 1 - 1
drivers/vorbis/audio_stream_ogg_vorbis.cpp

@@ -361,7 +361,7 @@ void AudioStreamPlaybackOGGVorbis::_clear_stream() {
 	_close_file();
 
 	stream_loaded=false;
-	stream_channels=1;
+	//stream_channels=1;
 	playing=false;
 }
 

+ 1 - 1
platform/flash/rasterizer_flash.h

@@ -577,7 +577,7 @@ class RasterizerFlash : public Rasterizer {
 					}
 				} else {
 
-					return B->material->shader_cache < B->material->shader_cache;
+					return A->material->shader_cache < B->material->shader_cache;
 				}
 			}
 		};

+ 2 - 0
platform/iphone/app_delegate.mm

@@ -236,6 +236,8 @@ static int frame_count = 0;
 	view_controller.view = glView;
 	window.rootViewController = view_controller;
 
+	glView.useCADisplayLink = bool(GLOBAL_DEF("display.iOS/use_cadisplaylink",true)) ? YES : NO;
+	printf("cadisaplylink: %d", glView.useCADisplayLink);
 	glView.animationInterval = 1.0 / kRenderingFrequency;
 	[glView startAnimation];
 	

+ 4 - 5
platform/iphone/gl_view.h

@@ -34,8 +34,6 @@
 #import <MediaPlayer/MediaPlayer.h>
 #import <AVFoundation/AVFoundation.h>
 
-#define USE_CADISPLAYLINK      0   //iOS version 3.1+ is required
-
 @protocol GLViewDelegate;
 
 @interface GLView : UIView<UIKeyInput>
@@ -53,13 +51,13 @@
 	// OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist)
 	GLuint depthRenderbuffer;
 	
-#if USE_CADISPLAYLINK
+	BOOL useCADisplayLink;
 	// CADisplayLink available on 3.1+ synchronizes the animation timer & drawing with the refresh rate of the display, only supports animation intervals of 1/60 1/30 & 1/15
 	CADisplayLink *displayLink;
-#else
+
 	// An animation timer that, when animation is started, will periodically call -drawView at the given rate.
+	// Only used if CADisplayLink is not
 	NSTimer *animationTimer;
-#endif
 	
 	NSTimeInterval animationInterval;
 	
@@ -104,6 +102,7 @@
 - (void)audioRouteChangeListenerCallback:(NSNotification*)notification;
 
 @property NSTimeInterval animationInterval;
+@property(nonatomic, assign) BOOL useCADisplayLink;
 
 @end
 

+ 38 - 37
platform/iphone/gl_view.mm

@@ -334,13 +334,15 @@ static void clear_touches() {
 	delegateSetup = ![delegate respondsToSelector:@selector(setupView:)];
 }
 
+@synthesize useCADisplayLink;
+
 // If our view is resized, we'll be asked to layout subviews.
 // This is the perfect opportunity to also update the framebuffer so that it is
 // the same size as our display area.
 
 -(void)layoutSubviews
 {
-	printf("HERE\n");
+	//printf("HERE\n");
 	[EAGLContext setCurrentContext:context];
 	[self destroyFramebuffer];
 	[self createFramebuffer];
@@ -418,19 +420,21 @@ static void clear_touches() {
 		return;
 	active = TRUE;
 	printf("start animation!\n");
-#if USE_CADISPLAYLINK
-	// Approximate frame rate
-	// assumes device refreshes at 60 fps
-	int frameInterval = (int) floor(animationInterval * 60.0f);
-
-	displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView)];
-	[displayLink setFrameInterval:frameInterval];
-
-	// Setup DisplayLink in main thread
-	[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
-#else
-	animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
-#endif
+	if (useCADisplayLink) {
+
+		// Approximate frame rate
+		// assumes device refreshes at 60 fps
+		int frameInterval = (int) floor(animationInterval * 60.0f);
+
+		displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView)];
+		[displayLink setFrameInterval:frameInterval];
+
+		// Setup DisplayLink in main thread
+		[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
+	}
+	else {
+		animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
+	}
 
 	if (video_playing)
 	{
@@ -444,13 +448,16 @@ static void clear_touches() {
 		return;
 	active = FALSE;
 	printf("******** stop animation!\n");
-#if USE_CADISPLAYLINK
-	[displayLink invalidate];
-	displayLink = nil;
-#else
-	[animationTimer invalidate];
-	animationTimer = nil;
-#endif
+
+	if (useCADisplayLink) {
+		[displayLink invalidate];
+		displayLink = nil;
+	}
+	else {
+		[animationTimer invalidate];
+		animationTimer = nil;
+	}
+
 	clear_touches();
 
 	if (video_playing)
@@ -462,13 +469,7 @@ static void clear_touches() {
 - (void)setAnimationInterval:(NSTimeInterval)interval
 {
 	animationInterval = interval;
-	
-#if USE_CADISPLAYLINK
-	if(displayLink)
-#else
-	if(animationTimer)
-#endif
-	{
+	if ( (useCADisplayLink && displayLink) || ( !useCADisplayLink && animationTimer ) ) {
 		[self stopAnimation];
 		[self startAnimation];
 	}
@@ -477,16 +478,16 @@ static void clear_touches() {
 // Updates the OpenGL view when the timer fires
 - (void)drawView
 {
-#if USE_CADISPLAYLINK
-	// Pause the CADisplayLink to avoid recursion
-	[displayLink setPaused: YES];
+	if (useCADisplayLink) {
+		// Pause the CADisplayLink to avoid recursion
+		[displayLink setPaused: YES];
 
-	// Process all input events
-	while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) == kCFRunLoopRunHandledSource);
+		// Process all input events
+		while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) == kCFRunLoopRunHandledSource);
 
-	// We are good to go, resume the CADisplayLink
-	[displayLink setPaused: NO];
-#endif
+		// We are good to go, resume the CADisplayLink
+		[displayLink setPaused: NO];
+	}
 
 	if (!active) {
 		printf("draw view not active!\n");
@@ -632,7 +633,7 @@ static void clear_touches() {
 		case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
 			NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable");
 			NSLog(@"Headphone/Line was pulled. Resuming video play....");
-			if (_is_video_playing) {
+			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

+ 1 - 0
platform/iphone/globals/global_defaults.cpp

@@ -9,4 +9,5 @@ void register_iphone_global_defaults() {
 	GLOBAL_DEF("rasterizer.iOS/fp16_framebuffer",false);
 	GLOBAL_DEF("display.iOS/driver","GLES2");
 	Globals::get_singleton()->set_custom_property_info("display.iOS/driver",PropertyInfo(Variant::STRING,"display.iOS/driver",PROPERTY_HINT_ENUM,"GLES1,GLES2"));
+	GLOBAL_DEF("display.iOS/use_cadisplaylink",true);
 }

+ 1 - 0
scene/3d/spatial_stream_player.cpp

@@ -171,6 +171,7 @@ void SpatialStreamPlayer::stop() {
 	//AudioServer::get_singleton()->stream_set_active(stream_rid,false);
 	SpatialSoundServer::get_singleton()->source_set_audio_stream(get_source_rid(),NULL);
 	playback->stop();
+	resampler.flush();
 	//set_idle_process(false);
 }
 

+ 2 - 0
scene/audio/stream_player.cpp

@@ -165,6 +165,8 @@ void StreamPlayer::stop() {
 	//_THREAD_SAFE_METHOD_
 	AudioServer::get_singleton()->stream_set_active(stream_rid,false);
 	playback->stop();
+	resampler.flush();
+
 	//set_idle_process(false);
 }
 

+ 51 - 38
scene/gui/tab_container.cpp

@@ -229,6 +229,18 @@ void TabContainer::_notification(int p_what) {
 
 			int w=0;
 			int idx=0;
+			Vector<int> offsets;
+			Vector<Control*> controls;
+			int from=0;
+			int limit=get_size().width;
+			if (popup) {
+				top_size.width-=menu->get_width();
+				limit-=menu->get_width();
+			}
+
+			bool notdone=false;
+			last_tab_cache=-1;
+
 			for(int i=0;i<get_child_count();i++) {
 
 				Control *c = get_child(i)->cast_to<Control>();
@@ -236,7 +248,20 @@ void TabContainer::_notification(int p_what) {
 					continue;
 				if (c->is_set_as_toplevel())
 					continue;
+				if (idx<tab_display_ofs) {
+					idx++;
+					from=idx;
+					continue;
+				}
 
+				if (w>=get_size().width) {
+					buttons_visible_cache=true;
+					notdone=true;
+					break;
+				}
+
+				offsets.push_back(w);
+				controls.push_back(c);
 
 				String s = c->has_meta("_tab_name")?String(XL_MESSAGE(String(c->get_meta("_tab_name")))):String(c->get_name());
 				w+=font->get_string_size(s).width;
@@ -257,55 +282,46 @@ void TabContainer::_notification(int p_what) {
 					w+=tab_bg->get_minimum_size().width;
 				}
 
-				idx++;
-			}
+				if (idx<tab_display_ofs) {
 
+				}
+				last_tab_cache=idx;
 
-			int ofs;
-			int limit=get_size().width;
-			if (popup) {
-				top_size.width-=menu->get_width();
-				limit-=menu->get_width();
+				idx++;
 			}
 
 
-			if (w<=limit) {
-				switch(align) {
+			int ofs;
 
-					case ALIGN_LEFT: ofs = side_margin; break;
-					case ALIGN_CENTER: ofs = (int(limit) - w)/2; break;
-					case ALIGN_RIGHT: ofs = int(limit) - w - side_margin; break;
-				};
+			switch(align) {
 
-				tab_display_ofs=0;
-				buttons_visible_cache=false;
-			} else {
+				case ALIGN_LEFT: ofs = side_margin; break;
+				case ALIGN_CENTER: ofs = (int(limit) - w)/2; break;
+				case ALIGN_RIGHT: ofs = int(limit) - w - side_margin; break;
+			};
 
-				ofs=0;
-				limit-=incr->get_width()+decr->get_width();
-				buttons_visible_cache=true;
-			}
+			tab_display_ofs=0;
 
 
 			tabs_ofs_cache=ofs;
-			last_tab_cache=-1;
 			idx=0;
-			bool notdone=false;
 
 
-			for(int i=0;i<get_child_count();i++) {
 
-				Control *c = get_child(i)->cast_to<Control>();
-				if (!c)
-					continue;
-				if (c->is_set_as_toplevel())
-					continue;
+			for(int i=0;i<controls.size();i++) {
 
-				if (idx<tab_display_ofs) {
-					idx++;
-					continue;
+				idx=i+from;
+				if (current>=from && current<from+controls.size()-1) {
+					//current is visible! draw it last.
+					if (i==controls.size()-1) {
+						idx=current;
+					} else if (idx>=current) {
+						idx+=1;
+					}
 				}
 
+				Control *c = controls[idx-from];
+
 				String s = c->has_meta("_tab_name")?String(c->get_meta("_tab_name")):String(c->get_name());
 				int w=font->get_string_size(s).width;
 				Ref<Texture> icon;
@@ -336,14 +352,12 @@ void TabContainer::_notification(int p_what) {
 					col=color_bg;
 				}
 
+				int lofs = ofs + offsets[idx-from];
 
 				Size2i sb_ms = sb->get_minimum_size();
-				Rect2 sb_rect = Rect2( ofs, 0, w+sb_ms.width, top_margin);
+				Rect2 sb_rect = Rect2( lofs, 0, w+sb_ms.width, top_margin);
+
 
-				if (sb_ms.width+w+ofs > limit) {
-					notdone=true;
-					break;
-				}
 				sb->draw(ci, sb_rect );
 
 				Point2i lpos = sb_rect.pos;
@@ -357,8 +371,7 @@ void TabContainer::_notification(int p_what) {
 				}
 
 				font->draw(ci, Point2i( lpos.x, sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-font->get_height())/2+font->get_ascent() ), s, col );
-				ofs+=sb_ms.x+w;
-				last_tab_cache=idx;
+				//ofs+=sb_ms.x+w;
 
 				/*
 				int sb_mw = sb->get_minimum_size().width;

二進制
scene/resources/default_theme/button_disabled.png


二進制
scene/resources/default_theme/button_hover.png


二進制
scene/resources/default_theme/button_normal.png


二進制
scene/resources/default_theme/button_pressed.png


+ 52 - 33
scene/resources/default_theme/default_theme.cpp

@@ -60,6 +60,16 @@ static Ref<StyleBoxTexture> make_stylebox(T p_src,float p_left, float p_top, flo
 	return style;
 }
 
+
+static Ref<StyleBoxTexture> sb_expand(Ref<StyleBoxTexture> p_sbox,float p_left, float p_top, float p_right, float p_botton) {
+
+	p_sbox->set_expand_margin_size(MARGIN_LEFT,p_left);
+	p_sbox->set_expand_margin_size(MARGIN_TOP,p_top);
+	p_sbox->set_expand_margin_size(MARGIN_RIGHT,p_right);
+	p_sbox->set_expand_margin_size(MARGIN_BOTTOM,p_botton);
+	return p_sbox;
+}
+
 template<class T>
 static Ref<Texture> make_icon(T p_src) {
 
@@ -195,18 +205,24 @@ void make_default_theme() {
 
 	Ref<StyleBoxTexture> focus = make_stylebox( focus_png,5,5,5,5);
 	for(int i=0;i<4;i++) {
-		focus->set_expand_margin_size(Margin(i),2);
+		focus->set_expand_margin_size(Margin(i),1);
 	}
 
 
 
 	// Button
 
-	t->set_stylebox("normal","Button", make_stylebox( button_normal_png,4,4,4,4,8,4,8,4) );
-	t->set_stylebox("pressed","Button", make_stylebox( button_pressed_png,4,4,4,4) );
-	t->set_stylebox("hover","Button", make_stylebox( button_hover_png,4,4,4,4) );
-	t->set_stylebox("disabled","Button", make_stylebox( button_disabled_png,4,4,4,4) );
-	t->set_stylebox("focus","Button", focus );
+	Ref<StyleBox> sb_button_normal = sb_expand( make_stylebox( button_normal_png,4,4,4,4,6,2,6,2),2,2,2,2);
+	Ref<StyleBox> sb_button_pressed = sb_expand( make_stylebox( button_pressed_png,4,4,4,4,6,2,6,2),2,2,2,2);
+	Ref<StyleBox> sb_button_hover = sb_expand( make_stylebox( button_hover_png,4,4,4,4,6,2,6,2),2,2,2,2);
+	Ref<StyleBox> sb_button_disabled = sb_expand( make_stylebox( button_disabled_png,4,4,4,4,6,2,6,2),2,2,2,2);
+	Ref<StyleBox> sb_button_focus = sb_expand( make_stylebox( button_focus_png,4,4,4,4,6,2,6,2),2,2,2,2);
+
+	t->set_stylebox("normal","Button", sb_button_normal);
+	t->set_stylebox("pressed","Button", sb_button_pressed);
+	t->set_stylebox("hover","Button", sb_button_hover);
+	t->set_stylebox("disabled","Button", sb_button_disabled);
+	t->set_stylebox("focus","Button", sb_button_focus);
 
 	t->set_font("font","Button", default_font );
 
@@ -221,11 +237,11 @@ void make_default_theme() {
 
 	// ColorPickerButton
 
-	t->set_stylebox("normal","ColorPickerButton", make_stylebox( button_normal_png,4,4,4,4) );
-	t->set_stylebox("pressed","ColorPickerButton", make_stylebox( button_pressed_png,4,4,4,4) );
-	t->set_stylebox("hover","ColorPickerButton", make_stylebox( button_hover_png,4,4,4,4) );
-	t->set_stylebox("disabled","ColorPickerButton", make_stylebox( button_disabled_png,4,4,4,4) );
-	t->set_stylebox("focus","ColorPickerButton", focus );
+	t->set_stylebox("normal","ColorPickerButton", sb_button_normal);
+	t->set_stylebox("pressed","ColorPickerButton", sb_button_pressed);
+	t->set_stylebox("hover","ColorPickerButton", sb_button_hover);
+	t->set_stylebox("disabled","ColorPickerButton", sb_button_disabled);
+	t->set_stylebox("focus","ColorPickerButton", sb_button_focus);
 
 	t->set_font("font","ColorPickerButton", default_font );
 
@@ -263,11 +279,17 @@ void make_default_theme() {
 
 	// OptionButton
 
-	t->set_stylebox("normal","OptionButton", make_stylebox( option_button_normal_png,5,5,21,5,8,4,8,4) );
-	t->set_stylebox("pressed","OptionButton", make_stylebox( option_button_pressed_png,5,5,21,5) );
-	t->set_stylebox("hover","OptionButton", make_stylebox( option_button_hover_png,5,5,21,5) );
-	t->set_stylebox("disabled","OptionButton", make_stylebox( option_button_disabled_png,5,5,21,5) );
-	t->set_stylebox("focus","OptionButton", focus );
+	Ref<StyleBox> sb_optbutton_normal = sb_expand( make_stylebox( option_button_normal_png,4,4,21,4,6,2,21,2),2,2,2,2);
+	Ref<StyleBox> sb_optbutton_pressed = sb_expand( make_stylebox( option_button_pressed_png,4,4,21,4,6,2,21,2),2,2,2,2);
+	Ref<StyleBox> sb_optbutton_hover = sb_expand( make_stylebox( option_button_hover_png,4,4,21,4,6,2,21,2),2,2,2,2);
+	Ref<StyleBox> sb_optbutton_disabled = sb_expand( make_stylebox( option_button_disabled_png,4,4,21,4,6,2,21,2),2,2,2,2);
+	Ref<StyleBox> sb_optbutton_focus = sb_expand( make_stylebox( button_focus_png,4,4,4,4,6,2,6,2),2,2,2,2);
+
+	t->set_stylebox("normal","OptionButton", sb_optbutton_normal );
+	t->set_stylebox("pressed","OptionButton", sb_optbutton_pressed );
+	t->set_stylebox("hover","OptionButton", sb_optbutton_hover );
+	t->set_stylebox("disabled","OptionButton", sb_optbutton_disabled );
+	t->set_stylebox("focus","OptionButton", sb_button_focus );
 
 	t->set_icon("arrow","OptionButton", make_icon( option_arrow_png ) );
 
@@ -285,9 +307,9 @@ void make_default_theme() {
 
 	// MenuButton
 
-	t->set_stylebox("normal","MenuButton", make_stylebox( button_normal_png,4,4,4,4,8,4,8,4) );
-	t->set_stylebox("pressed","MenuButton", make_stylebox( tool_button_pressed_png ,4,4,4,4) );
-	t->set_stylebox("hover","MenuButton", make_stylebox( button_normal_png,4,4,4,4) );
+	t->set_stylebox("normal","MenuButton", sb_button_normal );
+	t->set_stylebox("pressed","MenuButton", sb_button_pressed );
+	t->set_stylebox("hover","MenuButton", sb_button_pressed );
 	t->set_stylebox("disabled","MenuButton", make_empty_stylebox(0,0,0,0) );
 
 	t->set_font("font","MenuButton", default_font );
@@ -501,10 +523,10 @@ void make_default_theme() {
 
 	// WindowDialog
 
-	Ref<StyleBoxTexture> style_pp_win = make_stylebox( popup_window_png,6,28,6,7);
-	for(int i=0;i<4;i++)
+	Ref<StyleBoxTexture> style_pp_win = sb_expand(make_stylebox( popup_window_png,10,30,10,8),8,26,8,4);
+	/*for(int i=0;i<4;i++)
 		style_pp_win->set_expand_margin_size((Margin)i,3);
-	style_pp_win->set_expand_margin_size(MARGIN_TOP,26);
+	style_pp_win->set_expand_margin_size(MARGIN_TOP,26);*/
 
 	t->set_stylebox("panel","WindowDialog", style_pp_win );
 
@@ -524,7 +546,7 @@ void make_default_theme() {
 
 	// Popup
 
-	Ref<StyleBoxTexture> style_pp = make_stylebox( popup_bg_png,4,4,4,4,8,8,8,8);
+	Ref<StyleBoxTexture> style_pp =  sb_expand( make_stylebox( popup_bg_png,5,5,5,5,4,4,4,4),2,2,2,2);
 
 	Ref<StyleBoxTexture> selected = make_stylebox( selection_png,6,6,6,6);
 	for(int i=0;i<4;i++) {
@@ -648,16 +670,13 @@ void make_default_theme() {
 
 	// TabContainer
 
-	Ref<StyleBoxTexture> tc_sb = make_stylebox( tab_container_bg_png,4,4,4,4);
-	for(int i=0;i<4;i++) {
-		tc_sb->set_default_margin(Margin(i),4);
-		tc_sb->set_expand_margin_size(Margin(i),2);
-	}
+	Ref<StyleBoxTexture> tc_sb = sb_expand( make_stylebox( tab_container_bg_png,4,4,4,4,4,4,4,4),3,3,3,3);
+
 	tc_sb->set_expand_margin_size(MARGIN_TOP,2);
 	tc_sb->set_default_margin(MARGIN_TOP,8);
 
-	t->set_stylebox("tab_fg","TabContainer", make_stylebox( tab_current_png,4,4,4,4,16,4,16,4) );
-	t->set_stylebox("tab_bg","TabContainer", make_stylebox( tab_behind_png,4,4,4,4,16,6,16,4) );
+	t->set_stylebox("tab_fg","TabContainer", sb_expand( make_stylebox( tab_current_png,4,4,4,1,16,4,16,4),2,2,2,2) );
+	t->set_stylebox("tab_bg","TabContainer", sb_expand( make_stylebox( tab_behind_png,5,5,5,1,16,6,16,4),3,0,3,3) );
 	t->set_stylebox("panel","TabContainer", tc_sb );
 
 	t->set_icon("increment","TabContainer",make_icon( scroll_button_right_png));
@@ -682,9 +701,9 @@ void make_default_theme() {
 
 	// Tabs
 
-	t->set_stylebox("tab_fg","Tabs", make_stylebox( tab_current_png,4,4,4,4,16,4,16,4) );
-	t->set_stylebox("tab_bg","Tabs", make_stylebox( tab_behind_png,4,4,4,4,16,6,16,4) );
-	t->set_stylebox("panel","Tabs", make_stylebox( tab_container_bg_png,4,4,4,4) );
+	t->set_stylebox("tab_fg","Tabs", sb_expand( make_stylebox( tab_current_png,4,4,4,1,16,4,16,4),2,2,2,2) );
+	t->set_stylebox("tab_bg","Tabs", sb_expand( make_stylebox( tab_behind_png,5,5,5,1,16,6,16,4),3,3,3,3) );
+	t->set_stylebox("panel","Tabs",tc_sb );
 	t->set_stylebox("button_pressed","Tabs", make_stylebox( button_pressed_png,4,4,4,4) );
 	t->set_stylebox("button","Tabs", make_stylebox( button_normal_png,4,4,4,4) );
 

二進制
scene/resources/default_theme/focus.png


二進制
scene/resources/default_theme/line_edit.png


二進制
scene/resources/default_theme/line_edit_disabled.png


二進制
scene/resources/default_theme/option_button_disabled.png


二進制
scene/resources/default_theme/option_button_hover.png


二進制
scene/resources/default_theme/option_button_normal.png


二進制
scene/resources/default_theme/option_button_pressed.png


二進制
scene/resources/default_theme/panel_bg.png


二進制
scene/resources/default_theme/popup_bg.png


二進制
scene/resources/default_theme/popup_window.png


二進制
scene/resources/default_theme/tab_behind.png


二進制
scene/resources/default_theme/tab_container_bg.png


二進制
scene/resources/default_theme/tab_current.png


文件差異過大導致無法顯示
+ 0 - 1
scene/resources/default_theme/theme_data.h


二進制
scene/resources/default_theme/tree_bg.png


+ 20 - 0
scene/resources/texture.cpp

@@ -366,6 +366,16 @@ void ImageTexture::set_size_override(const Size2& p_size) {
 	VisualServer::get_singleton()->texture_set_size_override(texture,w,h);
 }
 
+void ImageTexture::set_path(const String& p_path,bool p_take_over) {
+
+	if (texture.is_valid()) {
+		VisualServer::get_singleton()->texture_set_path(texture,p_path);
+	}
+
+	Resource::set_path(p_path,p_take_over);
+}
+
+
 void ImageTexture::set_storage(Storage p_storage) {
 
 	storage=p_storage;
@@ -944,6 +954,16 @@ float CubeMap::get_lossy_storage_quality() const {
 	return lossy_storage_quality;
 }
 
+void CubeMap::set_path(const String& p_path,bool p_take_over) {
+
+	if (cubemap.is_valid()) {
+		VisualServer::get_singleton()->texture_set_path(cubemap,p_path);
+	}
+
+	Resource::set_path(p_path,p_take_over);
+}
+
+
 bool CubeMap::_set(const StringName& p_name, const Variant& p_value) {
 
 	if (p_name=="side/left") {

+ 4 - 1
scene/resources/texture.h

@@ -152,7 +152,8 @@ public:
 
 	void set_size_override(const Size2& p_size);
 
-	
+	virtual void set_path(const String& p_path,bool p_take_over=false);
+
 	ImageTexture();
 	~ImageTexture();
 
@@ -320,6 +321,8 @@ public:
 	void set_lossy_storage_quality(float p_lossy_storage_quality);
 	float get_lossy_storage_quality() const;
 
+	virtual void set_path(const String& p_path,bool p_take_over=false);
+
 	CubeMap();
 	~CubeMap();
 

+ 20 - 0
servers/register_server_types.cpp

@@ -35,6 +35,25 @@
 #include "physics_2d_server.h"
 #include "spatial_sound_server.h"
 #include "spatial_sound_2d_server.h"
+#include "script_debugger_remote.h"
+
+static void _debugger_get_resource_usage(List<ScriptDebuggerRemote::ResourceUsage>* r_usage) {
+
+	List<VS::TextureInfo> tinfo;
+	VS::get_singleton()->texture_debug_usage(&tinfo);
+
+	for (List<VS::TextureInfo>::Element *E=tinfo.front();E;E=E->next()) {
+
+		ScriptDebuggerRemote::ResourceUsage usage;
+		usage.path=E->get().path;
+		usage.vram=E->get().bytes;
+		usage.id=E->get().texture;
+		usage.type="Texture";
+		usage.format=itos(E->get().size.width)+"x"+itos(E->get().size.height)+" "+Image::get_format_name(E->get().format);
+		r_usage->push_back(usage);
+	}
+
+}
 
 void register_server_types() {
 
@@ -63,6 +82,7 @@ void register_server_types() {
 	ObjectTypeDB::register_virtual_type<PhysicsDirectSpaceState>();
 	ObjectTypeDB::register_virtual_type<PhysicsShapeQueryResult>();
 
+	ScriptDebuggerRemote::resource_usage_func=_debugger_get_resource_usage;
 }
 
 void unregister_server_types(){

+ 4 - 1
servers/visual/rasterizer.h

@@ -190,9 +190,12 @@ public:
 	virtual bool texture_has_alpha(RID p_texture) const=0;
 	virtual void texture_set_size_override(RID p_texture,int p_width, int p_height)=0;
 
-
 	virtual void texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const=0;
 
+	virtual void texture_set_path(RID p_texture,const String& p_path)=0;
+	virtual String texture_get_path(RID p_texture) const=0;
+	virtual void texture_debug_usage(List<VS::TextureInfo> *r_info)=0;
+
 	/* SHADER API */
 
 	virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL)=0;

+ 4 - 0
servers/visual/rasterizer_dummy.h

@@ -415,6 +415,10 @@ public:
 	virtual void texture_set_size_override(RID p_texture,int p_width, int p_height);
 	virtual void texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const;
 
+	virtual void texture_set_path(RID p_texture,const String& p_path) {}
+	virtual String texture_get_path(RID p_texture) const { return String(); }
+	virtual void texture_debug_usage(List<VS::TextureInfo> *r_info) {}
+
 	/* SHADER API */
 
 	virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL);

+ 15 - 0
servers/visual/visual_server_raster.cpp

@@ -112,6 +112,21 @@ void VisualServerRaster::texture_set_reload_hook(RID p_texture,ObjectID p_owner,
 	rasterizer->texture_set_reload_hook(p_texture,p_owner,p_function);
 }
 
+void VisualServerRaster::texture_set_path(RID p_texture,const String& p_path) {
+
+	rasterizer->texture_set_path(p_texture,p_path);
+}
+
+String VisualServerRaster::texture_get_path(RID p_texture) const{
+
+	return rasterizer->texture_get_path(p_texture);
+}
+
+void VisualServerRaster::texture_debug_usage(List<TextureInfo> *r_info){
+
+	rasterizer->texture_debug_usage(r_info);
+}
+
 /* SHADER API */
 
 RID VisualServerRaster::shader_create(ShaderMode p_mode) {

+ 5 - 0
servers/visual/visual_server_raster.h

@@ -668,6 +668,11 @@ public:
 	virtual bool texture_can_stream(RID p_texture) const;
 	virtual void texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const;
 
+	virtual void texture_set_path(RID p_texture,const String& p_path);
+	virtual String texture_get_path(RID p_texture) const;
+
+	virtual void texture_debug_usage(List<TextureInfo> *r_info);
+
 
 	/* SHADER API */
 	

+ 9 - 0
servers/visual/visual_server_wrap_mt.h

@@ -98,6 +98,15 @@ public:
 	FUNC1RC(bool,texture_can_stream,RID);
 	FUNC3C(texture_set_reload_hook,RID,ObjectID,const StringName&);
 
+	FUNC2(texture_set_path,RID,const String&);
+	FUNC1RC(String,texture_get_path,RID);
+
+	virtual void texture_debug_usage(List<TextureInfo> *r_info) {
+		//pass directly, should lock the server anyway
+		visual_server->texture_debug_usage(r_info);
+	}
+
+
 	/* SHADER API */
 
 	FUNC1R(RID,shader_create,ShaderMode);

+ 12 - 0
servers/visual_server.h

@@ -135,6 +135,18 @@ public:
 	virtual bool texture_can_stream(RID p_texture) const=0;
 	virtual void texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const=0;
 
+	virtual void texture_set_path(RID p_texture,const String& p_path)=0;
+	virtual String texture_get_path(RID p_texture) const=0;
+
+	struct TextureInfo {
+		RID texture;
+		Size2 size;
+		Image::Format format;
+		int bytes;
+		String path;
+	};
+
+	virtual void texture_debug_usage(List<TextureInfo> *r_info)=0;
 
 
 	/* SHADER API */

+ 15 - 6
tools/editor/editor_node.cpp

@@ -2946,6 +2946,20 @@ void EditorNode::_remove_edited_scene() {
 		unsaved_cache=false;
 	}
 }
+
+void EditorNode::_remove_scene(int index) {
+//	printf("Attempting to remove scene %d (current is %d)\n", index, editor_data.get_edited_scene());
+	if (editor_data.get_edited_scene() == index) {
+		//Scene to remove is current scene
+		_remove_edited_scene();
+	}
+	else {
+		// Scene to remove is not active scene.");
+		editor_data.remove_scene(index);
+		editor_data.get_undo_redo().clear_history();
+	}
+}
+
 void EditorNode::set_edited_scene(Node *p_scene) {
 
 	if (get_editor_data().get_edited_scene_root()) {
@@ -4390,12 +4404,7 @@ void EditorNode::_scene_tab_script_edited(int p_tab) {
 }
 
 void EditorNode::_scene_tab_closed(int p_tab) {
-	set_current_scene(p_tab);
- 	bool p_confirmed = true;
- 	if (unsaved_cache)
- 		p_confirmed = false;
-
- 	_menu_option_confirm(FILE_CLOSE, p_confirmed);
+ 	_remove_scene(p_tab);
 	_update_scene_tabs();
 }
 

+ 1 - 0
tools/editor/editor_node.h

@@ -461,6 +461,7 @@ class EditorNode : public Node {
 
 	void _cleanup_scene();
 	void _remove_edited_scene();
+	void _remove_scene(int index);
 	bool _find_and_save_resource(RES p_res,Map<RES,bool>& processed,int32_t flags);
 	bool _find_and_save_edited_subresources(Object *obj,Map<RES,bool>& processed,int32_t flags);
 	void _save_edited_subresources(Node* scene,Map<RES,bool>& processed,int32_t flags);

+ 16 - 4
tools/editor/io_plugins/editor_texture_import_plugin.cpp

@@ -1180,8 +1180,15 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
 
 		ep.step("Blitting Images",sources.size()+2);
 
+		bool blit_to_po2=tex_flags&Texture::FLAG_MIPMAPS;
+		int atlas_w=dst_size.width;
+		int atlas_h=dst_size.height;
+		if (blit_to_po2) {
+			atlas_w=nearest_power_of_2(dst_size.width);
+			atlas_h=nearest_power_of_2(dst_size.height);
+		}
 		Image atlas;
-		atlas.create(nearest_power_of_2(dst_size.width),nearest_power_of_2(dst_size.height),0,alpha?Image::FORMAT_RGBA:Image::FORMAT_RGB);
+		atlas.create(atlas_w,atlas_h,0,alpha?Image::FORMAT_RGBA:Image::FORMAT_RGB);
 
 
 		atlases.resize(from->get_source_count());
@@ -1210,16 +1217,21 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
 			ERR_CONTINUE( !source_map.has(i) );
 			for (List<int>::Element *E=source_map[i].front();E;E=E->next()) {
 
-				Ref<AtlasTexture> at = memnew( AtlasTexture );
+				String apath = p_path.get_base_dir().plus_file(from->get_source_path(E->get()).get_file().basename()+".atex");
+
+				Ref<AtlasTexture> at;
 
+				if (ResourceCache::has(apath)) {
+					at = Ref<AtlasTexture>( ResourceCache::get(apath)->cast_to<AtlasTexture>() );
+				} else {
 
+					at = Ref<AtlasTexture>( memnew( AtlasTexture ) );
+				}
 				at->set_region(region);
 				at->set_margin(margin);
-				String apath = p_path.get_base_dir().plus_file(from->get_source_path(E->get()).get_file().basename()+".atex");
 				at->set_path(apath);
 				atlases[E->get()]=at;
 				print_line("Atlas Tex: "+apath);
-
 			}
 		}
 		if (ResourceCache::has(p_path)) {

+ 2 - 1
tools/editor/scene_tree_dock.cpp

@@ -1088,7 +1088,8 @@ void SceneTreeDock::_delete_confirm() {
 void SceneTreeDock::_update_tool_buttons() {
 
 	Node *sel = scene_tree->get_selected();
-	bool disable = !sel || (sel!=edited_scene && sel->get_owner()!=edited_scene) || (edited_scene->get_scene_instance_state().is_valid() && edited_scene->get_scene_instance_state()->find_node_by_path(edited_scene->get_path_to(sel))>=0);
+	bool disable = !sel || (sel!=edited_scene && sel->get_owner()!=edited_scene);
+	disable = disable || (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(sel))>=0);
 	bool disable_root = disable || sel->get_parent()==scene_root;
 	bool disable_edit = !sel;
 

+ 80 - 0
tools/editor/script_editor_debugger.cpp

@@ -169,6 +169,17 @@ void ScriptEditorDebugger::_scene_tree_request() {
 
 }
 
+void ScriptEditorDebugger::_video_mem_request() {
+
+	ERR_FAIL_COND(connection.is_null());
+	ERR_FAIL_COND(!connection->is_connected());
+
+	Array msg;
+	msg.push_back("request_video_mem");
+	ppeer->put_var(msg);
+
+}
+
 Size2 ScriptEditorDebugger::get_minimum_size() const {
 
 	Size2 ms = Control::get_minimum_size();
@@ -244,6 +255,31 @@ void ScriptEditorDebugger::_parse_message(const String& p_msg,const Array& p_dat
 		le_clear->set_disabled(false);
 		le_set->set_disabled(false);
 
+	} else if (p_msg=="message:video_mem") {
+
+		vmem_tree->clear();
+		TreeItem* root=vmem_tree->create_item();
+
+		int total=0;
+
+		for(int i=0;i<p_data.size();i+=4) {
+
+			TreeItem *it = vmem_tree->create_item(root);
+			String type=p_data[i+1];
+			int bytes=p_data[i+3].operator int();
+			it->set_text(0,p_data[i+0]); //path
+			it->set_text(1,type); //type
+			it->set_text(2,p_data[i+2]); //type
+			it->set_text(3,String::humanize_size(bytes)); //type
+			total+=bytes;
+
+			if (has_icon(type,"EditorIcons"))
+				it->set_icon(0,get_icon(type,"EditorIcons"));
+		}
+
+		vmem_total->set_tooltip("Bytes: "+itos(total));
+		vmem_total->set_text(String::humanize_size(total));
+
 	} else if (p_msg=="stack_dump") {
 
 		stack_dump->clear();
@@ -506,6 +542,7 @@ void ScriptEditorDebugger::_notification(int p_what) {
 			le_clear->connect("pressed",this,"_live_edit_clear");
 			error_list->connect("item_selected",this,"_error_selected");
 			error_stack->connect("item_selected",this,"_error_stack_selected");
+			vmem_refresh->set_icon( get_icon("Reload","EditorIcons"));
 
 		} break;
 		case NOTIFICATION_PROCESS: {
@@ -1136,6 +1173,7 @@ void ScriptEditorDebugger::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("_performance_draw"),&ScriptEditorDebugger::_performance_draw);
 	ObjectTypeDB::bind_method(_MD("_performance_select"),&ScriptEditorDebugger::_performance_select);
 	ObjectTypeDB::bind_method(_MD("_scene_tree_request"),&ScriptEditorDebugger::_scene_tree_request);
+	ObjectTypeDB::bind_method(_MD("_video_mem_request"),&ScriptEditorDebugger::_video_mem_request);
 	ObjectTypeDB::bind_method(_MD("_live_edit_set"),&ScriptEditorDebugger::_live_edit_set);
 	ObjectTypeDB::bind_method(_MD("_live_edit_clear"),&ScriptEditorDebugger::_live_edit_clear);
 
@@ -1322,6 +1360,48 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor){
 
 	}
 
+	VBoxContainer *vmem_vb = memnew( VBoxContainer );
+	HBoxContainer *vmem_hb = memnew( HBoxContainer );
+	Label *vmlb = memnew(Label("List of Video Memory Usage by Resource: ") );
+	vmlb->set_h_size_flags(SIZE_EXPAND_FILL);
+	vmem_hb->add_child( vmlb );
+	vmem_hb->add_child( memnew(Label("Total: ")) );
+	vmem_total = memnew( LineEdit );
+	vmem_total->set_editable(false);
+	vmem_total->set_custom_minimum_size(Size2(100,1));
+	vmem_hb->add_child(vmem_total);
+	vmem_refresh = memnew( Button );
+	vmem_hb->add_child(vmem_refresh);
+	vmem_vb->add_child(vmem_hb);
+	vmem_refresh->connect("pressed",this,"_video_mem_request");
+
+	MarginContainer *vmmc = memnew( MarginContainer );
+	vmmc = memnew( MarginContainer );
+	vmem_tree = memnew( Tree );
+	vmem_tree->set_v_size_flags(SIZE_EXPAND_FILL);
+	vmem_tree->set_h_size_flags(SIZE_EXPAND_FILL);
+	vmmc->add_child(vmem_tree);
+	vmmc->set_v_size_flags(SIZE_EXPAND_FILL);
+	vmem_vb->add_child(vmmc);
+
+	vmem_vb->set_name("Video Mem");
+	vmem_tree->set_columns(4);
+	vmem_tree->set_column_titles_visible(true);
+	vmem_tree->set_column_title(0,"Resource Path");
+	vmem_tree->set_column_expand(0,true);
+	vmem_tree->set_column_expand(1,false);
+	vmem_tree->set_column_title(1,"Type");
+	vmem_tree->set_column_min_width(1,100);
+	vmem_tree->set_column_expand(2,false);
+	vmem_tree->set_column_title(2,"Format");
+	vmem_tree->set_column_min_width(2,150);
+	vmem_tree->set_column_expand(3,false);
+	vmem_tree->set_column_title(3,"Usage");
+	vmem_tree->set_column_min_width(3,80);
+	vmem_tree->set_hide_root(true);
+
+	tabs->add_child(vmem_vb);
+
 	info = memnew( HSplitContainer );
 	info->set_name("Info");
 	tabs->add_child(info);

+ 5 - 0
tools/editor/script_editor_debugger.h

@@ -96,6 +96,10 @@ class ScriptEditorDebugger : public Control {
 	Tree *perf_monitors;
 	Control *perf_draw;
 
+	Tree *vmem_tree;
+	Button *vmem_refresh;
+	LineEdit *vmem_total;
+
 	Tree *stack_dump;
 	PropertyEditor *inspector;
 
@@ -127,6 +131,7 @@ class ScriptEditorDebugger : public Control {
 	void _scene_tree_request();
 	void _parse_message(const String& p_msg,const Array& p_data);
 
+	void _video_mem_request();
 
 	int _get_node_path_cache(const NodePath& p_path);
 

部分文件因文件數量過多而無法顯示