diff options
author | Juan Linietsky <reduzio@gmail.com> | 2016-01-10 21:45:11 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2016-01-10 21:45:58 -0300 |
commit | 6eb742d49f5d60fe8b61d5ac4ae72703764c6f67 (patch) | |
tree | ba6df32ae710cdc14503f36ce9c34a2237c1c578 | |
parent | b21ce6cecbd75ae3281177c4890902586ca710f7 (diff) |
-Make a rare corner case where disabling/reenabling mipmaps causes invalid texture state. Fixes #3102
-rw-r--r-- | drivers/gles2/rasterizer_gles2.cpp | 13 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.h | 3 | ||||
-rw-r--r-- | scene/gui/tabs.cpp | 84 | ||||
-rw-r--r-- | scene/gui/tabs.h | 6 | ||||
-rw-r--r-- | tools/editor/editor_node.cpp | 2 |
5 files changed, 106 insertions, 2 deletions
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 1f3b3433f9..58d5c307f0 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -929,6 +929,7 @@ void RasterizerGLES2::texture_allocate(RID p_texture,int p_width, int p_height,I texture->compressed=compressed; texture->has_alpha=false; //by default it doesn't have alpha unless something with alpha is blitteds texture->data_size=0; + texture->mipmaps=0; glActiveTexture(GL_TEXTURE0); @@ -1086,6 +1087,7 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu glGenerateMipmap(texture->target); } + texture->mipmaps=mipmaps; @@ -1269,11 +1271,14 @@ void RasterizerGLES2::texture_set_flags(RID p_texture,uint32_t p_flags) { p_flags&=VS::TEXTURE_FLAG_FILTER;//can change only filter } + bool had_mipmaps = texture->flags&VS::TEXTURE_FLAG_MIPMAPS; + glActiveTexture(GL_TEXTURE0); glBindTexture(texture->target, texture->tex_id); uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP; texture->flags=p_flags|cube; // can't remove a cube from being a cube + bool force_clamp_to_edge = !(p_flags&VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) && (nearest_power_of_2(texture->alloc_height)!=texture->alloc_height || nearest_power_of_2(texture->alloc_width)!=texture->alloc_width); if (!force_clamp_to_edge && (texture->flags&VS::TEXTURE_FLAG_REPEAT || texture->flags&VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) { @@ -1304,9 +1309,13 @@ void RasterizerGLES2::texture_set_flags(RID p_texture,uint32_t p_flags) { } } - if (texture->flags&VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) + if (texture->flags&VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) { + if (!had_mipmaps && texture->mipmaps==1) { + glGenerateMipmap(texture->target); + } glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,use_fast_texture_filter?GL_LINEAR_MIPMAP_NEAREST:GL_LINEAR_MIPMAP_LINEAR); - else{ + + } else{ if (texture->flags&VS::TEXTURE_FLAG_FILTER) { glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,GL_LINEAR); } else { diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index f3edc28861..0f70ceaa97 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -138,6 +138,8 @@ class RasterizerGLES2 : public Rasterizer { StringName reloader_func; Image image[6]; + int mipmaps; + bool active; GLuint tex_id; @@ -159,6 +161,7 @@ class RasterizerGLES2 : public Rasterizer { compressed=false; total_data_size=0; target=GL_TEXTURE_2D; + mipmaps=0; reloader=0; } diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index 14cd0bee8e..bb64a57212 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -266,6 +266,7 @@ void Tabs::_notification(int p_what) { int label_valign_fg = get_constant("label_valign_fg"); int label_valign_bg = get_constant("label_valign_bg"); + int w=0; int mw = 0; @@ -277,12 +278,16 @@ void Tabs::_notification(int p_what) { for(int i=0;i<tabs.size();i++) { + Ref<Texture> tex = tabs[i].icon; if (tex.is_valid()) { if (tabs[i].text!="") mw+=get_constant("hseparation"); } + + tabs[i].ofs_cache=mw; + mw+=font->get_string_size(tabs[i].text).width; if (current==i) mw+=tab_fg->get_minimum_size().width; @@ -303,6 +308,9 @@ void Tabs::_notification(int p_what) { bms.width+=get_constant("hseparation"); mw+=bms.width; } + + + } } @@ -758,6 +766,79 @@ Tabs::TabAlign Tabs::get_tab_align() const { } +void Tabs::ensure_tab_visible(int p_idx) { + + if (!is_inside_tree()) + return; + + ERR_FAIL_INDEX(p_idx,tabs.size()); + + if (p_idx<offset) { + offset=p_idx; + update(); + return; + } + + Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); + Ref<StyleBox> tab_fg = get_stylebox("tab_fg"); + Ref<Font> font = get_font("font"); + + Ref<Texture> incr = get_icon("increment"); + Ref<Texture> decr = get_icon("decrement"); + + int limit=get_size().width-incr->get_width()-decr->get_width(); + + + + int x=0; + for(int i=0;i<tabs.size();i++) { + + if (i<offset) + continue; + + Ref<Texture> tex = tabs[i].icon; + if (tex.is_valid()) { + if (tabs[i].text!="") + x+=get_constant("hseparation"); + + } + + tabs[i].x_cache=x; + + x+=font->get_string_size(tabs[i].text).width; + if (current==i) + x+=tab_fg->get_minimum_size().width; + else + x+=tab_bg->get_minimum_size().width; + + if (tabs[i].right_button.is_valid()) { + Ref<Texture> rb=tabs[i].right_button; + Size2 bms = rb->get_size();//+get_stylebox("button")->get_minimum_size(); + bms.width+=get_constant("hseparation"); + + x+=bms.width; + } + + if (tabs[i].close_button.is_valid()) { + Ref<Texture> cb=tabs[i].close_button; + Size2 bms = cb->get_size();//+get_stylebox("button")->get_minimum_size(); + bms.width+=get_constant("hseparation"); + x+=bms.width; + } + + tabs[i].x_size_cache=x-tabs[i].x_cache; + + + + } + + while(offset<tabs.size() && ( (tabs[p_idx].x_cache + tabs[p_idx].x_size_cache) - tabs[offset].x_cache) < limit) { + offset++; + } + + update(); +} + void Tabs::_bind_methods() { ObjectTypeDB::bind_method(_MD("_input_event"),&Tabs::_input_event); @@ -772,6 +853,7 @@ void Tabs::_bind_methods() { ObjectTypeDB::bind_method(_MD("add_tab","title","icon:Texture"),&Tabs::add_tab); ObjectTypeDB::bind_method(_MD("set_tab_align","align"),&Tabs::set_tab_align); ObjectTypeDB::bind_method(_MD("get_tab_align"),&Tabs::get_tab_align); + ObjectTypeDB::bind_method(_MD("ensure_tab_visible","idx"),&Tabs::ensure_tab_visible); ADD_SIGNAL(MethodInfo("tab_changed",PropertyInfo(Variant::INT,"tab"))); ADD_SIGNAL(MethodInfo("right_button_pressed",PropertyInfo(Variant::INT,"tab"))); @@ -804,4 +886,6 @@ Tabs::Tabs() { cb_displaypolicy = SHOW_NEVER; // Default : no close button offset=0; max_drawn_tab=0; + + } diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index efcb291a52..82035291ec 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -59,10 +59,14 @@ private: Ref<Texture> icon; int ofs_cache; int size_cache; + int x_cache; + int x_size_cache; + Ref<Texture> right_button; Rect2 rb_rect; Ref<Texture> close_button; Rect2 cb_rect; + }; @@ -119,6 +123,8 @@ public: void clear_tabs(); + void ensure_tab_visible(int p_idx); + Size2 get_minimum_size() const; Tabs(); diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 462153a183..d7708fcefd 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -4723,11 +4723,13 @@ void EditorNode::_scene_tab_changed(int p_tab) { editor_data.get_undo_redo().add_do_method(this,"set_current_version",unsaved?saved_version:0); editor_data.get_undo_redo().add_do_method(this,"set_current_scene",p_tab); editor_data.get_undo_redo().add_do_method(scene_tabs,"set_current_tab",p_tab); + editor_data.get_undo_redo().add_do_method(scene_tabs,"ensure_tab_visible",p_tab); editor_data.get_undo_redo().add_do_method(this,"set_current_version",next_scene_version==0?editor_data.get_undo_redo().get_version()+1:next_scene_version); editor_data.get_undo_redo().add_undo_method(this,"set_current_version",next_scene_version); editor_data.get_undo_redo().add_undo_method(this,"set_current_scene",editor_data.get_edited_scene()); editor_data.get_undo_redo().add_undo_method(scene_tabs,"set_current_tab",editor_data.get_edited_scene()); + editor_data.get_undo_redo().add_undo_method(scene_tabs,"ensure_tab_visible",p_tab,editor_data.get_edited_scene()); editor_data.get_undo_redo().add_undo_method(this,"set_current_version",saved_version); editor_data.get_undo_redo().commit_action(); |