diff options
Diffstat (limited to 'servers/visual')
-rw-r--r-- | servers/visual/rasterizer.h | 111 | ||||
-rw-r--r-- | servers/visual/rasterizer_dummy.cpp | 2 | ||||
-rw-r--r-- | servers/visual/rasterizer_dummy.h | 2 | ||||
-rw-r--r-- | servers/visual/shader_language.cpp | 55 | ||||
-rw-r--r-- | servers/visual/shader_language.h | 2 | ||||
-rw-r--r-- | servers/visual/visual_server_raster.cpp | 718 | ||||
-rw-r--r-- | servers/visual/visual_server_raster.h | 110 | ||||
-rw-r--r-- | servers/visual/visual_server_wrap_mt.h | 50 |
8 files changed, 911 insertions, 139 deletions
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 63ebdbc34a..ebc210fe3d 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -564,41 +564,81 @@ public: CANVAS_RECT_REGION=1, CANVAS_RECT_TILE=2, CANVAS_RECT_FLIP_H=4, - CANVAS_RECT_FLIP_V=8 + CANVAS_RECT_FLIP_V=8, + CANVAS_RECT_TRANSPOSE=16 }; struct CanvasLight { + + bool enabled; - bool shadow; Color color; Matrix32 xform; float height; + float scale; int z_min; int z_max; + int layer_min; + int layer_max; int item_mask; - VS::CanvasLightBlendMode blend_mode; + int item_shadow_mask; + bool subtract; RID texture; - void *texture_cache; // implementation dependent Vector2 texture_offset; + RID canvas; + RID shadow_buffer; + int shadow_buffer_size; + float shadow_esm_mult; + + void *texture_cache; // implementation dependent + Rect2 rect_cache; + Matrix32 xform_cache; + float radius_cache; //used for shadow far plane + CameraMatrix shadow_matrix_cache; + + Matrix32 light_shader_xform; + Vector2 light_shader_pos; + + CanvasLight *shadows_next_ptr; + CanvasLight *filter_next_ptr; CanvasLight *next_ptr; CanvasLight() { - enabled=true; - shadow=false; + enabled=true; color=Color(1,1,1); height=0; z_min=-1024; z_max=1024; + layer_min=0; + layer_max=0; item_mask=1; - blend_mode=VS::CANVAS_LIGHT_BLEND_ADD; + scale=1.0; + item_shadow_mask=-1; + subtract=false; texture_cache=NULL; next_ptr=NULL; + filter_next_ptr=NULL; + shadow_buffer_size=2048; + shadow_esm_mult=80; + } }; + struct CanvasItem; + + struct CanvasItemMaterial { + + RID shader; + Map<StringName,Variant> shader_param; + uint32_t shader_version; + Set<CanvasItem*> owners; + bool unshaded; + + CanvasItemMaterial() {unshaded=false; shader_version=0; } + }; struct CanvasItem { @@ -722,25 +762,32 @@ public: bool visible; bool ontop; VS::MaterialBlendMode blend_mode; + int light_mask; Vector<Command*> commands; mutable bool custom_rect; mutable bool rect_dirty; mutable Rect2 rect; CanvasItem*next; - RID shader; - Map<StringName,Variant> shader_param; - uint32_t shader_version; + CanvasItemMaterial* material; + struct CopyBackBuffer { + Rect2 rect; + Rect2 screen_rect; + bool full; + }; + CopyBackBuffer *copy_back_buffer; float final_opacity; Matrix32 final_transform; Rect2 final_clip_rect; CanvasItem* final_clip_owner; - CanvasItem* shader_owner; + CanvasItem* material_owner; ViewportRender *vp_render; + bool distance_field; - const Rect2& get_rect() const { + Rect2 global_rect_cache; + const Rect2& get_rect() const { if (custom_rect || !rect_dirty) return rect; @@ -863,15 +910,16 @@ public: return rect; } - void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true; final_clip_owner=NULL; shader_owner=NULL;} - CanvasItem() { vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_opacity=1; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; shader_version=0; shader_owner=NULL;} - virtual ~CanvasItem() { clear(); } + void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true; final_clip_owner=NULL; material_owner=NULL;} + CanvasItem() { light_mask=1; vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_opacity=1; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; material_owner=NULL; material=NULL; copy_back_buffer=NULL; distance_field=false; } + virtual ~CanvasItem() { clear(); if (copy_back_buffer) memdelete(copy_back_buffer); } }; CanvasItemDrawViewportFunc draw_viewport_func; + virtual void begin_canvas_bg()=0; virtual void canvas_begin()=0; virtual void canvas_disable_blending()=0; virtual void canvas_set_opacity(float p_opacity)=0; @@ -886,8 +934,37 @@ public: virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor)=0; virtual void canvas_set_transform(const Matrix32& p_transform)=0; - virtual void canvas_render_items(CanvasItem *p_item_list)=0; + virtual void canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light)=0; + virtual void canvas_debug_viewport_shadows(CanvasLight* p_lights_with_shadow)=0; + /* LIGHT SHADOW MAPPING */ + + virtual RID canvas_light_occluder_create()=0; + virtual void canvas_light_occluder_set_polylines(RID p_occluder, const DVector<Vector2>& p_lines)=0; + + + virtual RID canvas_light_shadow_buffer_create(int p_width)=0; + + struct CanvasLightOccluderInstance { + + bool enabled; + RID canvas; + RID polygon; + RID polygon_buffer; + Rect2 aabb_cache; + Matrix32 xform; + Matrix32 xform_cache; + int light_mask; + VS::CanvasOccluderPolygonCullMode cull_cache; + + CanvasLightOccluderInstance *next; + + CanvasLightOccluderInstance() { enabled=true; next=NULL; light_mask=1; cull_cache=VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; } + }; + + + + virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, CanvasLightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache)=0; /* ENVIRONMENT */ @@ -927,6 +1004,8 @@ public: virtual bool is_environment(const RID& p_rid) const=0; virtual bool is_shader(const RID& p_rid) const=0; + virtual bool is_canvas_light_occluder(const RID& p_rid) const=0; + virtual void free(const RID& p_rid)=0; virtual void init()=0; diff --git a/servers/visual/rasterizer_dummy.cpp b/servers/visual/rasterizer_dummy.cpp index 6c1b6697c1..7fb8eb02fc 100644 --- a/servers/visual/rasterizer_dummy.cpp +++ b/servers/visual/rasterizer_dummy.cpp @@ -1622,7 +1622,7 @@ void RasterizerDummy::canvas_set_transform(const Matrix32& p_transform) { } -void RasterizerDummy::canvas_render_items(CanvasItem *p_item_list) { +void RasterizerDummy::canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light) { } diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h index c72149f88f..baa48951d6 100644 --- a/servers/visual/rasterizer_dummy.h +++ b/servers/visual/rasterizer_dummy.h @@ -710,7 +710,7 @@ public: virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor); virtual void canvas_set_transform(const Matrix32& p_transform); - virtual void canvas_render_items(CanvasItem *p_item_list); + virtual void canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light); /* ENVIRONMENT */ diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index dfa0172e82..af65a7a639 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -56,6 +56,7 @@ const char * ShaderLanguage::token_names[TK_MAX]={ "TYPE_VEC2", "TYPE_VEC3", "TYPE_VEC4", + "TYPE_MAT2", "TYPE_MAT3", "TYPE_MAT4", "TYPE_TEXTURE", @@ -403,9 +404,9 @@ ShaderLanguage::Token ShaderLanguage::read_token(const CharType* p_text,int p_le {TK_TYPE_TEXTURE,"texture"}, {TK_TYPE_CUBEMAP,"cubemap"}, {TK_TYPE_COLOR,"color"}, - /* + {TK_TYPE_MAT2,"mat2"}, - {TK_TYPE_MAT3,"mat3"}, + /*{TK_TYPE_MAT3,"mat3"}, {TK_TYPE_MAT4,"mat3"},*/ {TK_TYPE_MAT3,"mat3"}, {TK_TYPE_MAT4,"mat4"}, @@ -511,6 +512,7 @@ bool ShaderLanguage::is_token_datatype(TokenType p_type) { (p_type==TK_TYPE_VEC3) || (p_type==TK_TYPE_VEC4) || (p_type==TK_TYPE_COLOR) || + (p_type==TK_TYPE_MAT2) || (p_type==TK_TYPE_MAT3) || (p_type==TK_TYPE_MAT4) || (p_type==TK_TYPE_CUBEMAP) || @@ -529,6 +531,7 @@ ShaderLanguage::DataType ShaderLanguage::get_token_datatype(TokenType p_type) { case TK_TYPE_VEC3: return TYPE_VEC3; case TK_TYPE_VEC4: return TYPE_VEC4; case TK_TYPE_COLOR: return TYPE_VEC4; + case TK_TYPE_MAT2: return TYPE_MAT2; case TK_TYPE_MAT3: return TYPE_MAT3; case TK_TYPE_MAT4: return TYPE_MAT4; case TK_TYPE_TEXTURE: return TYPE_TEXTURE; @@ -550,6 +553,7 @@ String ShaderLanguage::get_datatype_name(DataType p_type) { case TYPE_VEC2: return "vec2"; case TYPE_VEC3: return "vec3"; case TYPE_VEC4: return "vec4"; + case TYPE_MAT2: return "mat2"; case TYPE_MAT3: return "mat3"; case TYPE_MAT4: return "mat4"; case TYPE_TEXTURE: return "texture"; @@ -570,6 +574,7 @@ bool ShaderLanguage::is_token_nonvoid_datatype(TokenType p_type) { (p_type==TK_TYPE_VEC3) || (p_type==TK_TYPE_VEC4) || (p_type==TK_TYPE_COLOR) || + (p_type==TK_TYPE_MAT2) || (p_type==TK_TYPE_MAT3) || (p_type==TK_TYPE_MAT4) || (p_type==TK_TYPE_TEXTURE) || @@ -782,6 +787,7 @@ const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[]={ {"vec4",TYPE_VEC4,{TYPE_FLOAT,TYPE_VEC3,TYPE_VOID}}, {"vec4",TYPE_VEC4,{TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}}, {"vec4",TYPE_VEC4,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}}, + {"mat2",TYPE_MAT2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}}, {"mat3",TYPE_MAT3,{TYPE_VEC3,TYPE_VEC3,TYPE_VEC3,TYPE_VOID}}, {"mat4",TYPE_MAT4,{TYPE_VEC4,TYPE_VEC4,TYPE_VEC4,TYPE_VEC4,TYPE_VOID}}, //intrinsics - trigonometry @@ -918,6 +924,7 @@ const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[]={ {OP_ASSIGN,TYPE_VOID,{TYPE_VEC2,TYPE_VEC2}}, {OP_ASSIGN,TYPE_VOID,{TYPE_VEC3,TYPE_VEC3}}, {OP_ASSIGN,TYPE_VOID,{TYPE_VEC4,TYPE_VEC4}}, + {OP_ASSIGN,TYPE_VOID,{TYPE_MAT2,TYPE_MAT2}}, {OP_ASSIGN,TYPE_VOID,{TYPE_MAT3,TYPE_MAT3}}, {OP_ASSIGN,TYPE_VOID,{TYPE_MAT4,TYPE_MAT4}}, {OP_ADD,TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT}}, @@ -933,6 +940,8 @@ const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[]={ {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_FLOAT}}, {OP_MUL,TYPE_VEC2,{TYPE_FLOAT,TYPE_VEC2}}, {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_MAT3}}, + {OP_MUL,TYPE_VEC2,{TYPE_MAT2,TYPE_VEC2}}, + {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_MAT2}}, {OP_MUL,TYPE_VEC2,{TYPE_MAT3,TYPE_VEC2}}, {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_MAT4}}, {OP_MUL,TYPE_VEC2,{TYPE_MAT4,TYPE_VEC2}}, @@ -947,6 +956,7 @@ const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[]={ {OP_MUL,TYPE_VEC4,{TYPE_FLOAT,TYPE_VEC4}}, {OP_MUL,TYPE_VEC4,{TYPE_MAT4,TYPE_VEC4}}, {OP_MUL,TYPE_VEC4,{TYPE_VEC4,TYPE_MAT4}}, + {OP_MUL,TYPE_MAT2,{TYPE_MAT2,TYPE_MAT2}}, {OP_MUL,TYPE_MAT3,{TYPE_MAT3,TYPE_MAT3}}, {OP_MUL,TYPE_MAT4,{TYPE_MAT4,TYPE_MAT4}}, {OP_DIV,TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT}}, @@ -976,15 +986,15 @@ const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[]={ {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_FLOAT,TYPE_FLOAT}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC2,TYPE_VEC2}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC2,TYPE_FLOAT}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT3,TYPE_VEC2}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT4,TYPE_VEC2}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC2,TYPE_MAT2}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT2,TYPE_MAT2}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_MAT3}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_VEC3}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_FLOAT}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT3,TYPE_VEC3}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT4,TYPE_VEC3}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_MAT4}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC4,TYPE_VEC4}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC4,TYPE_FLOAT}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT4,TYPE_VEC4}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC4,TYPE_MAT4}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT3,TYPE_MAT3}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT4,TYPE_MAT4}}, {OP_ASSIGN_DIV,TYPE_VOID,{TYPE_FLOAT,TYPE_FLOAT}}, @@ -1149,11 +1159,19 @@ const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_fragment_builtins_defs[]={ const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_light_builtins_defs[]={ - { "COLOR", TYPE_VEC4}, + { "POSITION", TYPE_VEC4}, { "NORMAL", TYPE_VEC3}, - { "LIGHT_DIR", TYPE_VEC2}, - { "LIGHT_DISTANCE", TYPE_FLOAT}, - { "LIGHT", TYPE_VEC3}, + { "UV", TYPE_VEC2}, + { "COLOR", TYPE_VEC4}, + { "TEXTURE", TYPE_TEXTURE}, + { "TEXTURE_PIXEL_SIZE", TYPE_VEC2}, + { "VAR1", TYPE_VEC4}, + { "VAR2", TYPE_VEC4}, + { "SCREEN_UV", TYPE_VEC2}, + { "LIGHT_VEC", TYPE_VEC2}, + { "LIGHT_HEIGHT", TYPE_FLOAT}, + { "LIGHT_COLOR", TYPE_VEC4}, + { "LIGHT", TYPE_VEC4}, { "POINT_COORD", TYPE_VEC2}, // { "SCREEN_POS", TYPE_VEC2}, // { "SCREEN_TEXEL_SIZE", TYPE_VEC2}, @@ -1558,6 +1576,7 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex case TYPE_VEC2: name="vec2"; break; case TYPE_VEC3: name="vec3"; break; case TYPE_VEC4: name="vec4"; break; + case TYPE_MAT2: name="mat2"; break; case TYPE_MAT3: name="mat3"; break; case TYPE_MAT4: name="mat4"; break; default: ERR_FAIL_V(ERR_BUG); @@ -1852,6 +1871,7 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex } } break; + case TYPE_MAT2: ok=(ident=="x" || ident=="y"); member_type=TYPE_VEC2; break; case TYPE_MAT3: ok=(ident=="x" || ident=="y" || ident=="z" ); member_type=TYPE_VEC3; break; case TYPE_MAT4: ok=(ident=="x" || ident=="y" || ident=="z" || ident=="w"); member_type=TYPE_VEC4; break; default: {} @@ -2059,7 +2079,9 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex at+=get_datatype_name(compute_node_type(op->arguments[i])); } - parser.set_error("Invalid arguments to operator "+String(token_names[op->op])+": "+at); + static const char *op_names[OP_MAX]={"=","+","-","*","/","+=","-=","*=","/=","-","!","==","!=","<=",">=","<",">","||","&&","call","()"}; + + parser.set_error("Invalid arguments to operator "+String(op_names[op->op])+": "+at); return ERR_PARSE_ERROR; } expression.remove(next_op); @@ -2236,6 +2258,7 @@ Error ShaderLanguage::parse_variable_declaration(Parser& parser,BlockNode *p_blo case TYPE_VEC2: con->value=Vector2(); break; case TYPE_VEC3: con->value=Vector3(); break; case TYPE_VEC4: con->value=iscolor?Variant(Color()):Variant(Plane()); break; + case TYPE_MAT2: con->value=Matrix32(); break; case TYPE_MAT3: con->value=Matrix3(); break; case TYPE_MAT4: con->value=Transform(); break; case TYPE_TEXTURE: @@ -2618,12 +2641,20 @@ void ShaderLanguage::get_keyword_list(ShaderType p_type, List<String> *p_keyword int idx=0; + p_keywords->push_back("uniform"); + p_keywords->push_back("texture"); + p_keywords->push_back("cubemap"); + p_keywords->push_back("color"); + p_keywords->push_back("if"); + p_keywords->push_back("else"); + while(intrinsic_func_defs[idx].name) { p_keywords->push_back(intrinsic_func_defs[idx].name); idx++; } + switch(p_type) { case SHADER_MATERIAL_VERTEX: { idx=0; diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index f79c219d85..7777c8bcf3 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -56,6 +56,7 @@ public: TK_TYPE_VEC2, TK_TYPE_VEC3, TK_TYPE_VEC4, + TK_TYPE_MAT2, TK_TYPE_MAT3, TK_TYPE_MAT4, TK_TYPE_TEXTURE, @@ -118,6 +119,7 @@ public: TYPE_VEC2, TYPE_VEC3, TYPE_VEC4, + TYPE_MAT2, TYPE_MAT3, TYPE_MAT4, TYPE_TEXTURE, diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index e8fa319f11..83bfbbc6c3 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -1576,6 +1576,15 @@ void VisualServerRaster::viewport_set_render_target_vflip(RID p_viewport,bool p_ } +void VisualServerRaster::viewport_set_render_target_clear_on_new_frame(RID p_viewport,bool p_enable) { + + Viewport *viewport = viewport_owner.get( p_viewport ); + ERR_FAIL_COND(!viewport); + + viewport->render_target_clear_on_new_frame=p_enable; + +} + void VisualServerRaster::viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect) { Viewport *viewport = viewport_owner.get( p_viewport ); @@ -1594,6 +1603,23 @@ bool VisualServerRaster::viewport_get_render_target_vflip(RID p_viewport) const{ } +bool VisualServerRaster::viewport_get_render_target_clear_on_new_frame(RID p_viewport) const{ + + const Viewport *viewport = viewport_owner.get( p_viewport ); + ERR_FAIL_COND_V(!viewport,false); + + return viewport->render_target_clear_on_new_frame; + +} + +void VisualServerRaster::viewport_render_target_clear(RID p_viewport) { + + Viewport *viewport = viewport_owner.get( p_viewport ); + ERR_FAIL_COND(!viewport); + + viewport->render_target_clear=true; + +} void VisualServerRaster::viewport_queue_screen_capture(RID p_viewport) { @@ -1667,6 +1693,17 @@ void VisualServerRaster::viewport_set_hide_canvas(RID p_viewport,bool p_hide) { } +void VisualServerRaster::viewport_set_disable_environment(RID p_viewport,bool p_disable) { + + VS_CHANGED; + + Viewport *viewport=NULL; + viewport = viewport_owner.get( p_viewport ); + ERR_FAIL_COND(!viewport); + viewport->disable_environment=p_disable; + +} + void VisualServerRaster::viewport_attach_camera(RID p_viewport,RID p_camera) { VS_CHANGED; @@ -3195,6 +3232,7 @@ RID VisualServerRaster::canvas_create() { return rid; } + void VisualServerRaster::canvas_set_item_mirroring(RID p_canvas,RID p_item,const Point2& p_mirroring) { Canvas * canvas = canvas_owner.get(p_canvas); @@ -3220,6 +3258,14 @@ Point2 VisualServerRaster::canvas_get_item_mirroring(RID p_canvas,RID p_item) co return canvas->child_items[idx].mirror; } +void VisualServerRaster::canvas_set_modulate(RID p_canvas,const Color& p_color) { + + Canvas * canvas = canvas_owner.get(p_canvas); + ERR_FAIL_COND(!canvas); + canvas->modulate=p_color; +} + + RID VisualServerRaster::canvas_item_create() { @@ -3305,14 +3351,27 @@ bool VisualServerRaster::canvas_item_is_visible(RID p_item) const { } +void VisualServerRaster::canvas_item_set_light_mask(RID p_canvas_item,int p_mask) { + + VS_CHANGED; + + CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item ); + ERR_FAIL_COND(!canvas_item); + + if (canvas_item->light_mask==p_mask) + return; + VS_CHANGED; + + canvas_item->light_mask=p_mask; + +} + + void VisualServerRaster::canvas_item_set_blend_mode(RID p_canvas_item,MaterialBlendMode p_blend) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item ); - if (!canvas_item) { - printf("!canvas_item\n"); - }; ERR_FAIL_COND(!canvas_item); if (canvas_item->blend_mode==p_blend) @@ -3352,6 +3411,14 @@ void VisualServerRaster::canvas_item_set_clip(RID p_item, bool p_clip) { canvas_item->clip=p_clip; } +void VisualServerRaster::canvas_item_set_distance_field_mode(RID p_item, bool p_distance_field) { + VS_CHANGED; + CanvasItem *canvas_item = canvas_item_owner.get( p_item ); + ERR_FAIL_COND(!canvas_item); + + canvas_item->distance_field=p_distance_field; +} + void VisualServerRaster::canvas_item_set_transform(RID p_item, const Matrix32& p_transform) { @@ -3470,7 +3537,7 @@ void VisualServerRaster::canvas_item_add_circle(RID p_item, const Point2& p_pos, } -void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile,const Color& p_modulate) { +void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile,const Color& p_modulate,bool p_transpose) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); @@ -3493,12 +3560,16 @@ void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p rect->flags|=Rasterizer::CANVAS_RECT_FLIP_V; rect->rect.size.y = -rect->rect.size.y; } + if (p_transpose) { + rect->flags|=Rasterizer::CANVAS_RECT_TRANSPOSE; + SWAP(rect->rect.size.x, rect->rect.size.y); + } rect->texture=p_texture; canvas_item->rect_dirty=true; canvas_item->commands.push_back(rect); } -void VisualServerRaster::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) { +void VisualServerRaster::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) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); @@ -3521,12 +3592,17 @@ void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const R rect->flags|=Rasterizer::CANVAS_RECT_FLIP_V; rect->rect.size.y = -rect->rect.size.y; } + if (p_transpose) { + rect->flags|=Rasterizer::CANVAS_RECT_TRANSPOSE; + SWAP(rect->rect.size.x, rect->rect.size.y); + } canvas_item->rect_dirty=true; canvas_item->commands.push_back(rect); } + void VisualServerRaster::canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center,const Color& p_modulate) { VS_CHANGED; @@ -3708,55 +3784,53 @@ void VisualServerRaster::canvas_item_set_z_as_relative_to_parent(RID p_item, boo } -void VisualServerRaster::canvas_item_set_use_parent_shader(RID p_item, bool p_enable) { +void VisualServerRaster::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2& p_rect) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); - canvas_item->use_parent_shader=p_enable; + if (bool(canvas_item->copy_back_buffer!=NULL) !=p_enable) { + if (p_enable) { + canvas_item->copy_back_buffer = memnew( Rasterizer::CanvasItem::CopyBackBuffer ); + } else { + memdelete(canvas_item->copy_back_buffer); + canvas_item->copy_back_buffer=NULL; + } + } + + if (p_enable) { + canvas_item->copy_back_buffer->rect=p_rect; + canvas_item->copy_back_buffer->full=p_rect==Rect2(); + } } -void VisualServerRaster::canvas_item_set_shader(RID p_item, RID p_shader) { +void VisualServerRaster::canvas_item_set_use_parent_material(RID p_item, bool p_enable) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); - canvas_item->shader=p_shader; -} - -RID VisualServerRaster::canvas_item_get_shader(RID p_item) const{ - - CanvasItem *canvas_item = canvas_item_owner.get( p_item ); - ERR_FAIL_COND_V(!canvas_item,RID()); - return canvas_item->shader; + canvas_item->use_parent_material=p_enable; } -void VisualServerRaster::canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value){ +void VisualServerRaster::canvas_item_set_material(RID p_item, RID p_material) { VS_CHANGED; - CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item ); + CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); - if (p_value.get_type()==Variant::NIL) - canvas_item->shader_param.erase(p_param); - else - canvas_item->shader_param[p_param]=p_value; -} -Variant VisualServerRaster::canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const{ + if (canvas_item->material) + canvas_item->material->owners.erase(canvas_item); - CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item ); - ERR_FAIL_COND_V(!canvas_item,Variant()); - if (!canvas_item->shader_param.has(p_param)) { - ERR_FAIL_COND_V(!canvas_item->shader.is_valid(),Variant()); - return rasterizer->shader_get_default_param(canvas_item->shader,p_param); - } + canvas_item->material=NULL; - return canvas_item->shader_param[p_param]; + if (canvas_item_material_owner.owns(p_material)) { + canvas_item->material=canvas_item_material_owner.get(p_material); + canvas_item->material->owners.insert(canvas_item); + } } - void VisualServerRaster::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) { VS_CHANGED; @@ -3832,6 +3906,23 @@ void VisualServerRaster::canvas_light_attach_to_canvas(RID p_light,RID p_canvas) Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); + if (clight->canvas.is_valid()) { + + Canvas *canvas = canvas_owner.get(clight->canvas); + canvas->lights.erase(clight); + } + + if (!canvas_owner.owns(p_canvas)) + p_canvas=RID(); + clight->canvas=p_canvas; + + if (clight->canvas.is_valid()) { + + Canvas *canvas = canvas_owner.get(clight->canvas); + canvas->lights.insert(clight); + } + + } void VisualServerRaster::canvas_light_set_enabled(RID p_light, bool p_enabled){ @@ -3848,6 +3939,15 @@ void VisualServerRaster::canvas_light_set_transform(RID p_light, const Matrix32& clight->xform=p_transform; } +void VisualServerRaster::canvas_light_set_scale(RID p_light, float p_scale) { + + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->scale=p_scale; + +} + + void VisualServerRaster::canvas_light_set_texture(RID p_light, RID p_texture){ Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); @@ -3885,6 +3985,16 @@ void VisualServerRaster::canvas_light_set_z_range(RID p_light, int p_min_z,int p clight->z_max=p_max_z; } + +void VisualServerRaster::canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer) { + + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->layer_min=p_min_layer; + clight->layer_max=p_max_layer; + +} + void VisualServerRaster::canvas_light_set_item_mask(RID p_light, int p_mask){ Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); @@ -3893,30 +4003,62 @@ void VisualServerRaster::canvas_light_set_item_mask(RID p_light, int p_mask){ } -void VisualServerRaster::canvas_light_set_blend_mode(RID p_light, CanvasLightBlendMode p_blend_mode){ +void VisualServerRaster::canvas_light_set_item_shadow_mask(RID p_light, int p_mask){ Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); - clight->blend_mode=p_blend_mode; + clight->item_shadow_mask=p_mask; + +} + + +void VisualServerRaster::canvas_light_set_subtract_mode(RID p_light, bool p_enable) { + + + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->subtract=p_enable; } void VisualServerRaster::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled){ Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); - clight->shadow=p_enabled; + + if (clight->shadow_buffer.is_valid()==p_enabled) + return; + if (p_enabled) { + clight->shadow_buffer=rasterizer->canvas_light_shadow_buffer_create(clight->shadow_buffer_size); + } else { + rasterizer->free(clight->shadow_buffer); + clight->shadow_buffer=RID(); + + } } + void VisualServerRaster::canvas_light_set_shadow_buffer_size(RID p_light, int p_size){ Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); + ERR_FAIL_COND(p_size<32 || p_size>16384); + + clight->shadow_buffer_size=nearest_power_of_2(p_size); + + + if (clight->shadow_buffer.is_valid()) { + rasterizer->free(clight->shadow_buffer); + clight->shadow_buffer=rasterizer->canvas_light_shadow_buffer_create(clight->shadow_buffer_size); + } + } -void VisualServerRaster::canvas_light_set_shadow_filter(RID p_light, int p_size){ + +void VisualServerRaster::canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier) { Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); + clight->shadow_esm_mult=p_multiplier; } @@ -3924,24 +4066,215 @@ void VisualServerRaster::canvas_light_set_shadow_filter(RID p_light, int p_size) RID VisualServerRaster::canvas_light_occluder_create() { - return RID(); + Rasterizer::CanvasLightOccluderInstance *occluder = memnew( Rasterizer::CanvasLightOccluderInstance ); + + return canvas_light_occluder_owner.make_rid( occluder ); + } void VisualServerRaster::canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas) { + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + if (occluder->canvas.is_valid()) { + + Canvas *canvas = canvas_owner.get(occluder->canvas); + canvas->occluders.erase(occluder); + } + + if (!canvas_owner.owns(p_canvas)) + p_canvas=RID(); + + occluder->canvas=p_canvas; + + if (occluder->canvas.is_valid()) { + + Canvas *canvas = canvas_owner.get(occluder->canvas); + canvas->occluders.insert(occluder); + } } void VisualServerRaster::canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled){ + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + occluder->enabled=p_enabled; + +} + +void VisualServerRaster::canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + if (occluder->polygon.is_valid()) { + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_polygon); + if (occluder_poly) { + occluder_poly->owners.erase(occluder); + } + } + + occluder->polygon=p_polygon; + occluder->polygon_buffer=RID(); + + if (occluder->polygon.is_valid()) { + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_polygon); + if (!occluder_poly) + occluder->polygon=RID(); + ERR_FAIL_COND(!occluder_poly); + occluder_poly->owners.insert(occluder); + occluder->polygon_buffer=occluder_poly->occluder; + occluder->aabb_cache=occluder_poly->aabb; + occluder->cull_cache=occluder_poly->cull_mode; + } + +} + + + + +void VisualServerRaster::canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + occluder->xform=p_xform; + +} + +void VisualServerRaster::canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + occluder->light_mask=p_mask; + +} + + +RID VisualServerRaster::canvas_occluder_polygon_create() { + + CanvasLightOccluderPolygon * occluder_poly = memnew( CanvasLightOccluderPolygon ); + occluder_poly->occluder=rasterizer->canvas_light_occluder_create(); + return canvas_light_occluder_polygon_owner.make_rid(occluder_poly); + +} + +void VisualServerRaster::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const DVector<Vector2>& p_shape, bool p_close){ + + if (p_shape.size()<3) { + canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon,p_shape); + return; + } + + DVector<Vector2> lines; + int lc = p_shape.size()*2; + + lines.resize(lc-(p_close?0:2)); + { + DVector<Vector2>::Write w = lines.write(); + DVector<Vector2>::Read r = p_shape.read(); + + int max=lc/2; + if (!p_close) { + max--; + } + for(int i=0;i<max;i++) { + Vector2 a = r[i]; + Vector2 b = r[(i+1)%(lc/2)]; + w[i*2+0]=a; + w[i*2+1]=b; + } + + } + + canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon,lines); +} + +void VisualServerRaster::canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector<Vector2>& p_shape) { + + CanvasLightOccluderPolygon * occluder_poly = canvas_light_occluder_polygon_owner.get(p_occluder_polygon); + ERR_FAIL_COND(!occluder_poly); + ERR_FAIL_COND(p_shape.size()&1); + + int lc = p_shape.size(); + occluder_poly->aabb=Rect2(); + { + DVector<Vector2>::Read r = p_shape.read(); + for(int i=0;i<lc;i++) { + if (i==0) + occluder_poly->aabb.pos=r[i]; + else + occluder_poly->aabb.expand_to(r[i]); + } + } + + rasterizer->canvas_light_occluder_set_polylines(occluder_poly->occluder,p_shape); + for( Set<Rasterizer::CanvasLightOccluderInstance*>::Element *E=occluder_poly->owners.front();E;E=E->next()) { + E->get()->aabb_cache=occluder_poly->aabb; + } } -void VisualServerRaster::canvas_light_occluder_set_shape(RID p_occluder,const DVector<Vector2>& p_shape){ +void VisualServerRaster::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode) { + CanvasLightOccluderPolygon * occluder_poly = canvas_light_occluder_polygon_owner.get(p_occluder_polygon); + ERR_FAIL_COND(!occluder_poly); + occluder_poly->cull_mode=p_mode; + for( Set<Rasterizer::CanvasLightOccluderInstance*>::Element *E=occluder_poly->owners.front();E;E=E->next()) { + E->get()->cull_cache=p_mode; + } + +} + +RID VisualServerRaster::canvas_item_material_create() { + + Rasterizer::CanvasItemMaterial *material = memnew( Rasterizer::CanvasItemMaterial ); + return canvas_item_material_owner.make_rid(material); + +} + +void VisualServerRaster::canvas_item_material_set_shader(RID p_material, RID p_shader){ + + VS_CHANGED; + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND(!material); + material->shader=p_shader; + +} +void VisualServerRaster::canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value){ + + VS_CHANGED; + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND(!material); + if (p_value.get_type()==Variant::NIL) + material->shader_param.erase(p_param); + else + material->shader_param[p_param]=p_value; + + +} +Variant VisualServerRaster::canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const{ + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND_V(!material,Variant()); + if (!material->shader_param.has(p_param)) { + ERR_FAIL_COND_V(!material->shader.is_valid(),Variant()); + return rasterizer->shader_get_default_param(material->shader,p_param); + } + return material->shader_param[p_param]; } +void VisualServerRaster::canvas_item_material_set_unshaded(RID p_material, bool p_unshaded){ + + VS_CHANGED; + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND(!material); + material->unshaded=p_unshaded; + +} /******** CANVAS *********/ @@ -4194,7 +4527,17 @@ void VisualServerRaster::free( RID p_rid ) { canvas->child_items[i].item->parent=RID(); } - + + for (Set<Rasterizer::CanvasLight*>::Element *E=canvas->lights.front();E;E=E->next()) { + + E->get()->canvas=RID(); + } + + for (Set<Rasterizer::CanvasLightOccluderInstance*>::Element *E=canvas->occluders.front();E;E=E->next()) { + + E->get()->canvas=RID(); + } + canvas_owner.free( p_rid ); memdelete( canvas ); @@ -4223,18 +4566,82 @@ void VisualServerRaster::free( RID p_rid ) { canvas_item->child_items[i]->parent=RID(); } + if (canvas_item->material) { + canvas_item->material->owners.erase(canvas_item); + } + canvas_item_owner.free( p_rid ); memdelete( canvas_item ); + } else if (canvas_item_material_owner.owns(p_rid)) { + + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get(p_rid); + ERR_FAIL_COND(!material); + for(Set<Rasterizer::CanvasItem*>::Element *E=material->owners.front();E;E=E->next()) { + + E->get()->material=NULL; + } + + canvas_item_material_owner.free(p_rid); + memdelete(material); + } else if (canvas_light_owner.owns(p_rid)) { Rasterizer::CanvasLight *canvas_light = canvas_light_owner.get(p_rid); ERR_FAIL_COND(!canvas_light); + if (canvas_light->canvas.is_valid()) { + Canvas* canvas = canvas_owner.get(canvas_light->canvas); + if (canvas) + canvas->lights.erase(canvas_light); + } + + if (canvas_light->shadow_buffer.is_valid()) + rasterizer->free(canvas_light->shadow_buffer); + canvas_light_owner.free( p_rid ); memdelete( canvas_light ); + } else if (canvas_light_occluder_owner.owns(p_rid)) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_rid); + ERR_FAIL_COND(!occluder); + + if (occluder->polygon.is_valid()) { + + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(occluder->polygon); + if (occluder_poly) { + occluder_poly->owners.erase(occluder); + } + + } + + if (occluder->canvas.is_valid() && canvas_owner.owns(occluder->canvas)) { + + Canvas *canvas = canvas_owner.get(occluder->canvas); + canvas->occluders.erase(occluder); + + } + + canvas_light_occluder_owner.free( p_rid ); + memdelete(occluder); + + } else if (canvas_light_occluder_polygon_owner.owns(p_rid)) { + + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_rid); + ERR_FAIL_COND(!occluder_poly); + rasterizer->free(occluder_poly->occluder); + + while(occluder_poly->owners.size()) { + + occluder_poly->owners.front()->get()->polygon=RID(); + occluder_poly->owners.erase( occluder_poly->owners.front() ); + } + + canvas_light_occluder_polygon_owner.free( p_rid ); + memdelete(occluder_poly); + } else if (scenario_owner.owns(p_rid)) { Scenario *scenario=scenario_owner.get(p_rid); @@ -5879,6 +6286,20 @@ void VisualServerRaster::_process_sampled_light(const Transform& p_camera,Instan } +void VisualServerRaster::_render_no_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario) { + RID environment; + if (p_scenario->environment.is_valid()) + environment=p_scenario->environment; + else + environment=p_scenario->fallback_environment; + + rasterizer->set_camera(Transform(),CameraMatrix()); + rasterizer->begin_scene(p_viewport->viewport_data,environment,p_scenario->debug); + rasterizer->set_viewport(viewport_rect); + rasterizer->end_scene(); +} + + void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario) { @@ -6280,7 +6701,7 @@ 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) { +void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, const Color& p_modulate, Rasterizer::CanvasLight *p_lights) { static const int z_range = CANVAS_ITEM_Z_MAX-CANVAS_ITEM_Z_MIN+1; @@ -6298,7 +6719,7 @@ void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item,cons for(int i=0;i<z_range;i++) { if (!z_list[i]) continue; - rasterizer->canvas_render_items(z_list[i]); + rasterizer->canvas_render_items(z_list[i],CANVAS_ITEM_Z_MIN+i,p_modulate,p_lights); } } @@ -6313,7 +6734,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_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_material_owner) { CanvasItem *ci = p_canvas_item; @@ -6358,11 +6779,11 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat ci->vp_render=NULL; } - if (ci->use_parent_shader && p_shader_owner) - ci->shader_owner=p_shader_owner; + if (ci->use_parent_material && p_material_owner) + ci->material_owner=p_material_owner; else { - p_shader_owner=ci; - ci->shader_owner=NULL; + p_material_owner=ci; + ci->material_owner=NULL; } @@ -6396,15 +6817,19 @@ 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,p_z,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_material_owner); } + if (ci->copy_back_buffer) { + + ci->copy_back_buffer->screen_rect = xform.xform(ci->copy_back_buffer->rect).clip(p_clip_rect); + } - if ((!ci->commands.empty() && p_clip_rect.intersects(global_rect)) || ci->vp_render) { + if ((!ci->commands.empty() && p_clip_rect.intersects(global_rect)) || ci->vp_render || ci->copy_back_buffer) { //something to draw? ci->final_transform=xform; ci->final_opacity=opacity * ci->self_opacity; - + ci->global_rect_cache=global_rect; int zidx = p_z-CANVAS_ITEM_Z_MIN; @@ -6417,6 +6842,8 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat z_last_list[zidx]=ci; } + + ci->next=NULL; } @@ -6425,12 +6852,12 @@ 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,p_z,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_material_owner); } } -void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_transform) { +void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_transform,Rasterizer::CanvasLight *p_lights) { rasterizer->canvas_begin(); @@ -6463,30 +6890,30 @@ void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_trans for(int i=0;i<z_range;i++) { if (!z_list[i]) continue; - rasterizer->canvas_render_items(z_list[i]); + rasterizer->canvas_render_items(z_list[i],CANVAS_ITEM_Z_MIN+i,p_canvas->modulate,p_lights); } } 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); + _render_canvas_item_tree(ci.item,p_transform,clip_rect,p_canvas->modulate,p_lights); //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); + _render_canvas_item_tree(ci.item,xform2,clip_rect,p_canvas->modulate,p_lights); } 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); + _render_canvas_item_tree(ci.item,xform2,clip_rect,p_canvas->modulate,p_lights); } 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); + _render_canvas_item_tree(ci.item,xform2,clip_rect,p_canvas->modulate,p_lights); } } @@ -6495,6 +6922,23 @@ void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_trans } +void VisualServerRaster::_draw_viewport_camera(Viewport *p_viewport,bool p_ignore_camera) { + + + Camera *camera=NULL; + if (camera_owner.owns( p_viewport->camera )) + camera=camera_owner.get( p_viewport->camera ); + Scenario *scenario = scenario_owner.get( p_viewport->scenario ); + + _update_instances(); // check dirty instances before rendering + + if (p_ignore_camera) + _render_no_camera(p_viewport, camera,scenario ); + else + _render_camera(p_viewport, camera,scenario ); + +} + void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ofs_y,int p_parent_w,int p_parent_h) { ViewportRect desired_rect=p_viewport->rect; @@ -6529,19 +6973,47 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ /* Camera should always be BEFORE any other 3D */ - if (!p_viewport->hide_scenario && camera_owner.owns(p_viewport->camera) && scenario_owner.owns(p_viewport->scenario)) { + bool scenario_draw_canvas_bg=false; + int scenario_canvas_max_layer=0; + + if (!p_viewport->hide_canvas && !p_viewport->disable_environment && scenario_owner.owns(p_viewport->scenario)) { + + Scenario *scenario=scenario_owner.get(p_viewport->scenario); + if (scenario->environment.is_valid()) { + if (rasterizer->is_environment(scenario->environment)) { + scenario_draw_canvas_bg=rasterizer->environment_get_background(scenario->environment)==VS::ENV_BG_CANVAS; + scenario_canvas_max_layer=rasterizer->environment_get_background_param(scenario->environment,VS::ENV_BG_PARAM_CANVAS_MAX_LAYER); + } + } + } + + bool can_draw_3d=!p_viewport->hide_scenario && camera_owner.owns(p_viewport->camera) && scenario_owner.owns(p_viewport->scenario); - Camera *camera = camera_owner.get( p_viewport->camera ); - Scenario *scenario = scenario_owner.get( p_viewport->scenario ); - _update_instances(); // check dirty instances before rendering + if (scenario_draw_canvas_bg) { - _render_camera(p_viewport, camera,scenario ); + rasterizer->begin_canvas_bg(); + } + + if (!scenario_draw_canvas_bg && can_draw_3d) { + + _draw_viewport_camera(p_viewport,false); } else if (true /*|| !p_viewport->canvas_list.empty()*/){ //clear the viewport black because of no camera? i seriously should.. - rasterizer->clear_viewport(clear_color); + if (p_viewport->render_target_clear_on_new_frame || p_viewport->render_target_clear) { + if (p_viewport->transparent_bg) { + rasterizer->clear_viewport(Color(0,0,0,0)); + } + else { + Color cc=clear_color; + if (scenario_draw_canvas_bg) + cc.a=0; + rasterizer->clear_viewport(cc); + } + p_viewport->render_target_clear=false; + } } if (!p_viewport->hide_canvas) { @@ -6549,21 +7021,141 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ Map<Viewport::CanvasKey,Viewport::CanvasData*> canvas_map; + Rect2 clip_rect(0,0,viewport_rect.width,viewport_rect.height); + Rasterizer::CanvasLight *lights=NULL; + Rasterizer::CanvasLight *lights_with_shadow=NULL; + Rect2 shadow_rect; + + int light_count=0; + for (Map<RID,Viewport::CanvasData>::Element *E=p_viewport->canvas_map.front();E;E=E->next()) { + + Matrix32 xf = p_viewport->global_transform * E->get().transform; + + //find lights in canvas + + + for(Set<Rasterizer::CanvasLight*>::Element *F=E->get().canvas->lights.front();F;F=F->next()) { + + Rasterizer::CanvasLight* cl=F->get(); + if (cl->enabled && cl->texture.is_valid()) { + //not super efficient.. + Size2 tsize(rasterizer->texture_get_width(cl->texture),rasterizer->texture_get_height(cl->texture)); + tsize*=cl->scale; + Vector2 offset=tsize/2.0; + cl->rect_cache=Rect2(-offset+cl->texture_offset,tsize); + cl->xform_cache=xf * cl->xform; + + + if (clip_rect.intersects_transformed(cl->xform_cache,cl->rect_cache)) { + cl->filter_next_ptr=lights; + lights=cl; + cl->texture_cache=NULL; + Matrix32 scale; + scale.scale(cl->rect_cache.size); + scale.elements[2]=cl->rect_cache.pos; + cl->light_shader_xform = (cl->xform_cache * scale).affine_inverse(); + cl->light_shader_pos=cl->xform_cache[2]; + if (cl->shadow_buffer.is_valid()) { + cl->shadows_next_ptr=lights_with_shadow; + if (lights_with_shadow==NULL) { + shadow_rect = cl->xform_cache.xform(cl->rect_cache); + } else { + shadow_rect=shadow_rect.merge( cl->xform_cache.xform(cl->rect_cache) ); + } + lights_with_shadow=cl; + cl->radius_cache=cl->rect_cache.size.length(); + + } + + light_count++; + } + } + } + + //print_line("lights: "+itos(light_count)); canvas_map[ Viewport::CanvasKey( E->key(), E->get().layer) ]=&E->get(); } + if (lights_with_shadow) { + //update shadows if any + + Rasterizer::CanvasLightOccluderInstance * occluders=NULL; + + //make list of occluders + for (Map<RID,Viewport::CanvasData>::Element *E=p_viewport->canvas_map.front();E;E=E->next()) { + + Matrix32 xf = p_viewport->global_transform * E->get().transform; + + for(Set<Rasterizer::CanvasLightOccluderInstance*>::Element *F=E->get().canvas->occluders.front();F;F=F->next()) { + + F->get()->xform_cache = xf * F->get()->xform; + if (shadow_rect.intersects_transformed(F->get()->xform_cache,F->get()->aabb_cache)) { + + F->get()->next=occluders; + occluders=F->get(); + + } + } + } + //update the light shadowmaps with them + Rasterizer::CanvasLight *light=lights_with_shadow; + while(light) { + + rasterizer->canvas_light_shadow_buffer_update(light->shadow_buffer,light->xform_cache.affine_inverse(),light->item_mask,light->radius_cache/1000.0,light->radius_cache*1.1,occluders,&light->shadow_matrix_cache); + light=light->shadows_next_ptr; + } + + rasterizer->set_viewport(viewport_rect); //must reset viewport afterwards + } + + + + + if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer>scenario_canvas_max_layer) { + + _draw_viewport_camera(p_viewport,!can_draw_3d); + scenario_draw_canvas_bg=false; + + } + for (Map<Viewport::CanvasKey,Viewport::CanvasData*>::Element *E=canvas_map.front();E;E=E->next()) { // print_line("canvas "+itos(i)+" size: "+itos(I->get()->canvas->child_items.size())); //print_line("GT "+p_viewport->global_transform+". CT: "+E->get()->transform); Matrix32 xform = p_viewport->global_transform * E->get()->transform; - _render_canvas( E->get()->canvas,xform ); + + Rasterizer::CanvasLight *canvas_lights=NULL; + + Rasterizer::CanvasLight *ptr=lights; + while(ptr) { + if (E->get()->layer>=ptr->layer_min && E->get()->layer<=ptr->layer_max) { + ptr->next_ptr=canvas_lights; + canvas_lights=ptr; + } + ptr=ptr->filter_next_ptr; + } + + _render_canvas( E->get()->canvas,xform,canvas_lights ); i++; + if (scenario_draw_canvas_bg && E->key().layer>=scenario_canvas_max_layer) { + _draw_viewport_camera(p_viewport,!can_draw_3d); + scenario_draw_canvas_bg=false; + } + + + } + + if (scenario_draw_canvas_bg) { + _draw_viewport_camera(p_viewport,!can_draw_3d); + scenario_draw_canvas_bg=false; } + + + //rasterizer->canvas_debug_viewport_shadows(lights_with_shadow); } //capture diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index c15b6ebb26..72af793278 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -371,7 +371,7 @@ class VisualServerRaster : public VisualServer { - + mutable RID_Owner<Rasterizer::CanvasItemMaterial> canvas_item_material_owner; struct CanvasItem : public Rasterizer::CanvasItem { @@ -384,7 +384,7 @@ class VisualServerRaster : public VisualServer { bool sort_y; float opacity; float self_opacity; - bool use_parent_shader; + bool use_parent_material; Vector<CanvasItem*> child_items; @@ -396,7 +396,7 @@ class VisualServerRaster : public VisualServer { opacity=1; self_opacity=1; sort_y=false; - use_parent_shader=false; + use_parent_material=false; z_relative=true; } }; @@ -410,6 +410,26 @@ class VisualServerRaster : public VisualServer { } }; + struct CanvasLightOccluder; + + struct CanvasLightOccluderPolygon { + + bool active; + Rect2 aabb; + CanvasOccluderPolygonCullMode cull_mode; + RID occluder; + Set<Rasterizer::CanvasLightOccluderInstance*> owners; + + CanvasLightOccluderPolygon() { active=false; cull_mode=CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; } + }; + + + RID_Owner<CanvasLightOccluderPolygon> canvas_light_occluder_polygon_owner; + + RID_Owner<Rasterizer::CanvasLightOccluderInstance> canvas_light_occluder_owner; + + struct CanvasLight; + struct Canvas { Set<RID> viewports; @@ -419,8 +439,11 @@ class VisualServerRaster : public VisualServer { CanvasItem *item; }; + Set<Rasterizer::CanvasLight*> lights; + Set<Rasterizer::CanvasLightOccluderInstance*> occluders; Vector<ChildItem> child_items; + Color modulate; int find_item(CanvasItem *p_item) { for(int i=0;i<child_items.size();i++) { @@ -435,7 +458,7 @@ class VisualServerRaster : public VisualServer { child_items.remove(idx); } - Canvas() { } + Canvas() { modulate=Color(1,1,1,1); } }; @@ -464,6 +487,10 @@ class VisualServerRaster : public VisualServer { bool transparent_bg; bool queue_capture; bool render_target_vflip; + bool render_target_clear_on_new_frame; + bool render_target_clear; + bool disable_environment; + Image capture; bool rendered_in_prev_frame; @@ -490,7 +517,7 @@ class VisualServerRaster : public VisualServer { SelfList<Viewport> update_list; - Viewport() : update_list(this) { transparent_bg=false; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; queue_capture=false; rendered_in_prev_frame=false; render_target_vflip=false;} + Viewport() : update_list(this) { transparent_bg=false; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; queue_capture=false; rendered_in_prev_frame=false; render_target_vflip=false; render_target_clear_on_new_frame=true; render_target_clear=true; disable_environment=false; } }; SelfList<Viewport>::List viewport_update_list; @@ -601,11 +628,12 @@ class VisualServerRaster : public VisualServer { void _cull_room(Camera *p_camera, Instance *p_room,Instance *p_from_portal=NULL); void _process_sampled_light(const Transform &p_camera, Instance *p_sampled_light, bool p_linear_colorspace); + void _render_no_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario); 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,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); + void _render_canvas_item_tree(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, const Color &p_modulate, Rasterizer::CanvasLight *p_lights); + 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_material_owner); + void _render_canvas(Canvas *p_canvas, const Matrix32 &p_transform, Rasterizer::CanvasLight *p_lights); 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); @@ -618,6 +646,7 @@ class VisualServerRaster : public VisualServer { int changes; bool draw_extra_frame; + void _draw_viewport_camera(Viewport *p_viewport, bool p_ignore_camera); void _draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ofs_y,int p_parent_w,int p_parent_h); void _draw_viewports(); void _draw_cursors_and_margins(); @@ -953,8 +982,12 @@ public: virtual RID viewport_get_render_target_texture(RID p_viewport) const; virtual void viewport_set_render_target_vflip(RID p_viewport,bool p_enable); virtual bool viewport_get_render_target_vflip(RID p_viewport) const; + virtual void viewport_set_render_target_clear_on_new_frame(RID p_viewport,bool p_enable); + virtual bool viewport_get_render_target_clear_on_new_frame(RID p_viewport) const; + virtual void viewport_render_target_clear(RID p_viewport); virtual void viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect); + virtual void viewport_queue_screen_capture(RID p_viewport); virtual Image viewport_get_screen_capture(RID p_viewport) const; @@ -963,6 +996,7 @@ public: virtual void viewport_set_hide_scenario(RID p_viewport,bool p_hide); virtual void viewport_set_hide_canvas(RID p_viewport,bool p_hide); + virtual void viewport_set_disable_environment(RID p_viewport,bool p_disable); virtual void viewport_attach_camera(RID p_viewport,RID p_camera); virtual void viewport_set_scenario(RID p_viewport,RID p_scenario); @@ -1075,6 +1109,8 @@ public: virtual RID canvas_create(); virtual void canvas_set_item_mirroring(RID p_canvas,RID p_item,const Point2& p_mirroring); virtual Point2 canvas_get_item_mirroring(RID p_canvas,RID p_item) const; + virtual void canvas_set_modulate(RID p_canvas,const Color& p_color); + virtual RID canvas_item_create(); @@ -1085,11 +1121,14 @@ public: virtual bool canvas_item_is_visible(RID p_item) const; virtual void canvas_item_set_blend_mode(RID p_canvas_item,MaterialBlendMode p_blend); + virtual void canvas_item_set_light_mask(RID p_canvas_item,int p_mask); + //virtual void canvas_item_set_rect(RID p_item, const Rect2& p_rect); virtual void canvas_item_set_transform(RID p_item, const Matrix32& p_transform); virtual void canvas_item_set_clip(RID p_item, bool p_clip); + virtual void canvas_item_set_distance_field_mode(RID p_item, bool p_enable); virtual void canvas_item_set_custom_rect(RID p_item, bool p_custom_rect,const Rect2& p_rect=Rect2()); virtual void canvas_item_set_opacity(RID p_item, float p_opacity); virtual float canvas_item_get_opacity(RID p_item, float p_opacity) const; @@ -1104,8 +1143,8 @@ public: virtual void canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0); virtual void canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color); virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color); - 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)); - 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)); + 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); + 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); virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1)); virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width=1.0); virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID()); @@ -1117,53 +1156,58 @@ public: 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_copy_to_backbuffer(RID p_item, bool p_enable,const Rect2& p_rect); - virtual void canvas_item_set_shader(RID p_item, RID p_shader); - virtual RID canvas_item_get_shader(RID p_item) const; - - virtual void canvas_item_set_use_parent_shader(RID p_item, bool p_enable); - - - - virtual void canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value); - virtual Variant canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const; + virtual void canvas_item_set_material(RID p_item, RID p_material); + virtual void canvas_item_set_use_parent_material(RID p_item, bool p_enable); virtual RID canvas_light_create(); virtual void canvas_light_attach_to_canvas(RID p_light,RID p_canvas); virtual void canvas_light_set_enabled(RID p_light, bool p_enabled); virtual void canvas_light_set_transform(RID p_light, const Matrix32& p_transform); + virtual void canvas_light_set_scale(RID p_light, float p_scale); virtual void canvas_light_set_texture(RID p_light, RID p_texture); virtual void canvas_light_set_texture_offset(RID p_light, const Vector2& p_offset); virtual void canvas_light_set_color(RID p_light, const Color& p_color); virtual void canvas_light_set_height(RID p_light, float p_height); virtual void canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z); + virtual void canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer); virtual void canvas_light_set_item_mask(RID p_light, int p_mask); + virtual void canvas_light_set_item_shadow_mask(RID p_light, int p_mask); - enum CanvasightBlendMode { - CANVAS_LIGHT_BLEND_ADD, - CANVAS_LIGHT_BLEND_SUB, - CANVAS_LIGHT_BLEND_MULTIPLY, - CANVAS_LIGHT_BLEND_DODGE, - CANVAS_LIGHT_BLEND_BURN, - CANVAS_LIGHT_BLEND_LIGHTEN, - CANVAS_LIGHT_BLEND_DARKEN, - CANVAS_LIGHT_BLEND_OVERLAY, - CANVAS_LIGHT_BLEND_SCREEN, - }; - virtual void canvas_light_set_blend_mode(RID p_light, CanvasLightBlendMode p_blend_mode); + virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable); virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled); virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size); - virtual void canvas_light_set_shadow_filter(RID p_light, int p_size); + virtual void canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier); virtual RID canvas_light_occluder_create(); virtual void canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas); virtual void canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled); - virtual void canvas_light_occluder_set_shape(RID p_occluder,const DVector<Vector2>& p_shape); + virtual void canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon); + virtual void canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform); + virtual void canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask); + + + virtual RID canvas_occluder_polygon_create(); + virtual void canvas_occluder_polygon_set_shape(RID p_occluder_polygon,const DVector<Vector2>& p_shape,bool p_close); + virtual void canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector<Vector2>& p_shape); + virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode); + + virtual void canvas_item_clear(RID p_item); virtual void canvas_item_raise(RID p_item); + /* CANVAS ITEM MATERIAL */ + + virtual RID canvas_item_material_create(); + virtual void canvas_item_material_set_shader(RID p_material, RID p_shader); + virtual void canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value); + virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const; + virtual void canvas_item_material_set_unshaded(RID p_material, bool p_unshaded); + + /* CURSOR */ virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0); // radians virtual void cursor_set_texture(RID p_texture, const Point2 &p_center_offset, int p_cursor=0); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 9574dff018..ded4c6fc00 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -967,6 +967,10 @@ public: FUNC2(viewport_set_render_target_vflip,RID,bool); FUNC1RC(bool,viewport_get_render_target_vflip,RID); FUNC2(viewport_set_render_target_to_screen_rect,RID,const Rect2&); + + FUNC2(viewport_set_render_target_clear_on_new_frame,RID,bool); + FUNC1RC(bool,viewport_get_render_target_clear_on_new_frame,RID); + FUNC1(viewport_render_target_clear,RID); FUNC1(viewport_queue_screen_capture,RID); FUNC1RC(Image,viewport_get_screen_capture,RID); @@ -978,6 +982,7 @@ public: FUNC2(viewport_set_hide_canvas,RID,bool ); FUNC2(viewport_attach_camera,RID,RID ); FUNC2(viewport_set_scenario,RID,RID ); + FUNC2(viewport_set_disable_environment,RID,bool ); FUNC1RC(RID,viewport_get_attached_camera,RID); FUNC1RC(RID,viewport_get_scenario,RID ); @@ -1087,6 +1092,8 @@ public: FUNC0R(RID,canvas_create); FUNC3(canvas_set_item_mirroring,RID,RID,const Point2&); FUNC2RC(Point2,canvas_get_item_mirroring,RID,RID); + FUNC2(canvas_set_modulate,RID,const Color&); + FUNC0R(RID,canvas_item_create); @@ -1097,11 +1104,12 @@ public: FUNC1RC(bool,canvas_item_is_visible,RID); FUNC2(canvas_item_set_blend_mode,RID,MaterialBlendMode ); - + FUNC2(canvas_item_set_light_mask,RID,int ); //FUNC(canvas_item_set_rect,RID, const Rect2& p_rect); FUNC2(canvas_item_set_transform,RID, const Matrix32& ); FUNC2(canvas_item_set_clip,RID, bool ); + FUNC2(canvas_item_set_distance_field_mode,RID, bool ); FUNC3(canvas_item_set_custom_rect,RID, bool ,const Rect2&); FUNC2(canvas_item_set_opacity,RID, float ); FUNC2RC(float,canvas_item_get_opacity,RID, float ); @@ -1116,9 +1124,8 @@ public: FUNC5(canvas_item_add_line,RID, const Point2& , const Point2& ,const Color& ,float ); FUNC3(canvas_item_add_rect,RID, const Rect2& , const Color& ); FUNC4(canvas_item_add_circle,RID, const Point2& , float ,const Color& ); - FUNC5(canvas_item_add_texture_rect,RID, const Rect2& , RID ,bool ,const Color& ); - FUNC5(canvas_item_add_texture_rect_region,RID, const Rect2& , RID ,const Rect2& ,const Color& ); - + FUNC6(canvas_item_add_texture_rect,RID, const Rect2& , RID ,bool ,const Color&,bool ); + FUNC6(canvas_item_add_texture_rect_region,RID, const Rect2& , RID ,const Rect2& ,const Color&,bool ); FUNC7(canvas_item_add_style_box,RID, const Rect2& , RID ,const Vector2& ,const Vector2&, bool ,const Color& ); FUNC6(canvas_item_add_primitive,RID, const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID ,float ); FUNC5(canvas_item_add_polygon,RID, const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID ); @@ -1133,15 +1140,12 @@ 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); + FUNC3(canvas_item_set_copy_to_backbuffer,RID,bool,const Rect2&); - FUNC2(canvas_item_set_shader,RID, RID ); - FUNC1RC(RID,canvas_item_get_shader,RID ); - - FUNC2(canvas_item_set_use_parent_shader,RID, bool ); + FUNC2(canvas_item_set_material,RID, RID ); - FUNC3(canvas_item_set_shader_param,RID,const StringName&,const Variant&); - FUNC2RC(Variant,canvas_item_get_shader_param,RID,const StringName&); + FUNC2(canvas_item_set_use_parent_material,RID, bool ); FUNC1(canvas_item_clear,RID); FUNC1(canvas_item_raise,RID); @@ -1151,24 +1155,44 @@ public: FUNC2(canvas_light_attach_to_canvas,RID,RID); FUNC2(canvas_light_set_enabled,RID,bool); FUNC2(canvas_light_set_transform,RID,const Matrix32&); + FUNC2(canvas_light_set_scale,RID,float); FUNC2(canvas_light_set_texture,RID,RID); FUNC2(canvas_light_set_texture_offset,RID,const Vector2&); FUNC2(canvas_light_set_color,RID,const Color&); FUNC2(canvas_light_set_height,RID,float); + FUNC3(canvas_light_set_layer_range,RID,int,int); FUNC3(canvas_light_set_z_range,RID,int,int); FUNC2(canvas_light_set_item_mask,RID,int); + FUNC2(canvas_light_set_item_shadow_mask,RID,int); - FUNC2(canvas_light_set_blend_mode,RID,CanvasLightBlendMode); + FUNC2(canvas_light_set_subtract_mode,RID,bool); FUNC2(canvas_light_set_shadow_enabled,RID,bool); FUNC2(canvas_light_set_shadow_buffer_size,RID,int); - FUNC2(canvas_light_set_shadow_filter,RID,int); + FUNC2(canvas_light_set_shadow_esm_multiplier,RID,float); + /* CANVAS OCCLUDER */ FUNC0R(RID,canvas_light_occluder_create); FUNC2(canvas_light_occluder_attach_to_canvas,RID,RID); FUNC2(canvas_light_occluder_set_enabled,RID,bool); - FUNC2(canvas_light_occluder_set_shape,RID,const DVector<Vector2>&); + FUNC2(canvas_light_occluder_set_polygon,RID,RID); + FUNC2(canvas_light_occluder_set_transform,RID,const Matrix32&); + FUNC2(canvas_light_occluder_set_light_mask,RID,int); + + + FUNC0R(RID,canvas_occluder_polygon_create); + FUNC3(canvas_occluder_polygon_set_shape,RID,const DVector<Vector2>&,bool); + FUNC2(canvas_occluder_polygon_set_shape_as_lines,RID,const DVector<Vector2>&); + FUNC2(canvas_occluder_polygon_set_cull_mode,RID,CanvasOccluderPolygonCullMode); + + /* CANVAS MATERIAL */ + + FUNC0R(RID,canvas_item_material_create); + FUNC2(canvas_item_material_set_shader,RID,RID); + FUNC3(canvas_item_material_set_shader_param,RID,const StringName&,const Variant&); + FUNC2RC(Variant,canvas_item_material_get_shader_param,RID,const StringName&); + FUNC2(canvas_item_material_set_unshaded,RID,bool); /* CURSOR */ FUNC2(cursor_set_rotation,float , int ); // radians |