Extract edit menu and Windows/bootstrap preview seams
This commit is contained in:
281
src/main.cpp
281
src/main.cpp
@@ -7,9 +7,7 @@
|
||||
#include "app.h"
|
||||
#include "canvas.h"
|
||||
#include "keymap.h"
|
||||
#include "legacy_gl_runtime_dispatch.h"
|
||||
#include "legacy_preference_storage.h"
|
||||
#include "renderer_gl/opengl_capabilities.h"
|
||||
#include "platform_windows/windows_bootstrap_helpers.h"
|
||||
#include "platform_windows/windows_platform_services.h"
|
||||
#include "platform_windows/windows_lifecycle_shell.h"
|
||||
#include "platform_windows/windows_splash.h"
|
||||
@@ -17,22 +15,15 @@
|
||||
#include "platform_windows/windows_vr_shell.h"
|
||||
#include "../resource.h"
|
||||
|
||||
#include <shellscalingapi.h>
|
||||
#include <WbemCli.h>
|
||||
#include <deque>
|
||||
#include "wacom.h"
|
||||
#include "abr.h"
|
||||
|
||||
#if __has_include(<renderdoc_app.h>)
|
||||
#include <renderdoc_app.h>
|
||||
#define USE_RENDERDOC
|
||||
#endif
|
||||
|
||||
#include <iomanip>
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);
|
||||
namespace pp::platform::windows {
|
||||
void set_async_render_context(HDC hdc, HGLRC hrc);
|
||||
void lock_async_render_context();
|
||||
@@ -40,20 +31,10 @@ namespace pp::platform::windows {
|
||||
void unlock_async_render_context();
|
||||
void swap_async_render_context();
|
||||
}
|
||||
extern HRESULT(*GetDpiForMonitor_fn)(HMONITOR hmonitor, MONITOR_DPI_TYPE dpiType, UINT* dpiX, UINT* dpiY);
|
||||
extern HRESULT(*SetProcessDpiAwareness_fn)(PROCESS_DPI_AWARENESS value);
|
||||
bool win32_renderdoc_init();
|
||||
void win32_renderdoc_frame_start();
|
||||
void win32_renderdoc_frame_end();
|
||||
void init_shcore_API();
|
||||
std::string GetLastErrorAsString();
|
||||
void _pre_call_callback(const char* name, void* funcptr, int len_args, ...);
|
||||
void _post_call_callback(const char* name, void* funcptr, int len_args, ...);
|
||||
struct RetainedState
|
||||
{
|
||||
HINSTANCE hInst{};
|
||||
HWND hWnd{};
|
||||
const wchar_t* className{};
|
||||
bool keys[256]{};
|
||||
std::map<kKey, int> vkey_map;
|
||||
wchar_t window_title[512]{};
|
||||
@@ -112,239 +93,6 @@ void drain_main_tasks()
|
||||
}
|
||||
}
|
||||
|
||||
struct MainWindowStartupState
|
||||
{
|
||||
WNDCLASS window_class{};
|
||||
PIXELFORMATDESCRIPTOR pixel_format{};
|
||||
DWORD window_style = WS_OVERLAPPEDWINDOW;
|
||||
RECT client_rect{ 0, 0, 0, 0 };
|
||||
POINT client_pos{ CW_USEDEFAULT, CW_USEDEFAULT };
|
||||
int show_command = SW_NORMAL;
|
||||
};
|
||||
|
||||
struct OpenGlWindowContext
|
||||
{
|
||||
HDC device_context{};
|
||||
HGLRC render_context{};
|
||||
pp::renderer::gl::OpenGlRuntimeInfo runtime_info{};
|
||||
};
|
||||
|
||||
enum class MainStartupResult
|
||||
{
|
||||
Ok = 0,
|
||||
GladLoadFailure = 1,
|
||||
MissingCoreContextSupport = 2,
|
||||
};
|
||||
|
||||
void ensure_runtime_data_directory()
|
||||
{
|
||||
FILE* fp_check = fopen("data\\layout.xml", "rb");
|
||||
if (!fp_check)
|
||||
{
|
||||
LOG("data files not found");
|
||||
static char path[MAX_PATH];
|
||||
GetModuleFileNameA(NULL, path, MAX_PATH);
|
||||
LOG("current dir %s", path);
|
||||
PathRemoveFileSpecA(path);
|
||||
SetCurrentDirectoryA(path);
|
||||
LOG("change dir to %s", path);
|
||||
return;
|
||||
}
|
||||
|
||||
fclose(fp_check);
|
||||
LOG("data files ok");
|
||||
}
|
||||
|
||||
MainWindowStartupState initialize_main_window_startup_state()
|
||||
{
|
||||
auto& state = retained_state();
|
||||
auto startup = MainWindowStartupState {};
|
||||
|
||||
state.hInst = GetModuleHandle(NULL);
|
||||
state.className = L"EngineMain";
|
||||
|
||||
startup.window_class.hInstance = state.hInst;
|
||||
startup.window_class.lpfnWndProc = (WNDPROC)WndProc;
|
||||
startup.window_class.lpszClassName = state.className;
|
||||
startup.window_class.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
startup.window_class.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
|
||||
RegisterClass(&startup.window_class);
|
||||
|
||||
auto monitor = MonitorFromWindow(0, MONITOR_DEFAULTTOPRIMARY);
|
||||
auto x = unsigned{ 96 };
|
||||
auto y = unsigned{ 96 };
|
||||
if (GetDpiForMonitor_fn)
|
||||
GetDpiForMonitor_fn(monitor, MDT_EFFECTIVE_DPI, &x, &y);
|
||||
App::I->display_density = (float)x / 96.f;
|
||||
|
||||
const auto window_preferences = pp::panopainter::read_legacy_window_preferences(SW_NORMAL);
|
||||
if (window_preferences.has_ui_scale)
|
||||
App::I->zoom = window_preferences.ui_scale;
|
||||
else
|
||||
App::I->zoom = (float)x / 96.f;
|
||||
|
||||
startup.show_command = window_preferences.show_command;
|
||||
startup.client_rect = {
|
||||
0,
|
||||
0,
|
||||
static_cast<LONG>(App::I->width * App::I->zoom),
|
||||
static_cast<LONG>(App::I->height * App::I->zoom),
|
||||
};
|
||||
if (window_preferences.has_window_rect)
|
||||
{
|
||||
auto wnd_rect = window_preferences.window_rect;
|
||||
App::I->width = wnd_rect.z - wnd_rect.x;
|
||||
App::I->height = wnd_rect.w - wnd_rect.y;
|
||||
startup.client_rect = { wnd_rect.x, wnd_rect.y, wnd_rect.z, wnd_rect.w };
|
||||
startup.client_pos = { wnd_rect.x, wnd_rect.y };
|
||||
}
|
||||
else
|
||||
{
|
||||
AdjustWindowRect(&startup.client_rect, startup.window_style, false);
|
||||
}
|
||||
|
||||
return startup;
|
||||
}
|
||||
|
||||
void create_main_window(const MainWindowStartupState& startup, const wchar_t* window_title)
|
||||
{
|
||||
auto& state = retained_state();
|
||||
const int window_width = startup.client_rect.right - startup.client_rect.left;
|
||||
const int window_height = startup.client_rect.bottom - startup.client_rect.top;
|
||||
state.hWnd = CreateWindow(
|
||||
startup.window_class.lpszClassName,
|
||||
window_title,
|
||||
startup.window_style,
|
||||
startup.client_pos.x,
|
||||
startup.client_pos.y,
|
||||
window_width,
|
||||
window_height,
|
||||
0,
|
||||
0,
|
||||
state.hInst,
|
||||
0);
|
||||
}
|
||||
|
||||
void initialize_pixel_format_descriptor(PIXELFORMATDESCRIPTOR& pixel_format)
|
||||
{
|
||||
pixel_format.nSize = sizeof(pixel_format);
|
||||
pixel_format.nVersion = 1;
|
||||
pixel_format.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pixel_format.iPixelType = PFD_TYPE_RGBA;
|
||||
pixel_format.cColorBits = 32;
|
||||
pixel_format.cDepthBits = 24;
|
||||
pixel_format.iLayerType = PFD_MAIN_PLANE;
|
||||
}
|
||||
|
||||
bool load_glad_entry_points(HDC device_context)
|
||||
{
|
||||
if (!gladLoadGL())
|
||||
{
|
||||
LOG("gladLoadGL() failed");
|
||||
return false;
|
||||
}
|
||||
if (!gladLoadWGL(device_context))
|
||||
{
|
||||
LOG("gladLoadWGL() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pp::renderer::gl::OpenGlRuntimeInfo log_runtime_info()
|
||||
{
|
||||
auto runtime_info = pp::renderer::gl::OpenGlRuntimeInfo {};
|
||||
const auto runtime_info_result = pp::renderer::gl::query_opengl_runtime_info(
|
||||
pp::legacy::gl_runtime::runtime_info_dispatch());
|
||||
if (runtime_info_result.ok())
|
||||
{
|
||||
runtime_info = runtime_info_result.value();
|
||||
LOG("GL version: %s", runtime_info.version);
|
||||
LOG("GL vendor: %s", runtime_info.vendor);
|
||||
LOG("GL renderer: %s", runtime_info.renderer);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("OpenGL runtime info query failed: %s", runtime_info_result.status().message);
|
||||
}
|
||||
|
||||
return runtime_info;
|
||||
}
|
||||
|
||||
bool upgrade_to_core_gl_context(const MainWindowStartupState& startup, OpenGlWindowContext& context)
|
||||
{
|
||||
if (!GLAD_WGL_ARB_create_context)
|
||||
{
|
||||
LOG("WGL_ARB_create_context not supported");
|
||||
// If not supported, go fuck yourself we are not gonna support your shitty device
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto wgl_config = pp::renderer::gl::windows_wgl_core_context_3_3_config();
|
||||
UINT num_format = 0;
|
||||
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(context.render_context);
|
||||
DestroyWindow(retained_state().hWnd);
|
||||
|
||||
create_main_window(startup, retained_state().window_title);
|
||||
|
||||
context.device_context = GetDC(retained_state().hWnd);
|
||||
int pixel_format = 0;
|
||||
wglChoosePixelFormatARB(
|
||||
context.device_context,
|
||||
wgl_config.pixel_format_attributes.data(),
|
||||
nullptr,
|
||||
1,
|
||||
&pixel_format,
|
||||
&num_format);
|
||||
SetPixelFormat(context.device_context, pixel_format, &startup.pixel_format);
|
||||
context.render_context = wglCreateContextAttribsARB(
|
||||
context.device_context,
|
||||
NULL,
|
||||
wgl_config.context_attributes.data());
|
||||
wglMakeCurrent(context.device_context, context.render_context);
|
||||
pp::platform::windows::set_async_render_context(context.device_context, context.render_context);
|
||||
return true;
|
||||
}
|
||||
|
||||
MainStartupResult initialize_main_window_and_gl(MainWindowStartupState& startup, OpenGlWindowContext& context)
|
||||
{
|
||||
create_main_window(startup, L"PanoPainter");
|
||||
initialize_pixel_format_descriptor(startup.pixel_format);
|
||||
|
||||
context.device_context = GetDC(retained_state().hWnd);
|
||||
const int pixel_format = ChoosePixelFormat(context.device_context, &startup.pixel_format);
|
||||
SetPixelFormat(context.device_context, pixel_format, &startup.pixel_format);
|
||||
context.render_context = wglCreateContext(context.device_context);
|
||||
wglMakeCurrent(context.device_context, context.render_context);
|
||||
pp::platform::windows::set_async_render_context(context.device_context, context.render_context);
|
||||
|
||||
if (!load_glad_entry_points(context.device_context))
|
||||
return MainStartupResult::GladLoadFailure;
|
||||
|
||||
context.runtime_info = log_runtime_info();
|
||||
|
||||
#ifdef USE_RENDERDOC
|
||||
if (!win32_renderdoc_init())
|
||||
LOG("Renderdoc not started");
|
||||
#endif
|
||||
|
||||
const auto renderer_name = std::string(context.runtime_info.renderer != nullptr ? context.runtime_info.renderer : "");
|
||||
swprintf_s(
|
||||
retained_state().window_title,
|
||||
L"PanoPainter %s (%s)",
|
||||
g_version_number_w,
|
||||
str2wstr(renderer_name).c_str());
|
||||
|
||||
if (!upgrade_to_core_gl_context(startup, context))
|
||||
return MainStartupResult::MissingCoreContextSupport;
|
||||
|
||||
return MainStartupResult::Ok;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
HWND pp_windows_main_window_handle()
|
||||
@@ -687,18 +435,19 @@ void win32_save_window_state()
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
auto& state = retained_state();
|
||||
state.hInst = GetModuleHandle(NULL);
|
||||
|
||||
App::I = new App();
|
||||
App::I->set_platform_services(&pp::platform::windows::platform_services());
|
||||
App::I->initLog();
|
||||
|
||||
init_shcore_API();
|
||||
pp::platform::windows::init_shcore_API();
|
||||
pp::platform::windows::initialize_stylus_input();
|
||||
|
||||
if(SetProcessDpiAwareness_fn)
|
||||
SetProcessDpiAwareness_fn(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||
if (pp::platform::windows::SetProcessDpiAwareness_fn)
|
||||
pp::platform::windows::SetProcessDpiAwareness_fn(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||
|
||||
ensure_runtime_data_directory();
|
||||
pp::platform::windows::ensure_runtime_data_directory();
|
||||
|
||||
pp::platform::windows::SplashScreen splash(GetModuleHandle(NULL));
|
||||
|
||||
@@ -712,15 +461,15 @@ int main(int argc, char** argv)
|
||||
App::I->create();
|
||||
|
||||
memset(&state.keys, 0, sizeof(state.keys));
|
||||
auto startup = initialize_main_window_startup_state();
|
||||
auto context = OpenGlWindowContext {};
|
||||
switch (initialize_main_window_and_gl(startup, context))
|
||||
auto startup = pp::platform::windows::initialize_main_window_startup_state();
|
||||
auto context = pp::platform::windows::OpenGlWindowContext {};
|
||||
switch (pp::platform::windows::initialize_main_window_and_gl(startup, state.hWnd, state.hInst, state.window_title, context))
|
||||
{
|
||||
case MainStartupResult::Ok:
|
||||
case pp::platform::windows::MainStartupResult::Ok:
|
||||
break;
|
||||
case MainStartupResult::GladLoadFailure:
|
||||
case pp::platform::windows::MainStartupResult::GladLoadFailure:
|
||||
return 0;
|
||||
case MainStartupResult::MissingCoreContextSupport:
|
||||
case pp::platform::windows::MainStartupResult::MissingCoreContextSupport:
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -746,7 +495,7 @@ int main(int argc, char** argv)
|
||||
// link: https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-registertouchwindow
|
||||
if (RegisterTouchWindow(state.hWnd, 0) == 0)
|
||||
{
|
||||
LOG("RegisterTouchWindow error: %s", GetLastErrorAsString().c_str());
|
||||
LOG("RegisterTouchWindow error: %s", pp::platform::windows::GetLastErrorAsString().c_str());
|
||||
}
|
||||
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
@@ -756,8 +505,8 @@ int main(int argc, char** argv)
|
||||
App::I->runtime().ui_thread_start(*App::I);
|
||||
|
||||
#ifdef _DEBUG
|
||||
glad_set_pre_callback(_pre_call_callback);
|
||||
glad_set_post_callback(_post_call_callback);
|
||||
glad_set_pre_callback(pp::platform::windows::_pre_call_callback);
|
||||
glad_set_post_callback(pp::platform::windows::_post_call_callback);
|
||||
#endif
|
||||
|
||||
if (!state.sandboxed)
|
||||
|
||||
Reference in New Issue
Block a user