I just managed to draw pure shit
This commit is contained in:
parent
af94aeeef7
commit
09a64f4965
@ -994,8 +994,24 @@ typedef struct {
|
||||
VkBuffer buffer;
|
||||
} MargaretBufferInMemoryInfo;
|
||||
|
||||
SpanT_struct_Definition(MargaretBufferInMemoryInfo)
|
||||
SpanT_method_Definition(MargaretBufferInMemoryInfo)
|
||||
#define MargaretBufferInMemoryInfo_drop(self) {}
|
||||
#define MargaretBufferInMemoryInfo_clone(self) (*(self))
|
||||
|
||||
VecT_trivmove_struct_Definition(MargaretBufferInMemoryInfo);
|
||||
VecT_trivmove_method_Definition(MargaretBufferInMemoryInfo);
|
||||
VecT_primitive_zeroinit_method_Definition(MargaretBufferInMemoryInfo);
|
||||
|
||||
typedef MargaretBufferInMemoryInfo* MargaretBufferInMemoryInfo_Ptr;
|
||||
|
||||
#define MargaretBufferInMemoryInfo_Ptr_drop(self) {}
|
||||
#define MargaretBufferInMemoryInfo_Ptr_clone(self) (*(self))
|
||||
|
||||
VecT_trivmove_struct_Definition(MargaretBufferInMemoryInfo_Ptr);
|
||||
VecT_trivmove_method_Definition(MargaretBufferInMemoryInfo_Ptr);
|
||||
VecT_primitive_zeroinit_method_Definition(MargaretBufferInMemoryInfo_Ptr);
|
||||
SpanT_struct_Definition(MargaretBufferInMemoryInfo_Ptr)
|
||||
SpanT_method_Definition(MargaretBufferInMemoryInfo_Ptr)
|
||||
SpanT_VecT_method_Definition(MargaretBufferInMemoryInfo_Ptr)
|
||||
|
||||
// Used in autogenerated code
|
||||
typedef struct {
|
||||
@ -1009,19 +1025,35 @@ typedef struct {
|
||||
VkImage image;
|
||||
} MargaretImageInMemoryInfo;
|
||||
|
||||
SpanT_struct_Definition(MargaretImageInMemoryInfo)
|
||||
SpanT_method_Definition(MargaretImageInMemoryInfo)
|
||||
#define MargaretImageInMemoryInfo_drop(self) {}
|
||||
#define MargaretImageInMemoryInfo_clone(self) (*(self))
|
||||
|
||||
VecT_trivmove_struct_Definition(MargaretImageInMemoryInfo);
|
||||
VecT_trivmove_method_Definition(MargaretImageInMemoryInfo);
|
||||
VecT_primitive_zeroinit_method_Definition(MargaretImageInMemoryInfo);
|
||||
|
||||
typedef MargaretImageInMemoryInfo* MargaretImageInMemoryInfo_Ptr;
|
||||
|
||||
#define MargaretImageInMemoryInfo_Ptr_drop(self) {}
|
||||
#define MargaretImageInMemoryInfo_Ptr_clone(self) (*(self))
|
||||
|
||||
VecT_trivmove_struct_Definition(MargaretImageInMemoryInfo_Ptr);
|
||||
VecT_trivmove_method_Definition(MargaretImageInMemoryInfo_Ptr);
|
||||
VecT_primitive_zeroinit_method_Definition(MargaretImageInMemoryInfo_Ptr);
|
||||
SpanT_struct_Definition(MargaretImageInMemoryInfo_Ptr)
|
||||
SpanT_method_Definition(MargaretImageInMemoryInfo_Ptr)
|
||||
SpanT_VecT_method_Definition(MargaretImageInMemoryInfo_Ptr)
|
||||
|
||||
// A handy function to initialize buffers and images (attaching them to allocated memory)
|
||||
VkDeviceMemory margaret_initialize_buffers_and_images(
|
||||
VkPhysicalDevice physical_device, VkDevice device,
|
||||
SpanMargaretBufferInMemoryInfo buffer_hands, SpanMargaretImageInMemoryInfo image_hands,
|
||||
SpanMargaretBufferInMemoryInfo_Ptr buffer_hands, SpanMargaretImageInMemoryInfo_Ptr image_hands,
|
||||
VkMemoryPropertyFlags properties
|
||||
) {
|
||||
uint32_t memory_types_allowed = -1;
|
||||
VkDeviceSize offset = 0;
|
||||
for (size_t i = 0; i < buffer_hands.len; i++) {
|
||||
MargaretBufferInMemoryInfo* buf_hand = SpanMargaretBufferInMemoryInfo_at(buffer_hands, i);
|
||||
MargaretBufferInMemoryInfo* buf_hand = *SpanMargaretBufferInMemoryInfo_Ptr_at(buffer_hands, i);
|
||||
VkBufferCreateInfo create_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.size = buf_hand->sz,
|
||||
@ -1041,7 +1073,7 @@ VkDeviceMemory margaret_initialize_buffers_and_images(
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < image_hands.len; i++) {
|
||||
MargaretImageInMemoryInfo* img_hand = SpanMargaretImageInMemoryInfo_at(image_hands, i);
|
||||
MargaretImageInMemoryInfo* img_hand = *SpanMargaretImageInMemoryInfo_Ptr_at(image_hands, i);
|
||||
VkImageCreateInfo crinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
.imageType = VK_IMAGE_TYPE_2D,
|
||||
@ -1082,13 +1114,13 @@ VkDeviceMemory margaret_initialize_buffers_and_images(
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < buffer_hands.len; i++) {
|
||||
MargaretBufferInMemoryInfo* buf_hand = SpanMargaretBufferInMemoryInfo_at(buffer_hands, i);
|
||||
MargaretBufferInMemoryInfo* buf_hand = *SpanMargaretBufferInMemoryInfo_Ptr_at(buffer_hands, i);
|
||||
if (vkBindBufferMemory(device, buf_hand->buffer, memory, buf_hand->offset) != VK_SUCCESS)
|
||||
abortf("vkBindBufferMemory");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < image_hands.len; i++) {
|
||||
MargaretImageInMemoryInfo* img_hand = SpanMargaretImageInMemoryInfo_at(image_hands, i);
|
||||
MargaretImageInMemoryInfo* img_hand = *SpanMargaretImageInMemoryInfo_Ptr_at(image_hands, i);
|
||||
if (vkBindImageMemory(device, img_hand->image, memory, img_hand->offset) != VK_SUCCESS)
|
||||
abortf("vkBindImageMemory");
|
||||
}
|
||||
@ -1371,18 +1403,18 @@ VkDescriptorPool margaret_create_descriptor_set_pool(VkDevice device,
|
||||
return descriptor_pool;
|
||||
}
|
||||
|
||||
void margaret_record_buf_copying_command_buf(
|
||||
VkDevice device, VkCommandBuffer command_buffer,
|
||||
VkBuffer dest_buffer, VkBuffer src_buffer, VkDeviceSize buffer_size
|
||||
) {
|
||||
VkCommandBufferBeginInfo beginfo = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, };
|
||||
if (vkBeginCommandBuffer(command_buffer, &beginfo) != VK_SUCCESS)
|
||||
abortf("vkBeginCommandBuffer");
|
||||
VkBufferCopy regions_to_copy[1] = {(VkBufferCopy){.srcOffset = 0, .dstOffset = 0, .size = buffer_size}};
|
||||
vkCmdCopyBuffer(command_buffer, src_buffer, dest_buffer, ARRAY_SIZE(regions_to_copy), regions_to_copy);
|
||||
if (vkEndCommandBuffer(command_buffer) != VK_SUCCESS)
|
||||
abortf("vkEndCommandBuffer");
|
||||
}
|
||||
/* Won't actually use this function, it's too underpowered */
|
||||
// void margaret_record_buf_copying_command_buf(VkCommandBuffer command_buffer,
|
||||
// VkBuffer dest_buffer, VkBuffer src_buffer, VkDeviceSize buffer_size
|
||||
// ) {
|
||||
// VkCommandBufferBeginInfo beginfo = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, };
|
||||
// if (vkBeginCommandBuffer(command_buffer, &beginfo) != VK_SUCCESS)
|
||||
// abortf("vkBeginCommandBuffer");
|
||||
// VkBufferCopy regions_to_copy[1] = {(VkBufferCopy){.srcOffset = 0, .dstOffset = 0, .size = buffer_size}};
|
||||
// vkCmdCopyBuffer(command_buffer, src_buffer, dest_buffer, ARRAY_SIZE(regions_to_copy), regions_to_copy);
|
||||
// if (vkEndCommandBuffer(command_buffer) != VK_SUCCESS)
|
||||
// abortf("vkEndCommandBuffer");
|
||||
// }
|
||||
|
||||
VkDescriptorSet margaret_allocate_descriptor_set(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSetLayout layout) {
|
||||
VkDescriptorSetAllocateInfo alloc_info = {
|
||||
@ -1397,4 +1429,11 @@ VkDescriptorSet margaret_allocate_descriptor_set(VkDevice device, VkDescriptorPo
|
||||
return descriptor_set;
|
||||
}
|
||||
|
||||
#define VkBufferCopy_drop(x) {}
|
||||
#define VkBufferCopy_clone(xp) (*(xp))
|
||||
|
||||
VecT_trivmove_struct_Definition(VkBufferCopy)
|
||||
VecT_trivmove_method_Definition(VkBufferCopy)
|
||||
VecT_primitive_zeroinit_method_Definition(VkBufferCopy)
|
||||
|
||||
#endif
|
||||
|
||||
@ -90,7 +90,7 @@ VkRenderPass create_render_pass_0(VkDevice logical_device, VkFormat colorbuffer_
|
||||
return render_pass;
|
||||
}
|
||||
|
||||
margaret_prep_buffer_mem_info_of_gpu_vbo_Definition(Vertex)
|
||||
margaret_prep_buffer_mem_info_of_gpu_vbo_Definition(GenericMeshVertex)
|
||||
|
||||
PipelineHands create_graphics_pipeline_0(
|
||||
VkDevice device, VkRenderPass render_pass, uint32_t subpass
|
||||
@ -107,23 +107,56 @@ PipelineHands create_graphics_pipeline_0(
|
||||
margaret_shader_stage_fragment_crinfo(frag_module)
|
||||
};
|
||||
|
||||
VkVertexInputBindingDescription vertex_bindings[1] = { {
|
||||
.binding = 0,
|
||||
.stride = sizeof(Vertex),
|
||||
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
|
||||
} };
|
||||
VkVertexInputAttributeDescription vertex_attributes[2] = {
|
||||
VkVertexInputBindingDescription vertex_bindings[2] = {
|
||||
{
|
||||
.binding = 0,
|
||||
.stride = sizeof(GenericMeshVertex),
|
||||
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
|
||||
},
|
||||
{
|
||||
.binding = 1,
|
||||
.stride = sizeof(GenericMeshInstance),
|
||||
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE,
|
||||
}
|
||||
};
|
||||
VkVertexInputAttributeDescription vertex_attributes[2 + 4] = {
|
||||
{
|
||||
.location = 0,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32_SFLOAT,
|
||||
.offset = offsetof(Vertex, pos),
|
||||
.offset = offsetof(GenericMeshVertex, pos),
|
||||
},
|
||||
{
|
||||
.location = 1,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32_SFLOAT,
|
||||
.offset = offsetof(Vertex, tex),
|
||||
.offset = offsetof(GenericMeshVertex, tex),
|
||||
},
|
||||
|
||||
/* This is a mat4 datatype, so it will take 4 entire 'locations' */
|
||||
{
|
||||
.location = 2,
|
||||
.binding = 1,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = offsetof(GenericMeshInstance, model_trans) + offsetof(mat4, x)
|
||||
},
|
||||
{
|
||||
.location = 3,
|
||||
.binding = 1,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = offsetof(GenericMeshInstance, model_trans) + offsetof(mat4, y)
|
||||
},
|
||||
{
|
||||
.location = 4,
|
||||
.binding = 1,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = offsetof(GenericMeshInstance, model_trans) + offsetof(mat4, z)
|
||||
},
|
||||
{
|
||||
.location = 5,
|
||||
.binding = 1,
|
||||
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
.offset = offsetof(GenericMeshInstance, model_trans) + offsetof(mat4, w)
|
||||
},
|
||||
};
|
||||
|
||||
@ -153,8 +186,8 @@ PipelineHands create_graphics_pipeline_0(
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
||||
.depthClampEnable = VK_FALSE,
|
||||
.polygonMode = VK_POLYGON_MODE_FILL,
|
||||
.cullMode = VK_CULL_MODE_BACK_BIT,
|
||||
// .cullMode = VK_CULL_MODE_NONE,
|
||||
// .cullMode = VK_CULL_MODE_BACK_BIT,
|
||||
.cullMode = VK_CULL_MODE_NONE,
|
||||
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
|
||||
.depthBiasEnable = VK_FALSE,
|
||||
.depthBiasConstantFactor = 0.0f,
|
||||
@ -237,7 +270,13 @@ PipelineHands create_graphics_pipeline_0(
|
||||
{
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.offset = 0, .size = sizeof(mat4)
|
||||
}};
|
||||
},
|
||||
{
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.offset = sizeof(mat4), .size = sizeof(vec3)
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
VkPipelineLayoutCreateInfo layout_crinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
@ -498,8 +537,8 @@ VkFramebuffer create_IT1_framebuffer(VkDevice device, VkImageView IT1_view, VkIm
|
||||
void reset_and_record_command_buffer_0(
|
||||
VkCommandBuffer command_buffer, VkRenderPass render_pass_0,
|
||||
const PipelineHands* pipeline_and_layout,
|
||||
VkFramebuffer swapchain_image_framebuffer, VkExtent2D image_extent,
|
||||
const Scene* scene, VkDescriptorSet my_descriptor_set, mat4 t_mat
|
||||
VkFramebuffer swapchain_image_framebuffer, VkImage IT1_image, VkExtent2D image_extent,
|
||||
const Scene* scene, VkDescriptorSet my_descriptor_set, mat4 proj_cam_t, vec3 camera_pos
|
||||
) {
|
||||
if (vkResetCommandBuffer(command_buffer, 0) != VK_SUCCESS)
|
||||
abortf("vkResetCommandBuffer");
|
||||
@ -537,23 +576,50 @@ void reset_and_record_command_buffer_0(
|
||||
.extent = image_extent,
|
||||
};
|
||||
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
||||
vkCmdPushConstants(command_buffer, pipeline_and_layout->pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0, sizeof(mat4), &proj_cam_t);
|
||||
vkCmdPushConstants(command_buffer, pipeline_and_layout->pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
sizeof(mat4), sizeof(vec3), &camera_pos);
|
||||
for (size_t i = 0; i < scene->models.len; i++) {
|
||||
const UsedModelOnScene* model = VecUsedModelOnScene_cat(&scene->models, i);
|
||||
VkBuffer attached_buffers[1] = { model->model.vbo };
|
||||
VkBuffer attached_buffers[2] = { model->model.vbo, model->instance_attr_buf };
|
||||
// We use our whole buffer, no need for offset
|
||||
VkDeviceSize offsets_in_buffers[1] = {0};
|
||||
vkCmdBindVertexBuffers(command_buffer, 0, 1, attached_buffers, offsets_in_buffers);
|
||||
VkDeviceSize offsets_in_buffers[2] = {0, model->instance_attr_buf_offset};
|
||||
assert(ARRAY_SIZE(attached_buffers) == 2 && ARRAY_SIZE(offsets_in_buffers) == 2);
|
||||
vkCmdBindVertexBuffers(command_buffer, 0, 2, attached_buffers, offsets_in_buffers);
|
||||
vkCmdBindIndexBuffer(command_buffer, model->model.ebo, 0, VK_INDEX_TYPE_UINT32);
|
||||
mat4 tt = mat4_mul_mat4(t_mat, model->model_t);
|
||||
vkCmdPushConstants(command_buffer, pipeline_and_layout->pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0, sizeof(mat4), &tt);
|
||||
vkCmdBindDescriptorSets(
|
||||
command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout->pipeline_layout, 0,
|
||||
1, &my_descriptor_set, 0, NULL);
|
||||
vkCmdDrawIndexed(command_buffer, model->model.indexes, 1, 0, 0, 0);
|
||||
vkCmdDrawIndexed(command_buffer, model->model.indexes, model->instances.len, 0, 0, 0);
|
||||
}
|
||||
|
||||
vkCmdEndRenderPass(command_buffer);
|
||||
|
||||
// VkImageMemoryBarrier barrier = {
|
||||
// .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
// .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
// .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
|
||||
// .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
// .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
// .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
// .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
// .image = IT1_image,
|
||||
// .subresourceRange = (VkImageSubresourceRange){
|
||||
// .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
// .baseMipLevel = 0,
|
||||
// .levelCount = 1,
|
||||
// .baseArrayLayer = 0,
|
||||
// .layerCount = 1,
|
||||
// },
|
||||
// };
|
||||
// vkCmdPipelineBarrier(command_buffer,
|
||||
// VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
// VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
// 0,
|
||||
// 0, NULL,
|
||||
// 0, NULL,
|
||||
// 1, &barrier);
|
||||
if (vkEndCommandBuffer(command_buffer) != VK_SUCCESS)
|
||||
abortf("vkEndCommandBuffer");
|
||||
}
|
||||
@ -621,6 +687,74 @@ void reset_and_record_command_buffer_1(
|
||||
abortf("vkEndCommandBuffer");
|
||||
}
|
||||
|
||||
/* First, we copy our scene information to void* host_mem_buffer_mem.
|
||||
* Then, we record a command buffer that would copy these specific regions to corresponding device buffers
|
||||
* It's up to you to submit command_buffer
|
||||
* */
|
||||
void copy_scene_info_to_buffer_and_rerecord_full_copy_command_buffer(
|
||||
VkCommandBuffer command_buffer, VkBuffer host_memory_buffer, char* host_mem_buffer_mem, const Scene* scene,
|
||||
VkBuffer device_lighting_ubo, VkBuffer device_instance_attrs_for_all_generic_meshes
|
||||
) {
|
||||
|
||||
if (vkResetCommandBuffer(command_buffer, 0) != VK_SUCCESS)
|
||||
abortf("vkResetCommandBuffer");
|
||||
VkCommandBufferBeginInfo info_begin = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
|
||||
if (vkBeginCommandBuffer(command_buffer, &info_begin) != VK_SUCCESS)
|
||||
abortf("vkBeginCommandBuffer");
|
||||
|
||||
size_t offset_here = 0;
|
||||
{
|
||||
size_t offset_in_mesh_instance_buf = 0;
|
||||
VecVkBufferCopy regions_to_copy_A = VecVkBufferCopy_new();
|
||||
for (size_t mi = 0; mi < scene->models.len; mi++) {
|
||||
const UsedModelOnScene* model = VecUsedModelOnScene_cat(&scene->models, mi);
|
||||
assert(model->instances.len <= model->limit_max_instance_count);
|
||||
size_t all = model->instances.len * sizeof(GenericMeshInstance);
|
||||
memcpy(host_mem_buffer_mem + offset_here, model->instances.buf, all);
|
||||
/* Right now we don't combine multiple vkCmdCopyBuffer commands with same src and dst buffers into one, but later we should do it */
|
||||
VecVkBufferCopy_append(®ions_to_copy_A, (VkBufferCopy){.srcOffset = offset_here, .dstOffset = offset_in_mesh_instance_buf, .size = all});
|
||||
offset_here += all;
|
||||
offset_in_mesh_instance_buf += model->limit_max_instance_count * sizeof(GenericMeshInstance);
|
||||
}
|
||||
vkCmdCopyBuffer(command_buffer, host_memory_buffer, device_instance_attrs_for_all_generic_meshes, regions_to_copy_A.len, regions_to_copy_A.buf);
|
||||
VecVkBufferCopy_drop(regions_to_copy_A);
|
||||
}
|
||||
{
|
||||
assert(scene->point_lights.len <= pipeline_0_ubo_point_light_max_count);
|
||||
assert(scene->spotlights.len <= pipeline_0_ubo_spotlight_max_count);
|
||||
int point_lights = (int)scene->point_lights.len;
|
||||
int spotlights = (int)scene->spotlights.len;
|
||||
memcpy(host_mem_buffer_mem + offset_here, &point_lights, sizeof(int));
|
||||
memcpy(host_mem_buffer_mem + offset_here + sizeof(int), &spotlights, sizeof(int));
|
||||
memcpy(host_mem_buffer_mem + offset_here + sizeof(int) * 2, scene->point_lights.buf, sizeof(Pipeline0PointLight) * point_lights);
|
||||
memcpy(host_mem_buffer_mem + offset_here + sizeof(int) * 2 + sizeof(Pipeline0PointLight) * point_lights,
|
||||
scene->spotlights.buf, sizeof(Pipeline0Spotlight) * spotlights);
|
||||
VkBufferCopy regions_to_copy_B[] = {
|
||||
{
|
||||
.srcOffset = offset_here, .dstOffset = offsetof(Pipeline0UBO, point_light_count),
|
||||
.size = sizeof(int),
|
||||
},
|
||||
{
|
||||
.srcOffset = offset_here + sizeof(int), .dstOffset = offsetof(Pipeline0UBO, spotlight_count),
|
||||
.size = sizeof(int),
|
||||
},
|
||||
{
|
||||
.srcOffset = offset_here + 2 * sizeof(int), .dstOffset = offsetof(Pipeline0UBO, point_light_arr),
|
||||
.size = sizeof(Pipeline0PointLight) * point_lights,
|
||||
},
|
||||
{
|
||||
.srcOffset = offset_here + 2 * sizeof(int) + sizeof(Pipeline0PointLight) * point_lights,
|
||||
.dstOffset = offsetof(Pipeline0UBO, spotlight_arr),
|
||||
.size = sizeof(Pipeline0Spotlight) * spotlights,
|
||||
},
|
||||
};
|
||||
vkCmdCopyBuffer(command_buffer, host_memory_buffer, device_lighting_ubo, ARRAY_SIZE(regions_to_copy_B), regions_to_copy_B);
|
||||
}
|
||||
|
||||
if (vkEndCommandBuffer(command_buffer) != VK_SUCCESS)
|
||||
abortf("vkEndCommandBuffer");
|
||||
}
|
||||
|
||||
|
||||
// todo: add here deletion and recreation of several synchronization primitives
|
||||
void recreate_swapchain(
|
||||
@ -660,11 +794,11 @@ typedef struct {
|
||||
int main() {
|
||||
prepare_shaders();
|
||||
|
||||
ConstSpanU8 GPU = cstr("amd");
|
||||
ConstSpanU8 bugged_GPU = cstr("nvidia");
|
||||
ConstSpanU8 GPU = cstr("nvidia");
|
||||
ConstSpanU8 bugged_GPU = cstr("nothere");
|
||||
bool ENABLE_VALIDATION_LAYERS = true;
|
||||
U32 MAX_WIN_WIDTH = 1920;
|
||||
U32 MAX_WIN_HEIGHT = 1080;
|
||||
const U32 MAX_WIN_WIDTH = 1920;
|
||||
const U32 MAX_WIN_HEIGHT = 1080;
|
||||
|
||||
MargaretSingleWindowSetup x = MargaretSingleWindowSetup_new();
|
||||
Margaret_WEP wep = Margaret_WEP_new(x.dpy, x.win);
|
||||
@ -716,9 +850,14 @@ int main() {
|
||||
|
||||
MargaretSwapchainBundle swfb = MargaretSwapchainBundle_new(device, queue_fam, swapchain_details, surface, render_pass_1, NULL);
|
||||
|
||||
// Filling scene info
|
||||
ModelTopology cylinder_1 = generate_one_fourth_of_a_cylinder(10, 2, 6);
|
||||
ModelTopology cylinder_2 = generate_one_fourth_of_a_cylinder(5, 5, 10);
|
||||
SceneTemplate scene_template = {.models = VecModelInSceneTemplate_new(),
|
||||
.point_lights_max_count = pipeline_0_ubo_point_light_max_count,
|
||||
.spotlights_max_count = pipeline_0_ubo_spotlight_max_count};
|
||||
VecModelInSceneTemplate_append(&scene_template.models,
|
||||
(ModelInSceneTemplate){.topology = generate_one_fourth_of_a_cylinder(10, 2, 6), .max_instance_count = 100});
|
||||
VecModelInSceneTemplate_append(&scene_template.models,
|
||||
(ModelInSceneTemplate){.topology = generate_one_fourth_of_a_cylinder(5, 5, 10), .max_instance_count = 1});
|
||||
|
||||
// TextureDataR8G8B8A8 wood_texture_data = generate_texture_for_one_fourth_of_a_cylinder(20, 10, 2, 6);
|
||||
// todo: learn how to use libpng
|
||||
TextureDataR8G8B8A8 cyl_1_diffuse_tex = TextureDataR8G8B8A8_read_from_file("test_textures/log_10_2_6.r8g8b8a8");
|
||||
@ -726,95 +865,130 @@ int main() {
|
||||
// todo: and at the same time I need to add methods to convert between these formats
|
||||
TextureDataR8G8B8A8 cyl_1_normal_tex = TextureDataR8G8B8A8_read_from_file("test_textures/log_10_2_6_NORMAL.r8g8b8a8");
|
||||
|
||||
|
||||
// todo: kill myself
|
||||
// We have only one staging buffer in host memory (because we don't really need more)
|
||||
MargaretBufferInMemoryInfo host_mem_buffer = (MargaretBufferInMemoryInfo){ .sz =
|
||||
MAX_U64(ModelTopology_get_space_needed_for_staging_buffer(&cylinder_1),
|
||||
MAX_U64(ModelTopology_get_space_needed_for_staging_buffer(&cylinder_2),
|
||||
MAX_U64(sizeof(Pipeline0UBO),
|
||||
MAX_U64(SceneTemplate_get_space_for_initial_model_topology_transfer(&scene_template),
|
||||
MAX_U64(SceneTemplate_get_space_needed_for_widest_state_transfer(&scene_template),
|
||||
MAX_U64(TextureDataR8G8B8A8_get_size_in_bytes(&cyl_1_diffuse_tex),
|
||||
MAX_U64(TextureDataR8G8B8A8_get_size_in_bytes(&cyl_1_normal_tex), 0)))))
|
||||
MAX_U64(TextureDataR8G8B8A8_get_size_in_bytes(&cyl_1_normal_tex), 0))))
|
||||
, .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT };
|
||||
MargaretBufferInMemoryInfo_Ptr host_mem_buffer_SPAN[1] = {&host_mem_buffer};
|
||||
VkDeviceMemory host_mem = margaret_initialize_buffers_and_images(physical_device, device,
|
||||
(SpanMargaretBufferInMemoryInfo){.data = &host_mem_buffer, .len = 1}, (SpanMargaretImageInMemoryInfo){ 0 },
|
||||
(SpanMargaretBufferInMemoryInfo_Ptr){.data = host_mem_buffer_SPAN, .len = 1},
|
||||
(SpanMargaretImageInMemoryInfo_Ptr){ 0 },
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
|
||||
MargaretBufferInMemoryInfo device_mem_buffers[] = {
|
||||
Vertex_buffer_crinfo_of_gpu_vbo(cylinder_1.vertices.len),
|
||||
margaret_prep_buffer_mem_info_of_gpu_ebo(cylinder_1.indexes.len),
|
||||
Vertex_buffer_crinfo_of_gpu_vbo(cylinder_2.vertices.len),
|
||||
margaret_prep_buffer_mem_info_of_gpu_ebo(cylinder_2.indexes.len),
|
||||
margaret_prep_buffer_mem_info_of_gpu_ubo(sizeof(Pipeline0UBO)),
|
||||
// todo: split this in two (or maybe even better: merge it all into one/two buffer and use offsets
|
||||
VecMargaretBufferInMemoryInfo device_ebo_and_vbo_buffers_for_generic_meshes = VecMargaretBufferInMemoryInfo_new();
|
||||
for (size_t mi = 0; mi < scene_template.models.len; mi++) {
|
||||
const ModelInSceneTemplate* M = VecModelInSceneTemplate_cat(&scene_template.models, mi);
|
||||
VecMargaretBufferInMemoryInfo_append(&device_ebo_and_vbo_buffers_for_generic_meshes,
|
||||
GenericMeshVertex_buffer_crinfo_of_gpu_vbo(M->topology.vertices.len));
|
||||
VecMargaretBufferInMemoryInfo_append(&device_ebo_and_vbo_buffers_for_generic_meshes,
|
||||
margaret_prep_buffer_mem_info_of_gpu_ebo(M->topology.indexes.len));
|
||||
}
|
||||
MargaretBufferInMemoryInfo device_lighting_ubo = margaret_prep_buffer_mem_info_of_gpu_ubo(sizeof(Pipeline0UBO));
|
||||
MargaretBufferInMemoryInfo device_instance_attrs_for_all_generic_meshes = (MargaretBufferInMemoryInfo){
|
||||
.sz = SceneTemplate_get_space_needed_for_all_instance_attributes(&scene_template),
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
|
||||
};
|
||||
MargaretImageInMemoryInfo device_mem_images[] = {
|
||||
margaret_prep_image_mem_info_of_colorbuffer(MAX_WIN_WIDTH, MAX_WIN_HEIGHT, IT1_format.some),
|
||||
margaret_prep_image_mem_info_of_zbuffer(MAX_WIN_WIDTH, MAX_WIN_HEIGHT, zbuffer_format.some),
|
||||
margaret_prep_image_mem_info_of_gpu_texture_srgba(cyl_1_diffuse_tex.width,
|
||||
TextureDataR8G8B8A8_get_height(&cyl_1_diffuse_tex)),
|
||||
margaret_prep_image_mem_info_of_gpu_texture_srgba(cyl_1_normal_tex.width,
|
||||
TextureDataR8G8B8A8_get_height(&cyl_1_normal_tex)),
|
||||
|
||||
VecMargaretBufferInMemoryInfo_Ptr device_mem_buffers_SPAN = VecMargaretBufferInMemoryInfo_Ptr_new();
|
||||
for (size_t i = 0; i < device_ebo_and_vbo_buffers_for_generic_meshes.len; i++) {
|
||||
VecMargaretBufferInMemoryInfo_Ptr_append(&device_mem_buffers_SPAN,
|
||||
VecMargaretBufferInMemoryInfo_at(&device_ebo_and_vbo_buffers_for_generic_meshes, i));
|
||||
}
|
||||
VecMargaretBufferInMemoryInfo_Ptr_append(&device_mem_buffers_SPAN, &device_lighting_ubo);
|
||||
VecMargaretBufferInMemoryInfo_Ptr_append(&device_mem_buffers_SPAN, &device_instance_attrs_for_all_generic_meshes);
|
||||
printf("Buffers: %lu\n", device_mem_buffers_SPAN.len);
|
||||
|
||||
MargaretImageInMemoryInfo device_IT1_image = margaret_prep_image_mem_info_of_colorbuffer(MAX_WIN_WIDTH, MAX_WIN_HEIGHT, IT1_format.some);
|
||||
MargaretImageInMemoryInfo device_zbuffer_image = margaret_prep_image_mem_info_of_zbuffer(MAX_WIN_WIDTH, MAX_WIN_HEIGHT, zbuffer_format.some);
|
||||
MargaretImageInMemoryInfo device_cyl_1_diffuse_texture = margaret_prep_image_mem_info_of_gpu_texture_srgba(cyl_1_diffuse_tex.width,
|
||||
TextureDataR8G8B8A8_get_height(&cyl_1_diffuse_tex));
|
||||
MargaretImageInMemoryInfo device_cyl_1_normal_texture = margaret_prep_image_mem_info_of_gpu_texture_srgba(cyl_1_normal_tex.width,
|
||||
TextureDataR8G8B8A8_get_height(&cyl_1_normal_tex));
|
||||
|
||||
MargaretImageInMemoryInfo_Ptr device_mem_images_SPAN[] = {
|
||||
&device_IT1_image, &device_zbuffer_image, &device_cyl_1_diffuse_texture, &device_cyl_1_normal_texture
|
||||
};
|
||||
// todo: replace this ugly garbage with pointer spans. Seriously, this is fucking digusting
|
||||
VkDeviceMemory device_mem = margaret_initialize_buffers_and_images(physical_device, device,
|
||||
(SpanMargaretBufferInMemoryInfo){ .data = device_mem_buffers, .len = ARRAY_SIZE(device_mem_buffers)},
|
||||
(SpanMargaretImageInMemoryInfo){ .data = device_mem_images, .len = ARRAY_SIZE(device_mem_images) },
|
||||
VecMargaretBufferInMemoryInfo_Ptr_to_SpanMargaretBufferInMemoryInfo_Ptr(&device_mem_buffers_SPAN),
|
||||
(SpanMargaretImageInMemoryInfo_Ptr){ .data = device_mem_images_SPAN, .len = ARRAY_SIZE(device_mem_images_SPAN) },
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
MargaretBufferInMemoryInfo device_vbo_1_buffer = device_mem_buffers[0];
|
||||
MargaretBufferInMemoryInfo device_ebo_1_buffer = device_mem_buffers[1];
|
||||
MargaretBufferInMemoryInfo device_vbo_2_buffer = device_mem_buffers[2];
|
||||
MargaretBufferInMemoryInfo device_ebo_2_buffer = device_mem_buffers[3];
|
||||
MargaretBufferInMemoryInfo device_ubo_my_buffer = device_mem_buffers[4];
|
||||
MargaretImageInMemoryInfo device_IT1_image = device_mem_images[0];
|
||||
MargaretImageInMemoryInfo device_zbuffer_image = device_mem_images[1];
|
||||
MargaretImageInMemoryInfo device_cyl_1_diffuse_texture = device_mem_images[2];
|
||||
MargaretImageInMemoryInfo device_cyl_1_normal_texture = device_mem_images[3];
|
||||
|
||||
VkCommandPool command_pool = margaret_create_resettable_command_pool(device, queue_fam.for_graphics);
|
||||
VkCommandBuffer rendering_command_buffer_0 = margaret_allocate_command_buffer(device, command_pool);
|
||||
VkCommandBuffer rendering_command_buffer_1 = margaret_allocate_command_buffer(device, command_pool);
|
||||
VkCommandBuffer transfer_command_buffer = margaret_allocate_command_buffer(device, command_pool);
|
||||
|
||||
VkCommandBuffer uniform_transfer_command_buffer = margaret_allocate_command_buffer(device, command_pool);
|
||||
margaret_record_buf_copying_command_buf(device, uniform_transfer_command_buffer,
|
||||
device_ubo_my_buffer.buffer, host_mem_buffer.buffer, sizeof(Pipeline0UBO));
|
||||
Scene scene = Scene_new();
|
||||
{
|
||||
size_t offset_in_attr_buffer = 0;
|
||||
for (size_t mi = 0; mi < scene_template.models.len; mi++) {
|
||||
// UsedModelOnScene* ptb = VecUsedModelOnScene_cat()
|
||||
const ModelInSceneTemplate* M = VecModelInSceneTemplate_cat(&scene_template.models, mi);
|
||||
VecUsedModelOnScene_append(&scene.models, (UsedModelOnScene){
|
||||
.model = (ModelOnScene){
|
||||
.vbo = VecMargaretBufferInMemoryInfo_cat(&device_ebo_and_vbo_buffers_for_generic_meshes,
|
||||
2 * mi + 0)->buffer,
|
||||
.ebo = VecMargaretBufferInMemoryInfo_cat(&device_ebo_and_vbo_buffers_for_generic_meshes,
|
||||
2 * mi + 1)->buffer,
|
||||
.indexes = M->topology.indexes.len,
|
||||
},
|
||||
.instances = VecGenericMeshInstance_new(),
|
||||
.instance_attr_buf = device_instance_attrs_for_all_generic_meshes.buffer,
|
||||
.instance_attr_buf_offset = offset_in_attr_buffer,
|
||||
.limit_max_instance_count = M->max_instance_count
|
||||
});
|
||||
offset_in_attr_buffer += M->max_instance_count * sizeof(GenericMeshInstance);
|
||||
}
|
||||
}
|
||||
|
||||
for (int X = 0; X < 10; X++) {
|
||||
for (int Z = 0; Z < 10; Z++) {
|
||||
VecGenericMeshInstance_append(&VecUsedModelOnScene_at(&scene.models, 0)->instances,
|
||||
(GenericMeshInstance){ .model_trans = marie_translation_mat4((vec3){11.f * (float)X, -6, 4.f * (float)Z}) });
|
||||
}
|
||||
}
|
||||
VecGenericMeshInstance_append(&VecUsedModelOnScene_at(&scene.models, 1)->instances, (GenericMeshInstance){
|
||||
.model_trans = mat4_E
|
||||
});
|
||||
|
||||
void* host_mem_buffer_mem;
|
||||
if (vkMapMemory(device, host_mem, 0, VK_WHOLE_SIZE, 0, &host_mem_buffer_mem) != VK_SUCCESS)
|
||||
abortf("vkMapMemory");
|
||||
// Now this is what we will do for each buffer: we first memcpy it into mapped region, then we submit a copying command
|
||||
|
||||
SceneTemplate_copy_initial_model_topology_and_rerecord_transfer_cmd(&scene_template, &scene, host_mem_buffer_mem, transfer_command_buffer, host_mem_buffer.buffer);
|
||||
{
|
||||
size_t size = cylinder_1.vertices.len * sizeof(Vertex);
|
||||
memcpy(host_mem_buffer_mem, cylinder_1.vertices.buf, size);
|
||||
margaret_copy_buffer_imm(device, command_pool, graphics_queue,
|
||||
device_vbo_1_buffer.buffer, host_mem_buffer.buffer, size);
|
||||
}
|
||||
{
|
||||
size_t size = cylinder_1.indexes.len * sizeof(U32);
|
||||
memcpy(host_mem_buffer_mem, cylinder_1.indexes.buf, size);
|
||||
margaret_copy_buffer_imm(device, command_pool, graphics_queue,
|
||||
device_ebo_1_buffer.buffer, host_mem_buffer.buffer, size);
|
||||
}
|
||||
{
|
||||
size_t size = cylinder_2.vertices.len * sizeof(Vertex);
|
||||
memcpy(host_mem_buffer_mem, cylinder_2.vertices.buf, size);
|
||||
margaret_copy_buffer_imm(device, command_pool, graphics_queue,
|
||||
device_vbo_2_buffer.buffer, host_mem_buffer.buffer, size);
|
||||
}
|
||||
{
|
||||
size_t size = cylinder_2.indexes.len * sizeof(U32);
|
||||
memcpy(host_mem_buffer_mem, cylinder_2.indexes.buf, size);
|
||||
margaret_copy_buffer_imm(device, command_pool, graphics_queue,
|
||||
device_ebo_2_buffer.buffer, host_mem_buffer.buffer, size);
|
||||
VkCommandBuffer command_buffers[1] = { transfer_command_buffer };
|
||||
// VkSemaphore signaling_semaphores[1] = { swfb.in_frame_transfer_complete };
|
||||
VkSubmitInfo submit_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.commandBufferCount = ARRAY_SIZE(command_buffers),
|
||||
.pCommandBuffers = command_buffers,
|
||||
// .signalSemaphoreCount = ARRAY_SIZE(signaling_semaphores),
|
||||
// .pSignalSemaphores = signaling_semaphores,
|
||||
};
|
||||
if (vkQueueSubmit(graphics_queue, 1, &submit_info, NULL) != VK_SUCCESS)
|
||||
abortf("vkQueueSubmit\n");
|
||||
}
|
||||
vkDeviceWaitIdle(device);
|
||||
{
|
||||
memcpy(host_mem_buffer_mem, cyl_1_diffuse_tex.pixels.buf,
|
||||
TextureDataR8G8B8A8_get_size_in_bytes(&cyl_1_diffuse_tex));
|
||||
margaret_copy_buffer_to_texture_for_frag_shader_imm(device, command_pool, graphics_queue,
|
||||
&device_cyl_1_diffuse_texture, host_mem_buffer.buffer);
|
||||
}
|
||||
vkDeviceWaitIdle(device);
|
||||
{
|
||||
memcpy(host_mem_buffer_mem, cyl_1_normal_tex.pixels.buf, TextureDataR8G8B8A8_get_size_in_bytes(&cyl_1_normal_tex));
|
||||
margaret_copy_buffer_to_texture_for_frag_shader_imm(device, command_pool, graphics_queue,
|
||||
&device_cyl_1_normal_texture, host_mem_buffer.buffer);
|
||||
}
|
||||
vkDeviceWaitIdle(device);
|
||||
|
||||
// We sent everything we needed. but host_mem_buffer_mem may be used later
|
||||
|
||||
@ -830,25 +1004,21 @@ int main() {
|
||||
// My cylinder 1 normal texture also needs NkImageView
|
||||
VkImageView cyl_1_normal_texture_view = margaret_create_view_for_image(device, &device_cyl_1_normal_texture, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
Scene scene = Scene_new();
|
||||
VecUsedModelOnScene_append(&scene.models, (UsedModelOnScene){.model = {
|
||||
.vbo = device_vbo_1_buffer.buffer, .ebo = device_ebo_1_buffer.buffer, .indexes = cylinder_1.indexes.len
|
||||
}, .model_t = marie_translation_mat4((vec3){1, -1, 5}) });
|
||||
VecUsedModelOnScene_append(&scene.models, (UsedModelOnScene){.model = {
|
||||
.vbo = device_vbo_2_buffer.buffer, .ebo = device_ebo_2_buffer.buffer, .indexes = cylinder_2.indexes.len
|
||||
}, .model_t = marie_translation_mat4((vec3){6, -3, 16}) });
|
||||
// Right now I only have one light source
|
||||
VecPipeline0PointLight_append(&scene.point_lights, (Pipeline0PointLight){.pos = {0}, .color = {100, 100, 100}});
|
||||
|
||||
|
||||
// These samplers are global for a lot of my future textures
|
||||
VkSampler linear_sampler = margaret_create_sampler(physical_device, device, true);
|
||||
VkSampler nearest_sampler = margaret_create_sampler(physical_device, device, false);
|
||||
VkDescriptorPool descriptor_pool = margaret_create_descriptor_set_pool(device, 1, 3, 2);
|
||||
|
||||
VkDescriptorPool descriptor_pool = margaret_create_descriptor_set_pool(device, 1, 3, 2);
|
||||
VkDescriptorSet descriptor_set_for_pipeline_0 = margaret_allocate_descriptor_set(device, descriptor_pool, pipeline_hands_0.descriptor_set_layout);
|
||||
VkDescriptorSet descriptor_set_for_pipeline_1 = margaret_allocate_descriptor_set(device, descriptor_pool, pipeline_hands_1.descriptor_set_layout);
|
||||
|
||||
// Configuring my descriptor sets, that I just allocated
|
||||
VkDescriptorBufferInfo buffer_info_for_descriptor_0_in_set_0 = {
|
||||
.buffer = device_ubo_my_buffer.buffer,
|
||||
.buffer = device_lighting_ubo.buffer,
|
||||
.offset = 0,
|
||||
.range = sizeof(Pipeline0UBO),
|
||||
};
|
||||
@ -909,6 +1079,7 @@ int main() {
|
||||
vkUpdateDescriptorSets(device, ARRAY_SIZE(writes_in_descriptor_sets), writes_in_descriptor_sets, 0, NULL);
|
||||
|
||||
CamControlInfo my_cam_control_info = CamControlInfo_new();
|
||||
vec3 Buba_control_info = {0};
|
||||
|
||||
// Mainloop
|
||||
margaret_ns_time start = margaret_clock_gettime_monotonic_raw();
|
||||
@ -916,6 +1087,9 @@ int main() {
|
||||
int frame_count_since_key = 0;
|
||||
margaret_ns_time prev_frame_timestamp = start;
|
||||
|
||||
/* Will happen mid-frame */
|
||||
bool dt_transfer_required = true;
|
||||
|
||||
bool pressed_first_0x80[0x80] = {0};
|
||||
while (true) {
|
||||
margaret_ns_time frame_A0 = margaret_clock_gettime_monotonic_raw();
|
||||
@ -942,6 +1116,18 @@ int main() {
|
||||
KeySym keysym = XLookupKeysym(&ev->xkey, 0);
|
||||
if (keysym < 0x80)
|
||||
pressed_first_0x80[keysym] = false;
|
||||
if (keysym == XK_1) {
|
||||
vec3 p = my_cam_control_info.pos;
|
||||
VecPipeline0PointLight_at(&scene.point_lights, 0)->pos = p;
|
||||
printf("Point light source pos set to %f %f %f\n", p.x, p.y, p.z);
|
||||
dt_transfer_required = true;
|
||||
} else if (keysym == XK_2) {
|
||||
scene.hdr_factor /= 1.05f;
|
||||
printf("hdr factor decreased to %f\n", scene.hdr_factor);
|
||||
} else if (keysym == XK_3) {
|
||||
scene.hdr_factor *= 1.05f;
|
||||
printf("hdr factor increased to %f\n", scene.hdr_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pressed_first_0x80[XK_w])
|
||||
@ -957,6 +1143,33 @@ int main() {
|
||||
if (pressed_first_0x80[XK_e])
|
||||
CamControlInfo_up(&my_cam_control_info, fl);
|
||||
|
||||
if (pressed_first_0x80[XK_j]) {\
|
||||
Buba_control_info.x -= fl;
|
||||
VecGenericMeshInstance_at(&VecUsedModelOnScene_at(&scene.models, 1)->instances, 0)->model_trans =
|
||||
marie_translation_mat4(Buba_control_info);
|
||||
dt_transfer_required = true;
|
||||
}
|
||||
if (pressed_first_0x80[XK_k]) {\
|
||||
Buba_control_info.z -= fl;
|
||||
VecGenericMeshInstance_at(&VecUsedModelOnScene_at(&scene.models, 1)->instances, 0)->model_trans =
|
||||
marie_translation_mat4(Buba_control_info);
|
||||
dt_transfer_required = true;
|
||||
}
|
||||
if (pressed_first_0x80[XK_l]) {\
|
||||
Buba_control_info.z += fl;
|
||||
VecGenericMeshInstance_at(&VecUsedModelOnScene_at(&scene.models, 1)->instances, 0)->model_trans =
|
||||
marie_translation_mat4(Buba_control_info);
|
||||
dt_transfer_required = true;
|
||||
}
|
||||
if (pressed_first_0x80[XK_semicolon]) {\
|
||||
Buba_control_info.x += fl;
|
||||
VecGenericMeshInstance_at(&VecUsedModelOnScene_at(&scene.models, 1)->instances, 0)->model_trans =
|
||||
marie_translation_mat4(Buba_control_info);
|
||||
dt_transfer_required = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Rendering
|
||||
vkWaitForFences(device, 1, &swfb.in_flight_fence, VK_TRUE, UINT64_MAX);
|
||||
uint32_t ij;
|
||||
@ -980,62 +1193,63 @@ int main() {
|
||||
|
||||
float ae = margaret_ns_time_sec_diff(start, frame_A0);
|
||||
scene.anim_time = ae;
|
||||
scene.color = (VkClearColorValue){{0.5f, fabsf(sinf(ae)), .3f, 1.0f}};
|
||||
scene.color = (VkClearColorValue){{0, 0, 0, 1}};
|
||||
mat4 projection_matrix = marie_perspective_projection_fov_mat4((float)wep.width, (float)wep.height,
|
||||
my_cam_control_info.fov, 0.01f, 1000);
|
||||
mat4 camera_rotation_matrix = marie_mat3_to_mat4_transposed(my_cam_control_info.cam_basis);
|
||||
mat4 camera_translation_matrix = marie_translation_mat4(vec3_minus(my_cam_control_info.pos));
|
||||
mat4 t_mat = mat4_mul_mat4(projection_matrix, mat4_mul_mat4(camera_rotation_matrix, camera_translation_matrix));
|
||||
|
||||
{
|
||||
if (dt_transfer_required){
|
||||
assert(scene.spotlights.len < pipeline_0_ubo_spotlight_max_count);
|
||||
assert(scene.point_lights.len < pipeline_0_ubo_point_light_max_count);
|
||||
Pipeline0UBO* subo = (Pipeline0UBO*)host_mem_buffer_mem;
|
||||
// todo: speed it up a little
|
||||
subo->spotlight_count = (int)scene.spotlights.len;
|
||||
memcpy(&subo->spotlight_arr, scene.spotlights.buf, scene.spotlights.len * sizeof(Pipeline0Spotlight));
|
||||
subo->point_light_count = (int)scene.point_lights.len;
|
||||
memcpy(&subo->point_light_arr, scene.point_lights.buf, scene.point_lights.len * sizeof(Pipeline0PointLight));
|
||||
VkCommandBuffer command_buffers[1] = { uniform_transfer_command_buffer };
|
||||
copy_scene_info_to_buffer_and_rerecord_full_copy_command_buffer(
|
||||
transfer_command_buffer, host_mem_buffer.buffer, host_mem_buffer_mem, &scene, device_lighting_ubo.buffer,
|
||||
device_instance_attrs_for_all_generic_meshes.buffer);
|
||||
VkCommandBuffer command_buffers[1] = { transfer_command_buffer };
|
||||
VkSemaphore signaling_semaphores[1] = { swfb.in_frame_transfer_complete };
|
||||
VkSubmitInfo ubo_copying_cmd_buffer_submit = {
|
||||
VkSubmitInfo submit_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.commandBufferCount = ARRAY_SIZE(command_buffers),
|
||||
.pCommandBuffers = command_buffers,
|
||||
.signalSemaphoreCount = ARRAY_SIZE(signaling_semaphores),
|
||||
.pSignalSemaphores = signaling_semaphores,
|
||||
};
|
||||
vkQueueSubmit(graphics_queue, 1, &ubo_copying_cmd_buffer_submit, NULL);
|
||||
if (vkQueueSubmit(graphics_queue, 1, &submit_info, NULL) != VK_SUCCESS)
|
||||
abortf("vkQueueSubmit\n");
|
||||
}
|
||||
|
||||
reset_and_record_command_buffer_0(rendering_command_buffer_0, render_pass_0, &pipeline_hands_0,
|
||||
IT1_framebuffer, swfb.extent, &scene, descriptor_set_for_pipeline_0, t_mat);
|
||||
reset_and_record_command_buffer_0(
|
||||
rendering_command_buffer_0, render_pass_0, &pipeline_hands_0,
|
||||
IT1_framebuffer, device_IT1_image.image, swfb.extent, &scene,
|
||||
descriptor_set_for_pipeline_0, t_mat, my_cam_control_info.pos);
|
||||
|
||||
reset_and_record_command_buffer_1(rendering_command_buffer_1, render_pass_1, &pipeline_hands_1,
|
||||
*VecVkFramebuffer_cat(&swfb.framebuffers, ij),
|
||||
swfb.extent, (VkExtent2D){.width = MAX_WIN_WIDTH, .height = MAX_WIN_HEIGHT}, &scene, descriptor_set_for_pipeline_1);
|
||||
|
||||
{
|
||||
VkSemaphore waiting_for_semaphores[2] = {
|
||||
swfb.image_available_semaphore, swfb.in_frame_transfer_complete
|
||||
VkSemaphore waiting_for_semaphores_if_dt_transfer_required[1] = {
|
||||
swfb.in_frame_transfer_complete
|
||||
};
|
||||
VkPipelineStageFlags waiting_stages[2] = {
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
||||
VkPipelineStageFlags waiting_stages_if_dt_transfer_required[1] = {
|
||||
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
|
||||
};
|
||||
assert(ARRAY_SIZE(waiting_for_semaphores) == ARRAY_SIZE(waiting_stages));
|
||||
// VkCommandBuffer command_buffers[1] = {*VecVkCommandBuffer_cat(&rendering_command_buffers, ij)};
|
||||
assert(ARRAY_SIZE(waiting_for_semaphores_if_dt_transfer_required) ==
|
||||
ARRAY_SIZE(waiting_stages_if_dt_transfer_required));
|
||||
VkCommandBuffer command_buffers[1] = {rendering_command_buffer_0};
|
||||
VkSemaphore signaling_semaphores[1] = { swfb.rendered_to_IT1_semaphore };
|
||||
|
||||
VkSubmitInfo cmd_submit_info = {
|
||||
VkSubmitInfo submit_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
|
||||
// We wait for `waiting_for_semaphores` before THESE stages
|
||||
// waitSemaphoreCount specifies size for both pWaitSemaphores and pWaitDstStageMask
|
||||
.waitSemaphoreCount = ARRAY_SIZE(waiting_for_semaphores),
|
||||
.pWaitSemaphores = waiting_for_semaphores,
|
||||
.pWaitDstStageMask = waiting_stages,
|
||||
.waitSemaphoreCount = dt_transfer_required ?
|
||||
ARRAY_SIZE(waiting_for_semaphores_if_dt_transfer_required) : 0,
|
||||
.pWaitSemaphores = dt_transfer_required ?
|
||||
waiting_for_semaphores_if_dt_transfer_required : NULL,
|
||||
.pWaitDstStageMask = dt_transfer_required ?
|
||||
waiting_stages_if_dt_transfer_required : NULL,
|
||||
|
||||
.commandBufferCount = ARRAY_SIZE(command_buffers),
|
||||
.pCommandBuffers = command_buffers,
|
||||
@ -1043,13 +1257,18 @@ int main() {
|
||||
.signalSemaphoreCount = ARRAY_SIZE(signaling_semaphores),
|
||||
.pSignalSemaphores = signaling_semaphores,
|
||||
};
|
||||
if (vkQueueSubmit(graphics_queue, 1, &cmd_submit_info, NULL) != VK_SUCCESS)
|
||||
if (vkQueueSubmit(graphics_queue, 1, &submit_info, NULL) != VK_SUCCESS)
|
||||
abortf("vkQueueSubmit");
|
||||
}
|
||||
|
||||
{
|
||||
VkSemaphore waiting_for_semaphores[1] = { swfb.rendered_to_IT1_semaphore };
|
||||
VkPipelineStageFlags waiting_stages[1] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||
VkSemaphore waiting_for_semaphores[2] = {
|
||||
swfb.image_available_semaphore,
|
||||
swfb.rendered_to_IT1_semaphore };
|
||||
VkPipelineStageFlags waiting_stages[2] = {
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
// VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
|
||||
};
|
||||
assert(ARRAY_SIZE(waiting_for_semaphores) == ARRAY_SIZE(waiting_stages));
|
||||
VkCommandBuffer command_buffers[1] = { rendering_command_buffer_1 };
|
||||
VkSemaphore signaling_semaphores[1] = { swfb.render_finished_semaphore };
|
||||
@ -1102,6 +1321,7 @@ int main() {
|
||||
abortf("vkQueuePresentKHR");
|
||||
}
|
||||
}
|
||||
dt_transfer_required = false;
|
||||
margaret_ns_time frame_B0 = margaret_clock_gettime_monotonic_raw();
|
||||
if (margaret_ns_time_sec_diff(frame_A0, frame_B0) > 0.3) {
|
||||
fprintf(stderr, "]]] Profiling frame scheduling:\n"
|
||||
@ -1118,11 +1338,11 @@ int main() {
|
||||
}
|
||||
}
|
||||
vkDeviceWaitIdle(device);
|
||||
|
||||
// The End
|
||||
// dropping scene
|
||||
Scene_drop(scene);
|
||||
ModelTopology_drop(cylinder_1);
|
||||
ModelTopology_drop(cylinder_2);
|
||||
// todo: destroy objects that hold scene and model topology
|
||||
// destroying vulkan objects
|
||||
vkDestroyDescriptorPool(device, descriptor_pool, NULL);
|
||||
vkDestroySampler(device, linear_sampler, NULL);
|
||||
@ -1130,11 +1350,8 @@ int main() {
|
||||
vkDestroyImageView(device, cyl_1_diffuse_texture_view, NULL);
|
||||
vkDestroyImageView(device, cyl_1_normal_texture_view, NULL);
|
||||
|
||||
vkDestroyBuffer(device, device_vbo_1_buffer.buffer, NULL);
|
||||
vkDestroyBuffer(device, device_ebo_1_buffer.buffer, NULL);
|
||||
vkDestroyBuffer(device, device_vbo_2_buffer.buffer, NULL);
|
||||
vkDestroyBuffer(device, device_ebo_2_buffer.buffer, NULL);
|
||||
vkDestroyBuffer(device, device_ubo_my_buffer.buffer, NULL);
|
||||
// todo: destroy buffers for model topology
|
||||
vkDestroyBuffer(device, device_lighting_ubo.buffer, NULL);
|
||||
vkDestroyImage(device, device_cyl_1_diffuse_texture.image, NULL);
|
||||
vkDestroyImage(device, device_cyl_1_normal_texture.image, NULL);
|
||||
vkDestroyImage(device, device_IT1_image.image, NULL);
|
||||
|
||||
@ -12,28 +12,49 @@
|
||||
typedef struct {
|
||||
vec3 pos;
|
||||
vec2 tex;
|
||||
} Vertex;
|
||||
} GenericMeshVertex;
|
||||
|
||||
#define Vertex_drop(vp) {}
|
||||
#define Vertex_clone(vp) (*(vp))
|
||||
#define GenericMeshVertex_drop(vp) {}
|
||||
#define GenericMeshVertex_clone(vp) (*(vp))
|
||||
|
||||
VecT_trivmove_struct_Definition(Vertex)
|
||||
VecT_trivmove_method_Definition(Vertex)
|
||||
VecT_primitive_zeroinit_method_Definition(Vertex)
|
||||
SpanT_struct_Definition(Vertex)
|
||||
SpanT_method_Definition(Vertex)
|
||||
SpanT_VecT_method_Definition(Vertex)
|
||||
VecT_trivmove_struct_Definition(GenericMeshVertex)
|
||||
VecT_trivmove_method_Definition(GenericMeshVertex)
|
||||
VecT_primitive_zeroinit_method_Definition(GenericMeshVertex)
|
||||
SpanT_struct_Definition(GenericMeshVertex)
|
||||
SpanT_method_Definition(GenericMeshVertex)
|
||||
SpanT_VecT_method_Definition(GenericMeshVertex)
|
||||
|
||||
typedef struct {
|
||||
VecVertex vertices;
|
||||
VecGenericMeshVertex vertices;
|
||||
VecU32 indexes;
|
||||
} ModelTopology;
|
||||
|
||||
void ModelTopology_drop(ModelTopology self) {
|
||||
VecVertex_drop(self.vertices);
|
||||
VecGenericMeshVertex_drop(self.vertices);
|
||||
VecU32_drop(self.indexes);
|
||||
}
|
||||
|
||||
ModelTopology ModelTopology_clone(const ModelTopology* self) {
|
||||
return (ModelTopology){.vertices = VecGenericMeshVertex_new(&self->vertices), .indexes = VecU32_clone(&self->indexes)};
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
ModelTopology topology;
|
||||
U32 max_instance_count;
|
||||
} ModelInSceneTemplate;
|
||||
|
||||
void ModelInSceneTemplate_drop(ModelInSceneTemplate self) {
|
||||
ModelTopology_drop(self.topology);
|
||||
}
|
||||
|
||||
ModelInSceneTemplate ModelInSceneTemplate_clone(const ModelInSceneTemplate* self) {
|
||||
return (ModelInSceneTemplate){.topology = ModelTopology_clone(&self->topology), .max_instance_count = self->max_instance_count};
|
||||
}
|
||||
|
||||
VecT_trivmove_struct_Definition(ModelInSceneTemplate)
|
||||
VecT_trivmove_method_Definition(ModelInSceneTemplate)
|
||||
VecT_primitive_zeroinit_method_Definition(ModelInSceneTemplate)
|
||||
|
||||
typedef struct {
|
||||
vec2 win_scale;
|
||||
} Pipeline1PushRangeVertex;
|
||||
@ -77,19 +98,62 @@ VecT_trivmove_struct_Definition(Pipeline0PointLight)
|
||||
VecT_trivmove_method_Definition(Pipeline0PointLight)
|
||||
VecT_primitive_zeroinit_method_Definition(Pipeline0PointLight)
|
||||
|
||||
typedef struct {
|
||||
mat4 model_trans;
|
||||
} GenericMeshInstance;
|
||||
|
||||
#define GenericMeshInstance_drop(vp) {}
|
||||
#define GenericMeshInstance_clone(vp) (*(vp))
|
||||
|
||||
VecT_trivmove_struct_Definition(GenericMeshInstance)
|
||||
VecT_trivmove_method_Definition(GenericMeshInstance)
|
||||
VecT_primitive_zeroinit_method_Definition(GenericMeshInstance)
|
||||
|
||||
|
||||
typedef struct {
|
||||
VecModelInSceneTemplate models;
|
||||
size_t point_lights_max_count;
|
||||
size_t spotlights_max_count;
|
||||
} SceneTemplate;
|
||||
|
||||
size_t SceneTemplate_get_space_needed_for_all_instance_attributes(const SceneTemplate* self) {
|
||||
size_t s = 0;
|
||||
for (size_t mi = 0; mi < self->models.len; mi++) {
|
||||
const ModelInSceneTemplate* M = VecModelInSceneTemplate_cat(&self->models, mi);
|
||||
s += M->max_instance_count * sizeof(GenericMeshInstance);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t SceneTemplate_get_space_needed_for_widest_state_transfer(const SceneTemplate* self) {
|
||||
return self->point_lights_max_count * sizeof(Pipeline0PointLight) +
|
||||
self->spotlights_max_count * sizeof(Pipeline0Spotlight) +
|
||||
SceneTemplate_get_space_needed_for_all_instance_attributes(self);
|
||||
|
||||
}
|
||||
|
||||
size_t SceneTemplate_get_space_for_initial_model_topology_transfer(const SceneTemplate* self) {
|
||||
size_t s = 0;
|
||||
for (size_t mi = 0; mi < self->models.len; mi++) {
|
||||
const ModelInSceneTemplate* M = VecModelInSceneTemplate_cat(&self->models, mi);
|
||||
s += M->topology.vertices.len * sizeof(GenericMeshVertex) + M->topology.indexes.len * sizeof(U32);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#define pipeline_0_ubo_point_light_max_count 20
|
||||
#define pipeline_0_ubo_spotlight_max_count 120
|
||||
|
||||
typedef struct {
|
||||
int spotlight_count;
|
||||
int point_light_count;
|
||||
int spotlight_count;
|
||||
char _padding_1[8];
|
||||
Pipeline0PointLight point_light_arr[pipeline_0_ubo_point_light_max_count];
|
||||
Pipeline0Spotlight spotlight_arr[pipeline_0_ubo_spotlight_max_count];
|
||||
} Pipeline0UBO;
|
||||
|
||||
size_t ModelTopology_get_space_needed_for_staging_buffer(const ModelTopology* self) {
|
||||
return MAX_U64(self->vertices.len * sizeof(Vertex), self->indexes.len * sizeof(U32));
|
||||
return MAX_U64(self->vertices.len * sizeof(GenericMeshVertex), self->indexes.len * sizeof(U32));
|
||||
}
|
||||
|
||||
void TextureDataR8_pixel_maxing(TextureDataR8* self, S32 x, S32 y, U8 val) {
|
||||
@ -205,33 +269,6 @@ void TextureDataR8_draw_one_segment_maxing(TextureDataR8* self,
|
||||
TextureDataR8_draw_inner_line_maxing(self, v1, v2, r_cut, r_decay);
|
||||
}
|
||||
|
||||
// TextureDataR8G8B8A8 generate_wood_texture() {
|
||||
// const U32 width = 100;
|
||||
// const U32 height = 100;
|
||||
// TextureDataR8G8B8A8 res = TextureDataR8G8B8A8_new(width, height);
|
||||
// for (U32 y = 0; y < width; y++) {
|
||||
// for (U32 col = 0; col < height; col++) {
|
||||
// *TextureDataR8G8B8A8_at(&res, col, y) = (cvec4){150, 30, 50, 255};
|
||||
// }
|
||||
// }
|
||||
// for (U32 i = 0; i < 10; i++) {
|
||||
// for (U32 y = 0; y < height; y++) {
|
||||
// U32 col = 3 + i * 10 + ((30 < y + 3 * i && y - i < 60) ? 1 : 0);
|
||||
//
|
||||
// *TextureDataR8G8B8A8_at(&res, col, y) = (cvec4){130, 25, 40, 255};
|
||||
// *TextureDataR8G8B8A8_at(&res, col + 1, y) = (cvec4){80, 10, 15, 255};
|
||||
// *TextureDataR8G8B8A8_at(&res, col + 2, y) = (cvec4){70, 11, 12, 255};
|
||||
// *TextureDataR8G8B8A8_at(&res, col + 3, y) = (cvec4){125, 20, 20, 255};
|
||||
// }
|
||||
// }
|
||||
// for (U32 y = 0; y < 10; y++) {
|
||||
// for (U32 col = 0; col < 10; col++) {
|
||||
// *TextureDataR8G8B8A8_at(&res, col + 4, y + 13) = (cvec4){60, 8, 6, 255};
|
||||
// }
|
||||
// }
|
||||
// return res;
|
||||
// }
|
||||
|
||||
ModelTopology generate_one_fourth_of_a_cylinder(float w, float r, U32 k) {
|
||||
assert(k >= 1);
|
||||
const float a = M_PI_2f / (float)k;
|
||||
@ -240,33 +277,33 @@ ModelTopology generate_one_fourth_of_a_cylinder(float w, float r, U32 k) {
|
||||
const vec2 v1tex = {(r + w) / (2 * r + w), r / (2 * r + k * l)};
|
||||
const vec2 v2tex = {r / (2 * r + w), 2 * r / (2 * r + k * l)};
|
||||
const vec2 v3tex = {(r + w) / (2 * r + w), 2 * r / (2 * r + k * l)};
|
||||
VecVertex vertices = VecVertex_new(); // todo: reserve 4 * k + 6
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {0, 0, 0}, .tex = v0tex});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {w, 0, 0}, .tex = v1tex});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {0, r, 0}, .tex = v2tex});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {w, r, 0}, .tex = v3tex});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {0, 0, -r}, .tex = {r / (2 * r + w), 0}});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {w, 0, -r}, .tex = {(r + w) / (2 * r + w), 0}});
|
||||
VecGenericMeshVertex vertices = VecGenericMeshVertex_new(); // todo: reserve 4 * k + 6
|
||||
VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){.pos = {0, 0, 0}, .tex = v0tex});
|
||||
VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){.pos = {w, 0, 0}, .tex = v1tex});
|
||||
VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){.pos = {0, r, 0}, .tex = v2tex});
|
||||
VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){.pos = {w, r, 0}, .tex = v3tex});
|
||||
VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){.pos = {0, 0, -r}, .tex = {r / (2 * r + w), 0}});
|
||||
VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){.pos = {w, 0, -r}, .tex = {(r + w) / (2 * r + w), 0}});
|
||||
for (U32 i = 1; i <= k; i++) {
|
||||
VecVertex_append(&vertices, (Vertex){
|
||||
VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){
|
||||
.pos = {0, cosf(a * i) * r, -sinf(a * i) * r},
|
||||
.tex = vec2_add_vec2(v0tex, (vec2){r / (2 * r + w) * -sinf(a * i), r / (2 * r + k * l) * cos(a * i)})
|
||||
});
|
||||
}
|
||||
for (U32 i = 1; i <= k; i++) {
|
||||
VecVertex_append(&vertices, (Vertex){
|
||||
VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){
|
||||
.pos = {w, cosf(a * i) * r, -sinf(a * i) * r},
|
||||
.tex = vec2_add_vec2(v1tex, (vec2){r / (2 * r + w) * sinf(a * i), r / (2*r + k * l) * cos(a * i)})
|
||||
});
|
||||
}
|
||||
for (U32 i = 1; i <= k; i++) {
|
||||
VecVertex_append(&vertices, (Vertex){
|
||||
VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){
|
||||
.pos = {0, cosf(a * i) * r, -sinf(a * i) * r},
|
||||
.tex = {v2tex.x, v2tex.y + i * l / (2*r + k * l)}
|
||||
});
|
||||
}
|
||||
for (U32 i = 1; i <= k; i++) {
|
||||
VecVertex_append(&vertices, (Vertex){
|
||||
VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){
|
||||
.pos = {w, cosf(a * i) * r, -sinf(a * i) * r},
|
||||
.tex = {v3tex.x, v3tex.y + i * l / (2*r + k * l)}
|
||||
});
|
||||
|
||||
@ -3,7 +3,8 @@
|
||||
|
||||
#include "r0_assets.h"
|
||||
|
||||
/* No offset yet */
|
||||
/* No offset yet.
|
||||
* Contains references to vulkan handlers for buffers */
|
||||
typedef struct {
|
||||
VkBuffer vbo;
|
||||
VkBuffer ebo;
|
||||
@ -17,13 +18,25 @@ VecT_trivmove_struct_Definition(ModelOnScene)
|
||||
VecT_trivmove_method_Definition(ModelOnScene)
|
||||
VecT_primitive_zeroinit_method_Definition(ModelOnScene)
|
||||
|
||||
/* Contains both data for model instances attributes and buffer (+offset) where it is stored */
|
||||
typedef struct {
|
||||
ModelOnScene model;
|
||||
mat4 model_t;
|
||||
VecGenericMeshInstance instances;
|
||||
VkBuffer instance_attr_buf;
|
||||
VkDeviceSize instance_attr_buf_offset;
|
||||
U32 limit_max_instance_count;
|
||||
} UsedModelOnScene;
|
||||
|
||||
#define UsedModelOnScene_drop(vp) {}
|
||||
#define UsedModelOnScene_clone(vp) (*(vp))
|
||||
void UsedModelOnScene_drop(UsedModelOnScene self) {
|
||||
VecGenericMeshInstance_drop(self.instances);
|
||||
}
|
||||
|
||||
UsedModelOnScene UsedModelOnScene_clone(const UsedModelOnScene* self) {
|
||||
return (UsedModelOnScene){.model = self->model, .instances = VecGenericMeshInstance_clone(&self->instances),
|
||||
.instance_attr_buf = self->instance_attr_buf, .instance_attr_buf_offset = self->instance_attr_buf_offset,
|
||||
.limit_max_instance_count = self->limit_max_instance_count
|
||||
};
|
||||
}
|
||||
|
||||
VecT_trivmove_struct_Definition(UsedModelOnScene)
|
||||
VecT_trivmove_method_Definition(UsedModelOnScene)
|
||||
@ -96,7 +109,7 @@ typedef struct {
|
||||
} Scene;
|
||||
|
||||
Scene Scene_new() {
|
||||
return (Scene){.models = VecUsedModelOnScene_new(), .color = {.float32 = {1, 0.5, 0.7}},
|
||||
return (Scene){.models = VecUsedModelOnScene_new(), .color = {.float32 = {0, 0, 0, 1}},
|
||||
.gamma_correction_factor = 2.2, .hdr_factor = 1, .lsd_factor = 0, .anim_time = 0,
|
||||
.spotlights = VecPipeline0Spotlight_new(), .point_lights = VecPipeline0PointLight_new()};
|
||||
}
|
||||
@ -105,5 +118,39 @@ void Scene_drop(Scene self) {
|
||||
VecUsedModelOnScene_drop(self.models);
|
||||
}
|
||||
|
||||
void SceneTemplate_copy_initial_model_topology_and_rerecord_transfer_cmd(
|
||||
const SceneTemplate* scene_template, const Scene* scene, char* host_mem_buffer_mem,
|
||||
VkCommandBuffer command_buffer, VkBuffer host_memory_buffer
|
||||
) {
|
||||
assert(scene_template->models.len == scene->models.len);
|
||||
|
||||
if (vkResetCommandBuffer(command_buffer, 0) != VK_SUCCESS)
|
||||
abortf("vkResetCommandBuffer");
|
||||
VkCommandBufferBeginInfo info_begin = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
|
||||
if (vkBeginCommandBuffer(command_buffer, &info_begin) != VK_SUCCESS)
|
||||
abortf("vkBeginCommandBuffer");
|
||||
|
||||
size_t offset = 0;
|
||||
// todo: use BufferCopyCmd 2 (to perform all the copying in one command)
|
||||
// todo: ot use one buffer per all the data
|
||||
// VecVkBufferCopy regions_to_copy = VecVkBufferCopy_new_zeroinit(scene_template->models.len * 2);
|
||||
for (size_t mi = 0; mi < scene_template->models.len; mi++) {
|
||||
const ModelInSceneTemplate* mt = VecModelInSceneTemplate_cat(&scene_template->models, mi);
|
||||
const UsedModelOnScene* m_buf = VecUsedModelOnScene_cat(&scene->models, mi);
|
||||
size_t vbo_len = mt->topology.vertices.len * sizeof(GenericMeshVertex);
|
||||
memcpy(host_mem_buffer_mem + offset, mt->topology.vertices.buf, vbo_len);
|
||||
VkBufferCopy ra = {.srcOffset = offset, .dstOffset = 0, .size = vbo_len};
|
||||
vkCmdCopyBuffer(command_buffer, host_memory_buffer, m_buf->model.vbo, 1, &ra);
|
||||
offset += vbo_len;
|
||||
size_t ebo_len = mt->topology.indexes.len * sizeof(U32);
|
||||
memcpy(host_mem_buffer_mem + offset, mt->topology.indexes.buf, ebo_len);
|
||||
VkBufferCopy rb = {.srcOffset = offset, .dstOffset = 0, .size = ebo_len};
|
||||
vkCmdCopyBuffer(command_buffer, host_memory_buffer, m_buf->model.ebo, 1, &rb);
|
||||
offset += ebo_len;
|
||||
}
|
||||
|
||||
if (vkEndCommandBuffer(command_buffer) != VK_SUCCESS)
|
||||
abortf("vkEndCommandBuffer");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 fsin_tex;
|
||||
layout(location = 1) in vec3 fsin_pos;
|
||||
|
||||
layout(location = 0) out vec4 fin_color;
|
||||
|
||||
@ -8,29 +9,54 @@ layout(binding = 1) uniform sampler2D color_tex;
|
||||
|
||||
layout(binding = 2) uniform sampler2D normal_map;
|
||||
|
||||
struct Pipeline0Spotlight
|
||||
{
|
||||
vec3 pos;
|
||||
vec3 dir;
|
||||
vec3 colour;
|
||||
layout(push_constant, std430) uniform pc {
|
||||
layout(offset = 64) vec3 camera_pos;
|
||||
};
|
||||
|
||||
struct Pipeline0Spotlight {
|
||||
vec3 pos;
|
||||
vec3 dir;
|
||||
vec3 color;
|
||||
float range;
|
||||
};
|
||||
|
||||
struct Pipeline0PointLight
|
||||
{
|
||||
struct Pipeline0PointLight {
|
||||
vec3 pos;
|
||||
vec3 colour;
|
||||
vec3 color;
|
||||
};
|
||||
|
||||
layout(std140, binding = 0) uniform Pipeline0UBO
|
||||
{
|
||||
int spotlight_count;
|
||||
int point_light_count;
|
||||
|
||||
layout(std140, binding = 0) uniform Pipeline0UBO {
|
||||
int point_light_count;
|
||||
int spotlight_count;
|
||||
Pipeline0PointLight point_light_arr[20];
|
||||
Pipeline0Spotlight spotlight_arr [120];
|
||||
Pipeline0Spotlight spotlight_arr [120];
|
||||
};
|
||||
|
||||
float get_intensity(float dist){
|
||||
return 1 / pow(dist + 1, 2);
|
||||
}
|
||||
|
||||
void main(){
|
||||
fin_color = texture(normal_map, fsin_tex);
|
||||
vec3 compressed_normal = texture(normal_map, fsin_tex).xyz;
|
||||
vec3 norm = compressed_normal * 2 - 1;
|
||||
vec3 diffuse_illumination = vec3(0);
|
||||
vec3 specular_illumination = vec3(0);
|
||||
for (int i = 0; i < point_light_count; i++) {
|
||||
Pipeline0PointLight lamp = point_light_arr[i];
|
||||
vec3 to_light = -fsin_pos + lamp.pos;
|
||||
float dist = length(to_light);
|
||||
vec3 U = to_light / dist;
|
||||
diffuse_illumination += get_intensity(dist) * max(0.02, dot(U, norm)) * lamp.color;
|
||||
vec3 A = reflect(-U, norm);
|
||||
vec3 B = normalize(-fsin_pos+camera_pos);
|
||||
specular_illumination += get_intensity(dist) * pow(max(0, dot(A, B)), 32) * lamp.color;
|
||||
}
|
||||
for (int i = 0; i < spotlight_count; i++) {
|
||||
Pipeline0Spotlight lamp = spotlight_arr[i];
|
||||
}
|
||||
vec3 natural_color = texture(color_tex, fsin_tex).xyz;
|
||||
// todo: add specular texture
|
||||
// vec3 color = natural_color * (diffuse_illumination + specular_illumination);
|
||||
vec3 color = natural_color * ( specular_illumination);
|
||||
fin_color = vec4(color, 1);
|
||||
}
|
||||
|
||||
@ -2,18 +2,19 @@
|
||||
|
||||
layout(location = 0) in vec3 pos;
|
||||
layout(location = 1) in vec2 tex;
|
||||
layout(location = 2) in mat4 model_t;
|
||||
/* 2 <- 3, 4, 5 */
|
||||
|
||||
layout(location = 0) out vec2 vsout_tex;
|
||||
layout(location = 1) out vec3 vsout_pos;
|
||||
|
||||
layout(push_constant, std430) uniform pc {
|
||||
/* Individual transformation for a model. Fits in push constant range
|
||||
Includes global perspective matrix and camera matrix, but for each model there is a distinct
|
||||
transformation matrix. Right now I only have one instance for each model,
|
||||
otherwise I would use per-instance vertex attribute */
|
||||
mat4 t;
|
||||
mat4 proj_cam_t;
|
||||
};
|
||||
|
||||
void main(){
|
||||
vsout_tex = tex;
|
||||
gl_Position = t * vec4(pos, 1);
|
||||
vec4 real_pos = model_t * vec4(pos, 1);
|
||||
vsout_pos = real_pos.xyz;
|
||||
gl_Position = proj_cam_t * real_pos;
|
||||
}
|
||||
@ -14,5 +14,6 @@ layout(push_constant, std430) uniform pc {
|
||||
|
||||
void main() {
|
||||
vec2 tex_offset = 1.0 / textureSize(prev, 0);
|
||||
fin_color = texture(prev, gl_FragCoord.xy * tex_offset);
|
||||
vec4 hdr_color = texture(prev, gl_FragCoord.xy * tex_offset);
|
||||
fin_color = vec4(vec3(1) - exp(-hdr_factor * hdr_color.xyz), 1);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user