27 std::string windowTitle;
28 windowTitle =
title +
" - " + device;
30 windowTitle +=
" - " + std::to_string(
frameCounter) +
" fps";
40 VkCommandBufferAllocateInfo cmdBufAllocateInfo =
43 VK_COMMAND_BUFFER_LEVEL_PRIMARY,
56 return getAssetPath() +
"shaders/" +
shaderDir +
"/";
61 if (
ctx->enableDebugMarkers) {
84#ifdef DEBUG_FORCE_SHARED_GRAPHICS_COMPUTE_QUEUE
85 ctx->queueFamilyIndices.compute =
ctx->queueFamilyIndices.graphics;
99VkPipelineShaderStageCreateInfo
VkApp::loadShader(std::string fileName, VkShaderStageFlagBits stage)
101 VkPipelineShaderStageCreateInfo shaderStage = {};
102 shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
103 shaderStage.stage = stage;
105 shaderStage.pName =
"main";
106 assert(shaderStage.module != VK_NULL_HANDLE);
99VkPipelineShaderStageCreateInfo
VkApp::loadShader(std::string fileName, VkShaderStageFlagBits stage) {
…}
113 auto tStart = std::chrono::high_resolution_clock::now();
122 auto tEnd = std::chrono::high_resolution_clock::now();
123 auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
139 float fpsTimer = (float)(std::chrono::duration<double, std::milli>(tEnd -
lastTimestamp).count());
140 if (fpsTimer > 1000.0f)
146 SetWindowText(window, windowTitle.c_str());
163 bool quitMessageReceived =
false;
164 while (!quitMessageReceived) {
165 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
166 TranslateMessage(&msg);
167 DispatchMessage(&msg);
168 if (msg.message == WM_QUIT) {
169 quitMessageReceived =
true;
173 if (
prepared && !IsIconic(window)) {
177#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
182 struct android_poll_source* source;
183 bool destroy =
false;
187 while ((ident = ALooper_pollAll(focused ? 0 : -1, NULL, &events, (
void**)&source)) >= 0)
191 source->process(androidApp, source);
193 if (androidApp->destroyRequested != 0)
195 LOGD(
"Android app destroy requested");
205 ANativeActivity_finish(androidApp->activity);
212 auto tStart = std::chrono::high_resolution_clock::now();
215 auto tEnd = std::chrono::high_resolution_clock::now();
216 auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
228 float fpsTimer = std::chrono::duration<double, std::milli>(tEnd -
lastTimestamp).count();
229 if (fpsTimer > 1000.0f)
239 bool updateView =
false;
245 if (touchTimer >= 1.0) {
251 const float deadZone = 0.0015f;
290 if (
ctx->deviceHandle() != VK_NULL_HANDLE) {
291 vkDeviceWaitIdle(
ctx->deviceHandle());
300 ImGuiIO& io = ImGui::GetIO();
302 io.DisplaySize = ImVec2((
float)
width, (
float)
height);
311 ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0);
312 ImGui::SetNextWindowPos(ImVec2(10, 10));
313 ImGui::SetNextWindowSize(ImVec2(0, 0));
314 ImGui::Begin(
"Vulkan Example",
nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove);
315 ImGui::TextUnformatted(
title.c_str());
317 ImGui::Text(
"%.2f ms/frame (%.1d fps)", (1000.0f /
lastFPS),
lastFPS);
319#if defined(VK_USE_PLATFORM_ANDROID_KHR)
320 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 5.0f *
UIOverlay.scale));
322 ImGui::PushItemWidth(110.0f *
UIOverlay.scale);
324 ImGui::PopItemWidth();
325#if defined(VK_USE_PLATFORM_ANDROID_KHR)
326 ImGui::PopStyleVar();
330 ImGui::PopStyleVar();
338#if defined(VK_USE_PLATFORM_ANDROID_KHR)
350 vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
351 vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
362 if ((result == VK_ERROR_OUT_OF_DATE_KHR) || (result == VK_SUBOPTIMAL_KHR)) {
373 if (!((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR))) {
374 if (result == VK_ERROR_OUT_OF_DATE_KHR) {
387#if !defined(VK_USE_PLATFORM_ANDROID_KHR)
390 if (stat(getAssetPath().c_str(), &info) != 0)
393 std::string msg =
"Could not locate asset path in \"" + getAssetPath() +
"\" !";
394 MessageBox(NULL, msg.c_str(),
"Fatal error", MB_OK | MB_ICONERROR);
396 std::cerr <<
"Error: Could not find asset path in " << getAssetPath() <<
"\n";
402 settings.validation = enableValidation;
409 setupConsole(
"Vulkan validation output");
416 title =
"Compute shader Height FieldFluid simulation";
419 camera.setRotation(glm::vec3(-30.0f, -45.0f, 0.0f));
420 camera.setTranslation(glm::vec3(0.0f, 0.0f, -5.0f));
435 vkDestroyRenderPass(
ctx->deviceHandle(),
renderPass,
nullptr);
443 vkDestroyShaderModule(
ctx->deviceHandle(), shaderModule,
nullptr);
449 vkDestroyPipelineCache(
ctx->deviceHandle(),
ctx->pipelineCacheHandle(),
nullptr);
451 vkDestroyCommandPool(
ctx->deviceHandle(),
cmdPool,
nullptr);
453 vkDestroySemaphore(
ctx->deviceHandle(),
semaphores.presentComplete,
nullptr);
454 vkDestroySemaphore(
ctx->deviceHandle(),
semaphores.renderComplete,
nullptr);
456 vkDestroyFence(
ctx->deviceHandle(), fence,
nullptr);
463#if defined(VK_USE_PLATFORM_ANDROID_KHR)
470#if defined(VK_USE_PLATFORM_ANDROID_KHR)
504void VkApp::setupConsole(std::string title)
507 AttachConsole(GetCurrentProcessId());
509 freopen_s(&stream,
"CONOUT$",
"w+", stdout);
510 freopen_s(&stream,
"CONOUT$",
"w+", stderr);
511 SetConsoleTitle(TEXT(
title.c_str()));
514void VkApp::setupDPIAwareness()
516 typedef HRESULT *(__stdcall *SetProcessDpiAwarenessFunc)(PROCESS_DPI_AWARENESS);
518 HMODULE shCore = LoadLibraryA(
"Shcore.dll");
521 SetProcessDpiAwarenessFunc setProcessDpiAwareness =
522 (SetProcessDpiAwarenessFunc)GetProcAddress(shCore,
"SetProcessDpiAwareness");
524 if (setProcessDpiAwareness !=
nullptr)
526 setProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
533HWND VkApp::setupWindow(HINSTANCE hinstance, WNDPROC wndproc)
535 this->windowInstance = hinstance;
539 wndClass.cbSize =
sizeof(WNDCLASSEX);
540 wndClass.style = CS_HREDRAW | CS_VREDRAW;
541 wndClass.lpfnWndProc = wndproc;
542 wndClass.cbClsExtra = 0;
543 wndClass.cbWndExtra = 0;
544 wndClass.hInstance = hinstance;
545 wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
546 wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
547 wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
548 wndClass.lpszMenuName = NULL;
549 wndClass.lpszClassName =
name.c_str();
550 wndClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
552 if (!RegisterClassEx(&wndClass))
554 std::cout <<
"Could not register window class!\n";
559 int screenWidth = GetSystemMetrics(SM_CXSCREEN);
560 int screenHeight = GetSystemMetrics(SM_CYSCREEN);
564 if ((
width != (uint32_t)screenWidth) && (
height != (uint32_t)screenHeight))
566 DEVMODE dmScreenSettings;
567 memset(&dmScreenSettings, 0,
sizeof(dmScreenSettings));
568 dmScreenSettings.dmSize =
sizeof(dmScreenSettings);
569 dmScreenSettings.dmPelsWidth =
width;
570 dmScreenSettings.dmPelsHeight =
height;
571 dmScreenSettings.dmBitsPerPel = 32;
572 dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
573 if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
575 if (MessageBox(NULL,
"Fullscreen Mode not supported!\n Switch to window mode?",
"Error", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
595 dwExStyle = WS_EX_APPWINDOW;
596 dwStyle = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
600 dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
601 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
605 windowRect.left = 0L;
607 windowRect.right =
settings.fullscreen ? (long)screenWidth : (long)
width;
608 windowRect.bottom =
settings.fullscreen ? (long)screenHeight : (long)
height;
610 AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle);
613 window = CreateWindowEx(0,
616 dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
619 windowRect.right - windowRect.left,
620 windowRect.bottom - windowRect.top,
629 uint32_t x = (GetSystemMetrics(SM_CXSCREEN) - windowRect.right) / 2;
630 uint32_t y = (GetSystemMetrics(SM_CYSCREEN) - windowRect.bottom) / 2;
631 SetWindowPos(window, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
636 printf(
"Could not create window!\n");
641 ShowWindow(window, SW_SHOW);
642 SetForegroundWindow(window);
648void VkApp::handleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
658 ValidateRect(window, NULL);
715 camera.keys.right =
false;
721 mousePos = glm::vec2((
float)LOWORD(lParam), (
float)HIWORD(lParam));
725 mousePos = glm::vec2((
float)LOWORD(lParam), (
float)HIWORD(lParam));
729 mousePos = glm::vec2((
float)LOWORD(lParam), (
float)HIWORD(lParam));
743 short wheelDelta = GET_WHEEL_DELTA_WPARAM(wParam);
744 camera.translate(glm::vec3(0.0f, 0.0f, (
float)wheelDelta * 0.005f));
754 if ((
prepared) && (wParam != SIZE_MINIMIZED))
756 if ((
resizing) || ((wParam == SIZE_MAXIMIZED) || (wParam == SIZE_RESTORED)))
764 case WM_GETMINMAXINFO:
766 LPMINMAXINFO minMaxInfo = (LPMINMAXINFO)lParam;
767 minMaxInfo->ptMinTrackSize.x = 64;
768 minMaxInfo->ptMinTrackSize.y = 64;
771 case WM_ENTERSIZEMOVE:
774 case WM_EXITSIZEMOVE:
779#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
780int32_t VkApp::handleAppInput(
struct android_app* app, AInputEvent* event)
782 VkApp* vulkanExample =
reinterpret_cast<VkApp*
>(app->userData);
783 if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION)
785 int32_t eventSource = AInputEvent_getSource(event);
786 switch (eventSource) {
787 case AINPUT_SOURCE_JOYSTICK: {
789 vulkanExample->
gamePadState.
axisLeft.x = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_X, 0);
790 vulkanExample->
gamePadState.
axisLeft.y = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_Y, 0);
793 vulkanExample->
gamePadState.
axisRight.y = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_RZ, 0);
797 case AINPUT_SOURCE_TOUCHSCREEN: {
798 int32_t action = AMotionEvent_getAction(event);
801 case AMOTION_EVENT_ACTION_UP: {
802 vulkanExample->lastTapTime = AMotionEvent_getEventTime(event);
803 vulkanExample->touchPos.x = AMotionEvent_getX(event, 0);
804 vulkanExample->touchPos.y = AMotionEvent_getY(event, 0);
805 vulkanExample->touchTimer = 0.0;
806 vulkanExample->touchDown =
false;
810 int64_t eventTime = AMotionEvent_getEventTime(event);
811 int64_t downTime = AMotionEvent_getDownTime(event);
812 if (eventTime - downTime <= vks::android::TAP_TIMEOUT) {
813 float deadZone = (160.f / vks::android::screenDensity) * vks::android::TAP_SLOP * vks::android::TAP_SLOP;
814 float x = AMotionEvent_getX(event, 0) - vulkanExample->touchPos.x;
815 float y = AMotionEvent_getY(event, 0) - vulkanExample->touchPos.y;
816 if ((x * x + y * y) < deadZone) {
824 case AMOTION_EVENT_ACTION_DOWN: {
826 int64_t eventTime = AMotionEvent_getEventTime(event);
827 if (eventTime - vulkanExample->lastTapTime <= vks::android::DOUBLE_TAP_TIMEOUT) {
828 float deadZone = (160.f / vks::android::screenDensity) * vks::android::DOUBLE_TAP_SLOP * vks::android::DOUBLE_TAP_SLOP;
829 float x = AMotionEvent_getX(event, 0) - vulkanExample->touchPos.x;
830 float y = AMotionEvent_getY(event, 0) - vulkanExample->touchPos.y;
831 if ((x * x + y * y) < deadZone) {
833 vulkanExample->touchDown =
false;
837 vulkanExample->touchDown =
true;
839 vulkanExample->touchPos.x = AMotionEvent_getX(event, 0);
840 vulkanExample->touchPos.y = AMotionEvent_getY(event, 0);
841 vulkanExample->
mousePos.x = AMotionEvent_getX(event, 0);
842 vulkanExample->
mousePos.y = AMotionEvent_getY(event, 0);
845 case AMOTION_EVENT_ACTION_MOVE: {
846 bool handled =
false;
848 ImGuiIO& io = ImGui::GetIO();
849 handled = io.WantCaptureMouse;
852 int32_t eventX = AMotionEvent_getX(event, 0);
853 int32_t eventY = AMotionEvent_getY(event, 0);
855 float deltaX = (float)(vulkanExample->touchPos.y - eventY) * vulkanExample->
camera.
rotationSpeed * 0.5f;
856 float deltaY = (float)(vulkanExample->touchPos.x - eventX) * vulkanExample->
camera.
rotationSpeed * 0.5f;
858 vulkanExample->
camera.
rotate(glm::vec3(deltaX, 0.0f, 0.0f));
859 vulkanExample->
camera.
rotate(glm::vec3(0.0f, -deltaY, 0.0f));
863 vulkanExample->touchPos.x = eventX;
864 vulkanExample->touchPos.y = eventY;
878 if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY)
880 int32_t keyCode = AKeyEvent_getKeyCode((
const AInputEvent*)event);
881 int32_t action = AKeyEvent_getAction((
const AInputEvent*)event);
884 if (action == AKEY_EVENT_ACTION_UP)
889 case AKEYCODE_BUTTON_A:
892 case AKEYCODE_BUTTON_B:
895 case AKEYCODE_BUTTON_X:
898 case AKEYCODE_BUTTON_Y:
901 case AKEYCODE_BUTTON_L1:
904 case AKEYCODE_BUTTON_R1:
907 case AKEYCODE_BUTTON_START:
912 LOGD(
"Button %d pressed", keyCode);
918void VkApp::handleAppCommand(android_app * app, int32_t cmd)
920 assert(app->userData != NULL);
921 VkApp* vulkanExample =
reinterpret_cast<VkApp*
>(app->userData);
924 case APP_CMD_SAVE_STATE:
925 LOGD(
"APP_CMD_SAVE_STATE");
932 case APP_CMD_INIT_WINDOW:
933 LOGD(
"APP_CMD_INIT_WINDOW");
934 if (androidApp->window != NULL)
942 LOGE(
"Could not initialize Vulkan, exiting!");
943 androidApp->destroyRequested = 1;
948 LOGE(
"No window assigned!");
951 case APP_CMD_LOST_FOCUS:
952 LOGD(
"APP_CMD_LOST_FOCUS");
953 vulkanExample->focused =
false;
955 case APP_CMD_GAINED_FOCUS:
956 LOGD(
"APP_CMD_GAINED_FOCUS");
957 vulkanExample->focused =
true;
959 case APP_CMD_TERM_WINDOW:
961 LOGD(
"APP_CMD_TERM_WINDOW");
967 case APP_CMD_CONFIG_CHANGED:
968 LOGD(
"APP_CMD_CONFIG_CHANGED");
971 LOGD(
"APP_CMD_START");
974 LOGD(
"APP_CMD_RESUME");
977 LOGD(
"APP_CMD_PAUSE");
980 LOGD(
"APP_CMD_STOP");
982 case APP_CMD_DESTROY:
983 LOGD(
"APP_CMD_DESTROY");
996#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
1017 for (
auto it = scn->begin(); it != scn->end(); it++)
1019 for (
auto iter : it->graphicsPipeline()->activeModules())
1022 if (m && m->isVisible())
1024 m->viewChanged(
camera.matrices.perspective,
camera.matrices.view);
1038 VkClearValue clearValues[2];
1039 clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 1.0f } };;
1040 clearValues[1].depthStencil = { 1.0f, 0 };
1044 renderPassBeginInfo.renderArea.offset.x = 0;
1045 renderPassBeginInfo.renderArea.offset.y = 0;
1046 renderPassBeginInfo.renderArea.extent.width =
width;
1047 renderPassBeginInfo.renderArea.extent.height =
height;
1048 renderPassBeginInfo.clearValueCount = 2;
1049 renderPassBeginInfo.pClearValues = clearValues;
1060 vkCmdBeginRenderPass(
drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1085 VK_CHECK_RESULT(vkCreateFence(
ctx->deviceHandle(), &fenceCreateInfo,
nullptr, &fence));
1091 VkCommandPoolCreateInfo cmdPoolInfo = {};
1092 cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1093 cmdPoolInfo.queueFamilyIndex =
swapChain.queueNodeIndex;
1094 cmdPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
1100 VkImageCreateInfo imageCI{};
1101 imageCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1102 imageCI.imageType = VK_IMAGE_TYPE_2D;
1105 imageCI.mipLevels = 1;
1106 imageCI.arrayLayers = 1;
1107 imageCI.samples = VK_SAMPLE_COUNT_1_BIT;
1108 imageCI.tiling = VK_IMAGE_TILING_OPTIMAL;
1109 imageCI.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1112 VkMemoryRequirements memReqs{};
1113 vkGetImageMemoryRequirements(
ctx->deviceHandle(),
depthStencil.image, &memReqs);
1115 VkMemoryAllocateInfo memAllloc{};
1116 memAllloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1117 memAllloc.allocationSize = memReqs.size;
1118 memAllloc.memoryTypeIndex =
ctx->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1122 VkImageViewCreateInfo imageViewCI{};
1123 imageViewCI.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1124 imageViewCI.viewType = VK_IMAGE_VIEW_TYPE_2D;
1127 imageViewCI.subresourceRange.baseMipLevel = 0;
1128 imageViewCI.subresourceRange.levelCount = 1;
1129 imageViewCI.subresourceRange.baseArrayLayer = 0;
1130 imageViewCI.subresourceRange.layerCount = 1;
1131 imageViewCI.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1134 imageViewCI.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
1141 VkImageView attachments[2];
1146 VkFramebufferCreateInfo frameBufferCreateInfo = {};
1147 frameBufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
1148 frameBufferCreateInfo.pNext = NULL;
1149 frameBufferCreateInfo.renderPass =
renderPass;
1150 frameBufferCreateInfo.attachmentCount = 2;
1151 frameBufferCreateInfo.pAttachments = attachments;
1152 frameBufferCreateInfo.width =
width;
1153 frameBufferCreateInfo.height =
height;
1154 frameBufferCreateInfo.layers = 1;
1160 attachments[0] =
swapChain.buffers[i].view;
1167 std::array<VkAttachmentDescription, 2> attachments = {};
1169 attachments[0].format =
swapChain.colorFormat;
1170 attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
1171 attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1172 attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1173 attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1174 attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1175 attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1176 attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
1179 attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
1180 attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1181 attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1182 attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1183 attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1184 attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1185 attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1187 VkAttachmentReference colorReference = {};
1188 colorReference.attachment = 0;
1189 colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1191 VkAttachmentReference depthReference = {};
1192 depthReference.attachment = 1;
1193 depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1195 VkSubpassDescription subpassDescription = {};
1196 subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1197 subpassDescription.colorAttachmentCount = 1;
1198 subpassDescription.pColorAttachments = &colorReference;
1199 subpassDescription.pDepthStencilAttachment = &depthReference;
1200 subpassDescription.inputAttachmentCount = 0;
1201 subpassDescription.pInputAttachments =
nullptr;
1202 subpassDescription.preserveAttachmentCount = 0;
1203 subpassDescription.pPreserveAttachments =
nullptr;
1204 subpassDescription.pResolveAttachments =
nullptr;
1207 std::array<VkSubpassDependency, 2> dependencies;
1209 dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
1210 dependencies[0].dstSubpass = 0;
1211 dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
1212 dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1213 dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
1214 dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1215 dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
1217 dependencies[1].srcSubpass = 0;
1218 dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
1219 dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1220 dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
1221 dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1222 dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
1223 dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
1225 VkRenderPassCreateInfo renderPassInfo = {};
1226 renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
1227 renderPassInfo.attachmentCount =
static_cast<uint32_t
>(attachments.size());
1228 renderPassInfo.pAttachments = attachments.data();
1229 renderPassInfo.subpassCount = 1;
1230 renderPassInfo.pSubpasses = &subpassDescription;
1231 renderPassInfo.dependencyCount =
static_cast<uint32_t
>(dependencies.size());
1232 renderPassInfo.pDependencies = dependencies.data();
1249 vkDeviceWaitIdle(
ctx->deviceHandle());
1278 vkDeviceWaitIdle(
ctx->deviceHandle());
1293 int32_t dx = (int32_t)
mousePos.x - x;
1294 int32_t dy = (int32_t)
mousePos.y - y;
1296 bool handled =
false;
1299 ImGuiIO& io = ImGui::GetIO();
1300 handled = io.WantCaptureMouse;
1305 mousePos = glm::vec2((
float)x, (
float)y);
1310 camera.rotate(glm::vec3(dy *
camera.rotationSpeed, -dx *
camera.rotationSpeed, 0.0f));
1314 camera.translate(glm::vec3(-0.0f, 0.0f, dy * .005f));
1318 camera.translate(glm::vec3(-dx * 0.01f, -dy * 0.01f, 0.0f));
1321 mousePos = glm::vec2((
float)x, (
float)y);
1329 swapChain.initSurface(windowInstance, window);
1330#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
1331 swapChain.initSurface(androidApp->window);
1346 for (
auto it = scn->begin(); it != scn->end(); it++)
1348 for (
auto iter : it->graphicsPipeline()->activeModules())
1351 if (m && m->isVisible())
1354 m->buildCommandBuffers(commandBuffer);
1365 for (
auto it = scn->begin(); it != scn->end(); it++)
1367 for (
auto iter : it->graphicsPipeline()->activeModules())
1370 if (m && m->isVisible())
struct Camera::@053002266270240026173313023376237034104174045346 keys
void rotate(glm::vec3 delta)
void drawUI(const VkCommandBuffer commandBuffer)
Adds the drawing commands for the ImGui overlay to the given command buffer.
std::string getWindowTitle()
VkDescriptorPool descriptorPool
void destroyCommandBuffers()
void buildCustomCommandBuffer(VkCommandBuffer commandBuffer)
virtual void mouseMoved(double x, double y, bool &handled)
(Virtual) Called after the mouse cursor moved and before internal events (like camera rotation) is ha...
virtual void buildCommandBuffers()
(Virtual) Called when resources have been recreated that require a rebuild of the command buffers (e....
virtual void getEnabledFeatures()
(Virtual) Called after the physical device features have been read, can be used to set features to en...
virtual void setupFrameBuffer()
(Virtual) Setup default framebuffers for all requested swapchain images
std::string getShadersPath() const
VkPipelineShaderStageCreateInfo loadShader(std::string fileName, VkShaderStageFlagBits stage)
Loads a SPIR-V shader file for the given shader stage.
virtual void renderFrame()
(Virtual) Default image acquire + submission and command buffer submission function
virtual void viewChanged()
(Virtual) Called when the camera view has changed
void setWindowTitle(std::string name)
virtual void keyPressed(uint32_t)
(Virtual) Called after a key was pressed, can be used to do custom key handling
float frameTimer
Last frame time measured using a high performance timer (if available)
void submitFrame()
Presents the current image to the swap chain.
void handleMouseMove(int32_t x, int32_t y)
VkPipelineStageFlags submitPipelineStages
Pipeline stages used to wait at for graphics queue submissions.
virtual void setupDepthStencil()
(Virtual) Setup default depth and stencil views
void renderLoop()
Entry point for the main render loop.
std::vector< VkFence > waitFences
void createSynchronizationPrimitives()
VkApp(bool enableValidation=false)
virtual void windowResized()
(Virtual) Called when the window has been resized, can be used by the sample application to recreate ...
struct VkApp::@035006017256177105240376270267042317070052055111 depthStencil
std::chrono::time_point< std::chrono::high_resolution_clock > lastTimestamp
virtual void prepare()
Prepares all Vulkan resources and functions required to run the sample.
VkFormat depthFormat
Logical device, application's view of the physical device (GPU)
std::vector< VkFramebuffer > frameBuffers
std::vector< VkCommandBuffer > drawCmdBuffers
virtual void render()
(Pure virtual) Render function to be implemented by the sample application
VulkanSwapChain swapChain
void setSceneGraph(std::shared_ptr< dyno::SceneGraph > scn)
struct VkApp::@024362050273107367271176263277065044127044370222 semaphores
struct VkApp::@236151146162240273010117313013267214200120303363 gamePadState
void createCommandBuffers()
virtual void setupRenderPass()
(Virtual) Setup a default renderpass
struct VkApp::Settings settings
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
(Virtual) Called when the UI overlay is updating, can be used to add custom elements to the overlay
bool initVulkan()
Setup the vulkan instance, enable required extensions and connect to the physical device (GPU)
struct VkApp::@033204162100256106143271256032327056257013175042 mouseButtons
std::vector< VkShaderModule > shaderModules
static SceneGraphFactory * instance()
void pushScene(std::shared_ptr< SceneGraph > scn)
std::shared_ptr< SceneGraph > active()
VkContext * currentContext()
static VkSystem * instance()
VkCommandBufferAllocateInfo commandBufferAllocateInfo(VkCommandPool commandPool, VkCommandBufferLevel level, uint32_t bufferCount)
VkFenceCreateInfo fenceCreateInfo(VkFenceCreateFlags flags=0)
VkRenderPassBeginInfo renderPassBeginInfo()
VkCommandBufferBeginInfo commandBufferBeginInfo()
VkSemaphoreCreateInfo semaphoreCreateInfo()
VkRect2D rect2D(int32_t width, int32_t height, int32_t offsetX, int32_t offsetY)
VkViewport viewport(float width, float height, float minDepth, float maxDepth)
VkSubmitInfo submitInfo()
bool overlay
Enable UI overlay.