|
@@ -67,7 +67,7 @@ void RasterizerStorageGLES2::bind_quad_array() const {
|
|
glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
|
|
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;
|
|
r_gl_format = 0;
|
|
Ref<Image> image = p_image;
|
|
Ref<Image> image = p_image;
|
|
@@ -195,7 +195,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
|
|
} break;
|
|
} break;
|
|
case Image::FORMAT_DXT1: {
|
|
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_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
|
r_gl_format = GL_RGBA;
|
|
r_gl_format = GL_RGBA;
|
|
r_gl_type = GL_UNSIGNED_BYTE;
|
|
r_gl_type = GL_UNSIGNED_BYTE;
|
|
@@ -207,7 +207,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
|
|
} break;
|
|
} break;
|
|
case Image::FORMAT_DXT3: {
|
|
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_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
|
r_gl_format = GL_RGBA;
|
|
r_gl_format = GL_RGBA;
|
|
r_gl_type = GL_UNSIGNED_BYTE;
|
|
r_gl_type = GL_UNSIGNED_BYTE;
|
|
@@ -219,7 +219,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
|
|
} break;
|
|
} break;
|
|
case Image::FORMAT_DXT5: {
|
|
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_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
|
r_gl_format = GL_RGBA;
|
|
r_gl_format = GL_RGBA;
|
|
r_gl_type = GL_UNSIGNED_BYTE;
|
|
r_gl_type = GL_UNSIGNED_BYTE;
|
|
@@ -269,7 +269,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
|
|
} break;
|
|
} break;
|
|
case Image::FORMAT_ETC: {
|
|
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_internal_format = _EXT_ETC1_RGB8_OES;
|
|
r_gl_format = GL_RGBA;
|
|
r_gl_format = GL_RGBA;
|
|
r_gl_type = GL_UNSIGNED_BYTE;
|
|
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 (need_decompress) {
|
|
|
|
|
|
if (!image.is_null()) {
|
|
if (!image.is_null()) {
|
|
|
|
+
|
|
image = image->duplicate();
|
|
image = image->duplicate();
|
|
|
|
+ print_line("decompressing...");
|
|
image->decompress();
|
|
image->decompress();
|
|
ERR_FAIL_COND_V(image->is_compressed(), image);
|
|
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;
|
|
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_width = texture->width;
|
|
texture->alloc_height = texture->height;
|
|
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_format_cache = format;
|
|
texture->gl_type_cache = type;
|
|
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) {
|
|
if (p_flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) {
|
|
//prealloc if video
|
|
//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;
|
|
texture->active = true;
|
|
@@ -439,7 +480,19 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p
|
|
}
|
|
}
|
|
|
|
|
|
Image::Format real_format;
|
|
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)) {
|
|
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_internal_format;
|
|
GLenum gl_type;
|
|
GLenum gl_type;
|
|
bool compressed;
|
|
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;
|
|
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_internal_format;
|
|
GLenum gl_type;
|
|
GLenum gl_type;
|
|
bool compressed;
|
|
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;
|
|
PoolVector<uint8_t> data;
|
|
|
|
|
|
@@ -4900,10 +4953,13 @@ void RasterizerStorageGLES2::initialize() {
|
|
config.float_texture_supported = true;
|
|
config.float_texture_supported = true;
|
|
config.s3tc_supported = true;
|
|
config.s3tc_supported = true;
|
|
config.etc1_supported = false;
|
|
config.etc1_supported = false;
|
|
|
|
+ config.support_npot_repeat_mipmap = true;
|
|
#else
|
|
#else
|
|
config.float_texture_supported = config.extensions.has("GL_ARB_texture_float") || config.extensions.has("GL_OES_texture_float");
|
|
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.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.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
|
|
#endif
|
|
#ifdef GLES_OVER_GL
|
|
#ifdef GLES_OVER_GL
|
|
config.use_rgba_2d_shadows = false;
|
|
config.use_rgba_2d_shadows = false;
|