Browse Source

Removal of Image from Variant, converted to a Resource.

Juan Linietsky 8 years ago
parent
commit
98a3296702
100 changed files with 582 additions and 3058 deletions
  1. 1 1
      core/bind/core_bind.cpp
  2. 2 1
      core/bind/core_bind.h
  3. 0 1
      core/global_constants.cpp
  4. 176 54
      core/image.cpp
  5. 52 23
      core/image.h
  6. 2 1
      core/io/image_loader.cpp
  7. 2 2
      core/io/image_loader.h
  8. 0 56
      core/io/marshalls.cpp
  9. 1 133
      core/io/resource_format_binary.cpp
  10. 1 1
      core/method_bind.h
  11. 0 1
      core/method_ptrcall.h
  12. 1 1
      core/os/os.cpp
  13. 2 1
      core/os/os.h
  14. 0 1
      core/packed_data_container.cpp
  15. 2 0
      core/register_core_types.cpp
  16. 1 1
      core/resource.cpp
  17. 1 1
      core/resource.h
  18. 1 3
      core/script_debugger_remote.cpp
  19. 0 38
      core/variant.cpp
  20. 4 9
      core/variant.h
  21. 0 94
      core/variant_call.cpp
  22. 8 20
      core/variant_op.cpp
  23. 0 175
      core/variant_parser.cpp
  24. 2 2
      drivers/gles2/rasterizer_gles2.cpp
  25. 4 4
      drivers/gles3/rasterizer_gles3.cpp
  26. 1 1
      drivers/gles3/rasterizer_gles3.h
  27. 34 33
      drivers/gles3/rasterizer_storage_gles3.cpp
  28. 4 4
      drivers/gles3/rasterizer_storage_gles3.h
  29. 22 20
      drivers/png/image_loader_png.cpp
  30. 2 2
      drivers/png/image_loader_png.h
  31. 14 12
      drivers/png/resource_saver_png.cpp
  32. 2 1
      drivers/png/resource_saver_png.h
  33. 5 4
      editor/asset_library_editor_plugin.cpp
  34. 0 2
      editor/connections_dialog.cpp
  35. 0 4
      editor/doc/doc_data.cpp
  36. 0 4
      editor/doc/doc_dump.cpp
  37. 6 4
      editor/editor_file_dialog.cpp
  38. 3 2
      editor/editor_node.cpp
  39. 4 2
      editor/editor_profiler.cpp
  40. 5 4
      editor/editor_run_native.cpp
  41. 5 4
      editor/filesystem_dock.cpp
  42. 3 3
      editor/icons/SCsub
  43. 34 33
      editor/import/resource_importer_texture.cpp
  44. 3 1
      editor/import/resource_importer_texture.h
  45. 1 1
      editor/plugins/baked_light_baker.h
  46. 2 1
      editor/plugins/gradient_texture_editor_plugin.cpp
  47. 8 7
      editor/plugins/particles_2d_editor_plugin.cpp
  48. 2 2
      editor/plugins/particles_editor_plugin.cpp
  49. 1 1
      editor/plugins/spatial_editor_plugin.h
  50. 5 4
      editor/plugins/texture_region_editor_plugin.cpp
  51. 4 3
      editor/project_manager.cpp
  52. 0 72
      editor/property_editor.cpp
  53. 0 1
      editor/property_selector.cpp
  54. 2 2
      editor/pvrtc_compress.cpp
  55. 8 7
      main/main.cpp
  56. 0 12
      main/tests/test_containers.cpp
  57. 0 5
      main/tests/test_image.cpp
  58. 5 5
      main/tests/test_physics_2d.cpp
  59. 1 1
      modules/dds/texture_loader_dds.cpp
  60. 10 9
      modules/etc1/image_etc.cpp
  61. 1 1
      modules/etc1/texture_loader_pkm.cpp
  62. 1 1
      modules/gdnative/config.py
  63. 1 1
      modules/gdscript/gd_editor.cpp
  64. 0 1
      modules/gdscript/gd_tokenizer.cpp
  65. 6 5
      modules/jpg/image_loader_jpegd.cpp
  66. 1 1
      modules/jpg/image_loader_jpegd.h
  67. 22 21
      modules/pvr/texture_loader_pvr.cpp
  68. 1 1
      modules/theora/video_stream_theora.cpp
  69. 0 3
      modules/visual_script/visual_script_editor.cpp
  70. 18 17
      modules/webp/image_loader_webp.cpp
  71. 1 1
      modules/webp/image_loader_webp.h
  72. 1 1
      platform/android/export/export.cpp
  73. 1 1
      platform/javascript/export/export.cpp
  74. 1 1
      platform/osx/os_osx.h
  75. 10 9
      platform/osx/os_osx.mm
  76. 1 1
      platform/uwp/os_uwp.cpp
  77. 1 1
      platform/uwp/os_uwp.h
  78. 1 1
      platform/windows/export/export.cpp
  79. 8 7
      platform/windows/os_windows.cpp
  80. 1 1
      platform/windows/os_windows.h
  81. 1 1
      platform/x11/export/export.cpp
  82. 7 7
      platform/x11/os_x11.cpp
  83. 1 1
      platform/x11/os_x11.h
  84. 0 1754
      scene/3d/baked_light_instance.cpp
  85. 0 199
      scene/3d/baked_light_instance.h
  86. 10 10
      scene/3d/gi_probe.cpp
  87. 2 2
      scene/3d/gi_probe.h
  88. 0 20
      scene/3d/light.cpp
  89. 0 1
      scene/3d/light.h
  90. 7 7
      scene/gui/color_picker.cpp
  91. 1 1
      scene/gui/color_picker.h
  92. 2 1
      scene/gui/color_ramp_edit.cpp
  93. 1 1
      scene/gui/video_player.h
  94. 2 2
      scene/main/viewport.cpp
  95. 1 1
      scene/main/viewport.h
  96. 2 2
      scene/register_scene_types.cpp
  97. 0 31
      scene/resources/baked_light.cpp
  98. 0 36
      scene/resources/baked_light.h
  99. 7 7
      scene/resources/bit_mask.cpp
  100. 2 1
      scene/resources/bit_mask.h

+ 1 - 1
core/bind/core_bind.cpp

@@ -505,7 +505,7 @@ int _OS::get_dynamic_memory_usage() const {
 	return OS::get_singleton()->get_dynamic_memory_usage();
 }
 
-void _OS::set_icon(const Image &p_icon) {
+void _OS::set_icon(const Ref<Image> &p_icon) {
 
 	OS::get_singleton()->set_icon(p_icon);
 }

+ 2 - 1
core/bind/core_bind.h

@@ -30,6 +30,7 @@
 #ifndef CORE_BIND_H
 #define CORE_BIND_H
 
+#include "image.h"
 #include "io/resource_loader.h"
 #include "io/resource_saver.h"
 #include "os/dir_access.h"
@@ -226,7 +227,7 @@ public:
 
 	void set_use_file_access_save_and_swap(bool p_enable);
 
-	void set_icon(const Image &p_icon);
+	void set_icon(const Ref<Image> &p_icon);
 
 	int get_exit_code() const;
 	void set_exit_code(int p_code);

+ 0 - 1
core/global_constants.cpp

@@ -510,7 +510,6 @@ static _GlobalConstant _global_constants[] = {
 	{ "TYPE_BASIS", Variant::BASIS },
 	{ "TYPE_TRANSFORM", Variant::TRANSFORM },
 	{ "TYPE_COLOR", Variant::COLOR },
-	{ "TYPE_IMAGE", Variant::IMAGE }, // 15
 	{ "TYPE_NODE_PATH", Variant::NODE_PATH },
 	{ "TYPE_RID", Variant::_RID },
 	{ "TYPE_OBJECT", Variant::OBJECT },

+ 176 - 54
core/image.cpp

@@ -415,7 +415,7 @@ void Image::convert(Format p_new_format) {
 
 	//mipmaps=false;
 
-	*this = new_img;
+	_copy_internals_from(new_img);
 
 	if (gen_mipmaps)
 		generate_mipmaps();
@@ -611,14 +611,6 @@ void Image::resize_to_po2(bool p_square) {
 	resize(w, h);
 }
 
-Image Image::resized(int p_width, int p_height, int p_interpolation) {
-
-	Image ret = *this;
-	ret.resize(p_width, p_height, (Interpolation)p_interpolation);
-
-	return ret;
-};
-
 void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
 
 	if (!_can_modify(format)) {
@@ -681,7 +673,7 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
 	if (mipmaps > 0)
 		dst.generate_mipmaps();
 
-	*this = dst;
+	_copy_internals_from(dst);
 }
 void Image::crop(int p_width, int p_height) {
 
@@ -728,7 +720,7 @@ void Image::crop(int p_width, int p_height) {
 
 	if (mipmaps > 0)
 		dst.generate_mipmaps();
-	*this = dst;
+	_copy_internals_from(dst);
 }
 
 void Image::flip_y() {
@@ -1383,17 +1375,7 @@ Error Image::save_png(const String &p_path) {
 	if (save_png_func == NULL)
 		return ERR_UNAVAILABLE;
 
-	return save_png_func(p_path, *this);
-}
-
-bool Image::operator==(const Image &p_image) const {
-
-	if (data.size() == 0 && p_image.data.size() == 0)
-		return true;
-	PoolVector<uint8_t>::Read r = data.read();
-	PoolVector<uint8_t>::Read pr = p_image.data.read();
-
-	return r.ptr() == pr.ptr();
+	return save_png_func(p_path, Ref<Image>(this));
 }
 
 int Image::get_image_data_size(int p_width, int p_height, Format p_format, int p_mipmaps) {
@@ -1736,13 +1718,6 @@ bool Image::is_compressed() const {
 	return format >= FORMAT_RGB565;
 }
 
-Image Image::decompressed() const {
-
-	Image img = *this;
-	img.decompress();
-	return img;
-}
-
 Error Image::decompress() {
 
 	if (format >= FORMAT_DXT1 && format <= FORMAT_ATI2)
@@ -1797,14 +1772,6 @@ Error Image::compress(CompressMode p_mode) {
 	return OK;
 }
 
-Image Image::compressed(int p_mode) {
-
-	Image ret = *this;
-	ret.compress((Image::CompressMode)p_mode);
-
-	return ret;
-}
-
 Image::Image(const char **p_xpm) {
 
 	width = 0;
@@ -1875,21 +1842,21 @@ Rect2 Image::get_used_rect() const {
 		return Rect2(minx, miny, maxx - minx + 1, maxy - miny + 1);
 }
 
-Image Image::get_rect(const Rect2 &p_area) const {
-
-	Image img(p_area.size.x, p_area.size.y, mipmaps, format);
-	img.blit_rect(*this, p_area, Point2(0, 0));
+Ref<Image> Image::get_rect(const Rect2 &p_area) const {
 
+	Ref<Image> img = memnew(Image(p_area.size.x, p_area.size.y, mipmaps, format));
+	img->blit_rect(Ref<Image>(this), p_area, Point2(0, 0));
 	return img;
 }
 
-void Image::blit_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
+void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
 
+	ERR_FAIL_COND(p_src.is_null());
 	int dsize = data.size();
-	int srcdsize = p_src.data.size();
+	int srcdsize = p_src->data.size();
 	ERR_FAIL_COND(dsize == 0);
 	ERR_FAIL_COND(srcdsize == 0);
-	ERR_FAIL_COND(format != p_src.format);
+	ERR_FAIL_COND(format != p_src->format);
 
 	Rect2i local_src_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest + p_src_rect.pos, p_src_rect.size));
 
@@ -1900,7 +1867,7 @@ void Image::blit_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2
 	PoolVector<uint8_t>::Write wp = data.write();
 	uint8_t *dst_data_ptr = wp.ptr();
 
-	PoolVector<uint8_t>::Read rp = p_src.data.read();
+	PoolVector<uint8_t>::Read rp = p_src->data.read();
 	const uint8_t *src_data_ptr = rp.ptr();
 
 	int pixel_size = get_format_pixel_size(format);
@@ -1915,7 +1882,7 @@ void Image::blit_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2
 			int dst_x = local_src_rect.pos.x + j;
 			int dst_y = local_src_rect.pos.y + i;
 
-			const uint8_t *src = &src_data_ptr[(src_y * p_src.width + src_x) * pixel_size];
+			const uint8_t *src = &src_data_ptr[(src_y * p_src->width + src_x) * pixel_size];
 			uint8_t *dst = &dst_data_ptr[(dst_y * width + dst_x) * pixel_size];
 
 			for (int k = 0; k < pixel_size; k++) {
@@ -1925,8 +1892,8 @@ void Image::blit_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2
 	}
 }
 
-Image (*Image::_png_mem_loader_func)(const uint8_t *, int) = NULL;
-Image (*Image::_jpg_mem_loader_func)(const uint8_t *, int) = NULL;
+Ref<Image> (*Image::_png_mem_loader_func)(const uint8_t *, int) = NULL;
+Ref<Image> (*Image::_jpg_mem_loader_func)(const uint8_t *, int) = NULL;
 
 void (*Image::_image_compress_bc_func)(Image *) = NULL;
 void (*Image::_image_compress_pvrtc2_func)(Image *) = NULL;
@@ -1938,10 +1905,157 @@ void (*Image::_image_decompress_bc)(Image *) = NULL;
 void (*Image::_image_decompress_etc)(Image *) = NULL;
 void (*Image::_image_decompress_etc2)(Image *) = NULL;
 
-PoolVector<uint8_t> (*Image::lossy_packer)(const Image &, float) = NULL;
-Image (*Image::lossy_unpacker)(const PoolVector<uint8_t> &) = NULL;
-PoolVector<uint8_t> (*Image::lossless_packer)(const Image &) = NULL;
-Image (*Image::lossless_unpacker)(const PoolVector<uint8_t> &) = NULL;
+PoolVector<uint8_t> (*Image::lossy_packer)(const Ref<Image> &, float) = NULL;
+Ref<Image> (*Image::lossy_unpacker)(const PoolVector<uint8_t> &) = NULL;
+PoolVector<uint8_t> (*Image::lossless_packer)(const Ref<Image> &) = NULL;
+Ref<Image> (*Image::lossless_unpacker)(const PoolVector<uint8_t> &) = NULL;
+
+void Image::_set_data(const Dictionary &p_data) {
+
+	ERR_FAIL_COND(!p_data.has("width"));
+	ERR_FAIL_COND(!p_data.has("height"));
+	ERR_FAIL_COND(!p_data.has("format"));
+	ERR_FAIL_COND(!p_data.has("mipmaps"));
+	ERR_FAIL_COND(!p_data.has("data"));
+
+	int dwidth = p_data["width"];
+	int dheight = p_data["height"];
+	String dformat = p_data["format"];
+	bool dmipmaps = p_data["mipmaps"];
+	PoolVector<uint8_t> ddata = p_data["data"];
+	Format ddformat = FORMAT_MAX;
+	for (int i = 0; i < FORMAT_MAX; i++) {
+		if (dformat == get_format_name(Format(i))) {
+			ddformat = Format(i);
+			break;
+		}
+	}
+
+	ERR_FAIL_COND(ddformat == FORMAT_MAX);
+
+	create(dwidth, dheight, dmipmaps, ddformat, ddata);
+}
+
+Dictionary Image::_get_data() const {
+
+	Dictionary d;
+	d["width"] = width;
+	d["height"] = height;
+	d["format"] = get_format_name(format);
+	d["mipmaps"] = mipmaps;
+	d["data"] = data;
+	return d;
+}
+
+void Image::_bind_methods() {
+
+	ClassDB::bind_method(D_METHOD("get_width"), &Image::get_width);
+	ClassDB::bind_method(D_METHOD("get_height"), &Image::get_height);
+	ClassDB::bind_method(D_METHOD("has_mipmaps"), &Image::has_mipmaps);
+	ClassDB::bind_method(D_METHOD("get_format"), &Image::get_format);
+	ClassDB::bind_method(D_METHOD("get_data"), &Image::get_data);
+
+	ClassDB::bind_method(D_METHOD("convert", "format"), &Image::convert);
+
+	ClassDB::bind_method(D_METHOD("get_mipmap_offset", "mipmap"), &Image::get_mipmap_offset);
+
+	ClassDB::bind_method(D_METHOD("resize_to_po2", "square"), &Image::resize_to_po2, DEFVAL("false"));
+	ClassDB::bind_method(D_METHOD("resize", "width", "height", "interpolation"), &Image::resize_to_po2, DEFVAL(INTERPOLATE_BILINEAR));
+	ClassDB::bind_method(D_METHOD("shrink_x2"), &Image::shrink_x2);
+	ClassDB::bind_method(D_METHOD("expand_x2_hq2x"), &Image::expand_x2_hq2x);
+
+	ClassDB::bind_method(D_METHOD("crop", "width", "height"), &Image::crop);
+	ClassDB::bind_method(D_METHOD("flip_x"), &Image::flip_x);
+	ClassDB::bind_method(D_METHOD("flip_y"), &Image::flip_y);
+	ClassDB::bind_method(D_METHOD("generate_mipmaps"), &Image::generate_mipmaps);
+	ClassDB::bind_method(D_METHOD("clear_mipmaps"), &Image::clear_mipmaps);
+
+	ClassDB::bind_method(D_METHOD("create", "width", "height", "use_mipmaps", "format"), &Image::_create_empty);
+	ClassDB::bind_method(D_METHOD("create_from_data", "width", "height", "use_mipmaps", "format", "data"), &Image::_create_from_data);
+
+	ClassDB::bind_method(D_METHOD("is_empty"), &Image::empty);
+
+	ClassDB::bind_method(D_METHOD("load", "path"), &Image::load);
+	ClassDB::bind_method(D_METHOD("save_png", "path"), &Image::save_png);
+
+	ClassDB::bind_method(D_METHOD("detect_alpha"), &Image::detect_alpha);
+	ClassDB::bind_method(D_METHOD("is_invisible"), &Image::is_invisible);
+
+	ClassDB::bind_method(D_METHOD("compress", "mode"), &Image::compress);
+	ClassDB::bind_method(D_METHOD("decompress"), &Image::decompress);
+	ClassDB::bind_method(D_METHOD("is_compressed"), &Image::is_compressed);
+
+	ClassDB::bind_method(D_METHOD("fix_alpha_edges"), &Image::fix_alpha_edges);
+	ClassDB::bind_method(D_METHOD("premultiply_alpha"), &Image::premultiply_alpha);
+	ClassDB::bind_method(D_METHOD("srgb_to_linear"), &Image::srgb_to_linear);
+	ClassDB::bind_method(D_METHOD("normalmap_to_xy"), &Image::normalmap_to_xy);
+
+	ClassDB::bind_method(D_METHOD("blit_rect", "src:Image", "src_rect", "dst"), &Image::blit_rect);
+
+	ClassDB::bind_method(D_METHOD("get_used_rect"), &Image::get_used_rect);
+	ClassDB::bind_method(D_METHOD("get_rect:Image", "rect"), &Image::get_rect);
+
+	ClassDB::bind_method(D_METHOD("copy_from", "src:Image"), &Image::copy_internals_from);
+
+	ClassDB::bind_method(D_METHOD("_set_data", "data"), &Image::_set_data);
+	ClassDB::bind_method(D_METHOD("_get_data"), &Image::_get_data);
+
+	ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "_set_data", "_get_data");
+
+	BIND_CONSTANT(FORMAT_L8); //luminance
+	BIND_CONSTANT(FORMAT_LA8); //luminance-alpha
+	BIND_CONSTANT(FORMAT_R8);
+	BIND_CONSTANT(FORMAT_RG8);
+	BIND_CONSTANT(FORMAT_RGB8);
+	BIND_CONSTANT(FORMAT_RGBA8);
+	BIND_CONSTANT(FORMAT_RGB565); //16 bit
+	BIND_CONSTANT(FORMAT_RGBA4444);
+	BIND_CONSTANT(FORMAT_RGBA5551);
+	BIND_CONSTANT(FORMAT_RF); //float
+	BIND_CONSTANT(FORMAT_RGF);
+	BIND_CONSTANT(FORMAT_RGBF);
+	BIND_CONSTANT(FORMAT_RGBAF);
+	BIND_CONSTANT(FORMAT_RH); //half float
+	BIND_CONSTANT(FORMAT_RGH);
+	BIND_CONSTANT(FORMAT_RGBH);
+	BIND_CONSTANT(FORMAT_RGBAH);
+	BIND_CONSTANT(FORMAT_DXT1); //s3tc bc1
+	BIND_CONSTANT(FORMAT_DXT3); //bc2
+	BIND_CONSTANT(FORMAT_DXT5); //bc3
+	BIND_CONSTANT(FORMAT_ATI1); //bc4
+	BIND_CONSTANT(FORMAT_ATI2); //bc5
+	BIND_CONSTANT(FORMAT_BPTC_RGBA); //btpc bc6h
+	BIND_CONSTANT(FORMAT_BPTC_RGBF); //float /
+	BIND_CONSTANT(FORMAT_BPTC_RGBFU); //unsigned float
+	BIND_CONSTANT(FORMAT_PVRTC2); //pvrtc
+	BIND_CONSTANT(FORMAT_PVRTC2A);
+	BIND_CONSTANT(FORMAT_PVRTC4);
+	BIND_CONSTANT(FORMAT_PVRTC4A);
+	BIND_CONSTANT(FORMAT_ETC); //etc1
+	BIND_CONSTANT(FORMAT_ETC2_R11); //etc2
+	BIND_CONSTANT(FORMAT_ETC2_R11S); //signed ); NOT srgb.
+	BIND_CONSTANT(FORMAT_ETC2_RG11);
+	BIND_CONSTANT(FORMAT_ETC2_RG11S);
+	BIND_CONSTANT(FORMAT_ETC2_RGB8);
+	BIND_CONSTANT(FORMAT_ETC2_RGBA8);
+	BIND_CONSTANT(FORMAT_ETC2_RGB8A1);
+	BIND_CONSTANT(FORMAT_MAX);
+
+	BIND_CONSTANT(INTERPOLATE_NEAREST);
+	BIND_CONSTANT(INTERPOLATE_BILINEAR);
+	BIND_CONSTANT(INTERPOLATE_CUBIC);
+
+	BIND_CONSTANT(ALPHA_NONE);
+	BIND_CONSTANT(ALPHA_BIT);
+	BIND_CONSTANT(ALPHA_BLEND);
+
+	BIND_CONSTANT(COMPRESS_16BIT);
+	BIND_CONSTANT(COMPRESS_S3TC);
+	BIND_CONSTANT(COMPRESS_PVRTC2);
+	BIND_CONSTANT(COMPRESS_PVRTC4);
+	BIND_CONSTANT(COMPRESS_ETC);
+	BIND_CONSTANT(COMPRESS_ETC2);
+}
 
 void Image::set_compress_bc_func(void (*p_compress_func)(Image *)) {
 
@@ -2108,14 +2222,22 @@ Image::Image(const uint8_t *p_mem_png_jpg, int p_len) {
 	format = FORMAT_L8;
 
 	if (_png_mem_loader_func) {
-		*this = _png_mem_loader_func(p_mem_png_jpg, p_len);
+		copy_internals_from(_png_mem_loader_func(p_mem_png_jpg, p_len));
 	}
 
 	if (empty() && _jpg_mem_loader_func) {
-		*this = _jpg_mem_loader_func(p_mem_png_jpg, p_len);
+		copy_internals_from(_jpg_mem_loader_func(p_mem_png_jpg, p_len));
 	}
 }
 
+Ref<Resource> Image::duplicate(bool p_subresources) const {
+
+	Ref<Image> copy;
+	copy.instance();
+	copy->_copy_internals_from(*this);
+	return copy;
+}
+
 Image::Image() {
 
 	width = 0;

+ 52 - 23
core/image.h

@@ -33,6 +33,8 @@
 #include "color.h"
 #include "dvector.h"
 #include "math_2d.h"
+#include "resource.h"
+
 /**
  *	@author Juan Linietsky <[email protected]>
  *
@@ -43,9 +45,10 @@
 
 class Image;
 
-typedef Error (*SavePNGFunc)(const String &p_path, Image &p_img);
+typedef Error (*SavePNGFunc)(const String &p_path, const Ref<Image> &p_img);
 
-class Image {
+class Image : public Resource {
+	GDCLASS(Image, Resource);
 
 	enum {
 		MAX_WIDTH = 16384, // force a limit somehow
@@ -108,8 +111,8 @@ public:
 
 	//some functions provided by something else
 
-	static Image (*_png_mem_loader_func)(const uint8_t *p_png, int p_size);
-	static Image (*_jpg_mem_loader_func)(const uint8_t *p_png, int p_size);
+	static Ref<Image> (*_png_mem_loader_func)(const uint8_t *p_png, int p_size);
+	static Ref<Image> (*_jpg_mem_loader_func)(const uint8_t *p_png, int p_size);
 
 	static void (*_image_compress_bc_func)(Image *);
 	static void (*_image_compress_pvrtc2_func)(Image *);
@@ -124,17 +127,36 @@ public:
 
 	Error _decompress_bc();
 
-	static PoolVector<uint8_t> (*lossy_packer)(const Image &p_image, float p_quality);
-	static Image (*lossy_unpacker)(const PoolVector<uint8_t> &p_buffer);
-	static PoolVector<uint8_t> (*lossless_packer)(const Image &p_image);
-	static Image (*lossless_unpacker)(const PoolVector<uint8_t> &p_buffer);
+	static PoolVector<uint8_t> (*lossy_packer)(const Ref<Image> &p_image, float p_quality);
+	static Ref<Image> (*lossy_unpacker)(const PoolVector<uint8_t> &p_buffer);
+	static PoolVector<uint8_t> (*lossless_packer)(const Ref<Image> &p_image);
+	static Ref<Image> (*lossless_unpacker)(const PoolVector<uint8_t> &p_buffer);
+
+protected:
+	static void _bind_methods();
 
 private:
+	void _create_empty(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
+		create(p_width, p_height, p_use_mipmaps, p_format);
+	}
+
+	void _create_from_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const PoolVector<uint8_t> &p_data) {
+		create(p_width, p_height, p_use_mipmaps, p_format, p_data);
+	}
+
 	Format format;
 	PoolVector<uint8_t> data;
 	int width, height;
 	bool mipmaps;
 
+	void _copy_internals_from(const Image &p_image) {
+		format = p_image.format;
+		width = p_image.width;
+		height = p_image.height;
+		mipmaps = p_image.mipmaps;
+		data = p_image.data;
+	}
+
 	_FORCE_INLINE_ void _get_mipmap_offset_and_size(int p_mipmap, int &r_offset, int &r_width, int &r_height) const; //get where the mipmap begins in data
 
 	static int _get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps = -1);
@@ -143,6 +165,9 @@ private:
 	_FORCE_INLINE_ void _put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_dst, const uint8_t *p_src);
 	_FORCE_INLINE_ void _get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_src, uint8_t *p_dst);
 
+	void _set_data(const Dictionary &p_data);
+	Dictionary _get_data() const;
+
 public:
 	int get_width() const; ///< Get image width
 	int get_height() const; ///< Get image height
@@ -154,14 +179,6 @@ public:
 	 */
 	void convert(Format p_new_format);
 
-	Image converted(int p_new_format) {
-		ERR_FAIL_INDEX_V(p_new_format, FORMAT_MAX, Image());
-
-		Image ret = *this;
-		ret.convert((Format)p_new_format);
-		return ret;
-	};
-
 	/**
 	 * Get the current image format.
 	 */
@@ -178,7 +195,6 @@ public:
 
 	void resize_to_po2(bool p_square = false);
 	void resize(int p_width, int p_height, Interpolation p_interpolation = INTERPOLATE_BILINEAR);
-	Image resized(int p_width, int p_height, int p_interpolation = INTERPOLATE_BILINEAR);
 	void shrink_x2();
 	void expand_x2_hq2x();
 	/**
@@ -242,8 +258,6 @@ public:
 	static int get_image_data_size(int p_width, int p_height, Format p_format, int p_mipmaps = 0);
 	static int get_image_required_mipmaps(int p_width, int p_height, Format p_format);
 
-	bool operator==(const Image &p_image) const;
-
 	enum CompressMode {
 		COMPRESS_16BIT,
 		COMPRESS_S3TC,
@@ -254,9 +268,7 @@ public:
 	};
 
 	Error compress(CompressMode p_mode = COMPRESS_S3TC);
-	Image compressed(int p_mode); /* from the Image::CompressMode enum */
 	Error decompress();
-	Image decompressed() const;
 	bool is_compressed() const;
 
 	void fix_alpha_edges();
@@ -264,17 +276,34 @@ public:
 	void srgb_to_linear();
 	void normalmap_to_xy();
 
-	void blit_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
+	void blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
 
 	Rect2 get_used_rect() const;
-	Image get_rect(const Rect2 &p_area) const;
+	Ref<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_jpg, int p_len = -1);
 	Image(const char **p_xpm);
+
+	virtual Ref<Resource> duplicate(bool p_subresources = false) const;
+
+	void copy_internals_from(const Ref<Image> &p_image) {
+		ERR_FAIL_COND(p_image.is_null());
+		format = p_image->format;
+		width = p_image->width;
+		height = p_image->height;
+		mipmaps = p_image->mipmaps;
+		data = p_image->data;
+	}
+
 	~Image();
 };
 
+VARIANT_ENUM_CAST(Image::Format)
+VARIANT_ENUM_CAST(Image::Interpolation)
+VARIANT_ENUM_CAST(Image::CompressMode)
+VARIANT_ENUM_CAST(Image::AlphaMode)
+
 #endif

+ 2 - 1
core/io/image_loader.cpp

@@ -43,7 +43,8 @@ bool ImageFormatLoader::recognize(const String &p_extension) const {
 	return false;
 }
 
-Error ImageLoader::load_image(String p_file, Image *p_image, FileAccess *p_custom) {
+Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom) {
+	ERR_FAIL_COND_V(p_image.is_null(), ERR_INVALID_PARAMETER);
 
 	FileAccess *f = p_custom;
 	if (!f) {

+ 2 - 2
core/io/image_loader.h

@@ -56,7 +56,7 @@ class ImageFormatLoader {
 	friend class ImageLoader;
 
 protected:
-	virtual Error load_image(Image *p_image, FileAccess *p_fileaccess) = 0;
+	virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess) = 0;
 	virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
 	bool recognize(const String &p_extension) const;
 
@@ -75,7 +75,7 @@ class ImageLoader {
 
 protected:
 public:
-	static Error load_image(String p_file, Image *p_image, FileAccess *p_custom = NULL);
+	static Error load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom = NULL);
 	static void get_recognized_extensions(List<String> *p_extensions);
 	static bool recognize(const String &p_extension);
 

+ 0 - 56
core/io/marshalls.cpp

@@ -275,38 +275,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
 			if (r_len)
 				(*r_len) += 4 * 4;
 
-		} break;
-		case Variant::IMAGE: {
-
-			ERR_FAIL_COND_V(len < (int)5 * 4, ERR_INVALID_DATA);
-			Image::Format fmt = (Image::Format)decode_uint32(&buf[0]);
-			ERR_FAIL_INDEX_V(fmt, Image::FORMAT_MAX, ERR_INVALID_DATA);
-			uint32_t mipmaps = decode_uint32(&buf[4]);
-			uint32_t w = decode_uint32(&buf[8]);
-			uint32_t h = decode_uint32(&buf[12]);
-			uint32_t datalen = decode_uint32(&buf[16]);
-
-			Image img;
-			if (datalen > 0) {
-				len -= 5 * 4;
-				ERR_FAIL_COND_V(len < datalen, ERR_INVALID_DATA);
-				PoolVector<uint8_t> data;
-				data.resize(datalen);
-				PoolVector<uint8_t>::Write wr = data.write();
-				copymem(&wr[0], &buf[20], datalen);
-				wr = PoolVector<uint8_t>::Write();
-
-				img = Image(w, h, mipmaps, fmt, data);
-			}
-
-			r_variant = img;
-			if (r_len) {
-				if (datalen % 4)
-					(*r_len) += 4 - datalen % 4;
-
-				(*r_len) += 4 * 5 + datalen;
-			}
-
 		} break;
 		case Variant::NODE_PATH: {
 
@@ -1077,30 +1045,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
 
 			r_len += 4 * 4;
 
-		} break;
-		case Variant::IMAGE: {
-
-			Image image = p_variant;
-			PoolVector<uint8_t> data = image.get_data();
-
-			if (buf) {
-
-				encode_uint32(image.get_format(), &buf[0]);
-				encode_uint32(image.has_mipmaps(), &buf[4]);
-				encode_uint32(image.get_width(), &buf[8]);
-				encode_uint32(image.get_height(), &buf[12]);
-				int ds = data.size();
-				encode_uint32(ds, &buf[16]);
-				PoolVector<uint8_t>::Read r = data.read();
-				copymem(&buf[20], &r[0], ds);
-			}
-
-			int pad = 0;
-			if (data.size() % 4)
-				pad = 4 - data.size() % 4;
-
-			r_len += data.size() + 5 * 4 + pad;
-
 		} break;
 		/*case Variant::RESOURCE: {
 

+ 1 - 133
core/io/resource_format_binary.cpp

@@ -54,7 +54,7 @@ enum {
 	VARIANT_TRANSFORM = 17,
 	VARIANT_MATRIX32 = 18,
 	VARIANT_COLOR = 20,
-	VARIANT_IMAGE = 21,
+	//VARIANT_IMAGE = 21, - no longer variant type
 	VARIANT_NODE_PATH = 22,
 	VARIANT_RID = 23,
 	VARIANT_OBJECT = 24,
@@ -71,11 +71,6 @@ enum {
 	VARIANT_INT64 = 40,
 	VARIANT_DOUBLE = 41,
 
-	IMAGE_ENCODING_EMPTY = 0,
-	IMAGE_ENCODING_RAW = 1,
-	IMAGE_ENCODING_LOSSLESS = 2,
-	IMAGE_ENCODING_LOSSY = 3,
-
 	OBJECT_EMPTY = 0,
 	OBJECT_EXTERNAL_RESOURCE = 1,
 	OBJECT_INTERNAL_RESOURCE = 2,
@@ -259,74 +254,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
 			r_v = v;
 
 		} break;
-		case VARIANT_IMAGE: {
-
-			uint32_t encoding = f->get_32();
-			if (encoding == IMAGE_ENCODING_EMPTY) {
-				r_v = Variant();
-				break;
-			} else if (encoding == IMAGE_ENCODING_RAW) {
-				uint32_t width = f->get_32();
-				uint32_t height = f->get_32();
-				uint32_t mipmaps = f->get_32();
-				uint32_t format = f->get_32();
-				const uint32_t format_version_shift = 24;
-				const uint32_t format_version_mask = format_version_shift - 1;
-
-				uint32_t format_version = format >> format_version_shift;
-
-				const uint32_t current_version = 0;
-				if (format_version > current_version) {
-
-					ERR_PRINT("Format version for encoded binary image is too new");
-					return ERR_PARSE_ERROR;
-				}
-
-				Image::Format fmt = Image::Format(format & format_version_mask); //if format changes, we can add a compatibility bit on top
-
-				uint32_t datalen = f->get_32();
-				print_line("image format: " + String(Image::get_format_name(fmt)) + " datalen " + itos(datalen));
-
-				PoolVector<uint8_t> imgdata;
-				imgdata.resize(datalen);
-				PoolVector<uint8_t>::Write w = imgdata.write();
-				f->get_buffer(w.ptr(), datalen);
-				_advance_padding(datalen);
-				w = PoolVector<uint8_t>::Write();
-
-#ifdef TOOLS_ENABLED
-				//compatibility
-				int correct_size = Image::get_image_data_size(width, height, fmt, mipmaps ? -1 : 0);
-				if (correct_size < datalen) {
-					WARN_PRINT("Image data was too large, shrinking for compatibility")
-					imgdata.resize(correct_size);
-				}
-#endif
-				r_v = Image(width, height, mipmaps, fmt, imgdata);
-
-			} else {
-				//compressed
-				PoolVector<uint8_t> data;
-				data.resize(f->get_32());
-				PoolVector<uint8_t>::Write w = data.write();
-				f->get_buffer(w.ptr(), data.size());
-				w = PoolVector<uint8_t>::Write();
-
-				Image img;
-
-				if (encoding == IMAGE_ENCODING_LOSSY && Image::lossy_unpacker) {
-
-					img = Image::lossy_unpacker(data);
-				} else if (encoding == IMAGE_ENCODING_LOSSLESS && Image::lossless_unpacker) {
-
-					img = Image::lossless_unpacker(data);
-				}
-				_advance_padding(data.size());
-
-				r_v = img;
-			}
 
-		} break;
 		case VARIANT_NODE_PATH: {
 
 			Vector<StringName> names;
@@ -1469,67 +1397,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property,
 			f->store_real(val.a);
 
 		} break;
-		case Variant::IMAGE: {
-
-			f->store_32(VARIANT_IMAGE);
-			Image val = p_property;
-			if (val.empty()) {
-				f->store_32(IMAGE_ENCODING_EMPTY);
-				break;
-			}
-
-			int encoding = IMAGE_ENCODING_RAW;
-			float quality = 0.7;
-
-			if (!val.is_compressed()) {
-				//can only compress uncompressed stuff
-
-				if (p_hint.hint == PROPERTY_HINT_IMAGE_COMPRESS_LOSSY && Image::lossy_packer) {
-					encoding = IMAGE_ENCODING_LOSSY;
-					float qs = p_hint.hint_string.to_double();
-					if (qs != 0.0)
-						quality = qs;
-
-				} else if (p_hint.hint == PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS && Image::lossless_packer) {
-					encoding = IMAGE_ENCODING_LOSSLESS;
-				}
-			}
-
-			f->store_32(encoding); //raw encoding
-
-			if (encoding == IMAGE_ENCODING_RAW) {
-
-				f->store_32(val.get_width());
-				f->store_32(val.get_height());
-				f->store_32(val.has_mipmaps());
-				f->store_32(val.get_format()); //if format changes we can add a compatibility version bit
 
-				int dlen = val.get_data().size();
-				f->store_32(dlen);
-				PoolVector<uint8_t>::Read r = val.get_data().read();
-				f->store_buffer(r.ptr(), dlen);
-				_pad_buffer(dlen);
-			} else {
-
-				PoolVector<uint8_t> data;
-				if (encoding == IMAGE_ENCODING_LOSSY) {
-					data = Image::lossy_packer(val, quality);
-
-				} else if (encoding == IMAGE_ENCODING_LOSSLESS) {
-					data = Image::lossless_packer(val);
-				}
-
-				int ds = data.size();
-				f->store_32(ds);
-				if (ds > 0) {
-					PoolVector<uint8_t>::Read r = data.read();
-					f->store_buffer(r.ptr(), ds);
-
-					_pad_buffer(ds);
-				}
-			}
-
-		} break;
 		case Variant::NODE_PATH: {
 			f->store_32(VARIANT_NODE_PATH);
 			NodePath np = p_property;

+ 1 - 1
core/method_bind.h

@@ -146,7 +146,7 @@ struct VariantCaster<const T &> {
 // some helpers
 
 VARIANT_ENUM_CAST(Vector3::Axis);
-VARIANT_ENUM_CAST(Image::Format);
+
 VARIANT_ENUM_CAST(Error);
 VARIANT_ENUM_CAST(wchar_t);
 VARIANT_ENUM_CAST(Margin);

+ 0 - 1
core/method_ptrcall.h

@@ -103,7 +103,6 @@ MAKE_PTRARG(Rect3);
 MAKE_PTRARG(Basis);
 MAKE_PTRARG(Transform);
 MAKE_PTRARG(Color);
-MAKE_PTRARG(Image);
 MAKE_PTRARG(NodePath);
 MAKE_PTRARG(RID);
 MAKE_PTRARG(InputEvent);

+ 1 - 1
core/os/os.cpp

@@ -389,7 +389,7 @@ void OS::_ensure_data_dir() {
 	memdelete(da);
 }
 
-void OS::set_icon(const Image &p_icon) {
+void OS::set_icon(const Ref<Image> &p_icon) {
 }
 
 String OS::get_model_name() const {

+ 2 - 1
core/os/os.h

@@ -31,6 +31,7 @@
 #define OS_H
 
 #include "engine.h"
+#include "image.h"
 #include "list.h"
 #include "os/main_loop.h"
 #include "power.h"
@@ -357,7 +358,7 @@ public:
 	virtual void make_rendering_thread();
 	virtual void swap_buffers();
 
-	virtual void set_icon(const Image &p_icon);
+	virtual void set_icon(const Ref<Image> &p_icon);
 
 	virtual int get_exit_code() const;
 	virtual void set_exit_code(int p_code);

+ 0 - 1
core/packed_data_container.cpp

@@ -237,7 +237,6 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
 		case Variant::RECT3:
 		case Variant::BASIS:
 		case Variant::TRANSFORM:
-		case Variant::IMAGE:
 		case Variant::INPUT_EVENT:
 		case Variant::POOL_BYTE_ARRAY:
 		case Variant::POOL_INT_ARRAY:

+ 2 - 0
core/register_core_types.cpp

@@ -108,6 +108,8 @@ void register_core_types() {
 	ClassDB::register_class<Reference>();
 	ClassDB::register_class<WeakRef>();
 	ClassDB::register_class<Resource>();
+	ClassDB::register_class<Image>();
+
 	ClassDB::register_class<FuncRef>();
 	ClassDB::register_virtual_class<StreamPeer>();
 	ClassDB::register_class<StreamPeerBuffer>();

+ 1 - 1
core/resource.cpp

@@ -185,7 +185,7 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Res
 	return Ref<Resource>(r);
 }
 
-Ref<Resource> Resource::duplicate(bool p_subresources) {
+Ref<Resource> Resource::duplicate(bool p_subresources) const {
 
 	List<PropertyInfo> plist;
 	get_property_list(&plist);

+ 1 - 1
core/resource.h

@@ -103,7 +103,7 @@ public:
 	void set_subindex(int p_sub_index);
 	int get_subindex() const;
 
-	Ref<Resource> duplicate(bool p_subresources = false);
+	virtual Ref<Resource> duplicate(bool p_subresources = false) const;
 	Ref<Resource> duplicate_for_local_scene(Node *p_scene, Map<Ref<Resource>, Ref<Resource> > &remap_cache);
 
 	void set_local_to_scene(bool p_enable);

+ 1 - 3
core/script_debugger_remote.cpp

@@ -586,9 +586,7 @@ void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {
 				packet_peer_stream->put_var(E->get().hint);
 				packet_peer_stream->put_var(E->get().hint_string);
 				//only send information that can be sent..
-				if (var.get_type() == Variant::IMAGE) {
-					var = Image();
-				}
+
 				if (var.get_type() >= Variant::DICTIONARY) {
 					var = Array(); //send none for now, may be to big
 				}

+ 0 - 38
core/variant.cpp

@@ -119,11 +119,6 @@ String Variant::get_type_name(Variant::Type p_type) {
 
 			return "Color";
 
-		} break;
-		case IMAGE: {
-
-			return "Image";
-
 		} break;
 		case _RID: {
 
@@ -249,7 +244,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
 
 			static const Type invalid[] = {
 				OBJECT,
-				IMAGE,
 				NIL
 			};
 
@@ -790,11 +784,6 @@ bool Variant::is_zero() const {
 
 			return *reinterpret_cast<const Color *>(_data._mem) == Color();
 
-		} break;
-		case IMAGE: {
-
-			return _data._image->empty();
-
 		} break;
 		case _RID: {
 
@@ -1015,11 +1004,6 @@ void Variant::reference(const Variant &p_variant) {
 
 			memnew_placement(_data._mem, Color(*reinterpret_cast<const Color *>(p_variant._data._mem)));
 
-		} break;
-		case IMAGE: {
-
-			_data._image = memnew(Image(*p_variant._data._image));
-
 		} break;
 		case _RID: {
 
@@ -1141,11 +1125,6 @@ void Variant::clear() {
 		} break;
 
 		// misc types
-		case IMAGE: {
-
-			memdelete(_data._image);
-
-		} break;
 		case NODE_PATH: {
 
 			reinterpret_cast<NodePath *>(_data._mem)->~NodePath();
@@ -1760,13 +1739,6 @@ Variant::operator Color() const {
 	else
 		return Color();
 }
-Variant::operator Image() const {
-
-	if (type == IMAGE)
-		return *_data._image;
-	else
-		return Image();
-}
 
 Variant::operator NodePath() const {
 
@@ -2306,11 +2278,6 @@ Variant::Variant(const Color &p_color) {
 	type = COLOR;
 	memnew_placement(_data._mem, Color(p_color));
 }
-Variant::Variant(const Image &p_image) {
-
-	type = IMAGE;
-	_data._image = memnew(Image(p_image));
-}
 
 Variant::Variant(const NodePath &p_node_path) {
 
@@ -2710,11 +2677,6 @@ uint32_t Variant::hash() const {
 			hash = hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->b, hash);
 			return hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->a, hash);
 
-		} break;
-		case IMAGE: {
-
-			return 0;
-
 		} break;
 		case _RID: {
 

+ 4 - 9
core/variant.h

@@ -39,7 +39,6 @@
 #include "dictionary.h"
 #include "dvector.h"
 #include "face3.h"
-#include "image.h"
 #include "io/ip_address.h"
 #include "math_2d.h"
 #include "matrix3.h"
@@ -98,20 +97,19 @@ public:
 
 		// misc types
 		COLOR,
-		IMAGE, // 15
 		NODE_PATH,
 		_RID,
 		OBJECT,
 		INPUT_EVENT,
-		DICTIONARY, // 20
-		ARRAY,
+		DICTIONARY,
+		ARRAY, // 20
 
 		// arrays
 		POOL_BYTE_ARRAY,
 		POOL_INT_ARRAY,
 		POOL_REAL_ARRAY,
-		POOL_STRING_ARRAY, // 25
-		POOL_VECTOR2_ARRAY,
+		POOL_STRING_ARRAY,
+		POOL_VECTOR2_ARRAY, // 25
 		POOL_VECTOR3_ARRAY,
 		POOL_COLOR_ARRAY,
 
@@ -146,7 +144,6 @@ private:
 		Transform *_transform;
 		RefPtr *_resource;
 		InputEvent *_input_event;
-		Image *_image;
 		void *_ptr; //generic pointer
 		uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)];
 	} _data;
@@ -207,7 +204,6 @@ public:
 	operator Transform2D() const;
 
 	operator Color() const;
-	operator Image() const;
 	operator NodePath() const;
 	operator RefPtr() const;
 	operator RID() const;
@@ -276,7 +272,6 @@ public:
 	Variant(const Transform2D &p_transform);
 	Variant(const Transform &p_transform);
 	Variant(const Color &p_color);
-	Variant(const Image &p_image);
 	Variant(const NodePath &p_path);
 	Variant(const RefPtr &p_resource);
 	Variant(const RID &p_rid);

+ 0 - 94
core/variant_call.cpp

@@ -37,9 +37,6 @@
 typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_args);
 typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args);
 
-VARIANT_ENUM_CAST(Image::CompressMode);
-//VARIANT_ENUM_CAST(Image::Format);
-
 struct _VariantCall {
 
 	static void Vector3_dot(Variant &r_ret, Variant &p_self, const Variant **p_args) {
@@ -614,22 +611,6 @@ struct _VariantCall {
 #define VCALL_PTR5R(m_type, m_method) \
 	static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { r_ret = reinterpret_cast<m_type *>(p_self._data._ptr)->m_method(*p_args[0], *p_args[1], *p_args[2], *p_args[3], *p_args[4]); }
 
-	VCALL_PTR0R(Image, get_format);
-	VCALL_PTR0R(Image, get_width);
-	VCALL_PTR0R(Image, get_height);
-	VCALL_PTR0R(Image, empty);
-	VCALL_PTR0R(Image, get_used_rect);
-	VCALL_PTR1R(Image, load);
-	VCALL_PTR1R(Image, save_png);
-	VCALL_PTR1R(Image, get_rect);
-	VCALL_PTR1R(Image, compressed);
-	VCALL_PTR0R(Image, decompressed);
-	VCALL_PTR3R(Image, resized);
-	VCALL_PTR0R(Image, get_data);
-	VCALL_PTR3(Image, blit_rect);
-	VCALL_PTR1R(Image, converted);
-	VCALL_PTR0(Image, fix_alpha_edges);
-
 	VCALL_PTR0R(Rect3, get_area);
 	VCALL_PTR0R(Rect3, has_no_area);
 	VCALL_PTR0R(Rect3, has_no_surface);
@@ -901,11 +882,6 @@ struct _VariantCall {
 		r_ret = Transform(p_args[0]->operator Basis(), p_args[1]->operator Vector3());
 	}
 
-	static void Image_init1(Variant &r_ret, const Variant **p_args) {
-
-		r_ret = Image(*p_args[0], *p_args[1], *p_args[2], Image::Format(p_args[3]->operator int()));
-	}
-
 	static void add_constructor(VariantConstructFunc p_func, const Variant::Type p_type,
 			const String &p_name1 = "", const Variant::Type p_type1 = Variant::NIL,
 			const String &p_name2 = "", const Variant::Type p_type2 = Variant::NIL,
@@ -1056,7 +1032,6 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
 
 			// misc types
 			case COLOR: return Color();
-			case IMAGE: return Image();
 			case NODE_PATH:
 				return NodePath(); // 15
 			case _RID: return RID();
@@ -1138,7 +1113,6 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
 
 			// misc types
 			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 NODE_PATH:
 				return (NodePath(p_args[0]->operator NodePath())); // 15
 			case _RID: return (RID(*p_args[0]));
@@ -1527,22 +1501,6 @@ void register_variant_methods() {
 	ADDFUNC1(COLOR, COLOR, Color, blend, COLOR, "over", varray());
 	ADDFUNC1(COLOR, STRING, Color, to_html, BOOL, "with_alpha", varray(true));
 
-	ADDFUNC0(IMAGE, INT, Image, get_format, varray());
-	ADDFUNC0(IMAGE, INT, Image, get_width, varray());
-	ADDFUNC0(IMAGE, INT, Image, get_height, varray());
-	ADDFUNC0(IMAGE, BOOL, Image, empty, varray());
-	ADDFUNC1(IMAGE, INT, Image, load, STRING, "path", varray(0));
-	ADDFUNC1(IMAGE, INT, Image, save_png, STRING, "path", varray(0));
-	ADDFUNC0(IMAGE, RECT2, Image, get_used_rect, varray(0));
-	ADDFUNC1(IMAGE, IMAGE, Image, get_rect, RECT2, "area", varray(0));
-	ADDFUNC1(IMAGE, IMAGE, Image, compressed, INT, "format", varray(0));
-	ADDFUNC0(IMAGE, IMAGE, Image, decompressed, varray(0));
-	ADDFUNC3(IMAGE, IMAGE, Image, resized, INT, "x", INT, "y", INT, "interpolation", varray(((int)Image::INTERPOLATE_BILINEAR)));
-	ADDFUNC0(IMAGE, POOL_BYTE_ARRAY, Image, get_data, varray());
-	ADDFUNC3(IMAGE, NIL, Image, blit_rect, IMAGE, "src", RECT2, "src_rect", VECTOR2, "dest", varray(0));
-	ADDFUNC1(IMAGE, IMAGE, Image, converted, INT, "format", varray(0));
-	ADDFUNC0(IMAGE, NIL, Image, fix_alpha_edges, varray());
-
 	ADDFUNC0(_RID, INT, RID, get_id, varray());
 
 	ADDFUNC0(NODE_PATH, BOOL, NodePath, is_absolute, varray());
@@ -1771,8 +1729,6 @@ void register_variant_methods() {
 	_VariantCall::add_constructor(_VariantCall::Transform_init1, Variant::TRANSFORM, "x_axis", Variant::VECTOR3, "y_axis", Variant::VECTOR3, "z_axis", Variant::VECTOR3, "origin", Variant::VECTOR3);
 	_VariantCall::add_constructor(_VariantCall::Transform_init2, Variant::TRANSFORM, "basis", Variant::BASIS, "origin", Variant::VECTOR3);
 
-	_VariantCall::add_constructor(_VariantCall::Image_init1, Variant::IMAGE, "width", Variant::INT, "height", Variant::INT, "mipmaps", Variant::BOOL, "format", Variant::INT);
-
 	/* REGISTER CONSTANTS */
 
 	_VariantCall::add_constant(Variant::VECTOR3, "AXIS_X", Vector3::AXIS_X);
@@ -1788,56 +1744,6 @@ void register_variant_methods() {
 	_VariantCall::add_constant(Variant::INPUT_EVENT, "SCREEN_TOUCH", InputEvent::SCREEN_TOUCH);
 	_VariantCall::add_constant(Variant::INPUT_EVENT, "SCREEN_DRAG", InputEvent::SCREEN_DRAG);
 	_VariantCall::add_constant(Variant::INPUT_EVENT, "ACTION", InputEvent::ACTION);
-
-	_VariantCall::add_constant(Variant::IMAGE, "COMPRESS_16BIT", Image::COMPRESS_16BIT);
-	_VariantCall::add_constant(Variant::IMAGE, "COMPRESS_S3TC", Image::COMPRESS_S3TC);
-	_VariantCall::add_constant(Variant::IMAGE, "COMPRESS_PVRTC2", Image::COMPRESS_PVRTC2);
-	_VariantCall::add_constant(Variant::IMAGE, "COMPRESS_PVRTC4", Image::COMPRESS_PVRTC4);
-	_VariantCall::add_constant(Variant::IMAGE, "COMPRESS_ETC", Image::COMPRESS_ETC);
-	_VariantCall::add_constant(Variant::IMAGE, "COMPRESS_ETC2", Image::COMPRESS_ETC2);
-
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_L8", Image::FORMAT_L8);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_LA8", Image::FORMAT_LA8);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_R8", Image::FORMAT_R8);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_RG8", Image::FORMAT_RG8);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGB8", Image::FORMAT_RGB8);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGBA8", Image::FORMAT_RGBA8);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGB565", Image::FORMAT_RGB565);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGBA4444", Image::FORMAT_RGBA4444);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGBA5551", Image::FORMAT_DXT1);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_RF", Image::FORMAT_RF);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGF", Image::FORMAT_RGF);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGBF", Image::FORMAT_RGBF);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGBAF", Image::FORMAT_RGBAF);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_RH", Image::FORMAT_RH);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGH", Image::FORMAT_RGH);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGBH", Image::FORMAT_RGBH);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGBAH", Image::FORMAT_RGBAH);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_DXT1", Image::FORMAT_DXT1);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_DXT3", Image::FORMAT_DXT3);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_DXT5", Image::FORMAT_DXT5);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_ATI1", Image::FORMAT_ATI1);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_ATI2", Image::FORMAT_ATI2);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_BPTC_RGBA", Image::FORMAT_BPTC_RGBA);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_BPTC_RGBF", Image::FORMAT_BPTC_RGBF);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_BPTC_RGBFU", Image::FORMAT_BPTC_RGBFU);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_PVRTC2", Image::FORMAT_PVRTC2);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_PVRTC2A", Image::FORMAT_PVRTC2A);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_PVRTC4", Image::FORMAT_PVRTC4);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_PVRTC4A", Image::FORMAT_PVRTC4A);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC", Image::FORMAT_ETC);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC2_R11", Image::FORMAT_ETC2_R11);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC2_R11S", Image::FORMAT_ETC2_R11S);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC2_RG11", Image::FORMAT_ETC2_RG11);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC2_RG11S", Image::FORMAT_ETC2_RG11S);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC2_RGB8", Image::FORMAT_ETC2_RGB8);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC2_RGBA8", Image::FORMAT_ETC2_RGBA8);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC2_RGB8A1", Image::FORMAT_ETC2_RGB8A1);
-	_VariantCall::add_constant(Variant::IMAGE, "FORMAT_MAX", Image::FORMAT_MAX);
-
-	_VariantCall::add_constant(Variant::IMAGE, "INTERPOLATE_NEAREST", Image::INTERPOLATE_NEAREST);
-	_VariantCall::add_constant(Variant::IMAGE, "INTERPOLATE_BILINEAR", Image::INTERPOLATE_BILINEAR);
-	_VariantCall::add_constant(Variant::IMAGE, "INTERPOLATE_CUBIC", Image::INTERPOLATE_CUBIC);
 }
 
 void unregister_variant_methods() {

+ 8 - 20
core/variant_op.cpp

@@ -58,7 +58,6 @@ bool Variant::booleanize(bool &r_valid) const {
 		case BASIS:
 		case TRANSFORM:
 		case COLOR:
-		case IMAGE: r_valid = false; return false;
 		case _RID: return (*reinterpret_cast<const RID *>(_data._mem)).is_valid();
 		case OBJECT: return _get_obj().obj;
 		case NODE_PATH: return (*reinterpret_cast<const NodePath *>(_data._mem)) != NodePath();
@@ -283,7 +282,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
 					DEFAULT_OP_PTRREF(==, TRANSFORM, _transform);
 
 					DEFAULT_OP_LOCALMEM(==, COLOR, Color);
-					DEFAULT_OP_PTRREF(==, IMAGE, _image);
 					DEFAULT_OP_STR(==, NODE_PATH, NodePath);
 					DEFAULT_OP_LOCALMEM(==, _RID, RID);
 				case OBJECT: {
@@ -372,7 +370,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
 				DEFAULT_OP_FAIL(TRANSFORM);
 
 				DEFAULT_OP_FAIL(COLOR);
-				DEFAULT_OP_FAIL(IMAGE);
+
 				DEFAULT_OP_FAIL(NODE_PATH);
 				DEFAULT_OP_LOCALMEM(<, _RID, RID);
 				case OBJECT: {
@@ -437,7 +435,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
 				DEFAULT_OP_FAIL(TRANSFORM);
 
 				DEFAULT_OP_FAIL(COLOR);
-				DEFAULT_OP_FAIL(IMAGE);
+
 				DEFAULT_OP_FAIL(NODE_PATH);
 				DEFAULT_OP_LOCALMEM(<=, _RID, RID);
 				case OBJECT: {
@@ -500,7 +498,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
 				DEFAULT_OP_FAIL(TRANSFORM);
 
 				DEFAULT_OP_FAIL(COLOR);
-				DEFAULT_OP_FAIL(IMAGE);
+
 				DEFAULT_OP_FAIL(NODE_PATH);
 				DEFAULT_OP_FAIL(_RID);
 				DEFAULT_OP_FAIL(OBJECT);
@@ -557,7 +555,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
 				DEFAULT_OP_FAIL(TRANSFORM);
 
 				DEFAULT_OP_FAIL(COLOR);
-				DEFAULT_OP_FAIL(IMAGE);
+
 				DEFAULT_OP_FAIL(NODE_PATH);
 				DEFAULT_OP_FAIL(_RID);
 				DEFAULT_OP_FAIL(OBJECT);
@@ -654,7 +652,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
 					return;
 				} break;
 					DEFAULT_OP_FAIL(COLOR);
-					DEFAULT_OP_FAIL(IMAGE);
+
 					DEFAULT_OP_FAIL(NODE_PATH);
 					DEFAULT_OP_FAIL(_RID);
 					DEFAULT_OP_FAIL(OBJECT);
@@ -727,7 +725,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
 					DEFAULT_OP_FAIL(TRANSFORM);
 
 					DEFAULT_OP_FAIL(COLOR);
-					DEFAULT_OP_FAIL(IMAGE);
+
 					DEFAULT_OP_FAIL(NODE_PATH);
 					DEFAULT_OP_FAIL(_RID);
 					DEFAULT_OP_FAIL(OBJECT);
@@ -769,7 +767,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
 				DEFAULT_OP_LOCALMEM_POS(VECTOR2, Vector2);
 
 				DEFAULT_OP_FAIL(COLOR);
-				DEFAULT_OP_FAIL(IMAGE);
+
 				DEFAULT_OP_FAIL(NODE_PATH);
 				DEFAULT_OP_FAIL(_RID);
 				DEFAULT_OP_FAIL(OBJECT);
@@ -809,7 +807,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
 				DEFAULT_OP_FAIL(TRANSFORM);
 
 				DEFAULT_OP_FAIL(COLOR);
-				DEFAULT_OP_FAIL(IMAGE);
+
 				DEFAULT_OP_FAIL(NODE_PATH);
 				DEFAULT_OP_FAIL(_RID);
 				DEFAULT_OP_FAIL(OBJECT);
@@ -1479,8 +1477,6 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
 				}
 			}
 
-		} break;
-		case IMAGE: {
 		} break;
 		case NODE_PATH: {
 		} break; // 15
@@ -2238,8 +2234,6 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
 				}
 			}
 
-		} break;
-		case IMAGE: {
 		} break;
 		case NODE_PATH: {
 		} break; // 15
@@ -2806,8 +2800,6 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
 			p_list->push_back(PropertyInfo(Variant::INT, "b8"));
 			p_list->push_back(PropertyInfo(Variant::INT, "a8"));
 
-		} break;
-		case IMAGE: {
 		} break;
 		case NODE_PATH: {
 		} break; // 15
@@ -3631,10 +3623,6 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
 			r_dst = reinterpret_cast<const Color *>(a._data._mem)->linear_interpolate(*reinterpret_cast<const Color *>(b._data._mem), c);
 		}
 			return;
-		case IMAGE: {
-			r_dst = a;
-		}
-			return;
 		case NODE_PATH: {
 			r_dst = a;
 		}

+ 0 - 175
core/variant_parser.cpp

@@ -681,126 +681,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
 			value = Color(args[0], args[1], args[2], args[3]);
 			return OK;
 
-		} else if (id == "Image") {
-
-			//:|
-
-			get_token(p_stream, token, line, r_err_str);
-			if (token.type != TK_PARENTHESIS_OPEN) {
-				r_err_str = "Expected '('";
-				return ERR_PARSE_ERROR;
-			}
-
-			get_token(p_stream, token, line, r_err_str);
-			if (token.type == TK_PARENTHESIS_CLOSE) {
-				value = Image(); // just an Image()
-				return OK;
-			} else if (token.type != TK_NUMBER) {
-				r_err_str = "Expected number (width)";
-				return ERR_PARSE_ERROR;
-			}
-
-			get_token(p_stream, token, line, r_err_str);
-
-			int width = token.value;
-			if (token.type != TK_COMMA) {
-				r_err_str = "Expected ','";
-				return ERR_PARSE_ERROR;
-			}
-
-			get_token(p_stream, token, line, r_err_str);
-			if (token.type != TK_NUMBER) {
-				r_err_str = "Expected number (height)";
-				return ERR_PARSE_ERROR;
-			}
-
-			int height = token.value;
-
-			get_token(p_stream, token, line, r_err_str);
-			if (token.type != TK_COMMA) {
-				r_err_str = "Expected ','";
-				return ERR_PARSE_ERROR;
-			}
-
-			get_token(p_stream, token, line, r_err_str);
-
-			bool has_mipmaps = false;
-
-			if (token.type == TK_NUMBER) {
-				has_mipmaps = bool(token.value);
-			} else if (token.type == TK_IDENTIFIER && String(token.value) == "true") {
-				has_mipmaps = true;
-			} else if (token.type == TK_IDENTIFIER && String(token.value) == "false") {
-				has_mipmaps = false;
-			} else {
-				r_err_str = "Expected number/true/false (mipmaps)";
-				return ERR_PARSE_ERROR;
-			}
-
-			int mipmaps = token.value;
-
-			get_token(p_stream, token, line, r_err_str);
-			if (token.type != TK_COMMA) {
-				r_err_str = "Expected ','";
-				return ERR_PARSE_ERROR;
-			}
-
-			get_token(p_stream, token, line, r_err_str);
-			if (token.type != TK_IDENTIFIER) {
-				r_err_str = "Expected identifier (format)";
-				return ERR_PARSE_ERROR;
-			}
-
-			String sformat = token.value;
-
-			Image::Format format = Image::FORMAT_MAX;
-
-			for (int i = 0; i < Image::FORMAT_MAX; i++) {
-				if (Image::get_format_name(Image::Format(i)) == sformat) {
-					format = Image::Format(i);
-				}
-			}
-
-			if (format == Image::FORMAT_MAX) {
-				r_err_str = "Unknown image format: " + String(sformat);
-				return ERR_PARSE_ERROR;
-			}
-
-			int len = Image::get_image_data_size(width, height, format, mipmaps);
-
-			PoolVector<uint8_t> buffer;
-			buffer.resize(len);
-
-			if (buffer.size() != len) {
-				r_err_str = "Couldn't allocate image buffer of size: " + itos(len);
-			}
-
-			{
-				PoolVector<uint8_t>::Write w = buffer.write();
-
-				for (int i = 0; i < len; i++) {
-					get_token(p_stream, token, line, r_err_str);
-					if (token.type != TK_COMMA) {
-						r_err_str = "Expected ','";
-						return ERR_PARSE_ERROR;
-					}
-
-					get_token(p_stream, token, line, r_err_str);
-					if (token.type != TK_NUMBER) {
-						r_err_str = "Expected number";
-						return ERR_PARSE_ERROR;
-					}
-
-					w[i] = int(token.value);
-				}
-			}
-
-			Image img(width, height, mipmaps, format, buffer);
-
-			value = img;
-
-			return OK;
-
 		} else if (id == "NodePath") {
 
 			get_token(p_stream, token, line, r_err_str);
@@ -1356,28 +1236,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
 
 			value = ie;
 
-			return OK;
-		} else if (id == "img") { // compatibility with project.godot
-
-			Token token; // FIXME: no need for this declaration? the first argument in line 509 is a Token& token.
-			get_token(p_stream, token, line, r_err_str);
-			if (token.type != TK_PARENTHESIS_OPEN) {
-				r_err_str = "Expected '(' in old-style project.godot construct";
-				return ERR_PARSE_ERROR;
-			}
-
-			while (true) {
-				CharType c = p_stream->get_char();
-				if (p_stream->is_eof()) {
-					r_err_str = "Unexpected EOF in old style project.godot img()";
-					return ERR_PARSE_ERROR;
-				}
-				if (c == ')')
-					break;
-			}
-
-			value = Image();
-
 			return OK;
 
 		} else {
@@ -1886,39 +1744,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
 			p_store_string_func(p_store_string_ud, "Color( " + rtosfix(c.r) + ", " + rtosfix(c.g) + ", " + rtosfix(c.b) + ", " + rtosfix(c.a) + " )");
 
 		} break;
-		case Variant::IMAGE: {
-
-			Image img = p_variant;
-
-			if (img.empty()) {
-				p_store_string_func(p_store_string_ud, "Image()");
-				break;
-			}
-
-			String imgstr = "Image( ";
-			imgstr += itos(img.get_width());
-			imgstr += ", " + itos(img.get_height());
-			imgstr += ", " + String(img.has_mipmaps() ? "true" : "false");
-			imgstr += ", " + Image::get_format_name(img.get_format());
-
-			String s;
-
-			PoolVector<uint8_t> data = img.get_data();
-			int len = data.size();
-			PoolVector<uint8_t>::Read r = data.read();
-			const uint8_t *ptr = r.ptr();
-			for (int i = 0; i < len; i++) {
-
-				if (i > 0)
-					s += ", ";
-				s += itos(ptr[i]);
-			}
-
-			imgstr += ", ";
-			p_store_string_func(p_store_string_ud, imgstr);
-			p_store_string_func(p_store_string_ud, s);
-			p_store_string_func(p_store_string_ud, " )");
-		} break;
 		case Variant::NODE_PATH: {
 
 			String str = p_variant;

+ 2 - 2
drivers/gles2/rasterizer_gles2.cpp

@@ -342,12 +342,12 @@ void RasterizerGLES2::_draw_primitive(int p_points, const Vector3 *p_vertices, c
 
 /* TEXTURE API */
 
-Image RasterizerGLES2::_get_gl_image_and_format(const Image &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, int &r_gl_components, bool &r_has_alpha_cache, bool &r_compressed) {
+Ref<Image> RasterizerGLES2::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, int &r_gl_components, bool &r_has_alpha_cache, bool &r_compressed) {
 
 	r_has_alpha_cache = false;
 	r_compressed = false;
 	r_gl_format = 0;
-	Image image = p_image;
+	Ref<Image> image = p_image;
 
 	switch (p_format) {
 

+ 4 - 4
drivers/gles3/rasterizer_gles3.cpp

@@ -271,9 +271,9 @@ void RasterizerGLES3::clear_render_target(const Color &p_color) {
 	storage->frame.clear_request_color = p_color;
 }
 
-void RasterizerGLES3::set_boot_image(const Image &p_image, const Color &p_color, bool p_scale) {
+void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale) {
 
-	if (p_image.empty())
+	if (p_image.is_null() || p_image->empty())
 		return;
 
 	begin_frame();
@@ -290,10 +290,10 @@ void RasterizerGLES3::set_boot_image(const Image &p_image, const Color &p_color,
 	canvas->canvas_begin();
 
 	RID texture = storage->texture_create();
-	storage->texture_allocate(texture, p_image.get_width(), p_image.get_height(), p_image.get_format(), VS::TEXTURE_FLAG_FILTER);
+	storage->texture_allocate(texture, p_image->get_width(), p_image->get_height(), p_image->get_format(), VS::TEXTURE_FLAG_FILTER);
 	storage->texture_set_data(texture, p_image);
 
-	Rect2 imgrect(0, 0, p_image.get_width(), p_image.get_height());
+	Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height());
 	Rect2 screenrect;
 	if (p_scale) {
 

+ 1 - 1
drivers/gles3/rasterizer_gles3.h

@@ -48,7 +48,7 @@ public:
 	virtual RasterizerCanvas *get_canvas();
 	virtual RasterizerScene *get_scene();
 
-	virtual void set_boot_image(const Image &p_image, const Color &p_color, bool p_scale);
+	virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale);
 
 	virtual void initialize();
 	virtual void begin_frame();

+ 34 - 33
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -101,11 +101,11 @@
 
 GLuint RasterizerStorageGLES3::system_fbo = 0;
 
-Image RasterizerStorageGLES3::_get_gl_image_and_format(const Image &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool &srgb) {
+Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool &srgb) {
 
 	r_compressed = false;
 	r_gl_format = 0;
-	Image image = p_image;
+	Ref<Image> image = p_image;
 	srgb = false;
 
 	bool need_decompress = false;
@@ -538,16 +538,17 @@ Image RasterizerStorageGLES3::_get_gl_image_and_format(const Image &p_image, Ima
 		} break;
 		default: {
 
-			ERR_FAIL_V(Image());
+			ERR_FAIL_V(Ref<Image>());
 		}
 	}
 
 	if (need_decompress) {
 
-		if (!image.empty()) {
-			image.decompress();
-			ERR_FAIL_COND_V(image.is_compressed(), image);
-			image.convert(Image::FORMAT_RGBA8);
+		if (!image.is_null()) {
+			image = image->duplicate();
+			image->decompress();
+			ERR_FAIL_COND_V(image->is_compressed(), image);
+			image->convert(Image::FORMAT_RGBA8);
 		}
 
 		r_gl_format = GL_RGBA;
@@ -607,7 +608,7 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_
 	texture->stored_cube_sides = 0;
 	texture->target = (p_flags & VS::TEXTURE_FLAG_CUBEMAP) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
 
-	_get_gl_image_and_format(Image(), texture->format, texture->flags, format, internal_format, type, compressed, srgb);
+	_get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, format, internal_format, type, compressed, srgb);
 
 	texture->alloc_width = texture->width;
 	texture->alloc_height = texture->height;
@@ -631,15 +632,15 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_
 	texture->active = true;
 }
 
-void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Image &p_image, VS::CubeMapSide p_cube_side) {
+void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side) {
 
 	Texture *texture = texture_owner.get(p_texture);
 
 	ERR_FAIL_COND(!texture);
 	ERR_FAIL_COND(!texture->active);
 	ERR_FAIL_COND(texture->render_target);
-	ERR_FAIL_COND(texture->format != p_image.get_format());
-	ERR_FAIL_COND(p_image.empty());
+	ERR_FAIL_COND(texture->format != p_image->get_format());
+	ERR_FAIL_COND(p_image.is_null());
 
 	GLenum type;
 	GLenum format;
@@ -651,31 +652,31 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Image &p_imag
 		texture->images[p_cube_side] = p_image;
 	}
 
-	Image img = _get_gl_image_and_format(p_image, p_image.get_format(), texture->flags, format, internal_format, type, compressed, srgb);
+	Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, format, internal_format, type, compressed, srgb);
 
-	if (config.shrink_textures_x2 && (p_image.has_mipmaps() || !p_image.is_compressed()) && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) {
+	if (config.shrink_textures_x2 && (p_image->has_mipmaps() || !p_image->is_compressed()) && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) {
 
 		texture->alloc_height = MAX(1, texture->alloc_height / 2);
 		texture->alloc_width = MAX(1, texture->alloc_width / 2);
 
-		if (texture->alloc_width == img.get_width() / 2 && texture->alloc_height == img.get_height() / 2) {
+		if (texture->alloc_width == img->get_width() / 2 && texture->alloc_height == img->get_height() / 2) {
 
-			img.shrink_x2();
-		} else if (img.get_format() <= Image::FORMAT_RGB565) {
+			img->shrink_x2();
+		} else if (img->get_format() <= Image::FORMAT_RGB565) {
 
-			img.resize(texture->alloc_width, texture->alloc_height, Image::INTERPOLATE_BILINEAR);
+			img->resize(texture->alloc_width, texture->alloc_height, Image::INTERPOLATE_BILINEAR);
 		}
 	};
 
 	GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_cube_side] : GL_TEXTURE_2D;
 
-	texture->data_size = img.get_data().size();
-	PoolVector<uint8_t>::Read read = img.get_data().read();
+	texture->data_size = img->get_data().size();
+	PoolVector<uint8_t>::Read read = img->get_data().read();
 
 	glActiveTexture(GL_TEXTURE0);
 	glBindTexture(texture->target, texture->tex_id);
 
-	texture->ignore_mipmaps = compressed && !img.has_mipmaps();
+	texture->ignore_mipmaps = compressed && !img->has_mipmaps();
 
 	if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps)
 		glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, config.use_fast_texture_filter ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR_MIPMAP_LINEAR);
@@ -761,16 +762,16 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Image &p_imag
 		}
 	}
 
-	int mipmaps = (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && img.has_mipmaps()) ? img.get_mipmap_count() + 1 : 1;
+	int mipmaps = (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && img->has_mipmaps()) ? img->get_mipmap_count() + 1 : 1;
 
-	int w = img.get_width();
-	int h = img.get_height();
+	int w = img->get_width();
+	int h = img->get_height();
 
 	int tsize = 0;
 	for (int i = 0; i < mipmaps; i++) {
 
 		int size, ofs;
-		img.get_mipmap_offset_and_size(i, ofs, size);
+		img->get_mipmap_offset_and_size(i, ofs, size);
 
 		//print_line("mipmap: "+itos(i)+" size: "+itos(size)+" w: "+itos(mm_w)+", h: "+itos(mm_h));
 
@@ -813,16 +814,16 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Image &p_imag
 	//texture_set_flags(p_texture,texture->flags);
 }
 
-Image RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side) const {
+Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side) const {
 
 	Texture *texture = texture_owner.get(p_texture);
 
-	ERR_FAIL_COND_V(!texture, Image());
-	ERR_FAIL_COND_V(!texture->active, Image());
-	ERR_FAIL_COND_V(texture->data_size == 0, Image());
-	ERR_FAIL_COND_V(texture->render_target, Image());
+	ERR_FAIL_COND_V(!texture, Ref<Image>());
+	ERR_FAIL_COND_V(!texture->active, Ref<Image>());
+	ERR_FAIL_COND_V(texture->data_size == 0, Ref<Image>());
+	ERR_FAIL_COND_V(texture->render_target, Ref<Image>());
 
-	if (!texture->images[p_cube_side].empty()) {
+	if (!texture->images[p_cube_side].is_null()) {
 		return texture->images[p_cube_side];
 	}
 
@@ -867,13 +868,13 @@ Image RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSide p_
 
 	data.resize(data_size);
 
-	Image img(texture->alloc_width, texture->alloc_height, texture->mipmaps > 1 ? true : false, texture->format, data);
+	Image *img = memnew(Image(texture->alloc_width, texture->alloc_height, texture->mipmaps > 1 ? true : false, texture->format, data));
 
-	return img;
+	return Ref<Image>(img);
 #else
 
 	ERR_EXPLAIN("Sorry, It's not posible to obtain images back in OpenGL ES");
-	return Image();
+	return Ref<Image>();
 #endif
 }
 

+ 4 - 4
drivers/gles3/rasterizer_storage_gles3.h

@@ -240,7 +240,7 @@ public:
 
 		RenderTarget *render_target;
 
-		Image images[6];
+		Ref<Image> images[6];
 
 		VisualServer::TextureDetectCallback detect_3d;
 		void *detect_3d_ud;
@@ -280,12 +280,12 @@ public:
 
 	mutable RID_Owner<Texture> texture_owner;
 
-	Image _get_gl_image_and_format(const Image &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_type, bool &r_compressed, bool &srgb);
+	Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_type, bool &r_compressed, bool &srgb);
 
 	virtual RID texture_create();
 	virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT);
-	virtual void texture_set_data(RID p_texture, const Image &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT);
-	virtual Image texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const;
+	virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT);
+	virtual Ref<Image> texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const;
 	virtual void texture_set_flags(RID p_texture, uint32_t p_flags);
 	virtual uint32_t texture_get_flags(RID p_texture) const;
 	virtual Image::Format texture_get_format(RID p_texture) const;

+ 22 - 20
drivers/png/image_loader_png.cpp

@@ -68,7 +68,7 @@ static void _png_warn_function(png_structp, png_const_charp text) {
 
 typedef void(PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp));
 
-Error ImageLoaderPNG::_load_image(void *rf_up, png_rw_ptr p_func, Image *p_image) {
+Error ImageLoaderPNG::_load_image(void *rf_up, png_rw_ptr p_func, Ref<Image> p_image) {
 
 	png_structp png;
 	png_infop info;
@@ -201,7 +201,7 @@ Error ImageLoaderPNG::_load_image(void *rf_up, png_rw_ptr p_func, Image *p_image
 	return OK;
 }
 
-Error ImageLoaderPNG::load_image(Image *p_image, FileAccess *f) {
+Error ImageLoaderPNG::load_image(Ref<Image> p_image, FileAccess *f) {
 
 	Error err = _load_image(f, _read_png_data, p_image);
 	f->close();
@@ -238,25 +238,26 @@ static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t p_len
 	}
 }
 
-static Image _load_mem_png(const uint8_t *p_png, int p_size) {
+static Ref<Image> _load_mem_png(const uint8_t *p_png, int p_size) {
 
 	PNGReadStatus prs;
 	prs.image = p_png;
 	prs.offset = 0;
 	prs.size = p_size;
 
-	Image img;
-	Error err = ImageLoaderPNG::_load_image(&prs, user_read_data, &img);
-	ERR_FAIL_COND_V(err, Image());
+	Ref<Image> img;
+	img.instance();
+	Error err = ImageLoaderPNG::_load_image(&prs, user_read_data, img);
+	ERR_FAIL_COND_V(err, Ref<Image>());
 
 	return img;
 }
 
-static Image _lossless_unpack_png(const PoolVector<uint8_t> &p_data) {
+static Ref<Image> _lossless_unpack_png(const PoolVector<uint8_t> &p_data) {
 
 	int len = p_data.size();
 	PoolVector<uint8_t>::Read r = p_data.read();
-	ERR_FAIL_COND_V(r[0] != 'P' || r[1] != 'N' || r[2] != 'G' || r[3] != ' ', Image());
+	ERR_FAIL_COND_V(r[0] != 'P' || r[1] != 'N' || r[2] != 'G' || r[3] != ' ', Ref<Image>());
 	return _load_mem_png(&r[4], len - 4);
 }
 
@@ -271,13 +272,14 @@ static void _write_png_data(png_structp png_ptr, png_bytep data, png_size_t p_le
 	//print_line("png write: "+itos(p_length));
 }
 
-static PoolVector<uint8_t> _lossless_pack_png(const Image &p_image) {
+static PoolVector<uint8_t> _lossless_pack_png(const Ref<Image> &p_image) {
 
-	Image img = p_image;
-	if (img.is_compressed())
-		img.decompress();
+	Ref<Image> img = p_image->duplicate();
 
-	ERR_FAIL_COND_V(img.is_compressed(), PoolVector<uint8_t>());
+	if (img->is_compressed())
+		img->decompress();
+
+	ERR_FAIL_COND_V(img->is_compressed(), PoolVector<uint8_t>());
 
 	png_structp png_ptr;
 	png_infop info_ptr;
@@ -311,7 +313,7 @@ static PoolVector<uint8_t> _lossless_pack_png(const Image &p_image) {
 	int pngf = 0;
 	int cs = 0;
 
-	switch (img.get_format()) {
+	switch (img->get_format()) {
 
 		case Image::FORMAT_L8: {
 
@@ -335,22 +337,22 @@ static PoolVector<uint8_t> _lossless_pack_png(const Image &p_image) {
 		} break;
 		default: {
 
-			if (img.detect_alpha()) {
+			if (img->detect_alpha()) {
 
-				img.convert(Image::FORMAT_RGBA8);
+				img->convert(Image::FORMAT_RGBA8);
 				pngf = PNG_COLOR_TYPE_RGB_ALPHA;
 				cs = 4;
 			} else {
 
-				img.convert(Image::FORMAT_RGB8);
+				img->convert(Image::FORMAT_RGB8);
 				pngf = PNG_COLOR_TYPE_RGB;
 				cs = 3;
 			}
 		}
 	}
 
-	int w = img.get_width();
-	int h = img.get_height();
+	int w = img->get_width();
+	int h = img->get_height();
 	png_set_IHDR(png_ptr, info_ptr, w, h,
 			8, pngf, PNG_INTERLACE_NONE,
 			PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
@@ -362,7 +364,7 @@ static PoolVector<uint8_t> _lossless_pack_png(const Image &p_image) {
 		ERR_FAIL_V(PoolVector<uint8_t>());
 	}
 
-	PoolVector<uint8_t>::Read r = img.get_data().read();
+	PoolVector<uint8_t>::Read r = img->get_data().read();
 
 	row_pointers = (png_bytep *)memalloc(sizeof(png_bytep) * h);
 	for (int i = 0; i < h; i++) {

+ 2 - 2
drivers/png/image_loader_png.h

@@ -42,8 +42,8 @@ class ImageLoaderPNG : public ImageFormatLoader {
 	static void _read_png_data(png_structp png_ptr, png_bytep data, png_size_t p_length);
 
 public:
-	static Error _load_image(void *rf_up, png_rw_ptr p_func, Image *p_image);
-	virtual Error load_image(Image *p_image, FileAccess *f);
+	static Error _load_image(void *rf_up, png_rw_ptr p_func, Ref<Image> p_image);
+	virtual Error load_image(Ref<Image> p_image, FileAccess *f);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	ImageLoaderPNG();
 };

+ 14 - 12
drivers/png/resource_saver_png.cpp

@@ -50,7 +50,7 @@ Error ResourceSaverPNG::save(const String &p_path, const RES &p_resource, uint32
 	ERR_EXPLAIN("Can't save empty texture as PNG");
 	ERR_FAIL_COND_V(!texture->get_width() || !texture->get_height(), ERR_INVALID_PARAMETER);
 
-	Image img = texture->get_data();
+	Ref<Image> img = texture->get_data();
 
 	Error err = save_image(p_path, img);
 
@@ -95,12 +95,14 @@ Error ResourceSaverPNG::save(const String &p_path, const RES &p_resource, uint32
 	return err;
 };
 
-Error ResourceSaverPNG::save_image(const String &p_path, Image &p_img) {
+Error ResourceSaverPNG::save_image(const String &p_path, const Ref<Image> &p_img) {
 
-	if (p_img.is_compressed())
-		p_img.decompress();
+	Ref<Image> img = p_img->duplicate();
 
-	ERR_FAIL_COND_V(p_img.is_compressed(), ERR_INVALID_PARAMETER);
+	if (img->is_compressed())
+		img->decompress();
+
+	ERR_FAIL_COND_V(img->is_compressed(), ERR_INVALID_PARAMETER);
 
 	png_structp png_ptr;
 	png_infop info_ptr;
@@ -135,7 +137,7 @@ Error ResourceSaverPNG::save_image(const String &p_path, Image &p_img) {
 	int pngf = 0;
 	int cs = 0;
 
-	switch (p_img.get_format()) {
+	switch (img->get_format()) {
 
 		case Image::FORMAT_L8: {
 
@@ -159,22 +161,22 @@ Error ResourceSaverPNG::save_image(const String &p_path, Image &p_img) {
 		} break;
 		default: {
 
-			if (p_img.detect_alpha()) {
+			if (img->detect_alpha()) {
 
-				p_img.convert(Image::FORMAT_RGBA8);
+				img->convert(Image::FORMAT_RGBA8);
 				pngf = PNG_COLOR_TYPE_RGB_ALPHA;
 				cs = 4;
 			} else {
 
-				p_img.convert(Image::FORMAT_RGB8);
+				img->convert(Image::FORMAT_RGB8);
 				pngf = PNG_COLOR_TYPE_RGB;
 				cs = 3;
 			}
 		}
 	}
 
-	int w = p_img.get_width();
-	int h = p_img.get_height();
+	int w = img->get_width();
+	int h = img->get_height();
 	png_set_IHDR(png_ptr, info_ptr, w, h,
 			8, pngf, PNG_INTERLACE_NONE,
 			PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
@@ -187,7 +189,7 @@ Error ResourceSaverPNG::save_image(const String &p_path, Image &p_img) {
 		ERR_FAIL_V(ERR_CANT_OPEN);
 	}
 
-	PoolVector<uint8_t>::Read r = p_img.get_data().read();
+	PoolVector<uint8_t>::Read r = img->get_data().read();
 
 	row_pointers = (png_bytep *)memalloc(sizeof(png_bytep) * h);
 	for (int i = 0; i < h; i++) {

+ 2 - 1
drivers/png/resource_saver_png.h

@@ -30,11 +30,12 @@
 #ifndef RESOURCE_SAVER_PNG_H
 #define RESOURCE_SAVER_PNG_H
 
+#include "image.h"
 #include "io/resource_saver.h"
 
 class ResourceSaverPNG : public ResourceFormatSaver {
 public:
-	static Error save_image(const String &p_path, Image &p_img);
+	static Error save_image(const String &p_path, const Ref<Image> &p_img);
 
 	virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
 	virtual bool recognize(const RES &p_resource) const;

+ 5 - 4
editor/asset_library_editor_plugin.cpp

@@ -683,17 +683,18 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PoolByt
 
 		int len = image_data.size();
 		PoolByteArray::Read r = image_data.read();
-		Image image(r.ptr(), len);
-		if (!image.empty()) {
+		Ref<Image> image = Ref<Image>(memnew(Image(r.ptr(), len)));
+
+		if (!image->empty()) {
 			float max_height = 10000;
 			switch (image_queue[p_queue_id].image_type) {
 				case IMAGE_QUEUE_ICON: max_height = 80; break;
 				case IMAGE_QUEUE_THUMBNAIL: max_height = 80; break;
 				case IMAGE_QUEUE_SCREENSHOT: max_height = 345; break;
 			}
-			float scale_ratio = max_height / image.get_height();
+			float scale_ratio = max_height / image->get_height();
 			if (scale_ratio < 1) {
-				image.resize(image.get_width() * scale_ratio, image.get_height() * scale_ratio, Image::INTERPOLATE_CUBIC);
+				image->resize(image->get_width() * scale_ratio, image->get_height() * scale_ratio, Image::INTERPOLATE_CUBIC);
 			}
 
 			Ref<ImageTexture> tex;

+ 0 - 2
editor/connections_dialog.cpp

@@ -239,7 +239,6 @@ void ConnectDialog::_add_bind() {
 		case Variant::BASIS: value = Basis(); break;
 		case Variant::TRANSFORM: value = Transform(); break;
 		case Variant::COLOR: value = Color(); break;
-		case Variant::IMAGE: value = Image(); break;
 
 		default: { ERR_FAIL(); } break;
 	}
@@ -327,7 +326,6 @@ ConnectDialog::ConnectDialog() {
 	type_list->add_item("Transform", Variant::TRANSFORM);
 	//type_list->add_separator();
 	type_list->add_item("Color", Variant::COLOR);
-	type_list->add_item("Image", Variant::IMAGE);
 	type_list->select(0);
 
 	Button *add_bind = memnew(Button);

+ 0 - 4
editor/doc/doc_data.cpp

@@ -335,11 +335,7 @@ void DocData::generate(bool p_basic_types) {
 							case Variant::DICTIONARY: // 20
 							case Variant::ARRAY:
 							case Variant::_RID:
-							case Variant::IMAGE:
-								//case Variant::RESOURCE:
 
-								default_arg_text = Variant::get_type_name(default_arg.get_type()) + "()";
-								break;
 							default: {}
 						}
 

+ 0 - 4
editor/doc/doc_dump.cpp

@@ -198,11 +198,7 @@ void DocDump::dump(const String &p_file) {
 							case Variant::DICTIONARY: // 20
 							case Variant::ARRAY:
 							case Variant::_RID:
-							case Variant::IMAGE:
-								//case Variant::RESOURCE:
 
-								default_arg_text = Variant::get_type_name(default_arg.get_type()) + "()";
-								break;
 							default: {}
 						}
 

+ 6 - 4
editor/editor_file_dialog.cpp

@@ -488,8 +488,9 @@ void EditorFileDialog::update_file_list() {
 
 		if (!has_icon("ResizedFolder", "EditorIcons")) {
 			Ref<ImageTexture> folder = get_icon("FolderBig", "EditorIcons");
-			Image img = folder->get_data();
-			img.resize(thumbnail_size, thumbnail_size);
+			Ref<Image> img = folder->get_data();
+			img = img->duplicate();
+			img->resize(thumbnail_size, thumbnail_size);
 			Ref<ImageTexture> resized_folder = Ref<ImageTexture>(memnew(ImageTexture));
 			resized_folder->create_from_image(img, 0);
 			Theme::get_default()->set_icon("ResizedFolder", "EditorIcons", resized_folder);
@@ -499,8 +500,9 @@ void EditorFileDialog::update_file_list() {
 
 		if (!has_icon("ResizedFile", "EditorIcons")) {
 			Ref<ImageTexture> file = get_icon("FileBig", "EditorIcons");
-			Image img = file->get_data();
-			img.resize(thumbnail_size, thumbnail_size);
+			Ref<Image> img = file->get_data();
+			img = img->duplicate();
+			img->resize(thumbnail_size, thumbnail_size);
 			Ref<ImageTexture> resized_file = Ref<ImageTexture>(memnew(ImageTexture));
 			resized_file->create_from_image(img, 0);
 			Theme::get_default()->set_icon("ResizedFile", "EditorIcons", resized_file);

+ 3 - 2
editor/editor_node.cpp

@@ -4463,8 +4463,9 @@ Variant EditorNode::drag_resource(const Ref<Resource> &p_res, Control *p_from) {
 	{
 		//todo make proper previews
 		Ref<ImageTexture> pic = gui_base->get_icon("FileBig", "EditorIcons");
-		Image img = pic->get_data();
-		img.resize(48, 48); //meh
+		Ref<Image> img = pic->get_data();
+		img = img->duplicate();
+		img->resize(48, 48); //meh
 		Ref<ImageTexture> resized_pic = Ref<ImageTexture>(memnew(ImageTexture));
 		resized_pic->create_from_image(img);
 		preview = resized_pic;

+ 4 - 2
editor/editor_profiler.cpp

@@ -344,14 +344,16 @@ void EditorProfiler::_update_plot() {
 
 	wr = PoolVector<uint8_t>::Write();
 
-	Image img(w, h, 0, Image::FORMAT_RGBA8, graph_image);
+	Ref<Image> img;
+	img.instance();
+	img->create(w, h, 0, Image::FORMAT_RGBA8, graph_image);
 
 	if (reset_texture) {
 
 		if (graph_texture.is_null()) {
 			graph_texture.instance();
 		}
-		graph_texture->create(img.get_width(), img.get_height(), img.get_format(), Texture::FLAG_VIDEO_SURFACE);
+		graph_texture->create(img->get_width(), img->get_height(), img->get_format(), Texture::FLAG_VIDEO_SURFACE);
 	}
 
 	graph_texture->set_data(img);

+ 5 - 4
editor/editor_run_native.cpp

@@ -43,11 +43,12 @@ void EditorRunNative::_notification(int p_what) {
 				continue;
 			Ref<ImageTexture> icon = eep->get_logo();
 			if (!icon.is_null()) {
-				Image im = icon->get_data();
-				im.clear_mipmaps();
-				if (!im.empty()) {
+				Ref<Image> im = icon->get_data();
+				im = im->duplicate();
+				im->clear_mipmaps();
+				if (!im->empty()) {
 
-					im.resize(16, 16);
+					im->resize(16, 16);
 					Ref<ImageTexture> small_icon;
 					small_icon.instance();
 					small_icon->create_from_image(im, 0);

+ 5 - 4
editor/filesystem_dock.cpp

@@ -416,8 +416,9 @@ void FileSystemDock::_update_files(bool p_keep_selection) {
 
 		if (!has_icon("ResizedFolder", "EditorIcons")) {
 			Ref<ImageTexture> folder = get_icon("FolderBig", "EditorIcons");
-			Image img = folder->get_data();
-			img.resize(thumbnail_size, thumbnail_size);
+			Ref<Image> img = folder->get_data();
+			img = img->duplicate();
+			img->resize(thumbnail_size, thumbnail_size);
 			Ref<ImageTexture> resized_folder = Ref<ImageTexture>(memnew(ImageTexture));
 			resized_folder->create_from_image(img, 0);
 			Theme::get_default()->set_icon("ResizedFolder", "EditorIcons", resized_folder);
@@ -427,8 +428,8 @@ void FileSystemDock::_update_files(bool p_keep_selection) {
 
 		if (!has_icon("ResizedFile", "EditorIcons")) {
 			Ref<ImageTexture> file = get_icon("FileBig", "EditorIcons");
-			Image img = file->get_data();
-			img.resize(thumbnail_size, thumbnail_size);
+			Ref<Image> img = file->get_data();
+			img->resize(thumbnail_size, thumbnail_size);
 			Ref<ImageTexture> resized_file = Ref<ImageTexture>(memnew(ImageTexture));
 			resized_file->create_from_image(img, 0);
 			Theme::get_default()->set_icon("ResizedFile", "EditorIcons", resized_file);

+ 3 - 3
editor/icons/SCsub

@@ -62,9 +62,9 @@ def make_editor_icons_action(target, source, env):
     s.write("static Ref<ImageTexture> make_icon(const uint8_t* p_png,const uint8_t* p_hidpi_png) {\n")
     s.write("\tRef<ImageTexture> texture( memnew( ImageTexture ) );\n")
     s.write("\tbool use_hidpi_image=(editor_get_scale()>1.0&&p_hidpi_png);\n")
-    s.write("\tImage img(use_hidpi_image?p_hidpi_png:p_png);\n")
-    s.write("\tif (editor_get_scale()>1.0 && !p_hidpi_png) { img.convert(Image::FORMAT_RGBA8); img.expand_x2_hq2x(); use_hidpi_image=true;}\n")
-    s.write("\timg.resize(img.get_width()*EDSCALE/(use_hidpi_image?2:1),img.get_height()*EDSCALE/(use_hidpi_image?2:1));\n")
+    s.write("\tRef<Image> img = memnew(Image(use_hidpi_image?p_hidpi_png:p_png));\n")
+    s.write("\tif (editor_get_scale()>1.0 && !p_hidpi_png) { img->convert(Image::FORMAT_RGBA8); img->expand_x2_hq2x(); use_hidpi_image=true;}\n")
+    s.write("\timg->resize(img->get_width()*EDSCALE/(use_hidpi_image?2:1),img->get_height()*EDSCALE/(use_hidpi_image?2:1));\n")
     s.write("\ttexture->create_from_image( img,ImageTexture::FLAG_FILTER );\n")
     s.write("\treturn texture;\n")
     s.write("}\n\n")

+ 34 - 33
editor/import/resource_importer_texture.cpp

@@ -181,7 +181,7 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,
 	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "detect_3d"), p_preset == PRESET_DETECT));
 }
 
-void ResourceImporterTexture::_save_stex(const Image &p_image, const String &p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable, bool p_detect_3d, bool p_detect_srgb) {
+void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String &p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable, bool p_detect_3d, bool p_detect_srgb) {
 
 	FileAccess *f = FileAccess::open(p_to_path, FileAccess::WRITE);
 	f->store_8('G');
@@ -189,8 +189,8 @@ void ResourceImporterTexture::_save_stex(const Image &p_image, const String &p_t
 	f->store_8('S');
 	f->store_8('T'); //godot streamable texture
 
-	f->store_32(p_image.get_width());
-	f->store_32(p_image.get_height());
+	f->store_32(p_image->get_width());
+	f->store_32(p_image->get_height());
 	f->store_32(p_texture_flags);
 
 	uint32_t format = 0;
@@ -207,14 +207,14 @@ void ResourceImporterTexture::_save_stex(const Image &p_image, const String &p_t
 	switch (p_compress_mode) {
 		case COMPRESS_LOSSLESS: {
 
-			Image image = p_image;
+			Ref<Image> image = p_image->duplicate();
 			if (p_mipmaps) {
-				image.generate_mipmaps();
+				image->generate_mipmaps();
 			} else {
-				image.clear_mipmaps();
+				image->clear_mipmaps();
 			}
 
-			int mmc = image.get_mipmap_count() + 1;
+			int mmc = image->get_mipmap_count() + 1;
 
 			format |= StreamTexture::FORMAT_BIT_LOSSLESS;
 			f->store_32(format);
@@ -223,7 +223,7 @@ void ResourceImporterTexture::_save_stex(const Image &p_image, const String &p_t
 			for (int i = 0; i < mmc; i++) {
 
 				if (i > 0) {
-					image.shrink_x2();
+					image->shrink_x2();
 				}
 
 				PoolVector<uint8_t> data = Image::lossless_packer(image);
@@ -236,14 +236,14 @@ void ResourceImporterTexture::_save_stex(const Image &p_image, const String &p_t
 
 		} break;
 		case COMPRESS_LOSSY: {
-			Image image = p_image;
+			Ref<Image> image = p_image->duplicate();
 			if (p_mipmaps) {
-				image.generate_mipmaps();
+				image->generate_mipmaps();
 			} else {
-				image.clear_mipmaps();
+				image->clear_mipmaps();
 			}
 
-			int mmc = image.get_mipmap_count() + 1;
+			int mmc = image->get_mipmap_count() + 1;
 
 			format |= StreamTexture::FORMAT_BIT_LOSSY;
 			f->store_32(format);
@@ -252,7 +252,7 @@ void ResourceImporterTexture::_save_stex(const Image &p_image, const String &p_t
 			for (int i = 0; i < mmc; i++) {
 
 				if (i > 0) {
-					image.shrink_x2();
+					image->shrink_x2();
 				}
 
 				PoolVector<uint8_t> data = Image::lossy_packer(image, p_lossy_quality);
@@ -265,15 +265,15 @@ void ResourceImporterTexture::_save_stex(const Image &p_image, const String &p_t
 		} break;
 		case COMPRESS_VIDEO_RAM: {
 
-			Image image = p_image;
-			image.generate_mipmaps();
-			image.compress(p_vram_compression);
+			Ref<Image> image = p_image->duplicate();
+			image->generate_mipmaps();
+			image->compress(p_vram_compression);
 
-			format |= image.get_format();
+			format |= image->get_format();
 
 			f->store_32(format);
 
-			PoolVector<uint8_t> data = image.get_data();
+			PoolVector<uint8_t> data = image->get_data();
 			int dl = data.size();
 			PoolVector<uint8_t>::Read r = data.read();
 			f->store_buffer(r.ptr(), dl);
@@ -281,17 +281,17 @@ void ResourceImporterTexture::_save_stex(const Image &p_image, const String &p_t
 		} break;
 		case COMPRESS_UNCOMPRESSED: {
 
-			Image image = p_image;
+			Ref<Image> image = p_image->duplicate();
 			if (p_mipmaps) {
-				image.generate_mipmaps();
+				image->generate_mipmaps();
 			} else {
-				image.clear_mipmaps();
+				image->clear_mipmaps();
 			}
 
-			format |= image.get_format();
+			format |= image->get_format();
 			f->store_32(format);
 
-			PoolVector<uint8_t> data = image.get_data();
+			PoolVector<uint8_t> data = image->get_data();
 			int dl = data.size();
 			PoolVector<uint8_t>::Read r = data.read();
 
@@ -317,8 +317,9 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
 	bool stream = p_options["stream"];
 	int size_limit = p_options["size_limit"];
 
-	Image image;
-	Error err = ImageLoader::load_image(p_source_file, &image);
+	Ref<Image> image;
+	image.instance();
+	Error err = ImageLoader::load_image(p_source_file, image);
 	if (err != OK)
 		return err;
 
@@ -336,28 +337,28 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
 	if (srgb == 1)
 		tex_flags |= Texture::FLAG_CONVERT_TO_LINEAR;
 
-	if (size_limit > 0 && (image.get_width() > size_limit || image.get_height() > size_limit)) {
+	if (size_limit > 0 && (image->get_width() > size_limit || image->get_height() > size_limit)) {
 		//limit size
-		if (image.get_width() >= image.get_height()) {
+		if (image->get_width() >= image->get_height()) {
 			int new_width = size_limit;
-			int new_height = image.get_height() * new_width / image.get_width();
+			int new_height = image->get_height() * new_width / image->get_width();
 
-			image.resize(new_width, new_height, Image::INTERPOLATE_CUBIC);
+			image->resize(new_width, new_height, Image::INTERPOLATE_CUBIC);
 		} else {
 
 			int new_height = size_limit;
-			int new_width = image.get_width() * new_height / image.get_height();
+			int new_width = image->get_width() * new_height / image->get_height();
 
-			image.resize(new_width, new_height, Image::INTERPOLATE_CUBIC);
+			image->resize(new_width, new_height, Image::INTERPOLATE_CUBIC);
 		}
 	}
 
 	if (fix_alpha_border) {
-		image.fix_alpha_edges();
+		image->fix_alpha_edges();
 	}
 
 	if (premult_alpha) {
-		image.premultiply_alpha();
+		image->premultiply_alpha();
 	}
 
 	bool detect_3d = p_options["detect_3d"];

+ 3 - 1
editor/import/resource_importer_texture.h

@@ -30,7 +30,9 @@
 #ifndef RESOURCEIMPORTTEXTURE_H
 #define RESOURCEIMPORTTEXTURE_H
 
+#include "image.h"
 #include "io/resource_import.h"
+
 class StreamTexture;
 
 class ResourceImporterTexture : public ResourceImporter {
@@ -78,7 +80,7 @@ public:
 	virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
 	virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
 
-	void _save_stex(const Image &p_image, const String &p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable, bool p_detect_3d, bool p_detect_srgb);
+	void _save_stex(const Ref<Image> &p_image, const String &p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable, bool p_detect_3d, bool p_detect_srgb);
 
 	virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL);
 

+ 1 - 1
editor/plugins/baked_light_baker.h

@@ -31,7 +31,7 @@
 #define BAKED_LIGHT_BAKER_H
 
 #include "os/thread.h"
-#include "scene/3d/baked_light_instance.h"
+
 #include "scene/3d/light.h"
 #include "scene/3d/mesh_instance.h"
 

+ 2 - 1
editor/plugins/gradient_texture_editor_plugin.cpp

@@ -48,7 +48,8 @@ GradientTextureEdit::GradientTextureEdit() {
 	add_child(popup);
 
 	checker = Ref<ImageTexture>(memnew(ImageTexture));
-	checker->create_from_image(Image(checker_bg_png), ImageTexture::FLAG_REPEAT);
+	Ref<Image> checker_bg = memnew(Image(checker_bg_png));
+	checker->create_from_image(checker_bg, ImageTexture::FLAG_REPEAT);
 }
 
 int GradientTextureEdit::_get_point_from_pos(int x) {

+ 8 - 7
editor/plugins/particles_2d_editor_plugin.cpp

@@ -64,17 +64,18 @@ void Particles2DEditorPlugin::_file_selected(const String &p_file) {
 
 	int epc = epoints->get_value();
 
-	Image img;
-	Error err = ImageLoader::load_image(p_file, &img);
+	Ref<Image> img;
+	img.instance();
+	Error err = ImageLoader::load_image(p_file, img);
 	ERR_EXPLAIN(TTR("Error loading image:") + " " + p_file);
 	ERR_FAIL_COND(err != OK);
 
-	img.convert(Image::FORMAT_LA8);
-	ERR_FAIL_COND(img.get_format() != Image::FORMAT_LA8);
-	Size2i s = Size2(img.get_width(), img.get_height());
+	img->convert(Image::FORMAT_LA8);
+	ERR_FAIL_COND(img->get_format() != Image::FORMAT_LA8);
+	Size2i s = Size2(img->get_width(), img->get_height());
 	ERR_FAIL_COND(s.width == 0 || s.height == 0);
 
-	PoolVector<uint8_t> data = img.get_data();
+	PoolVector<uint8_t> data = img->get_data();
 	PoolVector<uint8_t>::Read r = data.read();
 
 	Vector<Point2i> valid_positions;
@@ -98,7 +99,7 @@ void Particles2DEditorPlugin::_file_selected(const String &p_file) {
 	epoints.resize(epc);
 	PoolVector<Point2>::Write w = epoints.write();
 
-	Size2 extents = Size2(img.get_width() * 0.5, img.get_height() * 0.5);
+	Size2 extents = Size2(img->get_width() * 0.5, img->get_height() * 0.5);
 
 	for (int i = 0; i < epc; i++) {
 

+ 2 - 2
editor/plugins/particles_editor_plugin.cpp

@@ -329,7 +329,7 @@ void ParticlesEditor::_generate_emission_points() {
 		copymem(iw.ptr(), r.ptr(), point_count * sizeof(float) * 3);
 	}
 
-	Image image(w, h, false, Image::FORMAT_RGBF, point_img);
+	Ref<Image> image = memnew(Image(w, h, false, Image::FORMAT_RGBF, point_img));
 
 	Ref<ImageTexture> tex;
 	tex.instance();
@@ -354,7 +354,7 @@ void ParticlesEditor::_generate_emission_points() {
 			copymem(iw.ptr(), r.ptr(), point_count * sizeof(float) * 3);
 		}
 
-		Image image2(w, h, false, Image::FORMAT_RGBF, point_img2);
+		Ref<Image> image2 = memnew(Image(w, h, false, Image::FORMAT_RGBF, point_img2));
 
 		Ref<ImageTexture> tex2;
 		tex2.instance();

+ 1 - 1
editor/plugins/spatial_editor_plugin.h

@@ -428,7 +428,7 @@ private:
 	ViewportContainer *settings_light_base;
 	Viewport *settings_light_vp;
 	ColorPickerButton *settings_ambient_color;
-	Image settings_light_dir_image;
+	Ref<Image> settings_light_dir_image;
 
 	void _xform_dialog_action();
 	void _menu_item_pressed(int p_option);

+ 5 - 4
editor/plugins/texture_region_editor_plugin.cpp

@@ -678,12 +678,13 @@ void TextureRegionEditor::_edit_region() {
 	}
 
 	autoslice_cache.clear();
-	Image i;
-	if (i.load(texture->get_path()) == OK) {
+	Ref<Image> i;
+	i.instance();
+	if (i->load(texture->get_path()) == OK) {
 		BitMap bm;
 		bm.create_from_image_alpha(i);
-		for (int y = 0; y < i.get_height(); y++) {
-			for (int x = 0; x < i.get_width(); x++) {
+		for (int y = 0; y < i->get_height(); y++) {
+			for (int x = 0; x < i->get_width(); x++) {
 				if (bm.get_bit(Point2(x, y))) {
 					bool found = false;
 					for (List<Rect2>::Element *E = autoslice_cache.front(); E; E = E->next()) {

+ 4 - 3
editor/project_manager.cpp

@@ -806,11 +806,12 @@ void ProjectManager::_load_recent_projects() {
 		if (cf->has_section_key("application", "icon")) {
 			String appicon = cf->get_value("application", "icon");
 			if (appicon != "") {
-				Image img;
-				Error err = img.load(appicon.replace_first("res://", path + "/"));
+				Ref<Image> img;
+				img.instance();
+				Error err = img->load(appicon.replace_first("res://", path + "/"));
 				if (err == OK) {
 
-					img.resize(64, 64);
+					img->resize(64, 64);
 					Ref<ImageTexture> it = memnew(ImageTexture);
 					it->create_from_image(img);
 					icon = it;

+ 0 - 72
editor/property_editor.cpp

@@ -861,15 +861,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
 			*/
 
 		} break;
-		case Variant::IMAGE: {
 
-			List<String> names;
-			names.push_back(TTR("New"));
-			names.push_back(TTR("Load"));
-			names.push_back(TTR("Clear"));
-			config_action_buttons(names);
-
-		} break;
 		case Variant::NODE_PATH: {
 
 			List<String> names;
@@ -1061,16 +1053,6 @@ void CustomPropertyEditor::_file_selected(String p_file) {
 			emit_signal("variant_changed");
 			hide();
 		} break;
-		case Variant::IMAGE: {
-
-			Image image;
-			Error err = ImageLoader::load_image(p_file, &image);
-			ERR_EXPLAIN(TTR("Couldn't load image"));
-			ERR_FAIL_COND(err);
-			v = image;
-			emit_signal("variant_changed");
-			hide();
-		} break;
 		default: {}
 	}
 }
@@ -1387,36 +1369,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
 			}
 
 		} break;
-		case Variant::IMAGE: {
 
-			if (p_which == 0) {
-				//new image too difficult
-				ERR_PRINT("New Image Unimplemented");
-
-			} else if (p_which == 1) {
-
-				file->set_access(EditorFileDialog::ACCESS_RESOURCES);
-				file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
-				List<String> extensions;
-				ImageLoader::get_recognized_extensions(&extensions);
-
-				file->clear_filters();
-
-				for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
-
-					file->add_filter("*." + E->get() + " ; " + E->get().to_upper());
-				}
-
-				file->popup_centered_ratio();
-
-			} else if (p_which == 2) {
-
-				v = Image();
-				emit_signal("variant_changed");
-				hide();
-			}
-
-		} break;
 		default: {};
 	}
 }
@@ -1756,9 +1709,7 @@ void CustomPropertyEditor::_modified(String p_string) {
 			emit_signal("variant_changed");
 			*/
 		} break;
-		case Variant::IMAGE: {
 
-		} break;
 		case Variant::NODE_PATH: {
 
 			v = NodePath(value_editor[0]->get_text());
@@ -2356,15 +2307,6 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String &p
 			tree->update();
 			//p_item->set_text(1,obj->get(p_name));
 
-		} break;
-		case Variant::IMAGE: {
-
-			Image img = obj->get(p_name);
-			if (img.empty())
-				p_item->set_text(1, "[Image (empty)]");
-			else
-				p_item->set_text(1, "[Image " + itos(img.get_width()) + "x" + itos(img.get_height()) + "-" + String(Image::get_format_name(img.get_format())) + "]");
-
 		} break;
 		case Variant::NODE_PATH: {
 
@@ -3588,19 +3530,7 @@ void PropertyEditor::update_tree() {
 					item->set_icon(0, get_icon("Color", "EditorIcons"));
 
 			} break;
-			case Variant::IMAGE: {
 
-				item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM);
-				item->set_editable(1, !read_only);
-				Image img = obj->get(p.name);
-				if (img.empty())
-					item->set_text(1, "[Image (empty)]");
-				else
-					item->set_text(1, "[Image " + itos(img.get_width()) + "x" + itos(img.get_height()) + "-" + String(Image::get_format_name(img.get_format())) + "]");
-				if (show_type_icons)
-					item->set_icon(0, get_icon("Image", "EditorIcons"));
-
-			} break;
 			case Variant::NODE_PATH: {
 
 				item->set_cell_mode(1, TreeItem::CELL_MODE_STRING);
@@ -3922,9 +3852,7 @@ void PropertyEditor::_item_edited() {
 		case Variant::COLOR: {
 			//_edit_set(name,item->get_custom_bg_color(0));
 		} break;
-		case Variant::IMAGE: {
 
-		} break;
 		case Variant::NODE_PATH: {
 			_edit_set(name, NodePath(item->get_text(1)), refresh_all);
 

+ 0 - 1
editor/property_selector.cpp

@@ -136,7 +136,6 @@ void PropertySelector::_update_search() {
 			Control::get_icon("MiniMatrix3", "EditorIcons"),
 			Control::get_icon("MiniTransform", "EditorIcons"),
 			Control::get_icon("MiniColor", "EditorIcons"),
-			Control::get_icon("MiniImage", "EditorIcons"),
 			Control::get_icon("MiniPath", "EditorIcons"),
 			Control::get_icon("MiniRid", "EditorIcons"),
 			Control::get_icon("MiniObject", "EditorIcons"),

+ 2 - 2
editor/pvrtc_compress.cpp

@@ -89,7 +89,7 @@ static void _compress_image(Image::CompressMode p_mode, Image *p_image) {
 		args.push_back("-m");
 
 	Ref<ImageTexture> t = memnew(ImageTexture);
-	t->create_from_image(*p_image, 0);
+	t->create_from_image(Ref<Image>(p_image), 0);
 	ResourceSaver::save(src_img, t);
 
 	Error err = OS::get_singleton()->execute(ttpath, args, true);
@@ -101,7 +101,7 @@ static void _compress_image(Image::CompressMode p_mode, Image *p_image) {
 	ERR_EXPLAIN(TTR("Can't load back converted image using PVRTC tool:") + " " + dst_img);
 	ERR_FAIL_COND(t.is_null());
 
-	*p_image = t->get_data();
+	p_image->copy_internals_from(t->get_data());
 }
 
 static void _compress_pvrtc2(Image *p_image) {

+ 8 - 7
main/main.cpp

@@ -917,18 +917,19 @@ Error Main::setup2() {
 		bool boot_logo_scale = GLOBAL_DEF("application/boot_splash_fullsize", true);
 		GlobalConfig::get_singleton()->set_custom_property_info("application/boot_splash", PropertyInfo(Variant::STRING, "application/boot_splash", PROPERTY_HINT_FILE, "*.png"));
 
-		Image boot_logo;
+		Ref<Image> boot_logo;
 
 		boot_logo_path = boot_logo_path.strip_edges();
 
 		if (boot_logo_path != String() /*&& FileAccess::exists(boot_logo_path)*/) {
 			print_line("Boot splash path: " + boot_logo_path);
-			Error err = boot_logo.load(boot_logo_path);
+			boot_logo.instance();
+			Error err = boot_logo->load(boot_logo_path);
 			if (err)
 				ERR_PRINTS("Non-existing or invalid boot splash at: " + boot_logo_path + ". Loading default splash.");
 		}
 
-		if (!boot_logo.empty()) {
+		if (boot_logo.is_valid()) {
 			OS::get_singleton()->_msec_splash = OS::get_singleton()->get_ticks_msec();
 			Color boot_bg = GLOBAL_DEF("application/boot_bg_color", clear);
 			VisualServer::get_singleton()->set_boot_image(boot_logo, boot_bg, boot_logo_scale);
@@ -941,7 +942,7 @@ Error Main::setup2() {
 #ifndef NO_DEFAULT_BOOT_LOGO
 
 			MAIN_PRINT("Main: Create bootsplash");
-			Image splash(boot_splash_png);
+			Ref<Image> splash = memnew(Image(boot_splash_png));
 
 			MAIN_PRINT("Main: ClearColor");
 			VisualServer::get_singleton()->set_default_clear_color(boot_splash_bg_color);
@@ -950,7 +951,7 @@ Error Main::setup2() {
 #endif
 		}
 
-		Image icon(app_icon_png);
+		Ref<Image> icon = memnew(Image(app_icon_png));
 		OS::get_singleton()->set_icon(icon);
 	}
 
@@ -1464,8 +1465,8 @@ bool Main::start() {
 
 				String iconpath = GLOBAL_DEF("application/icon", "Variant()");
 				if (iconpath != "") {
-					Image icon;
-					if (icon.load(iconpath) == OK)
+					Ref<Image> icon;
+					if (icon->load(iconpath) == OK)
 						OS::get_singleton()->set_icon(icon);
 				}
 			}

+ 0 - 12
main/tests/test_containers.cpp

@@ -55,18 +55,6 @@ MainLoop *test() {
 
 	{
 
-		Image img;
-		img.create(default_mouse_cursor_xpm);
-
-		{
-			for (int i = 0; i < 8; i++) {
-
-				Image mipmap;
-				//img.make_mipmap(mipmap);
-				img = mipmap;
-				if (img.get_width() <= 4) break;
-			};
-		};
 	};
 
 #if 0

+ 0 - 5
main/tests/test_image.cpp

@@ -63,11 +63,6 @@ public:
 
 MainLoop *test() {
 
-	Image img;
-	ImageLoader::load_image("as1.png", &img);
-
-	img.resize(512, 512);
-
 	return memnew(TestMainLoop);
 }
 }

+ 5 - 5
main/tests/test_physics_2d.cpp

@@ -82,7 +82,7 @@ class TestPhysics2DMainLoop : public MainLoop {
 				}
 			}
 
-			Image image(32, 2, 0, Image::FORMAT_LA8, pixels);
+			Ref<Image> image = memnew(Image(32, 2, 0, Image::FORMAT_LA8, pixels));
 
 			body_shape_data[Physics2DServer::SHAPE_SEGMENT].image = vs->texture_create_from_image(image);
 
@@ -109,7 +109,7 @@ class TestPhysics2DMainLoop : public MainLoop {
 				}
 			}
 
-			Image image(32, 32, 0, Image::FORMAT_LA8, pixels);
+			Ref<Image> image = memnew(Image(32, 32, 0, Image::FORMAT_LA8, pixels));
 
 			body_shape_data[Physics2DServer::SHAPE_CIRCLE].image = vs->texture_create_from_image(image);
 
@@ -136,7 +136,7 @@ class TestPhysics2DMainLoop : public MainLoop {
 				}
 			}
 
-			Image image(32, 32, 0, Image::FORMAT_LA8, pixels);
+			Ref<Image> image = memnew(Image(32, 32, 0, Image::FORMAT_LA8, pixels));
 
 			body_shape_data[Physics2DServer::SHAPE_RECTANGLE].image = vs->texture_create_from_image(image);
 
@@ -164,7 +164,7 @@ class TestPhysics2DMainLoop : public MainLoop {
 				}
 			}
 
-			Image image(32, 64, 0, Image::FORMAT_LA8, pixels);
+			Ref<Image> image = memnew(Image(32, 64, 0, Image::FORMAT_LA8, pixels));
 
 			body_shape_data[Physics2DServer::SHAPE_CAPSULE].image = vs->texture_create_from_image(image);
 
@@ -178,7 +178,7 @@ class TestPhysics2DMainLoop : public MainLoop {
 
 		{
 
-			Image image(convex_png);
+			Ref<Image> image = memnew(Image(convex_png));
 
 			body_shape_data[Physics2DServer::SHAPE_CONVEX_POLYGON].image = vs->texture_create_from_image(image);
 

+ 1 - 1
modules/dds/texture_loader_dds.cpp

@@ -441,7 +441,7 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
 		wb = PoolVector<uint8_t>::Write();
 	}
 
-	Image img(width, height, mipmaps - 1, info.format, src_data);
+	Ref<Image> img = memnew(Image(width, height, mipmaps - 1, info.format, src_data));
 
 	Ref<ImageTexture> texture = memnew(ImageTexture);
 	texture->create_from_image(img);

+ 10 - 9
modules/etc1/image_etc.cpp

@@ -88,25 +88,26 @@ static void _decompress_etc(Image *p_img) {
 
 	r = PoolVector<uint8_t>::Read();
 	//print_line("Re Creating ETC into regular image: w "+itos(p_img->get_width())+" h "+itos(p_img->get_height())+" mm "+itos(p_img->get_mipmaps()));
-	*p_img = Image(p_img->get_width(), p_img->get_height(), p_img->has_mipmaps(), Image::FORMAT_RGB8, dst);
-	if (p_img->has_mipmaps())
+	bool needs_mipmaps = p_img->has_mipmaps();
+	p_img->create(p_img->get_width(), p_img->get_height(), p_img->has_mipmaps(), Image::FORMAT_RGB8, dst);
+	if (needs_mipmaps)
 		p_img->generate_mipmaps();
 }
 
 static void _compress_etc(Image *p_img) {
 
-	Image img = *p_img;
+	Ref<Image> img = p_img->duplicate();
 
-	int imgw = img.get_width(), imgh = img.get_height();
+	int imgw = img->get_width(), imgh = img->get_height();
 
 	ERR_FAIL_COND(nearest_power_of_2(imgw) != imgw || nearest_power_of_2(imgh) != imgh);
 
-	if (img.get_format() != Image::FORMAT_RGB8)
-		img.convert(Image::FORMAT_RGB8);
+	if (img->get_format() != Image::FORMAT_RGB8)
+		img->convert(Image::FORMAT_RGB8);
 
 	PoolVector<uint8_t> res_data;
 	PoolVector<uint8_t> dst_data;
-	PoolVector<uint8_t>::Read r = img.get_data().read();
+	PoolVector<uint8_t>::Read r = img->get_data().read();
 
 	int target_size = Image::get_image_data_size(p_img->get_width(), p_img->get_height(), Image::FORMAT_ETC, p_img->has_mipmaps() ? -1 : 0);
 	int mmc = p_img->has_mipmaps() ? Image::get_image_required_mipmaps(p_img->get_width(), p_img->get_height(), Image::FORMAT_ETC) : 0;
@@ -122,7 +123,7 @@ static void _compress_etc(Image *p_img) {
 
 		int bw = MAX(imgw / 4, 1);
 		int bh = MAX(imgh / 4, 1);
-		const uint8_t *src = &r[img.get_mipmap_offset(i)];
+		const uint8_t *src = &r[img->get_mipmap_offset(i)];
 		int mmsize = MAX(bw, 1) * MAX(bh, 1) * 8;
 
 		uint8_t *dst = &w[ofs];
@@ -171,7 +172,7 @@ static void _compress_etc(Image *p_img) {
 		mc++;
 	}
 
-	*p_img = Image(p_img->get_width(), p_img->get_height(), (mc - 1) ? true : false, Image::FORMAT_ETC, dst_data);
+	p_img->create(p_img->get_width(), p_img->get_height(), (mc - 1) ? true : false, Image::FORMAT_ETC, dst_data);
 }
 
 void _register_etc1_compress_func() {

+ 1 - 1
modules/etc1/texture_loader_pkm.cpp

@@ -85,7 +85,7 @@ RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path,
 	int width = h.origWidth;
 	int height = h.origHeight;
 
-	Image img(width, height, mipmaps, Image::FORMAT_ETC, src_data);
+	Ref<Image> img = memnew(Image(width, height, mipmaps, Image::FORMAT_ETC, src_data));
 
 	Ref<ImageTexture> texture = memnew(ImageTexture);
 	texture->create_from_image(img);

+ 1 - 1
modules/gdnative/config.py

@@ -1,7 +1,7 @@
 
 
 def can_build(platform):
-    return True
+    return False
 
 
 def configure(env):

+ 1 - 1
modules/gdscript/gd_editor.cpp

@@ -1321,7 +1321,7 @@ static void _find_identifiers(GDCompletionContext &context, int p_line, bool p_o
 
 	static const char *_type_names[Variant::VARIANT_MAX] = {
 		"null", "bool", "int", "float", "String", "Vector2", "Rect2", "Vector3", "Transform2D", "Plane", "Quat", "AABB", "Basis", "Transform",
-		"Color", "Image", "NodePath", "RID", "Object", "InputEvent", "Dictionary", "Array", "RawArray", "IntArray", "FloatArray", "StringArray",
+		"Color", "NodePath", "RID", "Object", "InputEvent", "Dictionary", "Array", "RawArray", "IntArray", "FloatArray", "StringArray",
 		"Vector2Array", "Vector3Array", "ColorArray"
 	};
 

+ 0 - 1
modules/gdscript/gd_tokenizer.cpp

@@ -800,7 +800,6 @@ void GDTokenizerText::_advance() {
 							{ Variant::BASIS, "Basis" },
 							{ Variant::TRANSFORM, "Transform" },
 							{ Variant::COLOR, "Color" },
-							{ Variant::IMAGE, "Image" },
 							{ Variant::_RID, "RID" },
 							{ Variant::OBJECT, "Object" },
 							{ Variant::INPUT_EVENT, "InputEvent" },

+ 6 - 5
modules/jpg/image_loader_jpegd.cpp

@@ -89,7 +89,7 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p
 	return OK;
 }
 
-Error ImageLoaderJPG::load_image(Image *p_image, FileAccess *f) {
+Error ImageLoaderJPG::load_image(Ref<Image> p_image, FileAccess *f) {
 
 	PoolVector<uint8_t> src_image;
 	int src_image_len = f->get_len();
@@ -102,7 +102,7 @@ Error ImageLoaderJPG::load_image(Image *p_image, FileAccess *f) {
 
 	f->close();
 
-	Error err = jpeg_load_image_from_buffer(p_image, w.ptr(), src_image_len);
+	Error err = jpeg_load_image_from_buffer(p_image.ptr(), w.ptr(), src_image_len);
 
 	w = PoolVector<uint8_t>::Write();
 
@@ -115,10 +115,11 @@ void ImageLoaderJPG::get_recognized_extensions(List<String> *p_extensions) const
 	p_extensions->push_back("jpeg");
 }
 
-static Image _jpegd_mem_loader_func(const uint8_t *p_png, int p_size) {
+static Ref<Image> _jpegd_mem_loader_func(const uint8_t *p_png, int p_size) {
 
-	Image img;
-	Error err = jpeg_load_image_from_buffer(&img, p_png, p_size);
+	Ref<Image> img;
+	img.instance();
+	Error err = jpeg_load_image_from_buffer(img.ptr(), p_png, p_size);
 	if (err)
 		ERR_PRINT("Couldn't initialize ImageLoaderJPG with the given resource.");
 

+ 1 - 1
modules/jpg/image_loader_jpegd.h

@@ -38,7 +38,7 @@
 class ImageLoaderJPG : public ImageFormatLoader {
 
 public:
-	virtual Error load_image(Image *p_image, FileAccess *f);
+	virtual Error load_image(Ref<Image> p_image, FileAccess *f);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	ImageLoaderJPG();
 };

+ 22 - 21
modules/pvr/texture_loader_pvr.cpp

@@ -164,8 +164,8 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path,
 
 	print_line("flip: " + itos(flags & PVR_VFLIP));
 
-	Image image(width, height, mipmaps, format, data);
-	ERR_FAIL_COND_V(image.empty(), RES());
+	Ref<Image> image = memnew(Image(width, height, mipmaps, format, data));
+	ERR_FAIL_COND_V(image->empty(), RES());
 
 	Ref<ImageTexture> texture = memnew(ImageTexture);
 	texture->create_from_image(image, tex_flags);
@@ -193,30 +193,32 @@ String ResourceFormatPVR::get_resource_type(const String &p_path) const {
 
 static void _compress_pvrtc4(Image *p_img) {
 
-	Image img = *p_img;
+	Ref<Image> img = p_img->duplicate();
 
 	bool make_mipmaps = false;
-	if (img.get_width() % 8 || img.get_height() % 8) {
-		make_mipmaps = img.has_mipmaps();
-		img.resize(img.get_width() + (8 - (img.get_width() % 8)), img.get_height() + (8 - (img.get_height() % 8)));
+	if (img->get_width() % 8 || img->get_height() % 8) {
+		make_mipmaps = img->has_mipmaps();
+		img->resize(img->get_width() + (8 - (img->get_width() % 8)), img->get_height() + (8 - (img->get_height() % 8)));
 	}
-	img.convert(Image::FORMAT_RGBA8);
-	if (!img.has_mipmaps() && make_mipmaps)
-		img.generate_mipmaps();
+	img->convert(Image::FORMAT_RGBA8);
+	if (!img->has_mipmaps() && make_mipmaps)
+		img->generate_mipmaps();
 
-	bool use_alpha = img.detect_alpha();
+	bool use_alpha = img->detect_alpha();
 
-	Image new_img;
-	new_img.create(img.get_width(), img.get_height(), true, use_alpha ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4);
-	PoolVector<uint8_t> data = new_img.get_data();
+	Ref<Image> new_img;
+	new_img.instance();
+	new_img->create(img->get_width(), img->get_height(), true, use_alpha ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4);
+
+	PoolVector<uint8_t> data = new_img->get_data();
 	{
 		PoolVector<uint8_t>::Write wr = data.write();
-		PoolVector<uint8_t>::Read r = img.get_data().read();
+		PoolVector<uint8_t>::Read r = img->get_data().read();
 
-		for (int i = 0; i <= new_img.get_mipmap_count(); i++) {
+		for (int i = 0; i <= new_img->get_mipmap_count(); i++) {
 
 			int ofs, size, w, h;
-			img.get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h);
+			img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h);
 			Javelin::RgbaBitmap bm(w, h);
 			copymem(bm.GetData(), &r[ofs], size);
 			{
@@ -226,12 +228,12 @@ static void _compress_pvrtc4(Image *p_img) {
 				}
 			}
 
-			new_img.get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h);
+			new_img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h);
 			Javelin::PvrTcEncoder::EncodeRgba4Bpp(&wr[ofs], bm);
 		}
 	}
 
-	*p_img = Image(new_img.get_width(), new_img.get_height(), new_img.has_mipmaps(), new_img.get_format(), data);
+	p_img->create(new_img->get_width(), new_img->get_height(), new_img->has_mipmaps(), new_img->get_format(), data);
 }
 
 ResourceFormatPVR::ResourceFormatPVR() {
@@ -676,8 +678,7 @@ static void _pvrtc_decompress(Image *p_img) {
 	r = PoolVector<uint8_t>::Read();
 
 	bool make_mipmaps = p_img->has_mipmaps();
-	Image newimg(p_img->get_width(), p_img->get_height(), false, Image::FORMAT_RGBA8, newdata);
+	p_img->create(p_img->get_width(), p_img->get_height(), false, Image::FORMAT_RGBA8, newdata);
 	if (make_mipmaps)
-		newimg.generate_mipmaps();
-	*p_img = newimg;
+		p_img->generate_mipmaps();
 }

+ 1 - 1
modules/theora/video_stream_theora.cpp

@@ -138,7 +138,7 @@ void VideoStreamPlaybackTheora::video_write(void) {
 		format = Image::FORMAT_RGBA8;
 	}
 
-	Image img(size.x, size.y, 0, Image::FORMAT_RGBA8, frame_data); //zero copy image creation
+	Ref<Image> img = memnew(Image(size.x, size.y, 0, Image::FORMAT_RGBA8, frame_data)); //zero copy image creation
 
 	texture->set_data(img); //zero copy send to visual server
 

+ 0 - 3
modules/visual_script/visual_script_editor.cpp

@@ -346,7 +346,6 @@ static Color _color_from_type(Variant::Type p_type) {
 		case Variant::TRANSFORM: color = Color::html("f6a86e"); break;
 
 		case Variant::COLOR: color = Color::html("9dff70"); break;
-		case Variant::IMAGE: color = Color::html("93f1b9"); break;
 		case Variant::NODE_PATH: color = Color::html("6993ec"); break;
 		case Variant::_RID: color = Color::html("69ec9a"); break;
 		case Variant::OBJECT: color = Color::html("79f3e8"); break;
@@ -451,7 +450,6 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
 		Control::get_icon("MiniBasis", "EditorIcons"),
 		Control::get_icon("MiniTransform", "EditorIcons"),
 		Control::get_icon("MiniColor", "EditorIcons"),
-		Control::get_icon("MiniImage", "EditorIcons"),
 		Control::get_icon("MiniPath", "EditorIcons"),
 		Control::get_icon("MiniRid", "EditorIcons"),
 		Control::get_icon("MiniObject", "EditorIcons"),
@@ -735,7 +733,6 @@ void VisualScriptEditor::_update_members() {
 		Control::get_icon("MiniMatrix3", "EditorIcons"),
 		Control::get_icon("MiniTransform", "EditorIcons"),
 		Control::get_icon("MiniColor", "EditorIcons"),
-		Control::get_icon("MiniImage", "EditorIcons"),
 		Control::get_icon("MiniPath", "EditorIcons"),
 		Control::get_icon("MiniRid", "EditorIcons"),
 		Control::get_icon("MiniObject", "EditorIcons"),

+ 18 - 17
modules/webp/image_loader_webp.cpp

@@ -37,23 +37,23 @@
 #include <webp/decode.h>
 #include <webp/encode.h>
 
-static PoolVector<uint8_t> _webp_lossy_pack(const Image &p_image, float p_quality) {
+static PoolVector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality) {
 
-	ERR_FAIL_COND_V(p_image.empty(), PoolVector<uint8_t>());
+	ERR_FAIL_COND_V(p_image.is_null() || p_image->empty(), PoolVector<uint8_t>());
 
-	Image img = p_image;
-	if (img.detect_alpha())
-		img.convert(Image::FORMAT_RGBA8);
+	Ref<Image> img = p_image->duplicate();
+	if (img->detect_alpha())
+		img->convert(Image::FORMAT_RGBA8);
 	else
-		img.convert(Image::FORMAT_RGB8);
+		img->convert(Image::FORMAT_RGB8);
 
-	Size2 s(img.get_width(), img.get_height());
-	PoolVector<uint8_t> data = img.get_data();
+	Size2 s(img->get_width(), img->get_height());
+	PoolVector<uint8_t> data = img->get_data();
 	PoolVector<uint8_t>::Read r = data.read();
 
 	uint8_t *dst_buff = NULL;
 	size_t dst_size = 0;
-	if (img.get_format() == Image::FORMAT_RGB8) {
+	if (img->get_format() == Image::FORMAT_RGB8) {
 
 		dst_size = WebPEncodeRGB(r.ptr(), s.width, s.height, 3 * s.width, CLAMP(p_quality * 100.0, 0, 100.0), &dst_buff);
 	} else {
@@ -74,17 +74,17 @@ static PoolVector<uint8_t> _webp_lossy_pack(const Image &p_image, float p_qualit
 	return dst;
 }
 
-static Image _webp_lossy_unpack(const PoolVector<uint8_t> &p_buffer) {
+static Ref<Image> _webp_lossy_unpack(const PoolVector<uint8_t> &p_buffer) {
 
 	int size = p_buffer.size() - 4;
-	ERR_FAIL_COND_V(size <= 0, Image());
+	ERR_FAIL_COND_V(size <= 0, Ref<Image>());
 	PoolVector<uint8_t>::Read r = p_buffer.read();
 
-	ERR_FAIL_COND_V(r[0] != 'W' || r[1] != 'E' || r[2] != 'B' || r[3] != 'P', Image());
+	ERR_FAIL_COND_V(r[0] != 'W' || r[1] != 'E' || r[2] != 'B' || r[3] != 'P', Ref<Image>());
 	WebPBitstreamFeatures features;
 	if (WebPGetFeatures(&r[4], size, &features) != VP8_STATUS_OK) {
 		ERR_EXPLAIN("Error unpacking WEBP image:");
-		ERR_FAIL_V(Image());
+		ERR_FAIL_V(Ref<Image>());
 	}
 
 	/*
@@ -107,14 +107,15 @@ static Image _webp_lossy_unpack(const PoolVector<uint8_t> &p_buffer) {
 	}
 
 	//ERR_EXPLAIN("Error decoding webp! - "+p_file);
-	ERR_FAIL_COND_V(errdec, Image());
+	ERR_FAIL_COND_V(errdec, Ref<Image>());
 
 	dst_w = PoolVector<uint8_t>::Write();
 
-	return Image(features.width, features.height, 0, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image);
+	Ref<Image> img = memnew(Image(features.width, features.height, 0, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image));
+	return img;
 }
 
-Error ImageLoaderWEBP::load_image(Image *p_image, FileAccess *f) {
+Error ImageLoaderWEBP::load_image(Ref<Image> p_image, FileAccess *f) {
 
 	uint32_t size = f->get_len();
 	PoolVector<uint8_t> src_image;
@@ -160,7 +161,7 @@ Error ImageLoaderWEBP::load_image(Image *p_image, FileAccess *f) {
 	src_r = PoolVector<uint8_t>::Read();
 	dst_w = PoolVector<uint8_t>::Write();
 
-	*p_image = Image(features.width, features.height, 0, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image);
+	p_image->create(features.width, features.height, 0, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image);
 
 	return OK;
 }

+ 1 - 1
modules/webp/image_loader_webp.h

@@ -38,7 +38,7 @@
 class ImageLoaderWEBP : public ImageFormatLoader {
 
 public:
-	virtual Error load_image(Image *p_image, FileAccess *f);
+	virtual Error load_image(Ref<Image> p_image, FileAccess *f);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	ImageLoaderWEBP();
 };

+ 1 - 1
platform/android/export/export.cpp

@@ -3523,7 +3523,7 @@ public:
 
 	EditorExportAndroid() {
 
-		Image img(_android_logo);
+		Ref<Image> img = memnew(Image(_android_logo));
 		logo = Ref<ImageTexture>(memnew(ImageTexture));
 		logo->create_from_image(img);
 

+ 1 - 1
platform/javascript/export/export.cpp

@@ -316,7 +316,7 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese
 
 EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
 
-	Image img(_javascript_logo);
+	Ref<Image> img = memnew(Image(_javascript_logo));
 	logo.instance();
 	logo->create_from_image(img);
 }

+ 1 - 1
platform/osx/os_osx.h

@@ -151,7 +151,7 @@ public:
 
 	virtual Size2 get_window_size() const;
 
-	virtual void set_icon(const Image &p_icon);
+	virtual void set_icon(const Ref<Image> &p_icon);
 
 	virtual MainLoop *get_main_loop() const;
 

+ 10 - 9
platform/osx/os_osx.mm

@@ -1227,26 +1227,27 @@ void OS_OSX::set_window_title(const String &p_title) {
 	[window_object setTitle:[NSString stringWithUTF8String:p_title.utf8().get_data()]];
 }
 
-void OS_OSX::set_icon(const Image &p_icon) {
+void OS_OSX::set_icon(const Ref<Image> &p_icon) {
 
-	Image img = p_icon;
-	img.convert(Image::FORMAT_RGBA8);
+	Ref<Image> img = p_icon;
+	img = img->duplicate();
+	img->convert(Image::FORMAT_RGBA8);
 	NSBitmapImageRep *imgrep = [[[NSBitmapImageRep alloc]
 			initWithBitmapDataPlanes:NULL
-						  pixelsWide:p_icon.get_width()
-						  pixelsHigh:p_icon.get_height()
+						  pixelsWide:img->get_width()
+						  pixelsHigh:img->get_height()
 					   bitsPerSample:8
 					 samplesPerPixel:4
 							hasAlpha:YES
 							isPlanar:NO
 					  colorSpaceName:NSDeviceRGBColorSpace
-						 bytesPerRow:p_icon.get_width() * 4
+						 bytesPerRow:img->get_width() * 4
 						bitsPerPixel:32] autorelease];
 	ERR_FAIL_COND(imgrep == nil);
 	uint8_t *pixels = [imgrep bitmapData];
 
-	int len = img.get_width() * img.get_height();
-	PoolVector<uint8_t> data = img.get_data();
+	int len = img->get_width() * img->get_height();
+	PoolVector<uint8_t> data = img->get_data();
 	PoolVector<uint8_t>::Read r = data.read();
 
 	/* Premultiply the alpha channel */
@@ -1258,7 +1259,7 @@ void OS_OSX::set_icon(const Image &p_icon) {
 		pixels[i * 4 + 3] = alpha;
 	}
 
-	NSImage *nsimg = [[[NSImage alloc] initWithSize:NSMakeSize(img.get_width(), img.get_height())] autorelease];
+	NSImage *nsimg = [[[NSImage alloc] initWithSize:NSMakeSize(img->get_width(), img->get_height())] autorelease];
 	ERR_FAIL_COND(nsimg == nil);
 	[nsimg addRepresentation:imgrep];
 

+ 1 - 1
platform/uwp/os_uwp.cpp

@@ -746,7 +746,7 @@ String OSUWP::get_executable_path() const {
 	return "";
 }
 
-void OSUWP::set_icon(const Image &p_icon) {
+void OSUWP::set_icon(const Ref<Image> &p_icon) {
 }
 
 bool OSUWP::has_environment(const String &p_var) const {

+ 1 - 1
platform/uwp/os_uwp.h

@@ -227,7 +227,7 @@ public:
 	virtual String get_clipboard() const;
 
 	void set_cursor_shape(CursorShape p_shape);
-	void set_icon(const Image &p_icon);
+	void set_icon(const Ref<Image> &p_icon);
 
 	virtual String get_executable_path() const;
 

+ 1 - 1
platform/windows/export/export.cpp

@@ -35,7 +35,7 @@ void register_windows_exporter() {
 	Ref<EditorExportPlatformPC> platform;
 	platform.instance();
 
-	Image img(_windows_logo);
+	Ref<Image> img = memnew(Image(_windows_logo));
 	Ref<ImageTexture> logo;
 	logo.instance();
 	logo->create_from_image(img);

+ 8 - 7
platform/windows/os_windows.cpp

@@ -1996,13 +1996,14 @@ String OS_Windows::get_executable_path() const {
 	return s;
 }
 
-void OS_Windows::set_icon(const Image &p_icon) {
+void OS_Windows::set_icon(const Ref<Image> &p_icon) {
 
-	Image icon = p_icon;
-	if (icon.get_format() != Image::FORMAT_RGBA8)
-		icon.convert(Image::FORMAT_RGBA8);
-	int w = icon.get_width();
-	int h = icon.get_height();
+	ERR_FAIL_COND(!p_icon.is_valid());
+	Ref<Image> icon = p_icon->duplicate();
+	if (icon->get_format() != Image::FORMAT_RGBA8)
+		icon->convert(Image::FORMAT_RGBA8);
+	int w = icon->get_width();
+	int h = icon->get_height();
 
 	/* Create temporary bitmap buffer */
 	int icon_len = 40 + h * w * 4;
@@ -2023,7 +2024,7 @@ void OS_Windows::set_icon(const Image &p_icon) {
 	encode_uint32(0, &icon_bmp[36]);
 
 	uint8_t *wr = &icon_bmp[40];
-	PoolVector<uint8_t>::Read r = icon.get_data().read();
+	PoolVector<uint8_t>::Read r = icon->get_data().read();
 
 	for (int i = 0; i < h; i++) {
 

+ 1 - 1
platform/windows/os_windows.h

@@ -254,7 +254,7 @@ public:
 	virtual String get_clipboard() const;
 
 	void set_cursor_shape(CursorShape p_shape);
-	void set_icon(const Image &p_icon);
+	void set_icon(const Ref<Image> &p_icon);
 
 	virtual String get_executable_path() const;
 

+ 1 - 1
platform/x11/export/export.cpp

@@ -37,7 +37,7 @@ void register_x11_exporter() {
 	Ref<EditorExportPlatformPC> platform;
 	platform.instance();
 
-	Image img(_x11_logo);
+	Ref<Image> img = memnew(Image(_x11_logo));
 	Ref<ImageTexture> logo;
 	logo.instance();
 	logo->create_from_image(img);

+ 7 - 7
platform/x11/os_x11.cpp

@@ -1857,15 +1857,15 @@ void OS_X11::alert(const String &p_alert, const String &p_title) {
 	execute("/usr/bin/xmessage", args, true);
 }
 
-void OS_X11::set_icon(const Image &p_icon) {
+void OS_X11::set_icon(const Ref<Image> &p_icon) {
 	Atom net_wm_icon = XInternAtom(x11_display, "_NET_WM_ICON", False);
 
-	if (!p_icon.empty()) {
-		Image img = p_icon;
-		img.convert(Image::FORMAT_RGBA8);
+	if (p_icon.is_valid()) {
+		Ref<Image> img = p_icon->duplicate();
+		img->convert(Image::FORMAT_RGBA8);
 
-		int w = img.get_width();
-		int h = img.get_height();
+		int w = img->get_width();
+		int h = img->get_height();
 
 		// We're using long to have wordsize (32Bit build -> 32 Bits, 64 Bit build -> 64 Bits
 		Vector<long> pd;
@@ -1875,7 +1875,7 @@ void OS_X11::set_icon(const Image &p_icon) {
 		pd[0] = w;
 		pd[1] = h;
 
-		PoolVector<uint8_t>::Read r = img.get_data().read();
+		PoolVector<uint8_t>::Read r = img->get_data().read();
 
 		long *wr = &pd[2];
 		uint8_t const *pr = r.ptr();

+ 1 - 1
platform/x11/os_x11.h

@@ -206,7 +206,7 @@ public:
 	virtual int get_mouse_button_state() const;
 	virtual void set_window_title(const String &p_title);
 
-	virtual void set_icon(const Image &p_icon);
+	virtual void set_icon(const Ref<Image> &p_icon);
 
 	virtual MainLoop *get_main_loop() const;
 

+ 0 - 1754
scene/3d/baked_light_instance.cpp

@@ -1,1754 +0,0 @@
-/*************************************************************************/
-/*  baked_light_instance.cpp                                             */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                    http://www.godotengine.org                         */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)    */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "baked_light_instance.h"
-#include "light.h"
-#include "math.h"
-#include "mesh_instance.h"
-#include "scene/scene_string_names.h"
-
-#define FINDMINMAX(x0, x1, x2, min, max) \
-	min = max = x0;                      \
-	if (x1 < min) min = x1;              \
-	if (x1 > max) max = x1;              \
-	if (x2 < min) min = x2;              \
-	if (x2 > max) max = x2;
-
-static bool planeBoxOverlap(Vector3 normal, float d, Vector3 maxbox) {
-	int q;
-	Vector3 vmin, vmax;
-	for (q = 0; q <= 2; q++) {
-		if (normal[q] > 0.0f) {
-			vmin[q] = -maxbox[q];
-			vmax[q] = maxbox[q];
-		} else {
-			vmin[q] = maxbox[q];
-			vmax[q] = -maxbox[q];
-		}
-	}
-	if (normal.dot(vmin) + d > 0.0f) return false;
-	if (normal.dot(vmax) + d >= 0.0f) return true;
-
-	return false;
-}
-
-/*======================== X-tests ========================*/
-#define AXISTEST_X01(a, b, fa, fb)                 \
-	p0 = a * v0.y - b * v0.z;                      \
-	p2 = a * v2.y - b * v2.z;                      \
-	if (p0 < p2) {                                 \
-		min = p0;                                  \
-		max = p2;                                  \
-	} else {                                       \
-		min = p2;                                  \
-		max = p0;                                  \
-	}                                              \
-	rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
-	if (min > rad || max < -rad) return false;
-
-#define AXISTEST_X2(a, b, fa, fb)                  \
-	p0 = a * v0.y - b * v0.z;                      \
-	p1 = a * v1.y - b * v1.z;                      \
-	if (p0 < p1) {                                 \
-		min = p0;                                  \
-		max = p1;                                  \
-	} else {                                       \
-		min = p1;                                  \
-		max = p0;                                  \
-	}                                              \
-	rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
-	if (min > rad || max < -rad) return false;
-
-/*======================== Y-tests ========================*/
-#define AXISTEST_Y02(a, b, fa, fb)                 \
-	p0 = -a * v0.x + b * v0.z;                     \
-	p2 = -a * v2.x + b * v2.z;                     \
-	if (p0 < p2) {                                 \
-		min = p0;                                  \
-		max = p2;                                  \
-	} else {                                       \
-		min = p2;                                  \
-		max = p0;                                  \
-	}                                              \
-	rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
-	if (min > rad || max < -rad) return false;
-
-#define AXISTEST_Y1(a, b, fa, fb)                  \
-	p0 = -a * v0.x + b * v0.z;                     \
-	p1 = -a * v1.x + b * v1.z;                     \
-	if (p0 < p1) {                                 \
-		min = p0;                                  \
-		max = p1;                                  \
-	} else {                                       \
-		min = p1;                                  \
-		max = p0;                                  \
-	}                                              \
-	rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
-	if (min > rad || max < -rad) return false;
-
-/*======================== Z-tests ========================*/
-
-#define AXISTEST_Z12(a, b, fa, fb)                 \
-	p1 = a * v1.x - b * v1.y;                      \
-	p2 = a * v2.x - b * v2.y;                      \
-	if (p2 < p1) {                                 \
-		min = p2;                                  \
-		max = p1;                                  \
-	} else {                                       \
-		min = p1;                                  \
-		max = p2;                                  \
-	}                                              \
-	rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
-	if (min > rad || max < -rad) return false;
-
-#define AXISTEST_Z0(a, b, fa, fb)                  \
-	p0 = a * v0.x - b * v0.y;                      \
-	p1 = a * v1.x - b * v1.y;                      \
-	if (p0 < p1) {                                 \
-		min = p0;                                  \
-		max = p1;                                  \
-	} else {                                       \
-		min = p1;                                  \
-		max = p0;                                  \
-	}                                              \
-	rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
-	if (min > rad || max < -rad) return false;
-
-static bool fast_tri_box_overlap(const Vector3 &boxcenter, const Vector3 boxhalfsize, const Vector3 *triverts) {
-
-	/*    use separating axis theorem to test overlap between triangle and box */
-	/*    need to test for overlap in these directions: */
-	/*    1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */
-	/*       we do not even need to test these) */
-	/*    2) normal of the triangle */
-	/*    3) crossproduct(edge from tri, {x,y,z}-directin) */
-	/*       this gives 3x3=9 more tests */
-	Vector3 v0, v1, v2;
-	float min, max, d, p0, p1, p2, rad, fex, fey, fez;
-	Vector3 normal, e0, e1, e2;
-
-	/* This is the fastest branch on Sun */
-	/* move everything so that the boxcenter is in (0,0,0) */
-
-	v0 = triverts[0] - boxcenter;
-	v1 = triverts[1] - boxcenter;
-	v2 = triverts[2] - boxcenter;
-
-	/* compute triangle edges */
-	e0 = v1 - v0; /* tri edge 0 */
-	e1 = v2 - v1; /* tri edge 1 */
-	e2 = v0 - v2; /* tri edge 2 */
-
-	/* Bullet 3:  */
-	/*  test the 9 tests first (this was faster) */
-	fex = Math::abs(e0.x);
-	fey = Math::abs(e0.y);
-	fez = Math::abs(e0.z);
-	AXISTEST_X01(e0.z, e0.y, fez, fey);
-	AXISTEST_Y02(e0.z, e0.x, fez, fex);
-	AXISTEST_Z12(e0.y, e0.x, fey, fex);
-
-	fex = Math::abs(e1.x);
-	fey = Math::abs(e1.y);
-	fez = Math::abs(e1.z);
-	AXISTEST_X01(e1.z, e1.y, fez, fey);
-	AXISTEST_Y02(e1.z, e1.x, fez, fex);
-	AXISTEST_Z0(e1.y, e1.x, fey, fex);
-
-	fex = Math::abs(e2.x);
-	fey = Math::abs(e2.y);
-	fez = Math::abs(e2.z);
-	AXISTEST_X2(e2.z, e2.y, fez, fey);
-	AXISTEST_Y1(e2.z, e2.x, fez, fex);
-	AXISTEST_Z12(e2.y, e2.x, fey, fex);
-
-	/* Bullet 1: */
-	/*  first test overlap in the {x,y,z}-directions */
-	/*  find min, max of the triangle each direction, and test for overlap in */
-	/*  that direction -- this is equivalent to testing a minimal AABB around */
-	/*  the triangle against the AABB */
-
-	/* test in X-direction */
-	FINDMINMAX(v0.x, v1.x, v2.x, min, max);
-	if (min > boxhalfsize.x || max < -boxhalfsize.x) return false;
-
-	/* test in Y-direction */
-	FINDMINMAX(v0.y, v1.y, v2.y, min, max);
-	if (min > boxhalfsize.y || max < -boxhalfsize.y) return false;
-
-	/* test in Z-direction */
-	FINDMINMAX(v0.z, v1.z, v2.z, min, max);
-	if (min > boxhalfsize.z || max < -boxhalfsize.z) return false;
-
-	/* Bullet 2: */
-	/*  test if the box intersects the plane of the triangle */
-	/*  compute plane equation of triangle: normal*x+d=0 */
-	normal = e0.cross(e1);
-	d = -normal.dot(v0); /* plane eq: normal.x+d=0 */
-	if (!planeBoxOverlap(normal, d, boxhalfsize)) return false;
-
-	return true; /* box and triangle overlaps */
-}
-
-Vector<Color> BakedLight::_get_bake_texture(Image &p_image, const Color &p_color) {
-
-	Vector<Color> ret;
-
-	if (p_image.empty()) {
-
-		ret.resize(bake_texture_size * bake_texture_size);
-		for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
-			ret[i] = p_color;
-		}
-
-		return ret;
-	}
-
-	p_image.convert(Image::FORMAT_RGBA8);
-	p_image.resize(bake_texture_size, bake_texture_size, Image::INTERPOLATE_CUBIC);
-
-	PoolVector<uint8_t>::Read r = p_image.get_data().read();
-	ret.resize(bake_texture_size * bake_texture_size);
-
-	for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
-		Color c;
-		c.r = r[i * 4 + 0] / 255.0;
-		c.g = r[i * 4 + 1] / 255.0;
-		c.b = r[i * 4 + 2] / 255.0;
-		c.a = r[i * 4 + 3] / 255.0;
-		ret[i] = c;
-	}
-
-	return ret;
-}
-
-BakedLight::MaterialCache BakedLight::_get_material_cache(Ref<Material> p_material) {
-
-	//this way of obtaining materials is inaccurate and also does not support some compressed formats very well
-	Ref<SpatialMaterial> mat = p_material;
-
-	Ref<Material> material = mat; //hack for now
-
-	if (material_cache.has(material)) {
-		return material_cache[material];
-	}
-
-	MaterialCache mc;
-
-	if (mat.is_valid()) {
-
-		Ref<ImageTexture> albedo_tex = mat->get_texture(SpatialMaterial::TEXTURE_ALBEDO);
-
-		Image img_albedo;
-		if (albedo_tex.is_valid()) {
-
-			img_albedo = albedo_tex->get_data();
-		}
-
-		mc.albedo = _get_bake_texture(img_albedo, mat->get_albedo());
-
-		Ref<ImageTexture> emission_tex = mat->get_texture(SpatialMaterial::TEXTURE_EMISSION);
-
-		Color emission_col = mat->get_emission();
-		emission_col.r *= mat->get_emission_energy();
-		emission_col.g *= mat->get_emission_energy();
-		emission_col.b *= mat->get_emission_energy();
-
-		Image img_emission;
-
-		if (emission_tex.is_valid()) {
-
-			img_emission = emission_tex->get_data();
-		}
-
-		mc.emission = _get_bake_texture(img_emission, emission_col);
-
-	} else {
-		Image empty;
-
-		mc.albedo = _get_bake_texture(empty, Color(0.7, 0.7, 0.7));
-		mc.emission = _get_bake_texture(empty, Color(0, 0, 0));
-	}
-
-	material_cache[p_material] = mc;
-	return mc;
-}
-
-static _FORCE_INLINE_ Vector2 get_uv(const Vector3 &p_pos, const Vector3 *p_vtx, const Vector2 *p_uv) {
-
-	if (p_pos.distance_squared_to(p_vtx[0]) < CMP_EPSILON2)
-		return p_uv[0];
-	if (p_pos.distance_squared_to(p_vtx[1]) < CMP_EPSILON2)
-		return p_uv[1];
-	if (p_pos.distance_squared_to(p_vtx[2]) < CMP_EPSILON2)
-		return p_uv[2];
-
-	Vector3 v0 = p_vtx[1] - p_vtx[0];
-	Vector3 v1 = p_vtx[2] - p_vtx[0];
-	Vector3 v2 = p_pos - p_vtx[0];
-
-	float d00 = v0.dot(v0);
-	float d01 = v0.dot(v1);
-	float d11 = v1.dot(v1);
-	float d20 = v2.dot(v0);
-	float d21 = v2.dot(v1);
-	float denom = (d00 * d11 - d01 * d01);
-	if (denom == 0)
-		return p_uv[0];
-	float v = (d11 * d20 - d01 * d21) / denom;
-	float w = (d00 * d21 - d01 * d20) / denom;
-	float u = 1.0f - v - w;
-
-	return p_uv[0] * u + p_uv[1] * v + p_uv[2] * w;
-}
-
-void BakedLight::_plot_face(int p_idx, int p_level, const Vector3 *p_vtx, const Vector2 *p_uv, const MaterialCache &p_material, const Rect3 &p_aabb) {
-
-	if (p_level == cell_subdiv - 1) {
-		//plot the face by guessing it's albedo and emission value
-
-		//find best axis to map to, for scanning values
-		int closest_axis;
-		float closest_dot;
-
-		Vector3 normal = Plane(p_vtx[0], p_vtx[1], p_vtx[2]).normal;
-
-		for (int i = 0; i < 3; i++) {
-
-			Vector3 axis;
-			axis[i] = 1.0;
-			float dot = ABS(normal.dot(axis));
-			if (i == 0 || dot > closest_dot) {
-				closest_axis = i;
-				closest_dot = dot;
-			}
-		}
-
-		Vector3 axis;
-		axis[closest_axis] = 1.0;
-		Vector3 t1;
-		t1[(closest_axis + 1) % 3] = 1.0;
-		Vector3 t2;
-		t2[(closest_axis + 2) % 3] = 1.0;
-
-		t1 *= p_aabb.size[(closest_axis + 1) % 3] / float(color_scan_cell_width);
-		t2 *= p_aabb.size[(closest_axis + 2) % 3] / float(color_scan_cell_width);
-
-		Color albedo_accum;
-		Color emission_accum;
-		float alpha = 0.0;
-
-		//map to a grid average in the best axis for this face
-		for (int i = 0; i < color_scan_cell_width; i++) {
-
-			Vector3 ofs_i = float(i) * t1;
-
-			for (int j = 0; j < color_scan_cell_width; j++) {
-
-				Vector3 ofs_j = float(j) * t2;
-
-				Vector3 from = p_aabb.pos + ofs_i + ofs_j;
-				Vector3 to = from + t1 + t2 + axis * p_aabb.size[closest_axis];
-				Vector3 half = (to - from) * 0.5;
-
-				//is in this cell?
-				if (!fast_tri_box_overlap(from + half, half, p_vtx)) {
-					continue; //face does not span this cell
-				}
-
-				//go from -size to +size*2 to avoid skipping collisions
-				Vector3 ray_from = from + (t1 + t2) * 0.5 - axis * p_aabb.size[closest_axis];
-				Vector3 ray_to = ray_from + axis * p_aabb.size[closest_axis] * 2;
-
-				Vector3 intersection;
-
-				if (!Geometry::ray_intersects_triangle(ray_from, ray_to, p_vtx[0], p_vtx[1], p_vtx[2], &intersection)) {
-					//no intersect? look in edges
-
-					float closest_dist = 1e20;
-					for (int j = 0; j < 3; j++) {
-						Vector3 c;
-						Vector3 inters;
-						Geometry::get_closest_points_between_segments(p_vtx[j], p_vtx[(j + 1) % 3], ray_from, ray_to, inters, c);
-						float d = c.distance_to(intersection);
-						if (j == 0 || d < closest_dist) {
-							closest_dist = d;
-							intersection = inters;
-						}
-					}
-				}
-
-				Vector2 uv = get_uv(intersection, p_vtx, p_uv);
-
-				int uv_x = CLAMP(Math::fposmod(uv.x, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
-				int uv_y = CLAMP(Math::fposmod(uv.y, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
-
-				int ofs = uv_y * bake_texture_size + uv_x;
-				albedo_accum.r += p_material.albedo[ofs].r;
-				albedo_accum.g += p_material.albedo[ofs].g;
-				albedo_accum.b += p_material.albedo[ofs].b;
-				albedo_accum.a += p_material.albedo[ofs].a;
-
-				emission_accum.r += p_material.emission[ofs].r;
-				emission_accum.g += p_material.emission[ofs].g;
-				emission_accum.b += p_material.emission[ofs].b;
-				alpha += 1.0;
-			}
-		}
-
-		if (alpha == 0) {
-			//could not in any way get texture information.. so use closest point to center
-
-			Face3 f(p_vtx[0], p_vtx[1], p_vtx[2]);
-			Vector3 inters = f.get_closest_point_to(p_aabb.pos + p_aabb.size * 0.5);
-
-			Vector2 uv = get_uv(inters, p_vtx, p_uv);
-
-			int uv_x = CLAMP(Math::fposmod(uv.x, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
-			int uv_y = CLAMP(Math::fposmod(uv.y, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
-
-			int ofs = uv_y * bake_texture_size + uv_x;
-
-			alpha = 1.0 / (color_scan_cell_width * color_scan_cell_width);
-
-			albedo_accum.r = p_material.albedo[ofs].r * alpha;
-			albedo_accum.g = p_material.albedo[ofs].g * alpha;
-			albedo_accum.b = p_material.albedo[ofs].b * alpha;
-			albedo_accum.a = p_material.albedo[ofs].a * alpha;
-
-			emission_accum.r = p_material.emission[ofs].r * alpha;
-			emission_accum.g = p_material.emission[ofs].g * alpha;
-			emission_accum.b = p_material.emission[ofs].b * alpha;
-
-			zero_alphas++;
-		} else {
-
-			float accdiv = 1.0 / (color_scan_cell_width * color_scan_cell_width);
-			alpha *= accdiv;
-
-			albedo_accum.r *= accdiv;
-			albedo_accum.g *= accdiv;
-			albedo_accum.b *= accdiv;
-			albedo_accum.a *= accdiv;
-
-			emission_accum.r *= accdiv;
-			emission_accum.g *= accdiv;
-			emission_accum.b *= accdiv;
-		}
-
-		//put this temporarily here, corrected in a later step
-		bake_cells_write[p_idx].albedo[0] += albedo_accum.r;
-		bake_cells_write[p_idx].albedo[1] += albedo_accum.g;
-		bake_cells_write[p_idx].albedo[2] += albedo_accum.b;
-		bake_cells_write[p_idx].light[0] += emission_accum.r;
-		bake_cells_write[p_idx].light[1] += emission_accum.g;
-		bake_cells_write[p_idx].light[2] += emission_accum.b;
-		bake_cells_write[p_idx].alpha += alpha;
-
-		static const Vector3 side_normals[6] = {
-			Vector3(-1, 0, 0),
-			Vector3(1, 0, 0),
-			Vector3(0, -1, 0),
-			Vector3(0, 1, 0),
-			Vector3(0, 0, -1),
-			Vector3(0, 0, 1),
-		};
-
-		for (int i = 0; i < 6; i++) {
-			if (normal.dot(side_normals[i]) > CMP_EPSILON) {
-				bake_cells_write[p_idx].used_sides |= (1 << i);
-			}
-		}
-
-	} else {
-		//go down
-		for (int i = 0; i < 8; i++) {
-
-			Rect3 aabb = p_aabb;
-			aabb.size *= 0.5;
-
-			if (i & 1)
-				aabb.pos.x += aabb.size.x;
-			if (i & 2)
-				aabb.pos.y += aabb.size.y;
-			if (i & 4)
-				aabb.pos.z += aabb.size.z;
-
-			{
-				Rect3 test_aabb = aabb;
-				//test_aabb.grow_by(test_aabb.get_longest_axis_size()*0.05); //grow a bit to avoid numerical error in real-time
-				Vector3 qsize = test_aabb.size * 0.5; //quarter size, for fast aabb test
-
-				if (!fast_tri_box_overlap(test_aabb.pos + qsize, qsize, p_vtx)) {
-					//if (!Face3(p_vtx[0],p_vtx[1],p_vtx[2]).intersects_aabb2(aabb)) {
-					//does not fit in child, go on
-					continue;
-				}
-			}
-
-			if (bake_cells_write[p_idx].childs[i] == CHILD_EMPTY) {
-				//sub cell must be created
-
-				if (bake_cells_used == (1 << bake_cells_alloc)) {
-					//exhausted cells, creating more space
-					bake_cells_alloc++;
-					bake_cells_write = PoolVector<BakeCell>::Write();
-					bake_cells.resize(1 << bake_cells_alloc);
-					bake_cells_write = bake_cells.write();
-				}
-
-				bake_cells_write[p_idx].childs[i] = bake_cells_used;
-				bake_cells_level_used[p_level + 1]++;
-				bake_cells_used++;
-			}
-
-			_plot_face(bake_cells_write[p_idx].childs[i], p_level + 1, p_vtx, p_uv, p_material, aabb);
-		}
-	}
-}
-
-void BakedLight::_fixup_plot(int p_idx, int p_level, int p_x, int p_y, int p_z) {
-
-	if (p_level == cell_subdiv - 1) {
-
-		float alpha = bake_cells_write[p_idx].alpha;
-
-		bake_cells_write[p_idx].albedo[0] /= alpha;
-		bake_cells_write[p_idx].albedo[1] /= alpha;
-		bake_cells_write[p_idx].albedo[2] /= alpha;
-
-		//transfer emission to light
-		bake_cells_write[p_idx].light[0] /= alpha;
-		bake_cells_write[p_idx].light[1] /= alpha;
-		bake_cells_write[p_idx].light[2] /= alpha;
-
-		bake_cells_write[p_idx].alpha = 1.0;
-
-		//remove neighbours from used sides
-
-		for (int n = 0; n < 6; n++) {
-
-			int ofs[3] = { 0, 0, 0 };
-
-			ofs[n / 2] = (n & 1) ? 1 : -1;
-
-			//convert to x,y,z on this level
-			int x = p_x;
-			int y = p_y;
-			int z = p_z;
-
-			x += ofs[0];
-			y += ofs[1];
-			z += ofs[2];
-
-			int ofs_x = 0;
-			int ofs_y = 0;
-			int ofs_z = 0;
-			int size = 1 << p_level;
-			int half = size / 2;
-
-			if (x < 0 || x >= size || y < 0 || y >= size || z < 0 || z >= size) {
-				//neighbour is out, can't use it
-				bake_cells_write[p_idx].used_sides &= ~(1 << uint32_t(n));
-				continue;
-			}
-
-			uint32_t neighbour = 0;
-
-			for (int i = 0; i < cell_subdiv - 1; i++) {
-
-				BakeCell *bc = &bake_cells_write[neighbour];
-
-				int child = 0;
-				if (x >= ofs_x + half) {
-					child |= 1;
-					ofs_x += half;
-				}
-				if (y >= ofs_y + half) {
-					child |= 2;
-					ofs_y += half;
-				}
-				if (z >= ofs_z + half) {
-					child |= 4;
-					ofs_z += half;
-				}
-
-				neighbour = bc->childs[child];
-				if (neighbour == CHILD_EMPTY) {
-					break;
-				}
-
-				half >>= 1;
-			}
-
-			if (neighbour != CHILD_EMPTY) {
-				bake_cells_write[p_idx].used_sides &= ~(1 << uint32_t(n));
-			}
-		}
-	} else {
-
-		//go down
-
-		float alpha_average = 0;
-		int half = cells_per_axis >> (p_level + 1);
-		for (int i = 0; i < 8; i++) {
-
-			uint32_t child = bake_cells_write[p_idx].childs[i];
-
-			if (child == CHILD_EMPTY)
-				continue;
-
-			int nx = p_x;
-			int ny = p_y;
-			int nz = p_z;
-
-			if (i & 1)
-				nx += half;
-			if (i & 2)
-				ny += half;
-			if (i & 4)
-				nz += half;
-
-			_fixup_plot(child, p_level + 1, nx, ny, nz);
-			alpha_average += bake_cells_write[child].alpha;
-		}
-
-		bake_cells_write[p_idx].alpha = alpha_average / 8.0;
-		bake_cells_write[p_idx].light[0] = 0;
-		bake_cells_write[p_idx].light[1] = 0;
-		bake_cells_write[p_idx].light[2] = 0;
-		bake_cells_write[p_idx].albedo[0] = 0;
-		bake_cells_write[p_idx].albedo[1] = 0;
-		bake_cells_write[p_idx].albedo[2] = 0;
-	}
-
-	//clean up light
-	bake_cells_write[p_idx].light_pass = 0;
-	//find neighbours
-}
-
-void BakedLight::_bake_add_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh) {
-
-	for (int i = 0; i < p_mesh->get_surface_count(); i++) {
-
-		if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES)
-			continue; //only triangles
-
-		MaterialCache material = _get_material_cache(p_mesh->surface_get_material(i));
-
-		Array a = p_mesh->surface_get_arrays(i);
-
-		PoolVector<Vector3> vertices = a[Mesh::ARRAY_VERTEX];
-		PoolVector<Vector3>::Read vr = vertices.read();
-		PoolVector<Vector2> uv = a[Mesh::ARRAY_TEX_UV];
-		PoolVector<Vector2>::Read uvr;
-		PoolVector<int> index = a[Mesh::ARRAY_INDEX];
-
-		bool read_uv = false;
-
-		if (uv.size()) {
-
-			uvr = uv.read();
-			read_uv = true;
-		}
-
-		if (index.size()) {
-
-			int facecount = index.size() / 3;
-			PoolVector<int>::Read ir = index.read();
-
-			for (int j = 0; j < facecount; j++) {
-
-				Vector3 vtxs[3];
-				Vector2 uvs[3];
-
-				for (int k = 0; k < 3; k++) {
-					vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]);
-				}
-
-				if (read_uv) {
-					for (int k = 0; k < 3; k++) {
-						uvs[k] = uvr[ir[j * 3 + k]];
-					}
-				}
-
-				//plot face
-				_plot_face(0, 0, vtxs, uvs, material, bounds);
-			}
-
-		} else {
-
-			int facecount = vertices.size() / 3;
-
-			for (int j = 0; j < facecount; j++) {
-
-				Vector3 vtxs[3];
-				Vector2 uvs[3];
-
-				for (int k = 0; k < 3; k++) {
-					vtxs[k] = p_xform.xform(vr[j * 3 + k]);
-				}
-
-				if (read_uv) {
-					for (int k = 0; k < 3; k++) {
-						uvs[k] = uvr[j * 3 + k];
-					}
-				}
-
-				//plot face
-				_plot_face(0, 0, vtxs, uvs, material, bounds);
-			}
-		}
-	}
-}
-
-void BakedLight::_bake_add_to_aabb(const Transform &p_xform, Ref<Mesh> &p_mesh, bool &first) {
-
-	for (int i = 0; i < p_mesh->get_surface_count(); i++) {
-
-		if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES)
-			continue; //only triangles
-
-		Array a = p_mesh->surface_get_arrays(i);
-		PoolVector<Vector3> vertices = a[Mesh::ARRAY_VERTEX];
-		int vc = vertices.size();
-		PoolVector<Vector3>::Read vr = vertices.read();
-
-		if (first) {
-			bounds.pos = p_xform.xform(vr[0]);
-			first = false;
-		}
-
-		for (int j = 0; j < vc; j++) {
-			bounds.expand_to(p_xform.xform(vr[j]));
-		}
-	}
-}
-
-void BakedLight::bake() {
-
-	bake_cells_alloc = 16;
-	bake_cells.resize(1 << bake_cells_alloc);
-	bake_cells_used = 1;
-	cells_per_axis = (1 << (cell_subdiv - 1));
-	zero_alphas = 0;
-
-	bool aabb_first = true;
-	print_line("Generating AABB");
-
-	bake_cells_level_used.resize(cell_subdiv);
-	for (int i = 0; i < cell_subdiv; i++) {
-		bake_cells_level_used[i] = 0;
-	}
-
-	int count = 0;
-	for (Set<GeometryInstance *>::Element *E = geometries.front(); E; E = E->next()) {
-
-		print_line("aabb geom " + itos(count) + "/" + itos(geometries.size()));
-
-		GeometryInstance *geom = E->get();
-
-		if (geom->cast_to<MeshInstance>()) {
-
-			MeshInstance *mesh_instance = geom->cast_to<MeshInstance>();
-			Ref<Mesh> mesh = mesh_instance->get_mesh();
-			if (mesh.is_valid()) {
-
-				_bake_add_to_aabb(geom->get_relative_transform(this), mesh, aabb_first);
-			}
-		}
-		count++;
-	}
-
-	print_line("AABB: " + bounds);
-	ERR_FAIL_COND(aabb_first);
-
-	bake_cells_write = bake_cells.write();
-	count = 0;
-
-	for (Set<GeometryInstance *>::Element *E = geometries.front(); E; E = E->next()) {
-
-		GeometryInstance *geom = E->get();
-		print_line("plot geom " + itos(count) + "/" + itos(geometries.size()));
-
-		if (geom->cast_to<MeshInstance>()) {
-
-			MeshInstance *mesh_instance = geom->cast_to<MeshInstance>();
-			Ref<Mesh> mesh = mesh_instance->get_mesh();
-			if (mesh.is_valid()) {
-
-				_bake_add_mesh(geom->get_relative_transform(this), mesh);
-			}
-		}
-
-		count++;
-	}
-
-	_fixup_plot(0, 0, 0, 0, 0);
-
-	bake_cells_write = PoolVector<BakeCell>::Write();
-
-	bake_cells.resize(bake_cells_used);
-
-	print_line("total bake cells used: " + itos(bake_cells_used));
-	for (int i = 0; i < cell_subdiv; i++) {
-		print_line("level " + itos(i) + ": " + itos(bake_cells_level_used[i]));
-	}
-	print_line("zero alphas: " + itos(zero_alphas));
-}
-
-void BakedLight::_bake_directional(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 &p_dir, const Color &p_color, int p_sign) {
-
-	if (p_level == cell_subdiv - 1) {
-
-		Vector3 end;
-		end.x = float(p_x + 0.5) / cells_per_axis;
-		end.y = float(p_y + 0.5) / cells_per_axis;
-		end.z = float(p_z + 0.5) / cells_per_axis;
-
-		end = bounds.pos + bounds.size * end;
-
-		float max_ray_len = (bounds.size).length() * 1.2;
-
-		Vector3 begin = end + max_ray_len * -p_dir;
-
-		//clip begin
-
-		for (int i = 0; i < 3; i++) {
-
-			if (ABS(p_dir[i]) < CMP_EPSILON) {
-				continue; // parallel to axis, don't clip
-			}
-
-			Plane p;
-			p.normal[i] = 1.0;
-			p.d = bounds.pos[i];
-			if (p_dir[i] < 0) {
-				p.d += bounds.size[i];
-			}
-
-			Vector3 inters;
-			if (p.intersects_segment(end, begin, &inters)) {
-				begin = inters;
-			}
-		}
-
-		int idx = _plot_ray(begin, end);
-
-		if (idx >= 0 && light_pass != bake_cells_write[idx].light_pass) {
-			//hit something, add or remove light to it
-
-			Color albedo = Color(bake_cells_write[idx].albedo[0], bake_cells_write[idx].albedo[1], bake_cells_write[idx].albedo[2]);
-			bake_cells_write[idx].light[0] += albedo.r * p_color.r * p_sign;
-			bake_cells_write[idx].light[1] += albedo.g * p_color.g * p_sign;
-			bake_cells_write[idx].light[2] += albedo.b * p_color.b * p_sign;
-			bake_cells_write[idx].light_pass = light_pass;
-		}
-
-	} else {
-
-		int half = cells_per_axis >> (p_level + 1);
-
-		//go down
-		for (int i = 0; i < 8; i++) {
-
-			uint32_t child = bake_cells_write[p_idx].childs[i];
-
-			if (child == CHILD_EMPTY)
-				continue;
-
-			int nx = p_x;
-			int ny = p_y;
-			int nz = p_z;
-
-			if (i & 1)
-				nx += half;
-			if (i & 2)
-				ny += half;
-			if (i & 4)
-				nz += half;
-
-			_bake_directional(child, p_level + 1, nx, ny, nz, p_dir, p_color, p_sign);
-		}
-	}
-}
-
-void BakedLight::_bake_light(Light *p_light) {
-
-	if (p_light->cast_to<DirectionalLight>()) {
-
-		DirectionalLight *dl = p_light->cast_to<DirectionalLight>();
-
-		Transform rel_xf = dl->get_relative_transform(this);
-
-		Vector3 light_dir = -rel_xf.basis.get_axis(2);
-
-		Color color = dl->get_color();
-		float nrg = dl->get_param(Light::PARAM_ENERGY);
-		color.r *= nrg;
-		color.g *= nrg;
-		color.b *= nrg;
-
-		light_pass++;
-		_bake_directional(0, 0, 0, 0, 0, light_dir, color, 1);
-	}
-}
-
-void BakedLight::_upscale_light(int p_idx, int p_level) {
-
-	//go down
-
-	float light_accum[3] = { 0, 0, 0 };
-	float alpha_accum = 0;
-
-	bool check_children = p_level < (cell_subdiv - 2);
-
-	for (int i = 0; i < 8; i++) {
-
-		uint32_t child = bake_cells_write[p_idx].childs[i];
-
-		if (child == CHILD_EMPTY)
-			continue;
-
-		if (check_children) {
-			_upscale_light(child, p_level + 1);
-		}
-
-		light_accum[0] += bake_cells_write[child].light[0];
-		light_accum[1] += bake_cells_write[child].light[1];
-		light_accum[2] += bake_cells_write[child].light[2];
-		alpha_accum += bake_cells_write[child].alpha;
-	}
-
-	bake_cells_write[p_idx].light[0] = light_accum[0] / 8.0;
-	bake_cells_write[p_idx].light[1] = light_accum[1] / 8.0;
-	bake_cells_write[p_idx].light[2] = light_accum[2] / 8.0;
-	bake_cells_write[p_idx].alpha = alpha_accum / 8.0;
-}
-
-void BakedLight::bake_lights() {
-
-	ERR_FAIL_COND(bake_cells.size() == 0);
-
-	bake_cells_write = bake_cells.write();
-
-	for (Set<Light *>::Element *E = lights.front(); E; E = E->next()) {
-
-		_bake_light(E->get());
-	}
-
-	_upscale_light(0, 0);
-
-	bake_cells_write = PoolVector<BakeCell>::Write();
-}
-
-Color BakedLight::_cone_trace(const Vector3 &p_from, const Vector3 &p_dir, float p_half_angle) {
-
-	Color color(0, 0, 0, 0);
-	float tha = Math::tan(p_half_angle); //tan half angle
-	Vector3 from = (p_from - bounds.pos) / bounds.size; //convert to 0..1
-	from /= cells_per_axis; //convert to voxels of size 1
-	Vector3 dir = (p_dir / bounds.size).normalized();
-
-	float max_dist = Vector3(cells_per_axis, cells_per_axis, cells_per_axis).length();
-
-	float dist = 1.0;
-	// self occlusion in flat surfaces
-
-	float alpha = 0;
-
-	while (dist < max_dist && alpha < 0.95) {
-
-#if 0
-		// smallest sample diameter possible is the voxel size
-		float diameter = MAX(1.0, 2.0 * tha * dist);
-		float lod = log2(diameter);
-
-		Vector3 sample_pos = from + dist * dir;
-
-
-		Color samples_base[2][8]={{Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0)},
-		{Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0)}};
-
-		float levelf = Math::fposmod(lod,1.0);
-		float fx = Math::fposmod(sample_pos.x,1.0);
-		float fy = Math::fposmod(sample_pos.y,1.0);
-		float fz = Math::fposmod(sample_pos.z,1.0);
-
-		for(int l=0;l<2;l++){
-
-			int bx = Math::floor(sample_pos.x);
-			int by = Math::floor(sample_pos.y);
-			int bz = Math::floor(sample_pos.z);
-
-			int lodn=int(Math::floor(lod))-l;
-
-			bx>>=lodn;
-			by>>=lodn;
-			bz>>=lodn;
-
-			int limit = MAX(0,cell_subdiv-lodn-1);
-
-			for(int c=0;c<8;c++) {
-
-				int x = bx;
-				int y = by;
-				int z = bz;
-
-				if (c&1) {
-					x+=1;
-				}
-				if (c&2) {
-					y+=1;
-				}
-				if (c&4) {
-					z+=1;
-				}
-
-				int ofs_x=0;
-				int ofs_y=0;
-				int ofs_z=0;
-				int size = cells_per_axis>>lodn;
-				int half=size/2;
-
-				bool outside=x<0 || x>=size || y<0 || y>=size || z<0 || z>=size;
-
-				if (outside)
-					continue;
-
-
-				uint32_t cell=0;
-
-				for(int i=0;i<limit;i++) {
-
-					BakeCell *bc = &bake_cells_write[cell];
-
-					int child = 0;
-					if (x >= ofs_x + half) {
-						child|=1;
-						ofs_x+=half;
-					}
-					if (y >= ofs_y + half) {
-						child|=2;
-						ofs_y+=half;
-					}
-					if (z >= ofs_z + half) {
-						child|=4;
-						ofs_z+=half;
-					}
-
-					cell = bc->childs[child];
-					if (cell==CHILD_EMPTY)
-						break;
-
-					half>>=1;
-				}
-
-				if (cell!=CHILD_EMPTY) {
-
-					samples_base[l][c].r=bake_cells_write[cell].light[0];
-					samples_base[l][c].g=bake_cells_write[cell].light[1];
-					samples_base[l][c].b=bake_cells_write[cell].light[2];
-					samples_base[l][c].a=bake_cells_write[cell].alpha;
-				}
-
-			}
-
-
-		}
-
-		Color m0x0 = samples_base[0][0].linear_interpolate(samples_base[0][1],fx);
-		Color m0x1 = samples_base[0][2].linear_interpolate(samples_base[0][3],fx);
-		Color m0y0 = m0x0.linear_interpolate(m0x1,fy);
-		m0x0 = samples_base[0][4].linear_interpolate(samples_base[0][5],fx);
-		m0x1 = samples_base[0][6].linear_interpolate(samples_base[0][7],fx);
-		Color m0y1 = m0x0.linear_interpolate(m0x1,fy);
-		Color m0z = m0y0.linear_interpolate(m0y1,fz);
-
-		Color m1x0 = samples_base[1][0].linear_interpolate(samples_base[1][1],fx);
-		Color m1x1 = samples_base[1][2].linear_interpolate(samples_base[1][3],fx);
-		Color m1y0 = m1x0.linear_interpolate(m1x1,fy);
-		m1x0 = samples_base[1][4].linear_interpolate(samples_base[1][5],fx);
-		m1x1 = samples_base[1][6].linear_interpolate(samples_base[1][7],fx);
-		Color m1y1 = m1x0.linear_interpolate(m1x1,fy);
-		Color m1z = m1y0.linear_interpolate(m1y1,fz);
-
-		Color m = m0z.linear_interpolate(m1z,levelf);
-#else
-		float diameter = 1.0;
-		Vector3 sample_pos = from + dist * dir;
-
-		Color m(0, 0, 0, 0);
-		{
-			int x = Math::floor(sample_pos.x);
-			int y = Math::floor(sample_pos.y);
-			int z = Math::floor(sample_pos.z);
-
-			int ofs_x = 0;
-			int ofs_y = 0;
-			int ofs_z = 0;
-			int size = cells_per_axis;
-			int half = size / 2;
-
-			bool outside = x < 0 || x >= size || y < 0 || y >= size || z < 0 || z >= size;
-
-			if (!outside) {
-
-				uint32_t cell = 0;
-
-				for (int i = 0; i < cell_subdiv - 1; i++) {
-
-					BakeCell *bc = &bake_cells_write[cell];
-
-					int child = 0;
-					if (x >= ofs_x + half) {
-						child |= 1;
-						ofs_x += half;
-					}
-					if (y >= ofs_y + half) {
-						child |= 2;
-						ofs_y += half;
-					}
-					if (z >= ofs_z + half) {
-						child |= 4;
-						ofs_z += half;
-					}
-
-					cell = bc->childs[child];
-					if (cell == CHILD_EMPTY)
-						break;
-
-					half >>= 1;
-				}
-
-				if (cell != CHILD_EMPTY) {
-
-					m.r = bake_cells_write[cell].light[0];
-					m.g = bake_cells_write[cell].light[1];
-					m.b = bake_cells_write[cell].light[2];
-					m.a = bake_cells_write[cell].alpha;
-				}
-			}
-		}
-
-#endif
-		// front-to-back compositing
-		float a = (1.0 - alpha);
-		color.r += a * m.r;
-		color.g += a * m.g;
-		color.b += a * m.b;
-		alpha += a * m.a;
-		//occlusion += a * voxelColor.a;
-		//occlusion += (a * voxelColor.a) / (1.0 + 0.03 * diameter);
-		dist += diameter * 0.5; // smoother
-		//dist += diameter; // faster but misses more voxels
-	}
-
-	return color;
-}
-
-void BakedLight::_bake_radiance(int p_idx, int p_level, int p_x, int p_y, int p_z) {
-
-	if (p_level == cell_subdiv - 1) {
-
-		const int NUM_CONES = 6;
-		Vector3 cone_directions[6] = {
-			Vector3(1, 0, 0),
-			Vector3(0.5, 0.866025, 0),
-			Vector3(0.5, 0.267617, 0.823639),
-			Vector3(0.5, -0.700629, 0.509037),
-			Vector3(0.5, -0.700629, -0.509037),
-			Vector3(0.5, 0.267617, -0.823639)
-		};
-		float coneWeights[6] = { 0.25, 0.15, 0.15, 0.15, 0.15, 0.15 };
-
-		Vector3 pos = (Vector3(p_x, p_y, p_z) / float(cells_per_axis)) * bounds.size + bounds.pos;
-		Vector3 voxel_size = bounds.size / float(cells_per_axis);
-		pos += voxel_size * 0.5;
-
-		Color accum;
-
-		bake_cells_write[p_idx].light[0] = 0;
-		bake_cells_write[p_idx].light[1] = 0;
-		bake_cells_write[p_idx].light[2] = 0;
-
-		int freepix = 0;
-		for (int i = 0; i < 6; i++) {
-
-			if (!(bake_cells_write[p_idx].used_sides & (1 << i)))
-				continue;
-
-			if ((i & 1) == 0)
-				bake_cells_write[p_idx].light[i / 2] = 1.0;
-			freepix++;
-			continue;
-
-			int ofs = i / 2;
-
-			Vector3 dir;
-			if ((i & 1) == 0)
-				dir[ofs] = 1.0;
-			else
-				dir[ofs] = -1.0;
-
-			for (int j = 0; j < 1; j++) {
-
-				Vector3 cone_dir;
-				cone_dir.x = cone_directions[j][(ofs + 0) % 3];
-				cone_dir.y = cone_directions[j][(ofs + 1) % 3];
-				cone_dir.z = cone_directions[j][(ofs + 2) % 3];
-
-				cone_dir[ofs] *= dir[ofs];
-
-				Color res = _cone_trace(pos + dir * voxel_size, cone_dir, Math::deg2rad(29.9849));
-				accum.r += res.r; //*coneWeights[j];
-				accum.g += res.g; //*coneWeights[j];
-				accum.b += res.b; //*coneWeights[j];
-			}
-		}
-#if 0
-		if (freepix==0) {
-			bake_cells_write[p_idx].light[0]=0;
-			bake_cells_write[p_idx].light[1]=0;
-			bake_cells_write[p_idx].light[2]=0;
-		}
-
-		if (freepix==1) {
-			bake_cells_write[p_idx].light[0]=1;
-			bake_cells_write[p_idx].light[1]=0;
-			bake_cells_write[p_idx].light[2]=0;
-		}
-
-		if (freepix==2) {
-			bake_cells_write[p_idx].light[0]=0;
-			bake_cells_write[p_idx].light[1]=1;
-			bake_cells_write[p_idx].light[2]=0;
-		}
-
-		if (freepix==3) {
-			bake_cells_write[p_idx].light[0]=1;
-			bake_cells_write[p_idx].light[1]=1;
-			bake_cells_write[p_idx].light[2]=0;
-		}
-
-		if (freepix==4) {
-			bake_cells_write[p_idx].light[0]=0;
-			bake_cells_write[p_idx].light[1]=0;
-			bake_cells_write[p_idx].light[2]=1;
-		}
-
-		if (freepix==5) {
-			bake_cells_write[p_idx].light[0]=1;
-			bake_cells_write[p_idx].light[1]=0;
-			bake_cells_write[p_idx].light[2]=1;
-		}
-
-		if (freepix==6) {
-			bake_cells_write[p_idx].light[0]=0;
-			bake_cells_write[p_idx].light[0]=1;
-			bake_cells_write[p_idx].light[0]=1;
-		}
-#endif
-		//bake_cells_write[p_idx].radiance[0]=accum.r;
-		//bake_cells_write[p_idx].radiance[1]=accum.g;
-		//bake_cells_write[p_idx].radiance[2]=accum.b;
-
-	} else {
-
-		int half = cells_per_axis >> (p_level + 1);
-
-		//go down
-		for (int i = 0; i < 8; i++) {
-
-			uint32_t child = bake_cells_write[p_idx].childs[i];
-
-			if (child == CHILD_EMPTY)
-				continue;
-
-			int nx = p_x;
-			int ny = p_y;
-			int nz = p_z;
-
-			if (i & 1)
-				nx += half;
-			if (i & 2)
-				ny += half;
-			if (i & 4)
-				nz += half;
-
-			_bake_radiance(child, p_level + 1, nx, ny, nz);
-		}
-	}
-}
-
-void BakedLight::bake_radiance() {
-
-	ERR_FAIL_COND(bake_cells.size() == 0);
-
-	bake_cells_write = bake_cells.write();
-
-	_bake_radiance(0, 0, 0, 0, 0);
-
-	bake_cells_write = PoolVector<BakeCell>::Write();
-}
-int BakedLight::_find_cell(int x, int y, int z) {
-
-	uint32_t cell = 0;
-
-	int ofs_x = 0;
-	int ofs_y = 0;
-	int ofs_z = 0;
-	int size = cells_per_axis;
-	int half = size / 2;
-
-	if (x < 0 || x >= size)
-		return -1;
-	if (y < 0 || y >= size)
-		return -1;
-	if (z < 0 || z >= size)
-		return -1;
-
-	for (int i = 0; i < cell_subdiv - 1; i++) {
-
-		BakeCell *bc = &bake_cells_write[cell];
-
-		int child = 0;
-		if (x >= ofs_x + half) {
-			child |= 1;
-			ofs_x += half;
-		}
-		if (y >= ofs_y + half) {
-			child |= 2;
-			ofs_y += half;
-		}
-		if (z >= ofs_z + half) {
-			child |= 4;
-			ofs_z += half;
-		}
-
-		cell = bc->childs[child];
-		if (cell == CHILD_EMPTY)
-			return -1;
-
-		half >>= 1;
-	}
-
-	return cell;
-}
-
-int BakedLight::_plot_ray(const Vector3 &p_from, const Vector3 &p_to) {
-
-	Vector3 from = (p_from - bounds.pos) / bounds.size;
-	Vector3 to = (p_to - bounds.pos) / bounds.size;
-
-	int x1 = Math::floor(from.x * cells_per_axis);
-	int y1 = Math::floor(from.y * cells_per_axis);
-	int z1 = Math::floor(from.z * cells_per_axis);
-
-	int x2 = Math::floor(to.x * cells_per_axis);
-	int y2 = Math::floor(to.y * cells_per_axis);
-	int z2 = Math::floor(to.z * cells_per_axis);
-
-	int i, dx, dy, dz, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2;
-	int point[3];
-
-	point[0] = x1;
-	point[1] = y1;
-	point[2] = z1;
-	dx = x2 - x1;
-	dy = y2 - y1;
-	dz = z2 - z1;
-	x_inc = (dx < 0) ? -1 : 1;
-	l = ABS(dx);
-	y_inc = (dy < 0) ? -1 : 1;
-	m = ABS(dy);
-	z_inc = (dz < 0) ? -1 : 1;
-	n = ABS(dz);
-	dx2 = l << 1;
-	dy2 = m << 1;
-	dz2 = n << 1;
-
-	if ((l >= m) && (l >= n)) {
-		err_1 = dy2 - l;
-		err_2 = dz2 - l;
-		for (i = 0; i < l; i++) {
-			int cell = _find_cell(point[0], point[1], point[2]);
-			if (cell >= 0)
-				return cell;
-
-			if (err_1 > 0) {
-				point[1] += y_inc;
-				err_1 -= dx2;
-			}
-			if (err_2 > 0) {
-				point[2] += z_inc;
-				err_2 -= dx2;
-			}
-			err_1 += dy2;
-			err_2 += dz2;
-			point[0] += x_inc;
-		}
-	} else if ((m >= l) && (m >= n)) {
-		err_1 = dx2 - m;
-		err_2 = dz2 - m;
-		for (i = 0; i < m; i++) {
-			int cell = _find_cell(point[0], point[1], point[2]);
-			if (cell >= 0)
-				return cell;
-			if (err_1 > 0) {
-				point[0] += x_inc;
-				err_1 -= dy2;
-			}
-			if (err_2 > 0) {
-				point[2] += z_inc;
-				err_2 -= dy2;
-			}
-			err_1 += dx2;
-			err_2 += dz2;
-			point[1] += y_inc;
-		}
-	} else {
-		err_1 = dy2 - n;
-		err_2 = dx2 - n;
-		for (i = 0; i < n; i++) {
-			int cell = _find_cell(point[0], point[1], point[2]);
-			if (cell >= 0)
-				return cell;
-
-			if (err_1 > 0) {
-				point[1] += y_inc;
-				err_1 -= dz2;
-			}
-			if (err_2 > 0) {
-				point[0] += x_inc;
-				err_2 -= dz2;
-			}
-			err_1 += dy2;
-			err_2 += dx2;
-			point[2] += z_inc;
-		}
-	}
-	return _find_cell(point[0], point[1], point[2]);
-}
-
-void BakedLight::set_cell_subdiv(int p_subdiv) {
-
-	cell_subdiv = p_subdiv;
-
-	//VS::get_singleton()->baked_light_set_subdivision(baked_light,p_subdiv);
-}
-
-int BakedLight::get_cell_subdiv() const {
-
-	return cell_subdiv;
-}
-
-Rect3 BakedLight::get_aabb() const {
-
-	return Rect3(Vector3(0, 0, 0), Vector3(1, 1, 1));
-}
-PoolVector<Face3> BakedLight::get_faces(uint32_t p_usage_flags) const {
-
-	return PoolVector<Face3>();
-}
-
-String BakedLight::get_configuration_warning() const {
-	return String();
-}
-
-void BakedLight::_debug_mesh(int p_idx, int p_level, const Rect3 &p_aabb, DebugMode p_mode, Ref<MultiMesh> &p_multimesh, int &idx) {
-
-	if (p_level == cell_subdiv - 1) {
-
-		Vector3 center = p_aabb.pos + p_aabb.size * 0.5;
-		Transform xform;
-		xform.origin = center;
-		xform.basis.scale(p_aabb.size * 0.5);
-		p_multimesh->set_instance_transform(idx, xform);
-		Color col;
-		switch (p_mode) {
-			case DEBUG_ALBEDO: {
-				col = Color(bake_cells_write[p_idx].albedo[0], bake_cells_write[p_idx].albedo[1], bake_cells_write[p_idx].albedo[2]);
-			} break;
-			case DEBUG_LIGHT: {
-				col = Color(bake_cells_write[p_idx].light[0], bake_cells_write[p_idx].light[1], bake_cells_write[p_idx].light[2]);
-				Color colr = Color(bake_cells_write[p_idx].radiance[0], bake_cells_write[p_idx].radiance[1], bake_cells_write[p_idx].radiance[2]);
-				col.r += colr.r;
-				col.g += colr.g;
-				col.b += colr.b;
-			} break;
-		}
-		p_multimesh->set_instance_color(idx, col);
-
-		idx++;
-
-	} else {
-
-		for (int i = 0; i < 8; i++) {
-
-			if (bake_cells_write[p_idx].childs[i] == CHILD_EMPTY)
-				continue;
-
-			Rect3 aabb = p_aabb;
-			aabb.size *= 0.5;
-
-			if (i & 1)
-				aabb.pos.x += aabb.size.x;
-			if (i & 2)
-				aabb.pos.y += aabb.size.y;
-			if (i & 4)
-				aabb.pos.z += aabb.size.z;
-
-			_debug_mesh(bake_cells_write[p_idx].childs[i], p_level + 1, aabb, p_mode, p_multimesh, idx);
-		}
-	}
-}
-
-void BakedLight::create_debug_mesh(DebugMode p_mode) {
-
-	Ref<MultiMesh> mm;
-	mm.instance();
-
-	mm->set_transform_format(MultiMesh::TRANSFORM_3D);
-	mm->set_color_format(MultiMesh::COLOR_8BIT);
-	mm->set_instance_count(bake_cells_level_used[cell_subdiv - 1]);
-
-	Ref<Mesh> mesh;
-	mesh.instance();
-
-	{
-		Array arr;
-		arr.resize(Mesh::ARRAY_MAX);
-
-		PoolVector<Vector3> vertices;
-		PoolVector<Color> colors;
-
-		int vtx_idx = 0;
-#define ADD_VTX(m_idx)                      \
-	;                                       \
-	vertices.push_back(face_points[m_idx]); \
-	colors.push_back(Color(1, 1, 1, 1));    \
-	vtx_idx++;
-
-		for (int i = 0; i < 6; i++) {
-
-			Vector3 face_points[4];
-
-			for (int j = 0; j < 4; j++) {
-
-				float v[3];
-				v[0] = 1.0;
-				v[1] = 1 - 2 * ((j >> 1) & 1);
-				v[2] = v[1] * (1 - 2 * (j & 1));
-
-				for (int k = 0; k < 3; k++) {
-
-					if (i < 3)
-						face_points[j][(i + k) % 3] = v[k] * (i >= 3 ? -1 : 1);
-					else
-						face_points[3 - j][(i + k) % 3] = v[k] * (i >= 3 ? -1 : 1);
-				}
-			}
-
-			//tri 1
-			ADD_VTX(0);
-			ADD_VTX(1);
-			ADD_VTX(2);
-			//tri 2
-			ADD_VTX(2);
-			ADD_VTX(3);
-			ADD_VTX(0);
-		}
-
-		arr[Mesh::ARRAY_VERTEX] = vertices;
-		arr[Mesh::ARRAY_COLOR] = colors;
-		mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arr);
-	}
-
-	{
-		Ref<SpatialMaterial> fsm;
-		fsm.instance();
-		fsm->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
-		fsm->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
-		fsm->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
-		fsm->set_albedo(Color(1, 1, 1, 1));
-
-		mesh->surface_set_material(0, fsm);
-	}
-
-	mm->set_mesh(mesh);
-
-	bake_cells_write = bake_cells.write();
-
-	int idx = 0;
-	_debug_mesh(0, 0, bounds, p_mode, mm, idx);
-
-	print_line("written: " + itos(idx) + " total: " + itos(bake_cells_level_used[cell_subdiv - 1]));
-
-	MultiMeshInstance *mmi = memnew(MultiMeshInstance);
-	mmi->set_multimesh(mm);
-	add_child(mmi);
-#ifdef TOOLS_ENABLED
-	if (get_tree()->get_edited_scene_root() == this) {
-		mmi->set_owner(this);
-	} else {
-		mmi->set_owner(get_owner());
-	}
-#else
-	mmi->set_owner(get_owner());
-#endif
-}
-
-void BakedLight::_debug_mesh_albedo() {
-	create_debug_mesh(DEBUG_ALBEDO);
-}
-
-void BakedLight::_debug_mesh_light() {
-	create_debug_mesh(DEBUG_LIGHT);
-}
-
-void BakedLight::_bind_methods() {
-
-	ClassDB::bind_method(D_METHOD("set_cell_subdiv", "steps"), &BakedLight::set_cell_subdiv);
-	ClassDB::bind_method(D_METHOD("get_cell_subdiv"), &BakedLight::get_cell_subdiv);
-
-	ClassDB::bind_method(D_METHOD("bake"), &BakedLight::bake);
-	ClassDB::set_method_flags(get_class_static(), _scs_create("bake"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
-
-	ClassDB::bind_method(D_METHOD("bake_lights"), &BakedLight::bake_lights);
-	ClassDB::set_method_flags(get_class_static(), _scs_create("bake_lights"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
-
-	ClassDB::bind_method(D_METHOD("bake_radiance"), &BakedLight::bake_radiance);
-	ClassDB::set_method_flags(get_class_static(), _scs_create("bake_radiance"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
-
-	ClassDB::bind_method(D_METHOD("debug_mesh_albedo"), &BakedLight::_debug_mesh_albedo);
-	ClassDB::set_method_flags(get_class_static(), _scs_create("debug_mesh_albedo"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
-
-	ClassDB::bind_method(D_METHOD("debug_mesh_light"), &BakedLight::_debug_mesh_light);
-	ClassDB::set_method_flags(get_class_static(), _scs_create("debug_mesh_light"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
-
-	ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_subdiv"), "set_cell_subdiv", "get_cell_subdiv");
-	ADD_SIGNAL(MethodInfo("baked_light_changed"));
-}
-
-BakedLight::BakedLight() {
-
-	//baked_light=VisualServer::get_singleton()->baked_light_create();
-	VS::get_singleton()->instance_set_base(get_instance(), baked_light);
-
-	cell_subdiv = 8;
-	bake_texture_size = 128;
-	color_scan_cell_width = 8;
-	light_pass = 0;
-}
-
-BakedLight::~BakedLight() {
-
-	VS::get_singleton()->free(baked_light);
-}
-
-/////////////////////////
-
-#if 0
-void BakedLightSampler::set_param(Param p_param,float p_value) {
-	ERR_FAIL_INDEX(p_param,PARAM_MAX);
-	params[p_param]=p_value;
-	VS::get_singleton()->baked_light_sampler_set_param(base,VS::BakedLightSamplerParam(p_param),p_value);
-}
-
-float BakedLightSampler::get_param(Param p_param) const{
-
-	ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0);
-	return params[p_param];
-
-}
-
-void BakedLightSampler::set_resolution(int p_resolution){
-
-    ERR_FAIL_COND(p_resolution<4 || p_resolution>32);
-	resolution=p_resolution;
-	VS::get_singleton()->baked_light_sampler_set_resolution(base,resolution);
-}
-int BakedLightSampler::get_resolution() const {
-
-	return resolution;
-}
-
-AABB BakedLightSampler::get_aabb() const {
-
-	float r = get_param(PARAM_RADIUS);
-	return AABB( Vector3(-r,-r,-r),Vector3(r*2,r*2,r*2));
-}
-DVector<Face3> BakedLightSampler::get_faces(uint32_t p_usage_flags) const {
-	return DVector<Face3>();
-}
-
-void BakedLightSampler::_bind_methods() {
-
-	ClassDB::bind_method(D_METHOD("set_param","param","value"),&BakedLightSampler::set_param);
-	ClassDB::bind_method(D_METHOD("get_param","param"),&BakedLightSampler::get_param);
-
-	ClassDB::bind_method(D_METHOD("set_resolution","resolution"),&BakedLightSampler::set_resolution);
-	ClassDB::bind_method(D_METHOD("get_resolution"),&BakedLightSampler::get_resolution);
-
-
-	BIND_CONSTANT( PARAM_RADIUS );
-	BIND_CONSTANT( PARAM_STRENGTH );
-	BIND_CONSTANT( PARAM_ATTENUATION );
-	BIND_CONSTANT( PARAM_DETAIL_RATIO );
-	BIND_CONSTANT( PARAM_MAX );
-
-	ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/radius",PROPERTY_HINT_RANGE,"0.01,1024,0.01"),"set_param","get_param",PARAM_RADIUS);
-	ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/strength",PROPERTY_HINT_RANGE,"0.01,16,0.01"),"set_param","get_param",PARAM_STRENGTH);
-	ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/attenuation",PROPERTY_HINT_EXP_EASING),"set_param","get_param",PARAM_ATTENUATION);
-	ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/detail_ratio",PROPERTY_HINT_RANGE,"0.01,1.0,0.01"),"set_param","get_param",PARAM_DETAIL_RATIO);
-	//ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/detail_ratio",PROPERTY_HINT_RANGE,"0,20,1"),"set_param","get_param",PARAM_DETAIL_RATIO);
-	ADD_PROPERTY( PropertyInfo(Variant::REAL,"params/resolution",PROPERTY_HINT_RANGE,"4,32,1"),"set_resolution","get_resolution");
-
-}
-
-BakedLightSampler::BakedLightSampler() {
-
-	base = VS::get_singleton()->baked_light_sampler_create();
-	set_base(base);
-
-	params[PARAM_RADIUS]=1.0;
-	params[PARAM_STRENGTH]=1.0;
-	params[PARAM_ATTENUATION]=1.0;
-	params[PARAM_DETAIL_RATIO]=0.1;
-	resolution=16;
-
-
-}
-
-BakedLightSampler::~BakedLightSampler(){
-
-	VS::get_singleton()->free(base);
-}
-#endif

+ 0 - 199
scene/3d/baked_light_instance.h

@@ -1,199 +0,0 @@
-/*************************************************************************/
-/*  baked_light_instance.h                                               */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                    http://www.godotengine.org                         */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)    */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#ifndef BAKED_LIGHT_INSTANCE_H
-#define BAKED_LIGHT_INSTANCE_H
-
-#include "scene/3d/multimesh_instance.h"
-#include "scene/3d/visual_instance.h"
-#include "scene/resources/baked_light.h"
-
-class BakedLightBaker;
-class Light;
-
-class BakedLight : public VisualInstance {
-	GDCLASS(BakedLight, VisualInstance);
-
-public:
-	enum DebugMode {
-		DEBUG_ALBEDO,
-		DEBUG_LIGHT
-	};
-
-private:
-	RID baked_light;
-	int cell_subdiv;
-	Rect3 bounds;
-	int cells_per_axis;
-
-	enum {
-		CHILD_EMPTY = 0xFFFFFFFF,
-	};
-
-	/* BAKE DATA */
-
-	struct BakeCell {
-
-		uint32_t childs[8];
-		float albedo[3]; //albedo in RGB24
-		float light[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast)
-		float radiance[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast)
-		uint32_t used_sides;
-		float alpha; //used for upsampling
-		uint32_t light_pass; //used for baking light
-
-		BakeCell() {
-			for (int i = 0; i < 8; i++) {
-				childs[i] = 0xFFFFFFFF;
-			}
-
-			for (int i = 0; i < 3; i++) {
-				light[i] = 0;
-				albedo[i] = 0;
-				radiance[i] = 0;
-			}
-			alpha = 0;
-			light_pass = 0;
-			used_sides = 0;
-		}
-	};
-
-	int bake_texture_size;
-	int color_scan_cell_width;
-
-	struct MaterialCache {
-		//128x128 textures
-		Vector<Color> albedo;
-		Vector<Color> emission;
-	};
-
-	Vector<Color> _get_bake_texture(Image &p_image, const Color &p_color);
-
-	Map<Ref<Material>, MaterialCache> material_cache;
-	MaterialCache _get_material_cache(Ref<Material> p_material);
-
-	int bake_cells_alloc;
-	int bake_cells_used;
-	int zero_alphas;
-	Vector<int> bake_cells_level_used;
-	PoolVector<BakeCell> bake_cells;
-	PoolVector<BakeCell>::Write bake_cells_write;
-
-	void _plot_face(int p_idx, int p_level, const Vector3 *p_vtx, const Vector2 *p_uv, const MaterialCache &p_material, const Rect3 &p_aabb);
-	void _fixup_plot(int p_idx, int p_level, int p_x, int p_y, int p_z);
-	void _bake_add_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh);
-	void _bake_add_to_aabb(const Transform &p_xform, Ref<Mesh> &p_mesh, bool &first);
-
-	void _debug_mesh(int p_idx, int p_level, const Rect3 &p_aabb, DebugMode p_mode, Ref<MultiMesh> &p_multimesh, int &idx);
-	void _debug_mesh_albedo();
-	void _debug_mesh_light();
-
-	_FORCE_INLINE_ int _find_cell(int x, int y, int z);
-	int _plot_ray(const Vector3 &p_from, const Vector3 &p_to);
-
-	uint32_t light_pass;
-
-	void _bake_directional(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 &p_dir, const Color &p_color, int p_sign);
-	void _upscale_light(int p_idx, int p_level);
-	void _bake_light(Light *p_light);
-
-	Color _cone_trace(const Vector3 &p_from, const Vector3 &p_dir, float p_half_angle);
-	void _bake_radiance(int p_idx, int p_level, int p_x, int p_y, int p_z);
-
-	friend class GeometryInstance;
-
-	Set<GeometryInstance *> geometries;
-	friend class Light;
-
-	Set<Light *> lights;
-
-protected:
-	static void _bind_methods();
-
-public:
-	void set_cell_subdiv(int p_subdiv);
-	int get_cell_subdiv() const;
-
-	void bake();
-	void bake_lights();
-	void bake_radiance();
-
-	void create_debug_mesh(DebugMode p_mode);
-
-	virtual Rect3 get_aabb() const;
-	virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const;
-
-	String get_configuration_warning() const;
-
-	BakedLight();
-	~BakedLight();
-};
-
-#if 0
-class BakedLightSampler : public VisualInstance {
-	GDCLASS(BakedLightSampler,VisualInstance);
-
-
-public:
-
-	enum Param {
-		PARAM_RADIUS=VS::BAKED_LIGHT_SAMPLER_RADIUS,
-		PARAM_STRENGTH=VS::BAKED_LIGHT_SAMPLER_STRENGTH,
-		PARAM_ATTENUATION=VS::BAKED_LIGHT_SAMPLER_ATTENUATION,
-		PARAM_DETAIL_RATIO=VS::BAKED_LIGHT_SAMPLER_DETAIL_RATIO,
-		PARAM_MAX=VS::BAKED_LIGHT_SAMPLER_MAX
-	};
-
-
-
-protected:
-
-	RID base;
-	float params[PARAM_MAX];
-	int resolution;
-	static void _bind_methods();
-public:
-
-	virtual AABB get_aabb() const;
-	virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const;
-
-	void set_param(Param p_param,float p_value);
-	float get_param(Param p_param) const;
-
-	void set_resolution(int p_resolution);
-	int get_resolution() const;
-
-	BakedLightSampler();
-	~BakedLightSampler();
-};
-
-VARIANT_ENUM_CAST( BakedLightSampler::Param );
-
-#endif
-#endif // BAKED_LIGHT_H

+ 10 - 10
scene/3d/gi_probe.cpp

@@ -881,11 +881,11 @@ void GIProbe::_fixup_plot(int p_idx, int p_level, int p_x, int p_y, int p_z, Bak
 	}
 }
 
-Vector<Color> GIProbe::_get_bake_texture(Image &p_image, const Color &p_color) {
+Vector<Color> GIProbe::_get_bake_texture(Ref<Image> p_image, const Color &p_color) {
 
 	Vector<Color> ret;
 
-	if (p_image.empty()) {
+	if (p_image.is_null()) {
 
 		ret.resize(bake_texture_size * bake_texture_size);
 		for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
@@ -895,14 +895,14 @@ Vector<Color> GIProbe::_get_bake_texture(Image &p_image, const Color &p_color) {
 		return ret;
 	}
 
-	if (p_image.is_compressed()) {
+	if (p_image->is_compressed()) {
 		print_line("DECOMPRESSING!!!!");
-		p_image.decompress();
+		p_image->decompress();
 	}
-	p_image.convert(Image::FORMAT_RGBA8);
-	p_image.resize(bake_texture_size, bake_texture_size, Image::INTERPOLATE_CUBIC);
+	p_image->convert(Image::FORMAT_RGBA8);
+	p_image->resize(bake_texture_size, bake_texture_size, Image::INTERPOLATE_CUBIC);
 
-	PoolVector<uint8_t>::Read r = p_image.get_data().read();
+	PoolVector<uint8_t>::Read r = p_image->get_data().read();
 	ret.resize(bake_texture_size * bake_texture_size);
 
 	for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
@@ -934,7 +934,7 @@ GIProbe::Baker::MaterialCache GIProbe::_get_material_cache(Ref<Material> p_mater
 
 		Ref<Texture> albedo_tex = mat->get_texture(SpatialMaterial::TEXTURE_ALBEDO);
 
-		Image img_albedo;
+		Ref<Image> img_albedo;
 		if (albedo_tex.is_valid()) {
 
 			img_albedo = albedo_tex->get_data();
@@ -950,7 +950,7 @@ GIProbe::Baker::MaterialCache GIProbe::_get_material_cache(Ref<Material> p_mater
 		emission_col.g *= mat->get_emission_energy();
 		emission_col.b *= mat->get_emission_energy();
 
-		Image img_emission;
+		Ref<Image> img_emission;
 
 		if (emission_tex.is_valid()) {
 
@@ -960,7 +960,7 @@ GIProbe::Baker::MaterialCache GIProbe::_get_material_cache(Ref<Material> p_mater
 		mc.emission = _get_bake_texture(img_emission, emission_col);
 
 	} else {
-		Image empty;
+		Ref<Image> empty;
 
 		mc.albedo = _get_bake_texture(empty, Color(0.7, 0.7, 0.7));
 		mc.emission = _get_bake_texture(empty, Color(0, 0, 0));

+ 2 - 2
scene/3d/gi_probe.h

@@ -134,7 +134,7 @@ private:
 			Vector<Color> emission;
 		};
 
-		Vector<Color> _get_bake_texture(Image &p_image, const Color &p_color);
+		Vector<Color> _get_bake_texture(Ref<Image> p_image, const Color &p_color);
 		Map<Ref<Material>, MaterialCache> material_cache;
 		MaterialCache _get_material_cache(Ref<Material> p_material);
 		int leaf_voxel_count;
@@ -170,7 +170,7 @@ private:
 	int color_scan_cell_width;
 	int bake_texture_size;
 
-	Vector<Color> _get_bake_texture(Image &p_image, const Color &p_color);
+	Vector<Color> _get_bake_texture(Ref<Image> p_image, const Color &p_color);
 	Baker::MaterialCache _get_material_cache(Ref<Material> p_material, Baker *p_baker);
 	void _plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector2 *p_uv, const Baker::MaterialCache &p_material, const Rect3 &p_aabb, Baker *p_baker);
 	void _plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, Baker *p_baker, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material);

+ 0 - 20
scene/3d/light.cpp

@@ -29,7 +29,6 @@
 /*************************************************************************/
 #include "light.h"
 
-#include "baked_light_instance.h"
 #include "global_config.h"
 #include "scene/resources/surface_tool.h"
 
@@ -166,26 +165,9 @@ void Light::_notification(int p_what) {
 
 	if (p_what == NOTIFICATION_ENTER_TREE) {
 		_update_visibility();
-
-		Node *node = this;
-
-		while (node) {
-
-			baked_light = node->cast_to<BakedLight>();
-			if (baked_light) {
-				baked_light->lights.insert(this);
-				break;
-			}
-
-			node = node->get_parent();
-		}
 	}
 
 	if (p_what == NOTIFICATION_EXIT_TREE) {
-
-		if (baked_light) {
-			baked_light->lights.erase(this);
-		}
 	}
 }
 
@@ -262,8 +244,6 @@ Light::Light(VisualServer::LightType p_type) {
 	light = VisualServer::get_singleton()->light_create(p_type);
 	VS::get_singleton()->instance_set_base(get_instance(), light);
 
-	baked_light = NULL;
-
 	editor_only = false;
 	set_color(Color(1, 1, 1, 1));
 	set_shadow(false);

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

@@ -75,7 +75,6 @@ private:
 	bool editor_only;
 	void _update_visibility();
 
-	BakedLight *baked_light;
 	// bind helpers
 
 protected:

+ 7 - 7
scene/gui/color_picker.cpp

@@ -178,7 +178,7 @@ void ColorPicker::_update_presets() {
 		}
 	}
 
-	Image i(size.x * presets.size(), size.y, false, Image::FORMAT_RGB8, img);
+	Ref<Image> i = memnew(Image(size.x * presets.size(), size.y, false, Image::FORMAT_RGB8, img));
 
 	Ref<ImageTexture> t;
 	t.instance();
@@ -399,16 +399,16 @@ void ColorPicker::_screen_input(const InputEvent &ev) {
 		Viewport *r = get_tree()->get_root();
 		if (!r->get_visible_rect().has_point(Point2(mev.global_x, mev.global_y)))
 			return;
-		Image img = r->get_screen_capture();
-		if (!img.empty()) {
+		Ref<Image> img = r->get_screen_capture();
+		if (!img.is_null()) {
 			last_capture = img;
 			r->queue_screen_capture();
 		}
-		if (!last_capture.empty()) {
-			int pw = last_capture.get_format() == Image::FORMAT_RGBA8 ? 4 : 3;
-			int ofs = (mev.global_y * last_capture.get_width() + mev.global_x) * pw;
+		if (last_capture.is_valid() && !last_capture->empty()) {
+			int pw = last_capture->get_format() == Image::FORMAT_RGBA8 ? 4 : 3;
+			int ofs = (mev.global_y * last_capture->get_width() + mev.global_x) * pw;
 
-			PoolVector<uint8_t>::Read r = last_capture.get_data().read();
+			PoolVector<uint8_t>::Read r = last_capture->get_data().read();
 
 			Color c(r[ofs + 0] / 255.0, r[ofs + 1] / 255.0, r[ofs + 2] / 255.0);
 

+ 1 - 1
scene/gui/color_picker.h

@@ -47,7 +47,7 @@ class ColorPicker : public BoxContainer {
 
 private:
 	Control *screen;
-	Image last_capture;
+	Ref<Image> last_capture;
 	Control *uv_edit;
 	Control *w_edit;
 	TextureRect *sample;

+ 2 - 1
scene/gui/color_ramp_edit.cpp

@@ -42,7 +42,8 @@ ColorRampEdit::ColorRampEdit() {
 	add_child(popup);
 
 	checker = Ref<ImageTexture>(memnew(ImageTexture));
-	checker->create_from_image(Image(checker_bg_png), ImageTexture::FLAG_REPEAT);
+	Ref<Image> img = memnew(Image(checker_bg_png));
+	checker->create_from_image(img, ImageTexture::FLAG_REPEAT);
 }
 
 int ColorRampEdit::_get_point_from_pos(int x) {

+ 1 - 1
scene/gui/video_player.h

@@ -59,7 +59,7 @@ class VideoPlayer : public Control {
 	RID stream_rid;
 
 	Ref<ImageTexture> texture;
-	Image last_frame;
+	Ref<Image> last_frame;
 
 	AudioRBResampler resampler;
 

+ 2 - 2
scene/main/viewport.cpp

@@ -1226,10 +1226,10 @@ void Viewport::queue_screen_capture() {
 
 	//VS::get_singleton()->viewport_queue_screen_capture(viewport);
 }
-Image Viewport::get_screen_capture() const {
+Ref<Image> Viewport::get_screen_capture() const {
 
 	//return VS::get_singleton()->viewport_get_screen_capture(viewport);
-	return Image();
+	return Ref<Image>();
 }
 
 Ref<ViewportTexture> Viewport::get_texture() const {

+ 1 - 1
scene/main/viewport.h

@@ -383,7 +383,7 @@ public:
 	Vector2 get_camera_rect_size() const;
 
 	void queue_screen_capture();
-	Image get_screen_capture() const;
+	Ref<Image> get_screen_capture() const;
 
 	void set_use_own_world(bool p_world);
 	bool is_using_own_world() const;

+ 2 - 2
scene/register_scene_types.cpp

@@ -212,7 +212,7 @@
 #include "scene/resources/environment.h"
 
 #include "scene/3d/area.h"
-#include "scene/3d/baked_light_instance.h"
+
 #include "scene/3d/body_shape.h"
 #include "scene/3d/immediate_geometry.h"
 #include "scene/3d/multimesh_instance.h"
@@ -452,7 +452,7 @@ void register_scene_types() {
 	ClassDB::register_class<PathFollow>();
 	ClassDB::register_class<VisibilityNotifier>();
 	ClassDB::register_class<VisibilityEnabler>();
-	ClassDB::register_class<BakedLight>();
+	//	ClassDB::register_class<BakedLight>();
 	//ClassDB::register_type<BakedLightSampler>();
 	ClassDB::register_class<WorldEnvironment>();
 	ClassDB::register_class<RemoteTransform>();

+ 0 - 31
scene/resources/baked_light.cpp

@@ -1,31 +0,0 @@
-/*************************************************************************/
-/*  baked_light.cpp                                                      */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                    http://www.godotengine.org                         */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)    */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "baked_light.h"
-#include "servers/visual_server.h"

+ 0 - 36
scene/resources/baked_light.h

@@ -1,36 +0,0 @@
-/*************************************************************************/
-/*  baked_light.h                                                        */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                    http://www.godotengine.org                         */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)    */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#ifndef BAKED_LIGHT_H
-#define BAKED_LIGHT_H
-
-#include "resource.h"
-#include "scene/resources/texture.h"
-
-#endif // BAKED_LIGHT_H

+ 7 - 7
scene/resources/bit_mask.cpp

@@ -41,16 +41,16 @@ void BitMap::create(const Size2 &p_size) {
 	zeromem(bitmask.ptr(), bitmask.size());
 }
 
-void BitMap::create_from_image_alpha(const Image &p_image) {
+void BitMap::create_from_image_alpha(const Ref<Image> &p_image) {
 
-	ERR_FAIL_COND(p_image.empty());
-	Image img = p_image;
-	img.convert(Image::FORMAT_LA8);
-	ERR_FAIL_COND(img.get_format() != Image::FORMAT_LA8);
+	ERR_FAIL_COND(p_image.is_null() || p_image->empty());
+	Ref<Image> img = p_image->duplicate();
+	img->convert(Image::FORMAT_LA8);
+	ERR_FAIL_COND(img->get_format() != Image::FORMAT_LA8);
 
-	create(Size2(img.get_width(), img.get_height()));
+	create(Size2(img->get_width(), img->get_height()));
 
-	PoolVector<uint8_t>::Read r = img.get_data().read();
+	PoolVector<uint8_t>::Read r = img->get_data().read();
 	uint8_t *w = bitmask.ptr();
 
 	for (int i = 0; i < width * height; i++) {

+ 2 - 1
scene/resources/bit_mask.h

@@ -30,6 +30,7 @@
 #ifndef BIT_MASK_H
 #define BIT_MASK_H
 
+#include "image.h" 0
 #include "io/resource_loader.h"
 #include "resource.h"
 
@@ -51,7 +52,7 @@ protected:
 
 public:
 	void create(const Size2 &p_size);
-	void create_from_image_alpha(const Image &p_image);
+	void create_from_image_alpha(const Ref<Image> &p_image);
 
 	void set_bit(const Point2 &p_pos, bool p_value);
 	bool get_bit(const Point2 &p_pos) const;

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