diff --git a/app/src/main/assets/dummy.png b/app/src/main/assets/dummy.png index bccb906..59993d0 100644 Binary files a/app/src/main/assets/dummy.png and b/app/src/main/assets/dummy.png differ diff --git a/app/src/main/assets/shaders/texture.frag b/app/src/main/assets/shaders/texture.frag index b3e0d70..5621a00 100644 --- a/app/src/main/assets/shaders/texture.frag +++ b/app/src/main/assets/shaders/texture.frag @@ -5,17 +5,20 @@ layout (binding = 1) uniform sampler2D samplerColor; layout (location = 0) in vec2 inUV; layout (location = 1) in vec3 inNormal; -layout(push_constant) uniform PushConstantsFS { - float ux; - float uy; -} pc_fs; +layout(push_constant) uniform PushConstants { + float myValue; + float ux; + float uy; +} pushConstants; layout (location = 0) out vec4 outFragColor; void main() { - vec4 color = texture(samplerColor, inUV); + vec2 pos = vec2(pushConstants.ux/2880.f, pushConstants.uy/2880.f); + vec2 uv = pos + vec2(inUV.x/8.f, inUV.y/8.f); + vec4 color = texture(samplerColor, uv); outFragColor = color; diff --git a/app/src/main/assets/shaders/texture.frag.spv b/app/src/main/assets/shaders/texture.frag.spv index c54133d..3407953 100644 Binary files a/app/src/main/assets/shaders/texture.frag.spv and b/app/src/main/assets/shaders/texture.frag.spv differ diff --git a/app/src/main/assets/shaders/texture.vert b/app/src/main/assets/shaders/texture.vert index 183bc7b..1cd1180 100644 --- a/app/src/main/assets/shaders/texture.vert +++ b/app/src/main/assets/shaders/texture.vert @@ -18,6 +18,8 @@ layout (location = 1) out vec3 outNormal; layout(push_constant) uniform PushConstants { float myValue; + float ux; + float uy; } pushConstants; out gl_PerVertex diff --git a/app/src/main/assets/shaders/texture.vert.spv b/app/src/main/assets/shaders/texture.vert.spv index d407944..63c5499 100644 Binary files a/app/src/main/assets/shaders/texture.vert.spv and b/app/src/main/assets/shaders/texture.vert.spv differ diff --git a/app/src/main/java/com/hmwl/face_sdk/FaceActivity.java b/app/src/main/java/com/hmwl/face_sdk/FaceActivity.java index 7d77f60..bf6afc0 100644 --- a/app/src/main/java/com/hmwl/face_sdk/FaceActivity.java +++ b/app/src/main/java/com/hmwl/face_sdk/FaceActivity.java @@ -301,9 +301,8 @@ public class FaceActivity extends GameActivity implements FaceLandmarkerHelper.L } protected native void ChangeMotionCpp(String json, AnimationFinishedCallbackInterface callback, boolean loop); - protected void ChangeMotion(String json, AnimationFinishedCallbackInterface callback, boolean loop){ - Log.i("FaceActivity", "ChangeState:" + json); - ChangeMotionCpp(json, callback, loop); + protected void ChangeMotionList(AnimationFinishedCallbackInterface callback, boolean loop){ + ChangeMotionCpp("", callback, loop); } // 添加这个缺失的方法 diff --git a/app/src/main/java/com/hmwl/face_sdk/Motion.java b/app/src/main/java/com/hmwl/face_sdk/Motion.java index f3376d4..6552c17 100644 --- a/app/src/main/java/com/hmwl/face_sdk/Motion.java +++ b/app/src/main/java/com/hmwl/face_sdk/Motion.java @@ -19,9 +19,9 @@ public class Motion { try { JSONObject jsonObject = new JSONObject(); jsonObject.put("name", name); - JSONObject jframes = new JSONObject(); + JSONArray jframes = new JSONArray(); for(int i = 0; i < frames.size(); ++i){ - jframes.put(frames.get(i).name, frames.get(i).toJsonObject()); + jframes.put(frames.get(i).toJsonObject()); } jsonObject.put("frames", jframes); return jsonObject; diff --git a/compile_shader.bat b/compile_shader.bat index 4093d63..2d46b71 100644 --- a/compile_shader.bat +++ b/compile_shader.bat @@ -4,8 +4,9 @@ glslangValidator -V app/src/main/assets/shaders/bg.vert -o app/src/main/assets/s glslangValidator -V app/src/main/assets/shaders/texture.frag -o app/src/main/assets/shaders/texture.frag.spv glslangValidator -V app/src/main/assets/shaders/texture.vert -o app/src/main/assets/shaders/texture.vert.spv -glslangValidator -V app/src/main/assets/shaders/texture_thick.frag -o app/src/main/assets/shaders/texture_thick.frag.spv -glslangValidator -V app/src/main/assets/shaders/texture_thick.vert -o app/src/main/assets/shaders/texture_thick.vert.spv - glslangValidator -V app/src/main/assets/shaders/simple_shader.frag -o app/src/main/assets/shaders/simple_shader.frag.spv -glslangValidator -V app/src/main/assets/shaders/simple_shader.vert -o app/src/main/assets/shaders/simple_shader.vert.spv \ No newline at end of file +glslangValidator -V app/src/main/assets/shaders/simple_shader.vert -o app/src/main/assets/shaders/simple_shader.vert.spv + +glslangValidator -V app/src/main/assets/shaders/texture_thick.frag -o app/src/main/assets/shaders/texture_thick.frag.spv +rem glslangValidator -V app/src/main/assets/shaders/texture_thick.vert -o app/src/main/assets/shaders/texture_thick.vert.spv + diff --git a/example/src/main/assets/pic/4/4ex.png b/example/src/main/assets/pic/4/4ex.png index 7f37a6b..b4df950 100644 Binary files a/example/src/main/assets/pic/4/4ex.png and b/example/src/main/assets/pic/4/4ex.png differ diff --git a/example/src/main/java/com/inewme/uvmirror/MakeupActivity.kt b/example/src/main/java/com/inewme/uvmirror/MakeupActivity.kt index 5a08413..363c59d 100644 --- a/example/src/main/java/com/inewme/uvmirror/MakeupActivity.kt +++ b/example/src/main/java/com/inewme/uvmirror/MakeupActivity.kt @@ -29,13 +29,23 @@ class MakeupActivity : FaceActivity() } } - var isLoadFinished : Boolean = false var loadFinishedFun = object : CallbackInterface { override fun OnLoadActionFinished(motion_type: String) { - isLoadFinished = true; + if(actionState == ActionState.Loading) + { + actionState = ActionState.LoadingFinished + } } } + var actionState : ActionState = ActionState.None; + + enum class ActionState{ + None, + Loading, + LoadingFinished, + Playing + } private var updateJob: Job? = null @@ -65,31 +75,23 @@ class MakeupActivity : FaceActivity() val mlist = MotionList(); getMotionByName("4")?.let { mlist.motions.add(it) } - //getMotionByName("11")?.let { mlist.motions.add(it) } - //getMotionByName("13")?.let { mlist.motions.add(it) } - PreLoadAction(mlist.toJsonString(), loadFinishedFun) + getMotionByName("11")?.let { mlist.motions.add(it) } + getMotionByName("13")?.let { mlist.motions.add(it) } + if(actionState == ActionState.None) + { + PreLoadAction(mlist.toJsonString(), loadFinishedFun) + actionState = ActionState.Loading + } + } private fun update() { -// //下一个动画加载完成,并且当前动画已经播放完了 (刚开始的时候当前动画初始化为播放完成) -// if(isLoadFinished && isMotionFinished) -// { -// //切换到加载完成的动画 -// isMotionFinished = false -// ChangeMotion(motionQueue[_motionIndex], animationFinishedFun, false) -// -// isLoadFinished = false -// -// //如果还有动画,则开始预先加载 -// if(_motionIndex + 1 < motionQueue.size) -// { -// _motionIndex += 1 -// PreLoadAction(motionQueue[_motionIndex], loadFinishedFun) -// } -// -// } - + if(actionState == ActionState.LoadingFinished) + { + ChangeMotionList(animationFinishedFun, true) + actionState = ActionState.Playing + } } override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { diff --git a/vulkan/Application.cpp b/vulkan/Application.cpp index 86b5408..16aaa31 100644 --- a/vulkan/Application.cpp +++ b/vulkan/Application.cpp @@ -2,7 +2,7 @@ #include "lodepng.h" #ifdef _WIN32 - + #include #else #include #include @@ -658,13 +658,13 @@ void Application::loadTexture(std::string path, Texture& tex, bool srgb, VkComma std::vector image; unsigned w, h; unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8); - processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb, pool); + processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb, pool, path); //return tex; } -void Application::loadTexture(std::vector& image_data, size_t image_size, int w, int h, Texture& tex, bool srgb, VkCommandPool pool) +void Application::loadTexture(std::vector& image_data, size_t image_size, int w, int h, Texture& tex, bool srgb, VkCommandPool pool, std::string path) { - processWithVulkan(image_data.data(), w, h, w * 4, image_size, tex, srgb, pool); + processWithVulkan(image_data.data(), w, h, w * 4, image_size, tex, srgb, pool, path); //return tex; } @@ -675,7 +675,9 @@ void Application::loadTextureExample(std::wstring path, Texture& tex, bool srgb, std::vector image; unsigned w, h; unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8); - processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb, pool); + std::wstring_convert> converter; + std::string str = converter.to_bytes(path); + processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb, pool, str); //return tex; } @@ -684,7 +686,7 @@ void Application::loadTextureExample(std::wstring path, Texture& tex, bool srgb, -void Application::createTexture(VkDevice device, VkPhysicalDevice physicalDevice, int width, int height, Texture& texture, bool srgb) +void Application::createTexture(VkDevice device, VkPhysicalDevice physicalDevice, int width, int height, Texture& texture, bool srgb, std::string tex_path, size_t dataSize) { texture.width = width; texture.height = height; @@ -731,6 +733,8 @@ void Application::createTexture(VkDevice device, VkPhysicalDevice physicalDevice throw std::runtime_error("Failed to allocate image memory!"); } + std::cout << "vkAllocateMemory device_memory " << tex_path << ": " << texture.device_memory << std::endl; + vkBindImageMemory(device, texture.image, texture.device_memory, 0); VkImageViewCreateInfo viewInfo = {}; @@ -779,21 +783,56 @@ void Application::createTexture(VkDevice device, VkPhysicalDevice physicalDevice throw std::runtime_error("Failed to create texture sampler!"); } + if (texture.stagingBuffer == nullptr) + { + VkBufferCreateInfo bufferInfo = {}; + bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufferInfo.size = dataSize; + bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + + if (vkCreateBuffer(device, &bufferInfo, nullptr, &texture.stagingBuffer) != VK_SUCCESS) + { + throw std::runtime_error("Failed to create staging buffer!"); + } + } + + if (texture.stagingBufferMemory == nullptr) + { + VkMemoryRequirements memRequirements; + vkGetBufferMemoryRequirements(device, texture.stagingBuffer, &memRequirements); + + VkMemoryAllocateInfo allocInfo = {}; + allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocInfo.allocationSize = memRequirements.size; + allocInfo.memoryTypeIndex = findMemoryType(physicalDevice, + memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + + if (vkAllocateMemory(device, &allocInfo, nullptr, &texture.stagingBufferMemory) != VK_SUCCESS) + { + throw std::runtime_error("Failed to allocate staging buffer memory!"); + } + + std::cout << "vkAllocateMemory stagingBufferMemory " << tex_path << ": " << texture.stagingBufferMemory << std::endl; + + vkBindBufferMemory(device, texture.stagingBuffer, texture.stagingBufferMemory, 0); + } + texture.image_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; texture.device = device; + texture.texture_path = tex_path; } -void Application::processWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& out_texture, bool srgb, VkCommandPool pool) +void Application::processWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& texture, bool srgb, VkCommandPool pool, std::string tex_path) { std::unique_lock lock(mtx); - if (out_texture.image == VK_NULL_HANDLE) + if (texture.image == VK_NULL_HANDLE) { - createTexture(device, physicalDevice, width, height, out_texture, srgb); - + createTexture(device, physicalDevice, width, height, texture, srgb, tex_path, dataSize); } updateTexture(device, physicalDevice, pool, graphicsQueue, data, width, height, - rowStride, dataSize, out_texture); + rowStride, dataSize, texture); } @@ -842,39 +881,6 @@ void Application::updateTexture(VkDevice device, VkPhysicalDevice physicalDevice //VkBuffer stagingBuffer; //VkDeviceMemory stagingBufferMemory; - if (texture.stagingBuffer == nullptr) - { - VkBufferCreateInfo bufferInfo = {}; - bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferInfo.size = dataSize; - bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - - if (vkCreateBuffer(device, &bufferInfo, nullptr, &texture.stagingBuffer) != VK_SUCCESS) - { - throw std::runtime_error("Failed to create staging buffer!"); - } - } - - if (texture.stagingBufferMemory == nullptr) - { - VkMemoryRequirements memRequirements; - vkGetBufferMemoryRequirements(device, texture.stagingBuffer, &memRequirements); - - VkMemoryAllocateInfo allocInfo = {}; - allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - allocInfo.allocationSize = memRequirements.size; - allocInfo.memoryTypeIndex = findMemoryType(physicalDevice, - memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - - if (vkAllocateMemory(device, &allocInfo, nullptr, &texture.stagingBufferMemory) != VK_SUCCESS) - { - throw std::runtime_error("Failed to allocate staging buffer memory!"); - } - - vkBindBufferMemory(device, texture.stagingBuffer, texture.stagingBufferMemory, 0); - } - void* mappedData; vkMapMemory(device, texture.stagingBufferMemory, 0, dataSize, 0, &mappedData); diff --git a/vulkan/Application.h b/vulkan/Application.h index 74df371..409e74f 100644 --- a/vulkan/Application.h +++ b/vulkan/Application.h @@ -8,24 +8,18 @@ struct Texture { - VkSampler sampler; - VkImage image; - VkImageLayout image_layout; - VkDeviceMemory device_memory; - VkImageView view; - uint32_t width, height; - uint32_t mip_levels; + VkSampler sampler = VK_NULL_HANDLE; + VkImage image = VK_NULL_HANDLE; + VkImageLayout image_layout = VkImageLayout::VK_IMAGE_LAYOUT_UNDEFINED; + VkDeviceMemory device_memory = VK_NULL_HANDLE; + VkImageView view = VK_NULL_HANDLE; + uint32_t width = 0; + uint32_t height = 0; + uint32_t mip_levels = 0; VkBuffer stagingBuffer = VK_NULL_HANDLE; VkDeviceMemory stagingBufferMemory = VK_NULL_HANDLE; - VkDevice device; - void reset() { - sampler = VK_NULL_HANDLE; - image = VK_NULL_HANDLE; - device_memory = VK_NULL_HANDLE; - view = VK_NULL_HANDLE; - stagingBuffer = VK_NULL_HANDLE; - stagingBufferMemory = VK_NULL_HANDLE; - } + VkDevice device = VK_NULL_HANDLE; + std::string texture_path; }; class Application : public AppBase @@ -54,7 +48,7 @@ public: virtual void render(VkCommandBuffer commandBuffer, long long frameTime); virtual bool isInited() { return inited; } - void processWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& out_texture, bool srgb, VkCommandPool pool); + void processWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& texture, bool srgb, VkCommandPool pool, std::string tex_path); protected: @@ -88,14 +82,14 @@ public: protected: void loadTexture(std::string path, Texture& tex, bool srgb, VkCommandPool pool); - void loadTexture(std::vector& image_data, size_t image_size, int w, int h, Texture& tex, bool srgb, VkCommandPool pool); + void loadTexture(std::vector& image_data, size_t image_size, int w, int h, Texture& tex, bool srgb, VkCommandPool pool, std::string path); #ifdef _WIN32 void loadTextureExample(std::wstring path, Texture& tex, bool srgb, VkCommandPool pool); #endif uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter, VkMemoryPropertyFlags properties); - void createTexture(VkDevice device, VkPhysicalDevice physicalDevice, int width, int height, Texture& texture, bool srgb); + void createTexture(VkDevice device, VkPhysicalDevice physicalDevice, int width, int height, Texture& texture, bool srgb, std::string tex_path, size_t dataSize); void updateTexture(VkDevice device, VkPhysicalDevice physicalDevice, VkCommandPool commandPool, VkQueue queue, uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& texture); VkCommandBuffer beginSingleTimeCommands(VkDevice device, VkCommandPool commandPool); void endSingleTimeCommands(VkDevice device, VkCommandPool commandPool, VkQueue queue, VkCommandBuffer commandBuffer); diff --git a/vulkan/FaceApp.cpp b/vulkan/FaceApp.cpp index 2871723..fc729eb 100644 --- a/vulkan/FaceApp.cpp +++ b/vulkan/FaceApp.cpp @@ -110,7 +110,8 @@ void TextureLoadProcessWithVulkan(uint8_t* data, int width, int height, int rowS oldestFrame.dataSize, tex_bg, false, - FaceApp::Get()->commandPool + FaceApp::Get()->commandPool, + "data_from_camera" ); frameQueue.pop(); @@ -524,13 +525,26 @@ void FaceApp::setup_descriptor_set_layout() 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); + //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; + + VkPushConstantRange pushConstantRanges[1]; + pushConstantRanges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT| VK_SHADER_STAGE_FRAGMENT_BIT; + pushConstantRanges[0].offset = 0; + pushConstantRanges[0].size = sizeof(float)*3; + + //pushConstantRanges[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + //pushConstantRanges[1].offset = sizeof(float); + //pushConstantRanges[1].size = 2*sizeof(float); + pipeline_layout_create_info.pushConstantRangeCount = 1; - pipeline_layout_create_info.pPushConstantRanges = &pushConstantRange; + pipeline_layout_create_info.pPushConstantRanges = &pushConstantRanges[0]; VK_CHECK(vkCreatePipelineLayout(device, &pipeline_layout_create_info, nullptr, &m_pipelineLayout)); } @@ -541,11 +555,11 @@ void FaceApp::setup_descriptor_pool() std::vector pool_sizes = { { .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = kMaxTexture + .descriptorCount = (kTextureMax *2) }, { .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .descriptorCount = (kMaxTexture + 1) + .descriptorCount = ((kTextureMax + 1)*2) }, // 如果需要其他类型的描述符,在这里添加 }; @@ -554,7 +568,7 @@ void FaceApp::setup_descriptor_pool() descriptor_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; descriptor_pool_info.poolSizeCount = static_cast(pool_sizes.size()); descriptor_pool_info.pPoolSizes = pool_sizes.data(); - descriptor_pool_info.maxSets = kMaxTexture + (kMaxTexture + 1); + descriptor_pool_info.maxSets = kTextureMax + (kTextureMax + 1 + kTextureMax); descriptor_pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; VK_CHECK(vkCreateDescriptorPool(device, &descriptor_pool_info, nullptr, &descriptor_pool)); @@ -563,21 +577,31 @@ void FaceApp::setup_descriptor_pool() void FaceApp::setup_descriptor_set() { - m_descriptor_sets.resize(kMaxTexture); - std::vector layouts(kMaxTexture, m_descriptorSetLayout); + m_descriptor_sets_left.resize(kTextureMax); + std::vector layouts(kTextureMax, 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())); - update_descriptor_set(m_texs); + alloc_info.descriptorSetCount = m_descriptor_sets_left.size(); + VK_CHECK(vkAllocateDescriptorSets(device, &alloc_info, m_descriptor_sets_left.data())); + update_descriptor_set(m_texs_left, m_descriptor_sets_left); + + + m_descriptor_sets_right.resize(kTextureMax); + VK_CHECK(vkAllocateDescriptorSets(device, &alloc_info, m_descriptor_sets_right.data())); + update_descriptor_set(m_texs_left, m_descriptor_sets_right); } -void FaceApp::update_descriptor_set(vector& texs) +void FaceApp::update_descriptor_set(vector& texs, vector& descriptSet) { - for (int i = 0; i < kMaxTexture; ++i) + for (int i = 0; i < kTextureMax; ++i) { + if (texs[i].image == VK_NULL_HANDLE) + { + break; + } + VkDescriptorBufferInfo buffer_descriptor{}; buffer_descriptor.buffer = uniform_buffer_vs; buffer_descriptor.range = VK_WHOLE_SIZE; @@ -591,7 +615,7 @@ void FaceApp::update_descriptor_set(vector& texs) 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.dstSet = descriptSet[i]; write_descriptor_set_uniform.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; write_descriptor_set_uniform.dstBinding = 0; write_descriptor_set_uniform.pBufferInfo = &buffer_descriptor; @@ -600,7 +624,7 @@ void FaceApp::update_descriptor_set(vector& texs) 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.dstSet = descriptSet[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; @@ -610,14 +634,14 @@ void FaceApp::update_descriptor_set(vector& texs) { // 第二个纹理描述符 - 假设你的第二个纹理变量名为 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; + image_descriptor1.imageView = m_texs_thick[i].view; + image_descriptor1.sampler = m_texs_thick[i].sampler; + image_descriptor1.imageLayout = m_texs_thick[i].image_layout; // 添加第二个纹理的写入描述符 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.dstSet = descriptSet[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; @@ -656,34 +680,42 @@ void FaceApp::render(VkCommandBuffer commandBuffer, long long frameTime) 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); - float fsValues[2] = { 0, 0 }; + + vkCmdDraw(commandBuffer, 6, 1, 0, 0); + + + if (cur_left) + { + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &m_descriptor_sets_left[_curMotionIndex], 0, NULL); + } + else + { + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &m_descriptor_sets_right[_curMotionIndex], 0, NULL); + } + + float fsValues[3] = { myFloatValue, 0 , 0}; if (_curMotionIndex < _curMotions.size()) { if (_curFrameIndex < _curMotions[_curMotionIndex].frames.size()) { float ux = _curMotions[_curMotionIndex].frames[_curFrameIndex].x; float uy = _curMotions[_curMotionIndex].frames[_curFrameIndex].y; - fsValues[0] = ux; - fsValues[1] = uy; + fsValues[1] = ux; + fsValues[2] = uy; } } + //fsValues[1] = 0; + //fsValues[2] = 360; - vkCmdPushConstants(commandBuffer, m_pipelineLayout_bg, VK_SHADER_STAGE_FRAGMENT_BIT, 4, sizeof(fsValues), fsValues); - - vkCmdDraw(commandBuffer, 6, 1, 0, 0); + vkCmdPushConstants(commandBuffer, m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT| VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(fsValues), &fsValues); + //vkCmdPushConstants(commandBuffer, m_pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(fsValues), fsValues); - - vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &m_descriptor_sets[_curMotionIndex], 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); @@ -730,25 +762,24 @@ void FaceApp::initVulkan() Application::initVulkan(); createVmaAllocator(); LoadOBJ("face_picture_3dmax.obj", obj_vertices, obj_indices); - m_texs.resize(kMaxTexture); - m_texs_next.resize(kMaxTexture); + m_texs_left.resize(kTextureMax); + m_texs_right.resize(kTextureMax); if (kThick) { - m_texs_ex.resize(kMaxTexture); + m_texs_thick.resize(kTextureMax); } std::vector data = readFileUnsignedChar("dummy.png", false); - std::vector image; - unsigned w, h; - unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8); + unsigned error = lodepng::decode(dummy_data, dummy_w, dummy_h, data, LCT_RGBA, 8); - for (int i = 0; i < kMaxTexture; ++i) + for (int i = 0; i < kTextureInit; ++i) { - loadTexture(image, image.size(), w, h, m_texs[i], true, commandPool); - loadTexture(image, image.size(), w, h, m_texs_next[i], true, commandPool); + string id_str = std::to_string(i); + loadTexture(dummy_data, dummy_data.size(), dummy_w, dummy_h, m_texs_left[i], true, commandPool, "dummy.png_left_" + id_str); + loadTexture(dummy_data, dummy_data.size(), dummy_w, dummy_h, m_texs_right[i], true, commandPool, "dummy.png_right_" + id_str); if (kThick) { - loadTexture(image, image.size(), w, h, m_texs_ex[i], true, commandPool); + loadTexture(dummy_data, dummy_data.size(), dummy_w, dummy_h, m_texs_thick[i], true, commandPool, "dummy.png_thick_" + id_str); } } @@ -1096,16 +1127,12 @@ void FaceApp::setup_descriptor_set_layout_bg() pipeline_layout_create_info.pSetLayouts = &m_descriptorSetLayout_bg; - VkPushConstantRange pushConstantRanges[2]; - pushConstantRanges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; // 只在片段着色器中使用 + VkPushConstantRange pushConstantRanges[1]; + pushConstantRanges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; pushConstantRanges[0].offset = 0; - pushConstantRanges[0].size = sizeof(float); // 或者 sizeof(PushConstants) + pushConstantRanges[0].size = sizeof(float); - pushConstantRanges[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; // 只在片段着色器中使用 - pushConstantRanges[1].offset = sizeof(float); - pushConstantRanges[1].size = 2 * sizeof(float); // 或者 sizeof(PushConstants) - - pipeline_layout_create_info.pushConstantRangeCount = 2; + pipeline_layout_create_info.pushConstantRangeCount = 1; pipeline_layout_create_info.pPushConstantRanges = &pushConstantRanges[0]; VK_CHECK(vkCreatePipelineLayout(device, &pipeline_layout_create_info, nullptr, &m_pipelineLayout_bg)); @@ -1167,6 +1194,7 @@ void FaceApp::destroyTexture(VkDevice device, Texture& texture) { if (texture.device_memory != VK_NULL_HANDLE) { vkFreeMemory(device, texture.device_memory, nullptr); texture.device_memory = VK_NULL_HANDLE; + //std::cout << "vkFreeMemory device_memory " << texture.texture_path << std::endl; } if (texture.stagingBuffer != VK_NULL_HANDLE) @@ -1178,6 +1206,7 @@ void FaceApp::destroyTexture(VkDevice device, Texture& texture) { if (texture.stagingBufferMemory != VK_NULL_HANDLE) { vkFreeMemory(device, texture.stagingBufferMemory, nullptr); + //std::cout << "vkFreeMemory stagingBufferMemory " << texture.texture_path << std::endl; texture.stagingBufferMemory = VK_NULL_HANDLE; } } @@ -1256,7 +1285,8 @@ void FaceApp::cleanupResources(VkDevice device, VmaAllocator allocator) { } // 清空描述符集列表(不需要单独销毁,由描述符池管理) - m_descriptor_sets.clear(); + m_descriptor_sets_left.clear(); + m_descriptor_sets_right.clear(); } void FaceApp::cleanup() @@ -1277,18 +1307,19 @@ void FaceApp::cleanup() } cleanupResources(device, allocator); - for (int i = 0; i < this->m_texs.size(); ++i) + for (int i = 0; i < this->m_texs_left.size(); ++i) { - destroyTexture(device, m_texs[i]); + destroyTexture(device, m_texs_left[i]); } - for (int i = 0; i < this->m_texs_next.size(); ++i) + for (int i = 0; i < this->m_texs_right.size(); ++i) { - destroyTexture(device, m_texs_next[i]); + destroyTexture(device, m_texs_right[i]); } destroyTexture(device, tex_bg); vkDestroyCommandPool(device, commandPool, nullptr); + vkDestroyCommandPool(device, commandPool_ex, nullptr); Application::cleanup(); //if (allocator != VK_NULL_HANDLE) { // vmaDestroyAllocator(allocator); @@ -1340,6 +1371,7 @@ void FaceApp::drawFrame(long long frameTime) std::unique_lock lock(changeMotionMtx); + if (_curMotions.size() > 0) { static long long game_time = 0; @@ -1407,21 +1439,38 @@ string FaceApp::preLoadMotionList(string motion_list_str, Callback callback) void FaceApp::loadMotionThread() { + while (!_running) + { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + + vector* load_text = nullptr; + if (cur_left) + { + load_text = &m_texs_right; + } + else + { + load_text = &m_texs_left; + } + + vector& pre_texs = *load_text; for (int i = 0; i < _preLoadMotions.size(); ++i) { - if (!_running) + if (pre_texs[i].image == VK_NULL_HANDLE) { - break; + loadTexture(dummy_data, dummy_data.size(), dummy_w, dummy_h, pre_texs[i], true, commandPool, ""); } + #ifdef _WIN32 string path = "pic"; string path_name = path + "/" + _preLoadMotions[i].name + "/" + _preLoadMotions[i].name + "ex.png"; - loadTextureExample(UTF8ToWideString(path_name), m_texs_next[i], true, commandPool_ex); + loadTextureExample(UTF8ToWideString(path_name), pre_texs[i], true, commandPool_ex); #else string path = "pic"; string path_name = path + "/" + _preLoadMotions[i].name + "/" + _preLoadMotions[i].name + "ex.png"; - loadTexture(path_name, m_texs_next[i], true, commandPool_ex); + loadTexture(path_name, pre_texs[i], true, commandPool_ex); #endif // _WIN32 } @@ -1429,28 +1478,6 @@ void FaceApp::loadMotionThread() _callback_loadfinish(); } -void FaceApp::doChangeMotion() -{ - std::unique_lock lock_changeMotion(changeMotionMtx); - - - for (int i = 0; i < _preLoadMotions.size(); ++i) - { - destroyTexture(device, m_texs[i]); - } - - for (int i = 0; i < _preLoadMotions.size(); ++i) - { - m_texs[i] = m_texs_next[i]; - m_texs_next[i].reset(); - } - - update_descriptor_set(m_texs); - _curMotions = _preLoadMotions; - - _curFrameIndex = 0; - _curMotionIndex = 0; -} void FaceApp::changeMotionList(AnimationFinishedCallback callback, bool loop) { @@ -1458,9 +1485,40 @@ void FaceApp::changeMotionList(AnimationFinishedCallback callback, bool loop) { return; } + + std::unique_lock lock_changeMotion(changeMotionMtx); + + //for (int i = 0; i < _preLoadMotions.size(); ++i) + //{ + // destroyTexture(device, m_texs[i]); + //} + + //for (int i = 0; i < _preLoadMotions.size(); ++i) + //{ + // m_texs[i] = m_texs_next[i]; + // //m_texs_next[i].reset(); + //} + + + if (cur_left) + { + update_descriptor_set(m_texs_right, m_descriptor_sets_right); + cur_left = false; + } + else + { + update_descriptor_set(m_texs_left, m_descriptor_sets_left); + cur_left = true; + } + + _curMotions = _preLoadMotions; + + _curFrameIndex = 0; + _curMotionIndex = 0; + _animationFinishedCallback = callback; _animationLoop = loop; - _needChangeMotion = true; + } \ No newline at end of file diff --git a/vulkan/FaceApp.h b/vulkan/FaceApp.h index 64ceda7..408f1a2 100644 --- a/vulkan/FaceApp.h +++ b/vulkan/FaceApp.h @@ -94,7 +94,7 @@ private: void setup_descriptor_pool(); void setup_descriptor_set_layout(); void setup_descriptor_set(); - void update_descriptor_set(vector& texs); + void update_descriptor_set(vector& texs, vector& descriptSet); const bool kThick = false; void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size); @@ -115,12 +115,18 @@ private: VkPipeline m_graphicsPipeline = VK_NULL_HANDLE; VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE; - vector m_descriptor_sets; - const uint32_t kMaxTexture = 10; - vector m_texs; - vector m_texs_next; - vector m_texs_ex; - + vector m_descriptor_sets_left; + vector m_descriptor_sets_right; + const uint32_t kTextureInit = 1; + const uint32_t kTextureMax = 10; + vector m_texs_left; + vector m_texs_right; + bool cur_left = true; + //vector* _cur_texs; + vector m_texs_thick; + std::vector dummy_data; + unsigned dummy_w = 2880; + unsigned dummy_h = 2880; std::vector obj_vertices; std::vector obj_indices; @@ -155,8 +161,6 @@ public: void loadMotionThread(); std::thread worker_; bool _isLoadMotion = false; - bool _needChangeMotion = false; - void doChangeMotion(); Callback _callback_loadfinish; AnimationFinishedCallback _animationFinishedCallback; bool _animationLoop = true; diff --git a/vulkan/main.cpp b/vulkan/main.cpp index 1cf3da4..68027b9 100644 --- a/vulkan/main.cpp +++ b/vulkan/main.cpp @@ -120,7 +120,7 @@ int main() { //init_arg.motion = motion; - init_arg.action_fps = 20; + init_arg.action_fps = 10; init_arg.zoom = 1.5f; string json_str = json(init_arg).dump(); @@ -142,6 +142,8 @@ int main() { MotionList s_motions; s_motions.motions.push_back(motions["4"]); + s_motions.motions.push_back(motions["11"]); + s_motions.motions.push_back(motions["13"]); json j = s_motions; auto s = j.dump();