|
|
|
@ -190,6 +190,7 @@ typedef struct SceneContextStruct {
|
|
|
|
|
VkDescriptorSet* descriptors;
|
|
|
|
|
GPUBuffer* ubos;
|
|
|
|
|
void** ubo_ptrs;
|
|
|
|
|
VkPushConstantRange pcr;
|
|
|
|
|
} SceneContext;
|
|
|
|
|
|
|
|
|
|
struct TextureVertex {
|
|
|
|
@ -208,6 +209,10 @@ struct ModelUBO {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct SceneUBO {
|
|
|
|
|
mat4 test;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ScenePC {
|
|
|
|
|
mat4 view;
|
|
|
|
|
mat4 proj;
|
|
|
|
|
};
|
|
|
|
@ -895,13 +900,25 @@ VkShaderModule create_shader_module(VkDevice device, const char * code, uint32_t
|
|
|
|
|
return shader;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkShaderModule load_shader_file(uint32_t buffer_size, const char* path, VkDevice device) {
|
|
|
|
|
VkShaderModule load_shader_file(const char* path, VkDevice device) {
|
|
|
|
|
FILE* file;
|
|
|
|
|
file = fopen(path, "r");
|
|
|
|
|
file = fopen(path, "rb");
|
|
|
|
|
if(file == 0) {
|
|
|
|
|
return VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int result = fseek(file, 0, SEEK_END);
|
|
|
|
|
if(result != 0) {
|
|
|
|
|
return VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long buffer_size = ftell(file);
|
|
|
|
|
|
|
|
|
|
result = fseek(file, 0, SEEK_SET);
|
|
|
|
|
if(result != 0) {
|
|
|
|
|
return VK_NULL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char * buffer = malloc(buffer_size);
|
|
|
|
|
if(buffer == 0) {
|
|
|
|
|
return VK_NULL_HANDLE;
|
|
|
|
@ -1554,8 +1571,9 @@ void command_draw_object(Material material, Object object, uint32_t frame_num, V
|
|
|
|
|
vkCmdDrawIndexed(command_buffer, mesh->index_count, 1, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void command_draw_material(Material material, uint32_t object_count, Object* objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, VkCommandBuffer command_buffer) {
|
|
|
|
|
void command_draw_material(Material material, uint32_t object_count, Object* objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, struct ScenePC* scene_constants, VkCommandBuffer command_buffer) {
|
|
|
|
|
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.pipeline);
|
|
|
|
|
vkCmdPushConstants(command_buffer, material.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(struct ScenePC), scene_constants);
|
|
|
|
|
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.layout, 0, 1, &scene_descriptors[frame_num], 0, 0);
|
|
|
|
|
if(material.material_descriptors != 0) {
|
|
|
|
|
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.layout, 1, 1, &material.material_descriptors[frame_num], 0, 0);
|
|
|
|
@ -1565,7 +1583,7 @@ void command_draw_material(Material material, uint32_t object_count, Object* obj
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult command_draw_scene(uint32_t materials_count, Material* materials, uint32_t* object_counts, Object** objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent) {
|
|
|
|
|
VkResult command_draw_scene(uint32_t materials_count, Material* materials, uint32_t* object_counts, Object** objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, struct ScenePC* scene_constants, VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent) {
|
|
|
|
|
VkCommandBufferBeginInfo begin_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
|
|
|
|
.flags = 0,
|
|
|
|
@ -1625,7 +1643,7 @@ VkResult command_draw_scene(uint32_t materials_count, Material* materials, uint3
|
|
|
|
|
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
|
|
|
|
|
|
|
|
|
for(uint i = 0; i < materials_count; i++) {
|
|
|
|
|
command_draw_material(materials[i], object_counts[i], objects[i], frame_num, scene_descriptors, command_buffer);
|
|
|
|
|
command_draw_material(materials[i], object_counts[i], objects[i], frame_num, scene_descriptors, scene_constants, command_buffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vkCmdEndRenderPass(command_buffer);
|
|
|
|
@ -1762,6 +1780,7 @@ Material create_material(
|
|
|
|
|
uint32_t shader_stage_count,
|
|
|
|
|
VkPipelineShaderStageCreateInfo* shader_stages,
|
|
|
|
|
VkDescriptorSetLayout scene_ubo_layout,
|
|
|
|
|
VkPushConstantRange scene_pcr,
|
|
|
|
|
PipelineLayout pipeline_layout,
|
|
|
|
|
MeshType mesh_type,
|
|
|
|
|
uint32_t max_frames_in_flight,
|
|
|
|
@ -1862,8 +1881,8 @@ Material create_material(
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
|
|
|
|
.setLayoutCount = 3,
|
|
|
|
|
.pSetLayouts = all_layouts,
|
|
|
|
|
.pushConstantRangeCount = 0,
|
|
|
|
|
.pPushConstantRanges = 0,
|
|
|
|
|
.pushConstantRangeCount = 1,
|
|
|
|
|
.pPushConstantRanges = &scene_pcr,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
result = vkCreatePipelineLayout(device, &layout_info, 0, &layout);
|
|
|
|
@ -1892,9 +1911,9 @@ Material create_material(
|
|
|
|
|
return material;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout, uint32_t max_frames_in_flight) {
|
|
|
|
|
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);
|
|
|
|
|
Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout, VkPushConstantRange scene_pcr, uint32_t max_frames_in_flight) {
|
|
|
|
|
VkShaderModule vert_shader = load_shader_file("shader_src/basic.vert.spv", device);
|
|
|
|
|
VkShaderModule frag_shader = load_shader_file("shader_src/basic.frag.spv", device);
|
|
|
|
|
VkPipelineShaderStageCreateInfo shader_stages[2] = {
|
|
|
|
|
{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
|
@ -1979,16 +1998,16 @@ Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRende
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, simple_layout, simple_mesh_type, max_frames_in_flight, object_descriptor_mappings);
|
|
|
|
|
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, scene_pcr, simple_layout, simple_mesh_type, max_frames_in_flight, object_descriptor_mappings);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout, uint32_t max_frames_in_flight) {
|
|
|
|
|
VkShaderModule vert_shader = load_shader_file(2048, "shader_src/texture.vert.spv", device);
|
|
|
|
|
Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout, VkPushConstantRange scene_pcr, uint32_t max_frames_in_flight) {
|
|
|
|
|
VkShaderModule vert_shader = load_shader_file("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);
|
|
|
|
|
VkShaderModule frag_shader = load_shader_file("shader_src/texture.frag.spv", device);
|
|
|
|
|
if(frag_shader == VK_NULL_HANDLE) {
|
|
|
|
|
Material tmp = {};
|
|
|
|
|
return tmp;
|
|
|
|
@ -2090,7 +2109,7 @@ Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRend
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, texture_layout, textured_mesh_type, max_frames_in_flight, object_descriptor_mappings);
|
|
|
|
|
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, scene_pcr, texture_layout, textured_mesh_type, max_frames_in_flight, object_descriptor_mappings);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult command_copy_to_buffer(VkDevice device, GPUBuffer staging, VkBuffer destination, void* data, VkDeviceSize size, VkDeviceSize offset, VkCommandPool pool, VkQueue queue) {
|
|
|
|
@ -2502,6 +2521,11 @@ SceneContext create_scene_context(VkDevice device, VkPhysicalDeviceMemoryPropert
|
|
|
|
|
.descriptors = sets,
|
|
|
|
|
.ubos = ubos,
|
|
|
|
|
.ubo_ptrs = ubo_ptrs,
|
|
|
|
|
.pcr = {
|
|
|
|
|
.offset = 0,
|
|
|
|
|
.size = sizeof(struct ScenePC),
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return scene;
|
|
|
|
@ -2641,7 +2665,7 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod
|
|
|
|
|
vec3 world_position = {0.0f, 0.0f, 0.0f};
|
|
|
|
|
versor world_rotation = {-1.0f, 0.0f, 0.0f, 0.0f};
|
|
|
|
|
|
|
|
|
|
VkResult update_scene_descriptor(void** buffers, uint32_t frame_index, vec3 world_position, versor world_rotation, float aspect_ratio, float time_delta) {
|
|
|
|
|
struct ScenePC get_scene_constants(vec3 world_position, versor world_rotation, float aspect_ratio, float time_delta) {
|
|
|
|
|
vec3 movement_sum = {0.0f, 0.0f, 0.0f};
|
|
|
|
|
|
|
|
|
|
if(key_flags.forward) {
|
|
|
|
@ -2718,18 +2742,16 @@ VkResult update_scene_descriptor(void** buffers, uint32_t frame_index, vec3 worl
|
|
|
|
|
glm_quat_rotatev(world_rotation, movement_sum, movement_rot);
|
|
|
|
|
glm_vec3_add(movement_rot, world_position, world_position);
|
|
|
|
|
|
|
|
|
|
struct SceneUBO ubo = {};
|
|
|
|
|
|
|
|
|
|
glm_perspective(1.5708f, aspect_ratio, 0.01, 1000, ubo.proj);
|
|
|
|
|
glm_quat_look(world_position, world_rotation, ubo.view);
|
|
|
|
|
struct ScenePC constants = {};
|
|
|
|
|
|
|
|
|
|
memcpy(buffers[frame_index], (void*)&ubo, sizeof(ubo));
|
|
|
|
|
glm_perspective(1.5708f, aspect_ratio, 0.01, 1000, constants.proj);
|
|
|
|
|
glm_quat_look(world_position, world_rotation, constants.view);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
return constants;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materials_count, Material* materials, uint32_t* objects_counts, Object** objects) {
|
|
|
|
|
update_scene_descriptor(scene->ubo_ptrs, context->current_frame, world_position, world_rotation, (float)context->swapchain_extent.width/(float)context->swapchain_extent.height, 0.01);
|
|
|
|
|
struct ScenePC scene_constants = get_scene_constants(world_position, world_rotation, (float)context->swapchain_extent.width/(float)context->swapchain_extent.height, 0.01);
|
|
|
|
|
|
|
|
|
|
VkResult result;
|
|
|
|
|
result = vkWaitForFences(context->device, 1, &context->in_flight_fences[context->current_frame], VK_TRUE, UINT64_MAX);
|
|
|
|
@ -2753,7 +2775,7 @@ VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materi
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = command_draw_scene(materials_count, materials, objects_counts, objects, context->current_frame, scene->descriptors, context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent);
|
|
|
|
|
result = command_draw_scene(materials_count, materials, objects_counts, objects, context->current_frame, scene->descriptors, &scene_constants, context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent);
|
|
|
|
|
if(result != VK_SUCCESS) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
@ -3080,7 +3102,7 @@ void main_loop(GLFWwindow* window, VulkanContext* context) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Material simple_mesh_material = create_simple_mesh_material(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, context->max_frames_in_flight);
|
|
|
|
|
Material simple_mesh_material = create_simple_mesh_material(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, scene.pcr, context->max_frames_in_flight);
|
|
|
|
|
if(simple_mesh_material.pipeline == VK_NULL_HANDLE) {
|
|
|
|
|
fprintf(stderr, "failed to create simple mesh material\n");
|
|
|
|
|
return;
|
|
|
|
@ -3113,7 +3135,7 @@ void main_loop(GLFWwindow* window, VulkanContext* context) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Material texture_mesh_material = create_texture_mesh_material(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, context->max_frames_in_flight);
|
|
|
|
|
Material texture_mesh_material = create_texture_mesh_material(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, scene.pcr, context->max_frames_in_flight);
|
|
|
|
|
if(texture_mesh_material.pipeline == VK_NULL_HANDLE) {
|
|
|
|
|
fprintf(stderr, "failed to create texture mesh material\n");
|
|
|
|
|
return;
|
|
|
|
|