ability to shrink all images x2 on load
this is for extreme cases when running on devices with very low video memory, so you can still retain compatibility.
This commit is contained in:
parent
4bc494ae2e
commit
d6e30256ad
|
@ -901,6 +901,66 @@ static void _generate_po2_mipmap(const uint8_t* p_src, uint8_t* p_dst, uint32_t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Image::shrink_x2() {
|
||||||
|
|
||||||
|
ERR_FAIL_COND(format==FORMAT_INDEXED || format==FORMAT_INDEXED_ALPHA);
|
||||||
|
ERR_FAIL_COND( data.size()==0 );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (mipmaps) {
|
||||||
|
|
||||||
|
//just use the lower mipmap as base and copy all
|
||||||
|
DVector<uint8_t> new_img;
|
||||||
|
|
||||||
|
int ofs = get_mipmap_offset(1);
|
||||||
|
|
||||||
|
int new_size = data.size()-ofs;
|
||||||
|
new_img.resize(new_size);
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
DVector<uint8_t>::Write w=new_img.write();
|
||||||
|
DVector<uint8_t>::Read r=data.read();
|
||||||
|
|
||||||
|
copymem(w.ptr(),&r[ofs],new_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
mipmaps--;
|
||||||
|
width/=2;
|
||||||
|
height/=2;
|
||||||
|
data=new_img;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
DVector<uint8_t> new_img;
|
||||||
|
|
||||||
|
ERR_FAIL_COND( format>=FORMAT_INDEXED );
|
||||||
|
int ps = get_format_pixel_size(format);
|
||||||
|
new_img.resize((width/2)*(height/2)*ps);
|
||||||
|
|
||||||
|
{
|
||||||
|
DVector<uint8_t>::Write w=new_img.write();
|
||||||
|
DVector<uint8_t>::Read r=data.read();
|
||||||
|
|
||||||
|
switch(format) {
|
||||||
|
|
||||||
|
case FORMAT_GRAYSCALE:
|
||||||
|
case FORMAT_INTENSITY: _generate_po2_mipmap<1>(r.ptr(), w.ptr(), width,height); break;
|
||||||
|
case FORMAT_GRAYSCALE_ALPHA: _generate_po2_mipmap<2>(r.ptr(), w.ptr(), width,height); break;
|
||||||
|
case FORMAT_RGB: _generate_po2_mipmap<3>(r.ptr(), w.ptr(), width,height); break;
|
||||||
|
case FORMAT_RGBA: _generate_po2_mipmap<4>(r.ptr(), w.ptr(), width,height); break;
|
||||||
|
default: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width/=2;
|
||||||
|
height/=2;
|
||||||
|
data=new_img;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Error Image::generate_mipmaps(int p_mipmaps,bool p_keep_existing) {
|
Error Image::generate_mipmaps(int p_mipmaps,bool p_keep_existing) {
|
||||||
|
|
||||||
if (!_can_modify(format)) {
|
if (!_can_modify(format)) {
|
||||||
|
|
|
@ -248,6 +248,7 @@ public:
|
||||||
void resize_to_po2(bool p_square=false);
|
void resize_to_po2(bool p_square=false);
|
||||||
void resize( int p_width, int p_height, Interpolation p_interpolation=INTERPOLATE_BILINEAR );
|
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 );
|
Image resized( int p_width, int p_height, int p_interpolation=INTERPOLATE_BILINEAR );
|
||||||
|
void shrink_x2();
|
||||||
/**
|
/**
|
||||||
* Crop the image to a specific size, if larger, then the image is filled by black
|
* Crop the image to a specific size, if larger, then the image is filled by black
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -921,6 +921,11 @@ void RasterizerGLES2::texture_allocate(RID p_texture,int p_width, int p_height,I
|
||||||
texture->alloc_height = texture->height;
|
texture->alloc_height = texture->height;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (shrink_textures_x2) {
|
||||||
|
texture->alloc_height = MAX(1,texture->alloc_height/2);
|
||||||
|
texture->alloc_width = MAX(1,texture->alloc_width/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
texture->gl_components_cache=components;
|
texture->gl_components_cache=components;
|
||||||
texture->gl_format_cache=format;
|
texture->gl_format_cache=format;
|
||||||
|
@ -970,8 +975,15 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu
|
||||||
|
|
||||||
if (texture->alloc_width != img.get_width() || texture->alloc_height != img.get_height()) {
|
if (texture->alloc_width != img.get_width() || texture->alloc_height != img.get_height()) {
|
||||||
|
|
||||||
if (img.get_format() <= Image::FORMAT_INDEXED_ALPHA)
|
|
||||||
|
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_INDEXED_ALPHA) {
|
||||||
|
|
||||||
img.resize(texture->alloc_width, texture->alloc_height, Image::INTERPOLATE_BILINEAR);
|
img.resize(texture->alloc_width, texture->alloc_height, Image::INTERPOLATE_BILINEAR);
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1452,6 +1464,11 @@ void RasterizerGLES2::texture_debug_usage(List<VS::TextureInfo> *r_info){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterizerGLES2::texture_set_shrink_all_x2_on_set_data(bool p_enable) {
|
||||||
|
|
||||||
|
shrink_textures_x2=p_enable;
|
||||||
|
}
|
||||||
|
|
||||||
/* SHADER API */
|
/* SHADER API */
|
||||||
|
|
||||||
RID RasterizerGLES2::shader_create(VS::ShaderMode p_mode) {
|
RID RasterizerGLES2::shader_create(VS::ShaderMode p_mode) {
|
||||||
|
|
|
@ -108,6 +108,8 @@ class RasterizerGLES2 : public Rasterizer {
|
||||||
bool use_half_float;
|
bool use_half_float;
|
||||||
bool low_memory_2d;
|
bool low_memory_2d;
|
||||||
|
|
||||||
|
bool shrink_textures_x2;
|
||||||
|
|
||||||
Vector<float> skel_default;
|
Vector<float> skel_default;
|
||||||
|
|
||||||
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,int &r_gl_components,bool &r_has_alpha_cache,bool &r_compressed);
|
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,int &r_gl_components,bool &r_has_alpha_cache,bool &r_compressed);
|
||||||
|
@ -1334,6 +1336,8 @@ public:
|
||||||
virtual String texture_get_path(RID p_texture) const;
|
virtual String texture_get_path(RID p_texture) const;
|
||||||
virtual void texture_debug_usage(List<VS::TextureInfo> *r_info);
|
virtual void texture_debug_usage(List<VS::TextureInfo> *r_info);
|
||||||
|
|
||||||
|
virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable);
|
||||||
|
|
||||||
GLuint _texture_get_name(RID p_tex);
|
GLuint _texture_get_name(RID p_tex);
|
||||||
|
|
||||||
/* SHADER API */
|
/* SHADER API */
|
||||||
|
|
|
@ -196,6 +196,8 @@ public:
|
||||||
virtual String texture_get_path(RID p_texture) const=0;
|
virtual String texture_get_path(RID p_texture) const=0;
|
||||||
virtual void texture_debug_usage(List<VS::TextureInfo> *r_info)=0;
|
virtual void texture_debug_usage(List<VS::TextureInfo> *r_info)=0;
|
||||||
|
|
||||||
|
virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable)=0;
|
||||||
|
|
||||||
/* SHADER API */
|
/* SHADER API */
|
||||||
|
|
||||||
virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL)=0;
|
virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL)=0;
|
||||||
|
|
|
@ -415,6 +415,8 @@ public:
|
||||||
virtual String texture_get_path(RID p_texture) const { return String(); }
|
virtual String texture_get_path(RID p_texture) const { return String(); }
|
||||||
virtual void texture_debug_usage(List<VS::TextureInfo> *r_info) {}
|
virtual void texture_debug_usage(List<VS::TextureInfo> *r_info) {}
|
||||||
|
|
||||||
|
virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable) {}
|
||||||
|
|
||||||
/* SHADER API */
|
/* SHADER API */
|
||||||
|
|
||||||
virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL);
|
virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL);
|
||||||
|
|
|
@ -127,6 +127,11 @@ void VisualServerRaster::texture_debug_usage(List<TextureInfo> *r_info){
|
||||||
rasterizer->texture_debug_usage(r_info);
|
rasterizer->texture_debug_usage(r_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VisualServerRaster::texture_set_shrink_all_x2_on_set_data(bool p_enable) {
|
||||||
|
|
||||||
|
rasterizer->texture_set_shrink_all_x2_on_set_data(p_enable);
|
||||||
|
}
|
||||||
|
|
||||||
/* SHADER API */
|
/* SHADER API */
|
||||||
|
|
||||||
RID VisualServerRaster::shader_create(ShaderMode p_mode) {
|
RID VisualServerRaster::shader_create(ShaderMode p_mode) {
|
||||||
|
|
|
@ -659,7 +659,7 @@ public:
|
||||||
|
|
||||||
virtual RID texture_create();
|
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=TEXTURE_FLAGS_DEFAULT);
|
virtual void texture_allocate(RID p_texture,int p_width, int p_height,Image::Format p_format,uint32_t p_flags=TEXTURE_FLAGS_DEFAULT);
|
||||||
virtual void texture_set_data(RID p_texture,const Image& p_image,CubeMapSide p_cube_side=CUBEMAP_LEFT);
|
virtual void texture_set_data(RID p_texture,const Image& p_image,CubeMapSide p_cube_side=CUBEMAP_LEFT);
|
||||||
virtual Image texture_get_data(RID p_texture,CubeMapSide p_cube_side=CUBEMAP_LEFT) const;
|
virtual Image texture_get_data(RID p_texture,CubeMapSide p_cube_side=CUBEMAP_LEFT) const;
|
||||||
virtual void texture_set_flags(RID p_texture,uint32_t p_flags) ;
|
virtual void texture_set_flags(RID p_texture,uint32_t p_flags) ;
|
||||||
virtual uint32_t texture_get_flags(RID p_texture) const;
|
virtual uint32_t texture_get_flags(RID p_texture) const;
|
||||||
|
@ -675,6 +675,8 @@ public:
|
||||||
|
|
||||||
virtual void texture_debug_usage(List<TextureInfo> *r_info);
|
virtual void texture_debug_usage(List<TextureInfo> *r_info);
|
||||||
|
|
||||||
|
virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable);
|
||||||
|
|
||||||
|
|
||||||
/* SHADER API */
|
/* SHADER API */
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,8 @@ public:
|
||||||
FUNC2(texture_set_path,RID,const String&);
|
FUNC2(texture_set_path,RID,const String&);
|
||||||
FUNC1RC(String,texture_get_path,RID);
|
FUNC1RC(String,texture_get_path,RID);
|
||||||
|
|
||||||
|
FUNC1(texture_set_shrink_all_x2_on_set_data,bool);
|
||||||
|
|
||||||
virtual void texture_debug_usage(List<TextureInfo> *r_info) {
|
virtual void texture_debug_usage(List<TextureInfo> *r_info) {
|
||||||
//pass directly, should lock the server anyway
|
//pass directly, should lock the server anyway
|
||||||
visual_server->texture_debug_usage(r_info);
|
visual_server->texture_debug_usage(r_info);
|
||||||
|
|
|
@ -355,8 +355,12 @@ void VisualServer::_bind_methods() {
|
||||||
ObjectTypeDB::bind_method(_MD("texture_get_flags"),&VisualServer::texture_get_flags );
|
ObjectTypeDB::bind_method(_MD("texture_get_flags"),&VisualServer::texture_get_flags );
|
||||||
ObjectTypeDB::bind_method(_MD("texture_get_width"),&VisualServer::texture_get_width );
|
ObjectTypeDB::bind_method(_MD("texture_get_width"),&VisualServer::texture_get_width );
|
||||||
ObjectTypeDB::bind_method(_MD("texture_get_height"),&VisualServer::texture_get_height );
|
ObjectTypeDB::bind_method(_MD("texture_get_height"),&VisualServer::texture_get_height );
|
||||||
|
|
||||||
|
ObjectTypeDB::bind_method(_MD("texture_set_shrink_all_x2_on_set_data","shrink"),&VisualServer::texture_set_shrink_all_x2_on_set_data );
|
||||||
|
|
||||||
#ifndef _3D_DISABLED
|
#ifndef _3D_DISABLED
|
||||||
|
|
||||||
|
|
||||||
ObjectTypeDB::bind_method(_MD("shader_create","mode"),&VisualServer::shader_create,DEFVAL(SHADER_MATERIAL));
|
ObjectTypeDB::bind_method(_MD("shader_create","mode"),&VisualServer::shader_create,DEFVAL(SHADER_MATERIAL));
|
||||||
ObjectTypeDB::bind_method(_MD("shader_set_mode","shader","mode"),&VisualServer::shader_set_mode);
|
ObjectTypeDB::bind_method(_MD("shader_set_mode","shader","mode"),&VisualServer::shader_set_mode);
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,8 @@ public:
|
||||||
virtual void texture_set_path(RID p_texture,const String& p_path)=0;
|
virtual void texture_set_path(RID p_texture,const String& p_path)=0;
|
||||||
virtual String texture_get_path(RID p_texture) const=0;
|
virtual String texture_get_path(RID p_texture) const=0;
|
||||||
|
|
||||||
|
virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable)=0;
|
||||||
|
|
||||||
struct TextureInfo {
|
struct TextureInfo {
|
||||||
RID texture;
|
RID texture;
|
||||||
Size2 size;
|
Size2 size;
|
||||||
|
|
Loading…
Reference in New Issue