Got ply loading working\n

main
noah metz 2024-01-13 02:24:35 -07:00
parent 3e7920bc92
commit 61e1e6fcef
5 changed files with 223 additions and 72 deletions

@ -7,29 +7,29 @@
typedef enum {
PLY_FORMAT_INVALID = -1,
PLY_FORMAT_ASCII,
PLY_FORMAT_LE,
PLY_FORMAT_BE,
PLY_FORMAT_ASCII = 0,
PLY_FORMAT_LE = 1,
PLY_FORMAT_BE = 2,
} PlyFormatType;
typedef enum {
PLY_HEADER_INVALID = -1,
PLY_HEADER_COMMENT,
PLY_HEADER_END,
PLY_HEADER_ELEMENT,
PLY_HEADER_PROPERTY,
PLY_HEADER_COMMENT = 0,
PLY_HEADER_END = 1,
PLY_HEADER_ELEMENT = 2,
PLY_HEADER_PROPERTY = 3,
} PlyHeaderType;
typedef enum {
PLY_TYPE_INVALID = -1,
PLY_TYPE_CHAR,
PLY_TYPE_UCHAR,
PLY_TYPE_SHORT,
PLY_TYPE_USHORT,
PLY_TYPE_INT,
PLY_TYPE_UINT,
PLY_TYPE_FLOAT,
PLY_TYPE_DOUBLE,
PLY_TYPE_CHAR = 0,
PLY_TYPE_UCHAR = 1,
PLY_TYPE_SHORT = 2,
PLY_TYPE_USHORT = 3,
PLY_TYPE_INT = 4,
PLY_TYPE_UINT = 5,
PLY_TYPE_FLOAT = 6,
PLY_TYPE_DOUBLE = 7,
} PlyPropertyType;
typedef struct PlyPropertyStruct {
@ -63,18 +63,10 @@ typedef struct PlyMeshStruct {
typedef struct PlyMappingsStruct {
char* vertex_element;
char* x;
char* y;
char* z;
char* nx;
char* ny;
char* nz;
char* r;
char* g;
char* b;
char* a;
char* u;
char* v;
char* position[3];
char* normal[3];
char* colour[4];
char* texture[2];
char* face_element;
char* index;

Binary file not shown.

@ -205,6 +205,9 @@ VkResult gpu_buffer_malloc(VkDevice device, GPUPage* page, VkDeviceSize size, Vk
return VK_ERROR_VALIDATION_FAILED_EXT;
}
//TODO: use real alignment size instead of hard-coded to 16
size += size % 16;
VkBufferCreateInfo buffer_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = size,

@ -978,30 +978,37 @@ VkRenderPass create_render_pass(VkDevice device, VkSurfaceFormatKHR format, VkFo
.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
VkSubpassDescription subpass = {
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
.colorAttachmentCount = sizeof(color_attachment_refs)/sizeof(VkAttachmentReference),
.pColorAttachments = color_attachment_refs,
.pDepthStencilAttachment = &depth_attachment_ref,
// Create a subpass with the color and depth attachments
VkSubpassDescription subpasses[] = {
{
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
.colorAttachmentCount = sizeof(color_attachment_refs)/sizeof(VkAttachmentReference),
.pColorAttachments = color_attachment_refs,
.pDepthStencilAttachment = &depth_attachment_ref,
},
};
VkSubpassDependency dependency = {
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccessMask = 0,
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
// This basically says "make sure nothing else is writing to the depth_stencil or the color attachment during the pipeline
VkSubpassDependency dependencies[] = {
{
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccessMask = 0,
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT,
}
};
VkRenderPassCreateInfo render_info = {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
.attachmentCount = sizeof(attachments)/sizeof(VkAttachmentDescription),
.pAttachments = attachments,
.subpassCount = 1,
.pSubpasses = &subpass,
.dependencyCount = 1,
.pDependencies = &dependency,
.subpassCount = sizeof(subpasses)/sizeof(VkSubpassDescription),
.pSubpasses = subpasses,
.dependencyCount = sizeof(dependencies)/sizeof(VkSubpassDependency),
.pDependencies = dependencies,
};
VkRenderPass render_pass;
@ -2800,28 +2807,38 @@ VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materi
return vkQueuePresentKHR(context->queues.present, &present_info);
}
Object create_simple_mesh_object(Material* simple_mesh_material, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, uint32_t max_frames_in_flight, VkDescriptorPool pool) {
Object create_simple_mesh_object(PlyMesh ply_mesh, Material* simple_mesh_material, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, uint32_t max_frames_in_flight, VkDescriptorPool pool) {
Object zero = {};
GPUPage* mesh_memory = NULL;
VkResult result = gpu_page_allocate(device, memories, 10000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &mesh_memory);
VkResult result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &mesh_memory);
if(result != VK_SUCCESS) {
return zero;
}
GPUPage* transfer_memory = NULL;
result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &transfer_memory);
result = gpu_page_allocate(device, memories, 200000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &transfer_memory);
if(result != VK_SUCCESS) {
return zero;
}
GPUBuffer transfer_buffer = {0};
result = gpu_buffer_malloc(device, transfer_memory, 10000, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &transfer_buffer);
result = gpu_buffer_malloc(device, transfer_memory, 100000, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &transfer_buffer);
if(result != VK_SUCCESS) {
return zero;
}
Mesh* mesh = load_mesh_to_buffer(device, mesh_memory, transfer_buffer, 4, sizeof(struct Vertex), (void*)vertices, 6, sizeof(uint16_t), (void*)indices, transfer_pool, transfer_queue);
struct Vertex* tmp = malloc(sizeof(struct Vertex)*ply_mesh.vertex_count);
for(uint32_t i = 0; i < ply_mesh.vertex_count; i++) {
tmp[i].pos[0] = ply_mesh.position[i][0];
tmp[i].pos[1] = ply_mesh.position[i][1];
tmp[i].pos[2] = ply_mesh.position[i][2];
tmp[i].color[0] = ply_mesh.colour[i][0];
tmp[i].color[1] = ply_mesh.colour[i][1];
tmp[i].color[2] = ply_mesh.colour[i][2];
}
Mesh* mesh = load_mesh_to_buffer(device, mesh_memory, transfer_buffer, ply_mesh.vertex_count, sizeof(struct Vertex), (void*)tmp, ply_mesh.index_count, sizeof(uint16_t), (void*)ply_mesh.index, transfer_pool, transfer_queue);
if(mesh == 0) {
return zero;
}
@ -2862,9 +2879,9 @@ Object create_simple_mesh_object(Material* simple_mesh_material, VkPhysicalDevic
return zero;
}
glm_quat_identity(position->rotation);
position->scale[0] = 10.f;
position->scale[1] = 10.f;
position->scale[2] = 10.f;
position->scale[0] = 1.f;
position->scale[1] = 1.f;
position->scale[2] = 1.f;
position->position[0] = 0.0f;
position->position[1] = 0.0f;
position->position[2] = 1.1f;
@ -3006,7 +3023,7 @@ Object create_texture_mesh_object(Material* texture_mesh_material, VkPhysicalDev
return object;
}
void main_loop(GLFWwindow* window, VulkanContext* context) {
void main_loop(PlyMesh ply_mesh, GLFWwindow* window, VulkanContext* context) {
SceneContext scene = create_scene_context(context->device, context->memories, context->max_frames_in_flight);
if(scene.pool == VK_NULL_HANDLE) {
return;
@ -3039,7 +3056,7 @@ void main_loop(GLFWwindow* window, VulkanContext* context) {
return;
}
Object triangle_object = create_simple_mesh_object(&simple_mesh_material, context->memories, context->device, context->transfer_command_pool, context->queues.transfer, context->max_frames_in_flight, simple_pool);
Object triangle_object = create_simple_mesh_object(ply_mesh, &simple_mesh_material, context->memories, context->device, context->transfer_command_pool, context->queues.transfer, context->max_frames_in_flight, simple_pool);
if(triangle_object.attributes.buckets == 0) {
fprintf(stderr, "failed to create simple mesh object\n");
return;
@ -3201,7 +3218,7 @@ int main() {
}
glfwSetKeyCallback(window, key_callback);
main_loop(window, context);
main_loop(monkey, window, context);
cleanup(window, context);

@ -92,22 +92,99 @@ void ply_free_elements(PlyElement* elements_head) {
PlyMappings default_ply_mappings = {
.vertex_element = "vertex",
.x = "x",
.y = "y",
.z = "z",
.nx = "nx",
.ny = "ny",
.nz = "nz",
.r = "red",
.g = "green",
.b = "blue",
.a = "alpha",
.u = "s",
.v = "t",
.position = {"x", "y", "z"},
.normal = {"nx", "ny", "nz"},
.colour = {"red", "green", "blue", "alpha"},
.texture = {"s", "t"},
.face_element = "face",
.index = "vetex_indices",
};
uint16_t ply_conv_index(PlyPropertyType type, void* value, int swap_order) {
if(type == PLY_TYPE_INVALID) {
return 0.0f;
}
uint8_t* ptr = value;
uint8_t tmp[8];
size_t type_size = ply_type_sizes[type];
for(uint32_t i = 0; i < type_size; i++) {
if(swap_order) {
tmp[type_size-i] = ptr[i];
} else {
tmp[i] = ptr[i];
}
}
switch(type) {
case PLY_TYPE_CHAR:
return (uint16_t)*(int8_t*)(tmp);
case PLY_TYPE_UCHAR:
return (uint16_t)*(uint8_t*)(tmp);
case PLY_TYPE_SHORT:
return *(int16_t*)(tmp);
case PLY_TYPE_USHORT:
return (uint16_t)*(uint16_t*)(tmp);
case PLY_TYPE_INT:
return (uint16_t)*(int32_t*)(tmp);
case PLY_TYPE_UINT:
return (uint16_t)*(uint32_t*)(tmp);
default:
return 0.0f;
}
}
float ply_conv_value(PlyPropertyType type, void* value, int swap_order) {
if(type == PLY_TYPE_INVALID) {
return 0.0f;
}
uint8_t* ptr = value;
uint8_t tmp[8];
size_t type_size = ply_type_sizes[type];
for(uint32_t i = 0; i < type_size; i++) {
if(swap_order) {
tmp[type_size-i] = ptr[i];
} else {
tmp[i] = ptr[i];
}
}
switch(type) {
case PLY_TYPE_CHAR:
return (float)*(int8_t*)(tmp)/(float)INT8_MAX;
case PLY_TYPE_UCHAR:
return (float)*(uint8_t*)(tmp)/(float)UINT8_MAX;
case PLY_TYPE_SHORT:
return (float)*(int16_t*)(tmp)/(float)INT16_MAX;
case PLY_TYPE_USHORT:
return (float)*(uint16_t*)(tmp)/(float)UINT16_MAX;
case PLY_TYPE_INT:
return (float)*(int32_t*)(tmp)/(float)INT32_MAX;
case PLY_TYPE_UINT:
return (float)*(uint32_t*)(tmp)/(float)UINT32_MAX;
case PLY_TYPE_FLOAT:
return *(float*)(tmp);
case PLY_TYPE_DOUBLE:
return *(float*)(tmp);
default:
return 0.0f;
}
}
int ply_map_values(char* name, int stride, int count, PlyPropertyType type, int mapping_count, char** mapping, void* data, float* out) {
for(int i = 0; i < mapping_count; i++) {
if(strcmp(name, mapping[i]) == 0) {
for(int j = 0; j < count; j++) {
size_t type_size = ply_type_sizes[type];
out[(stride*j)+i] = ply_conv_value(type, data + (type_size*j), 0);
}
return 1;
}
}
return 0;
}
PlyMesh ply_load_mesh(char* filename, PlyMappings mappings) {
PlyMesh mesh = {
.vertex_count = 0,
@ -263,12 +340,6 @@ PlyMesh ply_load_mesh(char* filename, PlyMappings mappings) {
PlyElement* elem = elements_head;
while(elem != NULL) {
if(strcmp(elem->name, mappings.vertex_element) == 0) {
} else if(strcmp(elem->name, mappings.face_element) == 0) {
}
PlyProperty* prop = elem->properties;
while(prop != NULL) {
if(prop->count == PLY_TYPE_INVALID) {
@ -313,6 +384,74 @@ PlyMesh ply_load_mesh(char* filename, PlyMappings mappings) {
elem = elem->next;
}
elem = elements_head;
while(elem != NULL) {
int type = -1;
if(strcmp(elem->name, mappings.vertex_element) == 0) {
type = 0;
mesh.position = malloc(sizeof(vec3)*elem->count);
mesh.colour = malloc(sizeof(vec4)*elem->count);
mesh.normal = malloc(sizeof(vec3)*elem->count);
mesh.uv = malloc(sizeof(vec2)*elem->count);
mesh.vertex_count = elem->count;
} else if(strcmp(elem->name, mappings.face_element) == 0) {
type = 1;
mesh.index_count = 3*elem->count;
mesh.index = malloc(3*elem->count*sizeof(uint16_t));
} else {
continue;
}
PlyProperty* prop = elem->properties;
while(prop != NULL) {
if(prop->count == PLY_TYPE_INVALID && type == 0) {
if(ply_map_values(prop->name,
3,
elem->count,
prop->element,
sizeof(mappings.position)/sizeof(char*),
mappings.position,
prop->elements,
(float*)mesh.position)) {
} else if(ply_map_values(prop->name,
4,
elem->count,
prop->element,
sizeof(mappings.colour)/sizeof(char*),
mappings.colour,
prop->elements,
(float*)mesh.colour)) {
} else if(ply_map_values(prop->name,
3,
elem->count,
prop->element,
sizeof(mappings.normal)/sizeof(char*),
mappings.normal,
prop->elements,
(float*)mesh.normal)) {
} else if(ply_map_values(prop->name,
2,
elem->count,
prop->element,
sizeof(mappings.texture)/sizeof(char*),
mappings.texture,
prop->elements,
(float*)mesh.uv)) {
}
} else if (prop->count != PLY_TYPE_INVALID && type == 1) {
for(int i = 0; i < elem->count; i++) {
int type_size = ply_type_sizes[prop->element];
void ** lists = prop->elements;
mesh.index[i*3 + 0] = ply_conv_index(prop->element, lists[i] + (0*type_size), 0);
mesh.index[i*3 + 1] = ply_conv_index(prop->element, lists[i] + (1*type_size), 0);
mesh.index[i*3 + 2] = ply_conv_index(prop->element, lists[i] + (2*type_size), 0);
}
}
prop = prop->next;
}
elem = elem->next;
}
clean:
ply_free_elements(elements_head);
close: