Compare commits

..

13 Commits

18 changed files with 274 additions and 1649 deletions

2
.gitignore vendored
View File

@ -53,5 +53,3 @@ build/
/data/output
*.glb
*.ktx
data/output/video/device0/result.mp4

View File

@ -81,6 +81,20 @@
"rsyncCommandArgs": "-t --delete",
"remoteCopyBuildOutput": false,
"remoteCopySourcesMethod": "rsync"
},
{
"name": "WSL-Clang-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeExecutable": "cmake",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "linux_clang_x64" ],
"wslPath": "${defaultWSLPath}",
"variables": []
}
]
}

View File

@ -9,7 +9,16 @@
2. 支持gltf动画
3. 支持模型的PBR材质渲染
4. 使用基于IBL的环境光照
5. 支持渲染结果输出为图片序列通过ffmpeg转为视频main分支上该功能暂时屏蔽
#### 分支add image output ToDo list
1. 添加ppm格式图片序列输出
2. 单帧输出,预览效果
3. 接入ffmpeg将图片序列转图片
#### todo list
1. 参数化模板选择:维护一个模板数组,前端发送一个数组索引
#### 展示
@ -27,22 +36,16 @@
![](https://lychee.inksoul.top/uploads/original/39/56/ec512b70f1da4cf0771bcc38a6b9.webp)
#### 下一步计划
#### 下一步计划(等待研究生考试结束)
- [ ] 引入spdlog日志库细化日志正在做
- [ ] 重置CMakeLists.txt添加Xmake 的lua脚本
- [ ] 二次封装vulkan API提供统一的渲染接口
- [ ] 更换imgui的分支允许dock UI
- [ ] 添加启动UI避免对默认模型的依赖
- [ ] 添加obj格式支持
- [ ] 添加PMX格式支持
- [ ] 引入USD格式支持
#### 重构
暂定层级:
![](doc/层级.png)
1. 引入spdlog日志库细化日志正在做
2. 重置CMakeLists.txt添加Xmake 的lua脚本
3. 二次封装vulkan API提供统一的渲染接口
4. 更换imgui的分支允许dock UI
5. 添加启动UI避免对默认模型的依赖
6. 添加obj格式支持
7. 添加PMX格式支持
8. 引入USD格式支持
#### 使用开源库

View File

@ -12,7 +12,7 @@ set(KTX_SOURCES
add_library(base STATIC ${BASE_SRC} ${KTX_SOURCES})
if(WIN32)
target_link_libraries(base ${Vulkan_LIBRARY} ${WINLIBS})
target_link_libraries(base ${Vulkan_LIBRARY} )
else(WIN32)
target_link_libraries(base ${Vulkan_LIBRARY} ${XCB_LIBRARIES} ${WAYLAND_CLIENT_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
endif(WIN32)

View File

@ -80,7 +80,7 @@ namespace vks
~VulkanDevice()
{
if (commandPool) {
vkDestroyCommandPool(logicalDevice, commandPool, nullptr);
//vkDestroyCommandPool(logicalDevice, commandPool, nullptr);
}
if (logicalDevice) {
vkDestroyDevice(logicalDevice, nullptr);
@ -225,16 +225,17 @@ namespace vks
}
VkResult result = vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &logicalDevice);
/*
if (result == VK_SUCCESS) {
commandPool = createCommandPool(queueFamilyIndices.graphics);
}
*/
this->enabledFeatures = enabledFeatures;
return result;
}
/**
* Create a buffer on the device
*
@ -313,6 +314,11 @@ namespace vks
return cmdPool;
}
void setCommandPool(VkCommandPool commandPool)
{
this->commandPool = commandPool;
}
/**
* Allocate a command buffer from the command pool
*

View File

@ -53,7 +53,8 @@ public:
VkExtent2D extent = {};
uint32_t queueNodeIndex = UINT32_MAX;
/** @brief Creates the platform specific surface abstraction of the native platform window used for presentation */
/* @brief Creates the platform specific surface abstraction of the native platform window used for presentation */
/*
#if defined(VK_USE_PLATFORM_WIN32_KHR)
void initSurface(void* platformHandle, void* platformWindow)
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
@ -67,6 +68,7 @@ public:
#elif defined(_DIRECT2DISPLAY)
void initSurface(uint32_t width, uint32_t height)
#endif
void initSurface
{
VkResult err = VK_SUCCESS;
@ -112,6 +114,7 @@ public:
err = vkCreateXcbSurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface);
#endif
if (err != VK_SUCCESS) {
std::cerr << "Could not create surface!" << std::endl;
exit(err);
@ -232,7 +235,7 @@ public:
}
}
*/
/**
* Set instance, physical and logical device to use for the swapchain and get all required function pointers
*

View File

@ -10,25 +10,26 @@ const std::string getAssetPath()
return "";
#elif defined(VK_EXAMPLE_DATA_DIR)
if (_access("./../data/", 0) != -1)
if (std::filesystem::exists("./../data/"))
{
return "./../data/";
}
else if (_access("./data/", 0) != -1)
else if (std::filesystem::exists("./data/"))
{
return "./data/";
}
else if (_access("./../../data/", 0) != -1)
else if (std::filesystem::exists("./../../data/"))
{
return "../../data/";
}
else
{
return VK_EXAMPLE_DATA_DIR;
std::filesystem::path dataPath = VK_EXAMPLE_DATA_DIR;
std::string strDataPath = dataPath.generic_string() ;
return strDataPath;
}
#endif

View File

@ -16,6 +16,7 @@
#include <stdexcept>
#include <fstream>
#include <algorithm>
#include <filesystem>
#if defined(_WIN32)
#include <windows.h>
#include <fcntl.h>

View File

@ -107,6 +107,7 @@ VkPipelineShaderStageCreateInfo loadShader(VkDevice device, std::string filename
return shaderStage;
}
/*
void readDirectory(const std::string& directory, const std::string &pattern, std::map<std::string, std::string> &filelist, bool recursive)
{
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
@ -174,3 +175,4 @@ void readDirectory(const std::string& directory, const std::string &pattern, std
closedir(dir);
#endif
}
*/

View File

@ -174,7 +174,7 @@ public:
VkPipelineMultisampleStateCreateInfo multisampleStateCI{};
multisampleStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
if (multiSampleCount > VK_SAMPLE_COUNT_1_BIT) {
if (multiSampleCount >= VK_SAMPLE_COUNT_1_BIT) {
multisampleStateCI.rasterizationSamples = multiSampleCount;
}

File diff suppressed because it is too large Load Diff

View File

@ -8,29 +8,7 @@
#pragma once
#ifdef _WIN32
#pragma comment(linker, "/subsystem:windows")
#include <windows.h>
#include <fcntl.h>
#include <io.h>
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
#include <android/native_activity.h>
#include <android/asset_manager.h>
#include <android_native_app_glue.h>
#include <sys/system_properties.h>
#include "VulkanAndroid.h"
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
#include <wayland-client.h>
#elif defined(_DIRECT2DISPLAY)
//
#elif defined(VK_USE_PLATFORM_XCB_KHR)
#include <xcb/xcb.h>
#elif defined(VK_USE_PLATFORM_MACOS_MVK)
#include <Cocoa/Cocoa.h>
#include <Carbon/Carbon.h>
#include <QuartzCore/CAMetalLayer.h>
#include <CoreVideo/CVDisplayLink.h>
#endif
#include <iostream>
#include <chrono>
@ -99,29 +77,41 @@ protected:
VulkanSwapChain swapChain;
std::string title = "Vulkan Example";
std::string name = "vulkanExample";
void windowResize();
//void windowResize();
public:
static std::vector<const char*> args;
uint32_t selectedPhysicalDeviceIndex = 0;
bool prepared = false;
uint32_t width = 1280;
uint32_t height = 720;
uint32_t width = 1920;
uint32_t height = 1080;
float frameTimer = 1.0f;
Camera camera;
glm::vec2 mousePos;
bool paused = false;
uint32_t lastFPS = 0;
VkFormat colorFormat = VK_FORMAT_R8G8B8A8_SRGB;
uint32_t queueFamilyIndex;
uint32_t renderingFrameIndex = 3;
struct Signal
{
bool imageSequenceOutputComplete = false;
bool imageSequenceToVideoComplete = false;
}signal;
struct Settings {
uint32_t selectedPhysicalDeviceIndex = 7;
bool validation = false; // 校验层开关
bool fullscreen = false; // 全屏开关
bool vsync = false; // 垂直同步开关
bool multiSampling = true; // 多重采样
bool rotateModel = false; // 模型自旋转(暂时失效)
bool multiSampling = false; // 多重采样
bool rotateModel = true; // 模型自旋转(暂时失效)
bool headless = false; // 无头开关
bool outputPNGimage = false;
bool enableSaveToImageSequeue = true; // 图片序列开关(暂时弃用)
uint32_t outputFrameCount = 100; // 图片序列结束帧
uint32_t outputFrameCount = 10; // 图片序列结束帧
bool takeScreenShot = false; // 截屏(暂时弃用)
uint32_t startFrameCount = 1; // 图片序列开始帧
@ -136,6 +126,12 @@ public:
VkImageView view;
} depthStencil;
struct ColorAttachment {
VkImage image;
VkDeviceMemory memory;
VkImageView view;
} colorAttachment;
struct GamePadState {
glm::vec2 axisLeft = glm::vec2(0.0f);
glm::vec2 axisRight = glm::vec2(0.0f);
@ -148,105 +144,7 @@ public:
} mouseButtons;
// OS specific
#if defined(_WIN32)
HWND window;
HINSTANCE windowInstance;
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
// true if application has focused, false if moved to background
bool focused = false;
std::string androidProduct;
struct TouchPoint {
int32_t id;
float x;
float y;
bool down = false;
};
float pinchDist = 0.0f;
std::array<TouchPoint, 2> touchPoints;
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
wl_display *display = nullptr;
wl_registry *registry = nullptr;
wl_compositor *compositor = nullptr;
wl_shell *shell = nullptr;
wl_seat *seat = nullptr;
wl_pointer *pointer = nullptr;
wl_keyboard *keyboard = nullptr;
wl_surface *surface = nullptr;
wl_shell_surface *shell_surface = nullptr;
bool quit = false;
#elif defined(_DIRECT2DISPLAY)
bool quit = false;
#elif defined(VK_USE_PLATFORM_XCB_KHR)
bool quit = false;
xcb_connection_t *connection;
xcb_screen_t *screen;
xcb_window_t window;
xcb_intern_atom_reply_t *atom_wm_delete_window;
#elif defined(VK_USE_PLATFORM_MACOS_MVK)
NSWindow* window;
#endif
#if defined(_WIN32)
HWND setupWindow(HINSTANCE hinstance, WNDPROC wndproc);
void handleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
static int32_t handleAppInput(struct android_app* app, AInputEvent* event);
static void handleAppCommand(android_app* app, int32_t cmd);
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
wl_shell_surface *setupWindow();
void initWaylandConnection();
static void registryGlobalCb(void *data, struct wl_registry *registry,
uint32_t name, const char *interface, uint32_t version);
void registryGlobal(struct wl_registry *registry, uint32_t name,
const char *interface, uint32_t version);
static void registryGlobalRemoveCb(void *data, struct wl_registry *registry,
uint32_t name);
static void seatCapabilitiesCb(void *data, wl_seat *seat, uint32_t caps);
void seatCapabilities(wl_seat *seat, uint32_t caps);
static void pointerEnterCb(void *data, struct wl_pointer *pointer,
uint32_t serial, struct wl_surface *surface, wl_fixed_t sx,
wl_fixed_t sy);
static void pointerLeaveCb(void *data, struct wl_pointer *pointer,
uint32_t serial, struct wl_surface *surface);
static void pointerMotionCb(void *data, struct wl_pointer *pointer,
uint32_t time, wl_fixed_t sx, wl_fixed_t sy);
void pointerMotion(struct wl_pointer *pointer,
uint32_t time, wl_fixed_t sx, wl_fixed_t sy);
static void pointerButtonCb(void *data, struct wl_pointer *wl_pointer,
uint32_t serial, uint32_t time, uint32_t button, uint32_t state);
void pointerButton(struct wl_pointer *wl_pointer,
uint32_t serial, uint32_t time, uint32_t button, uint32_t state);
static void pointerAxisCb(void *data, struct wl_pointer *wl_pointer,
uint32_t time, uint32_t axis, wl_fixed_t value);
void pointerAxis(struct wl_pointer *wl_pointer,
uint32_t time, uint32_t axis, wl_fixed_t value);
static void keyboardKeymapCb(void *data, struct wl_keyboard *keyboard,
uint32_t format, int fd, uint32_t size);
static void keyboardEnterCb(void *data, struct wl_keyboard *keyboard,
uint32_t serial, struct wl_surface *surface, struct wl_array *keys);
static void keyboardLeaveCb(void *data, struct wl_keyboard *keyboard,
uint32_t serial, struct wl_surface *surface);
static void keyboardKeyCb(void *data, struct wl_keyboard *keyboard,
uint32_t serial, uint32_t time, uint32_t key, uint32_t state);
void keyboardKey(struct wl_keyboard *keyboard,
uint32_t serial, uint32_t time, uint32_t key, uint32_t state);
static void keyboardModifiersCb(void *data, struct wl_keyboard *keyboard,
uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,
uint32_t mods_locked, uint32_t group);
#elif defined(_DIRECT2DISPLAY)
//
#elif defined(VK_USE_PLATFORM_XCB_KHR)
xcb_window_t setupWindow();
void initxcbConnection();
void handleEvent(const xcb_generic_event_t *event);
#elif defined(VK_USE_PLATFORM_MACOS_MVK)
NSWindow* setupWindow();
void mouseDragged(float x, float y);
void windowWillResize(float x, float y);
void windowDidResize();
#endif
VulkanExampleBase();
virtual ~VulkanExampleBase();
@ -255,7 +153,7 @@ public:
virtual VkResult createInstance(bool enableValidation);
virtual void render() = 0;
virtual void windowResized();
//virtual void windowResized();
virtual void setupFrameBuffer();
virtual void prepare();
virtual void fileDropped(std::string filename);

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 263 KiB

BIN
render 100644

Binary file not shown.

View File

@ -30,12 +30,12 @@ function(buildHomework HOMEWORK_NAME)
# Add optional readme / tutorial
#file(GLOB README_FILES "${HOMEWORK_FOLDER}/*.md")
if(WIN32)
add_executable(${HOMEWORK_NAME} WIN32 ${MAIN_CPP} ${SOURCE} ${MAIN_HEADER} ${SHADERS_GLSL} ${SHADERS_HLSL} ${README_FILES}
add_executable(${HOMEWORK_NAME} ${MAIN_CPP} ${SOURCE} ${MAIN_HEADER} ${SHADERS_GLSL} ${SHADERS_HLSL} ${README_FILES}
"render/glTFModel.h"
"render/glTFModel.cpp"
"render/renderFoundation.h" "render/renderFoundation.cpp")
target_link_libraries(${HOMEWORK_NAME} base ${Vulkan_LIBRARY} ${WINLIBS})
target_link_libraries(${HOMEWORK_NAME} base ${Vulkan_LIBRARY})
else(WIN32)
add_executable(${HOMEWORK_NAME} ${MAIN_CPP} ${SOURCE} ${MAIN_HEADER} ${SHADERS_GLSL} ${SHADERS_HLSL} ${README_FILES})
target_link_libraries(${HOMEWORK_NAME} base )

View File

@ -183,7 +183,7 @@ PlumageRender::PlumageRender()
}
// User interface
gui->draw(currentCB);
//gui->draw(currentCB);
vkCmdEndRenderPass(currentCB);
VK_CHECK_RESULT(vkEndCommandBuffer(currentCB));
@ -203,7 +203,7 @@ PlumageRender::PlumageRender()
models.scene.loadFromFile(filename, vulkanDevice, queue);
auto tFileLoad = std::chrono::duration<double, std::milli>(std::chrono::high_resolution_clock::now() - tStart).count();
std::cout << "Loading took " << tFileLoad << " ms" << std::endl;
camera.setPosition({ 0.0f, 0.0f, -2.0f });
camera.setPosition({ 0.0f, 0.5f, -6.0f });
camera.setRotation({ 0.0f, 0.0f, 0.0f });
}
@ -223,10 +223,10 @@ PlumageRender::PlumageRender()
{
const std::string assetpath = getAssetPath();
if (_access(assetpath.c_str(),0) != 0) {
if (!std::filesystem::exists(assetpath.c_str())) {
std::string msg = "Could not locate asset path in \"" + assetpath + "\".\nMake sure binary is running from correct relative directory!";
std::cerr << msg << std::endl;
system("pause");
//system("pause");
//exit(-1);
}
else {
@ -234,7 +234,7 @@ PlumageRender::PlumageRender()
std::cout << msg << std::endl;
}
readDirectory(assetpath + "environments", "*.ktx", environments, false);
//readDirectory(assetpath + "environments", "*.ktx", environments, false);
textures.empty.loadFromFile(PlumageRender::filePath.emptyEnvmapFilePath, VK_FORMAT_R8G8B8A8_UNORM, vulkanDevice, queue);
@ -321,14 +321,14 @@ PlumageRender::PlumageRender()
}
std::vector<VkDescriptorPoolSize> poolSizes = {
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, (4 + meshCount) * swapChain.imageCount },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSamplerCount * swapChain.imageCount }
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, (4 + meshCount) * renderingFrameIndex },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSamplerCount * renderingFrameIndex }
};
VkDescriptorPoolCreateInfo descriptorPoolCI{};
descriptorPoolCI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolCI.poolSizeCount = 2;
descriptorPoolCI.pPoolSizes = poolSizes.data();
descriptorPoolCI.maxSets = (2 + materialCount + meshCount) * swapChain.imageCount;
descriptorPoolCI.maxSets = (2 + materialCount + meshCount) * renderingFrameIndex;
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolCI, nullptr, &descriptorPool));
/*
@ -357,7 +357,7 @@ PlumageRender::PlumageRender()
descriptorSetAllocInfo.descriptorPool = descriptorPool;
descriptorSetAllocInfo.pSetLayouts = &descriptorSetLayouts.scene;
descriptorSetAllocInfo.descriptorSetCount = 1;
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &descriptorSetAllocInfo, &descriptorSets[i].scene));
vkAllocateDescriptorSets(device, &descriptorSetAllocInfo, &descriptorSets[i].scene);
std::array<VkWriteDescriptorSet, 5> writeDescriptorSets{};
@ -400,6 +400,7 @@ PlumageRender::PlumageRender()
}
}
// Material (samplers)
{
std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings = {
@ -559,6 +560,10 @@ PlumageRender::PlumageRender()
if (settings.multiSampling) {
multisampleStateCI.rasterizationSamples = settings.sampleCount;
}
else
{
multisampleStateCI.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
}
std::vector<VkDynamicState> dynamicStateEnables = {
VK_DYNAMIC_STATE_VIEWPORT,
@ -623,6 +628,10 @@ PlumageRender::PlumageRender()
if (settings.multiSampling) {
multisampleStateCI.rasterizationSamples = settings.sampleCount;
}
else
{
multisampleStateCI.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
}
// Skybox pipeline (background cube)
shaderStages = {
@ -1025,8 +1034,8 @@ PlumageRender::PlumageRender()
std::vector<glm::mat4> matrices = {
glm::rotate(glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), glm::vec3(0.0f, 1.0f, 0.0f)), glm::radians(180.0f), glm::vec3(1.0f, 0.0f, 0.0f)),
glm::rotate(glm::rotate(glm::mat4(1.0f), glm::radians(-90.0f), glm::vec3(0.0f, 1.0f, 0.0f)), glm::radians(180.0f), glm::vec3(1.0f, 0.0f, 0.0f)),
glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)),
glm::rotate(glm::mat4(1.0f), glm::radians(-90.0f), glm::vec3(1.0f, 0.0f, 0.0f)),
glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)),
glm::rotate(glm::mat4(1.0f), glm::radians(180.0f), glm::vec3(1.0f, 0.0f, 0.0f)),
glm::rotate(glm::mat4(1.0f), glm::radians(180.0f), glm::vec3(0.0f, 0.0f, 1.0f)),
};
@ -1035,11 +1044,9 @@ PlumageRender::PlumageRender()
VkViewport viewport{};
viewport.width = (float)dim;
viewport.height = -(float)dim;
viewport.height = (float)dim;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
viewport.x = 0;
viewport.y = -viewport.height;
VkRect2D scissor{};
scissor.extent.width = dim;
@ -1072,9 +1079,7 @@ PlumageRender::PlumageRender()
vulkanDevice->beginCommandBuffer(cmdBuf);
viewport.width = static_cast<float>(dim * std::pow(0.5f, m));
viewport.height = -static_cast<float>(dim * std::pow(0.5f, m));
viewport.x = 0;
viewport.y = -viewport.height;
viewport.height = static_cast<float>(dim * std::pow(0.5f, m));
vkCmdSetViewport(cmdBuf, 0, 1, &viewport);
vkCmdSetScissor(cmdBuf, 0, 1, &scissor);
@ -1137,7 +1142,7 @@ PlumageRender::PlumageRender()
copyRegion.dstOffset = { 0, 0, 0 };
copyRegion.extent.width = static_cast<uint32_t>(viewport.width);
copyRegion.extent.height = -static_cast<uint32_t>(viewport.height);
copyRegion.extent.height = static_cast<uint32_t>(viewport.height);
copyRegion.extent.depth = 1;
vkCmdCopyImage(
@ -1438,8 +1443,6 @@ PlumageRender::PlumageRender()
viewport.height = (float)dim;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
//viewport.x = 0;
//viewport.y = -viewport.height;
VkRect2D scissor{};
scissor.extent.width = dim;
@ -1503,7 +1506,7 @@ PlumageRender::PlumageRender()
if (settings.rotateModel)
{
//shaderDataScene.model = glm::mat4(1.0f);
shaderDataScene.model = glm::mat4(1.0f);
shaderDataScene.model = glm::rotate(shaderDataScene.model, glm::radians(modelrot), glm::vec3(0, 1, 0));
}
@ -1532,14 +1535,8 @@ PlumageRender::PlumageRender()
}
void PlumageRender::windowResized()
{
buildCommandBuffers();
vkDeviceWaitIdle(device);
updateUniformBuffers();
//update UI
updateUIOverlay();
}
void PlumageRender::prepare()
{
@ -1551,13 +1548,14 @@ PlumageRender::PlumageRender()
camera.rotationSpeed = 0.25f;
camera.movementSpeed = 0.1f;
auto frameRange = settings.outputFrameCount - settings.startFrameCount + 1;
waitFences.resize(renderAhead);
presentCompleteSemaphores.resize(renderAhead);
renderCompleteSemaphores.resize(renderAhead);
commandBuffers.resize(swapChain.imageCount);
uniformBuffers.resize(swapChain.imageCount);
descriptorSets.resize(swapChain.imageCount);
commandBuffers.resize(renderingFrameIndex);
uniformBuffers.resize(renderingFrameIndex);
descriptorSets.resize(renderingFrameIndex);
// Command buffer execution fences
for (auto& waitFence : waitFences) {
VkFenceCreateInfo fenceCI{ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT };
@ -1589,8 +1587,15 @@ PlumageRender::PlumageRender()
setupDescriptors();
preparePipelines();
gui = new UI(vulkanDevice, renderPass, queue, pipelineCache, settings.sampleCount);
updateUIOverlay();
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
if (settings.multiSampling)
{
sampleCount = settings.sampleCount;
}
//gui = new UI(vulkanDevice, renderPass, queue, pipelineCache, sampleCount);
//updateUIOverlay();
buildCommandBuffers();
@ -1635,13 +1640,13 @@ PlumageRender::PlumageRender()
}
// Source for the copy is the last rendered swapchain image
VkImage srcImage = swapChain.images[currentBuffer];
//VkImage srcImage = swapChain.images[currentBuffer];
VkImage srcImage = colorAttachment.image;
// Create the linear tiled destination image to copy to and to read the memory from
VkImageCreateInfo imageCreateCI(vks::initializers::imageCreateInfo());
imageCreateCI.imageType = VK_IMAGE_TYPE_2D;
// Note that vkCmdBlitImage (if supported) will also do format conversions if the swapchain color format would differ
imageCreateCI.format = VK_FORMAT_R8G8B8A8_UNORM;
imageCreateCI.format = colorFormat;
imageCreateCI.extent.width = width;
imageCreateCI.extent.height = height;
imageCreateCI.extent.depth = 1;
@ -1792,9 +1797,11 @@ PlumageRender::PlumageRender()
// Note: Not complete, only contains most common and basic BGR surface formats for demonstration purposes
if (!supportsBlit)
{
std::vector<VkFormat> formatsBGR = { VK_FORMAT_B8G8R8A8_SRGB, VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_SNORM };
colorSwizzle = (std::find(formatsBGR.begin(), formatsBGR.end(), swapChain.colorFormat) != formatsBGR.end());
std::vector<VkFormat> formatsBGR = { VK_FORMAT_B8G8R8A8_SRGB, VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_SNORM,
VK_FORMAT_B8G8R8_SRGB, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_B8G8R8_SNORM };
colorSwizzle = (std::find(formatsBGR.begin(), formatsBGR.end(), colorFormat) != formatsBGR.end());
}
// ppm binary pixel data
for (uint32_t y = 0; y < height; y++)
{
@ -1803,9 +1810,11 @@ PlumageRender::PlumageRender()
{
if (colorSwizzle)
{
file.write((char*)row + 2, 1);
file.write((char*)row + 1, 1);
file.write((char*)row, 1);
file.write((char*)row + 2, 1); // R
file.write((char*)row + 1, 1);// G
//std::cout << row << std::endl;
file.write((char*)row, 1);// B
}
else
{
@ -1838,7 +1847,7 @@ PlumageRender::PlumageRender()
removeImageSequence();
}
filePath.deviceSpecFilePath = filePath.imageOutputPath + "/device" + std::to_string(selectedPhysicalDeviceIndex);
filePath.deviceSpecFilePath = filePath.imageOutputPath + "/device" + std::to_string(settings.selectedPhysicalDeviceIndex);
if (savedFrameCounter > settings.outputFrameCount)
{
@ -1862,7 +1871,7 @@ PlumageRender::PlumageRender()
filePath.totalImageOutputPath = filePath.deviceSpecFilePath + fileName;
return;
}
if (_access(filePath.deviceSpecFilePath.c_str(), 0) == -1)
if (std::filesystem::exists(filePath.deviceSpecFilePath.c_str()))
{
std::filesystem::create_directories(filePath.deviceSpecFilePath.c_str());
}
@ -1892,8 +1901,8 @@ PlumageRender::PlumageRender()
{
return;
}
std::string deviceFilePath = filePath.videoOutputPath + "/device" + std::to_string(selectedPhysicalDeviceIndex);
if (_access(deviceFilePath.c_str(), 0) == -1)
std::string deviceFilePath = filePath.videoOutputPath + "/device" + std::to_string(settings.selectedPhysicalDeviceIndex);
if (std::filesystem::exists(deviceFilePath.c_str()))
{
std::filesystem::create_directories(deviceFilePath.c_str());
}
@ -1911,10 +1920,11 @@ PlumageRender::PlumageRender()
std::cout << commandLine << std::endl;
std::system(commandLine.c_str());
signal.imageSequenceToVideoComplete = true;
std::cout << "vidoe codec complete,saved in:" << resultVideoPath << std::endl;
std::cout << "star to clean up image sequence" << std::endl;
removeImageSequence();
signal.imageSequenceToVideoComplete = true;
}
void PlumageRender::removeImageSequence()
@ -1971,19 +1981,21 @@ PlumageRender::PlumageRender()
return;
}
updateUIOverlay();
//updateUIOverlay();
//加入写到文件的函数
//swapChainImage = swapChain.images[frameIndex];
//outputImageSequeue(swapChainImage,filePath.imageSequenceFilePath);
//outputImageSequence();
outputImageSequence();
imageSequenceToVideo();
VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[frameIndex], VK_TRUE, UINT64_MAX));
//imageSequenceToVideo();
VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[frameIndex]));
/*
VkResult acquire = swapChain.acquireNextImage(presentCompleteSemaphores[frameIndex], &currentBuffer);
if ((acquire == VK_ERROR_OUT_OF_DATE_KHR) || (acquire == VK_SUBOPTIMAL_KHR)) {
windowResize();
@ -1993,6 +2005,7 @@ PlumageRender::PlumageRender()
}
*/
// Update UBOs
updateUniformBuffers();
@ -2001,12 +2014,13 @@ PlumageRender::PlumageRender()
memcpy(currentUB.params.mapped, &shaderData, sizeof(shaderData));
memcpy(currentUB.skybox.mapped, &shaderDataSkybox, sizeof(shaderDataSkybox));
const VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.pWaitDstStageMask = &waitDstStageMask;
submitInfo.pWaitSemaphores = &presentCompleteSemaphores[frameIndex];
submitInfo.waitSemaphoreCount = 1;
//submitInfo.pWaitSemaphores = &presentCompleteSemaphores[frameIndex];
//submitInfo.waitSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &renderCompleteSemaphores[frameIndex];
submitInfo.signalSemaphoreCount = 1;
submitInfo.pCommandBuffers = &commandBuffers[currentBuffer];
@ -2014,6 +2028,7 @@ PlumageRender::PlumageRender()
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, waitFences[frameIndex]));
//显示队列
/*
VkResult present = swapChain.queuePresent(queue, currentBuffer, renderCompleteSemaphores[frameIndex]);
if (!((present == VK_SUCCESS) || (present == VK_SUBOPTIMAL_KHR))) {
if (present == VK_ERROR_OUT_OF_DATE_KHR) {
@ -2023,7 +2038,7 @@ PlumageRender::PlumageRender()
else {
VK_CHECK_RESULT(present);
}
}
}*/
frameIndex += 1;
frameIndex %= renderAhead;
@ -2061,7 +2076,7 @@ PlumageRender::PlumageRender()
buildCommandBuffers();
}
/*
void PlumageRender::updateUIOverlay()
{
ImGuiIO& io = ImGui::GetIO();
@ -2137,9 +2152,6 @@ PlumageRender::PlumageRender()
setupDescriptors();
updateCBs = true;
}
if (gui->checkbox("模型自转", &settings.rotateModel)) {
updateShaderParams = true;
}
if (gui->checkbox(chineseUI.environmentBackGround, &displayBackground)) {
updateShaderParams = true;
}
@ -2278,28 +2290,20 @@ PlumageRender::PlumageRender()
}
*/
PlumageRender* plumageRender;
// OS specific macros for the example main entry points
#if defined(_WIN32)
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
int main(int argc, char* argv[])
{
if (plumageRender != NULL)
{
plumageRender->handleMessages(hWnd, uMsg, wParam, lParam);
}
return (DefWindowProc(hWnd, uMsg, wParam, lParam));
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
for (int32_t i = 0; i < __argc; i++) { PlumageRender::args.push_back(__argv[i]); };
for (int32_t i = 0; i < argc; i++) { PlumageRender::args.push_back(argv[i]); };
plumageRender = new PlumageRender();
std::cout << "start to init vulkan" << std::endl;
plumageRender->initVulkan();
plumageRender->setupWindow(hInstance, WndProc);
//plumageRender->setupWindow(hInstance, WndProc);
plumageRender->prepare();
plumageRender->renderLoop();
delete(plumageRender);
return 0;
}
#endif

View File

@ -1,14 +1,6 @@
#pragma once
#if defined(_WIN32)
#include <io.h>
#include <direct.h>
#else
#include<sys/io.h>
#include<dirent.h>
#endif
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb/stb_image_write.h"
@ -55,13 +47,6 @@ public:
} info ;
struct Signal
{
bool imageSequenceOutputComplete = false;
bool imageSequenceToVideoComplete = false;
}signal;
struct Models
{
@ -144,7 +129,7 @@ public:
struct FilePath
{ //model path
std::string glTFModelFilePath = getAssetPath() + "models/DamagedHelmet/DamagedHelmet.gltf";
std::string glTFModelFilePath = getAssetPath() + "models/free_porsche_911_carrera_4s.glb";
std::string modelVertShaderPath = getAssetPath() + "buster_drone/shaders/glsl/mesh.vert.spv";
std::string modelFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/mesh.frag.spv";
@ -174,7 +159,7 @@ public:
std::string brdfVertShaderPath = getAssetPath() + "shaders/genbrdflut.vert.spv";
std::string brdfFragShaderPath = getAssetPath() + "shaders/genbrdflut.frag.spv";
// environment map texture
std::string envMapFilePath = getAssetPath() + "environments/brown_photostudio_02_4k_hdr16f_cube.ktx";
std::string envMapFilePath = getAssetPath() + "environments/7_4k_hdr16f_cube.ktx";
std::string emptyEnvmapFilePath = getAssetPath() + "textures/empty.ktx";
// pbr shader
std::string pbrVertShaderPath = getAssetPath() + "shaders/pbr.vert.spv";
@ -345,7 +330,7 @@ public:
textures.prefilteredCube.destroy();
textures.lutBrdf.destroy();
textures.empty.destroy();
delete gui;
//delete gui;
}
@ -363,7 +348,7 @@ public:
void prepareUniformBuffers();
void updateUniformBuffers();
void updateShaderData();
void windowResized();
//void windowResized();
void prepare();
void submitWork(VkCommandBuffer cmdBuffer, VkQueue queue);
@ -374,6 +359,6 @@ public:
//void outputScreenShot();
uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties);
virtual void render();
virtual void updateUIOverlay();
//virtual void updateUIOverlay();
virtual void fileDropped(std::string filename);
};