ソースを参照

Fix texture resource reload bug

If a non-imported texture resource file (e.g. DDS) gets updated the editor
doesn't reload it. The cause of the problem is two-fold:

First, the code of ImageTexture assumes that textures are always imported
from an image, but that's not the case for e.g. DDS. This change thus adds
code to issue a resource reload in case an image reload is not possible
(which is the case for non-imported texture resources).

Second, the code is filled with bogus calls to Image::get_image_data_size()
to determine the mipmap offset when that should be done using
Image::get_image_mipmap_offset(). Previous code literally passed the integer
mip level value to Image::get_image_data_size() where that actually expects
a boolean. Thus this part of the change might actually solve some other
issues as well.

To be pedantic, the texture_get_data() funciton of the rasterizer drivers is
still quite a mess, as it only ever returns the whole mipchain when
GLES_OVER_GL is set (practically only on desktop builds) but this change does
not attempt to resolve that.
Daniel Rakos 6 年 前
コミット
e34eb5c26c

+ 1 - 4
drivers/gles2/rasterizer_storage_gles2.cpp

@@ -774,10 +774,7 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer)
 
 	for (int i = 0; i < texture->mipmaps; i++) {
 
-		int ofs = 0;
-		if (i > 0) {
-			ofs = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, i - 1);
-		}
+		int ofs = Image::get_image_mipmap_offset(texture->alloc_width, texture->alloc_height, real_format, i);
 
 		if (texture->compressed) {
 			glPixelStorei(GL_PACK_ALIGNMENT, 4);

+ 1 - 4
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -1210,10 +1210,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer)
 
 	for (int i = 0; i < texture->mipmaps; i++) {
 
-		int ofs = 0;
-		if (i > 0) {
-			ofs = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, i - 1);
-		}
+		int ofs = Image::get_image_mipmap_offset(texture->alloc_width, texture->alloc_height, real_format, i);
 
 		if (texture->compressed) {
 

+ 8 - 9
scene/resources/texture.cpp

@@ -111,10 +111,12 @@ void ImageTexture::reload_from_file() {
 	Ref<Image> img;
 	img.instance();
 
-	Error err = ImageLoader::load_image(path, img);
-	ERR_FAIL_COND(err != OK);
-
-	create_from_image(img, flags);
+	if (ImageLoader::load_image(path, img) == OK) {
+		create_from_image(img, flags);
+	} else {
+		Resource::reload_from_file();
+		_change_notify();
+	}
 }
 
 bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) {
@@ -638,7 +640,7 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_
 		bool mipmaps = df & FORMAT_BIT_HAS_MIPMAPS;
 
 		if (!mipmaps) {
-			int size = Image::get_image_data_size(tw, th, format, 0);
+			int size = Image::get_image_data_size(tw, th, format, false);
 
 			PoolVector<uint8_t> img_data;
 			img_data.resize(size);
@@ -660,7 +662,6 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_
 			int mipmaps2 = Image::get_image_required_mipmaps(tw, th, format);
 			int total_size = Image::get_image_data_size(tw, th, format, true);
 			int idx = 0;
-			int ofs = 0;
 
 			while (mipmaps2 > 1 && p_size_limit > 0 && (sw > p_size_limit || sh > p_size_limit)) {
 
@@ -670,9 +671,7 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_
 				idx++;
 			}
 
-			if (idx > 0) {
-				ofs = Image::get_image_data_size(tw, th, format, idx - 1);
-			}
+			int ofs = Image::get_image_mipmap_offset(tw, th, format, idx);
 
 			if (total_size - ofs <= 0) {
 				memdelete(f);