diff --git a/app/src/main/assets/dummy.png b/app/src/main/assets/dummy.png new file mode 100644 index 0000000..bccb906 Binary files /dev/null and b/app/src/main/assets/dummy.png differ diff --git a/example/src/main/assets/pic/11/11ex.png b/example/src/main/assets/pic/11/11ex.png new file mode 100644 index 0000000..0224f7a Binary files /dev/null and b/example/src/main/assets/pic/11/11ex.png differ diff --git a/example/src/main/assets/pic/12/12ex.png b/example/src/main/assets/pic/12/12ex.png new file mode 100644 index 0000000..66461e2 Binary files /dev/null and b/example/src/main/assets/pic/12/12ex.png differ diff --git a/example/src/main/assets/pic/13/13ex.png b/example/src/main/assets/pic/13/13ex.png new file mode 100644 index 0000000..a515786 Binary files /dev/null and b/example/src/main/assets/pic/13/13ex.png differ diff --git a/example/src/main/assets/pic/14/14ex.png b/example/src/main/assets/pic/14/14ex.png new file mode 100644 index 0000000..45f5056 Binary files /dev/null and b/example/src/main/assets/pic/14/14ex.png differ diff --git a/example/src/main/assets/pic/21/21ex.png b/example/src/main/assets/pic/21/21ex.png new file mode 100644 index 0000000..21e8d1c Binary files /dev/null and b/example/src/main/assets/pic/21/21ex.png differ diff --git a/example/src/main/assets/pic/23/23ex.png b/example/src/main/assets/pic/23/23ex.png new file mode 100644 index 0000000..9b84969 Binary files /dev/null and b/example/src/main/assets/pic/23/23ex.png differ diff --git a/example/src/main/assets/pic/24/24ex.png b/example/src/main/assets/pic/24/24ex.png new file mode 100644 index 0000000..c973f85 Binary files /dev/null and b/example/src/main/assets/pic/24/24ex.png differ diff --git a/example/src/main/assets/pic/26/26ex.png b/example/src/main/assets/pic/26/26ex.png new file mode 100644 index 0000000..8088925 Binary files /dev/null and b/example/src/main/assets/pic/26/26ex.png differ diff --git a/example/src/main/assets/pic/27/27ex.png b/example/src/main/assets/pic/27/27ex.png new file mode 100644 index 0000000..9cafdee Binary files /dev/null and b/example/src/main/assets/pic/27/27ex.png differ diff --git a/example/src/main/assets/pic/32/32ex.png b/example/src/main/assets/pic/32/32ex.png new file mode 100644 index 0000000..e84da38 Binary files /dev/null and b/example/src/main/assets/pic/32/32ex.png differ diff --git a/example/src/main/assets/pic/37/37ex.png b/example/src/main/assets/pic/37/37ex.png new file mode 100644 index 0000000..d44136a Binary files /dev/null and b/example/src/main/assets/pic/37/37ex.png differ diff --git a/example/src/main/assets/pic/4/4ex.png b/example/src/main/assets/pic/4/4ex.png new file mode 100644 index 0000000..7f37a6b Binary files /dev/null and b/example/src/main/assets/pic/4/4ex.png differ diff --git a/example/src/main/assets/pic/40/40ex.png b/example/src/main/assets/pic/40/40ex.png new file mode 100644 index 0000000..e5d6455 Binary files /dev/null and b/example/src/main/assets/pic/40/40ex.png differ diff --git a/example/src/main/assets/pic/45/45ex.png b/example/src/main/assets/pic/45/45ex.png new file mode 100644 index 0000000..058a92d Binary files /dev/null and b/example/src/main/assets/pic/45/45ex.png differ diff --git a/example/src/main/assets/pic/48/48ex.png b/example/src/main/assets/pic/48/48ex.png new file mode 100644 index 0000000..2d7794c Binary files /dev/null and b/example/src/main/assets/pic/48/48ex.png differ diff --git a/example/src/main/assets/pic/49/49ex.png b/example/src/main/assets/pic/49/49ex.png new file mode 100644 index 0000000..c91096e Binary files /dev/null and b/example/src/main/assets/pic/49/49ex.png differ diff --git a/example/src/main/assets/pic/5/5ex.png b/example/src/main/assets/pic/5/5ex.png new file mode 100644 index 0000000..572fdd2 Binary files /dev/null and b/example/src/main/assets/pic/5/5ex.png differ diff --git a/example/src/main/assets/pic/53/53ex.png b/example/src/main/assets/pic/53/53ex.png new file mode 100644 index 0000000..9fcd091 Binary files /dev/null and b/example/src/main/assets/pic/53/53ex.png differ diff --git a/example/src/main/assets/pic/56/56ex.png b/example/src/main/assets/pic/56/56ex.png new file mode 100644 index 0000000..428dc8b Binary files /dev/null and b/example/src/main/assets/pic/56/56ex.png differ diff --git a/example/src/main/assets/pic/59/59ex.png b/example/src/main/assets/pic/59/59ex.png new file mode 100644 index 0000000..ff202df Binary files /dev/null and b/example/src/main/assets/pic/59/59ex.png differ diff --git a/example/src/main/assets/pic/6/6ex.png b/example/src/main/assets/pic/6/6ex.png new file mode 100644 index 0000000..e2390ff Binary files /dev/null and b/example/src/main/assets/pic/6/6ex.png differ diff --git a/example/src/main/assets/pic/62/62ex.png b/example/src/main/assets/pic/62/62ex.png new file mode 100644 index 0000000..f44d7ed Binary files /dev/null and b/example/src/main/assets/pic/62/62ex.png differ diff --git a/example/src/main/assets/pic/65/65ex.png b/example/src/main/assets/pic/65/65ex.png new file mode 100644 index 0000000..03e0f58 Binary files /dev/null and b/example/src/main/assets/pic/65/65ex.png differ diff --git a/example/src/main/assets/pic/68/68ex.png b/example/src/main/assets/pic/68/68ex.png new file mode 100644 index 0000000..7c90cd1 Binary files /dev/null and b/example/src/main/assets/pic/68/68ex.png differ diff --git a/example/src/main/assets/pic/7/7ex.png b/example/src/main/assets/pic/7/7ex.png new file mode 100644 index 0000000..0d4bd28 Binary files /dev/null and b/example/src/main/assets/pic/7/7ex.png differ diff --git a/example/src/main/assets/pic/71/71ex.png b/example/src/main/assets/pic/71/71ex.png new file mode 100644 index 0000000..6445dc1 Binary files /dev/null and b/example/src/main/assets/pic/71/71ex.png differ diff --git a/example/src/main/assets/pic/76/76ex.png b/example/src/main/assets/pic/76/76ex.png new file mode 100644 index 0000000..152c544 Binary files /dev/null and b/example/src/main/assets/pic/76/76ex.png differ diff --git a/example/src/main/assets/pic/77/77ex.png b/example/src/main/assets/pic/77/77ex.png new file mode 100644 index 0000000..9a9580d Binary files /dev/null and b/example/src/main/assets/pic/77/77ex.png differ diff --git a/example/src/main/assets/pic/78/78ex.png b/example/src/main/assets/pic/78/78ex.png new file mode 100644 index 0000000..e5ea4bb Binary files /dev/null and b/example/src/main/assets/pic/78/78ex.png differ diff --git a/example/src/main/assets/pic/80/80ex.png b/example/src/main/assets/pic/80/80ex.png new file mode 100644 index 0000000..c9e1179 Binary files /dev/null and b/example/src/main/assets/pic/80/80ex.png differ diff --git a/example/src/main/assets/pic/81/81ex.png b/example/src/main/assets/pic/81/81ex.png new file mode 100644 index 0000000..c2755a0 Binary files /dev/null and b/example/src/main/assets/pic/81/81ex.png differ diff --git a/example/src/main/assets/pic/82/82ex.png b/example/src/main/assets/pic/82/82ex.png new file mode 100644 index 0000000..483c539 Binary files /dev/null and b/example/src/main/assets/pic/82/82ex.png differ diff --git a/example/src/main/assets/pic/motion_data_ex.json b/example/src/main/assets/pic/motion_data_ex.json new file mode 100644 index 0000000..00c15fd --- /dev/null +++ b/example/src/main/assets/pic/motion_data_ex.json @@ -0,0 +1,530 @@ +{ + "4": { + "001.png": { + "x": 0, + "y": 0 + }, + "002.png": { + "x": 360, + "y": 0 + }, + "003.png": { + "x": 720, + "y": 0 + }, + "004.png": { + "x": 1080, + "y": 0 + }, + "005.png": { + "x": 1440, + "y": 0 + }, + "006.png": { + "x": 1800, + "y": 0 + }, + "007.png": { + "x": 2160, + "y": 0 + }, + "008.png": { + "x": 2520, + "y": 0 + }, + "009.png": { + "x": 0, + "y": 360 + }, + "010.png": { + "x": 360, + "y": 360 + }, + "011.png": { + "x": 720, + "y": 360 + }, + "012.png": { + "x": 1080, + "y": 360 + }, + "013.png": { + "x": 1440, + "y": 360 + }, + "014.png": { + "x": 1800, + "y": 360 + }, + "015.png": { + "x": 2160, + "y": 360 + }, + "016.png": { + "x": 2520, + "y": 360 + }, + "017.png": { + "x": 0, + "y": 720 + }, + "018.png": { + "x": 360, + "y": 720 + }, + "019.png": { + "x": 720, + "y": 720 + }, + "020.png": { + "x": 1080, + "y": 720 + }, + "021.png": { + "x": 1440, + "y": 720 + }, + "022.png": { + "x": 1800, + "y": 720 + }, + "023.png": { + "x": 2160, + "y": 720 + }, + "024.png": { + "x": 2520, + "y": 720 + }, + "025.png": { + "x": 0, + "y": 1080 + }, + "026.png": { + "x": 360, + "y": 1080 + }, + "027.png": { + "x": 720, + "y": 1080 + }, + "028.png": { + "x": 1080, + "y": 1080 + }, + "029.png": { + "x": 1440, + "y": 1080 + }, + "030.png": { + "x": 1800, + "y": 1080 + }, + "031.png": { + "x": 2160, + "y": 1080 + }, + "032.png": { + "x": 2520, + "y": 1080 + }, + "033.png": { + "x": 0, + "y": 1440 + }, + "034.png": { + "x": 360, + "y": 1440 + }, + "035.png": { + "x": 720, + "y": 1440 + }, + "036.png": { + "x": 1080, + "y": 1440 + }, + "037.png": { + "x": 1440, + "y": 1440 + }, + "038.png": { + "x": 1800, + "y": 1440 + }, + "039.png": { + "x": 2160, + "y": 1440 + }, + "040.png": { + "x": 2520, + "y": 1440 + }, + "041.png": { + "x": 0, + "y": 1800 + }, + "042.png": { + "x": 360, + "y": 1800 + }, + "043.png": { + "x": 720, + "y": 1800 + }, + "044.png": { + "x": 1080, + "y": 1800 + }, + "045.png": { + "x": 1440, + "y": 1800 + }, + "046.png": { + "x": 1800, + "y": 1800 + }, + "047.png": { + "x": 2160, + "y": 1800 + }, + "048.png": { + "x": 2520, + "y": 1800 + }, + "049.png": { + "x": 0, + "y": 2160 + }, + "050.png": { + "x": 360, + "y": 2160 + }, + "051.png": { + "x": 720, + "y": 2160 + }, + "052.png": { + "x": 1080, + "y": 2160 + }, + "053.png": { + "x": 1440, + "y": 2160 + }, + "054.png": { + "x": 1800, + "y": 2160 + }, + "055.png": { + "x": 2160, + "y": 2160 + }, + "056.png": { + "x": 2520, + "y": 2160 + }, + "057.png": { + "x": 0, + "y": 2520 + }, + "058.png": { + "x": 360, + "y": 2520 + }, + "059.png": { + "x": 720, + "y": 2520 + }, + "060.png": { + "x": 1080, + "y": 2520 + } + }, + "5": { + "5.png": { + "x": 0, + "y": 0 + } + }, + "6": { + "6.png": { + "x": 0, + "y": 0 + } + }, + "7": { + "7.png": { + "x": 0, + "y": 0 + } + }, + "11": { + "002.png": { + "x": 0, + "y": 0 + }, + "003.png": { + "x": 360, + "y": 0 + }, + "004.png": { + "x": 720, + "y": 0 + }, + "005.png": { + "x": 1080, + "y": 0 + }, + "006.png": { + "x": 1440, + "y": 0 + }, + "007.png": { + "x": 1800, + "y": 0 + }, + "008.png": { + "x": 2160, + "y": 0 + }, + "009.png": { + "x": 2520, + "y": 0 + }, + "010.png": { + "x": 0, + "y": 360 + }, + "011.png": { + "x": 360, + "y": 360 + }, + "11.png": { + "x": 720, + "y": 360 + }, + "012.png": { + "x": 1080, + "y": 360 + } + }, + "12": { + "12.png": { + "x": 0, + "y": 0 + } + }, + "13": { + "001.png": { + "x": 0, + "y": 0 + }, + "002.png": { + "x": 360, + "y": 0 + }, + "003.png": { + "x": 720, + "y": 0 + }, + "004.png": { + "x": 1080, + "y": 0 + }, + "005.png": { + "x": 1440, + "y": 0 + }, + "006.png": { + "x": 1800, + "y": 0 + }, + "007.png": { + "x": 2160, + "y": 0 + }, + "008.png": { + "x": 2520, + "y": 0 + }, + "009.png": { + "x": 0, + "y": 360 + }, + "010.png": { + "x": 360, + "y": 360 + }, + "011.png": { + "x": 720, + "y": 360 + }, + "012.png": { + "x": 1080, + "y": 360 + }, + "013.png": { + "x": 1440, + "y": 360 + }, + "13.png": { + "x": 1800, + "y": 360 + }, + "014.png": { + "x": 2160, + "y": 360 + } + }, + "14": { + "14.png": { + "x": 0, + "y": 0 + } + }, + "21": { + "21.png": { + "x": 0, + "y": 0 + } + }, + "23": { + "23.png": { + "x": 0, + "y": 0 + } + }, + "24": { + "24.png": { + "x": 0, + "y": 0 + } + }, + "26": { + "26.png": { + "x": 0, + "y": 0 + } + }, + "27": { + "27.png": { + "x": 0, + "y": 0 + } + }, + "32": { + "32.png": { + "x": 0, + "y": 0 + } + }, + "37": { + "37.png": { + "x": 0, + "y": 0 + } + }, + "40": { + "40.png": { + "x": 0, + "y": 0 + } + }, + "45": { + "45.png": { + "x": 0, + "y": 0 + } + }, + "48": { + "48.png": { + "x": 0, + "y": 0 + } + }, + "49": { + "49.png": { + "x": 0, + "y": 0 + } + }, + "53": { + "53.png": { + "x": 0, + "y": 0 + } + }, + "56": { + "56.png": { + "x": 0, + "y": 0 + } + }, + "59": { + "59.png": { + "x": 0, + "y": 0 + } + }, + "62": { + "62.png": { + "x": 0, + "y": 0 + } + }, + "65": { + "65.png": { + "x": 0, + "y": 0 + } + }, + "68": { + "68.png": { + "x": 0, + "y": 0 + } + }, + "71": { + "71.png": { + "x": 0, + "y": 0 + } + }, + "76": { + "76.png": { + "x": 0, + "y": 0 + } + }, + "77": { + "77.png": { + "x": 0, + "y": 0 + } + }, + "78": { + "78.png": { + "x": 0, + "y": 0 + } + }, + "80": { + "80.png": { + "x": 0, + "y": 0 + } + }, + "81": { + "81.png": { + "x": 0, + "y": 0 + } + }, + "82": { + "82.png": { + "x": 0, + "y": 0 + } + } +} \ No newline at end of file diff --git a/python/combin_png.py b/python/combin_png.py new file mode 100644 index 0000000..accd60c --- /dev/null +++ b/python/combin_png.py @@ -0,0 +1,95 @@ +import json +from PIL import Image +import os + +# 全局变量定义分辨率 +RESIZE_TO = (360, 360) +LARGE_IMAGE_SIZE = (2880, 2880) +IMAGE_COUNT = 64 + +ROOT_DIR = '../example/src/main/assets/pic' + +def load_json(file_path): + with open(file_path, 'r') as file: + return json.load(file) + +def remove_white_border(image): + """ + 去除图片边缘的一个像素宽的白色边框。 + :param image: 输入的PIL Image对象。 + :return: 处理后的PIL Image对象。 + """ + # 获取图像尺寸 + width, height = image.size + + # 定义白色阈值,允许一定的误差范围 + white_threshold = (250, 250, 250) + + # 查找左边界 + left = 0 + while left < width and all(image.getpixel((left, y))[:3] >= white_threshold for y in range(height)): + left += 1 + + # 查找右边界 + right = width - 1 + while right > 0 and all(image.getpixel((right, y))[:3] >= white_threshold for y in range(height)): + right -= 1 + + # 查找上边界 + top = 0 + while top < height and all(image.getpixel((x, top))[:3] >= white_threshold for x in range(width)): + top += 1 + + # 查找下边界 + bottom = height - 1 + while bottom > 0 and all(image.getpixel((x, bottom))[:3] >= white_threshold for x in range(width)): + bottom -= 1 + + # 如果发现有白色边框,则裁剪它们 + if left < right and top < bottom: + image = image.crop((left, top, right + 1, bottom + 1)) + + return image + +def resize_image(image_path): + image = Image.open(image_path).convert('RGBA') + image = remove_white_border(image) + return image.resize(RESIZE_TO) + +def main(json_file_path): + # 确保使用完整路径 + json_file_path = os.path.join(ROOT_DIR, json_file_path) + data = load_json(json_file_path) + + new_data = {} + + for folder_name, images in data.items(): + large_image = Image.new('RGBA', LARGE_IMAGE_SIZE, color=(0, 0, 0, 0)) + images_coordinates = {} + index = 0 + + for image_name in images: + if index >= IMAGE_COUNT: + break + # 图片位于子文件夹内 + img_path = os.path.join(ROOT_DIR, folder_name, image_name) + img = resize_image(img_path) + x = (index % 8) * RESIZE_TO[0] + y = (index // 8) * RESIZE_TO[1] + large_image.paste(img, (x, y)) + images_coordinates[image_name] = {'x': x, 'y': y} + index += 1 + + output_image_path = os.path.join(ROOT_DIR, folder_name, f"{folder_name}ex.png") + large_image.save(output_image_path, format='png') + + # 将坐标信息直接保存到new_data字典中 + new_data[folder_name] = images_coordinates + + # 输出新的json文件 + output_json_path = os.path.join(ROOT_DIR, 'motion_data_ex.json') + with open(output_json_path, 'w') as outfile: + json.dump(new_data, outfile, indent=4) + +# 使用示例 +main('motion_data.json') \ No newline at end of file diff --git a/vulkan/Application.cpp b/vulkan/Application.cpp index d4e4e2e..86b5408 100644 --- a/vulkan/Application.cpp +++ b/vulkan/Application.cpp @@ -404,6 +404,17 @@ void Application::createCommandPool() { if (vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) { throw std::runtime_error("failed to create command pool!"); } + + queueFamilyIndices = findQueueFamilies(physicalDevice, surface); + + VkCommandPoolCreateInfo poolInfo_ex{}; + poolInfo_ex.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + poolInfo_ex.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value(); + poolInfo_ex.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; // 添加标志 + + if (vkCreateCommandPool(device, &poolInfo_ex, nullptr, &commandPool_ex) != VK_SUCCESS) { + throw std::runtime_error("failed to create command pool!"); + } } void Application::createCommandBuffer() @@ -641,30 +652,30 @@ uint32_t Application::findMemoryType(VkPhysicalDevice physicalDevice, uint32_t t throw std::runtime_error("Failed to find suitable memory type!"); } -void Application::loadTexture(std::string path, Texture& tex, bool srgb) +void Application::loadTexture(std::string path, Texture& tex, bool srgb, VkCommandPool pool) { std::vector data = readFileUnsignedChar(path, false); 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); + processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb, pool); //return tex; } -void Application::loadTexture(std::vector& image_data, size_t image_size, int w, int h, Texture& tex, bool srgb) +void Application::loadTexture(std::vector& image_data, size_t image_size, int w, int h, Texture& tex, bool srgb, VkCommandPool pool) { - processWithVulkan(image_data.data(), w, h, w * 4, image_size, tex, srgb); + processWithVulkan(image_data.data(), w, h, w * 4, image_size, tex, srgb, pool); //return tex; } #ifdef _WIN32 -void Application::loadTextureExample(std::wstring path, Texture& tex, bool srgb) +void Application::loadTextureExample(std::wstring path, Texture& tex, bool srgb, VkCommandPool pool) { std::vector data = readFileUnsignedCharWin32(path, true); 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); + processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb, pool); //return tex; } @@ -772,7 +783,7 @@ void Application::createTexture(VkDevice device, VkPhysicalDevice physicalDevice texture.device = device; } -void Application::processWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& out_texture, bool srgb) +void Application::processWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& out_texture, bool srgb, VkCommandPool pool) { std::unique_lock lock(mtx); if (out_texture.image == VK_NULL_HANDLE) @@ -781,7 +792,7 @@ void Application::processWithVulkan(uint8_t* data, int width, int height, int ro } - updateTexture(device, physicalDevice, commandPool, graphicsQueue, data, width, height, + updateTexture(device, physicalDevice, pool, graphicsQueue, data, width, height, rowStride, dataSize, out_texture); } diff --git a/vulkan/Application.h b/vulkan/Application.h index 60f667a..74df371 100644 --- a/vulkan/Application.h +++ b/vulkan/Application.h @@ -54,7 +54,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); + void processWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& out_texture, bool srgb, VkCommandPool pool); protected: @@ -73,7 +73,9 @@ protected: std::vector swapChainFramebuffers; // 帧缓冲区 VkQueue presentQueue; // 呈现队列 +public: VkCommandPool commandPool; + VkCommandPool commandPool_ex; std::vector commandBuffers; std::vector imageAvailableSemaphores; // 每个交换链图像一个 std::vector renderFinishedSemaphores; // 每个交换链图像一个 @@ -85,10 +87,10 @@ protected: protected: - void loadTexture(std::string path, Texture& tex, bool srgb); - void loadTexture(std::vector& image_data, size_t image_size, int w, int h, Texture& tex, bool srgb); + 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); #ifdef _WIN32 - void loadTextureExample(std::wstring path, Texture& tex, bool srgb); + void loadTextureExample(std::wstring path, Texture& tex, bool srgb, VkCommandPool pool); #endif uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter, diff --git a/vulkan/FaceApp.cpp b/vulkan/FaceApp.cpp index fcde49a..7ba1efd 100644 --- a/vulkan/FaceApp.cpp +++ b/vulkan/FaceApp.cpp @@ -17,6 +17,9 @@ FaceApp::FaceApp(/* args */) FaceApp::~FaceApp() { + if (worker_.joinable()) { + worker_.join(); + } } void ReceiveFacePoint(float* pos, int pointCount, int width, int height) @@ -106,7 +109,8 @@ void TextureLoadProcessWithVulkan(uint8_t* data, int width, int height, int rowS oldestFrame.rowStride, oldestFrame.dataSize, tex_bg, - false + false, + FaceApp::Get()->commandPool ); frameQueue.pop(); @@ -660,7 +664,7 @@ void FaceApp::render(VkCommandBuffer commandBuffer, long long frameTime) - vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &m_descriptor_sets[_curTexIndex], 0, NULL); + 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); @@ -718,22 +722,22 @@ void FaceApp::initVulkan() m_texs_ex.resize(kMaxTexture); } - std::vector data = readFileUnsignedChar("demo0.png", false); + std::vector data = readFileUnsignedChar("dummy.png", false); std::vector image; unsigned w, h; unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8); for (int i = 0; i < kMaxTexture; ++i) { - loadTexture(image, image.size(), w, h, m_texs[i], true); - loadTexture(image, image.size(), w, h, m_texs_next[i], true); + loadTexture(image, image.size(), w, h, m_texs[i], true, commandPool); + loadTexture(image, image.size(), w, h, m_texs_next[i], true, commandPool); if (kThick) { - loadTexture(image, image.size(), w, h, m_texs_ex[i], true); + loadTexture(image, image.size(), w, h, m_texs_ex[i], true, commandPool); } } - loadTexture("out.png", tex_bg, true); + loadTexture("out.png", tex_bg, true, commandPool); createVertexBuffer(); createUniformBuffer(); setup_descriptor_pool(); @@ -1271,6 +1275,8 @@ void FaceApp::cleanup() // vmaDestroyAllocator(allocator); // allocator = VK_NULL_HANDLE; //} + + } @@ -1287,57 +1293,74 @@ void FaceApp::drawFrame(long long frameTime) return; } - if (_motionState == loading_next_motion) - { - int i = _nextMotionIndex; - //for (int i = 0; i < _curMotion.png_names.size(); ++i) - { - -#ifdef _WIN32 - string path = "pic"; - string path_name = path + "/" + _nextMotion.type + "/" + _nextMotion.png_names[i];// +std::to_string(i) + ".png"; - loadTextureExample(UTF8ToWideString(path_name), m_texs_next[i], true); -#else - //string path = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type; - string path = "pic"; - string path_name = path + "/" + _nextMotion.type + "/" + _nextMotion.png_names[i];// +std::to_string(i) + ".png"; - loadTexture(path_name, m_texs_next[i], true); -#endif // _WIN32 - - _nextMotionIndex++; - if (_nextMotionIndex >= _nextMotion.png_names.size()) - { - _motionState = load_next_motion_finished; - _callback(_nextMotion.type); - } - } - } +// if (_motionState == loading_next_motion) +// { +// int i = _nextMotionIndex; +// //for (int i = 0; i < _curMotion.png_names.size(); ++i) +// { +// +//#ifdef _WIN32 +// string path = "pic"; +// string path_name = path + "/" + _nextMotion.name + "/" + _nextMotion.png_names[i];// +std::to_string(i) + ".png"; +// loadTextureExample(UTF8ToWideString(path_name), m_texs_next[i], true); +//#else +// //string path = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type; +// string path = "pic"; +// string path_name = path + "/" + _nextMotion.type + "/" + _nextMotion.png_names[i];// +std::to_string(i) + ".png"; +// loadTexture(path_name, m_texs_next[i], true); +//#endif // _WIN32 +// +// _nextMotionIndex++; +// if (_nextMotionIndex >= _nextMotion.png_names.size()) +// { +// _motionState = load_next_motion_finished; +// _callback_loadfinish(_nextMotion.name); +// } +// } +// } std::unique_lock lock(changeMotionMtx); - static long long game_time = 0; - game_time += frameTime; - long long actionTime = (1000 / _initArg.action_fps); - if (game_time > actionTime) - { - _curTexIndex++; - if (_curTexIndex >= _curMotion_png_size) - { - if(_animationFinishedCallback != nullptr) - { - _animationFinishedCallback(); - } - if (_animationLoop) + if (_curMotions.size() > 0) + { + static long long game_time = 0; + game_time += frameTime; + long long actionTime = (1000 / _initArg.action_fps); + if (game_time > actionTime) + { + if (_curFrameIndex < _curMotions[_curMotionIndex].frames.size() - 1) { - _curTexIndex = 0; + _curFrameIndex += 1; } else { - _curTexIndex = _curMotion_png_size - 1; + if (_curMotionIndex < _curMotions.size() - 1) + { + _curMotionIndex++; + _curFrameIndex = 0; + } + else + { + if (_animationFinishedCallback != nullptr) + { + _animationFinishedCallback(); + } + + if (_animationLoop) + { + _curMotionIndex = 0; + _curFrameIndex = 0; + } + else + { + _animationFinishedCallback = nullptr; + } + } } + game_time = game_time - actionTime; } - game_time = game_time - actionTime; } + Application::drawFrame(frameTime); } @@ -1347,36 +1370,52 @@ void FaceApp::drawFrame(long long frameTime) // changeMotion(motion); //} -string FaceApp::preReadyMotion(const std::string& json, Callback callback) +string FaceApp::preLoadMotionList(const vector& motions, Callback callback) { - if (_motionState == loading_next_motion) + if (_isLoadMotion) { - return "busy on loading:" + _nextMotion.type; + return "failue load not finished"; } - else if (_motionState == load_next_motion_finished) + _isLoadMotion = true; + _callback_loadfinish = callback; + _preLoadMotions.clear(); + for (auto s : motions) { - return "waitting change next action:" + _nextMotion.type; + json j = json::parse(s); + Motion motion = j.get(); + _preLoadMotions.push_back(motion); } - else if (_motionState == ready) - { - Motion motion = json::parse(json); - _nextMotion = motion; - _motionState = loading_next_motion; - _nextMotionIndex = 0; - _callback = callback; - return "success"; - } - return "failure"; + worker_ = std::thread(&FaceApp::loadMotionThread, this); + return "ok"; } -void FaceApp::changeMotion(const string motion_type, AnimationFinishedCallback callback, bool loop) +void FaceApp::loadMotionThread() { - if (_curMotion_type == motion_type) + for (int i = 0; i < _preLoadMotions.size(); ++i) { - return; - } + if (!_running) + { + break; + } - if (_motionState != load_next_motion_finished) +#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); +#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); +#endif // _WIN32 + } + + _isLoadMotion = false; + _callback_loadfinish(); +} + +void FaceApp::changeMotionList(AnimationFinishedCallback callback, bool loop) +{ + if (_isLoadMotion) { return; } @@ -1384,24 +1423,23 @@ void FaceApp::changeMotion(const string motion_type, AnimationFinishedCallback c std::unique_lock lock_changeMotion(changeMotionMtx); - for (int i = 0; i < _nextMotion.png_names.size(); ++i) + for (int i = 0; i < _preLoadMotions.size(); ++i) { destroyTexture(device, m_texs[i]); } - for (int i = 0; i < _nextMotion.png_names.size(); ++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); - _curMotion_type = motion_type; - _curMotion_png_size = _nextMotion.png_names.size(); - _motionState = ready; + _curMotions = _preLoadMotions; _animationFinishedCallback = callback; _animationLoop = loop; - _curTexIndex = 0; + _curFrameIndex = 0; + _curMotionIndex = 0; // for (int i = 0; i < _curMotion.png_names.size(); ++i) diff --git a/vulkan/FaceApp.h b/vulkan/FaceApp.h index ba87ceb..9112027 100644 --- a/vulkan/FaceApp.h +++ b/vulkan/FaceApp.h @@ -12,13 +12,20 @@ using namespace std; using json = nlohmann::json; +struct Frame { + string name; + float x; + float y; + NLOHMANN_DEFINE_TYPE_INTRUSIVE(Frame, name, x, y) +}; + struct Motion { - string type; - vector png_names; + string name; + vector< Frame> frames; string getMotionId() { - return type; + return name; } - NLOHMANN_DEFINE_TYPE_INTRUSIVE(Motion, type, png_names) + NLOHMANN_DEFINE_TYPE_INTRUSIVE(Motion, name, frames) }; struct InitArg @@ -34,7 +41,7 @@ struct PushConstants { float myValue; }; -using Callback = std::function; +using Callback = std::function; using AnimationFinishedCallback = std::function; class FaceApp :public Application @@ -103,7 +110,7 @@ private: VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE; vector m_descriptor_sets; - const uint32_t kMaxTexture = 60; + const uint32_t kMaxTexture = 10; vector m_texs; vector m_texs_next; vector m_texs_ex; @@ -139,28 +146,35 @@ private: public: - Callback _callback; + void loadMotionThread(); + std::thread worker_; + bool _isLoadMotion = false; + Callback _callback_loadfinish; AnimationFinishedCallback _animationFinishedCallback; bool _animationLoop = true; - string preReadyMotion(const std::string& json, Callback callback); - void changeMotion(const string motion_type, AnimationFinishedCallback callback, bool loop); + string preLoadMotionList(const vector& motions, Callback callback); + vector_preLoadMotions; + vector_curMotions; + void changeMotionList(AnimationFinishedCallback callback, bool loop); + //void changeMotion(Motion& motion); InitArg _initArg; //Motion _curMotion; - string _curMotion_type; - int _curMotion_png_size; - Motion _nextMotion; - int _nextMotionIndex; + //string _curMotion_type; + //int _curMotion_png_size; + //Motion _nextMotion; + //int _nextMotionIndex; - enum MotionState { - ready, - loading_next_motion, - load_next_motion_finished, - }; + //enum MotionState { + // ready, + // loading_next_motion, + // load_next_motion_finished, + //}; - MotionState _motionState = ready; + //MotionState _motionState = ready; - int _curTexIndex = 0; + int _curFrameIndex = 0; + int _curMotionIndex = 0; void SetInitArg(const char* arg); void drawFrame(long long frameTime)override; diff --git a/vulkan/main.cpp b/vulkan/main.cpp index 3deda09..8e52759 100644 --- a/vulkan/main.cpp +++ b/vulkan/main.cpp @@ -47,9 +47,44 @@ void CppAnimationFinishedCallback() std::cout << "call CppAnimationFinishedCallback\n"; } -void CppCallback(const string& motion_type) +void CppCallback() { - g_app->changeMotion(motion_type.c_str(), CppAnimationFinishedCallback, true); + g_app->changeMotionList(CppAnimationFinishedCallback, true); +} + +// 读取JSON文件并填充到motions容器中 +void loadMotions(const std::string& filePath, std::map& motions) { + // 读取json文件 + std::ifstream i(filePath); + if (!i.is_open()) { + std::cerr << "无法打开文件" << std::endl; + return; + } + + json j; + try { + i >> j; + } + catch (json::parse_error& ex) { // 捕获解析错误 + std::cerr << "JSON解析错误: " << ex.what() << std::endl; + return; + } + + // 遍历json对象并填充到motions中 + for (auto& motionEntry : j.items()) { + Motion motion; + motion.name = motionEntry.key(); + + for (auto& frameEntry : motionEntry.value().items()) { + Frame frame; + frame.name = frameEntry.key(); + frame.x = frameEntry.value()["x"].get(); + frame.y = frameEntry.value()["y"].get(); + motion.frames.push_back(frame); + } + + motions[motion.getMotionId()] = motion; + } } @@ -62,23 +97,25 @@ int main() { InitArg init_arg; Motion motion; - motion.type = "4"; + motion.name = "4"; //motion.png_names.push_back("4.png"); - for (int i = 1; i < 61; ++i) - { - if (i < 10) - { - motion.png_names.push_back("00" + std::to_string(i) + ".png"); - } - else - { - motion.png_names.push_back("0" + std::to_string(i) + ".png"); + //for (int i = 1; i < 61; ++i) + //{ + // if (i < 10) + // { + // motion.png_names.push_back("00" + std::to_string(i) + ".png"); + // } + // else + // { + // motion.png_names.push_back("0" + std::to_string(i) + ".png"); - } - - } + // } + // + //} -# + + std::map motions; + loadMotions("example/src/main/assets/pic/motion_data_ex.json", motions); //init_arg.motion = motion; @@ -103,8 +140,11 @@ int main() { std::cout << "Warning: Empty motion string" << std::endl; } + vector s_motions; + json j = motions["4"]; + s_motions.push_back(j.dump()); - app.preReadyMotion(motion_str, CppCallback); + app.preLoadMotionList(s_motions, CppCallback); app.mainLoop(); //try { // app.mainLoop();