1010 lines
36 KiB
C++
1010 lines
36 KiB
C++
#include "FaceApp.h"
|
|
#include "hardcode_data.h"
|
|
#include <sstream>
|
|
|
|
|
|
|
|
|
|
FaceApp* FaceApp::faceIns = nullptr;
|
|
|
|
FaceApp::FaceApp(/* args */)
|
|
{
|
|
faceIns = this;
|
|
}
|
|
|
|
FaceApp::~FaceApp()
|
|
{
|
|
}
|
|
|
|
void ReceiveFacePoint(float* pos, int pointCount, int width, int height)
|
|
{
|
|
FaceApp* self = FaceApp::Get();
|
|
if (self != nullptr)
|
|
{
|
|
FaceApp::Get()->update_face_vertex_buffer(pos, pointCount);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void TextureLoadProcessWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize)
|
|
{
|
|
if(FaceApp::Get()->isInited())
|
|
{
|
|
Texture& tex_bg = FaceApp::Get()->tex_bg;
|
|
FaceApp::Get()->processWithVulkan(data, width, height, rowStride, dataSize, tex_bg, false);
|
|
}
|
|
}
|
|
|
|
bool FaceApp::LoadOBJ(const std::string& filename,
|
|
std::vector<TextureLoadingVertexStructure>& vertices,
|
|
std::vector<uint32_t>& indices) {
|
|
|
|
// 临时存储从OBJ文件读取的原始数据
|
|
std::vector<float> temp_positions;
|
|
std::vector<float> temp_texcoords;
|
|
std::vector<float> temp_normals;
|
|
|
|
// 用于处理顶点索引
|
|
std::vector<int> vertexIndices, uvIndices, normalIndices;
|
|
|
|
std::vector<char> data = readFile(filename);
|
|
|
|
// 将 vector<char> 转换为以 null 结尾的字符串(安全做法)
|
|
std::string content(data.begin(), data.end());
|
|
std::istringstream iss(content); // 用字符串创建字符串流
|
|
|
|
std::string line;
|
|
while (std::getline(iss, line)) {
|
|
// 跳过空行和注释行
|
|
if (line.empty() || line[0] == '#') {
|
|
continue;
|
|
}
|
|
|
|
std::istringstream iss(line);
|
|
std::string type;
|
|
iss >> type;
|
|
|
|
if (type == "v") { // 顶点位置
|
|
float x, y, z;
|
|
iss >> x >> y >> z;
|
|
temp_positions.push_back(x);
|
|
temp_positions.push_back(y);
|
|
temp_positions.push_back(z);
|
|
}
|
|
else if (type == "vt") { // 纹理坐标
|
|
float u, v;
|
|
iss >> u >> v;
|
|
temp_texcoords.push_back(u);
|
|
temp_texcoords.push_back(1 - v);
|
|
}
|
|
else if (type == "vn") { // 法线
|
|
float nx, ny, nz;
|
|
iss >> nx >> ny >> nz;
|
|
temp_normals.push_back(nx);
|
|
temp_normals.push_back(ny);
|
|
temp_normals.push_back(nz);
|
|
}
|
|
else if (type == "f") { // 面(三角形)
|
|
std::string vertex1, vertex2, vertex3;
|
|
iss >> vertex1 >> vertex2 >> vertex3;
|
|
|
|
// 处理每个顶点的索引
|
|
for (const std::string& vertex : { vertex1, vertex2, vertex3 }) {
|
|
std::istringstream viss(vertex);
|
|
std::string v, vt, vn;
|
|
|
|
// 解析顶点索引格式:v/vt/vn 或 v//vn 或 v
|
|
std::getline(viss, v, '/');
|
|
std::getline(viss, vt, '/');
|
|
std::getline(viss, vn, '/');
|
|
|
|
int posIndex = std::stoi(v) - 1; // OBJ索引从1开始
|
|
int texIndex = -1, normIndex = -1;
|
|
|
|
if (!vt.empty()) texIndex = std::stoi(vt) - 1;
|
|
if (!vn.empty()) normIndex = std::stoi(vn) - 1;
|
|
|
|
vertexIndices.push_back(posIndex);
|
|
uvIndices.push_back(texIndex);
|
|
normalIndices.push_back(normIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// 创建顶点数据
|
|
vertices.clear();
|
|
indices.clear();
|
|
|
|
// 用于去重的哈希映射
|
|
std::map<std::string, uint32_t> vertexMap;
|
|
|
|
for (size_t i = 0; i < vertexIndices.size(); i++) {
|
|
int posIndex = vertexIndices[i];
|
|
int texIndex = uvIndices[i];
|
|
int normIndex = normalIndices[i];
|
|
|
|
// 创建唯一标识符
|
|
std::string vertexKey = std::to_string(posIndex) + "/" +
|
|
std::to_string(texIndex) + "/" +
|
|
std::to_string(normIndex);
|
|
|
|
// 检查是否已经存在相同的顶点
|
|
if (vertexMap.find(vertexKey) != vertexMap.end()) {
|
|
// 使用现有顶点的索引
|
|
indices.push_back(vertexMap[vertexKey]);
|
|
}
|
|
else {
|
|
// 创建新顶点
|
|
TextureLoadingVertexStructure vertex;
|
|
|
|
// 设置位置
|
|
if (posIndex >= 0 && posIndex * 3 + 2 < temp_positions.size()) {
|
|
vertex.pos[0] = temp_positions[posIndex * 3];
|
|
vertex.pos[1] = temp_positions[posIndex * 3 + 1];
|
|
vertex.pos[2] = temp_positions[posIndex * 3 + 2];
|
|
}
|
|
else {
|
|
vertex.pos[0] = vertex.pos[1] = vertex.pos[2] = 0.0f;
|
|
}
|
|
|
|
// 设置纹理坐标
|
|
if (texIndex >= 0 && texIndex * 2 + 1 < temp_texcoords.size()) {
|
|
vertex.uv[0] = temp_texcoords[texIndex * 2];
|
|
vertex.uv[1] = temp_texcoords[texIndex * 2 + 1];
|
|
}
|
|
else {
|
|
vertex.uv[0] = vertex.uv[1] = 0.0f;
|
|
}
|
|
|
|
// 设置法线
|
|
if (normIndex >= 0 && normIndex * 3 + 2 < temp_normals.size()) {
|
|
vertex.normal[0] = temp_normals[normIndex * 3];
|
|
vertex.normal[1] = temp_normals[normIndex * 3 + 1];
|
|
vertex.normal[2] = temp_normals[normIndex * 3 + 2];
|
|
}
|
|
else {
|
|
vertex.normal[0] = vertex.normal[1] = 0.0f;
|
|
vertex.normal[2] = 1.0f; // 默认法线
|
|
}
|
|
|
|
// 添加新顶点并记录索引
|
|
uint32_t newIndex = static_cast<uint32_t>(vertices.size());
|
|
vertices.push_back(vertex);
|
|
indices.push_back(newIndex);
|
|
obj_vertices_map[newIndex] = posIndex;
|
|
vertexMap[vertexKey] = newIndex;
|
|
}
|
|
}
|
|
|
|
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<VkDynamicState> 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<uint32_t>(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<VkVertexInputBindingDescription> 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<VkVertexInputAttributeDescription> 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 = 1;
|
|
viaUv.binding = 0;
|
|
viaUv.format = VK_FORMAT_R32G32_SFLOAT;
|
|
viaUv.offset = offsetof(TextureLoadingVertexStructure, uv);
|
|
vertex_input_attributes.push_back(viaUv);
|
|
|
|
VkVertexInputAttributeDescription viaNormal{};
|
|
viaNormal.location = 2;
|
|
viaNormal.binding = 0;
|
|
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<uint32_t>(vertex_input_bindings.size());
|
|
vertex_input_state.pVertexBindingDescriptions = vertex_input_bindings.data();
|
|
vertex_input_state.vertexAttributeDescriptionCount = static_cast<uint32_t>(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{};
|
|
descriptor_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
|
descriptor_pool_size.descriptorCount = 2;
|
|
|
|
VkDescriptorPoolSize descriptor_pool_image_size{};
|
|
descriptor_pool_image_size.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
descriptor_pool_image_size.descriptorCount = kMaxTexture + 4;
|
|
|
|
|
|
std::vector<VkDescriptorPoolSize> pool_sizes;
|
|
pool_sizes.push_back(descriptor_pool_size);
|
|
pool_sizes.push_back(descriptor_pool_image_size);
|
|
|
|
|
|
VkDescriptorPoolCreateInfo descriptor_pool_info{};
|
|
descriptor_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
|
descriptor_pool_info.poolSizeCount = pool_sizes.size();
|
|
descriptor_pool_info.pPoolSizes = pool_sizes.data();
|
|
descriptor_pool_info.maxSets = kMaxTexture + 4 + 2;
|
|
|
|
VK_CHECK(vkCreateDescriptorPool(device, &descriptor_pool_info, nullptr, &descriptor_pool));
|
|
}
|
|
|
|
|
|
|
|
void FaceApp::setup_descriptor_set_layout()
|
|
{
|
|
|
|
|
|
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 = 1;
|
|
set_layout_binding_fragment.descriptorCount = 1;
|
|
|
|
// 添加第二个纹理绑定点
|
|
VkDescriptorSetLayoutBinding set_layout_binding_fragment1{};
|
|
set_layout_binding_fragment1.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
set_layout_binding_fragment1.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
set_layout_binding_fragment1.binding = 2;
|
|
set_layout_binding_fragment1.descriptorCount = 1;
|
|
|
|
std::vector<VkDescriptorSetLayoutBinding> set_layout_bindings{ set_layout_binding_vertex , set_layout_binding_fragment, set_layout_binding_fragment1 };
|
|
|
|
|
|
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<uint32_t>(set_layout_bindings.size());
|
|
|
|
VK_CHECK(vkCreateDescriptorSetLayout(device, &descriptor_layout, nullptr, &m_descriptorSetLayout));
|
|
|
|
|
|
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;
|
|
pushConstantRange.offset = 0;
|
|
pushConstantRange.size = sizeof(float);
|
|
|
|
pipeline_layout_create_info.pushConstantRangeCount = 1;
|
|
pipeline_layout_create_info.pPushConstantRanges = &pushConstantRange;
|
|
|
|
VK_CHECK(vkCreatePipelineLayout(device, &pipeline_layout_create_info, nullptr, &m_pipelineLayout));
|
|
}
|
|
|
|
void FaceApp::setup_descriptor_set()
|
|
{
|
|
m_descriptor_sets.resize(kMaxTexture);
|
|
std::vector<VkDescriptorSetLayout> layouts(kMaxTexture, m_descriptorSetLayout);
|
|
VkDescriptorSetAllocateInfo alloc_info{};
|
|
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
|
alloc_info.descriptorPool = descriptor_pool;
|
|
alloc_info.pSetLayouts = layouts.data();
|
|
alloc_info.descriptorSetCount = m_descriptor_sets.size();
|
|
VK_CHECK(vkAllocateDescriptorSets(device, &alloc_info, m_descriptor_sets.data()));
|
|
|
|
for (int i = 0; i < kMaxTexture; ++i)
|
|
{
|
|
VkDescriptorBufferInfo buffer_descriptor{};
|
|
buffer_descriptor.buffer = uniform_buffer_vs;
|
|
buffer_descriptor.range = VK_WHOLE_SIZE;
|
|
buffer_descriptor.offset = 0;
|
|
|
|
|
|
VkDescriptorImageInfo image_descriptor;
|
|
image_descriptor.imageView = m_texs[i].view;
|
|
image_descriptor.sampler = m_texs[i].sampler;
|
|
image_descriptor.imageLayout = m_texs[i].image_layout;
|
|
|
|
// 第二个纹理描述符 - 假设你的第二个纹理变量名为 tex_demo1
|
|
VkDescriptorImageInfo image_descriptor1;
|
|
image_descriptor1.imageView = m_texs_ex[i].view;
|
|
image_descriptor1.sampler = m_texs_ex[i].sampler;
|
|
image_descriptor1.imageLayout = m_texs_ex[i].image_layout;
|
|
|
|
VkWriteDescriptorSet write_descriptor_set_uniform{};
|
|
write_descriptor_set_uniform.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
write_descriptor_set_uniform.dstSet = m_descriptor_sets[i];
|
|
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_sets[i];
|
|
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;
|
|
|
|
// 添加第二个纹理的写入描述符
|
|
VkWriteDescriptorSet write_descriptor_set_image1{};
|
|
write_descriptor_set_image1.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
write_descriptor_set_image1.dstSet = m_descriptor_sets[i];
|
|
write_descriptor_set_image1.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
write_descriptor_set_image1.dstBinding = 2; // 绑定到位置2
|
|
write_descriptor_set_image1.pImageInfo = &image_descriptor1;
|
|
write_descriptor_set_image1.descriptorCount = 1;
|
|
|
|
std::vector<VkWriteDescriptorSet> write_descriptor_sets =
|
|
{
|
|
write_descriptor_set_uniform,
|
|
write_descriptor_set_image,
|
|
write_descriptor_set_image1, // 添加第二个纹理
|
|
};
|
|
|
|
vkUpdateDescriptorSets(device, static_cast<uint32_t>(write_descriptor_sets.size()), write_descriptor_sets.data(), 0, NULL);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void FaceApp::render(VkCommandBuffer commandBuffer)
|
|
{
|
|
std::unique_lock<std::mutex> lock(mtx);
|
|
std::unique_lock<std::mutex> lock_point(mtx_point);
|
|
//Application::render(commandBuffer);
|
|
|
|
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout_bg, 0, 1, &m_descriptor_set_bg, 0, NULL);
|
|
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline_bg);
|
|
|
|
|
|
vkCmdPushConstants(commandBuffer, m_pipelineLayout_bg, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float), &myFloatValue);
|
|
|
|
//vkCmdDraw(commandBuffer, 6, 1, 0, 0);
|
|
|
|
|
|
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &m_descriptor_sets[_curTexIndex], 0, NULL);
|
|
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline);
|
|
|
|
vkCmdPushConstants(commandBuffer, m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float), &myFloatValue);
|
|
|
|
VkDeviceSize offsets[1] = { 0 };
|
|
VkBuffer vertexBuffers[] = { m_vertexBuffer };
|
|
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
|
|
vkCmdBindIndexBuffer(commandBuffer, m_indexBuffer, 0, VK_INDEX_TYPE_UINT32);
|
|
|
|
#ifdef _WIN32
|
|
vkCmdDrawIndexed(commandBuffer, obj_indices.size(), 1, 0, 0, 0);
|
|
#else
|
|
if (getCurrentTimeMillis() - last_update_time < 2000)
|
|
{
|
|
vkCmdDrawIndexed(commandBuffer, obj_indices.size(), 1, 0, 0, 0);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void FaceApp::createVmaAllocator()
|
|
{
|
|
//VmaAllocatorCreateInfo allocatorInfo = {};
|
|
//allocatorInfo.physicalDevice = physicalDevice;
|
|
//allocatorInfo.device = device;
|
|
//allocatorInfo.instance = instance;
|
|
//allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_0;
|
|
//vmaCreateAllocator(&allocatorInfo, &allocator);
|
|
|
|
// 1. 设置 Vulkan 函数指针
|
|
VmaVulkanFunctions vulkanFunctions{};
|
|
vulkanFunctions.vkGetInstanceProcAddr = vkGetInstanceProcAddr;
|
|
vulkanFunctions.vkGetDeviceProcAddr = vkGetDeviceProcAddr;
|
|
|
|
// 2. 配置 Allocator
|
|
VmaAllocatorCreateInfo allocatorInfo{};
|
|
allocatorInfo.physicalDevice = physicalDevice;
|
|
allocatorInfo.device = device;
|
|
allocatorInfo.instance = instance;
|
|
allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_0;
|
|
allocatorInfo.pVulkanFunctions = &vulkanFunctions;
|
|
|
|
|
|
VkResult result = vmaCreateAllocator(&allocatorInfo, &allocator);
|
|
}
|
|
|
|
void FaceApp::initVulkan()
|
|
{
|
|
Application::initVulkan();
|
|
createVmaAllocator();
|
|
LoadOBJ("face_picture_3dmax.obj", obj_vertices, obj_indices);
|
|
m_texs.resize(kMaxTexture);
|
|
m_texs_ex.resize(kMaxTexture);
|
|
for (int i = 0; i < kMaxTexture; ++i)
|
|
{
|
|
loadTexture("demo0.png", m_texs[i], true);
|
|
loadTexture("demo0_ex.png", m_texs_ex[i], true);
|
|
}
|
|
|
|
loadTexture("out.png", tex_bg, false);
|
|
createVertexBuffer();
|
|
createUniformBuffer();
|
|
setup_descriptor_pool();
|
|
|
|
setup_descriptor_set_layout();
|
|
setup_descriptor_set();
|
|
create_face_pipelines();
|
|
|
|
setup_descriptor_set_layout_bg();
|
|
setup_descriptor_set_bg();
|
|
create_pipelines_bg();
|
|
|
|
uploadVertexData();
|
|
last_update_time = getCurrentTimeMillis();
|
|
faceAppInited = true;
|
|
|
|
#if _WIN32
|
|
std::vector<float> floatArray;
|
|
std::string& str = HardCodeData::Get().face_result_point_str;
|
|
std::stringstream ss(str);
|
|
std::string token;
|
|
while (std::getline(ss, token, ',')) {
|
|
floatArray.push_back(std::stof(token));
|
|
}
|
|
|
|
//ReceiveFacePoint(floatArray.data(), floatArray.size() / 3, 480, 480);
|
|
#endif
|
|
}
|
|
|
|
void FaceApp::update_uniform_buffers()
|
|
{
|
|
uint32_t width = 480;
|
|
uint32_t height = 480;
|
|
float zoom = 2;
|
|
// Vertex shader
|
|
ubo_vs.projection = glm::perspective(glm::radians(60.0f), static_cast<float>(width) / static_cast<float>(height), 0.001f, 256.0f);
|
|
glm::mat4 view_matrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, zoom));
|
|
|
|
ubo_vs.model = view_matrix * glm::translate(glm::mat4(1.0f), camera_pos);
|
|
ubo_vs.model = glm::rotate(ubo_vs.model, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
|
|
ubo_vs.model = glm::rotate(ubo_vs.model, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
|
|
ubo_vs.model = glm::rotate(ubo_vs.model, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
|
|
|
|
ubo_vs.view_pos = glm::vec4(0.0f, 0.0f, -zoom, 0.0f);
|
|
|
|
memcpy(uniform_buffer_mapped, &ubo_vs, sizeof(ubo_vs));
|
|
}
|
|
|
|
void FaceApp::createVertexBuffer()
|
|
{
|
|
VkDeviceSize vertexBufferSize = sizeof(TextureLoadingVertexStructure) * obj_vertices.size();
|
|
VkDeviceSize indexBufferSize = sizeof(uint32_t) * obj_indices.size();
|
|
|
|
|
|
VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
|
bufferInfo.size = vertexBufferSize;
|
|
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
|
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
|
|
VmaAllocationCreateInfo allocInfo = {};
|
|
allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
|
|
|
|
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &m_vertexBuffer, &m_vertexBufferAllocation, nullptr);
|
|
|
|
|
|
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
|
allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
|
|
|
|
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &m_stagingBuffer, &m_stagingBufferAllocation, nullptr);
|
|
|
|
|
|
bufferInfo.size = indexBufferSize;
|
|
bufferInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
|
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 FaceApp::update_face_vertex_buffer(float* pos, int pointCount)
|
|
{
|
|
if(!isInited())
|
|
{
|
|
return;
|
|
}
|
|
|
|
std::lock_guard<std::mutex> lock(mtx_point);
|
|
last_update_time = getCurrentTimeMillis();
|
|
|
|
|
|
for (int i = 0; i < obj_vertices.size(); ++i)
|
|
{
|
|
|
|
int face_index = obj_vertices_map[HardCodeData::Get().indexMap[i]];
|
|
float x = pos[face_index * 3 + 0];
|
|
float y = pos[face_index * 3 + 1];
|
|
float z = pos[face_index * 3 + 2];
|
|
|
|
obj_vertices[i].pos[0] = x;
|
|
obj_vertices[i].pos[1] = y;
|
|
obj_vertices[i].pos[2] = z;
|
|
}
|
|
calculateVertexNormals(obj_vertices, obj_indices);
|
|
uploadVertexData();
|
|
}
|
|
|
|
|
|
void FaceApp::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size)
|
|
{
|
|
VkCommandBuffer commandBuffer = beginSingleTimeCommands();
|
|
|
|
VkBufferCopy copyRegion = {};
|
|
copyRegion.size = size;
|
|
vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, ©Region);
|
|
|
|
endSingleTimeCommands(commandBuffer);
|
|
}
|
|
|
|
VkCommandBuffer FaceApp::beginSingleTimeCommands() {
|
|
VkCommandBufferAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
|
|
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
|
allocInfo.commandPool = commandPool;
|
|
allocInfo.commandBufferCount = 1;
|
|
|
|
VkCommandBuffer commandBuffer;
|
|
vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer);
|
|
|
|
VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
|
|
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
|
|
|
vkBeginCommandBuffer(commandBuffer, &beginInfo);
|
|
return commandBuffer;
|
|
}
|
|
|
|
void FaceApp::endSingleTimeCommands(VkCommandBuffer commandBuffer) {
|
|
vkEndCommandBuffer(commandBuffer);
|
|
|
|
VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
|
|
submitInfo.commandBufferCount = 1;
|
|
submitInfo.pCommandBuffers = &commandBuffer;
|
|
|
|
vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
|
|
vkQueueWaitIdle(graphicsQueue);
|
|
|
|
vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
|
|
}
|
|
|
|
void FaceApp::createUniformBuffer()
|
|
{
|
|
VkDeviceSize bufferSize = sizeof(ubo_vs);
|
|
|
|
VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
|
bufferInfo.size = bufferSize;
|
|
bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
|
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
|
|
VmaAllocationCreateInfo allocInfo = {};
|
|
allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
|
|
allocInfo.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
|
|
|
// 创建缓冲区和内存分配
|
|
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo,
|
|
&uniform_buffer_vs,
|
|
&uniform_buffer_allocation,
|
|
nullptr);
|
|
|
|
// 映射内存以便直接写入
|
|
vmaMapMemory(allocator, uniform_buffer_allocation, &uniform_buffer_mapped);
|
|
|
|
update_uniform_buffers();
|
|
}
|
|
|
|
|
|
void FaceApp::create_pipelines_bg()
|
|
{
|
|
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;
|
|
|
|
|
|
VkPipelineColorBlendAttachmentState colorBlendAttachment{};
|
|
colorBlendAttachment.blendEnable = VK_FALSE;
|
|
colorBlendAttachment.colorWriteMask = 0xf;
|
|
|
|
|
|
VkPipelineColorBlendStateCreateInfo colorBlending{};
|
|
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
|
colorBlending.attachmentCount = 1;
|
|
colorBlending.pAttachments = &colorBlendAttachment;
|
|
|
|
|
|
VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {};
|
|
|
|
depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
|
depth_stencil_state.depthTestEnable = VK_FALSE;
|
|
depth_stencil_state.depthWriteEnable = VK_FALSE;
|
|
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;
|
|
|
|
|
|
// 视口状态
|
|
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/bg.vert.spv");
|
|
auto fragShaderCode = readFile("shaders/bg.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 };
|
|
|
|
VkPipelineVertexInputStateCreateInfo vertex_input_state{};
|
|
vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
|
|
|
|
|
VkGraphicsPipelineCreateInfo pipeline_create_info{};
|
|
pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
|
pipeline_create_info.layout = m_pipelineLayout_bg;
|
|
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_bg));
|
|
}
|
|
|
|
void FaceApp::setup_descriptor_set_layout_bg()
|
|
{
|
|
VkDescriptorSetLayoutBinding set_layout_binding{};
|
|
set_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
set_layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
set_layout_binding.binding = 0;
|
|
set_layout_binding.descriptorCount = 1;
|
|
|
|
std::vector<VkDescriptorSetLayoutBinding> set_layout_bindings ={set_layout_binding };
|
|
|
|
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<uint32_t>(set_layout_bindings.size());
|
|
|
|
|
|
|
|
VK_CHECK(vkCreateDescriptorSetLayout(device, &descriptor_layout, nullptr, &m_descriptorSetLayout_bg));
|
|
|
|
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_bg;
|
|
|
|
|
|
VkPushConstantRange pushConstantRange{};
|
|
pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; // 只在片段着色器中使用
|
|
pushConstantRange.offset = 0;
|
|
pushConstantRange.size = sizeof(float); // 或者 sizeof(PushConstants)
|
|
|
|
pipeline_layout_create_info.pushConstantRangeCount = 1;
|
|
pipeline_layout_create_info.pPushConstantRanges = &pushConstantRange;
|
|
|
|
VK_CHECK(vkCreatePipelineLayout(device, &pipeline_layout_create_info, nullptr, &m_pipelineLayout_bg));
|
|
}
|
|
|
|
void FaceApp::setup_descriptor_set_bg()
|
|
{
|
|
|
|
VkDescriptorSetAllocateInfo alloc_info{};
|
|
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
|
alloc_info.descriptorPool = descriptor_pool;
|
|
alloc_info.pSetLayouts = &m_descriptorSetLayout_bg;
|
|
alloc_info.descriptorSetCount = 1;
|
|
|
|
VK_CHECK(vkAllocateDescriptorSets(device, &alloc_info, &m_descriptor_set_bg));
|
|
|
|
|
|
|
|
VkDescriptorImageInfo image_descriptor;
|
|
image_descriptor.imageView = tex_bg.view;
|
|
image_descriptor.sampler = tex_bg.sampler;
|
|
image_descriptor.imageLayout = tex_bg.image_layout;
|
|
|
|
VkWriteDescriptorSet write_descriptor_set{};
|
|
write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
write_descriptor_set.dstSet = m_descriptor_set_bg;
|
|
write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
write_descriptor_set.dstBinding = 0;
|
|
write_descriptor_set.pImageInfo = &image_descriptor;
|
|
write_descriptor_set.descriptorCount = 1;
|
|
|
|
std::vector<VkWriteDescriptorSet> write_descriptor_sets = { write_descriptor_set };
|
|
|
|
vkUpdateDescriptorSets(device, static_cast<uint32_t>(write_descriptor_sets.size()), write_descriptor_sets.data(), 0, NULL);
|
|
}
|
|
|
|
|
|
void FaceApp::cleanup()
|
|
{
|
|
vkDeviceWaitIdle(device);
|
|
vkDestroyCommandPool(device, commandPool, nullptr);
|
|
vkDestroyPipeline(device, m_graphicsPipeline, nullptr);
|
|
vkDestroyPipelineLayout(device, m_pipelineLayout, nullptr);
|
|
//vmaUnmapMemory(allocator, m_stagingBufferAllocation);
|
|
//vmaUnmapMemory(allocator, uniform_buffer_allocation);
|
|
//vmaDestroyBuffer(allocator, uniform_buffer_vs, uniform_buffer_allocation);
|
|
//vmaDestroyBuffer(allocator, m_indexBuffer, m_indexBufferAllocation);
|
|
//vmaDestroyBuffer(allocator, m_vertexBuffer, m_vertexBufferAllocation);
|
|
//vmaDestroyBuffer(allocator, m_stagingBuffer, m_stagingBufferAllocation);
|
|
vkDestroyDescriptorSetLayout(device, m_descriptorSetLayout, nullptr);
|
|
Application::cleanup();
|
|
}
|
|
|
|
|
|
void FaceApp::SetInitArg(const char* arg)
|
|
{
|
|
_initArg = json::parse(arg);
|
|
|
|
}
|
|
|
|
void FaceApp::changeMotion(Motion& motion)
|
|
{
|
|
if (_curMotion.getMotionId() == motion.getMotionId())
|
|
{
|
|
return;
|
|
}
|
|
_curMotion = _initArg.motion;
|
|
for (int i = 0; i < _curMotion.png_num; ++i)
|
|
{
|
|
string path = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type;
|
|
string path_name = path + "/" + _curMotion.png_name + std::to_string(i) + ".png";
|
|
loadTexture(path_name, m_texs[i], true);
|
|
string path_name_ex = path + "/" + _curMotion.png_name + std::to_string(i) + "_thick.png";
|
|
loadTexture(path_name, m_texs[i], true);
|
|
}
|
|
} |