save code
|
After Width: | Height: | Size: 445 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 205 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 35 KiB |
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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')
|
||||||
@@ -404,6 +404,17 @@ void Application::createCommandPool() {
|
|||||||
if (vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) {
|
if (vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create command pool!");
|
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()
|
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!");
|
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<unsigned char> data = readFileUnsignedChar(path, false);
|
std::vector<unsigned char> data = readFileUnsignedChar(path, false);
|
||||||
std::vector<unsigned char> image;
|
std::vector<unsigned char> image;
|
||||||
unsigned w, h;
|
unsigned w, h;
|
||||||
unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8);
|
unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8);
|
||||||
processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb);
|
processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb, pool);
|
||||||
//return tex;
|
//return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::loadTexture(std::vector<unsigned char>& image_data, size_t image_size, int w, int h, Texture& tex, bool srgb)
|
void Application::loadTexture(std::vector<unsigned char>& 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;
|
//return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#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<unsigned char> data = readFileUnsignedCharWin32(path, true);
|
std::vector<unsigned char> data = readFileUnsignedCharWin32(path, true);
|
||||||
std::vector<unsigned char> image;
|
std::vector<unsigned char> image;
|
||||||
unsigned w, h;
|
unsigned w, h;
|
||||||
unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8);
|
unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8);
|
||||||
processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb);
|
processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb, pool);
|
||||||
//return tex;
|
//return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -772,7 +783,7 @@ void Application::createTexture(VkDevice device, VkPhysicalDevice physicalDevice
|
|||||||
texture.device = device;
|
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<std::mutex> lock(mtx);
|
std::unique_lock<std::mutex> lock(mtx);
|
||||||
if (out_texture.image == VK_NULL_HANDLE)
|
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);
|
rowStride, dataSize, out_texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public:
|
|||||||
virtual void render(VkCommandBuffer commandBuffer, long long frameTime);
|
virtual void render(VkCommandBuffer commandBuffer, long long frameTime);
|
||||||
virtual bool isInited() { return inited; }
|
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:
|
protected:
|
||||||
|
|
||||||
@@ -73,7 +73,9 @@ protected:
|
|||||||
std::vector<VkFramebuffer> swapChainFramebuffers; // 帧缓冲区
|
std::vector<VkFramebuffer> swapChainFramebuffers; // 帧缓冲区
|
||||||
VkQueue presentQueue; // 呈现队列
|
VkQueue presentQueue; // 呈现队列
|
||||||
|
|
||||||
|
public:
|
||||||
VkCommandPool commandPool;
|
VkCommandPool commandPool;
|
||||||
|
VkCommandPool commandPool_ex;
|
||||||
std::vector<VkCommandBuffer> commandBuffers;
|
std::vector<VkCommandBuffer> commandBuffers;
|
||||||
std::vector<VkSemaphore> imageAvailableSemaphores; // 每个交换链图像一个
|
std::vector<VkSemaphore> imageAvailableSemaphores; // 每个交换链图像一个
|
||||||
std::vector<VkSemaphore> renderFinishedSemaphores; // 每个交换链图像一个
|
std::vector<VkSemaphore> renderFinishedSemaphores; // 每个交换链图像一个
|
||||||
@@ -85,10 +87,10 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void loadTexture(std::string path, Texture& tex, bool srgb);
|
void loadTexture(std::string path, Texture& tex, bool srgb, VkCommandPool pool);
|
||||||
void loadTexture(std::vector<unsigned char>& image_data, size_t image_size, int w, int h, Texture& tex, bool srgb);
|
void loadTexture(std::vector<unsigned char>& image_data, size_t image_size, int w, int h, Texture& tex, bool srgb, VkCommandPool pool);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
void loadTextureExample(std::wstring path, Texture& tex, bool srgb);
|
void loadTextureExample(std::wstring path, Texture& tex, bool srgb, VkCommandPool pool);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter,
|
uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter,
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ FaceApp::FaceApp(/* args */)
|
|||||||
|
|
||||||
FaceApp::~FaceApp()
|
FaceApp::~FaceApp()
|
||||||
{
|
{
|
||||||
|
if (worker_.joinable()) {
|
||||||
|
worker_.join();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReceiveFacePoint(float* pos, int pointCount, int width, int height)
|
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.rowStride,
|
||||||
oldestFrame.dataSize,
|
oldestFrame.dataSize,
|
||||||
tex_bg,
|
tex_bg,
|
||||||
false
|
false,
|
||||||
|
FaceApp::Get()->commandPool
|
||||||
);
|
);
|
||||||
|
|
||||||
frameQueue.pop();
|
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);
|
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline);
|
||||||
|
|
||||||
vkCmdPushConstants(commandBuffer, m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float), &myFloatValue);
|
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);
|
m_texs_ex.resize(kMaxTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unsigned char> data = readFileUnsignedChar("demo0.png", false);
|
std::vector<unsigned char> data = readFileUnsignedChar("dummy.png", false);
|
||||||
std::vector<unsigned char> image;
|
std::vector<unsigned char> image;
|
||||||
unsigned w, h;
|
unsigned w, h;
|
||||||
unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8);
|
unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8);
|
||||||
|
|
||||||
for (int i = 0; i < kMaxTexture; ++i)
|
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[i], true, commandPool);
|
||||||
loadTexture(image, image.size(), w, h, m_texs_next[i], true);
|
loadTexture(image, image.size(), w, h, m_texs_next[i], true, commandPool);
|
||||||
if (kThick)
|
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();
|
createVertexBuffer();
|
||||||
createUniformBuffer();
|
createUniformBuffer();
|
||||||
setup_descriptor_pool();
|
setup_descriptor_pool();
|
||||||
@@ -1271,6 +1275,8 @@ void FaceApp::cleanup()
|
|||||||
// vmaDestroyAllocator(allocator);
|
// vmaDestroyAllocator(allocator);
|
||||||
// allocator = VK_NULL_HANDLE;
|
// allocator = VK_NULL_HANDLE;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1287,57 +1293,74 @@ void FaceApp::drawFrame(long long frameTime)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_motionState == loading_next_motion)
|
// if (_motionState == loading_next_motion)
|
||||||
{
|
// {
|
||||||
int i = _nextMotionIndex;
|
// int i = _nextMotionIndex;
|
||||||
//for (int i = 0; i < _curMotion.png_names.size(); ++i)
|
// //for (int i = 0; i < _curMotion.png_names.size(); ++i)
|
||||||
{
|
// {
|
||||||
|
//
|
||||||
#ifdef _WIN32
|
//#ifdef _WIN32
|
||||||
string path = "pic";
|
// string path = "pic";
|
||||||
string path_name = path + "/" + _nextMotion.type + "/" + _nextMotion.png_names[i];// +std::to_string(i) + ".png";
|
// string path_name = path + "/" + _nextMotion.name + "/" + _nextMotion.png_names[i];// +std::to_string(i) + ".png";
|
||||||
loadTextureExample(UTF8ToWideString(path_name), m_texs_next[i], true);
|
// loadTextureExample(UTF8ToWideString(path_name), m_texs_next[i], true);
|
||||||
#else
|
//#else
|
||||||
//string path = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type;
|
// //string path = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type;
|
||||||
string path = "pic";
|
// string path = "pic";
|
||||||
string path_name = path + "/" + _nextMotion.type + "/" + _nextMotion.png_names[i];// +std::to_string(i) + ".png";
|
// string path_name = path + "/" + _nextMotion.type + "/" + _nextMotion.png_names[i];// +std::to_string(i) + ".png";
|
||||||
loadTexture(path_name, m_texs_next[i], true);
|
// loadTexture(path_name, m_texs_next[i], true);
|
||||||
#endif // _WIN32
|
//#endif // _WIN32
|
||||||
|
//
|
||||||
_nextMotionIndex++;
|
// _nextMotionIndex++;
|
||||||
if (_nextMotionIndex >= _nextMotion.png_names.size())
|
// if (_nextMotionIndex >= _nextMotion.png_names.size())
|
||||||
{
|
// {
|
||||||
_motionState = load_next_motion_finished;
|
// _motionState = load_next_motion_finished;
|
||||||
_callback(_nextMotion.type);
|
// _callback_loadfinish(_nextMotion.name);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
std::unique_lock lock(changeMotionMtx);
|
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
|
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);
|
Application::drawFrame(frameTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1347,36 +1370,52 @@ void FaceApp::drawFrame(long long frameTime)
|
|||||||
// changeMotion(motion);
|
// changeMotion(motion);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
string FaceApp::preReadyMotion(const std::string& json, Callback callback)
|
string FaceApp::preLoadMotionList(const vector<string>& 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<Motion>();
|
||||||
|
_preLoadMotions.push_back(motion);
|
||||||
}
|
}
|
||||||
else if (_motionState == ready)
|
worker_ = std::thread(&FaceApp::loadMotionThread, this);
|
||||||
{
|
return "ok";
|
||||||
Motion motion = json::parse(json);
|
|
||||||
_nextMotion = motion;
|
|
||||||
_motionState = loading_next_motion;
|
|
||||||
_nextMotionIndex = 0;
|
|
||||||
_callback = callback;
|
|
||||||
return "success";
|
|
||||||
}
|
|
||||||
return "failure";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_motionState != load_next_motion_finished)
|
_isLoadMotion = false;
|
||||||
|
_callback_loadfinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FaceApp::changeMotionList(AnimationFinishedCallback callback, bool loop)
|
||||||
|
{
|
||||||
|
if (_isLoadMotion)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1384,24 +1423,23 @@ void FaceApp::changeMotion(const string motion_type, AnimationFinishedCallback c
|
|||||||
std::unique_lock<std::mutex> lock_changeMotion(changeMotionMtx);
|
std::unique_lock<std::mutex> 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]);
|
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[i] = m_texs_next[i];
|
||||||
m_texs_next[i].reset();
|
m_texs_next[i].reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
update_descriptor_set(m_texs);
|
update_descriptor_set(m_texs);
|
||||||
_curMotion_type = motion_type;
|
_curMotions = _preLoadMotions;
|
||||||
_curMotion_png_size = _nextMotion.png_names.size();
|
|
||||||
_motionState = ready;
|
|
||||||
_animationFinishedCallback = callback;
|
_animationFinishedCallback = callback;
|
||||||
_animationLoop = loop;
|
_animationLoop = loop;
|
||||||
_curTexIndex = 0;
|
_curFrameIndex = 0;
|
||||||
|
_curMotionIndex = 0;
|
||||||
|
|
||||||
|
|
||||||
// for (int i = 0; i < _curMotion.png_names.size(); ++i)
|
// for (int i = 0; i < _curMotion.png_names.size(); ++i)
|
||||||
|
|||||||
@@ -12,13 +12,20 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
struct Frame {
|
||||||
|
string name;
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Frame, name, x, y)
|
||||||
|
};
|
||||||
|
|
||||||
struct Motion {
|
struct Motion {
|
||||||
string type;
|
string name;
|
||||||
vector<string> png_names;
|
vector< Frame> frames;
|
||||||
string getMotionId() {
|
string getMotionId() {
|
||||||
return type;
|
return name;
|
||||||
}
|
}
|
||||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Motion, type, png_names)
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Motion, name, frames)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InitArg
|
struct InitArg
|
||||||
@@ -34,7 +41,7 @@ struct PushConstants {
|
|||||||
float myValue;
|
float myValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
using Callback = std::function<void(const std::string&)>;
|
using Callback = std::function<void()>;
|
||||||
using AnimationFinishedCallback = std::function<void()>;
|
using AnimationFinishedCallback = std::function<void()>;
|
||||||
|
|
||||||
class FaceApp :public Application
|
class FaceApp :public Application
|
||||||
@@ -103,7 +110,7 @@ private:
|
|||||||
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
||||||
VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE;
|
VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE;
|
||||||
vector<VkDescriptorSet> m_descriptor_sets;
|
vector<VkDescriptorSet> m_descriptor_sets;
|
||||||
const uint32_t kMaxTexture = 60;
|
const uint32_t kMaxTexture = 10;
|
||||||
vector<Texture> m_texs;
|
vector<Texture> m_texs;
|
||||||
vector<Texture> m_texs_next;
|
vector<Texture> m_texs_next;
|
||||||
vector<Texture> m_texs_ex;
|
vector<Texture> m_texs_ex;
|
||||||
@@ -139,28 +146,35 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Callback _callback;
|
void loadMotionThread();
|
||||||
|
std::thread worker_;
|
||||||
|
bool _isLoadMotion = false;
|
||||||
|
Callback _callback_loadfinish;
|
||||||
AnimationFinishedCallback _animationFinishedCallback;
|
AnimationFinishedCallback _animationFinishedCallback;
|
||||||
bool _animationLoop = true;
|
bool _animationLoop = true;
|
||||||
string preReadyMotion(const std::string& json, Callback callback);
|
string preLoadMotionList(const vector<string>& motions, Callback callback);
|
||||||
void changeMotion(const string motion_type, AnimationFinishedCallback callback, bool loop);
|
vector<Motion>_preLoadMotions;
|
||||||
|
vector<Motion>_curMotions;
|
||||||
|
void changeMotionList(AnimationFinishedCallback callback, bool loop);
|
||||||
|
|
||||||
//void changeMotion(Motion& motion);
|
//void changeMotion(Motion& motion);
|
||||||
InitArg _initArg;
|
InitArg _initArg;
|
||||||
//Motion _curMotion;
|
//Motion _curMotion;
|
||||||
string _curMotion_type;
|
//string _curMotion_type;
|
||||||
int _curMotion_png_size;
|
//int _curMotion_png_size;
|
||||||
Motion _nextMotion;
|
//Motion _nextMotion;
|
||||||
int _nextMotionIndex;
|
//int _nextMotionIndex;
|
||||||
|
|
||||||
enum MotionState {
|
//enum MotionState {
|
||||||
ready,
|
// ready,
|
||||||
loading_next_motion,
|
// loading_next_motion,
|
||||||
load_next_motion_finished,
|
// 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 SetInitArg(const char* arg);
|
||||||
|
|
||||||
void drawFrame(long long frameTime)override;
|
void drawFrame(long long frameTime)override;
|
||||||
|
|||||||
@@ -47,9 +47,44 @@ void CppAnimationFinishedCallback()
|
|||||||
std::cout << "call CppAnimationFinishedCallback\n";
|
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<std::string, Motion>& 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<float>();
|
||||||
|
frame.y = frameEntry.value()["y"].get<float>();
|
||||||
|
motion.frames.push_back(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
motions[motion.getMotionId()] = motion;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -62,23 +97,25 @@ int main() {
|
|||||||
|
|
||||||
InitArg init_arg;
|
InitArg init_arg;
|
||||||
Motion motion;
|
Motion motion;
|
||||||
motion.type = "4";
|
motion.name = "4";
|
||||||
//motion.png_names.push_back("4.png");
|
//motion.png_names.push_back("4.png");
|
||||||
for (int i = 1; i < 61; ++i)
|
//for (int i = 1; i < 61; ++i)
|
||||||
{
|
//{
|
||||||
if (i < 10)
|
// if (i < 10)
|
||||||
{
|
// {
|
||||||
motion.png_names.push_back("00" + std::to_string(i) + ".png");
|
// motion.png_names.push_back("00" + std::to_string(i) + ".png");
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
motion.png_names.push_back("0" + std::to_string(i) + ".png");
|
// motion.png_names.push_back("0" + std::to_string(i) + ".png");
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
std::map<string, Motion> motions;
|
||||||
|
loadMotions("example/src/main/assets/pic/motion_data_ex.json", motions);
|
||||||
|
|
||||||
//init_arg.motion = motion;
|
//init_arg.motion = motion;
|
||||||
|
|
||||||
@@ -103,8 +140,11 @@ int main() {
|
|||||||
std::cout << "Warning: Empty motion string" << std::endl;
|
std::cout << "Warning: Empty motion string" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<string> s_motions;
|
||||||
|
json j = motions["4"];
|
||||||
|
s_motions.push_back(j.dump());
|
||||||
|
|
||||||
app.preReadyMotion(motion_str, CppCallback);
|
app.preLoadMotionList(s_motions, CppCallback);
|
||||||
app.mainLoop();
|
app.mainLoop();
|
||||||
//try {
|
//try {
|
||||||
// app.mainLoop();
|
// app.mainLoop();
|
||||||
|
|||||||