summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/image.cpp60
-rw-r--r--core/image.h1
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp19
-rw-r--r--drivers/gles2/rasterizer_gles2.h4
-rw-r--r--servers/visual/rasterizer.h2
-rw-r--r--servers/visual/rasterizer_dummy.h2
-rw-r--r--servers/visual/visual_server_raster.cpp5
-rw-r--r--servers/visual/visual_server_raster.h4
-rw-r--r--servers/visual/visual_server_wrap_mt.h2
-rw-r--r--servers/visual_server.cpp4
-rw-r--r--servers/visual_server.h2
11 files changed, 103 insertions, 2 deletions
diff --git a/core/image.cpp b/core/image.cpp
index 52946bbb85..8635aa1b29 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -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) {
if (!_can_modify(format)) {
diff --git a/core/image.h b/core/image.h
index fe1822f661..35bbd1a684 100644
--- a/core/image.h
+++ b/core/image.h
@@ -249,6 +249,7 @@ public:
void resize_to_po2(bool p_square=false);
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 );
+ void shrink_x2();
/**
* Crop the image to a specific size, if larger, then the image is filled by black
*/
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 373de2bb22..20d1ca956a 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -921,6 +921,11 @@ void RasterizerGLES2::texture_allocate(RID p_texture,int p_width, int p_height,I
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_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 (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);
+
+ }
};
@@ -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 */
RID RasterizerGLES2::shader_create(VS::ShaderMode p_mode) {
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index 2a2f587f11..b52918c02f 100644
--- a/drivers/gles2/rasterizer_gles2.h
+++ b/drivers/gles2/rasterizer_gles2.h
@@ -108,6 +108,8 @@ class RasterizerGLES2 : public Rasterizer {
bool use_half_float;
bool low_memory_2d;
+ bool shrink_textures_x2;
+
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);
@@ -1336,6 +1338,8 @@ public:
virtual String texture_get_path(RID p_texture) const;
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);
/* SHADER API */
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index e2de20785a..e3d1b14835 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -196,6 +196,8 @@ public:
virtual String texture_get_path(RID p_texture) const=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 */
virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL)=0;
diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h
index efa843839a..674c165966 100644
--- a/servers/visual/rasterizer_dummy.h
+++ b/servers/visual/rasterizer_dummy.h
@@ -415,6 +415,8 @@ public:
virtual String texture_get_path(RID p_texture) const { return String(); }
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 */
virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL);
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 1db7971d3b..ad85ecc7c0 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -127,6 +127,11 @@ void VisualServerRaster::texture_debug_usage(List<TextureInfo> *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 */
RID VisualServerRaster::shader_create(ShaderMode p_mode) {
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 2b72b0b900..cb9e96e284 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -657,7 +657,7 @@ public:
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_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 void texture_set_flags(RID p_texture,uint32_t p_flags) ;
virtual uint32_t texture_get_flags(RID p_texture) const;
@@ -673,6 +673,8 @@ public:
virtual void texture_debug_usage(List<TextureInfo> *r_info);
+ virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable);
+
/* SHADER API */
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index b6018f1c25..6a42fcc8a6 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -101,6 +101,8 @@ public:
FUNC2(texture_set_path,RID,const String&);
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) {
//pass directly, should lock the server anyway
visual_server->texture_debug_usage(r_info);
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 17d5b16b9f..5ac0e5b5d5 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -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_width"),&VisualServer::texture_get_width );
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
+
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);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index c70a72ef2a..750c090bbe 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -138,6 +138,8 @@ public:
virtual void texture_set_path(RID p_texture,const String& p_path)=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 {
RID texture;
Size2 size;