summaryrefslogtreecommitdiff
path: root/servers/visual
diff options
context:
space:
mode:
Diffstat (limited to 'servers/visual')
-rw-r--r--servers/visual/visual_server_raster.cpp105
-rw-r--r--servers/visual/visual_server_raster.h5
-rw-r--r--servers/visual/visual_server_wrap_mt.h1
3 files changed, 82 insertions, 29 deletions
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index dfa1e849b7..dc0bff4cf4 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -3691,7 +3691,7 @@ void VisualServerRaster::canvas_item_add_set_blend_mode(RID p_item, MaterialBlen
void VisualServerRaster::canvas_item_set_z(RID p_item, int p_z) {
- ERR_FAIL_COND(p_z<0 || p_z>=CANVAS_ITEM_Z_MAX);
+ ERR_FAIL_COND(p_z<CANVAS_ITEM_Z_MIN || p_z>CANVAS_ITEM_Z_MAX);
VS_CHANGED;
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
ERR_FAIL_COND(!canvas_item);
@@ -3699,6 +3699,15 @@ void VisualServerRaster::canvas_item_set_z(RID p_item, int p_z) {
}
+void VisualServerRaster::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) {
+
+ VS_CHANGED;
+ CanvasItem *canvas_item = canvas_item_owner.get( p_item );
+ ERR_FAIL_COND(!canvas_item);
+ canvas_item->z_relative=p_enable;
+
+}
+
void VisualServerRaster::canvas_item_set_use_parent_shader(RID p_item, bool p_enable) {
VS_CHANGED;
@@ -6139,18 +6148,20 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect) {
- Rasterizer::CanvasItem *z_list[CANVAS_ITEM_Z_MAX];
- Rasterizer::CanvasItem *z_last_list[CANVAS_ITEM_Z_MAX];
- for(int i=0;i<CANVAS_ITEM_Z_MAX;i++) {
+ static const int z_range = CANVAS_ITEM_Z_MAX-CANVAS_ITEM_Z_MIN+1;
+ Rasterizer::CanvasItem *z_list[z_range];
+ Rasterizer::CanvasItem *z_last_list[z_range];
+
+ for(int i=0;i<z_range;i++) {
z_list[i]=NULL;
z_last_list[i]=NULL;
}
- _render_canvas_item(p_canvas_item,p_transform,p_clip_rect,1.0,z_list,z_last_list,NULL,NULL);
+ _render_canvas_item(p_canvas_item,p_transform,p_clip_rect,1.0,0,z_list,z_last_list,NULL,NULL);
- for(int i=0;i<CANVAS_ITEM_Z_MAX;i++) {
+ for(int i=0;i<z_range;i++) {
if (!z_list[i])
continue;
rasterizer->canvas_render_items(z_list[i]);
@@ -6168,7 +6179,7 @@ void VisualServerRaster::_render_canvas_item_viewport(VisualServer* p_self,void
}
-void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner) {
+void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner) {
CanvasItem *ci = p_canvas_item;
@@ -6247,7 +6258,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
if (child_items[i]->ontop)
continue;
- _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner);
+ _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner);
}
@@ -6256,13 +6267,20 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
ci->final_transform=xform;
ci->final_opacity=opacity * ci->self_opacity;
- if (z_last_list[ci->z]) {
- z_last_list[ci->z]->next=ci;
- z_last_list[ci->z]=ci;
+ if (ci->z_relative)
+ p_z=CLAMP(p_z+ci->z,CANVAS_ITEM_Z_MIN,CANVAS_ITEM_Z_MAX);
+ else
+ p_z=ci->z;
+
+ int zidx = p_z-CANVAS_ITEM_Z_MIN;
+
+ if (z_last_list[zidx]) {
+ z_last_list[zidx]->next=ci;
+ z_last_list[zidx]=ci;
} else {
- z_list[ci->z]=ci;
- z_last_list[ci->z]=ci;
+ z_list[zidx]=ci;
+ z_last_list[zidx]=ci;
}
ci->next=NULL;
@@ -6273,7 +6291,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
if (!child_items[i]->ontop)
continue;
- _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner);
+ _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner);
}
}
@@ -6282,31 +6300,62 @@ void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_trans
rasterizer->canvas_begin();
-
int l = p_canvas->child_items.size();
+ Canvas::ChildItem *ci=p_canvas->child_items.ptr();
+ bool has_mirror=false;
for(int i=0;i<l;i++) {
+ if (ci[i].mirror.x || ci[i].mirror.y) {
+ has_mirror=true;
+ break;
+ }
+ }
- Canvas::ChildItem& ci=p_canvas->child_items[i];
- _render_canvas_item_tree(ci.item,p_transform,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height));
+ Rect2 clip_rect(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height);
+ if (!has_mirror) {
- //mirroring (useful for scrolling backgrounds)
- if (ci.mirror.x!=0) {
+ static const int z_range = CANVAS_ITEM_Z_MAX-CANVAS_ITEM_Z_MIN+1;
+ Rasterizer::CanvasItem *z_list[z_range];
+ Rasterizer::CanvasItem *z_last_list[z_range];
- Matrix32 xform2 = p_transform * Matrix32(0,Vector2(ci.mirror.x,0));
- _render_canvas_item_tree(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height));
+ for(int i=0;i<z_range;i++) {
+ z_list[i]=NULL;
+ z_last_list[i]=NULL;
}
- if (ci.mirror.y!=0) {
-
- Matrix32 xform2 = p_transform * Matrix32(0,Vector2(0,ci.mirror.y));
- _render_canvas_item_tree(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height));
+ for(int i=0;i<l;i++) {
+ _render_canvas_item(ci[i].item,p_transform,clip_rect,1.0,0,z_list,z_last_list,NULL,NULL);
}
- if (ci.mirror.y!=0 && ci.mirror.x!=0) {
- Matrix32 xform2 = p_transform * Matrix32(0,ci.mirror);
- _render_canvas_item_tree(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height));
+ for(int i=0;i<z_range;i++) {
+ if (!z_list[i])
+ continue;
+ rasterizer->canvas_render_items(z_list[i]);
}
+ } else {
+
+ for(int i=0;i<l;i++) {
+
+ Canvas::ChildItem& ci=p_canvas->child_items[i];
+ _render_canvas_item_tree(ci.item,p_transform,clip_rect);
+
+ //mirroring (useful for scrolling backgrounds)
+ if (ci.mirror.x!=0) {
+ Matrix32 xform2 = p_transform * Matrix32(0,Vector2(ci.mirror.x,0));
+ _render_canvas_item_tree(ci.item,xform2,clip_rect);
+ }
+ if (ci.mirror.y!=0) {
+
+ Matrix32 xform2 = p_transform * Matrix32(0,Vector2(0,ci.mirror.y));
+ _render_canvas_item_tree(ci.item,xform2,clip_rect);
+ }
+ if (ci.mirror.y!=0 && ci.mirror.x!=0) {
+
+ Matrix32 xform2 = p_transform * Matrix32(0,ci.mirror);
+ _render_canvas_item_tree(ci.item,xform2,clip_rect);
+ }
+
+ }
}
}
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index d30ac17400..3fd8d7355b 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -380,6 +380,7 @@ class VisualServerRaster : public VisualServer {
List<CanvasItem*>::Element *E;
RID viewport;
int z;
+ bool z_relative;
bool sort_y;
float opacity;
float self_opacity;
@@ -396,6 +397,7 @@ class VisualServerRaster : public VisualServer {
self_opacity=1;
sort_y=false;
use_parent_shader=false;
+ z_relative=true;
}
};
@@ -600,7 +602,7 @@ class VisualServerRaster : public VisualServer {
void _render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario);
static void _render_canvas_item_viewport(VisualServer* p_self,void *p_vp,const Rect2& p_rect);
void _render_canvas_item_tree(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect);
- void _render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect,float p_opacity,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner);
+ void _render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner);
void _render_canvas(Canvas *p_canvas,const Matrix32 &p_transform);
Vector<Vector3> _camera_generate_endpoints(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max);
Vector<Plane> _camera_generate_orthogonal_planes(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max);
@@ -1112,6 +1114,7 @@ public:
virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore);
virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable);
virtual void canvas_item_set_z(RID p_item, int p_z);
+ virtual void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable);
virtual void canvas_item_set_shader(RID p_item, RID p_shader);
virtual RID canvas_item_get_shader(RID p_item) const;
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index c344161445..b59fdbc66a 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -1132,6 +1132,7 @@ public:
FUNC2(canvas_item_set_sort_children_by_y,RID,bool);
FUNC2(canvas_item_set_z,RID,int);
+ FUNC2(canvas_item_set_z_as_relative_to_parent,RID,bool);
FUNC2(canvas_item_set_shader,RID, RID );
FUNC1RC(RID,canvas_item_get_shader,RID );