diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 0c07abb0028..a8895f7bfc1 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -466,8 +466,10 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); - glVertexAttrib4f(1, rect->rect.position.x, rect->rect.position.y, rect->rect.size.x, rect->rect.size.y); - glVertexAttrib4f(2, src_rect.position.x, src_rect.position.y, src_rect.size.x, src_rect.size.y); + state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(rect->rect.position.x, rect->rect.position.y, rect->rect.size.x, rect->rect.size.y)); + state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(src_rect.position.x, src_rect.position.y, src_rect.size.x, src_rect.size.y)); + state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, (rect->flags & CANVAS_RECT_CLIP_UV) ? true : false); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); if (untile) { @@ -477,8 +479,9 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur } else { - glVertexAttrib4f(1, rect->rect.position.x, rect->rect.position.y, rect->rect.size.x, rect->rect.size.y); - glVertexAttrib4f(2, 0, 0, 1, 1); + state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(rect->rect.position.x, rect->rect.position.y, rect->rect.size.x, rect->rect.size.y)); + state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(0, 0, 1, 1)); + state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, false); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } @@ -507,9 +510,10 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); + state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, false); -#define DSTRECT(m_x, m_y, m_w, m_h) glVertexAttrib4f(1, m_x, m_y, m_w, m_h) -#define SRCRECT(m_x, m_y, m_w, m_h) glVertexAttrib4f(2, (m_x)*texpixel_size.x, (m_y)*texpixel_size.y, (m_w)*texpixel_size.x, (m_h)*texpixel_size.y) +#define DSTRECT(m_x, m_y, m_w, m_h) state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(m_x, m_y, m_w, m_h)) +#define SRCRECT(m_x, m_y, m_w, m_h) state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color((m_x)*texpixel_size.x, (m_y)*texpixel_size.y, (m_w)*texpixel_size.x, (m_h)*texpixel_size.y)) //top left DSTRECT(np->rect.position.x, np->rect.position.y, np->margin[MARGIN_LEFT], np->margin[MARGIN_TOP]); @@ -1312,8 +1316,10 @@ void RasterizerCanvasGLES3::reset_canvas() { void RasterizerCanvasGLES3::draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src) { - glVertexAttrib4f(1, p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y); - glVertexAttrib4f(2, p_src.position.x, p_src.position.y, p_src.size.x, p_src.size.y); + state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y)); + state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(p_src.position.x, p_src.position.y, p_src.size.x, p_src.size.y)); + state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, false); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index b0ce38cb68b..7be6ee857ac 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -6,8 +6,8 @@ layout(location=3) in vec4 color_attrib; #ifdef USE_TEXTURE_RECT -layout(location=1) in highp vec4 dst_rect; -layout(location=2) in highp vec4 src_rect; +uniform vec4 dst_rect; +uniform vec4 src_rect; #else @@ -65,6 +65,7 @@ const bool at_light_pass = false; #endif + VERTEX_SHADER_GLOBALS #if defined(USE_MATERIAL) @@ -228,22 +229,39 @@ LIGHT_SHADER_CODE } +#ifdef USE_TEXTURE_RECT + +uniform vec4 dst_rect; +uniform vec4 src_rect; +uniform bool clip_rect_uv; + +#endif + uniform bool use_default_normal; void main() { vec4 color = color_interp; + vec2 uv = uv_interp; +#ifdef USE_TEXTURE_RECT + if (clip_rect_uv) { + + vec2 half_texpixel = color_texpixel_size * 0.5; + uv = clamp(uv,src_rect.xy+half_texpixel,src_rect.xy+abs(src_rect.zw)-color_texpixel_size); + } + +#endif #if !defined(COLOR_USED) //default behavior, texture by color #ifdef USE_DISTANCE_FIELD const float smoothing = 1.0/32.0; - float distance = textureLod(color_texture, uv_interp,0.0).a; + float distance = textureLod(color_texture, uv,0.0).a; color.a = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance) * color.a; #else - color *= texture( color_texture, uv_interp ); + color *= texture( color_texture, uv ); #endif @@ -259,7 +277,7 @@ void main() { #endif if (use_default_normal) { - normal.xy = textureLod(normal_texture, uv_interp,0.0).xy * 2.0 - 1.0; + normal.xy = textureLod(normal_texture, uv,0.0).xy * 2.0 - 1.0; normal.z = sqrt(1.0-dot(normal.xy,normal.xy)); normal_used=true; } else { diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 4f3a20d61ff..471f529713a 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -459,14 +459,14 @@ void CanvasItem::draw_texture_rect(const Ref &p_texture, const Rect2 &p ERR_FAIL_COND(p_texture.is_null()); p_texture->draw_rect(canvas_item, p_rect, p_tile, p_modulate, p_transpose, p_normal_map); } -void CanvasItem::draw_texture_rect_region(const Ref &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref &p_normal_map) { +void CanvasItem::draw_texture_rect_region(const Ref &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref &p_normal_map, bool p_clip_uv) { if (!drawing) { ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); ERR_FAIL(); } ERR_FAIL_COND(p_texture.is_null()); - p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_normal_map); + p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_normal_map, p_clip_uv); } void CanvasItem::draw_style_box(const Ref &p_style_box, const Rect2 &p_rect) { @@ -758,7 +758,7 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_circle", "pos", "radius", "color"), &CanvasItem::draw_circle); ClassDB::bind_method(D_METHOD("draw_texture", "texture:Texture", "pos", "modulate", "normal_map:Texture"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture:Texture", "rect", "tile", "modulate", "transpose", "normal_map:Texture"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("draw_texture_rect_region", "texture:Texture", "rect", "src_rect", "modulate", "transpose", "normal_map:Texture"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("draw_texture_rect_region", "texture:Texture", "rect", "src_rect", "modulate", "transpose", "normal_map:Texture", "clip_uv"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(true)); ClassDB::bind_method(D_METHOD("draw_style_box", "style_box:StyleBox", "rect"), &CanvasItem::draw_style_box); ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture:Texture", "width", "normal_map:Texture"), &CanvasItem::draw_primitive, DEFVAL(Variant()), DEFVAL(1.0), DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture:Texture", "normal_map:Texture"), &CanvasItem::draw_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant())); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index b47dbd00fa1..595dd03057e 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -160,7 +160,7 @@ public: void draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color); void draw_texture(const Ref &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1), const Ref &p_normal_map = Ref()); void draw_texture_rect(const Ref &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()); - void draw_texture_rect_region(const Ref &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()); + void draw_texture_rect_region(const Ref &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref(), bool p_clip_uv = true); void draw_style_box(const Ref &p_style_box, const Rect2 &p_rect); void draw_primitive(const Vector &p_points, const Vector &p_colors, const Vector &p_uvs, Ref p_texture = Ref(), float p_width = 1, const Ref &p_normal_map = Ref()); void draw_polygon(const Vector &p_points, const Vector &p_colors, const Vector &p_uvs = Vector(), Ref p_texture = Ref(), const Ref &p_normal_map = Ref()); diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index dedec2dd49e..ff574a6bd61 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -65,11 +65,13 @@ void Sprite::_notification(int p_what) { Size2 s; Rect2 src_rect; + bool filter_clip = false; if (region) { s = region_rect.size; src_rect = region_rect; + filter_clip = region_filter_clip; } else { s = Size2(texture->get_size()); s = s / Size2(hframes, vframes); @@ -93,7 +95,7 @@ void Sprite::_notification(int p_what) { if (vflip) dst_rect.size.y = -dst_rect.size.y; - texture->draw_rect_region(ci, dst_rect, src_rect, Color(1, 1, 1), false, normal_map); + texture->draw_rect_region(ci, dst_rect, src_rect, Color(1, 1, 1), false, normal_map, filter_clip); } break; } @@ -214,6 +216,15 @@ Rect2 Sprite::get_region_rect() const { return region_rect; } +void Sprite::set_region_filter_clip(bool p_enable) { + region_filter_clip = p_enable; + update(); +} + +bool Sprite::is_region_filter_clip_enabled() const { + return region_filter_clip; +} + void Sprite::set_frame(int p_frame) { ERR_FAIL_INDEX(p_frame, vframes * hframes); @@ -323,6 +334,9 @@ void Sprite::_bind_methods() { ClassDB::bind_method(D_METHOD("set_region_rect", "rect"), &Sprite::set_region_rect); ClassDB::bind_method(D_METHOD("get_region_rect"), &Sprite::get_region_rect); + ClassDB::bind_method(D_METHOD("set_region_filter_clip", "enabled"), &Sprite::set_region_filter_clip); + ClassDB::bind_method(D_METHOD("is_region_filter_clip_enabled"), &Sprite::is_region_filter_clip_enabled); + ClassDB::bind_method(D_METHOD("set_frame", "frame"), &Sprite::set_frame); ClassDB::bind_method(D_METHOD("get_frame"), &Sprite::get_frame); @@ -344,8 +358,11 @@ void Sprite::_bind_methods() { ADD_PROPERTYNO(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes"); ADD_PROPERTYNO(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes"); ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "region"), "set_region", "is_region"); + + ADD_GROUP("Region", "region_"); + ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region", "is_region"); ADD_PROPERTYNZ(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); + ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "region_filter_clip"), "set_region_filter_clip", "is_region_filter_clip_enabled"); } Sprite::Sprite() { @@ -354,6 +371,7 @@ Sprite::Sprite() { hflip = false; vflip = false; region = false; + region_filter_clip = false; frame = 0; diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h index 3b5d031e92e..d3f9a5f0325 100644 --- a/scene/2d/sprite.h +++ b/scene/2d/sprite.h @@ -47,6 +47,7 @@ class Sprite : public Node2D { bool vflip; bool region; Rect2 region_rect; + bool region_filter_clip; int frame; @@ -86,6 +87,9 @@ public: void set_region(bool p_region); bool is_region() const; + void set_region_filter_clip(bool p_enable); + bool is_region_filter_clip_enabled() const; + void set_region_rect(const Rect2 &p_region_rect); Rect2 get_region_rect() const; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 1682971f9c9..2120b37497f 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -46,10 +46,10 @@ void Texture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, con RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose, normal_rid); } -void Texture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref &p_normal_map) const { +void Texture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref &p_normal_map, bool p_clip_uv) const { RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, normal_rid); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv); } bool Texture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const { @@ -70,7 +70,7 @@ void Texture::_bind_methods() { ClassDB::bind_method(D_METHOD("get_flags"), &Texture::get_flags); ClassDB::bind_method(D_METHOD("draw", "canvas_item", "pos", "modulate", "transpose", "normal_map:Texture"), &Texture::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose", "normal_map:Texture"), &Texture::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "normal_map:Texture"), &Texture::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "normal_map:Texture", "clip_uv"), &Texture::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(true)); BIND_CONSTANT(FLAG_MIPMAPS); BIND_CONSTANT(FLAG_REPEAT); @@ -282,12 +282,12 @@ void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid); } -void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref &p_normal_map) const { +void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref &p_normal_map, bool p_clip_uv) const { if ((w | h) == 0) return; RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv); } void ImageTexture::set_size_override(const Size2 &p_size) { @@ -685,12 +685,12 @@ void StreamTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_til RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid); } -void StreamTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref &p_normal_map) const { +void StreamTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref &p_normal_map, bool p_clip_uv) const { if ((w | h) == 0) return; RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv); } bool StreamTexture::has_alpha() const { @@ -912,7 +912,7 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid); } -void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref &p_normal_map) const { +void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref &p_normal_map, bool p_clip_uv) const { //this might not necessarily work well if using a rect, needs to be fixed properly Rect2 rc = region; @@ -941,7 +941,7 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons Rect2 dr(p_rect.position + ofs * scale, src_c.size * scale); RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, normal_rid); + VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, normal_rid, p_clip_uv); } bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const { @@ -1130,7 +1130,7 @@ void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile pieces[i].texture->draw_rect(p_canvas_item, Rect2(pieces[i].offset * scale + p_rect.position, pieces[i].texture->get_size() * scale), false, p_modulate, p_transpose, p_normal_map); } } -void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref &p_normal_map) const { +void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref &p_normal_map, bool p_clip_uv) const { //tiling not supported for this if (p_src_rect.size.x == 0 || p_src_rect.size.y == 0) @@ -1150,7 +1150,7 @@ void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons target.size *= scale; target.position = p_rect.position + (p_src_rect.position + rect.position) * scale; local.position -= rect.position; - pieces[i].texture->draw_rect_region(p_canvas_item, target, local, p_modulate, p_transpose, p_normal_map); + pieces[i].texture->draw_rect_region(p_canvas_item, target, local, p_modulate, p_transpose, p_normal_map, false); } } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 78693b07acd..2b82dbd21fd 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -70,7 +70,7 @@ public: virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref(), bool p_clip_uv = true) const; virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const; virtual Ref get_data() const { return Ref(); } @@ -133,7 +133,7 @@ public: bool has_alpha() const; virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref(), bool p_clip_uv = true) const; void set_storage(Storage p_storage); Storage get_storage() const; @@ -205,7 +205,7 @@ public: virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref(), bool p_clip_uv = true) const; virtual bool has_alpha() const; virtual void set_flags(uint32_t p_flags); @@ -259,7 +259,7 @@ public: virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref(), bool p_clip_uv = true) const; virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const; AtlasTexture(); @@ -307,7 +307,7 @@ public: virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref()) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref &p_normal_map = Ref(), bool p_clip_uv = true) const; LargeTexture(); }; diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index a56cdcdc50e..07d6542b628 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -525,7 +525,8 @@ public: CANVAS_RECT_TILE = 2, CANVAS_RECT_FLIP_H = 4, CANVAS_RECT_FLIP_V = 8, - CANVAS_RECT_TRANSPOSE = 16 + CANVAS_RECT_TRANSPOSE = 16, + CANVAS_RECT_CLIP_UV = 32 }; struct Light : public RID_Data { diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp index 0ae86cd3891..2ef1fd417b9 100644 --- a/servers/visual/visual_server_canvas.cpp +++ b/servers/visual/visual_server_canvas.cpp @@ -461,7 +461,7 @@ void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p canvas_item->commands.push_back(rect); } -void VisualServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, RID p_normal_map) { +void VisualServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, RID p_normal_map, bool p_clip_uv) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -490,6 +490,10 @@ void VisualServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const R SWAP(rect->rect.size.x, rect->rect.size.y); } + if (p_clip_uv) { + rect->flags |= RasterizerCanvas::CANVAS_RECT_CLIP_UV; + } + canvas_item->rect_dirty = true; canvas_item->commands.push_back(rect); diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h index 0808bf72adf..2c86b14c70a 100644 --- a/servers/visual/visual_server_canvas.h +++ b/servers/visual/visual_server_canvas.h @@ -166,7 +166,7 @@ public: void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color); void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color); void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID()); - void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID()); + void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), bool p_clip_uv = true); void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, VS::NinePatchAxisMode p_x_axis_mode = VS::NINE_PATCH_STRETCH, VS::NinePatchAxisMode p_y_axis_mode = VS::NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID()); void canvas_item_add_primitive(RID p_item, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()); void canvas_item_add_polygon(RID p_item, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs = Vector(), RID p_texture = RID(), RID p_normal_map = RID()); diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 504d836913f..c48bee7fa44 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -1042,7 +1042,7 @@ public: BIND3(canvas_item_add_rect, RID, const Rect2 &, const Color &) BIND4(canvas_item_add_circle, RID, const Point2 &, float, const Color &) BIND7(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool, RID) - BIND7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, RID) + BIND8(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, RID, bool) BIND11(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &, RID) BIND7(canvas_item_add_primitive, RID, const Vector &, const Vector &, const Vector &, RID, float, RID) BIND6(canvas_item_add_polygon, RID, const Vector &, const Vector &, const Vector &, RID, RID) diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index e60a478bd96..94cbfc815e2 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -469,7 +469,7 @@ public: FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &) FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &) FUNC7(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool, RID) - FUNC7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, RID) + FUNC8(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, RID, bool) FUNC11(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &, RID) FUNC7(canvas_item_add_primitive, RID, const Vector &, const Vector &, const Vector &, RID, float, RID) FUNC6(canvas_item_add_polygon, RID, const Vector &, const Vector &, const Vector &, RID, RID) diff --git a/servers/visual_server.h b/servers/visual_server.h index 22f91f6a738..a27b32f54f2 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -786,7 +786,7 @@ public: virtual void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) = 0; virtual void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) = 0; virtual void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID()) = 0; - virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID()) = 0; + virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), bool p_clip_uv = true) = 0; virtual void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, NinePatchAxisMode p_x_axis_mode = NINE_PATCH_STRETCH, NinePatchAxisMode p_y_axis_mode = NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID()) = 0; virtual void canvas_item_add_primitive(RID p_item, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()) = 0; virtual void canvas_item_add_polygon(RID p_item, const Vector &p_points, const Vector &p_colors, const Vector &p_uvs = Vector(), RID p_texture = RID(), RID p_normal_map = RID()) = 0;