diff options
Diffstat (limited to 'servers/visual/visual_server_raster.cpp')
-rw-r--r-- | servers/visual/visual_server_raster.cpp | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index a94d4f64c7..3675194325 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -6777,6 +6777,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,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_material_owner) { CanvasItem *ci = p_canvas_item; @@ -6878,6 +6879,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat ci->final_opacity=opacity * ci->self_opacity; ci->global_rect_cache=global_rect; ci->global_rect_cache.pos-=p_clip_rect.pos; + ci->light_masked=false; int zidx = p_z-CANVAS_ITEM_Z_MIN; @@ -6905,7 +6907,34 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat } -void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_transform,Rasterizer::CanvasLight *p_lights) { +void VisualServerRaster::_light_mask_canvas_items(int p_z,Rasterizer::CanvasItem *p_canvas_item,Rasterizer::CanvasLight *p_masked_lights) { + + if (!p_masked_lights) + return; + + Rasterizer::CanvasItem *ci=p_canvas_item; + + while(ci) { + + Rasterizer::CanvasLight *light=p_masked_lights; + while(light) { + + if (ci->light_mask&light->item_mask && p_z>=light->z_min && p_z<=light->z_max && ci->global_rect_cache.intersects_transformed(light->xform_cache,light->rect_cache)) { + ci->light_masked=true; + } + + light=light->mask_next_ptr; + } + + ci=ci->next; + } + + + + +} + +void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_transform,Rasterizer::CanvasLight *p_lights,Rasterizer::CanvasLight *p_masked_lights) { rasterizer->canvas_begin(); @@ -6938,6 +6967,11 @@ void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_trans for(int i=0;i<z_range;i++) { if (!z_list[i]) continue; + + if (p_masked_lights) { + _light_mask_canvas_items(CANVAS_ITEM_Z_MIN+i,z_list[i],p_masked_lights); + } + rasterizer->canvas_render_items(z_list[i],CANVAS_ITEM_Z_MIN+i,p_canvas->modulate,p_lights); } } else { @@ -7072,6 +7106,7 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ Rect2 clip_rect(0,0,viewport_rect.width,viewport_rect.height); Rasterizer::CanvasLight *lights=NULL; Rasterizer::CanvasLight *lights_with_shadow=NULL; + Rasterizer::CanvasLight *lights_with_mask=NULL; Rect2 shadow_rect; int light_count=0; @@ -7119,9 +7154,14 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ cl->radius_cache=cl->rect_cache.size.length(); } + if (cl->mode==CANVAS_LIGHT_MODE_MASK) { + cl->mask_next_ptr=lights_with_mask; + lights_with_mask=cl; + } light_count++; } + } } @@ -7142,6 +7182,8 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ for(Set<Rasterizer::CanvasLightOccluderInstance*>::Element *F=E->get().canvas->occluders.front();F;F=F->next()) { + if (!F->get()->enabled) + continue; F->get()->xform_cache = xf * F->get()->xform; if (shadow_rect.intersects_transformed(F->get()->xform_cache,F->get()->aabb_cache)) { @@ -7190,7 +7232,7 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ ptr=ptr->filter_next_ptr; } - _render_canvas( E->get()->canvas,xform,canvas_lights ); + _render_canvas( E->get()->canvas,xform,canvas_lights,lights_with_mask ); i++; if (scenario_draw_canvas_bg && E->key().layer>=scenario_canvas_max_layer) { |