Many separate fixes to ensure non power of 2 textures work on GLES2, closes #25897 and many others

This commit is contained in:
Juan Linietsky 2019-02-24 22:34:12 -03:00
parent 5f34664f61
commit 74d0ed2236
9 changed files with 158 additions and 44 deletions

View file

@ -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: {

View file

@ -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,16 +315,37 @@ 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;
r_gl_format = GL_RGBA;
r_gl_internal_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_real_format = Image::FORMAT_RGBA8;
} break;
}
}
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;

View file

@ -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);

View file

@ -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";

View file

@ -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 {

View file

@ -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;

View file

@ -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);

View file

@ -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);
}

View file

@ -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;