Compare commits

..

4 Commits

Author SHA1 Message Date
InkSoul 1a54e75ea2 update RM 2024-05-20 23:20:36 +08:00
ink-soul b37eee6c18 Update ReadMe.md 2024-05-13 11:27:25 +08:00
ink-soul 3600a1f4b7 Update .gitignore 2024-05-13 11:04:45 +08:00
ink-soul 61c501adcb fix envMapRotate 2024-05-13 11:04:28 +08:00
18 changed files with 1650 additions and 275 deletions

2
.gitignore vendored
View File

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

View File

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

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} )
target_link_libraries(base ${Vulkan_LIBRARY} ${WINLIBS})
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,17 +225,16 @@ 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
*
@ -314,11 +313,6 @@ namespace vks
return cmdPool;
}
void setCommandPool(VkCommandPool commandPool)
{
this->commandPool = commandPool;
}
/**
* Allocate a command buffer from the command pool
*

View File

@ -53,8 +53,7 @@ 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)
@ -68,7 +67,6 @@ public:
#elif defined(_DIRECT2DISPLAY)
void initSurface(uint32_t width, uint32_t height)
#endif
void initSurface
{
VkResult err = VK_SUCCESS;
@ -114,7 +112,6 @@ public:
err = vkCreateXcbSurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface);
#endif
if (err != VK_SUCCESS) {
std::cerr << "Could not create surface!" << std::endl;
exit(err);
@ -235,7 +232,7 @@ public:
}
}
*/
/**
* Set instance, physical and logical device to use for the swapchain and get all required function pointers
*

View File

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

View File

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

View File

@ -107,7 +107,6 @@ 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,5 +173,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,7 +8,29 @@
#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>
@ -77,41 +99,29 @@ 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 = 1920;
uint32_t height = 1080;
uint32_t width = 1280;
uint32_t height = 720;
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 = false; // 多重采样
bool rotateModel = true; // 模型自旋转(暂时失效)
bool multiSampling = true; // 多重采样
bool rotateModel = false; // 模型自旋转(暂时失效)
bool headless = false; // 无头开关
bool outputPNGimage = false;
bool enableSaveToImageSequeue = true; // 图片序列开关(暂时弃用)
uint32_t outputFrameCount = 10; // 图片序列结束帧
uint32_t outputFrameCount = 100; // 图片序列结束帧
bool takeScreenShot = false; // 截屏(暂时弃用)
uint32_t startFrameCount = 1; // 图片序列开始帧
@ -126,12 +136,6 @@ 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);
@ -144,7 +148,105 @@ 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();
@ -153,7 +255,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.

BIN
doc/层级.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

BIN
render

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} ${MAIN_CPP} ${SOURCE} ${MAIN_HEADER} ${SHADERS_GLSL} ${SHADERS_HLSL} ${README_FILES}
add_executable(${HOMEWORK_NAME} WIN32 ${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})
target_link_libraries(${HOMEWORK_NAME} base ${Vulkan_LIBRARY} ${WINLIBS})
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.5f, -6.0f });
camera.setPosition({ 0.0f, 0.0f, -2.0f });
camera.setRotation({ 0.0f, 0.0f, 0.0f });
}
@ -223,10 +223,10 @@ PlumageRender::PlumageRender()
{
const std::string assetpath = getAssetPath();
if (!std::filesystem::exists(assetpath.c_str())) {
if (_access(assetpath.c_str(),0) != 0) {
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) * renderingFrameIndex },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSamplerCount * renderingFrameIndex }
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, (4 + meshCount) * swapChain.imageCount },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSamplerCount * swapChain.imageCount }
};
VkDescriptorPoolCreateInfo descriptorPoolCI{};
descriptorPoolCI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolCI.poolSizeCount = 2;
descriptorPoolCI.pPoolSizes = poolSizes.data();
descriptorPoolCI.maxSets = (2 + materialCount + meshCount) * renderingFrameIndex;
descriptorPoolCI.maxSets = (2 + materialCount + meshCount) * swapChain.imageCount;
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolCI, nullptr, &descriptorPool));
/*
@ -357,7 +357,7 @@ PlumageRender::PlumageRender()
descriptorSetAllocInfo.descriptorPool = descriptorPool;
descriptorSetAllocInfo.pSetLayouts = &descriptorSetLayouts.scene;
descriptorSetAllocInfo.descriptorSetCount = 1;
vkAllocateDescriptorSets(device, &descriptorSetAllocInfo, &descriptorSets[i].scene);
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &descriptorSetAllocInfo, &descriptorSets[i].scene));
std::array<VkWriteDescriptorSet, 5> writeDescriptorSets{};
@ -399,7 +399,6 @@ PlumageRender::PlumageRender()
vkUpdateDescriptorSets(device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, NULL);
}
}
// Material (samplers)
{
@ -560,10 +559,6 @@ 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,
@ -628,10 +623,6 @@ PlumageRender::PlumageRender()
if (settings.multiSampling) {
multisampleStateCI.rasterizationSamples = settings.sampleCount;
}
else
{
multisampleStateCI.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
}
// Skybox pipeline (background cube)
shaderStages = {
@ -1034,8 +1025,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)),
};
@ -1044,10 +1035,12 @@ 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;
scissor.extent.height = dim;
@ -1079,7 +1072,9 @@ 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.height = -static_cast<float>(dim * std::pow(0.5f, m));
viewport.x = 0;
viewport.y = -viewport.height;
vkCmdSetViewport(cmdBuf, 0, 1, &viewport);
vkCmdSetScissor(cmdBuf, 0, 1, &scissor);
@ -1142,7 +1137,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(
@ -1443,6 +1438,8 @@ 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;
@ -1506,7 +1503,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));
}
@ -1534,9 +1531,15 @@ PlumageRender::PlumageRender()
0.0f);
}
void PlumageRender::windowResized()
{
buildCommandBuffers();
vkDeviceWaitIdle(device);
updateUniformBuffers();
//update UI
updateUIOverlay();
}
void PlumageRender::prepare()
{
@ -1548,14 +1551,13 @@ 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(renderingFrameIndex);
uniformBuffers.resize(renderingFrameIndex);
descriptorSets.resize(renderingFrameIndex);
commandBuffers.resize(swapChain.imageCount);
uniformBuffers.resize(swapChain.imageCount);
descriptorSets.resize(swapChain.imageCount);
// Command buffer execution fences
for (auto& waitFence : waitFences) {
VkFenceCreateInfo fenceCI{ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT };
@ -1587,15 +1589,8 @@ PlumageRender::PlumageRender()
setupDescriptors();
preparePipelines();
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
if (settings.multiSampling)
{
sampleCount = settings.sampleCount;
}
//gui = new UI(vulkanDevice, renderPass, queue, pipelineCache, sampleCount);
//updateUIOverlay();
gui = new UI(vulkanDevice, renderPass, queue, pipelineCache, settings.sampleCount);
updateUIOverlay();
buildCommandBuffers();
@ -1640,13 +1635,13 @@ PlumageRender::PlumageRender()
}
// Source for the copy is the last rendered swapchain image
//VkImage srcImage = swapChain.images[currentBuffer];
VkImage srcImage = colorAttachment.image;
VkImage srcImage = swapChain.images[currentBuffer];
// 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 = colorFormat;
imageCreateCI.format = VK_FORMAT_R8G8B8A8_UNORM;
imageCreateCI.extent.width = width;
imageCreateCI.extent.height = height;
imageCreateCI.extent.depth = 1;
@ -1797,11 +1792,9 @@ 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,
VK_FORMAT_B8G8R8_SRGB, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_B8G8R8_SNORM };
colorSwizzle = (std::find(formatsBGR.begin(), formatsBGR.end(), colorFormat) != formatsBGR.end());
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());
}
// ppm binary pixel data
for (uint32_t y = 0; y < height; y++)
{
@ -1810,11 +1803,9 @@ PlumageRender::PlumageRender()
{
if (colorSwizzle)
{
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
file.write((char*)row + 2, 1);
file.write((char*)row + 1, 1);
file.write((char*)row, 1);
}
else
{
@ -1847,7 +1838,7 @@ PlumageRender::PlumageRender()
removeImageSequence();
}
filePath.deviceSpecFilePath = filePath.imageOutputPath + "/device" + std::to_string(settings.selectedPhysicalDeviceIndex);
filePath.deviceSpecFilePath = filePath.imageOutputPath + "/device" + std::to_string(selectedPhysicalDeviceIndex);
if (savedFrameCounter > settings.outputFrameCount)
{
@ -1871,7 +1862,7 @@ PlumageRender::PlumageRender()
filePath.totalImageOutputPath = filePath.deviceSpecFilePath + fileName;
return;
}
if (std::filesystem::exists(filePath.deviceSpecFilePath.c_str()))
if (_access(filePath.deviceSpecFilePath.c_str(), 0) == -1)
{
std::filesystem::create_directories(filePath.deviceSpecFilePath.c_str());
}
@ -1901,8 +1892,8 @@ PlumageRender::PlumageRender()
{
return;
}
std::string deviceFilePath = filePath.videoOutputPath + "/device" + std::to_string(settings.selectedPhysicalDeviceIndex);
if (std::filesystem::exists(deviceFilePath.c_str()))
std::string deviceFilePath = filePath.videoOutputPath + "/device" + std::to_string(selectedPhysicalDeviceIndex);
if (_access(deviceFilePath.c_str(), 0) == -1)
{
std::filesystem::create_directories(deviceFilePath.c_str());
}
@ -1920,11 +1911,10 @@ 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()
@ -1981,21 +1971,19 @@ PlumageRender::PlumageRender()
return;
}
//updateUIOverlay();
updateUIOverlay();
//加入写到文件的函数
//swapChainImage = swapChain.images[frameIndex];
//outputImageSequeue(swapChainImage,filePath.imageSequenceFilePath);
outputImageSequence();
imageSequenceToVideo();
//outputImageSequence();
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();
@ -2005,7 +1993,6 @@ PlumageRender::PlumageRender()
}
*/
// Update UBOs
updateUniformBuffers();
@ -2014,21 +2001,19 @@ 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];
submitInfo.commandBufferCount = 1;
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) {
@ -2038,7 +2023,7 @@ PlumageRender::PlumageRender()
else {
VK_CHECK_RESULT(present);
}
}*/
}
frameIndex += 1;
frameIndex %= renderAhead;
@ -2076,7 +2061,7 @@ PlumageRender::PlumageRender()
buildCommandBuffers();
}
/*
void PlumageRender::updateUIOverlay()
{
ImGuiIO& io = ImGui::GetIO();
@ -2152,6 +2137,9 @@ PlumageRender::PlumageRender()
setupDescriptors();
updateCBs = true;
}
if (gui->checkbox("模型自转", &settings.rotateModel)) {
updateShaderParams = true;
}
if (gui->checkbox(chineseUI.environmentBackGround, &displayBackground)) {
updateShaderParams = true;
}
@ -2290,20 +2278,28 @@ PlumageRender::PlumageRender()
}
*/
PlumageRender* plumageRender;
// OS specific macros for the example main entry points
int main(int argc, char* argv[])
#if defined(_WIN32)
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
for (int32_t i = 0; i < argc; i++) { PlumageRender::args.push_back(argv[i]); };
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]); };
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,6 +1,14 @@
#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"
@ -47,7 +55,14 @@ public:
} info ;
struct Signal
{
bool imageSequenceOutputComplete = false;
bool imageSequenceToVideoComplete = false;
}signal;
struct Models
{
glTFModel::Model scene;
@ -129,7 +144,7 @@ public:
struct FilePath
{ //model path
std::string glTFModelFilePath = getAssetPath() + "models/free_porsche_911_carrera_4s.glb";
std::string glTFModelFilePath = getAssetPath() + "models/DamagedHelmet/DamagedHelmet.gltf";
std::string modelVertShaderPath = getAssetPath() + "buster_drone/shaders/glsl/mesh.vert.spv";
std::string modelFragShaderPath = getAssetPath() + "buster_drone/shaders/glsl/mesh.frag.spv";
@ -159,7 +174,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/7_4k_hdr16f_cube.ktx";
std::string envMapFilePath = getAssetPath() + "environments/brown_photostudio_02_4k_hdr16f_cube.ktx";
std::string emptyEnvmapFilePath = getAssetPath() + "textures/empty.ktx";
// pbr shader
std::string pbrVertShaderPath = getAssetPath() + "shaders/pbr.vert.spv";
@ -330,7 +345,7 @@ public:
textures.prefilteredCube.destroy();
textures.lutBrdf.destroy();
textures.empty.destroy();
//delete gui;
delete gui;
}
@ -348,7 +363,7 @@ public:
void prepareUniformBuffers();
void updateUniformBuffers();
void updateShaderData();
//void windowResized();
void windowResized();
void prepare();
void submitWork(VkCommandBuffer cmdBuffer, VkQueue queue);
@ -359,6 +374,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);
};