diff --git a/src/l2/codegen/codegen.c b/src/l2/codegen/codegen.c index e527a81..20ef585 100644 --- a/src/l2/codegen/codegen.c +++ b/src/l2/codegen/codegen.c @@ -4,17 +4,16 @@ #include "../../l1/system/fsmanip.h" #include "../../l1/codegen/util_template_inst.h" -// todo: generate here eve headers for margaret and for tests (long asset description files in r0) - void eve_of_l2() { make_dir_nofail("l2/eve"); make_dir_nofail("l2/eve/r0"); /* Needed in r0_assets.h */ - generate_eve_span_garden_for_primitive(cstr("l2"), cstr("r0"), cstr("GenericMeshVertex"), true, false); - generate_eve_span_garden_for_non_primitive_clonable(cstr("l2"), cstr("r0"), cstr("ModelInSceneTemplate"), true, false); + generate_eve_span_garden_for_primitive(cstr("l2"), cstr("r0"), cstr("GenericMeshVertex"), true, true); + generate_eve_span_garden_for_non_primitive_clonable(cstr("l2"), cstr("r0"), cstr("GenericMeshInSceneTemplate"), true, false); generate_eve_span_garden_for_primitive(cstr("l2"), cstr("r0"), cstr("GenericMeshInstance"), true, false); - generate_eve_span_garden_for_primitive(cstr("l2"), cstr("r0"), cstr("ShinyMeshVertex"), true, false); + generate_eve_span_garden_for_primitive(cstr("l2"), cstr("r0"), cstr("ShinyMeshVertex"), true, true); generate_eve_span_garden_for_primitive(cstr("l2"), cstr("r0"), cstr("ShinyMeshInstance"), true, false); + generate_eve_span_garden_for_non_primitive_clonable(cstr("l2"), cstr("r0"), cstr("ShinyMeshInSceneTemplate"), true, false); generate_eve_span_garden_for_primitive(cstr("l2"), cstr("r0"), cstr("Pipeline0Spotlight"), true, false); generate_eve_span_garden_for_primitive(cstr("l2"), cstr("r0"), cstr("Pipeline0PointLight"), true, false); generate_eve_span_garden_for_primitive(cstr("l2"), cstr("r0"), cstr("Wimbzle"), true, false); @@ -23,11 +22,10 @@ void eve_of_l2() { generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("MarieTriangle"), true, false); generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("MarieTriangleAttr"), true, false); /* Needed in r0_scene.h */ - generate_eve_span_garden_for_primitive(cstr("l2"), cstr("r0"), cstr("ModelOnScene"), true, false); - generate_eve_span_garden_for_non_primitive_clonable(cstr("l2"), cstr("r0"), cstr("UsedModelOnScene"), true, false); + generate_eve_span_garden_for_non_primitive_non_clonable(cstr("l2"), cstr("r0"), cstr("UsedGenericModelOnScene"), true, false); + generate_eve_span_garden_for_non_primitive_non_clonable(cstr("l2"), cstr("r0"), cstr("UsedShinyModelOnScene"), true, false); /* Needed in margaret/vulkan.h */ generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("CSTR"), true, false); - // generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("MargaretChosenQueueFamilies"), true, false); generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("VkQueueFamilyProperties"), true, false); generate_eve_span_garden_for_primitive(cstr("l2"), cstr(""), cstr("VkExtensionProperties"), true, false); generate_eve_header(cstr("l2"), cstr(""), cstr("VkSurfaceFormatKHR"), diff --git a/src/l2/tests/r0/r0.c b/src/l2/tests/r0/r0.c index c7df585..6651af2 100644 --- a/src/l2/tests/r0/r0.c +++ b/src/l2/tests/r0/r0.c @@ -94,7 +94,14 @@ VkRenderPass create_render_pass_0(VkDevice logical_device, VkFormat colorbuffer_ return render_pass; } -margaret_prep_buffer_mem_info_of_gpu_vbo_Definition(GenericMeshVertex) +MargaretBufferInMemoryInfo GenericMeshVertex_buffer_crinfo_of_gpu_vbo(size_t n) { + return (MargaretBufferInMemoryInfo){ .sz = safe_mul_U64(sizeof(GenericMeshVertex), n), + .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT }; +} +MargaretBufferInMemoryInfo ShinyMeshVertex_buffer_crinfo_of_gpu_vbo(size_t n) { + return (MargaretBufferInMemoryInfo){ .sz = safe_mul_U64(sizeof(ShinyMeshVertex), n), + .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT }; +} PipelineHands create_graphics_pipeline_0( VkDevice device, VkRenderPass render_pass, uint32_t subpass @@ -133,7 +140,7 @@ PipelineHands create_graphics_pipeline_0( { .location = 1, .binding = 0, - .format = VK_FORMAT_R32G32_SFLOAT, + .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = offsetof(GenericMeshVertex, tex), }, @@ -319,6 +326,229 @@ PipelineHands create_graphics_pipeline_0( return (PipelineHands){.pipeline_layout = pipeline_layout, .pipeline = pipeline, .descriptor_set_layout = my_descriptor_set_layout}; } +PipelineHands create_graphics_pipeline_0_b( + VkDevice device, VkRenderPass render_pass, uint32_t subpass + ) { + VecU8 vert_bin_code = read_whole_file_or_abort("shaders/spv/0b/vert.spv"); + VecU8 frag_bin_code = read_whole_file_or_abort("shaders/spv/0b/frag.spv"); + VkShaderModule vert_module = margaret_VkShaderModule_new(device, vert_bin_code); + VkShaderModule frag_module = margaret_VkShaderModule_new(device, frag_bin_code); + VecU8_drop(vert_bin_code); + VecU8_drop(frag_bin_code); + + VkPipelineShaderStageCreateInfo shader_stages_crinfo[2] = { + margaret_shader_stage_vertex_crinfo(vert_module), + margaret_shader_stage_fragment_crinfo(frag_module) + }; + + VkVertexInputBindingDescription vertex_bindings[2] = { + { + .binding = 0, + .stride = sizeof(ShinyMeshVertex), + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, + }, + { + .binding = 1, + .stride = sizeof(ShinyMeshInstance), + .inputRate = VK_VERTEX_INPUT_RATE_INSTANCE, + } + }; + VkVertexInputAttributeDescription vertex_attributes[2 + 6] = { + { + .location = 0, + .binding = 0, + .format = VK_FORMAT_R32G32B32_SFLOAT, + .offset = offsetof(ShinyMeshVertex, pos), + }, + { + .location = 1, + .binding = 0, + .format = VK_FORMAT_R32G32B32_SFLOAT, + .offset = offsetof(ShinyMeshVertex, normal), + }, + + /* This is a mat4 datatype, so it will take 4 entire 'locations' */ + { + .location = 2, + .binding = 1, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = offsetof(ShinyMeshInstance, model_t) + offsetof(mat4, x) + }, + { + .location = 3, + .binding = 1, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = offsetof(ShinyMeshInstance, model_t) + offsetof(mat4, y) + }, + { + .location = 4, + .binding = 1, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = offsetof(ShinyMeshInstance, model_t) + offsetof(mat4, z) + }, + { + .location = 5, + .binding = 1, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = offsetof(ShinyMeshInstance, model_t) + offsetof(mat4, w) + }, + { + .location = 6, + .binding = 1, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = offsetof(ShinyMeshInstance, color_off) + }, + { + .location = 7, + .binding = 1, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = offsetof(ShinyMeshInstance, color_on) + }, + }; + + VkPipelineVertexInputStateCreateInfo vertex_input_crinfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = ARRAY_SIZE(vertex_bindings), + .pVertexBindingDescriptions = vertex_bindings, + .vertexAttributeDescriptionCount = ARRAY_SIZE(vertex_attributes), + .pVertexAttributeDescriptions = vertex_attributes, + }; + + VkPipelineInputAssemblyStateCreateInfo input_assembly_crinfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + .primitiveRestartEnable = VK_FALSE, + }; + + VkPipelineViewportStateCreateInfo viewport_state = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .viewportCount = 1, + .scissorCount = 1, + }; + + VkPipelineRasterizationStateCreateInfo rasterizer_crinfo = { + .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, + .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, + .depthBiasEnable = VK_FALSE, + .depthBiasConstantFactor = 0.0f, + .depthBiasClamp = 0.0f, + .depthBiasSlopeFactor = 0.0f, + .lineWidth = 1.0f, + }; + + VkPipelineMultisampleStateCreateInfo multisampling_crinfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .sampleShadingEnable = VK_FALSE, + .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, + .minSampleShading = 1.0f, + .pSampleMask = NULL, + .alphaToCoverageEnable = VK_FALSE, + .alphaToOneEnable = VK_FALSE, + }; + + VkPipelineDepthStencilStateCreateInfo depth_stencil_state_crinfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + .depthTestEnable = VK_TRUE, + .depthWriteEnable = VK_TRUE, + .depthCompareOp = VK_COMPARE_OP_LESS + }; + + // For one framebuffer + VkPipelineColorBlendAttachmentState color_blend_attachments[1] = {(VkPipelineColorBlendAttachmentState){ + .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, + .blendEnable = VK_FALSE, + }}; + + // For the entire pipeline + VkPipelineColorBlendStateCreateInfo color_blending_crinfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + .logicOpEnable = VK_FALSE, + .logicOp = VK_LOGIC_OP_COPY, + .attachmentCount = ARRAY_SIZE(color_blend_attachments), + .pAttachments = color_blend_attachments, + // Blend constants specified heres + }; + + VkDynamicState dynamic_states[2] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR}; + VkPipelineDynamicStateCreateInfo dynamic_state_crinfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + .dynamicStateCount = ARRAY_SIZE(dynamic_states), + .pDynamicStates = dynamic_states, + }; + + VkDescriptorSetLayoutBinding bindings_for_my_descr_set_layout[] = { + { + .binding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + // our shader variable is not an array of descriptors, so this stays 1 + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + }, + }; + VkDescriptorSetLayoutCreateInfo descriptor_set_layout_crinfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .bindingCount = ARRAY_SIZE(bindings_for_my_descr_set_layout), + .pBindings = bindings_for_my_descr_set_layout, + }; + VkDescriptorSetLayout my_descriptor_set_layout; + if (vkCreateDescriptorSetLayout(device, &descriptor_set_layout_crinfo, NULL, &my_descriptor_set_layout) != VK_SUCCESS) + abortf("vkCreateDescriptorSetLayout"); + + VkPushConstantRange pc_ranges[] = { + { + .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, + .setLayoutCount = 1, + .pSetLayouts = &my_descriptor_set_layout, + .pushConstantRangeCount = ARRAY_SIZE(pc_ranges), + .pPushConstantRanges = pc_ranges, + }; + VkPipelineLayout pipeline_layout; + if (vkCreatePipelineLayout(device, &layout_crinfo, NULL, &pipeline_layout) != VK_SUCCESS) + abortf("vkCreatePipelineLayout"); + VkGraphicsPipelineCreateInfo pipeline_crinfo = { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .stageCount = ARRAY_SIZE(shader_stages_crinfo), + .pStages = shader_stages_crinfo, + .pVertexInputState = &vertex_input_crinfo, + .pInputAssemblyState = &input_assembly_crinfo, + .pViewportState = &viewport_state, + .pRasterizationState = &rasterizer_crinfo, + .pMultisampleState = &multisampling_crinfo, + .pDepthStencilState = &depth_stencil_state_crinfo, + .pColorBlendState = &color_blending_crinfo, + .pDynamicState = &dynamic_state_crinfo, + .layout = pipeline_layout, + .renderPass = render_pass, + .subpass = subpass, + .basePipelineHandle = VK_NULL_HANDLE, + }; + + VkPipeline pipeline; + if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_crinfo, NULL, &pipeline) != VK_SUCCESS) + abortf("vkCreateGraphicsPipelines"); + + vkDestroyShaderModule(device, frag_module, NULL); + vkDestroyShaderModule(device, vert_module, NULL); + return (PipelineHands){.pipeline_layout = pipeline_layout, .pipeline = pipeline, .descriptor_set_layout = my_descriptor_set_layout}; +} + + + // todo: generate this function in l2 VkRenderPass create_render_pass_1(VkDevice logical_device, VkFormat image_format) { @@ -538,11 +768,30 @@ VkFramebuffer create_IT1_framebuffer(VkDevice device, VkImageView IT1_view, VkIm return framebuffer; } +void record_cmd_set_viewport_and_scissors(VkCommandBuffer command_buffer, VkExtent2D image_extent) { + VkViewport viewport = { + .x = 0.0f, + .y = 0.0f, + .width = (float)(image_extent.width), + .height = (float)(image_extent.height), + .minDepth = 0.0f, + .maxDepth = 1.0f, + }; + vkCmdSetViewport(command_buffer, 0, 1, &viewport); + VkRect2D scissor = { + .offset = (VkOffset2D){0, 0}, + .extent = image_extent, + }; + vkCmdSetScissor(command_buffer, 0, 1, &scissor); +} + void reset_and_record_command_buffer_0( VkCommandBuffer command_buffer, VkRenderPass render_pass_0, - const PipelineHands* pipeline_and_layout, - VkFramebuffer swapchain_image_framebuffer, VkImage IT1_image, VkExtent2D image_extent, - const Scene* scene, VkDescriptorSet my_descriptor_set, mat4 proj_cam_t, vec3 camera_pos + const PipelineHands* pipeline_and_layout_0a, const PipelineHands* pipeline_and_layout_0b, + VkFramebuffer result_framebuffer, VkExtent2D image_extent, + const Scene* scene, + VkDescriptorSet descriptor_set_for_pipeline_0a, VkDescriptorSet descriptor_set_for_pipeline_0b, + mat4 proj_cam_t, vec3 camera_pos ) { if (vkResetCommandBuffer(command_buffer, 0) != VK_SUCCESS) abortf("vkResetCommandBuffer"); @@ -554,7 +803,7 @@ void reset_and_record_command_buffer_0( VkRenderPassBeginInfo renderpass_begin = { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, .renderPass = render_pass_0, - .framebuffer = swapchain_image_framebuffer, + .framebuffer = result_framebuffer, .renderArea.offset = (VkOffset2D){0, 0}, .renderArea.extent = image_extent, .clearValueCount = ARRAY_SIZE(clear_values), @@ -562,39 +811,45 @@ void reset_and_record_command_buffer_0( }; vkCmdBeginRenderPass(command_buffer, &renderpass_begin, VK_SUBPASS_CONTENTS_INLINE); - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout->pipeline); - + vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout_0a->pipeline); // We forgot that viewport is not built into our pipeline - VkViewport viewport = { - .x = 0.0f, - .y = 0.0f, - .width = (float)(image_extent.width), - .height = (float)(image_extent.height), - .minDepth = 0.0f, - .maxDepth = 1.0f, - }; - vkCmdSetViewport(command_buffer, 0, 1, &viewport); // We forgot that scissors are not built into out pipeline - VkRect2D scissor = { - .offset = (VkOffset2D){0, 0}, - .extent = image_extent, - }; - vkCmdSetScissor(command_buffer, 0, 1, &scissor); - vkCmdPushConstants(command_buffer, pipeline_and_layout->pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, + record_cmd_set_viewport_and_scissors(command_buffer, image_extent); + vkCmdPushConstants(command_buffer, pipeline_and_layout_0a->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, + vkCmdPushConstants(command_buffer, pipeline_and_layout_0a->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_at(&scene->models, i); - VkBuffer attached_buffers[2] = { model->model.vbo, model->instance_attr_buf }; + for (size_t i = 0; i < scene->generic_models.len; i++) { + const UsedGenericModelOnScene *model = VecUsedGenericModelOnScene_at(&scene->generic_models, i); + VkBuffer attached_buffers[2] = { model->model.vbo, model->model.instance_attr_buf }; // We use our whole buffer, no need for offset - VkDeviceSize offsets_in_buffers[2] = {0, model->instance_attr_buf_offset}; + VkDeviceSize offsets_in_buffers[2] = {0, model->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); vkCmdBindDescriptorSets( - command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout->pipeline_layout, 0, - 1, &my_descriptor_set, 0, NULL); + command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout_0a->pipeline_layout, 0, + 1, &descriptor_set_for_pipeline_0a, 0, NULL); + vkCmdDrawIndexed(command_buffer, model->model.indexes, model->instances.len, 0, 0, 0); + } + + vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout_0b->pipeline); + record_cmd_set_viewport_and_scissors(command_buffer, image_extent); + vkCmdPushConstants(command_buffer, pipeline_and_layout_0b->pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, + 0, sizeof(mat4), &proj_cam_t); + vkCmdPushConstants(command_buffer, pipeline_and_layout_0b->pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, + sizeof(mat4), sizeof(vec3), &camera_pos); + for (size_t i = 0; i < scene->shiny_models.len; i++) { + const UsedShinyModelOnScene* model = VecUsedShinyModelOnScene_at(&scene->shiny_models, i); + VkBuffer attached_buffers[2] = { model->model.vbo, model->model.instance_attr_buf }; + // We use our whole buffer, no need for offset + VkDeviceSize offsets_in_buffers[2] = {0, model->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); + vkCmdBindDescriptorSets( + command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout_0b->pipeline_layout, 0, + 1, &descriptor_set_for_pipeline_0b, 0, NULL); vkCmdDrawIndexed(command_buffer, model->model.indexes, model->instances.len, 0, 0, 0); } @@ -627,20 +882,7 @@ void reset_and_record_command_buffer_1( vkCmdBeginRenderPass(command_buffer, &renderpass_begin, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout_1->pipeline); - VkViewport viewport = { - .x = 0.0f, - .y = 0.0f, - .width = (float)(image_extent.width), - .height = (float)(image_extent.height), - .minDepth = 0.0f, - .maxDepth = 1.0f, - }; - vkCmdSetViewport(command_buffer, 0, 1, &viewport); - VkRect2D scissor = { - .offset = (VkOffset2D){0, 0}, - .extent = image_extent, - }; - vkCmdSetScissor(command_buffer, 0, 1, &scissor); + record_cmd_set_viewport_and_scissors(command_buffer, image_extent); vkCmdBindDescriptorSets( command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout_1->pipeline_layout, 0, 1, &descriptor_set_for_pipeline_1, 0, NULL); @@ -666,13 +908,14 @@ void reset_and_record_command_buffer_1( abortf("vkEndCommandBuffer"); } +// todo: kill myself /* 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 + VkBuffer device_lighting_ubo, VkBuffer device_instance_attrs_for_models ) { if (vkResetCommandBuffer(command_buffer, 0) != VK_SUCCESS) @@ -681,21 +924,32 @@ void copy_scene_info_to_buffer_and_rerecord_full_copy_command_buffer( if (vkBeginCommandBuffer(command_buffer, &info_begin) != VK_SUCCESS) abortf("vkBeginCommandBuffer"); + // todo: rewrite this entire fucking shit 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_at(&scene->models, mi); - assert(model->instances.len <= model->limit_max_instance_count); + for (size_t mi = 0; mi < scene->generic_models.len; mi++) { + const UsedGenericModelOnScene* model = VecUsedGenericModelOnScene_at(&scene->generic_models, mi); + assert(model->instances.len <= model->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); + offset_in_mesh_instance_buf += model->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); + for (size_t mi = 0; mi < scene->shiny_models.len; mi++) { + const UsedShinyModelOnScene* model = VecUsedShinyModelOnScene_at(&scene->shiny_models, mi); + assert(model->instances.len <= model->model.limit_max_instance_count); + size_t all = model->instances.len * sizeof(ShinyMeshInstance); + 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->model.limit_max_instance_count * sizeof(ShinyMeshInstance); + } + vkCmdCopyBuffer(command_buffer, host_memory_buffer, device_instance_attrs_for_models, regions_to_copy_A.len, regions_to_copy_A.buf); VecVkBufferCopy_drop(regions_to_copy_A); } { @@ -734,7 +988,6 @@ void copy_scene_info_to_buffer_and_rerecord_full_copy_command_buffer( abortf("vkEndCommandBuffer"); } -// todo: generate this structure in l2 typedef struct { VkSemaphore in_frame_transfer_complete; VkSemaphore image_available_semaphore; @@ -774,7 +1027,8 @@ typedef struct { VkFormat zbuffer_format; VkFormat IT1_format; VkRenderPass render_pass_0; - PipelineHands pipeline_hands_0; + PipelineHands pipeline_hands_0a; + PipelineHands pipeline_hands_0b; VkRenderPass render_pass_1; PipelineHands pipeline_hands_1; Jane_r0 jane; @@ -785,9 +1039,12 @@ typedef struct { TextureDataR8G8B8A8 cyl_1_normal_tex; MargaretBufferInMemoryInfo host_mem_buffer; VkDeviceMemory host_mem; - VecMargaretBufferInMemoryInfo device_ebo_and_vbo_buffers_for_generic_meshes; + VecMargaretBufferInMemoryInfo device_ebo_buffers_for_generic_meshes; + VecMargaretBufferInMemoryInfo device_vbo_buffers_for_generic_meshes; + VecMargaretBufferInMemoryInfo device_ebo_buffers_for_shiny_meshes; + VecMargaretBufferInMemoryInfo device_vbo_buffers_for_shiny_meshes; MargaretBufferInMemoryInfo device_lighting_ubo; - MargaretBufferInMemoryInfo device_instance_attrs_for_all_generic_meshes; + MargaretBufferInMemoryInfo device_instance_attrs_for_models; MargaretImageInMemoryInfo device_IT1_image; MargaretImageInMemoryInfo device_zbuffer_image; MargaretImageInMemoryInfo device_cyl_1_diffuse_texture; @@ -811,7 +1068,8 @@ typedef struct { VkSampler linear_sampler; VkSampler nearest_sampler; VkDescriptorPool descriptor_pool; - VkDescriptorSet descriptor_set_for_pipeline_0; + VkDescriptorSet descriptor_set_for_pipeline_0a; + VkDescriptorSet descriptor_set_for_pipeline_0b; VkDescriptorSet descriptor_set_for_pipeline_1; CamControlInfo my_cam_control_info; @@ -898,25 +1156,25 @@ void update_state(state_r0* state, uint32_t dur) { if (state->first_0x80_keys[XKB_KEY_j]) { state->vk_ctx.Buba_control_info.x -= fl; - VecGenericMeshInstance_mat(&VecUsedModelOnScene_mat(&state->vk_ctx.scene.models, 1)->instances, 0)->model_t = + VecGenericMeshInstance_mat(&VecUsedGenericModelOnScene_mat(&state->vk_ctx.scene.generic_models, 1)->instances, 0)->model_t = marie_translation_mat4(state->vk_ctx.Buba_control_info); state->vk_ctx.dt_transfer_required = true; } if (state->first_0x80_keys[XKB_KEY_k]) { state->vk_ctx.Buba_control_info.z -= fl; - VecGenericMeshInstance_mat(&VecUsedModelOnScene_mat(&state->vk_ctx.scene.models, 1)->instances, 0)->model_t = + VecGenericMeshInstance_mat(&VecUsedGenericModelOnScene_mat(&state->vk_ctx.scene.generic_models, 1)->instances, 0)->model_t = marie_translation_mat4(state->vk_ctx.Buba_control_info); state->vk_ctx.dt_transfer_required = true; } if (state->first_0x80_keys[XKB_KEY_l]) { state->vk_ctx.Buba_control_info.z += fl; - VecGenericMeshInstance_mat(&VecUsedModelOnScene_mat(&state->vk_ctx.scene.models, 1)->instances, 0)->model_t = + VecGenericMeshInstance_mat(&VecUsedGenericModelOnScene_mat(&state->vk_ctx.scene.generic_models, 1)->instances, 0)->model_t = marie_translation_mat4(state->vk_ctx.Buba_control_info); state->vk_ctx.dt_transfer_required = true; } if (state->first_0x80_keys[XKB_KEY_semicolon]) { state->vk_ctx.Buba_control_info.x += fl; - VecGenericMeshInstance_mat(&VecUsedModelOnScene_mat(&state->vk_ctx.scene.models, 1)->instances, 0)->model_t = + VecGenericMeshInstance_mat(&VecUsedGenericModelOnScene_mat(&state->vk_ctx.scene.generic_models, 1)->instances, 0)->model_t = marie_translation_mat4(state->vk_ctx.Buba_control_info); state->vk_ctx.dt_transfer_required = true; } @@ -958,7 +1216,7 @@ void vulkano_frame_drawing(state_r0* state) { copy_scene_info_to_buffer_and_rerecord_full_copy_command_buffer( state->vk_ctx.transfer_command_buffer, state->vk_ctx.host_mem_buffer.buffer, state->vk_ctx.host_mem_buffer_mem, &state->vk_ctx.scene, state->vk_ctx.device_lighting_ubo.buffer, - state->vk_ctx.device_instance_attrs_for_all_generic_meshes.buffer); + state->vk_ctx.device_instance_attrs_for_models.buffer); VkCommandBuffer command_buffers[1] = { state->vk_ctx.transfer_command_buffer }; VkSemaphore signaling_semaphores[1] = { state->vk_ctx.jane.in_frame_transfer_complete }; VkSubmitInfo submit_info = { @@ -973,10 +1231,12 @@ void vulkano_frame_drawing(state_r0* state) { } reset_and_record_command_buffer_0( - state->vk_ctx.rendering_command_buffer_0, state->vk_ctx.render_pass_0, &state->vk_ctx.pipeline_hands_0, - state->vk_ctx.IT1_framebuffer, state->vk_ctx.device_IT1_image.image, state->vk_ctx.swfb.extent, + state->vk_ctx.rendering_command_buffer_0, state->vk_ctx.render_pass_0, + &state->vk_ctx.pipeline_hands_0a, &state->vk_ctx.pipeline_hands_0b, + state->vk_ctx.IT1_framebuffer, state->vk_ctx.swfb.extent, &state->vk_ctx.scene, - state->vk_ctx.descriptor_set_for_pipeline_0, t_mat, state->vk_ctx.my_cam_control_info.pos); + state->vk_ctx.descriptor_set_for_pipeline_0a, state->vk_ctx.descriptor_set_for_pipeline_0b, + t_mat, state->vk_ctx.my_cam_control_info.pos); reset_and_record_command_buffer_1(state->vk_ctx.rendering_command_buffer_1, state->vk_ctx.render_pass_1, &state->vk_ctx.pipeline_hands_1, @@ -1390,6 +1650,7 @@ void compile_shader_dir(SpanU8 name) { int main() { compile_shader_dir(cstr("0")); + compile_shader_dir(cstr("0b")); compile_shader_dir(cstr("1")); SpanU8 GPU = cstr("nvidia"); @@ -1477,7 +1738,8 @@ int main() { state.vk_ctx.IT1_format = IT1_format.some; state.vk_ctx.render_pass_0 = create_render_pass_0(state.vk_ctx.device, IT1_format.some, zbuffer_format.some); - state.vk_ctx.pipeline_hands_0 = create_graphics_pipeline_0(state.vk_ctx.device, state.vk_ctx.render_pass_0, 0); + state.vk_ctx.pipeline_hands_0a = create_graphics_pipeline_0(state.vk_ctx.device, state.vk_ctx.render_pass_0, 0); + state.vk_ctx.pipeline_hands_0b = create_graphics_pipeline_0_b(state.vk_ctx.device, state.vk_ctx.render_pass_0, 0); state.vk_ctx.render_pass_1 = create_render_pass_1(state.vk_ctx.device, swapchain_details_res.ok.surface_format.format); state.vk_ctx.pipeline_hands_1 = create_graphics_pipeline_1(state.vk_ctx.device, state.vk_ctx.render_pass_1, 0); @@ -1486,13 +1748,22 @@ int main() { state.vk_ctx.device, state.vk_ctx.queue_fam, swapchain_details_res.ok, state.vk_ctx.surface, state.vk_ctx.render_pass_1, NULL); - state.vk_ctx.scene_template = (SceneTemplate){.models = VecModelInSceneTemplate_new(), + state.vk_ctx.scene_template = (SceneTemplate){ + .generic_models = VecGenericMeshInSceneTemplate_new(), + .shiny_models = VecShinyMeshInSceneTemplate_new(), .point_lights_max_count = pipeline_0_ubo_point_light_max_count, .spotlights_max_count = pipeline_0_ubo_spotlight_max_count}; - VecModelInSceneTemplate_append(&state.vk_ctx.scene_template.models, - (ModelInSceneTemplate){.topology = generate_one_fourth_of_a_cylinder(10, 2, 6), .max_instance_count = 100}); - VecModelInSceneTemplate_append(&state.vk_ctx.scene_template.models, - (ModelInSceneTemplate){.topology = generate_one_fourth_of_a_cylinder(5, 5, 10), .max_instance_count = 1}); + VecGenericMeshInSceneTemplate_append(&state.vk_ctx.scene_template.generic_models, + (GenericMeshInSceneTemplate){.topology = generate_one_fourth_of_a_cylinder(10, 2, 6), .max_instance_count = 100}); + VecGenericMeshInSceneTemplate_append(&state.vk_ctx.scene_template.generic_models, + (GenericMeshInSceneTemplate){.topology = generate_one_fourth_of_a_cylinder(5, 5, 10), .max_instance_count = 1}); + VecShinyMeshInSceneTemplate_append(&state.vk_ctx.scene_template.shiny_models, (ShinyMeshInSceneTemplate){ + .topology = generate_shiny_rhombicuboctahedron(0.5f), .max_instance_count = 5 + }); + VecShinyMeshInSceneTemplate_append(&state.vk_ctx.scene_template.shiny_models, (ShinyMeshInSceneTemplate){ + .topology = generate_shiny_cube(0.5f), .max_instance_count = 5 + }); + // todo: generate more cool shiny models // todo: learn how to use libpng state.vk_ctx.cyl_1_diffuse_tex = TextureDataR8G8B8A8_read_from_file("textures/log_10_2_6.r8g8b8a8"); @@ -1516,27 +1787,51 @@ int main() { VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); // todo: split this in two (or maybe even better: merge it all into one/two buffer and use offsets - state.vk_ctx.device_ebo_and_vbo_buffers_for_generic_meshes = VecMargaretBufferInMemoryInfo_new(); - for (size_t mi = 0; mi < state.vk_ctx.scene_template.models.len; mi++) { - const ModelInSceneTemplate* M = VecModelInSceneTemplate_at(&state.vk_ctx.scene_template.models, mi); - VecMargaretBufferInMemoryInfo_append(&state.vk_ctx.device_ebo_and_vbo_buffers_for_generic_meshes, + state.vk_ctx.device_ebo_buffers_for_generic_meshes = VecMargaretBufferInMemoryInfo_new(); + state.vk_ctx.device_vbo_buffers_for_generic_meshes = VecMargaretBufferInMemoryInfo_new(); + for (size_t mi = 0; mi < state.vk_ctx.scene_template.generic_models.len; mi++) { + const GenericMeshInSceneTemplate* M = VecGenericMeshInSceneTemplate_at(&state.vk_ctx.scene_template.generic_models, mi); + VecMargaretBufferInMemoryInfo_append(&state.vk_ctx.device_vbo_buffers_for_generic_meshes, GenericMeshVertex_buffer_crinfo_of_gpu_vbo(M->topology.vertices.len)); - VecMargaretBufferInMemoryInfo_append(&state.vk_ctx.device_ebo_and_vbo_buffers_for_generic_meshes, + VecMargaretBufferInMemoryInfo_append(&state.vk_ctx.device_ebo_buffers_for_generic_meshes, margaret_prep_buffer_mem_info_of_gpu_ebo(M->topology.indexes.len)); } + state.vk_ctx.device_ebo_buffers_for_shiny_meshes = VecMargaretBufferInMemoryInfo_new(); + state.vk_ctx.device_vbo_buffers_for_shiny_meshes = VecMargaretBufferInMemoryInfo_new(); + for (size_t mi = 0; mi < state.vk_ctx.scene_template.shiny_models.len; mi++) { + const ShinyMeshInSceneTemplate* M = VecShinyMeshInSceneTemplate_at(&state.vk_ctx.scene_template.shiny_models, mi); + VecMargaretBufferInMemoryInfo_append(&state.vk_ctx.device_vbo_buffers_for_shiny_meshes, + ShinyMeshVertex_buffer_crinfo_of_gpu_vbo(M->topology.vertices.len)); + VecMargaretBufferInMemoryInfo_append(&state.vk_ctx.device_ebo_buffers_for_shiny_meshes, + margaret_prep_buffer_mem_info_of_gpu_ebo(M->topology.indexes.len)); + } + state.vk_ctx.device_lighting_ubo = margaret_prep_buffer_mem_info_of_gpu_ubo(sizeof(Pipeline0UBO)); - state.vk_ctx.device_instance_attrs_for_all_generic_meshes = (MargaretBufferInMemoryInfo){ + state.vk_ctx.device_instance_attrs_for_models = (MargaretBufferInMemoryInfo){ .sz = SceneTemplate_get_space_needed_for_all_instance_attributes(&state.vk_ctx.scene_template), .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT }; VecPtrMargaretBufferInMemoryInfo device_mem_buffers_SPAN = VecPtrMargaretBufferInMemoryInfo_new(); - for (size_t i = 0; i < state.vk_ctx.device_ebo_and_vbo_buffers_for_generic_meshes.len; i++) { + // todo: add iteration macro generation + for (size_t i = 0; i < state.vk_ctx.device_ebo_buffers_for_generic_meshes.len; i++) { VecPtrMargaretBufferInMemoryInfo_append(&device_mem_buffers_SPAN, - VecMargaretBufferInMemoryInfo_mat(&state.vk_ctx.device_ebo_and_vbo_buffers_for_generic_meshes, i)); + VecMargaretBufferInMemoryInfo_mat(&state.vk_ctx.device_ebo_buffers_for_generic_meshes, i)); + } + for (size_t i = 0; i < state.vk_ctx.device_vbo_buffers_for_generic_meshes.len; i++) { + VecPtrMargaretBufferInMemoryInfo_append(&device_mem_buffers_SPAN, + VecMargaretBufferInMemoryInfo_mat(&state.vk_ctx.device_vbo_buffers_for_generic_meshes, i)); + } + for (size_t i = 0; i < state.vk_ctx.device_ebo_buffers_for_shiny_meshes.len; i++) { + VecPtrMargaretBufferInMemoryInfo_append(&device_mem_buffers_SPAN, + VecMargaretBufferInMemoryInfo_mat(&state.vk_ctx.device_ebo_buffers_for_shiny_meshes, i)); + } + for (size_t i = 0; i < state.vk_ctx.device_vbo_buffers_for_shiny_meshes.len; i++) { + VecPtrMargaretBufferInMemoryInfo_append(&device_mem_buffers_SPAN, + VecMargaretBufferInMemoryInfo_mat(&state.vk_ctx.device_vbo_buffers_for_shiny_meshes, i)); } VecPtrMargaretBufferInMemoryInfo_append(&device_mem_buffers_SPAN, &state.vk_ctx.device_lighting_ubo); - VecPtrMargaretBufferInMemoryInfo_append(&device_mem_buffers_SPAN, &state.vk_ctx.device_instance_attrs_for_all_generic_meshes); + VecPtrMargaretBufferInMemoryInfo_append(&device_mem_buffers_SPAN, &state.vk_ctx.device_instance_attrs_for_models); state.vk_ctx.device_IT1_image = margaret_prep_image_mem_info_of_colorbuffer( MAX_WIN_WIDTH, MAX_WIN_HEIGHT, IT1_format.some); @@ -1563,37 +1858,67 @@ int main() { state.vk_ctx.rendering_command_buffer_1 = margaret_allocate_command_buffer(state.vk_ctx.device, state.vk_ctx.command_pool); state.vk_ctx.transfer_command_buffer = margaret_allocate_command_buffer(state.vk_ctx.device, state.vk_ctx.command_pool); + state.vk_ctx.my_cam_control_info = CamControlInfo_new(); + state.vk_ctx.Buba_control_info = (vec3){0}; + state.vk_ctx.scene = Scene_new(); { size_t offset_in_attr_buffer = 0; - for (size_t mi = 0; mi < state.vk_ctx.scene_template.models.len; mi++) { - const ModelInSceneTemplate* M = VecModelInSceneTemplate_at(&state.vk_ctx.scene_template.models, mi); - VecUsedModelOnScene_append(&state.vk_ctx.scene.models, (UsedModelOnScene){ - .model = (ModelOnScene){ - .vbo = VecMargaretBufferInMemoryInfo_at(&state.vk_ctx.device_ebo_and_vbo_buffers_for_generic_meshes, - 2 * mi + 0)->buffer, - .ebo = VecMargaretBufferInMemoryInfo_at(&state.vk_ctx.device_ebo_and_vbo_buffers_for_generic_meshes, - 2 * mi + 1)->buffer, + for (size_t mi = 0; mi < state.vk_ctx.scene_template.generic_models.len; mi++) { + const GenericMeshInSceneTemplate* M = VecGenericMeshInSceneTemplate_at(&state.vk_ctx.scene_template.generic_models, mi); + VecUsedGenericModelOnScene_append(&state.vk_ctx.scene.generic_models, (UsedGenericModelOnScene){ + .model = (ModelOnSceneMem){ + .vbo = VecMargaretBufferInMemoryInfo_at( + &state.vk_ctx.device_vbo_buffers_for_generic_meshes, mi)->buffer, + .ebo = VecMargaretBufferInMemoryInfo_at( + &state.vk_ctx.device_ebo_buffers_for_generic_meshes, mi)->buffer, .indexes = M->topology.indexes.len, + .instance_attr_buf = state.vk_ctx.device_instance_attrs_for_models.buffer, + .instance_attr_buf_offset = offset_in_attr_buffer, + .limit_max_instance_count = M->max_instance_count }, .instances = VecGenericMeshInstance_new(), - .instance_attr_buf = state.vk_ctx.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 (size_t mi = 0; mi < state.vk_ctx.scene_template.shiny_models.len; mi++) { + const ShinyMeshInSceneTemplate* M = VecShinyMeshInSceneTemplate_at(&state.vk_ctx.scene_template.shiny_models, mi); + VecUsedShinyModelOnScene_append(&state.vk_ctx.scene.shiny_models, (UsedShinyModelOnScene){ + .model = (ModelOnSceneMem){ + .vbo = VecMargaretBufferInMemoryInfo_at( + &state.vk_ctx.device_vbo_buffers_for_shiny_meshes, mi)->buffer, + .ebo = VecMargaretBufferInMemoryInfo_at( + &state.vk_ctx.device_ebo_buffers_for_shiny_meshes, mi)->buffer, + .indexes = M->topology.indexes.len, + .instance_attr_buf = state.vk_ctx.device_instance_attrs_for_models.buffer, + .instance_attr_buf_offset = offset_in_attr_buffer, + .limit_max_instance_count = M->max_instance_count + }, + .instances = VecShinyMeshInstance_new(), + }); + offset_in_attr_buffer += M->max_instance_count * sizeof(ShinyMeshInstance); + } } for (int X = 0; X < 10; X++) { for (int Z = 0; Z < 10; Z++) { - VecGenericMeshInstance_append(&VecUsedModelOnScene_mat(&state.vk_ctx.scene.models, 0)->instances, + VecGenericMeshInstance_append(&VecUsedGenericModelOnScene_mat(&state.vk_ctx.scene.generic_models, 0)->instances, (GenericMeshInstance){ .model_t = marie_translation_mat4((vec3){11.f * (float)X, -6, 4.f * (float)Z}) }); } } - VecGenericMeshInstance_append(&VecUsedModelOnScene_mat(&state.vk_ctx.scene.models, 1)->instances, (GenericMeshInstance){ - .model_t = mat4_E + VecGenericMeshInstance_append(&VecUsedGenericModelOnScene_mat(&state.vk_ctx.scene.generic_models, 1)->instances, + (GenericMeshInstance){ .model_t = marie_translation_mat4(state.vk_ctx.Buba_control_info) }); + for (U64 i = 0; i < 5; i++) { + VecShinyMeshInstance_append(&VecUsedShinyModelOnScene_mat(&state.vk_ctx.scene.shiny_models, 0)->instances, + (ShinyMeshInstance){ .model_t = marie_translation_mat4((vec3){ + (float)((i * i * 10 + i * 4 + 1) % 13) + 2, + (float)((i * i * 11 + i * 2 + 2) % 13), + (float)((i * i * 9 + i * 1 + 4) % 13) + 3}), .color_off = (vec3){0.6f, 0.2f, 0.2f}}); + } + VecShinyMeshInstance_append(&VecUsedShinyModelOnScene_mat(&state.vk_ctx.scene.shiny_models, 1)->instances, + (ShinyMeshInstance){ .model_t = marie_translation_mat4((vec3){-5, 0, 3}), .color_off = (vec3){0.3f, 0.5f, 0.5f}}); + // todo: synchronize them with my cool light sources) if (vkMapMemory(state.vk_ctx.device, state.vk_ctx.host_mem, 0, VK_WHOLE_SIZE, 0, &state.vk_ctx.host_mem_buffer_mem) != VK_SUCCESS) abortf("vkMapMemory"); @@ -1654,28 +1979,35 @@ int main() { state.vk_ctx.linear_sampler = margaret_create_sampler(state.vk_ctx.physical_device, state.vk_ctx.device, true); state.vk_ctx.nearest_sampler = margaret_create_sampler(state.vk_ctx.physical_device, state.vk_ctx.device, false); - state.vk_ctx.descriptor_pool = margaret_create_descriptor_set_pool(state.vk_ctx.device, 1, 3, 2); - state.vk_ctx.descriptor_set_for_pipeline_0 = margaret_allocate_descriptor_set( - state.vk_ctx.device, state.vk_ctx.descriptor_pool, state.vk_ctx.pipeline_hands_0.descriptor_set_layout); + state.vk_ctx.descriptor_pool = margaret_create_descriptor_set_pool(state.vk_ctx.device, 2, 3, 3); + state.vk_ctx.descriptor_set_for_pipeline_0a = margaret_allocate_descriptor_set( + state.vk_ctx.device, state.vk_ctx.descriptor_pool, state.vk_ctx.pipeline_hands_0a.descriptor_set_layout); + state.vk_ctx.descriptor_set_for_pipeline_0b = margaret_allocate_descriptor_set( + state.vk_ctx.device, state.vk_ctx.descriptor_pool, state.vk_ctx.pipeline_hands_0b.descriptor_set_layout); state.vk_ctx.descriptor_set_for_pipeline_1 = margaret_allocate_descriptor_set( state.vk_ctx.device, state.vk_ctx.descriptor_pool, state.vk_ctx.pipeline_hands_1.descriptor_set_layout); // Configuring my descriptor sets, that I just allocated - VkDescriptorBufferInfo buffer_info_for_descriptor_0_in_set_0 = { + VkDescriptorBufferInfo buffer_info_for_descriptor_0_in_set_0a = { .buffer = state.vk_ctx.device_lighting_ubo.buffer, .offset = 0, .range = sizeof(Pipeline0UBO), }; - VkDescriptorImageInfo image_info_for_descriptor_1_in_set_0 = { + VkDescriptorImageInfo image_info_for_descriptor_1_in_set_0a = { .sampler = state.vk_ctx.linear_sampler, .imageView = state.vk_ctx.cyl_1_diffuse_texture_view, .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, }; - VkDescriptorImageInfo image_info_for_descriptor_2_in_set_0 = { + VkDescriptorImageInfo image_info_for_descriptor_2_in_set_0a = { .sampler = state.vk_ctx.nearest_sampler, .imageView = state.vk_ctx.cyl_1_normal_texture_view, .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, }; + VkDescriptorBufferInfo buffer_info_for_descriptor_0_in_set_0b = { + .buffer = state.vk_ctx.device_lighting_ubo.buffer, + .offset = 0, + .range = sizeof(Pipeline0UBO), + }; VkDescriptorImageInfo image_info_for_descriptor_0_in_set_1 = { .sampler = state.vk_ctx.nearest_sampler, .imageView = state.vk_ctx.IT1_view, @@ -1684,30 +2016,40 @@ int main() { VkWriteDescriptorSet writes_in_descriptor_sets[] = { { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = state.vk_ctx.descriptor_set_for_pipeline_0, + .dstSet = state.vk_ctx.descriptor_set_for_pipeline_0a, .dstBinding = 0, .dstArrayElement = 0, .descriptorCount = 1, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .pBufferInfo = &buffer_info_for_descriptor_0_in_set_0, + .pBufferInfo = &buffer_info_for_descriptor_0_in_set_0a, }, { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = state.vk_ctx.descriptor_set_for_pipeline_0, + .dstSet = state.vk_ctx.descriptor_set_for_pipeline_0a, .dstBinding = 1, .dstArrayElement = 0, .descriptorCount = 1, .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .pImageInfo = &image_info_for_descriptor_1_in_set_0, + .pImageInfo = &image_info_for_descriptor_1_in_set_0a, }, { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = state.vk_ctx.descriptor_set_for_pipeline_0, + .dstSet = state.vk_ctx.descriptor_set_for_pipeline_0a, .dstBinding = 2, .dstArrayElement = 0, .descriptorCount = 1, .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .pImageInfo = &image_info_for_descriptor_2_in_set_0, + .pImageInfo = &image_info_for_descriptor_2_in_set_0a, + }, + + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = state.vk_ctx.descriptor_set_for_pipeline_0b, + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .pBufferInfo = &buffer_info_for_descriptor_0_in_set_0b, }, { @@ -1722,9 +2064,6 @@ int main() { }; vkUpdateDescriptorSets(state.vk_ctx.device, ARRAY_SIZE(writes_in_descriptor_sets), writes_in_descriptor_sets, 0, NULL); - state.vk_ctx.my_cam_control_info = CamControlInfo_new(); - state.vk_ctx.Buba_control_info = (vec3){0}; - state.vk_ctx.jane = Jane_r0_create(state.vk_ctx.device); state.prev_key_frame_time = margaret_clock_gettime_monotonic_raw(); @@ -1762,12 +2101,34 @@ int main() { vkDestroyImage(state.vk_ctx.device, state.vk_ctx.device_IT1_image.image, NULL); vkDestroyImage(state.vk_ctx.device, state.vk_ctx.device_zbuffer_image.image, NULL); vkDestroyBuffer(state.vk_ctx.device, state.vk_ctx.device_lighting_ubo.buffer, NULL); - vkDestroyBuffer(state.vk_ctx.device, state.vk_ctx.device_instance_attrs_for_all_generic_meshes.buffer, NULL); - for (size_t i = 0; i < state.vk_ctx.device_ebo_and_vbo_buffers_for_generic_meshes.len; i++) + + vkDestroyBuffer(state.vk_ctx.device, state.vk_ctx.device_instance_attrs_for_models.buffer, NULL); + + for (size_t i = 0; i < state.vk_ctx.device_ebo_buffers_for_generic_meshes.len; i++) vkDestroyBuffer(state.vk_ctx.device, - VecMargaretBufferInMemoryInfo_at(&state.vk_ctx.device_ebo_and_vbo_buffers_for_generic_meshes, i)->buffer, + VecMargaretBufferInMemoryInfo_at(&state.vk_ctx.device_ebo_buffers_for_generic_meshes, i)->buffer, NULL); - VecMargaretBufferInMemoryInfo_drop(state.vk_ctx.device_ebo_and_vbo_buffers_for_generic_meshes); + VecMargaretBufferInMemoryInfo_drop(state.vk_ctx.device_ebo_buffers_for_generic_meshes); + + for (size_t i = 0; i < state.vk_ctx.device_vbo_buffers_for_generic_meshes.len; i++) + vkDestroyBuffer(state.vk_ctx.device, + VecMargaretBufferInMemoryInfo_at(&state.vk_ctx.device_vbo_buffers_for_generic_meshes, i)->buffer, + NULL); + VecMargaretBufferInMemoryInfo_drop(state.vk_ctx.device_vbo_buffers_for_generic_meshes); + + for (size_t i = 0; i < state.vk_ctx.device_ebo_buffers_for_shiny_meshes.len; i++) + vkDestroyBuffer(state.vk_ctx.device, + VecMargaretBufferInMemoryInfo_at(&state.vk_ctx.device_ebo_buffers_for_shiny_meshes, i)->buffer, + NULL); + VecMargaretBufferInMemoryInfo_drop(state.vk_ctx.device_ebo_buffers_for_shiny_meshes); + + for (size_t i = 0; i < state.vk_ctx.device_vbo_buffers_for_shiny_meshes.len; i++) + vkDestroyBuffer(state.vk_ctx.device, + VecMargaretBufferInMemoryInfo_at(&state.vk_ctx.device_vbo_buffers_for_shiny_meshes, i)->buffer, + NULL); + VecMargaretBufferInMemoryInfo_drop(state.vk_ctx.device_vbo_buffers_for_shiny_meshes); + + vkDestroyBuffer(state.vk_ctx.device, state.vk_ctx.host_mem_buffer.buffer, NULL); @@ -1779,7 +2140,8 @@ int main() { Jane_r0_destroy(state.vk_ctx.device, state.vk_ctx.jane); destroy_graphics_pipeline_hands(state.vk_ctx.device, state.vk_ctx.pipeline_hands_1); vkDestroyRenderPass(state.vk_ctx.device, state.vk_ctx.render_pass_1, NULL); - destroy_graphics_pipeline_hands(state.vk_ctx.device, state.vk_ctx.pipeline_hands_0); + destroy_graphics_pipeline_hands(state.vk_ctx.device, state.vk_ctx.pipeline_hands_0b); + destroy_graphics_pipeline_hands(state.vk_ctx.device, state.vk_ctx.pipeline_hands_0a); vkDestroyRenderPass(state.vk_ctx.device, state.vk_ctx.render_pass_0, NULL); vkDestroyDevice(state.vk_ctx.device, NULL); vkDestroySurfaceKHR(instance, state.vk_ctx.surface, NULL); diff --git a/src/l2/tests/r0/r0_assets.h b/src/l2/tests/r0/r0_assets.h index 166d0b0..980410c 100644 --- a/src/l2/tests/r0/r0_assets.h +++ b/src/l2/tests/r0/r0_assets.h @@ -13,59 +13,89 @@ typedef struct { vec3 pos; vec2 tex; } GenericMeshVertex; - -#include "../../../../gen/l2/eve/r0/VecGenericMeshVertex.h" +#include "../../../../gen/l2/eve/r0/VecAndSpan_GenericMeshVertex.h" typedef struct { VecGenericMeshVertex vertices; VecU32 indexes; -} ModelTopology; +} GenericMeshTopology; -void ModelTopology_drop(ModelTopology self) { +void GenericMeshTopology_drop(GenericMeshTopology self) { VecGenericMeshVertex_drop(self.vertices); VecU32_drop(self.indexes); } -ModelTopology ModelTopology_clone(const ModelTopology* self) { - return (ModelTopology){.vertices = VecGenericMeshVertex_clone(&self->vertices), .indexes = VecU32_clone(&self->indexes)}; +GenericMeshTopology GenericMeshTopology_clone(const GenericMeshTopology* self) { + return (GenericMeshTopology){.vertices = VecGenericMeshVertex_clone(&self->vertices), .indexes = VecU32_clone(&self->indexes)}; } typedef struct { - ModelTopology topology; + GenericMeshTopology topology; U32 max_instance_count; -} ModelInSceneTemplate; +} GenericMeshInSceneTemplate; -void ModelInSceneTemplate_drop(ModelInSceneTemplate self) { - ModelTopology_drop(self.topology); +void GenericMeshInSceneTemplate_drop(GenericMeshInSceneTemplate self) { + GenericMeshTopology_drop(self.topology); } -ModelInSceneTemplate ModelInSceneTemplate_clone(const ModelInSceneTemplate* self) { - return (ModelInSceneTemplate){.topology = ModelTopology_clone(&self->topology), .max_instance_count = self->max_instance_count}; +GenericMeshInSceneTemplate GenericMeshInSceneTemplate_clone(const GenericMeshInSceneTemplate* self) { + return (GenericMeshInSceneTemplate){.topology = GenericMeshTopology_clone(&self->topology), .max_instance_count = self->max_instance_count}; } -#include "../../../../gen/l2/eve/r0/VecModelInSceneTemplate.h" +#include "../../../../gen/l2/eve/r0/VecGenericMeshInSceneTemplate.h" typedef struct { mat4 model_t; } GenericMeshInstance; - #include "../../../../gen/l2/eve/r0/VecGenericMeshInstance.h" + + typedef struct { vec3 pos; vec3 normal; } ShinyMeshVertex; +#include "../../../../gen/l2/eve/r0/VecAndSpan_ShinyMeshVertex.h" -#include "../../../../gen/l2/eve/r0/VecShinyMeshVertex.h" +typedef struct { + VecShinyMeshVertex vertices; + VecU32 indexes; +} ShinyMeshTopology; + +void ShinyMeshTopology_drop(ShinyMeshTopology self) { + VecShinyMeshVertex_drop(self.vertices); + VecU32_drop(self.indexes); +} + +ShinyMeshTopology ShinyMeshTopology_clone(const ShinyMeshTopology* self) { + return (ShinyMeshTopology){.vertices = VecShinyMeshVertex_clone(&self->vertices), VecU32_clone(&self->indexes)}; +} + +typedef struct { + ShinyMeshTopology topology; + U32 max_instance_count; +} ShinyMeshInSceneTemplate; + +void ShinyMeshInSceneTemplate_drop(ShinyMeshInSceneTemplate self) { + ShinyMeshTopology_drop(self.topology); +} + +ShinyMeshInSceneTemplate ShinyMeshInSceneTemplate_clone(const ShinyMeshInSceneTemplate* self) { + return (ShinyMeshInSceneTemplate){.topology = ShinyMeshTopology_clone(&self->topology), + .max_instance_count = self->max_instance_count}; +} + +#include "../../../../gen/l2/eve/r0/VecShinyMeshInSceneTemplate.h" typedef struct { mat4 model_t; vec3 color_off; vec3 color_on; } ShinyMeshInstance; - #include "../../../../gen/l2/eve/r0/VecShinyMeshInstance.h" + + typedef struct { vec2 win_scale; } Pipeline1PushRangeVertex; @@ -87,7 +117,6 @@ typedef struct { float d; char _padding_3[12]; } Pipeline0Spotlight; - #include "../../../../gen/l2/eve/r0/VecPipeline0Spotlight.h" typedef struct { @@ -96,25 +125,29 @@ typedef struct { vec3 color; char _padding_1[4]; } Pipeline0PointLight; - #include "../../../../gen/l2/eve/r0/VecPipeline0PointLight.h" typedef struct { - VecModelInSceneTemplate models; + VecGenericMeshInSceneTemplate generic_models; + VecShinyMeshInSceneTemplate shiny_models; size_t point_lights_max_count; size_t spotlights_max_count; } SceneTemplate; void SceneTemplate_drop(SceneTemplate self) { - VecModelInSceneTemplate_drop(self.models); + VecGenericMeshInSceneTemplate_drop(self.generic_models); } 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_at(&self->models, mi); + for (size_t mi = 0; mi < self->generic_models.len; mi++) { + const GenericMeshInSceneTemplate* M = VecGenericMeshInSceneTemplate_at(&self->generic_models, mi); s += M->max_instance_count * sizeof(GenericMeshInstance); } + for (size_t mi = 0; mi < self->shiny_models.len; mi++) { + const ShinyMeshInSceneTemplate* M = VecShinyMeshInSceneTemplate_at(&self->shiny_models, mi); + s += M->max_instance_count * sizeof(ShinyMeshInstance); + } return s; } @@ -127,10 +160,14 @@ size_t SceneTemplate_get_space_needed_for_widest_state_transfer(const SceneTempl 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_at(&self->models, mi); + for (size_t mi = 0; mi < self->generic_models.len; mi++) { + const GenericMeshInSceneTemplate* M = VecGenericMeshInSceneTemplate_at(&self->generic_models, mi); s += M->topology.vertices.len * sizeof(GenericMeshVertex) + M->topology.indexes.len * sizeof(U32); } + for (size_t mi = 0; mi < self->shiny_models.len; mi++) { + const ShinyMeshInSceneTemplate* M = VecShinyMeshInSceneTemplate_at(&self->shiny_models, mi); + s += M->topology.vertices.len * sizeof(ShinyMeshVertex) + M->topology.indexes.len * sizeof(U32); + } return s; } @@ -145,7 +182,7 @@ typedef struct { Pipeline0Spotlight spotlight_arr[pipeline_0_ubo_spotlight_max_count]; } Pipeline0UBO; -size_t ModelTopology_get_space_needed_for_staging_buffer(const ModelTopology* self) { +size_t GenericMeshTopology_get_space_needed_for_staging_buffer(const GenericMeshTopology* self) { return MAX_U64(self->vertices.len * sizeof(GenericMeshVertex), self->indexes.len * sizeof(U32)); } @@ -177,7 +214,7 @@ void TextureDataR8_draw_spot_maxing(TextureDataR8* self, vec2 v, float r_cut, fl } } -ModelTopology generate_one_fourth_of_a_cylinder(float w, float r, U32 k) { +GenericMeshTopology generate_one_fourth_of_a_cylinder(float w, float r, U32 k) { assert(k >= 1); const float a = M_PI_2f / (float)k; const float l = 2 * r * sinf(M_PI_4f / (float)k); @@ -230,7 +267,7 @@ ModelTopology generate_one_fourth_of_a_cylinder(float w, float r, U32 k) { }; VecU32_append_span(&indexes, (SpanU32){.data = _span_1, .len = ARRAY_SIZE(_span_1)}); } - return (ModelTopology){.vertices = vertices, .indexes = indexes}; + return (GenericMeshTopology){.vertices = vertices, .indexes = indexes}; } vec2 perimeter_line_get_thorn_on_vertex(Spanvec2 P, size_t i, float thickness) { @@ -637,5 +674,117 @@ TextureDataR8G8B8 generate_normal_tex_for_one_fourth_of_a_cylinder(float s_resol return res; } +U32 quad_to_triangles_conv_arr[6] = {0, 1, 2, 0, 2, 3}; + +ShinyMeshTopology generate_shiny_cube(float r) { + ShinyMeshVertex vert[24] = { + {{+r, +r, +r}, {1, 0, 0}}, + {{+r, -r, +r}, {1, 0, 0}}, + {{+r, -r, -r}, {1, 0, 0}}, + {{+r, +r, -r}, {1, 0, 0}}, + + {{-r, -r, -r}, {-1, 0, 0}}, + {{-r, -r, +r}, {-1, 0, 0}}, + {{-r, +r, +r}, {-1, 0, 0}}, + {{-r, +r, -r}, {-1, 0, 0}}, + + {{+r, +r, +r}, {0, 1, 0}}, + {{+r, +r, -r}, {0, 1, 0}}, + {{-r, +r, -r}, {0, 1, 0}}, + {{-r, +r, +r}, {0, 1, 0}}, + + {{-r, -r, -r}, {0, -1, 0}}, + {{+r, -r, -r}, {0, -1, 0}}, + {{+r, -r, +r}, {0, -1, 0}}, + {{-r, -r, +r}, {0, -1, 0}}, + + {{+r, +r, +r}, {0, 0, 1}}, + {{-r, +r, +r}, {0, 0, 1}}, + {{-r, -r, +r}, {0, 0, 1}}, + {{+r, -r, +r}, {0, 0, 1}}, + + {{-r, -r, -r}, {0, 0, -1}}, + {{-r, +r, -r}, {0, 0, -1}}, + {{+r, +r, -r}, {0, 0, -1}}, + {{+r, -r, -r}, {0, 0, -1}}, + }; + VecShinyMeshVertex vertices_vec = VecShinyMeshVertex_new_zeroinit(24); + memcpy(vertices_vec.buf, vert, sizeof(vert)); + VecU32 indexes_vec = VecU32_new_reserved(36); + for (U32 f = 0; f < 6; f++) { + for (U32 j = 0; j < 6; j++) + VecU32_append(&indexes_vec, f * 4 + quad_to_triangles_conv_arr[j]); + } + return (ShinyMeshTopology){ .vertices = vertices_vec, .indexes = indexes_vec}; +} + +typedef struct { + int face; + /* There is a counterclockwise one-to-one correspondence between vertexes of face and edges of face */ + int vert_on_it; +} CubeVertOfFace; + +CubeVertOfFace CubeVertOfFace_jump(CubeVertOfFace vert) { + const CubeVertOfFace cube_detour_get_neighbour_face[6][4] = { + {{4, 3}, {3, 1}, {5, 2}, {2, 0}}, + {{3, 3}, {4, 1}, {2, 2}, {5, 0}}, + {{0, 3}, {5, 1}, {1, 2}, {4, 0}}, + {{5, 3}, {0, 1}, {4, 2}, {1, 0}}, + {{2, 3}, {1, 1}, {3, 2}, {0, 0}}, + {{1, 3}, {2, 1}, {0, 2}, {3, 0}} + }; + return cube_detour_get_neighbour_face[vert.face][vert.vert_on_it]; +} + +U32 CubeVertOfFace_to_vid(CubeVertOfFace vert) { + return 4 * vert.face + vert.vert_on_it; +} + +CubeVertOfFace CubeVertOfFace_next(CubeVertOfFace vert) { + return (CubeVertOfFace){vert.face, (vert.vert_on_it + 1) % 4}; +} + +ShinyMeshTopology generate_shiny_rhombicuboctahedron(float r) { + ShinyMeshTopology res = generate_shiny_cube(r); + for (int f = 0; f < 6; f++) { + vec3 growth = vec3_mul_scal((*VecShinyMeshVertex_at(&res.vertices, f * 4)).normal, M_SQRT1_2); + for (int i = 0; i < 4; i++) { + vec3* pos = &VecShinyMeshVertex_mat(&res.vertices, f * 4 + i)->pos; + *pos = vec3_add_vec3(*pos, growth); + } + } + for (int f = 0; f < 6; f++) { + for (int i = 0; i < 2; i++) { + CubeVertOfFace vof = {f, 2*i+(f%2)}; + ShinyMeshVertex A = *VecShinyMeshVertex_at(&res.vertices, CubeVertOfFace_to_vid(vof)); + ShinyMeshVertex B = *VecShinyMeshVertex_at(&res.vertices, CubeVertOfFace_to_vid(CubeVertOfFace_next(CubeVertOfFace_jump(vof)))); + ShinyMeshVertex C = *VecShinyMeshVertex_at(&res.vertices, CubeVertOfFace_to_vid(CubeVertOfFace_jump(vof))); + ShinyMeshVertex D = *VecShinyMeshVertex_at(&res.vertices, CubeVertOfFace_to_vid(CubeVertOfFace_next(vof))); + vec3 norm = vec3_normalize(vec3_add_vec3(A.normal, B.normal)); + ShinyMeshVertex quad_v[4] = {{A.pos, norm}, {B.pos, norm}, {C.pos, norm}, {D.pos, norm}}; + size_t b = res.vertices.len; + VecShinyMeshVertex_append_span(&res.vertices, (SpanShinyMeshVertex){quad_v, ARRAY_SIZE(quad_v)}); + for (U32 j = 0; j < 6; j++) + VecU32_append(&res.indexes, b + quad_to_triangles_conv_arr[j]); + } + } + for (int f = 0; f < 2; f++) { + for (int e = 0; e < 4; e++) { + CubeVertOfFace vof = {f, e}; + ShinyMeshVertex A = *VecShinyMeshVertex_at(&res.vertices, CubeVertOfFace_to_vid(CubeVertOfFace_next(vof))); + ShinyMeshVertex B = *VecShinyMeshVertex_at(&res.vertices, CubeVertOfFace_to_vid(CubeVertOfFace_jump(vof))); + ShinyMeshVertex C = *VecShinyMeshVertex_at(&res.vertices, + CubeVertOfFace_to_vid(CubeVertOfFace_next(CubeVertOfFace_jump(CubeVertOfFace_next(vof))))); + vec3 norm = vec3_normalize(vec3_add_vec3(A.normal, vec3_add_vec3(B.normal, C.normal))); + + ShinyMeshVertex ang_v[3] = {{A.pos, norm}, {B.pos, norm}, {C.pos, norm}}; + size_t b = res.vertices.len; + VecShinyMeshVertex_append_span(&res.vertices, (SpanShinyMeshVertex){ang_v, ARRAY_SIZE(ang_v)}); + for (int i = 0; i < 3; i++) + VecU32_append(&res.indexes, b + i); + } + } + return res; +} #endif diff --git a/src/l2/tests/r0/r0_scene.h b/src/l2/tests/r0/r0_scene.h index 68d35c9..e8e9f39 100644 --- a/src/l2/tests/r0/r0_scene.h +++ b/src/l2/tests/r0/r0_scene.h @@ -9,31 +9,34 @@ typedef struct { VkBuffer vbo; VkBuffer ebo; size_t indexes; -} ModelOnScene; - -#include "../../../../gen/l2/eve/r0/VecModelOnScene.h" - -/* Contains both data for model instances attributes and buffer (+offset) where it is stored */ -typedef struct { - ModelOnScene model; - VecGenericMeshInstance instances; VkBuffer instance_attr_buf; VkDeviceSize instance_attr_buf_offset; U32 limit_max_instance_count; -} UsedModelOnScene; +} ModelOnSceneMem; -void UsedModelOnScene_drop(UsedModelOnScene self) { +/* Contains both data for model instances attributes and buffer (+offset) where it is stored */ +/* Also, I made it non-clonable. Thus */ +typedef struct { + ModelOnSceneMem model; + VecGenericMeshInstance instances; +} UsedGenericModelOnScene; + +void UsedGenericModelOnScene_drop(UsedGenericModelOnScene 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 - }; +#include "../../../../gen/l2/eve/r0/VecUsedGenericModelOnScene.h" + +typedef struct { + ModelOnSceneMem model; + VecShinyMeshInstance instances; +} UsedShinyModelOnScene; + +void UsedShinyModelOnScene_drop(UsedShinyModelOnScene self) { + VecShinyMeshInstance_drop(self.instances); } -#include "../../../../gen/l2/eve/r0/VecUsedModelOnScene.h" +#include "../../../../gen/l2/eve/r0/VecUsedShinyModelOnScene.h" typedef struct { float fov; @@ -85,8 +88,10 @@ void CamControlInfo_update_direction(CamControlInfo* self, int win_width, int wi self->cam_basis = marie_simple_camera_rot_m_basis_in_cols(yaw, pitch, 0); } +/* Non copyable */ typedef struct { - VecUsedModelOnScene models; + VecUsedGenericModelOnScene generic_models; + VecUsedShinyModelOnScene shiny_models; VkClearColorValue color; float gamma_correction_factor; float hdr_factor; @@ -97,13 +102,16 @@ typedef struct { } Scene; Scene Scene_new() { - return (Scene){.models = VecUsedModelOnScene_new(), .color = {.float32 = {0, 0, 0, 1}}, - .gamma_correction_factor = 2.2f, .hdr_factor = 1, .lsd_factor = 0, .anim_time = 0, - .spotlights = VecPipeline0Spotlight_new(), .point_lights = VecPipeline0PointLight_new()}; + return (Scene){.generic_models = VecUsedGenericModelOnScene_new(), .shiny_models = VecUsedShinyModelOnScene_new(), + .color = {.float32 = {0, 0, 0, 1}}, + .gamma_correction_factor = 2.2f, .hdr_factor = 1, .lsd_factor = 0, .anim_time = 0, + .spotlights = VecPipeline0Spotlight_new(), .point_lights = VecPipeline0PointLight_new() + }; } void Scene_drop(Scene self) { - VecUsedModelOnScene_drop(self.models); + VecUsedGenericModelOnScene_drop(self.generic_models); + VecUsedShinyModelOnScene_drop(self.shiny_models); VecPipeline0Spotlight_drop(self.spotlights); VecPipeline0PointLight_drop(self.point_lights); } @@ -112,7 +120,8 @@ 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); + assert(scene_template->generic_models.len == scene->generic_models.len); + assert(scene_template->shiny_models.len == scene->shiny_models.len); if (vkResetCommandBuffer(command_buffer, 0) != VK_SUCCESS) abortf("vkResetCommandBuffer"); @@ -123,19 +132,32 @@ void SceneTemplate_copy_initial_model_topology_and_rerecord_transfer_cmd( 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_at(&scene_template->models, mi); - const UsedModelOnScene* m_buf = VecUsedModelOnScene_at(&scene->models, mi); + for (size_t mi = 0; mi < scene_template->generic_models.len; mi++) { + const GenericMeshInSceneTemplate* mt = VecGenericMeshInSceneTemplate_at(&scene_template->generic_models, mi); + const ModelOnSceneMem *m_buf = &VecUsedGenericModelOnScene_at(&scene->generic_models, mi)->model; 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); + vkCmdCopyBuffer(command_buffer, host_memory_buffer, m_buf->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); + vkCmdCopyBuffer(command_buffer, host_memory_buffer, m_buf->ebo, 1, &rb); + offset += ebo_len; + } + for (size_t mi = 0; mi < scene_template->shiny_models.len; mi++) { + const ShinyMeshInSceneTemplate* mt = VecShinyMeshInSceneTemplate_at(&scene_template->shiny_models, mi); + const ModelOnSceneMem *m_buf = &VecUsedShinyModelOnScene_at(&scene->shiny_models, mi)->model; + size_t vbo_len = mt->topology.vertices.len * sizeof(ShinyMeshVertex); + 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->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->ebo, 1, &rb); offset += ebo_len; } diff --git a/src/l2/tests/r0/shaders/glsl/0/0.frag b/src/l2/tests/r0/shaders/glsl/0/0.frag index aee790f..2f8b360 100644 --- a/src/l2/tests/r0/shaders/glsl/0/0.frag +++ b/src/l2/tests/r0/shaders/glsl/0/0.frag @@ -58,4 +58,6 @@ void main(){ // todo: add specular map texture vec3 color = natural_color * diffuse_illumination + 0.5 * specular_illumination; fin_color = vec4(color, 1); + // fin_color = vec4(length(norm) / 2, 0, 0, 1); + fin_color = vec4(fsin_tex, 0, 1); } diff --git a/src/l2/tests/r0/shaders/glsl/0b/0b.frag b/src/l2/tests/r0/shaders/glsl/0b/0b.frag index 67b83d6..2e0fa37 100644 --- a/src/l2/tests/r0/shaders/glsl/0b/0b.frag +++ b/src/l2/tests/r0/shaders/glsl/0b/0b.frag @@ -52,4 +52,5 @@ void main(){ } vec3 color = color_off * diffuse_illumination + 0.5 * specular_illumination + color_on; fin_color = vec4(color, 1); + // fin_color = vec4(length(norm) / 2, 0, 0, 1); } diff --git a/src/l2/tests/r2/r2b.c b/src/l2/tests/r2/r2b.c index de3f655..8fa5da2 100644 --- a/src/l2/tests/r2/r2b.c +++ b/src/l2/tests/r2/r2b.c @@ -320,7 +320,6 @@ int main() { } else { printf("?\n"); } - } safe_pthread_join(th);