diff options
-rw-r--r-- | drivers/gles2/rasterizer_canvas_gles2.cpp | 24 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.cpp | 92 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.h | 6 | ||||
-rw-r--r-- | drivers/gles2/shader_compiler_gles2.cpp | 2 | ||||
-rw-r--r-- | drivers/gles2/shaders/canvas.glsl | 16 | ||||
-rw-r--r-- | editor/import/resource_importer_texture.cpp | 32 | ||||
-rw-r--r-- | editor/import/resource_importer_texture.h | 2 | ||||
-rw-r--r-- | scene/resources/texture.cpp | 26 | ||||
-rw-r--r-- | scene/resources/texture.h | 2 |
9 files changed, 158 insertions, 44 deletions
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index 9a49d5a7e4..320242b773 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -499,6 +499,23 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur glDisableVertexAttribArray(VS::ARRAY_COLOR); glVertexAttrib4fv(VS::ARRAY_COLOR, r->modulate.components); + bool can_tile = true; + if (r->texture.is_valid() && r->flags & CANVAS_RECT_TILE && !storage->config.support_npot_repeat_mipmap) { + // workaround for when setting tiling does not work due to hardware limitation + + RasterizerStorageGLES2::Texture *texture = storage->texture_owner.getornull(r->texture); + + if (texture) { + + texture = texture->get_ptr(); + + if (next_power_of_2(texture->alloc_width) != texture->alloc_width && next_power_of_2(texture->alloc_height) != texture->alloc_height) { + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_FORCE_REPEAT, true); + can_tile = false; + } + } + } + // On some widespread Nvidia cards, the normal draw method can produce some // flickering in draw_rect and especially TileMap rendering (tiles randomly flicker). // See GH-9913. @@ -559,7 +576,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur bool untile = false; - if (r->flags & CANVAS_RECT_TILE && !(texture->flags & VS::TEXTURE_FLAG_REPEAT)) { + if (can_tile && r->flags & CANVAS_RECT_TILE && !(texture->flags & VS::TEXTURE_FLAG_REPEAT)) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); untile = true; @@ -616,7 +633,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur bool untile = false; - if (r->flags & CANVAS_RECT_TILE && !(tex->flags & VS::TEXTURE_FLAG_REPEAT)) { + if (can_tile && r->flags & CANVAS_RECT_TILE && !(tex->flags & VS::TEXTURE_FLAG_REPEAT)) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); untile = true; @@ -664,6 +681,9 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } + + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_FORCE_REPEAT, false); + } break; case Item::Command::TYPE_NINEPATCH: { diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index c02eeaa0ee..8d81242c05 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -67,7 +67,7 @@ void RasterizerStorageGLES2::bind_quad_array() const { glEnableVertexAttribArray(VS::ARRAY_TEX_UV); } -Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed) const { +Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_will_need_resize) const { r_gl_format = 0; Ref<Image> image = p_image; @@ -195,7 +195,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_ } break; case Image::FORMAT_DXT1: { - if (config.s3tc_supported) { + if (config.s3tc_supported && !p_will_need_resize) { r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; @@ -207,7 +207,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_ } break; case Image::FORMAT_DXT3: { - if (config.s3tc_supported) { + if (config.s3tc_supported && !p_will_need_resize) { r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; @@ -219,7 +219,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_ } break; case Image::FORMAT_DXT5: { - if (config.s3tc_supported) { + if (config.s3tc_supported && !p_will_need_resize) { r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; @@ -269,7 +269,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_ } break; case Image::FORMAT_ETC: { - if (config.etc1_supported) { + if (config.etc1_supported && !p_will_need_resize) { r_gl_internal_format = _EXT_ETC1_RGB8_OES; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; @@ -315,17 +315,38 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_ if (need_decompress) { if (!image.is_null()) { + image = image->duplicate(); + print_line("decompressing..."); image->decompress(); ERR_FAIL_COND_V(image->is_compressed(), image); - image->convert(Image::FORMAT_RGBA8); + switch (image->get_format()) { + case Image::FORMAT_RGB8: { + r_gl_format = GL_RGB; + r_gl_internal_format = GL_RGB; + r_gl_type = GL_UNSIGNED_BYTE; + r_real_format = Image::FORMAT_RGB8; + r_compressed = false; + } break; + case Image::FORMAT_RGBA8: { + r_gl_format = GL_RGBA; + r_gl_internal_format = GL_RGBA; + r_gl_type = GL_UNSIGNED_BYTE; + r_real_format = Image::FORMAT_RGBA8; + r_compressed = false; + } break; + default: { + image->convert(Image::FORMAT_RGBA8); + r_gl_format = GL_RGBA; + r_gl_internal_format = GL_RGBA; + r_gl_type = GL_UNSIGNED_BYTE; + r_real_format = Image::FORMAT_RGBA8; + r_compressed = false; + + } break; + } } - r_gl_format = GL_RGBA; - r_gl_internal_format = GL_RGBA; - r_gl_type = GL_UNSIGNED_BYTE; - r_real_format = Image::FORMAT_RGBA8; - return image; } @@ -395,11 +416,31 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_ } } - Image::Format real_format; - _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, format, internal_format, type, compressed); - texture->alloc_width = texture->width; texture->alloc_height = texture->height; + texture->resize_to_po2 = false; + if (!config.support_npot_repeat_mipmap) { + int po2_width = next_power_of_2(p_width); + int po2_height = next_power_of_2(p_height); + + bool is_po2 = p_width == po2_width && p_height == po2_height; + + if (!is_po2 && (p_flags & VS::TEXTURE_FLAG_REPEAT || p_flags & VS::TEXTURE_FLAG_MIPMAPS)) { + + if (p_flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) { + //not supported + ERR_PRINTS("Streaming texture for non power of 2 or has mipmaps on this hardware: " + texture->path + "'. Mipmaps and repeat disabled."); + texture->flags &= ~(VS::TEXTURE_FLAG_REPEAT | VS::TEXTURE_FLAG_MIPMAPS); + } else { + texture->alloc_height = po2_height; + texture->alloc_width = po2_width; + texture->resize_to_po2 = true; + } + } + } + + Image::Format real_format; + _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, format, internal_format, type, compressed, texture->resize_to_po2); texture->gl_format_cache = format; texture->gl_type_cache = type; @@ -414,7 +455,7 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_ if (p_flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) { //prealloc if video - glTexImage2D(texture->target, 0, internal_format, p_width, p_height, 0, format, type, NULL); + glTexImage2D(texture->target, 0, internal_format, texture->alloc_width, texture->alloc_height, 0, format, type, NULL); } texture->active = true; @@ -439,7 +480,19 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p } Image::Format real_format; - Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, real_format, format, internal_format, type, compressed); + Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, real_format, format, internal_format, type, compressed, texture->resize_to_po2); + + if (texture->resize_to_po2) { + if (p_image->is_compressed()) { + ERR_PRINTS("Texture '" + texture->path + "' was required to be a power of 2 (because it uses either mipmaps or repeat), so it was decompressed. This will hurt performance and memory usage."); + } + + if (img == p_image) { + img = img->duplicate(); + } + img->resize_to_po2(false); + img->save_png("res://popo.png"); + } if (config.shrink_textures_x2 && (p_image->has_mipmaps() || !p_image->is_compressed()) && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) { @@ -575,7 +628,7 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer) GLenum gl_internal_format; GLenum gl_type; bool compressed; - _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed); + _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed, false); PoolVector<uint8_t> data; @@ -620,7 +673,7 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer) GLenum gl_internal_format; GLenum gl_type; bool compressed; - _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed); + _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed, texture->resize_to_po2); PoolVector<uint8_t> data; @@ -4900,10 +4953,13 @@ void RasterizerStorageGLES2::initialize() { config.float_texture_supported = true; config.s3tc_supported = true; config.etc1_supported = false; + config.support_npot_repeat_mipmap = true; #else config.float_texture_supported = config.extensions.has("GL_ARB_texture_float") || config.extensions.has("GL_OES_texture_float"); config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_s3tc") || config.extensions.has("WEBGL_compressed_texture_s3tc"); config.etc1_supported = config.extensions.has("GL_OES_compressed_ETC1_RGB8_texture") || config.extensions.has("WEBGL_compressed_texture_etc1"); + config.support_npot_repeat_mipmap = config.extensions.has("GL_OES_texture_npot"); + #endif #ifdef GLES_OVER_GL config.use_rgba_2d_shadows = false; diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index a0fa2aacc5..0f1d81f70d 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -82,6 +82,7 @@ public: bool support_32_bits_indices; bool support_write_depth; bool support_half_float_vertices; + bool support_npot_repeat_mipmap; } config; struct Resources { @@ -240,6 +241,8 @@ public: int mipmaps; + bool resize_to_po2; + bool active; GLenum tex_id; @@ -275,6 +278,7 @@ public: ignore_mipmaps(false), compressed(false), mipmaps(0), + resize_to_po2(false), active(false), tex_id(0), stored_cube_sides(0), @@ -313,7 +317,7 @@ public: mutable RID_Owner<Texture> texture_owner; - Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed) const; + Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_will_need_resize) const; virtual RID texture_create(); virtual void texture_allocate(RID p_texture, int p_width, int p_height, int p_depth_3d, Image::Format p_format, VS::TextureType p_type, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT); diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index fdd905458b..d00b03fb8a 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -770,7 +770,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { /** CANVAS ITEM SHADER **/ actions[VS::SHADER_CANVAS_ITEM].renames["VERTEX"] = "outvec.xy"; - actions[VS::SHADER_CANVAS_ITEM].renames["UV"] = "uv_interp"; + actions[VS::SHADER_CANVAS_ITEM].renames["UV"] = "uv"; actions[VS::SHADER_CANVAS_ITEM].renames["POINT_SIZE"] = "gl_PointSize"; actions[VS::SHADER_CANVAS_ITEM].renames["WORLD_MATRIX"] = "modelview_matrix"; diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index 605b6a0134..c292897ad0 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -107,6 +107,7 @@ vec2 select(vec2 a, vec2 b, bvec2 c) { void main() { vec4 color = color_attrib; + vec2 uv; #ifdef USE_INSTANCING mat4 extra_matrix_instance = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0))); @@ -121,9 +122,9 @@ void main() { #ifdef USE_TEXTURE_RECT if (dst_rect.z < 0.0) { // Transpose is encoded as negative dst_rect.z - uv_interp = src_rect.xy + abs(src_rect.zw) * vertex.yx; + uv = src_rect.xy + abs(src_rect.zw) * vertex.yx; } else { - uv_interp = src_rect.xy + abs(src_rect.zw) * vertex; + uv = src_rect.xy + abs(src_rect.zw) * vertex; } vec4 outvec = vec4(0.0, 0.0, 0.0, 1.0); @@ -140,7 +141,7 @@ void main() { #else vec4 outvec = vec4(vertex.xy, 0.0, 1.0); - uv_interp = uv_attrib; + uv = uv_attrib; #endif { @@ -189,6 +190,7 @@ VERTEX_SHADER_CODE #endif + uv_interp = uv; gl_Position = projection_matrix * outvec; #ifdef USE_LIGHTING @@ -345,10 +347,14 @@ void main() { vec4 color = color_interp; vec2 uv = uv_interp; +#ifdef USE_FORCE_REPEAT + //needs to use this to workaround GLES2/WebGL1 forcing tiling that textures that dont support it + uv = mod(uv,vec2(1.0,1.0)); +#endif #if !defined(COLOR_USED) //default behavior, texture by color - color *= texture2D(color_texture, uv_interp); + color *= texture2D(color_texture, uv); #endif #ifdef SCREEN_UV_USED @@ -365,7 +371,7 @@ void main() { #endif if (use_default_normal) { - normal.xy = texture2D(normal_texture, uv_interp).xy * 2.0 - 1.0; + normal.xy = texture2D(normal_texture, uv).xy * 2.0 - 1.0; normal.z = sqrt(1.0 - dot(normal.xy, normal.xy)); normal_used = true; } else { diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index a3bc9d0ec9..112e39cb4a 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -219,7 +219,7 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options, r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "svg/scale", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 1.0)); } -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, bool p_force_rgbe, bool p_detect_normal, bool p_force_normal) { +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, bool p_force_rgbe, bool p_detect_normal, bool p_force_normal, bool p_force_po2_for_compressed) { FileAccess *f = FileAccess::open(p_to_path, FileAccess::WRITE); f->store_8('G'); @@ -227,8 +227,21 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String 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()); + bool resize_to_po2 = false; + + if (p_compress_mode == COMPRESS_VIDEO_RAM && p_force_po2_for_compressed && (p_mipmaps || p_texture_flags & Texture::FLAG_REPEAT)) { + resize_to_po2 = true; + f->store_16(next_power_of_2(p_image->get_width())); + f->store_16(p_image->get_width()); + f->store_16(next_power_of_2(p_image->get_height())); + f->store_16(p_image->get_height()); + f->store_16(0); + } else { + f->store_16(p_image->get_width()); + f->store_16(0); + f->store_16(p_image->get_height()); + f->store_16(0); + } f->store_32(p_texture_flags); uint32_t format = 0; @@ -310,6 +323,9 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String case COMPRESS_VIDEO_RAM: { Ref<Image> image = p_image->duplicate(); + if (resize_to_po2) { + image->resize_to_po2(); + } if (p_mipmaps) { image->generate_mipmaps(p_force_normal); } @@ -478,25 +494,25 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String } if (can_bptc || can_s3tc) { - _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, can_bptc ? Image::COMPRESS_BPTC : Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); + _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, can_bptc ? Image::COMPRESS_BPTC : Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, false); r_platform_variants->push_back("s3tc"); ok_on_pc = true; } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) { - _save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); + _save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, false); r_platform_variants->push_back("etc2"); } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) { - _save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); + _save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, true); r_platform_variants->push_back("etc"); } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) { - _save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC4, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); + _save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC4, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, true); r_platform_variants->push_back("pvrtc"); } @@ -505,7 +521,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String } } else { //import normally - _save_stex(image, p_save_path + ".stex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); + _save_stex(image, p_save_path + ".stex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, false); } return OK; diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index 408af1edcf..49a8b52b04 100644 --- a/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h @@ -83,7 +83,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 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, bool p_force_rgbe, bool p_detect_normal, bool p_force_normal); + 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, bool p_force_rgbe, bool p_detect_normal, bool p_force_normal, bool p_force_po2_for_compressed); 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); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index e8cc160acf..430db59e44 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -481,7 +481,7 @@ Image::Format StreamTexture::get_format() const { return format; } -Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &flags, Ref<Image> &image, int p_size_limit) { +Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, int &flags, Ref<Image> &image, int p_size_limit) { alpha_cache.unref(); @@ -497,8 +497,11 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'D' || header[2] != 'S' || header[3] != 'T', ERR_FILE_CORRUPT); } - tw = f->get_32(); - th = f->get_32(); + tw = f->get_16(); + tw_custom = f->get_16(); + th = f->get_16(); + th_custom = f->get_16(); + flags = f->get_32(); //texture flags! uint32_t df = f->get_32(); //data format @@ -705,18 +708,26 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla Error StreamTexture::load(const String &p_path) { - int lw, lh, lflags; + int lw, lh, lwc, lhc, lflags; Ref<Image> image; image.instance(); - Error err = _load_data(p_path, lw, lh, lflags, image); + Error err = _load_data(p_path, lw, lh, lwc, lhc, lflags, image); if (err) return err; + if (get_path() == String()) { + //temporarily set path if no path set for resource, helps find errors + VisualServer::get_singleton()->texture_set_path(texture, p_path); + } VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), 0, image->get_format(), VS::TEXTURE_TYPE_2D, lflags); VS::get_singleton()->texture_set_data(texture, image); + if (lwc || lhc) { + VS::get_singleton()->texture_set_size_override(texture, lwc, lhc, 0); + } else { + } - w = lw; - h = lh; + w = lwc ? lwc : lw; + h = lhc ? lhc : lh; flags = lflags; path_to_file = p_path; format = image->get_format(); @@ -784,6 +795,7 @@ bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const { decom->decompress(); img = decom; } + alpha_cache.instance(); alpha_cache->create_from_image_alpha(img); } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index dc3a3e0c74..21d3782897 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -187,7 +187,7 @@ public: }; private: - Error _load_data(const String &p_path, int &tw, int &th, int &flags, Ref<Image> &image, int p_size_limit = 0); + Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, int &flags, Ref<Image> &image, int p_size_limit = 0); String path_to_file; RID texture; Image::Format format; |