197 lines
7.5 KiB
Plaintext
197 lines
7.5 KiB
Plaintext
Skin_Vertex :: struct {
|
|
bone_index: [4] float;
|
|
bone_weight: [4] float;
|
|
}
|
|
|
|
Mesh_Vertex_Data_Type :: enum {
|
|
NONE;
|
|
POSITION;
|
|
NORMAL;
|
|
TEXCOORD;
|
|
TANGENT;
|
|
COLOR;
|
|
BITANGENT;
|
|
BONE_INDICES;
|
|
BONE_WEIGHTS;
|
|
|
|
INSTANCED_MAT1;
|
|
INSTANCED_MAT2;
|
|
INSTANCED_MAT3;
|
|
INSTANCED_MAT4;
|
|
}
|
|
|
|
Mesh_Handle :: #type, distinct u32;
|
|
|
|
Mesh :: struct {
|
|
name : string;
|
|
positions : [..] Vector3;
|
|
normals : [..] Vector3;
|
|
texcoords : [..] Vector2;
|
|
tangents : [..] Vector3;
|
|
bitangents : [..] Vector3;
|
|
colors : [..] Vector4;
|
|
skin_data : [..] Skin_Vertex;
|
|
|
|
bone_indices: [..] s32;
|
|
bone_matrices: [..] Matrix4;
|
|
num_bones: s32;
|
|
|
|
indices : [..] u32;
|
|
ib : Buffer_Handle;
|
|
|
|
vbs : Table(u32, Buffer_Handle);
|
|
//vb : Buffer_Handle;
|
|
}
|
|
|
|
get_mesh_vb :: (mesh: *Mesh, pipeline_handle: Pipeline_State_Handle = 0) -> Buffer_Handle {
|
|
handle := ifx pipeline_handle == 0 then engine.renderer.current_state.last_set_pipeline else pipeline_handle;
|
|
|
|
pipeline_state := *engine.renderer.pipeline_states[handle-1];
|
|
return get_mesh_vb(mesh, pipeline_state.mesh_data_types);
|
|
}
|
|
|
|
get_mesh_vb :: (mesh: *Mesh, input: [] Mesh_Vertex_Data_Type) -> Buffer_Handle {
|
|
hash : u32 = 0;
|
|
|
|
nums : [8] u32 : .[13, 61, 84, 86, 65, 10000, 100000, 126];
|
|
for input, i: input {
|
|
hash += nums[i] * cast(u32)input;
|
|
}
|
|
|
|
if !table_contains(*mesh.vbs, hash) {
|
|
final_vertices : [..] float;
|
|
final_vertices.allocator = temp;
|
|
|
|
stride : u32 = 0;
|
|
|
|
for input: input {
|
|
if input == {
|
|
case .POSITION; stride += 3;
|
|
case .NORMAL; stride += 3;
|
|
case .TEXCOORD; stride += 2;
|
|
case .COLOR; stride += 4;
|
|
case .TANGENT; stride += 3;
|
|
case .BITANGENT; stride += 3;
|
|
case .BONE_INDICES; stride += 4;
|
|
case .BONE_WEIGHTS; stride += 4;
|
|
}
|
|
}
|
|
|
|
for 0..mesh.positions.count-1 {
|
|
for input: input {
|
|
if input == {
|
|
case .POSITION; {
|
|
array_add(*final_vertices, mesh.positions[it].x);
|
|
array_add(*final_vertices, mesh.positions[it].y);
|
|
array_add(*final_vertices, mesh.positions[it].z);
|
|
}
|
|
case .NORMAL; {
|
|
if mesh.normals.count > 0 {
|
|
array_add(*final_vertices, mesh.normals[it].x);
|
|
array_add(*final_vertices, mesh.normals[it].y);
|
|
array_add(*final_vertices, mesh.normals[it].z);
|
|
} else {
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
log_error("Mesh didn't have required normals\n");
|
|
}
|
|
}
|
|
case .TEXCOORD; {
|
|
if mesh.texcoords.count > 0 {
|
|
array_add(*final_vertices, mesh.texcoords[it].x);
|
|
array_add(*final_vertices, mesh.texcoords[it].y);
|
|
} else {
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
log_error("Mesh didn't have required texcoords\n");
|
|
}
|
|
}
|
|
case .COLOR; {
|
|
if mesh.colors.count > 0 {
|
|
array_add(*final_vertices, mesh.colors[it].x);
|
|
array_add(*final_vertices, mesh.colors[it].y);
|
|
array_add(*final_vertices, mesh.colors[it].z);
|
|
array_add(*final_vertices, mesh.colors[it].w);
|
|
} else {
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
log_error("Mesh didn't have required colors\n");
|
|
}
|
|
}
|
|
case .TANGENT; {
|
|
if mesh.tangents.count > 0 {
|
|
array_add(*final_vertices, mesh.tangents[it].x);
|
|
array_add(*final_vertices, mesh.tangents[it].y);
|
|
array_add(*final_vertices, mesh.tangents[it].z);
|
|
} else {
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
log_error("Mesh didn't have required tangents\n");
|
|
}
|
|
}
|
|
case .BITANGENT; {
|
|
if mesh.bitangents.count > 0 {
|
|
array_add(*final_vertices, mesh.bitangents[it].x);
|
|
array_add(*final_vertices, mesh.bitangents[it].y);
|
|
array_add(*final_vertices, mesh.bitangents[it].z);
|
|
} else {
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
log_error("Mesh didn't have required bitangents\n");
|
|
}
|
|
}
|
|
case .BONE_INDICES; {
|
|
if mesh.skin_data.count > 0 {
|
|
for index: 0..3 {
|
|
array_add(*final_vertices, mesh.skin_data[it].bone_index[index]);
|
|
}
|
|
} else {
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
log_error("Mesh didn't have required bone indices\n");
|
|
}
|
|
}
|
|
case .BONE_WEIGHTS; {
|
|
if mesh.skin_data.count > 0 {
|
|
for index: 0..3 {
|
|
array_add(*final_vertices, mesh.skin_data[it].bone_weight[index]);
|
|
}
|
|
} else {
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
array_add(*final_vertices, 0.0);
|
|
log_error("Mesh didn't have required bone weights\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vb_size := size_of(float)*stride*mesh.positions.count;
|
|
vb := create_vertex_buffer(engine.renderer, final_vertices.data, xx vb_size, stride=size_of(float)*stride);
|
|
table_add(*mesh.vbs, hash, vb);
|
|
}
|
|
|
|
success, value := table_find_new(*mesh.vbs, hash);
|
|
return value;
|
|
}
|
|
|
|
delete_mesh :: (handle: Mesh_Handle) {
|
|
mesh := parray_get(*engine.renderer.meshes, handle);
|
|
for mesh.vbs {
|
|
destroy_buffer(engine.renderer, it);
|
|
}
|
|
|
|
deinit(*mesh.vbs);
|
|
|
|
parray_remove(*engine.renderer.meshes, handle);
|
|
}
|