Fixed modifying mesh instances
Rather than use a uniform, the code was modified so that the vertex buffer for the mesh instances was not recreated from scratch. Now each mesh can be assigned a max number of instances. On each modififcation the instance data and the number of instances can be passed to the mesh.
This commit is contained in:
parent
0c55429241
commit
31e37846b4
@ -84,6 +84,7 @@ typedef struct mesh
|
||||
vulkan_buffer instance_buffer;
|
||||
vulkan_buffer index_buffer;
|
||||
u64 index_count;
|
||||
u64 max_instances;
|
||||
u64 instance_count;
|
||||
|
||||
} mesh;
|
||||
@ -2167,7 +2168,7 @@ static VkDeviceSize get_vertex_input_byte_size(const vertex_input_type t, const
|
||||
}
|
||||
}
|
||||
|
||||
static u8 load_mesh_geometry(mesh* msh, const mesh_geometry* geometry, vertex_input_type geometry_type)
|
||||
static u8 init_mesh(mesh* msh, const mesh_geometry* geometry, vertex_input_type geometry_type, u64 max_instances, vertex_input_type instance_type)
|
||||
{
|
||||
if (!geometry) return 0;
|
||||
|
||||
@ -2180,25 +2181,12 @@ static u8 load_mesh_geometry(mesh* msh, const mesh_geometry* geometry, vertex_in
|
||||
if (!upload_vulkan_gpu_buffer(&msh->index_buffer, geometry->indices, indices_byte_size)) return 0;
|
||||
msh->index_count = geometry->index_count;
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (!max_instances) return 0;
|
||||
|
||||
static u8 load_mesh_instance_data(mesh* msh, const mesh_instance_data* instance_data, vertex_input_type instance_type)
|
||||
{
|
||||
if (!instance_data) return 0;
|
||||
|
||||
const VkDeviceSize byte_size = get_vertex_input_byte_size(instance_type, instance_data->instance_count);
|
||||
const VkDeviceSize byte_size = get_vertex_input_byte_size(instance_type, max_instances);
|
||||
if (!init_vulkan_vertex_buffer(&msh->instance_buffer, byte_size)) return 0;
|
||||
if (!upload_vulkan_gpu_buffer(&msh->instance_buffer, instance_data->instances, byte_size)) return 0;
|
||||
msh->instance_count = instance_data->instance_count;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u8 init_mesh(mesh* msh, const mesh_geometry* geometry, vertex_input_type geometry_type, const mesh_instance_data* instance_data, vertex_input_type instance_type)
|
||||
{
|
||||
if (!load_mesh_geometry(msh, geometry, geometry_type)) return 0;
|
||||
if (!load_mesh_instance_data(msh, instance_data, instance_type)) return 0;
|
||||
msh->max_instances = max_instances;
|
||||
msh->instance_count = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -2684,7 +2672,7 @@ u8 change_mesh_pipeline_mode(const char* name, mesh_pipeline_mode mode)
|
||||
}
|
||||
}
|
||||
|
||||
u8 insert_mesh(const char* pipeline_name, const char* mesh_name, const mesh_geometry* geometry, const mesh_instance_data* instance_data)
|
||||
u8 insert_mesh(const char* pipeline_name, const char* mesh_name, const mesh_geometry* geometry, const u64 max_instances)
|
||||
{
|
||||
mesh_pipeline* pipeline = hash_table_lookup(&context.mesh_pipelines, pipeline_name);
|
||||
if (!pipeline)
|
||||
@ -2694,7 +2682,7 @@ u8 insert_mesh(const char* pipeline_name, const char* mesh_name, const mesh_geom
|
||||
}
|
||||
|
||||
mesh msh;
|
||||
if (!init_mesh(&msh, geometry, pipeline->geometry_type, instance_data, pipeline->instance_type)) return 0;
|
||||
if (!init_mesh(&msh, geometry, pipeline->geometry_type, max_instances, pipeline->instance_type)) return 0;
|
||||
if (!hash_table_insert(&pipeline->meshes, mesh_name, &msh))
|
||||
{
|
||||
shutdown_mesh(&msh);
|
||||
@ -2724,50 +2712,32 @@ u8 remove_mesh(const char* pipeline_name, const char* mesh_name)
|
||||
return hash_table_remove(&pipeline->meshes, mesh_name, NULL);
|
||||
}
|
||||
|
||||
u8 reload_mesh_geometry(const char* pipeline_name, const char* mesh_name, const mesh_geometry* geometry)
|
||||
u8 load_mesh_instance_data(const char* pipeline_name, const char* mesh_name, const mesh_instance_data* instance_data)
|
||||
{
|
||||
mesh_pipeline* pipeline = hash_table_lookup(&context.mesh_pipelines, pipeline_name);
|
||||
if (!pipeline)
|
||||
{
|
||||
trace_log(LOG_ERROR, "Failed to reload geometry for mesh '%s'; mesh pipeline '%s' lookup failed.", mesh_name, pipeline_name);
|
||||
trace_log(LOG_ERROR, "Failed to load instance data for mesh '%s'; mesh pipeline '%s' lookup failed.", mesh_name, pipeline_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mesh* msh = hash_table_lookup(&pipeline->meshes, mesh_name);
|
||||
if (!msh)
|
||||
{
|
||||
trace_log(LOG_ERROR, "Failed to reload geometry for mesh '%s'; lookup failed.", mesh_name);
|
||||
trace_log(LOG_ERROR, "Failed to load instance data geometry for mesh '%s'; lookup failed.", mesh_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (instance_data->instance_count > msh->max_instances)
|
||||
{
|
||||
trace_log(LOG_ERROR, "Failed to load instance data geometry for mesh '%s'; instance count '%d' would exceed the max allowed", mesh_name, instance_data->instance_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
shutdown_vulkan_buffer(&msh->index_buffer);
|
||||
shutdown_vulkan_buffer(&msh->vertex_buffer);
|
||||
|
||||
if (!load_mesh_geometry(msh, geometry, pipeline->geometry_type)) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
u8 reload_mesh_instance_data(const char* pipeline_name, const char* mesh_name, const mesh_instance_data* instance_data)
|
||||
{
|
||||
mesh_pipeline* pipeline = hash_table_lookup(&context.mesh_pipelines, pipeline_name);
|
||||
if (!pipeline)
|
||||
{
|
||||
trace_log(LOG_ERROR, "Failed to reload instance data for mesh '%s'; mesh pipeline '%s' lookup failed.", mesh_name, pipeline_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mesh* msh = hash_table_lookup(&pipeline->meshes, mesh_name);
|
||||
if (!msh)
|
||||
{
|
||||
trace_log(LOG_ERROR, "Failed to instance data geometry for mesh '%s'; lookup failed.", mesh_name);
|
||||
return 0;
|
||||
}
|
||||
const VkDeviceSize byte_size = get_vertex_input_byte_size(pipeline->instance_type, instance_data->instance_count);
|
||||
if (!upload_vulkan_gpu_buffer(&msh->instance_buffer, instance_data->instances, byte_size)) return 0;
|
||||
msh->instance_count = instance_data->instance_count;
|
||||
|
||||
shutdown_vulkan_buffer(&msh->instance_buffer);
|
||||
|
||||
if (!load_mesh_instance_data(msh, instance_data, pipeline->instance_type)) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -133,10 +133,9 @@ u8 draw_mesh_pipeline(const char* name);
|
||||
u8 insert_mesh_pipeline(const char* name, vertex_input_type geometry_type, vertex_input_type instance_type, const char* texture_name);
|
||||
u8 remove_mesh_pipeline(const char* name);
|
||||
u8 change_mesh_pipeline_mode(const char* name, mesh_pipeline_mode mode);
|
||||
u8 insert_mesh(const char* pipeline_name, const char* mesh_name, const mesh_geometry* geometry, const mesh_instance_data* instance_data);
|
||||
u8 insert_mesh(const char* pipeline_name, const char* mesh_name, const mesh_geometry* geometry, const u64 max_instances);
|
||||
u8 remove_mesh(const char* pipeline_name, const char* mesh_name);
|
||||
u8 reload_mesh_geometry(const char* pipeline_name, const char* mesh_name, const mesh_geometry* geometry);
|
||||
u8 reload_mesh_instance_data(const char* pipeline_name, const char* mesh_name, const mesh_instance_data* instance_data);
|
||||
u8 load_mesh_instance_data(const char* pipeline_name, const char* mesh_name, const mesh_instance_data* instance_data);
|
||||
|
||||
u8 init_vulkan();
|
||||
void shutdown_vulkan();
|
||||
|
@ -242,16 +242,13 @@
|
||||
(%change-mesh-pipeline-mode name (mesh-pipeline-mode mode))))
|
||||
|
||||
(define insert-mesh
|
||||
(foreign-procedure "insert_mesh" (string string (* mesh-geometry) (* mesh-instance-data)) boolean))
|
||||
(foreign-procedure "insert_mesh" (string string (* mesh-geometry) unsigned-64) boolean))
|
||||
|
||||
(define remove-mesh
|
||||
(foreign-procedure "remove_mesh" (string string) boolean))
|
||||
|
||||
(define reload-mesh-geometry
|
||||
(foreign-procedure "reload_mesh_geometry" (string string (* mesh-geometry)) boolean))
|
||||
|
||||
(define reload-mesh-instance-data
|
||||
(foreign-procedure "reload_mesh_instance_data" (string string (* mesh-instance-data)) boolean))
|
||||
(define load-mesh-instance-data
|
||||
(foreign-procedure "load_mesh_instance_data" (string string (* mesh-instance-data)) boolean))
|
||||
|
||||
(define %init-vulkan
|
||||
(foreign-procedure "init_vulkan" () boolean))
|
||||
|
69
src/grid.ss
69
src/grid.ss
@ -86,6 +86,28 @@
|
||||
(define grid-selector-shift-x #f)
|
||||
(define grid-selector-shift-y #f)
|
||||
|
||||
(define load-grid-selector-position
|
||||
(lambda (position)
|
||||
(let ([sel-instances (make-ftype-pointer pos3-pos3-color4 (foreign-alloc (ftype-sizeof pos3-pos3-color4)))]
|
||||
[instance-data (make-ftype-pointer mesh-instance-data (foreign-alloc (ftype-sizeof mesh-instance-data)))])
|
||||
|
||||
(fvec3-copy-c!
|
||||
(ftype-&ref pos3-pos3-color4 (posa) sel-instances 0)
|
||||
position)
|
||||
(fvec3-copy-c!
|
||||
(ftype-&ref pos3-pos3-color4 (posb) sel-instances 0)
|
||||
(fvec 1 1 1))
|
||||
(fvec3-copy-c!
|
||||
(ftype-&ref pos3-pos3-color4 (color) sel-instances 0)
|
||||
(fvec 1 1 1 1))
|
||||
|
||||
(ftype-set! mesh-instance-data (instances) instance-data (ftype-pointer-address sel-instances))
|
||||
(ftype-set! mesh-instance-data (instance-count) instance-data 1)
|
||||
|
||||
(load-mesh-instance-data "grid-selector" "quad" instance-data)
|
||||
(foreign-free (ftype-pointer-address sel-instances))
|
||||
(foreign-free (ftype-pointer-address instance-data)))))
|
||||
|
||||
(define init-grid-selector
|
||||
(lambda ()
|
||||
|
||||
@ -98,9 +120,7 @@
|
||||
|
||||
(let ([sel-vertices (make-ftype-pointer pos2 (foreign-alloc (* 4 (ftype-sizeof pos2))))]
|
||||
[sel-indices (make-ftype-pointer unsigned-32 (foreign-alloc (* 6 (ftype-sizeof unsigned-32))))]
|
||||
[geometry (make-ftype-pointer mesh-geometry (foreign-alloc (ftype-sizeof mesh-geometry)))]
|
||||
[sel-instances (make-ftype-pointer pos3-pos3-color4 (foreign-alloc (ftype-sizeof pos3-pos3-color4)))]
|
||||
[instance-data (make-ftype-pointer mesh-instance-data (foreign-alloc (ftype-sizeof mesh-instance-data)))])
|
||||
[geometry (make-ftype-pointer mesh-geometry (foreign-alloc (ftype-sizeof mesh-geometry)))])
|
||||
|
||||
(fvec2-copy-c!
|
||||
(ftype-&ref pos2 (pos) sel-vertices 0)
|
||||
@ -127,25 +147,12 @@
|
||||
(ftype-set! mesh-geometry (indices) geometry (ftype-pointer-address sel-indices))
|
||||
(ftype-set! mesh-geometry (index-count) geometry 6)
|
||||
|
||||
(fvec3-copy-c!
|
||||
(ftype-&ref pos3-pos3-color4 (posa) sel-instances 0)
|
||||
(fvec 0 0 0))
|
||||
(fvec3-copy-c!
|
||||
(ftype-&ref pos3-pos3-color4 (posb) sel-instances 0)
|
||||
(fvec 1 1 1))
|
||||
(fvec3-copy-c!
|
||||
(ftype-&ref pos3-pos3-color4 (color) sel-instances 0)
|
||||
(fvec 1 1 1 1))
|
||||
|
||||
(ftype-set! mesh-instance-data (instances) instance-data (ftype-pointer-address sel-instances))
|
||||
(ftype-set! mesh-instance-data (instance-count) instance-data 1)
|
||||
|
||||
(insert-mesh "grid-selector" "quad" geometry instance-data)
|
||||
(insert-mesh "grid-selector" "quad" geometry 1)
|
||||
(foreign-free (ftype-pointer-address sel-vertices))
|
||||
(foreign-free (ftype-pointer-address sel-indices))
|
||||
(foreign-free (ftype-pointer-address geometry))
|
||||
(foreign-free (ftype-pointer-address sel-instances))
|
||||
(foreign-free (ftype-pointer-address instance-data)))))
|
||||
(foreign-free (ftype-pointer-address geometry)))
|
||||
|
||||
(load-grid-selector-position (fvec 0 0 0))))
|
||||
|
||||
(define shutdown-grid-selector
|
||||
(lambda ()
|
||||
@ -181,30 +188,10 @@
|
||||
(define update-grid-selector!
|
||||
(lambda ()
|
||||
(unless (and (zero? grid-selector-shift-x) (zero? grid-selector-shift-y))
|
||||
|
||||
(set! grid-selector-grid-coord (tile-shift-grid-coord grid-selector-grid-coord grid-selector-shift-x grid-selector-shift-y))
|
||||
(set! grid-selector-shift-x 0)
|
||||
(set! grid-selector-shift-y 0)
|
||||
|
||||
(let ([sel-instances (make-ftype-pointer pos3-pos3-color4 (foreign-alloc (ftype-sizeof pos3-pos3-color4)))]
|
||||
[instance-data (make-ftype-pointer mesh-instance-data (foreign-alloc (ftype-sizeof mesh-instance-data)))])
|
||||
|
||||
(fvec3-copy-c!
|
||||
(ftype-&ref pos3-pos3-color4 (posa) sel-instances 0)
|
||||
(grid-coords->world-displacement grid-coord-origin grid-selector-grid-coord))
|
||||
(fvec3-copy-c!
|
||||
(ftype-&ref pos3-pos3-color4 (posb) sel-instances 0)
|
||||
(fvec 1 1 1))
|
||||
(fvec3-copy-c!
|
||||
(ftype-&ref pos3-pos3-color4 (color) sel-instances 0)
|
||||
(fvec 1 1 1 1))
|
||||
|
||||
(ftype-set! mesh-instance-data (instances) instance-data (ftype-pointer-address sel-instances))
|
||||
(ftype-set! mesh-instance-data (instance-count) instance-data 1)
|
||||
|
||||
(reload-mesh-instance-data "grid-selector" "quad" instance-data)
|
||||
(foreign-free (ftype-pointer-address sel-instances))
|
||||
(foreign-free (ftype-pointer-address instance-data))))))
|
||||
(load-grid-selector-position (grid-coords->world-displacement grid-coord-origin grid-selector-grid-coord)))))
|
||||
|
||||
(define render-grid-selector
|
||||
(lambda ()
|
||||
|
Loading…
Reference in New Issue
Block a user