diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 296d945cda3..5071fbba01c 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -2866,7 +2866,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: glGenBuffers(1, &surface->vertex_id); glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id); - glBufferData(GL_ARRAY_BUFFER, array_size, vr.ptr(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, array_size, vr.ptr(), p_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind if (p_format & VS::ARRAY_FORMAT_INDEX) { @@ -3104,6 +3104,22 @@ VS::BlendShapeMode RasterizerStorageGLES3::mesh_get_blend_shape_mode(RID p_mesh) return mesh->blend_shape_mode; } +void RasterizerStorageGLES3::mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const PoolVector &p_data) { + + Mesh *mesh = mesh_owner.getornull(p_mesh); + ERR_FAIL_COND(!mesh); + ERR_FAIL_INDEX(p_surface, mesh->surfaces.size()); + + int total_size = p_data.size(); + ERR_FAIL_COND(p_offset + total_size > mesh->surfaces[p_surface]->array_byte_size); + + PoolVector::Read r = p_data.read(); + + glBindBuffer(GL_ARRAY_BUFFER, mesh->surfaces[p_surface]->array_id); + glBufferSubData(GL_ARRAY_BUFFER, p_offset, total_size, r.ptr()); + glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind +} + void RasterizerStorageGLES3::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) { Mesh *mesh = mesh_owner.getornull(p_mesh); diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 6abc22b643c..bd5aad29c93 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -692,6 +692,8 @@ public: virtual void mesh_set_blend_shape_mode(RID p_mesh, VS::BlendShapeMode p_mode); virtual VS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const; + virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const PoolVector &p_data); + virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material); virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 26f5deae1d2..3e86daf3a7b 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -920,6 +920,12 @@ String ArrayMesh::surface_get_name(int p_idx) const { return surfaces[p_idx].name; } +void ArrayMesh::surface_update_region(int p_surface, int p_offset, const PoolVector &p_data) { + + ERR_FAIL_INDEX(p_surface, surfaces.size()); + VS::get_singleton()->mesh_surface_update_region(mesh, p_surface, p_offset, p_data); +} + void ArrayMesh::surface_set_custom_aabb(int p_idx, const Rect3 &p_aabb) { ERR_FAIL_INDEX(p_idx, surfaces.size()); @@ -1041,6 +1047,7 @@ void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(ARRAY_COMPRESS_DEFAULT)); ClassDB::bind_method(D_METHOD("get_surface_count"), &ArrayMesh::get_surface_count); ClassDB::bind_method(D_METHOD("surface_remove", "surf_idx"), &ArrayMesh::surface_remove); + ClassDB::bind_method(D_METHOD("surface_update_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_region); ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len); ClassDB::bind_method(D_METHOD("surface_get_array_index_len", "surf_idx"), &ArrayMesh::surface_get_array_index_len); ClassDB::bind_method(D_METHOD("surface_get_format", "surf_idx"), &ArrayMesh::surface_get_format); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index b11adf50b9d..75927079c7d 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -95,6 +95,7 @@ public: ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1, ARRAY_FLAG_USE_16_BIT_BONES = ARRAY_COMPRESS_INDEX << 2, + ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3, ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_VERTEX | ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2 | ARRAY_COMPRESS_WEIGHTS @@ -185,6 +186,8 @@ public: void set_blend_shape_mode(BlendShapeMode p_mode); BlendShapeMode get_blend_shape_mode() const; + void surface_update_region(int p_surface, int p_offset, const PoolVector &p_data); + int get_surface_count() const; void surface_remove(int p_idx); diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 164baa8c9b8..333fe1e72ad 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -242,6 +242,8 @@ public: virtual void mesh_set_blend_shape_mode(RID p_mesh, VS::BlendShapeMode p_mode) = 0; virtual VS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const = 0; + virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const PoolVector &p_data) = 0; + virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) = 0; virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const = 0; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 69e2d1c1627..9432d3fdd91 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -120,6 +120,8 @@ void VisualServerRaster::draw() { frame_drawn_callbacks.pop_front(); } + + emit_signal("frame_drawn_in_thread"); } void VisualServerRaster::sync() { } diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index b579f4032fd..67375e81b63 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -73,521 +73,6 @@ class VisualServerRaster : public VisualServer { List frame_drawn_callbacks; -// FIXME: Kept as reference for future implementation -#if 0 - struct Room { - - bool occlude_exterior; - BSP_Tree bounds; - Room() { occlude_exterior=true; } - }; - - - BalloonAllocator<> octree_allocator; - - struct OctreeAllocator { - - static BalloonAllocator<> *allocator; - - _FORCE_INLINE_ static void *alloc(size_t p_size) { return allocator->alloc(p_size); } - _FORCE_INLINE_ static void free(void *p_ptr) { return allocator->free(p_ptr); } - - }; - - struct Portal { - - bool enabled; - float disable_distance; - Color disable_color; - float connect_range; - Vector shape; - Rect2 bounds; - - - Portal() { enabled=true; disable_distance=50; disable_color=Color(); connect_range=0.8; } - }; - - struct BakedLight { - - Rasterizer::BakedLightData data; - PoolVector sampler; - Rect3 octree_aabb; - Size2i octree_tex_size; - Size2i light_tex_size; - - }; - - struct BakedLightSampler { - - float params[BAKED_LIGHT_SAMPLER_MAX]; - int resolution; - Vector dp_cache; - - BakedLightSampler() { - params[BAKED_LIGHT_SAMPLER_STRENGTH]=1.0; - params[BAKED_LIGHT_SAMPLER_ATTENUATION]=1.0; - params[BAKED_LIGHT_SAMPLER_RADIUS]=1.0; - params[BAKED_LIGHT_SAMPLER_DETAIL_RATIO]=0.1; - resolution=16; - } - }; - - void _update_baked_light_sampler_dp_cache(BakedLightSampler * blsamp); - struct Camera { - - enum Type { - PERSPECTIVE, - ORTHOGONAL - }; - Type type; - float fov; - float znear,zfar; - float size; - uint32_t visible_layers; - bool vaspect; - RID env; - - Transform transform; - - Camera() { - - visible_layers=0xFFFFFFFF; - fov=60; - type=PERSPECTIVE; - znear=0.1; zfar=100; - size=1.0; - vaspect=false; - - } - }; - - - struct Instance; - typedef Set,OctreeAllocator> InstanceSet; - struct Scenario; - - struct Instance { - - enum { - - MAX_LIGHTS=4 - }; - - RID self; - OctreeElementID octree_id; - Scenario *scenario; - bool update; - bool update_aabb; - bool update_materials; - Instance *update_next; - InstanceType base_type; - - RID base_rid; - - Rect3 aabb; - Rect3 transformed_aabb; - uint32_t object_ID; - bool visible; - bool visible_in_all_rooms; - uint32_t layer_mask; - float draw_range_begin; - float draw_range_end; - float extra_margin; - - - - Rasterizer::InstanceData data; - - - Set auto_rooms; - Set valid_auto_rooms; - Instance *room; - List::Element *RE; - Instance *baked_light; - List::Element *BLE; - Instance *sampled_light; - bool exterior; - - uint64_t last_render_pass; - uint64_t last_frame_pass; - - uint64_t version; // changes to this, and changes to base increase version - - InstanceSet lights; - bool light_cache_dirty; - - - - struct RoomInfo { - - Transform affine_inverse; - Room *room; - List owned_geometry_instances; - List owned_portal_instances; - List owned_room_instances; - List owned_light_instances; //not used, but just for the sake of it - Set disconnected_child_portals; - Set owned_autoroom_geometry; - uint64_t last_visited_pass; - RoomInfo() { last_visited_pass=0; } - - }; - - struct PortalInfo { - - Portal *portal; - Set candidate_set; - Instance *connected; - uint64_t last_visited_pass; - - Plane plane_cache; - Vector transformed_point_cache; - - - PortalInfo() { connected=NULL; last_visited_pass=0;} - }; - - struct LightInfo { - - RID instance; - int light_set_index; - uint64_t last_version; - uint64_t last_add_pass; - List::Element *D; // directional light in scenario - InstanceSet affected; - bool enabled; - float dtc; //distance to camera, used for sorting - - - LightInfo() { - - D=NULL; - light_set_index=-1; - last_add_pass=0; - enabled=true; - } - }; - - struct BakedLightInfo { - - BakedLight *baked_light; - Transform affine_inverse; - List owned_instances; - }; - - struct BakedLightSamplerInfo { - - Set baked_lights; - Set owned_instances; - BakedLightSampler *sampler; - int resolution; - Vector light_buffer; - RID sampled_light; - uint64_t last_pass; - Transform xform; // viewspace normal to lightspace, might not use one. - BakedLightSamplerInfo() { - sampler=NULL; - last_pass=0; - resolution=0; - } - }; - - struct ParticlesInfo { - - RID instance; - }; - - - RoomInfo *room_info; - LightInfo *light_info; - ParticlesInfo *particles_info; - PortalInfo * portal_info; - BakedLightInfo * baked_light_info; - BakedLightSamplerInfo * baked_light_sampler_info; - - - Instance() { - octree_id=0; - update_next=0; - object_ID=0; - last_render_pass=0; - last_frame_pass=0; - light_info=0; - particles_info=0; - update_next=NULL; - update=false; - visible=true; - data.cast_shadows=SHADOW_CASTING_SETTING_ON; - data.receive_shadows=true; - data.depth_scale=false; - data.billboard=false; - data.billboard_y=false; - data.baked_light=NULL; - data.baked_light_octree_xform=NULL; - data.baked_lightmap_id=-1; - version=1; - room_info=NULL; - room=NULL; - RE=NULL; - portal_info=NULL; - exterior=false; - layer_mask=1; - draw_range_begin=0; - draw_range_end=0; - extra_margin=0; - visible_in_all_rooms=false; - update_aabb=false; - update_materials=false; - - baked_light=NULL; - baked_light_info=NULL; - baked_light_sampler_info=NULL; - sampled_light=NULL; - BLE=NULL; - - light_cache_dirty=true; - - } - - ~Instance() { - - if (light_info) - memdelete(light_info); - if (particles_info) - memdelete(particles_info); - if (room_info) - memdelete(room_info); - if (portal_info) - memdelete(portal_info); - if (baked_light_info) - memdelete(baked_light_info); - }; - }; - - struct _InstanceLightsort { - - bool operator()(const Instance* p_A, const Instance* p_B) const { return p_A->light_info->dtc < p_B->light_info->dtc; } - }; - - struct Scenario { - - - ScenarioDebugMode debug; - RID self; - // well wtf, balloon allocator is slower? - typedef ::Octree Octree; - - Octree octree; - - List directional_lights; - RID environment; - RID fallback_environment; - - Instance *dirty_instances; - - Scenario() { dirty_instances=NULL; debug=SCENARIO_DEBUG_DISABLED; } - }; - - - - mutable RID_Owner canvas_item_material_owner; - - - - struct Viewport { - - RID self; - RID parent; - - VisualServer::ViewportRect rect; - RID camera; - RID scenario; - RID viewport_data; - - RenderTargetUpdateMode render_target_update_mode; - RID render_target; - RID render_target_texture; - - Rect2 rt_to_screen_rect; - - bool hide_scenario; - bool hide_canvas; - 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; - - struct CanvasKey { - - int layer; - RID canvas; - bool operator<(const CanvasKey& p_canvas) const { if (layer==p_canvas.layer) return canvas < p_canvas.canvas; return layer canvas_map; - - SelfList 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; render_target_clear_on_new_frame=true; render_target_clear=true; disable_environment=false; } - }; - - SelfList::List viewport_update_list; - - Map screen_viewports; - - struct CullRange { - - Plane nearp; - float min,max; - float z_near,z_far; - - void add_aabb(const Rect3& p_aabb) { - - - } - }; - - struct Cursor { - - Point2 pos; - float rot; - RID texture; - Point2 center; - bool visible; - Rect2 region; - Cursor() { - - rot = 0; - visible = false; - region = Rect2(); - }; - }; - - Rect2 canvas_clip; - Color clear_color; - Cursor cursors[MAX_CURSORS]; - RID default_cursor_texture; - - static void* instance_pair(void *p_self, OctreeElementID,Instance *p_A,int, OctreeElementID,Instance *p_B,int); - static void instance_unpair(void *p_self, OctreeElementID,Instance *p_A,int, OctreeElementID,Instance *p_B,int,void*); - - Instance *instance_cull_result[MAX_INSTANCE_CULL]; - Instance *instance_shadow_cull_result[MAX_INSTANCE_CULL]; //used for generating shadowmaps - Instance *light_cull_result[MAX_LIGHTS_CULLED]; - int light_cull_count; - - Instance *exterior_portal_cull_result[MAX_EXTERIOR_PORTALS]; - int exterior_portal_cull_count; - bool exterior_visited; - - Instance *light_sampler_cull_result[MAX_LIGHT_SAMPLERS]; - int light_samplers_culled; - - Instance *room_cull_result[MAX_ROOM_CULL]; - int room_cull_count; - bool room_cull_enabled; - bool light_discard_enabled; - bool shadows_enabled; - int black_margin[4]; - RID black_image[4]; - - Vector aabb_random_points; - Vector transformed_aabb_random_points; - - void _instance_validate_autorooms(Instance *p_geometry); - - void _portal_disconnect(Instance *p_portal,bool p_cleanup=false); - void _portal_attempt_connect(Instance *p_portal); - void _dependency_queue_update(RID p_rid, bool p_update_aabb=false, bool p_update_materials=false); - _FORCE_INLINE_ void _instance_queue_update(Instance *p_instance,bool p_update_aabb=false,bool p_update_materials=false); - void _update_instances(); - void _update_instance_aabb(Instance *p_instance); - void _update_instance(Instance *p_instance); - void _free_attached_instances(RID p_rid,bool p_free_scenario=false); - void _clean_up_owner(RID_OwnerBase *p_owner,String p_type); - - Instance *instance_update_list; - - //RID default_scenario; - //RID default_viewport; - - RID test_cube; - - - mutable RID_Owner room_owner; - mutable RID_Owner portal_owner; - - mutable RID_Owner baked_light_owner; - mutable RID_Owner baked_light_sampler_owner; - - mutable RID_Owner camera_owner; - mutable RID_Owner viewport_owner; - - mutable RID_Owner scenario_owner; - mutable RID_Owner instance_owner; - - mutable RID_Owner canvas_owner; - mutable RID_Owner canvas_item_owner; - - Map< RID, Set > instance_dependency_map; - Map< RID, Set > skeleton_dependency_map; - - - ViewportRect viewport_rect; - _FORCE_INLINE_ void _instance_draw(Instance *p_instance); - - bool _test_portal_cull(Camera *p_camera, Instance *p_portal_from, Instance *p_portal_to); - void _cull_portal(Camera *p_camera, Instance *p_portal,Instance *p_from_portal); - 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 Transform2D& p_transform, const Rect2& p_clip_rect, const Color &p_modulate, Rasterizer::CanvasLight *p_lights); - void _render_canvas_item(CanvasItem *p_canvas_item, const Transform2D& 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 Transform2D &p_transform, Rasterizer::CanvasLight *p_lights, Rasterizer::CanvasLight *p_masked_lights); - void _light_mask_canvas_items(int p_z,Rasterizer::CanvasItem *p_canvas_item,Rasterizer::CanvasLight *p_masked_lights); - - Vector _camera_generate_endpoints(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max); - Vector _camera_generate_orthogonal_planes(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max); - - void _light_instance_update_lispsm_shadow(Instance *p_light,Scenario *p_scenario,Camera *p_camera,const CullRange& p_cull_range); - void _light_instance_update_pssm_shadow(Instance *p_light,Scenario *p_scenario,Camera *p_camera,const CullRange& p_cull_range); - - void _light_instance_update_shadow(Instance *p_light,Scenario *p_scenario,Camera *p_camera,const CullRange& p_cull_range); - - uint64_t render_pass; - 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(); - - - Rasterizer *rasterizer; - -#endif - void _draw_margins(); static void _changes_changed() {} @@ -726,6 +211,8 @@ public: BIND2(mesh_set_blend_shape_mode, RID, BlendShapeMode) BIND1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID) + BIND4(mesh_surface_update_region, RID, int, int, const PoolVector &) + BIND3(mesh_surface_set_material, RID, int, RID) BIND2RC(RID, mesh_surface_get_material, RID, int) diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 80a1ef38793..1dddef7bd46 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -144,6 +144,8 @@ public: FUNC2(mesh_set_blend_shape_mode, RID, BlendShapeMode) FUNC1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID) + FUNC4(mesh_surface_update_region, RID, int, int, const PoolVector &) + FUNC3(mesh_surface_set_material, RID, int, RID) FUNC2RC(RID, mesh_surface_get_material, RID, int) diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 2234ddda0d7..039bbedbccb 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -1856,6 +1856,8 @@ void VisualServer::_bind_methods() { BIND_ENUM_CONSTANT(FEATURE_SHADERS); BIND_ENUM_CONSTANT(FEATURE_MULTITHREADED); + + ADD_SIGNAL(MethodInfo("frame_drawn_in_thread")); } void VisualServer::_canvas_item_add_style_box(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector &p_margins, const Color &p_modulate) { diff --git a/servers/visual_server.h b/servers/visual_server.h index 7b0976b100b..a36ba4a50af 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -227,6 +227,7 @@ public: ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1, ARRAY_FLAG_USE_16_BIT_BONES = ARRAY_COMPRESS_INDEX << 2, + ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3, ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_VERTEX | ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2 | ARRAY_COMPRESS_WEIGHTS @@ -259,6 +260,8 @@ public: virtual void mesh_set_blend_shape_mode(RID p_mesh, BlendShapeMode p_mode) = 0; virtual BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const = 0; + virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const PoolVector &p_data) = 0; + virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) = 0; virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const = 0;