|
|
|
@ -112,12 +112,20 @@ typedef struct VulkanContextStruct {
|
|
|
|
|
void** scene_ubo_ptrs;
|
|
|
|
|
|
|
|
|
|
Mesh triangle_mesh;
|
|
|
|
|
Mesh triangle_mesh_textured;
|
|
|
|
|
Material simple_mesh_material;
|
|
|
|
|
Material texture_mesh_material;
|
|
|
|
|
|
|
|
|
|
uint32_t current_frame;
|
|
|
|
|
} VulkanContext;
|
|
|
|
|
|
|
|
|
|
struct Vertex{
|
|
|
|
|
struct TextureVertex {
|
|
|
|
|
vec3 pos;
|
|
|
|
|
vec3 color;
|
|
|
|
|
vec2 tex;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct Vertex {
|
|
|
|
|
vec3 pos;
|
|
|
|
|
vec3 color;
|
|
|
|
|
};
|
|
|
|
@ -132,12 +140,17 @@ const struct Vertex vertices[] = {
|
|
|
|
|
{.pos = { 0.5f, -0.5f, 0.5f}, .color = {0.0f, 1.0f, 0.0f}},
|
|
|
|
|
{.pos = { 0.5f, 0.5f, 0.5f}, .color = {0.0f, 0.0f, 1.0f}},
|
|
|
|
|
{.pos = {-0.5f, 0.5f, 0.5f}, .color = {1.0f, 1.0f, 1.0f}},
|
|
|
|
|
{.pos = { 0.5f, 0.5f, 1.0f}, .color = {0.0f, 0.0f, 1.0f}},
|
|
|
|
|
{.pos = {-0.5f, 0.5f, 1.0f}, .color = {1.0f, 1.0f, 1.0f}},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const struct TextureVertex texture_vertices[] = {
|
|
|
|
|
{.pos = {-0.5f, -0.5f, 0.5f}, .color = {1.0f, 0.0f, 0.0f}, .tex = {0.0f, 1.0f}},
|
|
|
|
|
{.pos = { 0.5f, -0.5f, 0.5f}, .color = {0.0f, 1.0f, 0.0f}, .tex = {1.0f, 0.0f}},
|
|
|
|
|
{.pos = { 0.5f, 0.5f, 0.5f}, .color = {0.0f, 0.0f, 1.0f}, .tex = {1.0f, 1.0f}},
|
|
|
|
|
{.pos = {-0.5f, 0.5f, 0.5f}, .color = {1.0f, 1.0f, 1.0f}, .tex = {0.5f, 0.5f}},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const uint16_t indices[] = {
|
|
|
|
|
2, 1, 0, 0, 3, 2, 5, 4, 3,
|
|
|
|
|
2, 1, 0, 0, 3, 2,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const char * validation_layers[] = {
|
|
|
|
@ -1363,7 +1376,36 @@ VkFence* create_fences(VkDevice device, VkFenceCreateFlags flags, uint32_t count
|
|
|
|
|
return fences;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mesh load_mesh(VkPhysicalDevice physical_device, VkDevice device, struct Vertex* vertices, uint32_t vertex_count, uint16_t* indices, uint32_t index_count, VkCommandPool transfer_pool, VkQueue transfer_queue) {
|
|
|
|
|
Mesh load_texture_mesh(VkPhysicalDevice physical_device, VkDevice device, struct TextureVertex* vertices, uint32_t vertex_count, uint16_t* indices, uint32_t index_count, VkCommandPool transfer_pool, VkQueue transfer_queue) {
|
|
|
|
|
Mesh mesh = {};
|
|
|
|
|
mesh.vertex_buffer.buffer = VK_NULL_HANDLE;
|
|
|
|
|
mesh.vertex_buffer.memory = VK_NULL_HANDLE;
|
|
|
|
|
mesh.index_buffer.buffer = VK_NULL_HANDLE;
|
|
|
|
|
mesh.index_buffer.memory = VK_NULL_HANDLE;
|
|
|
|
|
|
|
|
|
|
AllocatedBuffer vertex_buffer = create_populated_buffer(physical_device, device, (void*)vertices, sizeof(struct TextureVertex) * vertex_count, transfer_pool, transfer_queue, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
|
|
|
|
if(vertex_buffer.memory == VK_NULL_HANDLE) {
|
|
|
|
|
return mesh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mesh.vertex_buffer = vertex_buffer;
|
|
|
|
|
mesh.vertex_count = vertex_count;
|
|
|
|
|
|
|
|
|
|
AllocatedBuffer index_buffer = create_populated_buffer(physical_device, device, (void*)indices, sizeof(uint16_t) * index_count, transfer_pool, transfer_queue, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
|
|
|
|
|
if(index_buffer.memory == VK_NULL_HANDLE) {
|
|
|
|
|
deallocate_buffer(device, vertex_buffer);
|
|
|
|
|
AllocatedBuffer tmp = { .memory = VK_NULL_HANDLE, .buffer = VK_NULL_HANDLE};
|
|
|
|
|
mesh.vertex_buffer = tmp;
|
|
|
|
|
return mesh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mesh.index_buffer = index_buffer;
|
|
|
|
|
mesh.index_count = index_count;
|
|
|
|
|
|
|
|
|
|
return mesh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mesh load_simple_mesh(VkPhysicalDevice physical_device, VkDevice device, struct Vertex* vertices, uint32_t vertex_count, uint16_t* indices, uint32_t index_count, VkCommandPool transfer_pool, VkQueue transfer_queue) {
|
|
|
|
|
Mesh mesh = {};
|
|
|
|
|
mesh.vertex_buffer.buffer = VK_NULL_HANDLE;
|
|
|
|
|
mesh.vertex_buffer.memory = VK_NULL_HANDLE;
|
|
|
|
@ -1452,6 +1494,100 @@ Material create_material(
|
|
|
|
|
return material;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout) {
|
|
|
|
|
VkShaderModule vert_shader = load_shader_file(2048, "shader_src/basic.vert.spv", device);
|
|
|
|
|
VkShaderModule frag_shader = load_shader_file(2048, "shader_src/basic.frag.spv", device);
|
|
|
|
|
VkPipelineShaderStageCreateInfo shader_stages[2] = {};
|
|
|
|
|
shader_stages[0].sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT;
|
|
|
|
|
shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
|
|
shader_stages[0].module = vert_shader;
|
|
|
|
|
shader_stages[0].pName = "main";
|
|
|
|
|
|
|
|
|
|
shader_stages[1].sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT;
|
|
|
|
|
shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
|
|
shader_stages[1].module = frag_shader;
|
|
|
|
|
shader_stages[1].pName = "main";
|
|
|
|
|
|
|
|
|
|
VkVertexInputBindingDescription bindings[1] = {
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.stride = sizeof(struct Vertex),
|
|
|
|
|
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkVertexInputAttributeDescription attributes[2] = {
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.location = 0,
|
|
|
|
|
.format = VK_FORMAT_R32G32B32_SFLOAT,
|
|
|
|
|
.offset = offsetof(struct Vertex, pos),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.location = 1,
|
|
|
|
|
.format = VK_FORMAT_R32G32B32_SFLOAT,
|
|
|
|
|
.offset = offsetof(struct Vertex, color),
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, 0, 0, 0, 0, 1, bindings, 2, attributes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout) {
|
|
|
|
|
VkShaderModule vert_shader = load_shader_file(2048, "shader_src/texture.vert.spv", device);
|
|
|
|
|
if(vert_shader == VK_NULL_HANDLE) {
|
|
|
|
|
Material tmp = {};
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
VkShaderModule frag_shader = load_shader_file(2048, "shader_src/texture.frag.spv", device);
|
|
|
|
|
if(frag_shader == VK_NULL_HANDLE) {
|
|
|
|
|
Material tmp = {};
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
VkPipelineShaderStageCreateInfo shader_stages[2] = {};
|
|
|
|
|
shader_stages[0].sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT;
|
|
|
|
|
shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
|
|
shader_stages[0].module = vert_shader;
|
|
|
|
|
shader_stages[0].pName = "main";
|
|
|
|
|
|
|
|
|
|
shader_stages[1].sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT;
|
|
|
|
|
shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
|
|
shader_stages[1].module = frag_shader;
|
|
|
|
|
shader_stages[1].pName = "main";
|
|
|
|
|
|
|
|
|
|
VkVertexInputBindingDescription bindings[1] = {
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.stride = sizeof(struct TextureVertex),
|
|
|
|
|
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkVertexInputAttributeDescription attributes[3] = {
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.location = 0,
|
|
|
|
|
.format = VK_FORMAT_R32G32B32_SFLOAT,
|
|
|
|
|
.offset = offsetof(struct TextureVertex, pos),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.location = 1,
|
|
|
|
|
.format = VK_FORMAT_R32G32B32_SFLOAT,
|
|
|
|
|
.offset = offsetof(struct TextureVertex, color),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.location = 2,
|
|
|
|
|
.format = VK_FORMAT_R32G32_SFLOAT,
|
|
|
|
|
.offset = offsetof(struct TextureVertex, tex),
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, 0, 0, 0, 0, 1, bindings, 3, attributes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
|
|
|
|
|
VulkanContext* context = (VulkanContext*)malloc(sizeof(VulkanContext));
|
|
|
|
|
|
|
|
|
@ -1688,43 +1824,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
|
|
|
|
|
vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkShaderModule vert_shader = load_shader_file(2048, "shader_src/basic.vert.spv", device);
|
|
|
|
|
VkShaderModule frag_shader = load_shader_file(2048, "shader_src/basic.frag.spv", device);
|
|
|
|
|
VkPipelineShaderStageCreateInfo shader_stages[2] = {};
|
|
|
|
|
shader_stages[0].sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT;
|
|
|
|
|
shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
|
|
shader_stages[0].module = vert_shader;
|
|
|
|
|
shader_stages[0].pName = "main";
|
|
|
|
|
|
|
|
|
|
shader_stages[1].sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT;
|
|
|
|
|
shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
|
|
shader_stages[1].module = frag_shader;
|
|
|
|
|
shader_stages[1].pName = "main";
|
|
|
|
|
|
|
|
|
|
VkVertexInputBindingDescription bindings[1] = {
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.stride = sizeof(struct Vertex),
|
|
|
|
|
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkVertexInputAttributeDescription attributes[2] = {
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.location = 0,
|
|
|
|
|
.format = VK_FORMAT_R32G32B32_SFLOAT,
|
|
|
|
|
.offset = offsetof(struct Vertex, pos),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.location = 1,
|
|
|
|
|
.format = VK_FORMAT_R32G32B32_SFLOAT,
|
|
|
|
|
.offset = offsetof(struct Vertex, color),
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Material simple_mesh_material = create_material(context->device, context->swapchain_extent, context->render_pass, 2, shader_stages, context->scene_ubo_layout, 0, 0, 0, 0, 1, bindings, 2, attributes);
|
|
|
|
|
Material simple_mesh_material = create_simple_mesh_material(context->device, context->swapchain_extent, context->render_pass, context->scene_ubo_layout);
|
|
|
|
|
if(simple_mesh_material.pipeline == VK_NULL_HANDLE) {
|
|
|
|
|
fprintf(stderr, "failed to create simple mesh material\n");
|
|
|
|
|
return 0;
|
|
|
|
@ -1732,13 +1832,30 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {
|
|
|
|
|
context->simple_mesh_material = simple_mesh_material;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mesh triangle_mesh = load_mesh(context->physical_device, context->device, (struct Vertex*)vertices, 6, (uint16_t*)indices, 9, context->transfer_command_pool, context->queues.transfer);
|
|
|
|
|
Material texture_mesh_material = create_texture_mesh_material(context->device, context->swapchain_extent, context->render_pass, context->scene_ubo_layout);
|
|
|
|
|
if(texture_mesh_material.pipeline == VK_NULL_HANDLE) {
|
|
|
|
|
fprintf(stderr, "failed to create texture mesh material\n");
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
context->texture_mesh_material = texture_mesh_material;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mesh triangle_mesh = load_simple_mesh(context->physical_device, context->device, (struct Vertex*)vertices, 4, (uint16_t*)indices, 6, context->transfer_command_pool, context->queues.transfer);
|
|
|
|
|
if(triangle_mesh.vertex_buffer.buffer == VK_NULL_HANDLE) {
|
|
|
|
|
fprintf(stderr, "failed to load triangle mesh\n");
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
context->triangle_mesh = triangle_mesh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mesh triangle_mesh_textured = load_texture_mesh(context->physical_device, context->device, (struct TextureVertex*)texture_vertices, 4, (uint16_t*)indices, 6, context->transfer_command_pool, context->queues.transfer);
|
|
|
|
|
if(triangle_mesh_textured.vertex_buffer.buffer == VK_NULL_HANDLE) {
|
|
|
|
|
fprintf(stderr, "failed to load textured triangle mesh\n");
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
context->triangle_mesh_textured = triangle_mesh_textured;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return context;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1937,8 +2054,8 @@ VkResult draw_frame(VulkanContext* context) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t mesh_counts[] = {1};
|
|
|
|
|
Mesh* meshes[] = {&context->triangle_mesh};
|
|
|
|
|
result = record_command_buffer_scene(1, &context->simple_mesh_material, (uint32_t*)&mesh_counts, (Mesh**)meshes, context->scene_ubo_descriptors[context->current_frame], context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent);
|
|
|
|
|
Mesh* meshes[] = {&context->triangle_mesh_textured};
|
|
|
|
|
result = record_command_buffer_scene(1, &context->texture_mesh_material, (uint32_t*)&mesh_counts, (Mesh**)meshes, context->scene_ubo_descriptors[context->current_frame], context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|