Mandrill 2025.6.0
Loading...
Searching...
No Matches
Common.h
1#pragma once
2
3#if defined(_WIN64)
4#ifndef NOMINMAX
5#define NOMINMAX
6#endif
7#include "windows.h"
8#endif
9
10#define GLFW_INCLUDE_VULKAN
11#include <GLFW/glfw3.h>
12
13#if defined(_WIN64)
14#define GLFW_EXPOSE_NATIVE_WIN32
15#include "GLFW/glfw3native.h"
16#endif
17
18#define GLM_FORCE_RADIANS
19#define GLM_FORCE_DEPTH_ZERO_TO_ONE
20#define GLM_ENABLE_EXPERIMENTAL
21#include <glm/glm.hpp>
22#include <glm/gtc/matrix_access.hpp>
23#include <glm/gtc/matrix_transform.hpp>
24#include <glm/gtc/type_ptr.hpp>
25#include <glm/gtx/hash.hpp>
26#include <glm/gtx/rotate_vector.hpp>
27
28#include <imgui/imgui.h>
29#include <imgui/imgui_impl_glfw.h>
30#include <imgui/imgui_impl_vulkan.h>
31
32#include <stb/stb_image.h>
33#include <stb/stb_image_write.h>
34
35#ifdef MANDRILL_USE_OPENVDB
36#include <openvdb/openvdb.h>
37#endif
38
39#include <algorithm>
40#include <array>
41#include <concepts>
42#include <condition_variable>
43#include <ctime>
44#include <filesystem>
45#include <format>
46#include <fstream>
47#include <iostream>
48#include <map>
49#include <memory>
50#include <random>
51#include <set>
52#include <source_location>
53#include <string>
54#include <thread>
55#include <unordered_map>
56#include <utility>
57#include <variant>
58#include <vector>
59
60#define MANDRILL_NAME "Mandrill"
61
62// Version (set in CMakeLists.txt)
63#ifndef MANDRILL_VERSION_MAJOR
64#error "Missing major version number"
65#endif
66#ifndef MANDRILL_VERSION_MINOR
67#error "Missing minor version number"
68#endif
69#ifndef MANDRILL_VERSION_PATCH
70#error "Missing patch version number"
71#endif
72
73// Platform
74#define MANDRILL_PLATFORM_WINDOWS 1
75#define MANDRILL_PLATFORM_LINUX 2
76
77#ifndef MANDRILL_PLATFORM
78#if defined(_WIN64)
79#define MANDRILL_PLATFORM MANDRILL_PLATFORM_WINDOWS
80#elif defined(__linux__)
81#define MANDRILL_PLATFORM MANDRILL_PLATFORM_LINUX
82#else
83#error "Unsupported target platform"
84#endif
85#endif
86
87#define MANDRILL_WINDOWS (MANDRILL_PLATFORM == MANDRILL_PLATFORM_WINDOWS)
88#define MANDRILL_LINUX (MANDRILL_PLATFORM == MANDRILL_PLATFORM_LINUX)
89
90// Library export
91#if MANDRILL_WINDOWS
92#define MANDRILL_API_EXPORT __declspec(dllexport)
93#define MANDRILL_API_IMPORT __declspec(dllimport)
94#elif MANDRILL_LINUX
95#define MANDRILL_API_EXPORT __attribute__((visibility("default")))
96#define MANDRILL_API_IMPORT
97#endif
98
99#ifdef MANDRILL_DLL
100#define MANDRILL_API MANDRILL_API_EXPORT
101#else
102#define MANDRILL_API MANDRILL_API_IMPORT
103#endif
104
105// Use this to disallow copying and default construction of class
106#define MANDRILL_NON_COPYABLE(x) \
107 MANDRILL_API x() = delete; \
108 MANDRILL_API x(const x&) = delete; \
109 MANDRILL_API x& operator=(const x&) = delete;
110
111// Some Mandrill specific helper types and classes
112namespace Mandrill
113{
114 // Shorthand for std::shared_ptr<T>
115 template <typename T> using ptr = std::shared_ptr<T>;
116
117 // Shorthand for std::make_shared<T>
118 template <typename T, typename... Args> static inline ptr<T> make_ptr(Args&&... args)
119 {
120 return std::make_shared<T>(std::forward<Args>(args)...);
121 }
122
123 template <typename T>
124 concept Sizable = requires(T t) {
125 { t.size() } -> std::convertible_to<std::size_t>;
126 };
127
128 // Most vector counts are uint32_t in Vulkan (use with any container that provides size())
129 template <Sizable T> static inline uint32_t count(const T& t)
130 {
131 return static_cast<uint32_t>(t.size());
132 }
133
134 static inline std::filesystem::path GetExecutablePath()
135 {
136 std::filesystem::path path;
137#if MANDRILL_WINDOWS
138 TCHAR szFile[260] = {0};
139 GetModuleFileNameA(NULL, szFile, 260);
140 path = std::filesystem::path(szFile);
141#elif MANDRILL_LINUX
142 path = std::filesystem::canonical("/proc/self/exe");
143#endif
144 return path.remove_filename();
145 }
146
147#if MANDRILL_LINUX
148#define LPCSTR const char*
149#endif
157 static inline std::string OpenFile(GLFWwindow* pWindow, LPCSTR filter)
158 {
159#if MANDRILL_WINDOWS
160 OPENFILENAME ofn;
161 TCHAR szFile[260] = {0};
162
163 ZeroMemory(&ofn, sizeof(ofn));
164 ofn.lStructSize = sizeof(ofn);
165 ofn.hwndOwner = glfwGetWin32Window(pWindow);
166 ofn.lpstrFile = szFile;
167 ofn.nMaxFile = sizeof(szFile);
168 ofn.lpstrFilter = filter;
169 ofn.nFilterIndex = 1;
170 ofn.lpstrFileTitle = NULL;
171 ofn.nMaxFileTitle = 0;
172 ofn.lpstrInitialDir = NULL;
173 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
174
175 if (GetOpenFileNameA(&ofn)) {
176 return std::string(ofn.lpstrFile);
177 }
178
179#elif MANDRILL_LINUX
180 char filename[1024];
181 FILE* f = popen("zenity --file-selection --modal --title=\"Select file\"", "r");
182
183 if (f) {
184 fgets(filename, sizeof(filename), f);
185 filename[std::strcspn(filename, "\n")] = 0; // Remove trailing new line
186 pclose(f);
187 return std::string(filename);
188 }
189#endif
190 return "";
191 }
192
193} // namespace Mandrill