#ifndef TINYGLTF_IMPLEMENTATION #define TINYGLTF_IMPLEMENTATION #endif #ifndef STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION #endif #ifndef TINYGLTF_NO_STB_IMAGE_WRITE #define TINYGLTF_NO_STB_IMAGE_WRITE #endif #include "render.h" //#include "VulkanUtils.hpp" //#include "assetLoader.h" void PlumageRender::renderMain::initWindow(int Width, int Height) { glfwInit(); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); window = glfwCreateWindow(Width, Height, "vulkan", nullptr, nullptr); glfwSetWindowUserPointer(window, this); glfwSetFramebufferSizeCallback(window, framebufferResizeCallback); } void PlumageRender::renderMain::framebufferResizeCallback(GLFWwindow* window, int width, int height) { auto app = reinterpret_cast(glfwGetWindowUserPointer(window)); app->framebufferResized = true; } // todo:重写成glfw的 void PlumageRender::renderMain::windowResized() { buildCommandBuffers(); vkDeviceWaitIdle(device); updateUniformBuffers(); //update UI updateUIOverlay(); } void PlumageRender::renderMain::prepare() { //VulkanExampleBase::prepare(); setupCamera(); loadAssets(); generateBRDFLUT(); generateCubemaps(); //prepareUniformBuffers(); //setupDescriptors(); preparePipelines(); if (!PlumageRender::Setter::settings.headless) { gui = new UI(vulkanDevice, renderPass, queue, pipelineCache,PlumageRender::Setter::settings.sampleCount); updateUIOverlay(); } buildCommandBuffers(); prepared = true; } void PlumageRender::renderMain::setupCamera() { camera.type = Camera::CameraType::lookat; camera.setPerspective(45.0f, (float)PlumageRender::Setter::settings.width / (float)PlumageRender::Setter::settings.height, 0.1f, 256.0f); camera.rotationSpeed = 0.25f; camera.movementSpeed = 0.1f; camera.setPosition({ 0.0f, 0.0f, -1.0f }); camera.setRotation({ 0.0f, 0.0f, 0.0f }); } void PlumageRender::renderMain::submitWork(VkCommandBuffer cmdBuffer, VkQueue queue) { VkSubmitInfo submitInfo = vks::initializers::submitInfo(); submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &cmdBuffer; VkFenceCreateInfo fenceInfo = vks::initializers::fenceCreateInfo(); VkFence fence; VK_CHECK_RESULT(vkCreateFence(device, &fenceInfo, nullptr, &fence)); VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, fence)); VK_CHECK_RESULT(vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX)); vkDestroyFence(device, fence, nullptr); } void PlumageRender::renderMain::render() { if (!prepared) { return; } if (!PlumageRender::Setter::settings.headless) { updateUIOverlay(); } //加入写到文件的函数 //swapChainImage = swapChain.images[frameIndex]; //outputImageSequeue(swapChainImage,filePath.imageSequenceFilePath); 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], ¤tBuffer); if ((acquire == VK_ERROR_OUT_OF_DATE_KHR) || (acquire == VK_SUBOPTIMAL_KHR)) { windowResize(); } else { VK_CHECK_RESULT(acquire); } // Update UBOs updateUniformBuffers(); UniformBufferSet[currentUB] = uniformBuffers[currentBuffer]; memcpy(currentUB.scene.mapped, &shaderDataScene, sizeof(shaderDataScene)); 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.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) { windowResize(); return; } else { VK_CHECK_RESULT(present); } } frameIndex += 1; frameIndex %= renderAhead; if (!paused) { if (PlumageRender::Setter::settings.rotateModel) { modelrot.y += frameTimer * 35.0f; if (modelrot.y > 360.0f) { modelrot.y -= 360.0f; } } if ((animate) && (models.scene.animations.size() > 0)) { animationTimer += frameTimer; if (animationTimer > models.scene.animations[animationIndex].end) { animationTimer -= models.scene.animations[animationIndex].end; } models.scene.updateAnimation(animationIndex, animationTimer); } updateShaderData(); if (PlumageRender::Setter::settings.rotateModel) { updateUniformBuffers(); } } if (camera.updated) { updateUniformBuffers(); } } void PlumageRender::renderMain::fileDropped(std::string filename) { vkDeviceWaitIdle(device); loadScene(filename); setupDescriptors(); buildCommandBuffers(); } // 完全重写,避免OS specific /* PlumageRender* plumageRender; #if defined(_WIN32) LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (plumageRender != NULL) { plumageRender->handleMessages(hWnd, uMsg, wParam, lParam); } return (DefWindowProc(hWnd, uMsg, wParam, lParam)); } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) { VulkanBackend::Setter setter; for (int32_t i = 0; i < __argc; i++) {setter.args.push_back(__argv[i]); }; plumageRender = new PlumageRender(); plumageRender->initVulkan(); if (!plumageRender->PlumageRender::Setter::settings.headless) { plumageRender->setupWindow(hInstance, WndProc); } plumageRender->prepare(); plumageRender->renderLoop(); delete(plumageRender); return 0; } #endif */ int main() { PlumageRender::renderMain plumageRender; VulkanBackend::VulkanFoundation vkFoundation; vkFoundation.initVulkan(); if (!PlumageRender::Setter::settings.headless) { plumageRender.initWindow(PlumageRender::Setter::settings.width,PlumageRender::Setter::settings.height); } return 0; }