From e6a776665f52fabd42b0adce25fe1595064bb542 Mon Sep 17 00:00:00 2001 From: Xiang Silian Date: Mon, 20 Oct 2025 15:27:33 +0800 Subject: [PATCH] =?UTF-8?q?=E7=8E=B0=E5=9C=A8=E6=89=8D=E6=98=AF=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=AE=8C=E6=88=90=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vulkan/AppBase.cpp | 33 ++++ vulkan/AppBase.h | 1 + vulkan/Application.cpp | 8 +- vulkan/Application.h | 5 +- vulkan/FaceApp.cpp | 432 ++++++++++++++++++++++++++--------------- vulkan/FaceApp.h | 11 +- 6 files changed, 323 insertions(+), 167 deletions(-) diff --git a/vulkan/AppBase.cpp b/vulkan/AppBase.cpp index a28ce81..0beef78 100644 --- a/vulkan/AppBase.cpp +++ b/vulkan/AppBase.cpp @@ -22,6 +22,39 @@ void VK_CHECK(VkResult ret) // return path; //} +std::vector AppBase::readFileEx(const std::string& path) +{ + std::vector buffer; +#ifdef _WIN32 + std::string enginePath = "app/src/main/assets/" + path; + std::ifstream file{ enginePath, std::ios::ate | std::ios::binary }; + + if (!file.is_open()) + { + throw std::runtime_error("failed to open file: " + enginePath); + } + + size_t fileSize = static_cast(file.tellg()); + buffer.resize(fileSize); + + file.seekg(0); + file.read((char*)buffer.data(), fileSize); + file.close(); +#else + AAsset* asset = AAssetManager_open(g_assetManager, path.c_str(), AASSET_MODE_BUFFER); + if (!asset) { + logOut << "Failed to load file: " << path.c_str() << std::endl; + return buffer; + } + + size_t length = AAsset_getLength(asset); + buffer.resize(length); + AAsset_read(asset, (char*)buffer.data(), length); + AAsset_close(asset); +#endif // _WIN32 + return buffer; +} + std::vector AppBase::readFile(const std::string& path) { std::vector buffer; diff --git a/vulkan/AppBase.h b/vulkan/AppBase.h index 5ee3f62..c2d7651 100644 --- a/vulkan/AppBase.h +++ b/vulkan/AppBase.h @@ -55,6 +55,7 @@ class AppBase { public: std::vector readFile(const std::string& enginePath); + std::vector readFileEx(const std::string& enginePath); //std::string getPath(const std::string path); VkShaderModule createShaderModule(VkDevice& device, const std::vector& code); const std::vector validationLayers = {"VK_LAYER_KHRONOS_validation"}; diff --git a/vulkan/Application.cpp b/vulkan/Application.cpp index 131afb6..008d201 100644 --- a/vulkan/Application.cpp +++ b/vulkan/Application.cpp @@ -652,12 +652,12 @@ uint32_t Application::findMemoryType(VkPhysicalDevice physicalDevice, uint32_t t throw std::runtime_error("Failed to find suitable memory type!"); } -Texture Application::loadTexture(std::string path, Texture tex) +Texture Application::loadTexture(std::string path, Texture& tex) { - std::vector data = readFile(path); + std::vector data = readFileEx(path); std::vector image; unsigned w, h; - unsigned error = lodepng::decode(image, w, h, data.data(), LCT_RGBA, 8); + unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8); processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, true); return tex; } @@ -770,7 +770,7 @@ void Application::processWithVulkan(uint8_t* data, int width, int height, int ro } - updateTexture(device, physicalDevice, commandPool, queue, data, width, height, + updateTexture(device, physicalDevice, commandPool, graphicsQueue, data, width, height, rowStride, dataSize, out_texture); } diff --git a/vulkan/Application.h b/vulkan/Application.h index fdc66b5..ccb3a73 100644 --- a/vulkan/Application.h +++ b/vulkan/Application.h @@ -43,7 +43,7 @@ public: void createSyncObjects(); void drawFrame(); virtual void render(VkCommandBuffer commandBuffer); - bool isInited() { return inited; } + virtual bool isInited() { return inited; } protected: @@ -73,7 +73,7 @@ protected: bool inited = false; protected: - Texture loadTexture(std::string path, Texture tex); + Texture loadTexture(std::string path, Texture& tex); void processWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& out_texture, bool srgb); uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter, VkMemoryPropertyFlags properties); @@ -83,6 +83,5 @@ protected: void endSingleTimeCommands(VkDevice device, VkCommandPool commandPool, VkQueue queue, VkCommandBuffer commandBuffer); void transitionImageLayout(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout); void destroy_texture(Texture texture); - VkQueue queue; std::mutex mtx; }; \ No newline at end of file diff --git a/vulkan/FaceApp.cpp b/vulkan/FaceApp.cpp index 5f7f473..d0e7edd 100644 --- a/vulkan/FaceApp.cpp +++ b/vulkan/FaceApp.cpp @@ -2,98 +2,7 @@ #include "hardcode_data.h" #include -inline VkDescriptorSetLayoutBinding descriptor_set_layout_binding( - VkDescriptorType type, - VkShaderStageFlags flags, - uint32_t binding, - uint32_t count = 1) -{ - VkDescriptorSetLayoutBinding set_layout_binding{}; - set_layout_binding.descriptorType = type; - set_layout_binding.stageFlags = flags; - set_layout_binding.binding = binding; - set_layout_binding.descriptorCount = count; - return set_layout_binding; -} -inline VkDescriptorSetLayoutCreateInfo descriptor_set_layout_create_info( - const VkDescriptorSetLayoutBinding* bindings, - uint32_t binding_count) -{ - VkDescriptorSetLayoutCreateInfo descriptor_set_layout_create_info{}; - descriptor_set_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - descriptor_set_layout_create_info.pBindings = bindings; - descriptor_set_layout_create_info.bindingCount = binding_count; - return descriptor_set_layout_create_info; -} - -inline VkPipelineLayoutCreateInfo fun_pipeline_layout_create_info( - const VkDescriptorSetLayout* set_layouts, - uint32_t set_layout_count = 1) -{ - VkPipelineLayoutCreateInfo pipeline_layout_create_info{}; - pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipeline_layout_create_info.setLayoutCount = set_layout_count; - pipeline_layout_create_info.pSetLayouts = set_layouts; - return pipeline_layout_create_info; -} - -inline VkDescriptorSetAllocateInfo descriptor_set_allocate_info( - VkDescriptorPool descriptor_pool, - const VkDescriptorSetLayout* set_layouts, - uint32_t descriptor_set_count) -{ - VkDescriptorSetAllocateInfo descriptor_set_allocate_info{}; - descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - descriptor_set_allocate_info.descriptorPool = descriptor_pool; - descriptor_set_allocate_info.pSetLayouts = set_layouts; - descriptor_set_allocate_info.descriptorSetCount = descriptor_set_count; - return descriptor_set_allocate_info; -} - -VkDescriptorBufferInfo create_descriptor(VkBuffer buffer, VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0) -{ - VkDescriptorBufferInfo descriptor{}; - descriptor.buffer = buffer; - descriptor.range = size; - descriptor.offset = offset; - return descriptor; -} - -inline VkWriteDescriptorSet write_descriptor_set( - VkDescriptorSet dst_set, - VkDescriptorType type, - uint32_t binding, - VkDescriptorBufferInfo* buffer_info, - uint32_t descriptor_count = 1) -{ - VkWriteDescriptorSet write_descriptor_set{}; - write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptor_set.dstSet = dst_set; - write_descriptor_set.descriptorType = type; - write_descriptor_set.dstBinding = binding; - write_descriptor_set.pBufferInfo = buffer_info; - write_descriptor_set.descriptorCount = descriptor_count; - return write_descriptor_set; -} - - -inline VkWriteDescriptorSet write_descriptor_set( - VkDescriptorSet dst_set, - VkDescriptorType type, - uint32_t binding, - VkDescriptorImageInfo* image_info, - uint32_t descriptor_count = 1) -{ - VkWriteDescriptorSet write_descriptor_set{}; - write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptor_set.dstSet = dst_set; - write_descriptor_set.descriptorType = type; - write_descriptor_set.dstBinding = binding; - write_descriptor_set.pImageInfo = image_info; - write_descriptor_set.descriptorCount = descriptor_count; - return write_descriptor_set; -} FaceApp* FaceApp::faceIns = nullptr; @@ -251,6 +160,194 @@ bool FaceApp::LoadOBJ(const std::string& filename, return true; } + +void FaceApp::create_face_pipelines() +{ + VkPipelineInputAssemblyStateCreateInfo input_assembly_state{}; + input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + input_assembly_state.flags = 0; + input_assembly_state.primitiveRestartEnable = VK_FALSE; + + + VkPipelineRasterizationStateCreateInfo rasterization_state{}; + rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterization_state.polygonMode = VK_POLYGON_MODE_FILL; + rasterization_state.cullMode = VK_CULL_MODE_NONE; + rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + rasterization_state.flags = 0; + rasterization_state.depthClampEnable = VK_FALSE; + rasterization_state.lineWidth = 1.0f; + + rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT; + rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + + + + VkPipelineColorBlendAttachmentState colorBlendAttachment{}; + colorBlendAttachment.blendEnable = VK_TRUE; + colorBlendAttachment.colorWriteMask = + VK_COLOR_COMPONENT_R_BIT | + VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | + VK_COLOR_COMPONENT_A_BIT; + + // 常用的Alpha混合公式 + colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; + colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD; + colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; + + + + VkPipelineColorBlendStateCreateInfo colorBlending{}; + colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + colorBlending.logicOpEnable = VK_FALSE; + colorBlending.attachmentCount = 1; + colorBlending.pAttachments = &colorBlendAttachment; + + // Note: Using reversed depth-buffer for increased precision, so Greater depth values are kept + VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {}; + + depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + depth_stencil_state.depthTestEnable = VK_TRUE; + depth_stencil_state.depthWriteEnable = VK_TRUE; + depth_stencil_state.depthCompareOp = VK_COMPARE_OP_GREATER; + depth_stencil_state.front = depth_stencil_state.back; + depth_stencil_state.back.compareOp = VK_COMPARE_OP_ALWAYS; + + + VkPipelineViewportStateCreateInfo viewport_state{}; + viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewport_state.viewportCount = 1; + viewport_state.scissorCount = 1; + viewport_state.flags = 0; + + + VkPipelineMultisampleStateCreateInfo multisample_state{}; + multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + multisample_state.flags = 0; + + // 动态定义视口和剪裁,暂时用不到 + //std::vector dynamic_state_enables = { + // VK_DYNAMIC_STATE_VIEWPORT, + // VK_DYNAMIC_STATE_SCISSOR }; + + + //VkPipelineDynamicStateCreateInfo dynamic_state{}; + //dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + //dynamic_state.pDynamicStates = dynamic_state_enables.data(); + //dynamic_state.dynamicStateCount = static_cast(dynamic_state_enables.size()); + //dynamic_state.flags = 0; + + // 视口状态 + VkViewport viewport{}; + viewport.x = 0.0f; + viewport.y = 0.0f; + viewport.width = (float)swapChainExtent.width; + viewport.height = (float)swapChainExtent.height; + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + + VkRect2D scissor{}; + scissor.offset = { 0, 0 }; + scissor.extent = swapChainExtent; + + VkPipelineViewportStateCreateInfo viewportState{}; + viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewportState.viewportCount = 1; + viewportState.pViewports = &viewport; + viewportState.scissorCount = 1; + viewportState.pScissors = &scissor; + + + auto vertShaderCode = readFile("shaders/texture.vert.spv"); + auto fragShaderCode = readFile("shaders/texture.frag.spv"); + + VkShaderModule vertShaderModule = createShaderModule(this->device, vertShaderCode); + VkShaderModule fragShaderModule = createShaderModule(this->device, fragShaderCode); + + VkPipelineShaderStageCreateInfo vertShaderStageInfo{}; + vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; + vertShaderStageInfo.module = vertShaderModule; + vertShaderStageInfo.pName = "main"; + + VkPipelineShaderStageCreateInfo fragShaderStageInfo{}; + fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + fragShaderStageInfo.module = fragShaderModule; + fragShaderStageInfo.pName = "main"; + + VkPipelineShaderStageCreateInfo shader_stages[] = { vertShaderStageInfo, fragShaderStageInfo }; + + // Vertex bindings and attributes + std::vector vertex_input_bindings{};; + + VkVertexInputBindingDescription vertex_input_binding_description{}; + vertex_input_binding_description.binding = 0; + vertex_input_binding_description.stride = sizeof(TextureLoadingVertexStructure); + vertex_input_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + vertex_input_bindings.push_back(vertex_input_binding_description); + + + std::vector vertex_input_attributes{}; + + VkVertexInputAttributeDescription viaPos{}; + viaPos.location = 0; + viaPos.binding = 0; + viaPos.format = VK_FORMAT_R32G32B32_SFLOAT; + viaPos.offset = offsetof(TextureLoadingVertexStructure, pos); + vertex_input_attributes.push_back(viaPos); + + VkVertexInputAttributeDescription viaUv{}; + viaUv.location = 0; + viaUv.binding = 1; + viaUv.format = VK_FORMAT_R32G32_SFLOAT; + viaUv.offset = offsetof(TextureLoadingVertexStructure, uv); + vertex_input_attributes.push_back(viaUv); + + VkVertexInputAttributeDescription viaNormal{}; + viaNormal.location = 0; + viaNormal.binding = 2; + viaNormal.format = VK_FORMAT_R32G32B32_SFLOAT; + viaNormal.offset = offsetof(TextureLoadingVertexStructure, normal); + vertex_input_attributes.push_back(viaNormal); + + + VkPipelineVertexInputStateCreateInfo vertex_input_state{}; + vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertex_input_state.vertexBindingDescriptionCount = static_cast(vertex_input_bindings.size()); + vertex_input_state.pVertexBindingDescriptions = vertex_input_bindings.data(); + vertex_input_state.vertexAttributeDescriptionCount = static_cast(vertex_input_attributes.size()); + vertex_input_state.pVertexAttributeDescriptions = vertex_input_attributes.data(); + + VkGraphicsPipelineCreateInfo pipeline_create_info{}; + pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipeline_create_info.layout = m_pipelineLayout; + pipeline_create_info.renderPass = renderPass; + pipeline_create_info.flags = 0; + pipeline_create_info.basePipelineIndex = -1; + pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE; + + pipeline_create_info.pVertexInputState = &vertex_input_state; + pipeline_create_info.pInputAssemblyState = &input_assembly_state; + pipeline_create_info.pRasterizationState = &rasterization_state; + pipeline_create_info.pColorBlendState = &colorBlending; //&color_blend_state; + pipeline_create_info.pMultisampleState = &multisample_state; + pipeline_create_info.pViewportState = &viewport_state; + pipeline_create_info.pDepthStencilState = &depth_stencil_state; + //pipeline_create_info.pDynamicState = &dynamic_state; + pipeline_create_info.pViewportState = &viewportState; + pipeline_create_info.stageCount = 2; + pipeline_create_info.pStages = shader_stages; + + VK_CHECK(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, &m_graphicsPipeline)); +} + void FaceApp::setup_descriptor_pool() { VkDescriptorPoolSize descriptor_pool_size{}; @@ -280,31 +377,35 @@ void FaceApp::setup_descriptor_pool() void FaceApp::setup_descriptor_set_layout() { - std::vector set_layout_bindings = - { - // Binding 0 : Vertex shader uniform buffer - descriptor_set_layout_binding( - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - VK_SHADER_STAGE_VERTEX_BIT, - 0), - // Binding 1 : Fragment shader image sampler - descriptor_set_layout_binding( - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - VK_SHADER_STAGE_FRAGMENT_BIT, - 1) }; + - VkDescriptorSetLayoutCreateInfo descriptor_layout = - descriptor_set_layout_create_info( - set_layout_bindings.data(), - static_cast(set_layout_bindings.size())); + VkDescriptorSetLayoutBinding set_layout_binding_vertex{}; + set_layout_binding_vertex.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + set_layout_binding_vertex.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + set_layout_binding_vertex.binding = 0; + set_layout_binding_vertex.descriptorCount = 1; + + VkDescriptorSetLayoutBinding set_layout_binding_fragment{}; + set_layout_binding_fragment.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + set_layout_binding_fragment.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + set_layout_binding_fragment.binding = 2; + set_layout_binding_fragment.descriptorCount = 1; + + std::vector set_layout_bindings{ set_layout_binding_vertex , set_layout_binding_fragment}; + + + VkDescriptorSetLayoutCreateInfo descriptor_layout{}; + descriptor_layout.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + descriptor_layout.pBindings = set_layout_bindings.data(); + descriptor_layout.bindingCount = static_cast(set_layout_bindings.size()); VK_CHECK(vkCreateDescriptorSetLayout(device, &descriptor_layout, nullptr, &m_descriptorSetLayout)); - VkPipelineLayoutCreateInfo pipeline_layout_create_info = - fun_pipeline_layout_create_info( - &m_descriptorSetLayout, - 1); + VkPipelineLayoutCreateInfo pipeline_layout_create_info{}; + pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipeline_layout_create_info.setLayoutCount = 1; + pipeline_layout_create_info.pSetLayouts = &m_descriptorSetLayout; VkPushConstantRange pushConstantRange{}; pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; // 只在片段着色器中使用 @@ -319,15 +420,19 @@ void FaceApp::setup_descriptor_set_layout() void FaceApp::setup_descriptor_set() { - VkDescriptorSetAllocateInfo alloc_info = - descriptor_set_allocate_info( - descriptor_pool, - &m_descriptorSetLayout, - 1); + + VkDescriptorSetAllocateInfo alloc_info{}; + alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + alloc_info.descriptorPool = descriptor_pool; + alloc_info.pSetLayouts = &m_descriptorSetLayout; + alloc_info.descriptorSetCount = 1; VK_CHECK(vkAllocateDescriptorSets(device, &alloc_info, &m_descriptor_set)); - VkDescriptorBufferInfo buffer_descriptor = create_descriptor(uniform_buffer_vs); + VkDescriptorBufferInfo buffer_descriptor{}; + buffer_descriptor.buffer = uniform_buffer_vs; + buffer_descriptor.range = VK_WHOLE_SIZE; + buffer_descriptor.offset = 0; VkDescriptorImageInfo image_descriptor; @@ -335,21 +440,27 @@ void FaceApp::setup_descriptor_set() image_descriptor.sampler = tex_demo0.sampler; // The sampler (Telling the pipeline how to sample the texture, including repeat, border, etc.) image_descriptor.imageLayout = tex_demo0.image_layout; // The current layout of the image (Note: Should always fit the actual use, e.g. shader read) + VkWriteDescriptorSet write_descriptor_set_uniform{}; + write_descriptor_set_uniform.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptor_set_uniform.dstSet = m_descriptor_set; + write_descriptor_set_uniform.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + write_descriptor_set_uniform.dstBinding = 0; + write_descriptor_set_uniform.pBufferInfo = &buffer_descriptor; + write_descriptor_set_uniform.descriptorCount = 1; + + + VkWriteDescriptorSet write_descriptor_set_image{}; + write_descriptor_set_image.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptor_set_image.dstSet = m_descriptor_set; + write_descriptor_set_image.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + write_descriptor_set_image.dstBinding = 1; + write_descriptor_set_image.pImageInfo = &image_descriptor; + write_descriptor_set_image.descriptorCount = 1; + std::vector write_descriptor_sets = { - // Binding 0 : Vertex shader uniform buffer - write_descriptor_set( - m_descriptor_set, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 0, - &buffer_descriptor), - // Binding 1 : Fragment shader texture sampler - // Fragment shader: layout (binding = 1) uniform sampler2D samplerColor; - write_descriptor_set( - m_descriptor_set, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // The descriptor set will use a combined image sampler (sampler and image could be split) - 1, // Shader binding point 1 - &image_descriptor) // Pointer to the descriptor image for our texture + write_descriptor_set_uniform, + write_descriptor_set_image }; vkUpdateDescriptorSets(device, static_cast(write_descriptor_sets.size()), write_descriptor_sets.data(), 0, NULL); @@ -376,14 +487,19 @@ void FaceApp::render(VkCommandBuffer commandBuffer) #endif } +void FaceApp::createVmaAllocator() +{ + VmaAllocatorCreateInfo allocatorInfo = {}; + allocatorInfo.physicalDevice = physicalDevice; + allocatorInfo.device = device; + allocatorInfo.instance = instance; + vmaCreateAllocator(&allocatorInfo, &allocator); +} + void FaceApp::initVulkan() { Application::initVulkan(); - VmaAllocatorCreateInfo allocatorInfo = {}; - allocatorInfo.physicalDevice = physicalDevice; - allocatorInfo.device = device; - allocatorInfo.instance = instance; - vmaCreateAllocator(&allocatorInfo, &allocator); + createVmaAllocator(); LoadOBJ("face_picture_3dmax.obj", obj_vertices, obj_indices); loadTexture("demo0.png", tex_demo0); createVertexBuffer(); @@ -391,7 +507,9 @@ void FaceApp::initVulkan() setup_descriptor_pool(); setup_descriptor_set_layout(); setup_descriptor_set(); + create_face_pipelines(); uploadVertexData(); + faceAppInited = true; } void FaceApp::update_uniform_buffers() @@ -415,8 +533,8 @@ void FaceApp::update_uniform_buffers() void FaceApp::createVertexBuffer() { - VkDeviceSize vertexBufferSize = sizeof(TextureLoadingVertexStructure) * obj_vertices.capacity(); - VkDeviceSize indexBufferSize = sizeof(uint32_t) * obj_indices.capacity(); + VkDeviceSize vertexBufferSize = sizeof(TextureLoadingVertexStructure) * obj_vertices.size(); + VkDeviceSize indexBufferSize = sizeof(uint32_t) * obj_indices.size(); // 创建顶点缓冲区(设备本地,用于渲染) VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; @@ -425,7 +543,7 @@ void FaceApp::createVertexBuffer() bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; VmaAllocationCreateInfo allocInfo = {}; - allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; + allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &m_vertexBuffer, &m_vertexBufferAllocation, nullptr); @@ -438,11 +556,30 @@ void FaceApp::createVertexBuffer() // 创建索引缓冲区 bufferInfo.size = indexBufferSize; bufferInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; + allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &m_indexBuffer, &m_indexBufferAllocation, nullptr); } + +void FaceApp::uploadVertexData() { + // 上传顶点数据 + void* data; + vmaMapMemory(allocator, m_stagingBufferAllocation, &data); + memcpy(data, obj_vertices.data(), sizeof(TextureLoadingVertexStructure) * obj_vertices.size()); + vmaUnmapMemory(allocator, m_stagingBufferAllocation); + + // 复制到设备内存 + copyBuffer(m_stagingBuffer, m_vertexBuffer, sizeof(TextureLoadingVertexStructure) * obj_vertices.size()); + + // 上传索引数据(如果需要暂存缓冲区,可以创建另一个) + vmaMapMemory(allocator, m_stagingBufferAllocation, &data); + memcpy(data, obj_indices.data(), sizeof(uint32_t) * obj_indices.size()); + vmaUnmapMemory(allocator, m_stagingBufferAllocation); + + copyBuffer(m_stagingBuffer, m_indexBuffer, sizeof(uint32_t) * obj_indices.size()); +} + void ReceiveFacePoint(float* pos, int pointCount, int width, int height) { FaceApp* self = FaceApp::Get(); @@ -474,23 +611,6 @@ void FaceApp::update_face_vertex_buffer(float* pos, int pointCount) uploadVertexData(); } -void FaceApp::uploadVertexData() { - // 上传顶点数据 - void* data; - vmaMapMemory(allocator, m_stagingBufferAllocation, &data); - memcpy(data, obj_vertices.data(), sizeof(TextureLoadingVertexStructure) * obj_vertices.size()); - vmaUnmapMemory(allocator, m_stagingBufferAllocation); - - // 复制到设备内存 - copyBuffer(m_stagingBuffer, m_vertexBuffer, sizeof(TextureLoadingVertexStructure) * obj_vertices.size()); - - // 上传索引数据(如果需要暂存缓冲区,可以创建另一个) - vmaMapMemory(allocator, m_stagingBufferAllocation, &data); - memcpy(data, obj_indices.data(), sizeof(uint32_t) * obj_indices.size()); - vmaUnmapMemory(allocator, m_stagingBufferAllocation); - - copyBuffer(m_stagingBuffer, m_indexBuffer, sizeof(uint32_t) * obj_indices.size()); -} void FaceApp::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size) { diff --git a/vulkan/FaceApp.h b/vulkan/FaceApp.h index 4d5e578..e957a1a 100644 --- a/vulkan/FaceApp.h +++ b/vulkan/FaceApp.h @@ -42,21 +42,23 @@ public: static FaceApp* Get() { return faceIns; } void update_face_vertex_buffer(float* pos, int pointCount); + virtual bool isInited() { return inited && faceAppInited; } + private: glm::vec3 rotation = glm::vec3(); glm::vec3 camera_pos = glm::vec3(); private: static FaceApp* faceIns; VmaAllocator allocator = nullptr; - bool LoadOBJ(const std::string& filename, - std::vector& vertices, - std::vector& indices); + bool LoadOBJ(const std::string& filename,std::vector& vertices, std::vector& indices); + void createVmaAllocator(); void update_uniform_buffers(); void createVertexBuffer(); void uploadVertexData(); VkDescriptorPool descriptor_pool = VK_NULL_HANDLE; + void create_face_pipelines(); void setup_descriptor_pool(); void setup_descriptor_set_layout(); void setup_descriptor_set(); @@ -95,7 +97,8 @@ private: void* uniform_buffer_mapped = nullptr; // 映射的内存指针 void createUniformBuffer(); - Texture tex_demo0; + Texture tex_demo0 = {0}; + bool faceAppInited = false; }; #endif