aboutsummaryrefslogtreecommitdiff
path: root/demos/smoke/ShellWin32.cpp
diff options
context:
space:
mode:
authorTony Barbour <tony@LunarG.com>2016-02-25 15:44:10 -0700
committerTony Barbour <tony@LunarG.com>2016-02-26 13:53:07 -0700
commit6d366c23f50752c8bc39673416040d89a94a586f (patch)
tree7a9493a747ffad8b708fd373ffbee359459ddd66 /demos/smoke/ShellWin32.cpp
parent2e4f6dfe4624d966fb4db3c477586bd6b1c2b8e1 (diff)
downloadusermoji-6d366c23f50752c8bc39673416040d89a94a586f.tar.xz
demos: Add Hologram snapshot as Smoke test/demo
Diffstat (limited to 'demos/smoke/ShellWin32.cpp')
-rw-r--r--demos/smoke/ShellWin32.cpp256
1 files changed, 256 insertions, 0 deletions
diff --git a/demos/smoke/ShellWin32.cpp b/demos/smoke/ShellWin32.cpp
new file mode 100644
index 00000000..1a1a844c
--- /dev/null
+++ b/demos/smoke/ShellWin32.cpp
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <cassert>
+#include <iostream>
+#include <sstream>
+
+#include "Helpers.h"
+#include "Game.h"
+#include "ShellWin32.h"
+
+namespace {
+
+class Win32Timer {
+public:
+ Win32Timer()
+ {
+ LARGE_INTEGER freq;
+ QueryPerformanceFrequency(&freq);
+ freq_ = static_cast<double>(freq.QuadPart);
+
+ reset();
+ }
+
+ void reset()
+ {
+ QueryPerformanceCounter(&start_);
+ }
+
+ double get() const
+ {
+ LARGE_INTEGER now;
+ QueryPerformanceCounter(&now);
+
+ return static_cast<double>(now.QuadPart - start_.QuadPart) / freq_;
+ }
+
+private:
+ double freq_;
+ LARGE_INTEGER start_;
+};
+
+} // namespace
+
+ShellWin32::ShellWin32(Game &game) : Shell(game), hwnd_(nullptr)
+{
+ instance_extensions_.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
+ init_vk();
+}
+
+ShellWin32::~ShellWin32()
+{
+ cleanup_vk();
+ FreeLibrary(hmodule_);
+}
+
+void ShellWin32::create_window()
+{
+ const std::string class_name(settings_.name + "WindowClass");
+
+ hinstance_ = GetModuleHandle(nullptr);
+
+ WNDCLASSEX win_class = {};
+ win_class.cbSize = sizeof(WNDCLASSEX);
+ win_class.style = CS_HREDRAW | CS_VREDRAW;
+ win_class.lpfnWndProc = window_proc;
+ win_class.hInstance = hinstance_;
+ win_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
+ win_class.lpszClassName = class_name.c_str();
+ RegisterClassEx(&win_class);
+
+ const DWORD win_style =
+ WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE | WS_OVERLAPPEDWINDOW;
+
+ RECT win_rect = { 0, 0, settings_.initial_width, settings_.initial_height };
+ AdjustWindowRect(&win_rect, win_style, false);
+
+ hwnd_ = CreateWindowEx(WS_EX_APPWINDOW,
+ class_name.c_str(),
+ settings_.name.c_str(),
+ win_style,
+ 0,
+ 0,
+ win_rect.right - win_rect.left,
+ win_rect.bottom - win_rect.top,
+ nullptr,
+ nullptr,
+ hinstance_,
+ nullptr);
+
+ SetForegroundWindow(hwnd_);
+ SetWindowLongPtr(hwnd_, GWLP_USERDATA, (LONG_PTR) this);
+}
+
+PFN_vkGetInstanceProcAddr ShellWin32::load_vk()
+{
+ const char filename[] = "vulkan-1.dll";
+ HMODULE mod;
+ PFN_vkGetInstanceProcAddr get_proc;
+
+ mod = LoadLibrary(filename);
+ if (mod) {
+ get_proc = reinterpret_cast<PFN_vkGetInstanceProcAddr>(GetProcAddress(
+ mod, "vkGetInstanceProcAddr"));
+ }
+
+ if (!mod || !get_proc) {
+ std::stringstream ss;
+ ss << "failed to load " << filename;
+
+ if (mod)
+ FreeLibrary(mod);
+
+ throw std::runtime_error(ss.str());
+ }
+
+ hmodule_ = mod;
+
+ return get_proc;
+}
+
+bool ShellWin32::can_present(VkPhysicalDevice phy, uint32_t queue_family)
+{
+ return vk::GetPhysicalDeviceWin32PresentationSupportKHR(phy, queue_family);
+}
+
+VkSurfaceKHR ShellWin32::create_surface(VkInstance instance)
+{
+ VkWin32SurfaceCreateInfoKHR surface_info = {};
+ surface_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
+ surface_info.hinstance = hinstance_;
+ surface_info.hwnd = hwnd_;
+
+ VkSurfaceKHR surface;
+ vk::assert_success(vk::CreateWin32SurfaceKHR(instance, &surface_info, nullptr, &surface));
+
+ return surface;
+}
+
+LRESULT ShellWin32::handle_message(UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ switch (msg) {
+ case WM_SIZE:
+ {
+ UINT w = LOWORD(lparam);
+ UINT h = HIWORD(lparam);
+ resize_swapchain(w, h);
+ }
+ break;
+ case WM_KEYDOWN:
+ {
+ Game::Key key;
+
+ switch (wparam) {
+ case VK_ESCAPE:
+ key = Game::KEY_ESC;
+ break;
+ case VK_UP:
+ key = Game::KEY_UP;
+ break;
+ case VK_DOWN:
+ key = Game::KEY_DOWN;
+ break;
+ case VK_SPACE:
+ key = Game::KEY_SPACE;
+ break;
+ default:
+ key = Game::KEY_UNKNOWN;
+ break;
+ }
+
+ game_.on_key(key);
+ }
+ break;
+ case WM_CLOSE:
+ game_.on_key(Game::KEY_SHUTDOWN);
+ break;
+ case WM_DESTROY:
+ quit();
+ break;
+ default:
+ return DefWindowProc(hwnd_, msg, wparam, lparam);
+ break;
+ }
+
+ return 0;
+}
+
+void ShellWin32::quit()
+{
+ PostQuitMessage(0);
+}
+
+void ShellWin32::run()
+{
+ create_window();
+
+ create_context();
+ resize_swapchain(settings_.initial_width, settings_.initial_height);
+
+ Win32Timer timer;
+ double current_time = timer.get();
+
+ while (true) {
+ bool quit = false;
+
+ assert(settings_.animate);
+
+ // process all messages
+ MSG msg;
+ while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
+ if (msg.message == WM_QUIT) {
+ quit = true;
+ break;
+ }
+
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ if (quit)
+ break;
+
+ acquire_back_buffer();
+
+ double t = timer.get();
+ add_game_time(static_cast<float>(t - current_time));
+
+ present_back_buffer();
+
+ current_time = t;
+ }
+
+ destroy_context();
+
+ DestroyWindow(hwnd_);
+}