最初コミット

諏訪子 <suwako@076.moe>、2026-04-21 05:29
コミット 907a2cd9e8dfde49a6ce04daf58b4285c55835c4 ・ファイルを見る

443個のファイル、+20009 -0(多過ぎるので途中まで)

追加 .gitignore
@@ -0,0 +1,4 @@
1+x64
2+*.user
3+*.spv
4+.vs
@@ -0,0 +1,31 @@
1+
2+Microsoft Visual Studio Solution File, Format Version 12.00
3+# Visual Studio Version 17
4+VisualStudioVersion = 17.14.36915.13 d17.14
5+MinimumVisualStudioVersion = 10.0.40219.1
6+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VulkanExample", "VulkanExample\VulkanExample.vcxproj", "{1DEDAEAE-4462-4832-BC54-A82F277CDC82}"
7+EndProject
8+Global
9+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+ Debug|x64 = Debug|x64
11+ Debug|x86 = Debug|x86
12+ Release|x64 = Release|x64
13+ Release|x86 = Release|x86
14+ EndGlobalSection
15+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+ {1DEDAEAE-4462-4832-BC54-A82F277CDC82}.Debug|x64.ActiveCfg = Debug|x64
17+ {1DEDAEAE-4462-4832-BC54-A82F277CDC82}.Debug|x64.Build.0 = Debug|x64
18+ {1DEDAEAE-4462-4832-BC54-A82F277CDC82}.Debug|x86.ActiveCfg = Debug|Win32
19+ {1DEDAEAE-4462-4832-BC54-A82F277CDC82}.Debug|x86.Build.0 = Debug|Win32
20+ {1DEDAEAE-4462-4832-BC54-A82F277CDC82}.Release|x64.ActiveCfg = Release|x64
21+ {1DEDAEAE-4462-4832-BC54-A82F277CDC82}.Release|x64.Build.0 = Release|x64
22+ {1DEDAEAE-4462-4832-BC54-A82F277CDC82}.Release|x86.ActiveCfg = Release|Win32
23+ {1DEDAEAE-4462-4832-BC54-A82F277CDC82}.Release|x86.Build.0 = Release|Win32
24+ EndGlobalSection
25+ GlobalSection(SolutionProperties) = preSolution
26+ HideSolutionNode = FALSE
27+ EndGlobalSection
28+ GlobalSection(ExtensibilityGlobals) = postSolution
29+ SolutionGuid = {8394CBB8-AFAE-4D00-B123-700E41E2C0D5}
30+ EndGlobalSection
31+EndGlobal
@@ -0,0 +1,147 @@
1+<?xml version="1.0" encoding="utf-8"?>
2+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+ <ItemGroup Label="ProjectConfigurations">
4+ <ProjectConfiguration Include="Debug|Win32">
5+ <Configuration>Debug</Configuration>
6+ <Platform>Win32</Platform>
7+ </ProjectConfiguration>
8+ <ProjectConfiguration Include="Release|Win32">
9+ <Configuration>Release</Configuration>
10+ <Platform>Win32</Platform>
11+ </ProjectConfiguration>
12+ <ProjectConfiguration Include="Debug|x64">
13+ <Configuration>Debug</Configuration>
14+ <Platform>x64</Platform>
15+ </ProjectConfiguration>
16+ <ProjectConfiguration Include="Release|x64">
17+ <Configuration>Release</Configuration>
18+ <Platform>x64</Platform>
19+ </ProjectConfiguration>
20+ </ItemGroup>
21+ <PropertyGroup Label="Globals">
22+ <VCProjectVersion>17.0</VCProjectVersion>
23+ <Keyword>Win32Proj</Keyword>
24+ <ProjectGuid>{1dedaeae-4462-4832-bc54-a82f277cdc82}</ProjectGuid>
25+ <RootNamespace>VulkanExample</RootNamespace>
26+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
27+ </PropertyGroup>
28+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
29+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
30+ <ConfigurationType>Application</ConfigurationType>
31+ <UseDebugLibraries>true</UseDebugLibraries>
32+ <PlatformToolset>v143</PlatformToolset>
33+ <CharacterSet>Unicode</CharacterSet>
34+ </PropertyGroup>
35+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
36+ <ConfigurationType>Application</ConfigurationType>
37+ <UseDebugLibraries>false</UseDebugLibraries>
38+ <PlatformToolset>v143</PlatformToolset>
39+ <WholeProgramOptimization>true</WholeProgramOptimization>
40+ <CharacterSet>Unicode</CharacterSet>
41+ </PropertyGroup>
42+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
43+ <ConfigurationType>Application</ConfigurationType>
44+ <UseDebugLibraries>true</UseDebugLibraries>
45+ <PlatformToolset>v143</PlatformToolset>
46+ <CharacterSet>Unicode</CharacterSet>
47+ </PropertyGroup>
48+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
49+ <ConfigurationType>Application</ConfigurationType>
50+ <UseDebugLibraries>false</UseDebugLibraries>
51+ <PlatformToolset>v143</PlatformToolset>
52+ <WholeProgramOptimization>true</WholeProgramOptimization>
53+ <CharacterSet>Unicode</CharacterSet>
54+ </PropertyGroup>
55+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
56+ <ImportGroup Label="ExtensionSettings">
57+ </ImportGroup>
58+ <ImportGroup Label="Shared">
59+ </ImportGroup>
60+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
61+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
62+ </ImportGroup>
63+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
64+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
65+ </ImportGroup>
66+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
67+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
68+ </ImportGroup>
69+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
70+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
71+ </ImportGroup>
72+ <PropertyGroup Label="UserMacros" />
73+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
74+ <ClCompile>
75+ <WarningLevel>Level3</WarningLevel>
76+ <SDLCheck>true</SDLCheck>
77+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
78+ <ConformanceMode>true</ConformanceMode>
79+ </ClCompile>
80+ <Link>
81+ <SubSystem>Console</SubSystem>
82+ <GenerateDebugInformation>true</GenerateDebugInformation>
83+ </Link>
84+ </ItemDefinitionGroup>
85+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
86+ <ClCompile>
87+ <WarningLevel>Level3</WarningLevel>
88+ <FunctionLevelLinking>true</FunctionLevelLinking>
89+ <IntrinsicFunctions>true</IntrinsicFunctions>
90+ <SDLCheck>true</SDLCheck>
91+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
92+ <ConformanceMode>true</ConformanceMode>
93+ </ClCompile>
94+ <Link>
95+ <SubSystem>Console</SubSystem>
96+ <GenerateDebugInformation>true</GenerateDebugInformation>
97+ </Link>
98+ </ItemDefinitionGroup>
99+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
100+ <ClCompile>
101+ <WarningLevel>Level3</WarningLevel>
102+ <SDLCheck>true</SDLCheck>
103+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
104+ <ConformanceMode>true</ConformanceMode>
105+ <AdditionalIncludeDirectories>$(SolutionDir)dep\include;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
106+ <LanguageStandard>stdcpp20</LanguageStandard>
107+ </ClCompile>
108+ <Link>
109+ <SubSystem>Console</SubSystem>
110+ <GenerateDebugInformation>true</GenerateDebugInformation>
111+ <AdditionalLibraryDirectories>$(SolutionDir)dep\lib;$(VULKAN_SDK)\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
112+ <AdditionalDependencies>vulkan-1.lib;glm.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
113+ </Link>
114+ <PostBuildEvent>
115+ <Command>$(VULKAN_SDK)\Bin\glslc.exe $(ProjectDir)shader.vert -o $(ProjectDir)vert.spv
116+$(VULKAN_SDK)\Bin\glslc.exe $(ProjectDir)shader.frag -o $(ProjectDir)frag.spv</Command>
117+ </PostBuildEvent>
118+ </ItemDefinitionGroup>
119+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
120+ <ClCompile>
121+ <WarningLevel>Level3</WarningLevel>
122+ <FunctionLevelLinking>true</FunctionLevelLinking>
123+ <IntrinsicFunctions>true</IntrinsicFunctions>
124+ <SDLCheck>true</SDLCheck>
125+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
126+ <ConformanceMode>true</ConformanceMode>
127+ <AdditionalIncludeDirectories>$(SolutionDir)dep\include;$(VULKAN_SDK)\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
128+ <LanguageStandard>stdcpp20</LanguageStandard>
129+ </ClCompile>
130+ <Link>
131+ <SubSystem>Console</SubSystem>
132+ <GenerateDebugInformation>true</GenerateDebugInformation>
133+ <AdditionalLibraryDirectories>$(SolutionDir)dep\lib;$(VULKAN_SDK)\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
134+ <AdditionalDependencies>vulkan-1.lib;glm.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
135+ </Link>
136+ <PostBuildEvent>
137+ <Command>$(VULKAN_SDK)\Bin\glslc.exe $(ProjectDir)shader.vert -o $(ProjectDir)vert.spv
138+$(VULKAN_SDK)\Bin\glslc.exe $(ProjectDir)shader.frag -o $(ProjectDir)frag.spv</Command>
139+ </PostBuildEvent>
140+ </ItemDefinitionGroup>
141+ <ItemGroup>
142+ <ClCompile Include="main.cc" />
143+ </ItemGroup>
144+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
145+ <ImportGroup Label="ExtensionTargets">
146+ </ImportGroup>
147+</Project>
@@ -0,0 +1,22 @@
1+<?xml version="1.0" encoding="utf-8"?>
2+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+ <ItemGroup>
4+ <Filter Include="Source Files">
5+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
6+ <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
7+ </Filter>
8+ <Filter Include="Header Files">
9+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
10+ <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
11+ </Filter>
12+ <Filter Include="Resource Files">
13+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
14+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
15+ </Filter>
16+ </ItemGroup>
17+ <ItemGroup>
18+ <ClCompile Include="main.cc">
19+ <Filter>Source Files</Filter>
20+ </ClCompile>
21+ </ItemGroup>
22+</Project>
@@ -0,0 +1,706 @@
1+#define NOMINMAX
2+
3+#pragma region headers
4+#include <iostream>
5+#include <string>
6+#include <vector>
7+#include <map>
8+#include <ranges>
9+#include <algorithm>
10+#include <limits>
11+#include <fstream>
12+#include <cassert>
13+
14+#if defined(_WIN64)
15+#define VK_USE_PLATFORM_WIN32_KHR
16+#elif defined(__APPLE__)
17+#define VK_USE_PLATFORM_METAL_EXT
18+#else
19+#define VK_USE_PLATFORM_XCB_KHR
20+#endif
21+#define GLFW_INCLUDE_VULKAN
22+#include <GLFW/glfw3.h>
23+
24+#if defined(_WIN64)
25+#define GLFW_EXPOSE_NATIVE_WIN32
26+#elif defined(__APPLE__)
27+#define GLFW_EXPOSE_NATIVE_COCOA
28+#else
29+#define GLFW_EXPOSE_NATIVE_X11
30+#endif
31+#include <GLFW/glfw3native.h>
32+
33+#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
34+#include <vulkan/vulkan.hpp>
35+
36+VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
37+#pragma endregion
38+
39+std::vector<vk::Image> swapChainImages;
40+vk::CommandBuffer cmdBuf;
41+vk::CommandBufferBeginInfo beginInfo;
42+std::vector<vk::ImageView> swapChainImageViews;
43+vk::Extent2D swapChainExtent;
44+vk::Pipeline gfxPipeline;
45+
46+#pragma region debugCallback
47+static VKAPI_ATTR vk::Bool32 VKAPI_CALL debugCallback(
48+ vk::DebugUtilsMessageSeverityFlagBitsEXT severity,
49+ vk::DebugUtilsMessageTypeFlagsEXT type,
50+ const vk::DebugUtilsMessengerCallbackDataEXT *pCallbackData,
51+ void *pUserData) {
52+ if (severity >= vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning) {
53+ std::cerr << "validation layer: type " << to_string(type)
54+ << " msg: " << pCallbackData->pMessage << std::endl;
55+ }
56+
57+ return vk::False;
58+}
59+#pragma endregion
60+
61+#pragma region readShader
62+static std::vector<char> readFile(const std::string &filename) {
63+ std::ifstream file(filename, std::ios::ate | std::ios::binary);
64+ if (!file.is_open()) {
65+
66+ return {};
67+ }
68+
69+ size_t fileSize = (size_t)file.tellg();
70+ std::vector<char> buf(fileSize);
71+ file.seekg(0);
72+ file.read(buf.data(), fileSize);
73+ file.close();
74+ return buf;
75+}
76+#pragma endregion
77+
78+#pragma region transitionImgLayout
79+void transitionImgLayout(uint32_t imgIdx,
80+ vk::ImageLayout oldLayout,
81+ vk::ImageLayout newLayout,
82+ vk::AccessFlags2 srcAccessMask,
83+ vk::AccessFlags2 dstAccessMask,
84+ vk::PipelineStageFlags2 srcStageMask,
85+ vk::PipelineStageFlags2 dstStageMask) {
86+ vk::ImageSubresourceRange barrierSubres = {};
87+ barrierSubres.aspectMask = vk::ImageAspectFlagBits::eColor;
88+ barrierSubres.baseMipLevel = 0;
89+ barrierSubres.levelCount = 1;
90+ barrierSubres.baseArrayLayer = 0;
91+ barrierSubres.layerCount = 1;
92+
93+ vk::ImageMemoryBarrier2 barrier = {};
94+ barrier.srcStageMask = srcStageMask;
95+ barrier.dstStageMask = dstStageMask;
96+ barrier.srcAccessMask = srcAccessMask;
97+ barrier.dstAccessMask = dstAccessMask;
98+ barrier.oldLayout = oldLayout;
99+ barrier.newLayout = newLayout;
100+ barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
101+ barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
102+ barrier.image = swapChainImages[imgIdx];
103+ barrier.subresourceRange = barrierSubres;
104+
105+ vk::DependencyInfo depInfo = {};
106+ depInfo.dependencyFlags = {};
107+ depInfo.imageMemoryBarrierCount = 1;
108+ depInfo.pImageMemoryBarriers = &barrier;
109+
110+ cmdBuf.pipelineBarrier2(depInfo);
111+}
112+#pragma endregion
113+
114+#pragma region recordCmdBuf
115+void recordCmdBuf(uint32_t imgIdx) {
116+ cmdBuf.reset();
117+ cmdBuf.begin(beginInfo);
118+
119+
120+ transitionImgLayout(imgIdx,
121+ vk::ImageLayout::eUndefined,
122+ vk::ImageLayout::eColorAttachmentOptimal,
123+ {},
124+ vk::AccessFlagBits2::eColorAttachmentWrite,
125+ vk::PipelineStageFlagBits2::eColorAttachmentOutput,
126+ vk::PipelineStageFlagBits2::eColorAttachmentOutput);
127+
128+ vk::ClearValue clearColor = vk::ClearColorValue(0.f, 0.f, 0.f, 1.f);
129+ vk::RenderingAttachmentInfo attachInfo = {};
130+ attachInfo.imageView = swapChainImageViews[imgIdx];
131+ attachInfo.imageLayout = vk::ImageLayout::eColorAttachmentOptimal;
132+ attachInfo.loadOp = vk::AttachmentLoadOp::eClear;
133+ attachInfo.storeOp = vk::AttachmentStoreOp::eStore;
134+ attachInfo.clearValue = clearColor;
135+
136+ vk::RenderingInfo renderingInfo = {};
137+ renderingInfo.renderArea = vk::Rect2D{ {0, 0}, swapChainExtent };
138+ renderingInfo.layerCount = 1;
139+ renderingInfo.colorAttachmentCount = 1;
140+ renderingInfo.pColorAttachments = &attachInfo;
141+
142+ cmdBuf.beginRendering(renderingInfo);
143+ cmdBuf.bindPipeline(vk::PipelineBindPoint::eGraphics, gfxPipeline);
144+ cmdBuf.setViewport(0, vk::Viewport(0.f, 0.f,
145+ static_cast<float>(swapChainExtent.width),
146+ static_cast<float>(swapChainExtent.height),
147+ 0.f, 1.f));
148+ cmdBuf.setScissor(0, vk::Rect2D(vk::Offset2D(0, 0), swapChainExtent));
149+ cmdBuf.draw(3, 1, 0, 0);
150+ cmdBuf.endRendering();
151+
152+ transitionImgLayout(imgIdx,
153+ vk::ImageLayout::eColorAttachmentOptimal,
154+ vk::ImageLayout::ePresentSrcKHR,
155+ vk::AccessFlagBits2::eColorAttachmentWrite,
156+ {},
157+ vk::PipelineStageFlagBits2::eColorAttachmentOutput,
158+ vk::PipelineStageFlagBits2::eBottomOfPipe);
159+
160+ cmdBuf.end();
161+}
162+#pragma endregion
163+
164+int main() {
165+#pragma region window
166+ int winWidth = 800;
167+ int winHeight = 600;
168+
169+
170+ glfwInit();
171+ glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
172+ glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
173+ GLFWwindow *window = glfwCreateWindow(winWidth, winHeight, winName.c_str(), nullptr, nullptr);
174+#pragma endregion
175+
176+#pragma region instance
177+ vk::ApplicationInfo applicationInfo = {};
178+ applicationInfo.pApplicationName = "Vulkan Render";
179+ applicationInfo.applicationVersion = vk::makeVersion(1, 0, 0);
180+ applicationInfo.pEngineName = "Small Engine";
181+ applicationInfo.engineVersion = vk::makeVersion(1, 0, 0);
182+ applicationInfo.apiVersion = vk::ApiVersion14;
183+
184+ VULKAN_HPP_DEFAULT_DISPATCHER.init();
185+
186+ vk::InstanceCreateInfo instanceCreateInfo = {};
187+ instanceCreateInfo.pApplicationInfo = &applicationInfo;
188+
189+ uint32_t glfwExtCount = 0;
190+ const char **glfwExt = glfwGetRequiredInstanceExtensions(&glfwExtCount);
191+ std::vector<const char *> ext(glfwExt, glfwExt + glfwExtCount);
192+
193+#ifndef NDEBUG
194+ ext.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
195+
196+ std::vector<const char *> reqLayers = { "VK_LAYER_KHRONOS_validation" };
197+
198+ uint32_t layerCount;
199+ auto res1 = vk::enumerateInstanceLayerProperties(&layerCount, nullptr);
200+
201+ std::vector<vk::LayerProperties> availLayers(layerCount);
202+ auto res2 = vk::enumerateInstanceLayerProperties(&layerCount, availLayers.data());
203+
204+ bool layerFound = std::ranges::any_of(reqLayers, [&](const char *r) {
205+ return std::ranges::any_of(availLayers, [&](const auto &p) {
206+ return strcmp(r, p.layerName) == 0;
207+ });
208+ });
209+
210+ if (!layerFound) {
211+
212+ return -1;
213+ }
214+
215+ instanceCreateInfo.enabledLayerCount = static_cast<uint32_t>(reqLayers.size());
216+ instanceCreateInfo.ppEnabledLayerNames = reqLayers.data();
217+#else
218+ instanceCreateInfo.enabledLayerCount = 0;
219+#endif
220+
221+ instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(ext.size());
222+ instanceCreateInfo.ppEnabledExtensionNames = ext.data();
223+
224+ vk::Instance instance = vk::createInstance(instanceCreateInfo);
225+ VULKAN_HPP_DEFAULT_DISPATCHER.init(instance);
226+
227+#ifndef NDEBUG
228+ vk::DebugUtilsMessageSeverityFlagsEXT severityFlags(vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning
229+ | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError);
230+ vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags(vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral
231+ | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance
232+ | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation);
233+ vk::DebugUtilsMessengerCreateInfoEXT debugUtilsInfo = {};
234+ debugUtilsInfo.messageSeverity = severityFlags;
235+ debugUtilsInfo.messageType = messageTypeFlags;
236+ debugUtilsInfo.pfnUserCallback = &debugCallback;
237+ vk::DebugUtilsMessengerEXT debugMessenger = instance.createDebugUtilsMessengerEXT(debugUtilsInfo);
238+#endif
239+#pragma endregion
240+
241+#pragma region surface
242+#if defined(_WIN64)
243+ vk::Win32SurfaceCreateInfoKHR surfaceCreateInfo = {};
244+ surfaceCreateInfo.hinstance = GetModuleHandle(nullptr);
245+ surfaceCreateInfo.hwnd = glfwGetWin32Window(window);
246+
247+ vk::SurfaceKHR surface = instance.createWin32SurfaceKHR(surfaceCreateInfo);
248+#elif defined(__APPLE__)
249+ vk::MetalSurfaceCreateInfoEXT surfaceCreateInfo = {};
250+ surfaceCreateInfo.pLayer = glfwGetCocoaWindow(window);
251+
252+ vk::SurfaceKHR surface = instance.createMetalSurfaceEXT(surfaceCreateInfo);
253+#else
254+ vk::XcbSurfaceCreateInfoKHR surfaceCreateInfo = {};
255+ surfaceCreateInfo.connection = glfwGetX11Display();
256+ surfaceCreateInfo.window = glfwGetX11Window(window);
257+
258+ vk::SurfaceKHR surface = instance.createXcbSurfaceKHR(surfaceCreateInfo);
259+#endif
260+#pragma endregion
261+
262+#pragma region physdevice
263+ auto physDevs = instance.enumeratePhysicalDevices();
264+ if (physDevs.empty()) {
265+
266+ return -1;
267+ }
268+
269+ std::multimap<int, vk::PhysicalDevice> physDevices;
270+ for (const auto &dev : physDevs) {
271+ auto devProp = dev.getProperties();
272+ auto devFeat = dev.getFeatures();
273+ uint32_t score = 0;
274+
275+ if (devProp.deviceType == vk::PhysicalDeviceType::eDiscreteGpu) score += 1000;
276+ score += devProp.limits.maxImageDimension2D;
277+ if (!devFeat.geometryShader) continue;
278+ if (devProp.apiVersion < vk::ApiVersion13) continue;
279+ physDevices.insert(std::make_pair(score, dev));
280+ }
281+
282+ if (physDevices.empty()) {
283+
284+ return -1;
285+ }
286+
287+ vk::PhysicalDevice physicalDevice = physDevices.rbegin()->second;
288+
289+ auto queueFamilies = physicalDevice.getQueueFamilyProperties();
290+ bool supportsGfx = std::ranges::any_of(queueFamilies, [](auto const &q) {
291+ return !!(q.queueFlags & vk::QueueFlagBits::eGraphics);
292+ });
293+
294+ std::vector<const char *> reqDevExt = { vk::KHRSwapchainExtensionName };
295+ auto availDevExt = physicalDevice.enumerateDeviceExtensionProperties();
296+ bool supportAllExt = std::ranges::all_of(reqDevExt, [&availDevExt](auto const &reqDevExt) {
297+ return std::ranges::any_of(availDevExt, [reqDevExt](auto const &e) {
298+ return strcmp(e.extensionName, reqDevExt) == 0;;
299+ });
300+ });
301+
302+ auto features = physicalDevice.template getFeatures2<vk::PhysicalDeviceFeatures2,
303+ vk::PhysicalDeviceVulkan13Features,
304+ vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
305+ bool supportReqFeature = features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering
306+ && features.template get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>().extendedDynamicState;
307+
308+ if (!supportAllExt || !supportsGfx || !supportReqFeature) {
309+
310+ return -1;
311+ }
312+#pragma endregion
313+
314+#pragma region logicdevice
315+ std::vector<vk::QueueFamilyProperties> queueFamProps = physicalDevice.getQueueFamilyProperties();
316+ auto gfxQueueFamProp = std::ranges::find_if(queueFamProps, [](auto const &q) {
317+ return (q.queueFlags & vk::QueueFlagBits::eGraphics) != static_cast<vk::QueueFlags>(0);
318+ });
319+
320+ uint32_t queueIdx = ~0;
321+ for (uint32_t q = 0; q < queueFamProps.size(); ++q) {
322+ if ((queueFamProps[q].queueFlags & vk::QueueFlagBits::eGraphics)
323+ && physicalDevice.getSurfaceSupportKHR(q, surface)) {
324+ queueIdx = q;
325+ break;
326+ }
327+ }
328+
329+ if (queueIdx == ~0) {
330+
331+ return -1;
332+ }
333+
334+ auto gfxIdx = static_cast<uint32_t>(std::distance(queueFamProps.begin(), gfxQueueFamProp));
335+ float queuePriority = .5f;
336+
337+ vk::PhysicalDeviceFeatures2 baseFeatures{};
338+
339+ vk::PhysicalDeviceVulkan13Features features13{};
340+ features13.dynamicRendering = true;
341+ features13.synchronization2 = true;
342+
343+ vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT extDynState{};
344+ extDynState.extendedDynamicState = true;
345+
346+ vk::StructureChain<vk::PhysicalDeviceFeatures2,
347+ vk::PhysicalDeviceVulkan13Features,
348+ vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
349+ baseFeatures,
350+ features13,
351+ extDynState,
352+ };
353+
354+ vk::DeviceQueueCreateInfo devQueueCreateInfo = {};
355+ devQueueCreateInfo.queueFamilyIndex = gfxIdx;
356+ devQueueCreateInfo.queueCount = 1;
357+ devQueueCreateInfo.pQueuePriorities = &queuePriority;
358+
359+ vk::DeviceCreateInfo devCreateInfo = {};
360+ devCreateInfo.pNext = &featureChain.get<vk::PhysicalDeviceFeatures2>();
361+ devCreateInfo.queueCreateInfoCount = 1;
362+ devCreateInfo.pQueueCreateInfos = &devQueueCreateInfo;
363+ devCreateInfo.enabledExtensionCount = static_cast<uint32_t>(reqDevExt.size());
364+ devCreateInfo.ppEnabledExtensionNames = reqDevExt.data();
365+
366+ vk::Device device = physicalDevice.createDevice(devCreateInfo);
367+ VULKAN_HPP_DEFAULT_DISPATCHER.init(device);
368+ vk::Queue gfxQueue = device.getQueue(gfxIdx, 0);
369+#pragma endregion
370+
371+#pragma region swapchain
372+ auto surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(surface);
373+ std::vector<vk::SurfaceFormatKHR> availFormats = physicalDevice.getSurfaceFormatsKHR(surface);
374+ std::vector<vk::PresentModeKHR> availPresentModes = physicalDevice.getSurfacePresentModesKHR(surface);
375+ assert(!availFormats.empty());
376+
377+ const auto formatIt = std::ranges::find_if(availFormats, [](const auto &format) {
378+ return format.format == vk::Format::eB8G8R8A8Srgb && format.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear;
379+ });
380+
381+ vk::SurfaceFormatKHR swapChainFormat = formatIt != availFormats.end() ? *formatIt : availFormats[0];
382+
383+ assert(std::ranges::any_of(availPresentModes, [](auto present) { return present == vk::PresentModeKHR::eFifo; }));
384+ vk::PresentModeKHR presentMode = std::ranges::any_of(availPresentModes, [](const vk::PresentModeKHR val) {
385+ return vk::PresentModeKHR::eMailbox == val;
386+ }) ? vk::PresentModeKHR::eMailbox : vk::PresentModeKHR::eFifo;
387+
388+ if (surfaceCapabilities.currentExtent.width != std::numeric_limits<uint32_t>::max()) {
389+ swapChainExtent = surfaceCapabilities.currentExtent;
390+ } else {
391+ int width, height;
392+ glfwGetFramebufferSize(window, &width, &height);
393+ swapChainExtent.width = std::clamp<uint32_t>(width, surfaceCapabilities.minImageExtent.width, surfaceCapabilities.maxImageExtent.width);
394+ swapChainExtent.height = std::clamp<uint32_t>(height, surfaceCapabilities.minImageExtent.height, surfaceCapabilities.maxImageExtent.height);
395+ }
396+
397+ uint32_t minImageCount = std::max(3u, surfaceCapabilities.minImageCount);
398+ if ((0 < surfaceCapabilities.maxImageCount) && (surfaceCapabilities.maxImageCount < minImageCount)) {
399+ minImageCount = surfaceCapabilities.maxImageCount;
400+ }
401+
402+ vk::SwapchainCreateInfoKHR swapChainCreateInfo = {};
403+ swapChainCreateInfo.surface = surface;
404+ swapChainCreateInfo.minImageCount = minImageCount;
405+ swapChainCreateInfo.imageFormat = swapChainFormat.format;
406+ swapChainCreateInfo.imageColorSpace = swapChainFormat.colorSpace;
407+ swapChainCreateInfo.imageExtent = swapChainExtent;
408+ swapChainCreateInfo.imageArrayLayers = 1;
409+ swapChainCreateInfo.imageUsage = vk::ImageUsageFlagBits::eColorAttachment;
410+ swapChainCreateInfo.imageSharingMode = vk::SharingMode::eExclusive;
411+ swapChainCreateInfo.preTransform = surfaceCapabilities.currentTransform;
412+ swapChainCreateInfo.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque;
413+ swapChainCreateInfo.presentMode = presentMode;
414+ swapChainCreateInfo.clipped = true;
415+
416+ vk::SwapchainKHR swapChain = device.createSwapchainKHR(swapChainCreateInfo);
417+ swapChainImages = device.getSwapchainImagesKHR(swapChain);
418+#pragma endregion
419+
420+#pragma region imageviews
421+ assert(swapChainImageViews.empty());
422+
423+ vk::ImageSubresourceRange subrange = {};
424+ subrange.aspectMask = vk::ImageAspectFlagBits::eColor;
425+ subrange.levelCount = 1;
426+ subrange.layerCount = 1;
427+
428+ vk::ImageViewCreateInfo imgViewCreateInfo = {};
429+ imgViewCreateInfo.viewType = vk::ImageViewType::e2D;
430+ imgViewCreateInfo.format = swapChainFormat.format;
431+ imgViewCreateInfo.subresourceRange = subrange;
432+ imgViewCreateInfo.components = {
433+ vk::ComponentSwizzle::eIdentity,
434+ vk::ComponentSwizzle::eIdentity,
435+ vk::ComponentSwizzle::eIdentity,
436+ vk::ComponentSwizzle::eIdentity,
437+ };
438+
439+ for (auto &img : swapChainImages) {
440+ imgViewCreateInfo.image = img;
441+ swapChainImageViews.push_back(device.createImageView(imgViewCreateInfo));
442+ }
443+#pragma endregion
444+
445+#pragma region gfxPipeline
446+ auto vertShader = readFile("vert.spv");
447+ if (vertShader.empty()) return -1;
448+ auto fragShader = readFile("frag.spv");
449+ if (fragShader.empty()) return -1;
450+
451+ vk::ShaderModuleCreateInfo vertCreateInfo = {};
452+ vertCreateInfo.codeSize = vertShader.size() * sizeof(char);
453+ vertCreateInfo.pCode = reinterpret_cast<const uint32_t *>(vertShader.data());
454+ vk::ShaderModule vertShaderModule = device.createShaderModule(vertCreateInfo);
455+
456+ vk::ShaderModuleCreateInfo fragCreateInfo = {};
457+ fragCreateInfo.codeSize = fragShader.size() * sizeof(char);
458+ fragCreateInfo.pCode = reinterpret_cast<const uint32_t *>(fragShader.data());
459+ vk::ShaderModule fragShaderModule = device.createShaderModule(fragCreateInfo);
460+
461+ vk::PipelineShaderStageCreateInfo vertShaderStageInfo = {};
462+ vertShaderStageInfo.stage = vk::ShaderStageFlagBits::eVertex;
463+ vertShaderStageInfo.module = vertShaderModule;
464+ vertShaderStageInfo.pName = "main";
465+
466+ vk::PipelineShaderStageCreateInfo fragShaderStageInfo = {};
467+ fragShaderStageInfo.stage = vk::ShaderStageFlagBits::eFragment;
468+ fragShaderStageInfo.module = fragShaderModule;
469+ fragShaderStageInfo.pName = "main";
470+
471+ vk::PipelineShaderStageCreateInfo shaderStages[] = {
472+ vertShaderStageInfo,
473+ fragShaderStageInfo,
474+ };
475+#pragma endregion
476+
477+#pragma region fixedFunctions
478+ std::vector<vk::DynamicState> dynStates = {
479+ vk::DynamicState::eViewport,
480+ vk::DynamicState::eScissor,
481+ };
482+
483+ vk::PipelineVertexInputStateCreateInfo vertexInputInfo = {};
484+
485+ vk::PipelineInputAssemblyStateCreateInfo inputAss = {};
486+ inputAss.topology = vk::PrimitiveTopology::eTriangleList;
487+
488+ vk::Viewport viewport = {};
489+ viewport.x = 0.f;
490+ viewport.y = 0.f;
491+ viewport.width = static_cast<float>(swapChainExtent.width);
492+ viewport.height = static_cast<float>(swapChainExtent.height);
493+ viewport.minDepth = 0.f;
494+ viewport.maxDepth = 1.f;
495+
496+ vk::Rect2D scissor = {};
497+ scissor.offset = vk::Offset2D{ 0, 0 };
498+ scissor.extent = swapChainExtent;
499+
500+ vk::PipelineDynamicStateCreateInfo dynState = {};
501+ dynState.dynamicStateCount = static_cast<uint32_t>(dynStates.size());
502+ dynState.pDynamicStates = dynStates.data();
503+
504+ vk::PipelineViewportStateCreateInfo viewportState = {};
505+ viewportState.viewportCount = 1;
506+ viewportState.pViewports = &viewport;
507+ viewportState.scissorCount = 1;
508+ viewportState.pScissors = &scissor;
509+
510+ vk::PipelineRasterizationStateCreateInfo rasterizer = {};
511+ rasterizer.depthClampEnable = vk::False;
512+ rasterizer.rasterizerDiscardEnable = vk::False;
513+ rasterizer.polygonMode = vk::PolygonMode::eFill;
514+ rasterizer.cullMode = vk::CullModeFlagBits::eBack;
515+ rasterizer.frontFace = vk::FrontFace::eClockwise;
516+ rasterizer.depthBiasEnable = vk::False;
517+ rasterizer.lineWidth = 1.f;
518+
519+ vk::PipelineMultisampleStateCreateInfo multisampling = {};
520+ multisampling.rasterizationSamples = vk::SampleCountFlagBits::e1;
521+ multisampling.sampleShadingEnable = vk::False;
522+
523+ vk::PipelineColorBlendAttachmentState colorBlendAttachment = {};
524+ colorBlendAttachment.blendEnable = vk::True;
525+ colorBlendAttachment.srcColorBlendFactor = vk::BlendFactor::eSrcAlpha;
526+ colorBlendAttachment.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha;
527+ colorBlendAttachment.colorBlendOp = vk::BlendOp::eAdd;
528+ colorBlendAttachment.srcAlphaBlendFactor = vk::BlendFactor::eOne;
529+ colorBlendAttachment.dstAlphaBlendFactor = vk::BlendFactor::eZero;
530+ colorBlendAttachment.alphaBlendOp = vk::BlendOp::eAdd;
531+ colorBlendAttachment.colorWriteMask = vk::ColorComponentFlagBits::eR
532+ | vk::ColorComponentFlagBits::eG
533+ | vk::ColorComponentFlagBits::eB
534+ | vk::ColorComponentFlagBits::eA;
535+
536+ vk::PipelineColorBlendStateCreateInfo colorBlending = {};
537+ colorBlending.logicOpEnable = vk::False;
538+ colorBlending.logicOp = vk::LogicOp::eCopy;
539+ colorBlending.attachmentCount = 1;
540+ colorBlending.pAttachments = &colorBlendAttachment;
541+
542+ vk::PipelineLayoutCreateInfo pipelineLayoutInfo = {};
543+ pipelineLayoutInfo.setLayoutCount = 0;
544+ pipelineLayoutInfo.pushConstantRangeCount = 0;
545+
546+ vk::PipelineLayout pipelineLayout = device.createPipelineLayout(pipelineLayoutInfo);
547+#pragma endregion
548+
549+#pragma region pipelineRendering
550+ vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo = {};
551+ pipelineRenderingCreateInfo.colorAttachmentCount = 1;
552+ pipelineRenderingCreateInfo.pColorAttachmentFormats = &swapChainFormat.format;
553+
554+ vk::GraphicsPipelineCreateInfo pipelineInfo = {};
555+ pipelineInfo.stageCount = 2;
556+ pipelineInfo.pStages = shaderStages;
557+ pipelineInfo.pVertexInputState = &vertexInputInfo;
558+ pipelineInfo.pInputAssemblyState = &inputAss;
559+ pipelineInfo.pViewportState = &viewportState;
560+ pipelineInfo.pRasterizationState = &rasterizer;
561+ pipelineInfo.pMultisampleState = &multisampling;
562+ pipelineInfo.pColorBlendState = &colorBlending;
563+ pipelineInfo.pDynamicState = &dynState;
564+ pipelineInfo.layout = pipelineLayout;
565+ pipelineInfo.pNext = &pipelineRenderingCreateInfo;
566+ pipelineInfo.renderPass = nullptr;
567+
568+ auto [result, pipeline] = device.createGraphicsPipeline(nullptr, pipelineInfo);
569+ if (result != vk::Result::eSuccess) {
570+
571+ return -1;
572+ }
573+
574+ gfxPipeline = pipeline;
575+#pragma endregion
576+
577+#pragma region commandPool
578+ vk::CommandPoolCreateInfo poolInfo = {};
579+ poolInfo.flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer;
580+ poolInfo.queueFamilyIndex = queueIdx;
581+
582+ vk::CommandPool cmdPool = device.createCommandPool(poolInfo);
583+#pragma endregion
584+
585+#pragma region commandbuffers
586+ vk::CommandBufferAllocateInfo allocInfo = {};
587+ allocInfo.commandPool = cmdPool;
588+ allocInfo.level = vk::CommandBufferLevel::ePrimary;
589+ allocInfo.commandBufferCount = 1;
590+
591+ std::vector<vk::CommandBuffer> cmdBufs = device.allocateCommandBuffers(allocInfo);
592+ cmdBuf = cmdBufs.front();
593+
594+ beginInfo.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit;
595+
596+ uint32_t imgIdx = 0;
597+ recordCmdBuf(imgIdx);
598+#pragma endregion
599+
600+#pragma region syncObjects
601+ vk::Semaphore presentCompleteSemaphore = device.createSemaphore(vk::SemaphoreCreateInfo());
602+ vk::Semaphore renderFinishedSemaphore = device.createSemaphore(vk::SemaphoreCreateInfo());
603+
604+ vk::FenceCreateInfo fenceInfo = {};
605+ fenceInfo.flags = vk::FenceCreateFlagBits::eSignaled;
606+
607+ vk::Fence drawFence = device.createFence(fenceInfo);
608+#pragma endregion
609+
610+#pragma region framesInFlight
611+#pragma endregion
612+
613+#pragma region swapChainRecreate
614+#pragma endregion
615+
616+ while (!glfwWindowShouldClose(window)) {
617+ if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) {
618+ glfwSetWindowShouldClose(window, true);
619+ }
620+
621+ glfwPollEvents();
622+
623+#pragma region drawFrame
624+ auto fenceResult = device.waitForFences(drawFence, vk::True, UINT64_MAX);
625+ if (fenceResult != vk::Result::eSuccess) {
626+
627+ break;
628+ }
629+
630+ device.resetFences(drawFence);
631+ auto [acquireRes, imgIdx] = device.acquireNextImageKHR(swapChain, UINT64_MAX, presentCompleteSemaphore, nullptr);
632+
633+ if (acquireRes == vk::Result::eErrorOutOfDateKHR || acquireRes == vk::Result::eSuboptimalKHR) continue;
634+ if (acquireRes != vk::Result::eSuccess) {
635+
636+ break;
637+ }
638+
639+ recordCmdBuf(imgIdx);
640+
641+ vk::PipelineStageFlags waitStage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
642+
643+ vk::SubmitInfo submitInfo = {};
644+ submitInfo.waitSemaphoreCount = 1;
645+ submitInfo.pWaitSemaphores = &presentCompleteSemaphore;
646+ submitInfo.pWaitDstStageMask = &waitStage;
647+ submitInfo.commandBufferCount = 1;
648+ submitInfo.pCommandBuffers = &cmdBuf;
649+ submitInfo.signalSemaphoreCount = 1;
650+ submitInfo.pSignalSemaphores = &renderFinishedSemaphore;
651+
652+ gfxQueue.submit(submitInfo, drawFence);
653+
654+ vk::SubpassDependency depend = {};
655+ depend.srcSubpass = vk::SubpassExternal;
656+ depend.dstSubpass = 0;
657+ depend.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
658+ depend.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
659+ depend.srcAccessMask = vk::AccessFlagBits::eNone;
660+ depend.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
661+
662+ vk::PresentInfoKHR presentInfo = {};
663+ presentInfo.waitSemaphoreCount = 1;
664+ presentInfo.pWaitSemaphores = &renderFinishedSemaphore;
665+ presentInfo.swapchainCount = 1;
666+ presentInfo.pSwapchains = &swapChain;
667+ presentInfo.pImageIndices = &imgIdx;
668+
669+ vk::Result presentRes = gfxQueue.presentKHR(presentInfo);
670+#pragma endregion
671+
672+ device.waitIdle();
673+ }
674+
675+#pragma region destroy
676+ if (device) device.waitIdle();
677+ if (cmdPool) device.destroyCommandPool(cmdPool);
678+ if (gfxPipeline) device.destroyPipeline(gfxPipeline);
679+ if (pipelineLayout) device.destroyPipelineLayout(pipelineLayout);
680+ if (fragShaderModule) device.destroyShaderModule(fragShaderModule);
681+ if (vertShaderModule) device.destroyShaderModule(vertShaderModule);
682+
683+ for (auto &view : swapChainImageViews) device.destroyImageView(view);
684+ swapChainImageViews.clear();
685+
686+ if (swapChain) device.destroySwapchainKHR(swapChain);
687+ if (presentCompleteSemaphore) device.destroySemaphore(presentCompleteSemaphore);
688+ if (renderFinishedSemaphore) device.destroySemaphore(renderFinishedSemaphore);
689+ if (drawFence) device.destroyFence(drawFence);
690+ if (device) device.destroy();
691+#ifndef NDEBUG
692+ if (debugMessenger) instance.destroyDebugUtilsMessengerEXT(debugMessenger);
693+#endif
694+ if (surface) instance.destroySurfaceKHR(surface);
695+ if (instance) instance.destroy();
696+
697+ if (window) {
698+ glfwDestroyWindow(window);
699+ glfwTerminate();
700+ }
701+
702+ //Sleep(9 * 1000000);
703+#pragma endregion
704+
705+ return 0;
706+}
@@ -0,0 +1,8 @@
1+#version 450
2+
3+layout(location = 0) in vec3 fragColor;
4+layout(location = 0) out vec4 outColor;
5+
6+void main() {
7+ outColor = vec4(fragColor, 1.0);
8+}
@@ -0,0 +1,20 @@
1+#version 450
2+
3+layout(location = 0) out vec3 fragColor;
4+
5+vec2 pos[3] = vec2[](
6+ vec2(0.0, -0.5),
7+ vec2(0.5, 0.5),
8+ vec2(-0.5, 0.5)
9+);
10+
11+vec3 col[3] = vec3[](
12+ vec3(1.0, 0.0, 0.0),
13+ vec3(0.0, 1.0, 0.0),
14+ vec3(0.0, 0.0, 1.0)
15+);
16+
17+void main() {
18+ gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0);
19+ fragColor = col[gl_VertexIndex];
20+}

長いので途中までです

@@ -0,0 +1,6573 @@
1+/*************************************************************************
2+ * GLFW 3.5 - www.glfw.org
3+ * A library for OpenGL, window and input
4+ *------------------------------------------------------------------------
5+ * Copyright (c) 2002-2006 Marcus Geelnard
6+ * Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
7+ *
8+ * This software is provided 'as-is', without any express or implied
9+ * warranty. In no event will the authors be held liable for any damages
10+ * arising from the use of this software.
11+ *
12+ * Permission is granted to anyone to use this software for any purpose,
13+ * including commercial applications, and to alter it and redistribute it
14+ * freely, subject to the following restrictions:
15+ *
16+ * 1. The origin of this software must not be misrepresented; you must not
17+ * claim that you wrote the original software. If you use this software
18+ * in a product, an acknowledgment in the product documentation would
19+ * be appreciated but is not required.
20+ *
21+ * 2. Altered source versions must be plainly marked as such, and must not
22+ * be misrepresented as being the original software.
23+ *
24+ * 3. This notice may not be removed or altered from any source
25+ * distribution.
26+ *
27+ *************************************************************************/
28+
29+#ifndef _glfw3_h_
30+#define _glfw3_h_
31+
32+#ifdef __cplusplus
33+extern "C" {
34+#endif
35+
36+
37+/*************************************************************************
38+ * Doxygen documentation
39+ *************************************************************************/
40+
41+/*! @file glfw3.h
42+ * @brief The header of the GLFW 3 API.
43+ *
44+ * This is the header file of the GLFW 3 API. It defines all its types and
45+ * declares all its functions.
46+ *
47+ * For more information about how to use this file, see @ref build_include.
48+ */
49+/*! @defgroup context Context reference
50+ * @brief Functions and types related to OpenGL and OpenGL ES contexts.
51+ *
52+ * This is the reference documentation for OpenGL and OpenGL ES context related
53+ * functions. For more task-oriented information, see the @ref context_guide.
54+ */
55+/*! @defgroup vulkan Vulkan support reference
56+ * @brief Functions and types related to Vulkan.
57+ *
58+ * This is the reference documentation for Vulkan related functions and types.
59+ * For more task-oriented information, see the @ref vulkan_guide.
60+ */
61+/*! @defgroup init Initialization, version and error reference
62+ * @brief Functions and types related to initialization and error handling.
63+ *
64+ * This is the reference documentation for initialization and termination of
65+ * the library, version management and error handling. For more task-oriented
66+ * information, see the @ref intro_guide.
67+ */
68+/*! @defgroup input Input reference
69+ * @brief Functions and types related to input handling.
70+ *
71+ * This is the reference documentation for input related functions and types.
72+ * For more task-oriented information, see the @ref input_guide.
73+ */
74+/*! @defgroup monitor Monitor reference
75+ * @brief Functions and types related to monitors.
76+ *
77+ * This is the reference documentation for monitor related functions and types.
78+ * For more task-oriented information, see the @ref monitor_guide.
79+ */
80+/*! @defgroup window Window reference
81+ * @brief Functions and types related to windows.
82+ *
83+ * This is the reference documentation for window related functions and types,
84+ * including creation, deletion and event polling. For more task-oriented
85+ * information, see the @ref window_guide.
86+ */
87+
88+
89+/*************************************************************************
90+ * Compiler- and platform-specific preprocessor work
91+ *************************************************************************/
92+
93+/* If we are we on Windows, we want a single define for it.
94+ */
95+#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__))
96+ #define _WIN32
97+#endif /* _WIN32 */
98+
99+/* Include because most Windows GLU headers need wchar_t and
100+ * the macOS OpenGL header blocks the definition of ptrdiff_t by glext.h.
101+ * Include it unconditionally to avoid surprising side-effects.
102+ */
103+#include <stddef.h>
104+
105+/* Include because it is needed by Vulkan and related functions.
106+ * Include it unconditionally to avoid surprising side-effects.
107+ */
108+#include <stdint.h>
109+
110+#if defined(GLFW_INCLUDE_VULKAN)
111+ #include <vulkan/vulkan.h>
112+#endif /* Vulkan header */
113+
114+/* The Vulkan header may have indirectly included windows.h (because of
115+ * VK_USE_PLATFORM_WIN32_KHR) so we offer our replacement symbols after it.
116+ */
117+
118+/* It is customary to use APIENTRY for OpenGL function pointer declarations on
119+ * all platforms. Additionally, the Windows OpenGL header needs APIENTRY.
120+ */
121+#if !defined(APIENTRY)
122+ #if defined(_WIN32)
123+ #define APIENTRY __stdcall
124+ #else
125+ #define APIENTRY
126+ #endif
127+ #define GLFW_APIENTRY_DEFINED
128+#endif /* APIENTRY */
129+
130+/* Some Windows OpenGL headers need this.
131+ */
132+#if !defined(WINGDIAPI) && defined(_WIN32)
133+ #define WINGDIAPI __declspec(dllimport)
134+ #define GLFW_WINGDIAPI_DEFINED
135+#endif /* WINGDIAPI */
136+
137+/* Some Windows GLU headers need this.
138+ */
139+#if !defined(CALLBACK) && defined(_WIN32)
140+ #define CALLBACK __stdcall
141+ #define GLFW_CALLBACK_DEFINED
142+#endif /* CALLBACK */
143+
144+/* Include the chosen OpenGL or OpenGL ES headers.
145+ */
146+#if defined(GLFW_INCLUDE_ES1)
147+
148+ #include <GLES/gl.h>
149+ #if defined(GLFW_INCLUDE_GLEXT)
150+ #include <GLES/glext.h>
151+ #endif
152+
153+#elif defined(GLFW_INCLUDE_ES2)
154+
155+ #include <GLES2/gl2.h>
156+ #if defined(GLFW_INCLUDE_GLEXT)
157+ #include <GLES2/gl2ext.h>
158+ #endif
159+
160+#elif defined(GLFW_INCLUDE_ES3)
161+
162+ #include <GLES3/gl3.h>
163+ #if defined(GLFW_INCLUDE_GLEXT)
164+ #include <GLES2/gl2ext.h>
165+ #endif
166+
167+#elif defined(GLFW_INCLUDE_ES31)
168+
169+ #include <GLES3/gl31.h>
170+ #if defined(GLFW_INCLUDE_GLEXT)
171+ #include <GLES2/gl2ext.h>
172+ #endif
173+
174+#elif defined(GLFW_INCLUDE_ES32)
175+
176+ #include <GLES3/gl32.h>
177+ #if defined(GLFW_INCLUDE_GLEXT)
178+ #include <GLES2/gl2ext.h>
179+ #endif
180+
181+#elif defined(GLFW_INCLUDE_GLCOREARB)
182+
183+ #if defined(__APPLE__)
184+
185+ #include <OpenGL/gl3.h>
186+ #if defined(GLFW_INCLUDE_GLEXT)
187+ #include <OpenGL/gl3ext.h>
188+ #endif /*GLFW_INCLUDE_GLEXT*/
189+
190+ #else /*__APPLE__*/
191+
192+ #include <GL/glcorearb.h>
193+ #if defined(GLFW_INCLUDE_GLEXT)
194+ #include <GL/glext.h>
195+ #endif
196+
197+ #endif /*__APPLE__*/
198+
199+#elif defined(GLFW_INCLUDE_GLU)
200+
201+ #if defined(__APPLE__)
202+
203+ #if defined(GLFW_INCLUDE_GLU)
204+ #include <OpenGL/glu.h>
205+ #endif
206+
207+ #else /*__APPLE__*/
208+
209+ #if defined(GLFW_INCLUDE_GLU)
210+ #include <GL/glu.h>
211+ #endif
212+
213+ #endif /*__APPLE__*/
214+
215+#elif !defined(GLFW_INCLUDE_NONE) && \
216+ !defined(__gl_h_) && \
217+ !defined(__gles1_gl_h_) && \
218+ !defined(__gles2_gl2_h_) && \
219+ !defined(__gles2_gl3_h_) && \
220+ !defined(__gles2_gl31_h_) && \
221+ !defined(__gles2_gl32_h_) && \
222+ !defined(__gl_glcorearb_h_) && \
223+ !defined(__gl2_h_) /*legacy*/ && \
224+ !defined(__gl3_h_) /*legacy*/ && \
225+ !defined(__gl31_h_) /*legacy*/ && \
226+ !defined(__gl32_h_) /*legacy*/ && \
227+ !defined(__glcorearb_h_) /*legacy*/ && \
228+ !defined(__GL_H__) /*non-standard*/ && \
229+ !defined(__gltypes_h_) /*non-standard*/ && \
230+ !defined(__glee_h_) /*non-standard*/
231+
232+ #if defined(__APPLE__)
233+
234+ #if !defined(GLFW_INCLUDE_GLEXT)
235+ #define GL_GLEXT_LEGACY
236+ #endif
237+ #include <OpenGL/gl.h>
238+
239+ #else /*__APPLE__*/
240+
241+ #include <GL/gl.h>
242+ #if defined(GLFW_INCLUDE_GLEXT)
243+ #include <GL/glext.h>
244+ #endif
245+
246+ #endif /*__APPLE__*/
247+
248+#endif /* OpenGL and OpenGL ES headers */
249+
250+#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL)
251+ /* GLFW_DLL must be defined by applications that are linking against the DLL
252+ * version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW
253+ * configuration header when compiling the DLL version of the library.
254+ */
255+ #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined"
256+#endif
257+
258+/* GLFWAPI is used to declare public API functions for export
259+ * from the DLL / shared library / dynamic library.
260+ */
261+#if defined(_WIN32) && defined(_GLFW_BUILD_DLL)
262+ /* We are building GLFW as a Win32 DLL */
263+ #define GLFWAPI __declspec(dllexport)
264+#elif defined(_WIN32) && defined(GLFW_DLL)
265+ /* We are calling a GLFW Win32 DLL */
266+ #define GLFWAPI __declspec(dllimport)
267+#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)
268+ /* We are building GLFW as a Unix shared library */
269+ #define GLFWAPI __attribute__((visibility("default")))
270+#else
271+ #define GLFWAPI
272+#endif
273+
274+
275+/*************************************************************************
276+ * GLFW API tokens
277+ *************************************************************************/
278+
279+/*! @name GLFW version macros
280+ * @{ */
281+/*! @brief The major version number of the GLFW header.
282+ *
283+ * The major version number of the GLFW header. This is incremented when the
284+ * API is changed in non-compatible ways.
285+ * @ingroup init
286+ */
287+#define GLFW_VERSION_MAJOR 3
288+/*! @brief The minor version number of the GLFW header.
289+ *
290+ * The minor version number of the GLFW header. This is incremented when
291+ * features are added to the API but it remains backward-compatible.
292+ * @ingroup init
293+ */
294+#define GLFW_VERSION_MINOR 5
295+/*! @brief The revision number of the GLFW header.
296+ *
297+ * The revision number of the GLFW header. This is incremented when a bug fix
298+ * release is made that does not contain any API changes.
299+ * @ingroup init
300+ */
301+#define GLFW_VERSION_REVISION 0
302+/*! @} */
303+
304+/*! @brief One.
305+ *
306+ * This is only semantic sugar for the number 1. You can instead use `1` or
307+ * `true` or `_True` or `GL_TRUE` or `VK_TRUE` or anything else that is equal
308+ * to one.
309+ *
310+ * @ingroup init
311+ */
312+#define GLFW_TRUE 1
313+/*! @brief Zero.
314+ *
315+ * This is only semantic sugar for the number 0. You can instead use `0` or
316+ * `false` or `_False` or `GL_FALSE` or `VK_FALSE` or anything else that is
317+ * equal to zero.
318+ *
319+ * @ingroup init
320+ */
321+#define GLFW_FALSE 0
322+
323+/*! @name Key and button actions
324+ * @{ */
325+/*! @brief The key or mouse button was released.
326+ *
327+ * The key or mouse button was released.
328+ *
329+ * @ingroup input
330+ */
331+#define GLFW_RELEASE 0
332+/*! @brief The key or mouse button was pressed.
333+ *
334+ * The key or mouse button was pressed.
335+ *
336+ * @ingroup input
337+ */
338+#define GLFW_PRESS 1
339+/*! @brief The key was held down until it repeated.
340+ *
341+ * The key was held down until it repeated.
342+ *
343+ * @ingroup input
344+ */
345+#define GLFW_REPEAT 2
346+/*! @} */
347+
348+/*! @defgroup hat_state Joystick hat states
349+ * @brief Joystick hat states.
350+ *
351+ * See [joystick hat input](@ref joystick_hat) for how these are used.
352+ *
353+ * @ingroup input
354+ * @{ */
355+#define GLFW_HAT_CENTERED 0
356+#define GLFW_HAT_UP 1
357+#define GLFW_HAT_RIGHT 2
358+#define GLFW_HAT_DOWN 4
359+#define GLFW_HAT_LEFT 8
360+#define GLFW_HAT_RIGHT_UP (GLFW_HAT_RIGHT | GLFW_HAT_UP)
361+#define GLFW_HAT_RIGHT_DOWN (GLFW_HAT_RIGHT | GLFW_HAT_DOWN)
362+#define GLFW_HAT_LEFT_UP (GLFW_HAT_LEFT | GLFW_HAT_UP)
363+#define GLFW_HAT_LEFT_DOWN (GLFW_HAT_LEFT | GLFW_HAT_DOWN)
364+
365+/*! @ingroup input
366+ */
367+#define GLFW_KEY_UNKNOWN -1
368+
369+/*! @} */
370+
371+/*! @defgroup keys Keyboard key tokens
372+ * @brief Keyboard key tokens.
373+ *
374+ * See [key input](@ref input_key) for how these are used.
375+ *
376+ * These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60),
377+ * but re-arranged to map to 7-bit ASCII for printable keys (function keys are
378+ * put in the 256+ range).
379+ *
380+ * The naming of the key codes follow these rules:
381+ * - The US keyboard layout is used
382+ * - Names of printable alphanumeric characters are used (e.g. "A", "R",
383+ * "3", etc.)
384+ * - For non-alphanumeric characters, Unicode:ish names are used (e.g.
385+ * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not
386+ * correspond to the Unicode standard (usually for brevity)
387+ * - Keys that lack a clear US mapping are named "WORLD_x"
388+ * - For non-printable keys, custom names are used (e.g. "F4",
389+ * "BACKSPACE", etc.)
390+ *
391+ * @ingroup input
392+ * @{
393+ */
394+
395+/* Printable keys */
396+#define GLFW_KEY_SPACE 32
397+#define GLFW_KEY_APOSTROPHE 39 /* ' */
398+#define GLFW_KEY_COMMA 44 /* , */
399+#define GLFW_KEY_MINUS 45 /* - */
400+#define GLFW_KEY_PERIOD 46 /* . */
401+#define GLFW_KEY_SLASH 47 /* / */
402+#define GLFW_KEY_0 48
403+#define GLFW_KEY_1 49
404+#define GLFW_KEY_2 50
405+#define GLFW_KEY_3 51
406+#define GLFW_KEY_4 52
407+#define GLFW_KEY_5 53
408+#define GLFW_KEY_6 54
409+#define GLFW_KEY_7 55
410+#define GLFW_KEY_8 56
411+#define GLFW_KEY_9 57
412+#define GLFW_KEY_SEMICOLON 59 /* ; */
413+#define GLFW_KEY_EQUAL 61 /* = */
414+#define GLFW_KEY_A 65
415+#define GLFW_KEY_B 66
416+#define GLFW_KEY_C 67
417+#define GLFW_KEY_D 68
418+#define GLFW_KEY_E 69
419+#define GLFW_KEY_F 70
420+#define GLFW_KEY_G 71
421+#define GLFW_KEY_H 72
422+#define GLFW_KEY_I 73
423+#define GLFW_KEY_J 74
424+#define GLFW_KEY_K 75
425+#define GLFW_KEY_L 76
426+#define GLFW_KEY_M 77
427+#define GLFW_KEY_N 78
428+#define GLFW_KEY_O 79
429+#define GLFW_KEY_P 80
430+#define GLFW_KEY_Q 81
431+#define GLFW_KEY_R 82
432+#define GLFW_KEY_S 83
433+#define GLFW_KEY_T 84
434+#define GLFW_KEY_U 85
435+#define GLFW_KEY_V 86
436+#define GLFW_KEY_W 87
437+#define GLFW_KEY_X 88
438+#define GLFW_KEY_Y 89
439+#define GLFW_KEY_Z 90
440+#define GLFW_KEY_LEFT_BRACKET 91 /* [ */
441+#define GLFW_KEY_BACKSLASH 92 /* \ */
442+#define GLFW_KEY_RIGHT_BRACKET 93 /* ] */
443+#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */
444+#define GLFW_KEY_WORLD_1 161 /* non-US #1 */
445+#define GLFW_KEY_WORLD_2 162 /* non-US #2 */
446+
447+/* Function keys */
448+#define GLFW_KEY_ESCAPE 256
449+#define GLFW_KEY_ENTER 257
450+#define GLFW_KEY_TAB 258
451+#define GLFW_KEY_BACKSPACE 259
452+#define GLFW_KEY_INSERT 260
453+#define GLFW_KEY_DELETE 261
454+#define GLFW_KEY_RIGHT 262
455+#define GLFW_KEY_LEFT 263
456+#define GLFW_KEY_DOWN 264
457+#define GLFW_KEY_UP 265
458+#define GLFW_KEY_PAGE_UP 266
459+#define GLFW_KEY_PAGE_DOWN 267
460+#define GLFW_KEY_HOME 268
461+#define GLFW_KEY_END 269
462+#define GLFW_KEY_CAPS_LOCK 280
463+#define GLFW_KEY_SCROLL_LOCK 281
464+#define GLFW_KEY_NUM_LOCK 282
465+#define GLFW_KEY_PRINT_SCREEN 283
466+#define GLFW_KEY_PAUSE 284
467+#define GLFW_KEY_F1 290
468+#define GLFW_KEY_F2 291
469+#define GLFW_KEY_F3 292
470+#define GLFW_KEY_F4 293
471+#define GLFW_KEY_F5 294
472+#define GLFW_KEY_F6 295
473+#define GLFW_KEY_F7 296
474+#define GLFW_KEY_F8 297
475+#define GLFW_KEY_F9 298
476+#define GLFW_KEY_F10 299
477+#define GLFW_KEY_F11 300
478+#define GLFW_KEY_F12 301
479+#define GLFW_KEY_F13 302
480+#define GLFW_KEY_F14 303
481+#define GLFW_KEY_F15 304
482+#define GLFW_KEY_F16 305
483+#define GLFW_KEY_F17 306
484+#define GLFW_KEY_F18 307
485+#define GLFW_KEY_F19 308
486+#define GLFW_KEY_F20 309
487+#define GLFW_KEY_F21 310
488+#define GLFW_KEY_F22 311
489+#define GLFW_KEY_F23 312
490+#define GLFW_KEY_F24 313
491+#define GLFW_KEY_F25 314
492+#define GLFW_KEY_KP_0 320
493+#define GLFW_KEY_KP_1 321
494+#define GLFW_KEY_KP_2 322
495+#define GLFW_KEY_KP_3 323
496+#define GLFW_KEY_KP_4 324
497+#define GLFW_KEY_KP_5 325
498+#define GLFW_KEY_KP_6 326
499+#define GLFW_KEY_KP_7 327
500+#define GLFW_KEY_KP_8 328
501+#define GLFW_KEY_KP_9 329
502+#define GLFW_KEY_KP_DECIMAL 330
503+#define GLFW_KEY_KP_DIVIDE 331
504+#define GLFW_KEY_KP_MULTIPLY 332
505+#define GLFW_KEY_KP_SUBTRACT 333
506+#define GLFW_KEY_KP_ADD 334
507+#define GLFW_KEY_KP_ENTER 335
508+#define GLFW_KEY_KP_EQUAL 336
509+#define GLFW_KEY_LEFT_SHIFT 340
510+#define GLFW_KEY_LEFT_CONTROL 341
511+#define GLFW_KEY_LEFT_ALT 342
512+#define GLFW_KEY_LEFT_SUPER 343
513+#define GLFW_KEY_RIGHT_SHIFT 344
514+#define GLFW_KEY_RIGHT_CONTROL 345
515+#define GLFW_KEY_RIGHT_ALT 346
516+#define GLFW_KEY_RIGHT_SUPER 347
517+#define GLFW_KEY_MENU 348
518+
519+#define GLFW_KEY_LAST GLFW_KEY_MENU
520+
521+/*! @} */
522+
523+/*! @defgroup mods Modifier key flags
524+ * @brief Modifier key flags.
525+ *
526+ * See [key input](@ref input_key) for how these are used.
527+ *
528+ * @ingroup input
529+ * @{ */
530+
531+/*! @brief If this bit is set one or more Shift keys were held down.
532+ *
533+ * If this bit is set one or more Shift keys were held down.
534+ */
535+#define GLFW_MOD_SHIFT 0x0001
536+/*! @brief If this bit is set one or more Control keys were held down.
537+ *
538+ * If this bit is set one or more Control keys were held down.
539+ */
540+#define GLFW_MOD_CONTROL 0x0002
541+/*! @brief If this bit is set one or more Alt keys were held down.
542+ *
543+ * If this bit is set one or more Alt keys were held down.
544+ */
545+#define GLFW_MOD_ALT 0x0004
546+/*! @brief If this bit is set one or more Super keys were held down.
547+ *
548+ * If this bit is set one or more Super keys were held down.
549+ */
550+#define GLFW_MOD_SUPER 0x0008
551+/*! @brief If this bit is set the Caps Lock key is enabled.
552+ *
553+ * If this bit is set the Caps Lock key is enabled and the @ref
554+ * GLFW_LOCK_KEY_MODS input mode is set.
555+ */
556+#define GLFW_MOD_CAPS_LOCK 0x0010
557+/*! @brief If this bit is set the Num Lock key is enabled.
558+ *
559+ * If this bit is set the Num Lock key is enabled and the @ref
560+ * GLFW_LOCK_KEY_MODS input mode is set.
561+ */
562+#define GLFW_MOD_NUM_LOCK 0x0020
563+
564+/*! @} */
565+
566+/*! @defgroup buttons Mouse buttons
567+ * @brief Mouse button IDs.
568+ *
569+ * See [mouse button input](@ref input_mouse_button) for how these are used.
570+ *
571+ * @ingroup input
572+ * @{ */
573+#define GLFW_MOUSE_BUTTON_1 0
574+#define GLFW_MOUSE_BUTTON_2 1
575+#define GLFW_MOUSE_BUTTON_3 2
576+#define GLFW_MOUSE_BUTTON_4 3
577+#define GLFW_MOUSE_BUTTON_5 4
578+#define GLFW_MOUSE_BUTTON_6 5
579+#define GLFW_MOUSE_BUTTON_7 6
580+#define GLFW_MOUSE_BUTTON_8 7
581+#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8
582+#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1
583+#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2
584+#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3
585+/*! @} */
586+
587+/*! @defgroup joysticks Joysticks
588+ * @brief Joystick IDs.
589+ *
590+ * See [joystick input](@ref joystick) for how these are used.
591+ *
592+ * @ingroup input
593+ * @{ */
594+#define GLFW_JOYSTICK_1 0
595+#define GLFW_JOYSTICK_2 1
596+#define GLFW_JOYSTICK_3 2
597+#define GLFW_JOYSTICK_4 3
598+#define GLFW_JOYSTICK_5 4
599+#define GLFW_JOYSTICK_6 5
600+#define GLFW_JOYSTICK_7 6
601+#define GLFW_JOYSTICK_8 7
602+#define GLFW_JOYSTICK_9 8
603+#define GLFW_JOYSTICK_10 9
604+#define GLFW_JOYSTICK_11 10
605+#define GLFW_JOYSTICK_12 11
606+#define GLFW_JOYSTICK_13 12
607+#define GLFW_JOYSTICK_14 13
608+#define GLFW_JOYSTICK_15 14
609+#define GLFW_JOYSTICK_16 15
610+#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16
611+/*! @} */
612+
613+/*! @defgroup gamepad_buttons Gamepad buttons
614+ * @brief Gamepad buttons.
615+ *
616+ * See @ref gamepad for how these are used.
617+ *
618+ * @ingroup input
619+ * @{ */
620+#define GLFW_GAMEPAD_BUTTON_A 0
621+#define GLFW_GAMEPAD_BUTTON_B 1
622+#define GLFW_GAMEPAD_BUTTON_X 2
623+#define GLFW_GAMEPAD_BUTTON_Y 3
624+#define GLFW_GAMEPAD_BUTTON_LEFT_BUMPER 4
625+#define GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER 5
626+#define GLFW_GAMEPAD_BUTTON_BACK 6
627+#define GLFW_GAMEPAD_BUTTON_START 7
628+#define GLFW_GAMEPAD_BUTTON_GUIDE 8
629+#define GLFW_GAMEPAD_BUTTON_LEFT_THUMB 9
630+#define GLFW_GAMEPAD_BUTTON_RIGHT_THUMB 10
631+#define GLFW_GAMEPAD_BUTTON_DPAD_UP 11
632+#define GLFW_GAMEPAD_BUTTON_DPAD_RIGHT 12
633+#define GLFW_GAMEPAD_BUTTON_DPAD_DOWN 13
634+#define GLFW_GAMEPAD_BUTTON_DPAD_LEFT 14
635+#define GLFW_GAMEPAD_BUTTON_LAST GLFW_GAMEPAD_BUTTON_DPAD_LEFT
636+
637+#define GLFW_GAMEPAD_BUTTON_CROSS GLFW_GAMEPAD_BUTTON_A
638+#define GLFW_GAMEPAD_BUTTON_CIRCLE GLFW_GAMEPAD_BUTTON_B
639+#define GLFW_GAMEPAD_BUTTON_SQUARE GLFW_GAMEPAD_BUTTON_X
640+#define GLFW_GAMEPAD_BUTTON_TRIANGLE GLFW_GAMEPAD_BUTTON_Y
641+/*! @} */
642+
643+/*! @defgroup gamepad_axes Gamepad axes
644+ * @brief Gamepad axes.
645+ *
646+ * See @ref gamepad for how these are used.
647+ *
648+ * @ingroup input
649+ * @{ */
650+#define GLFW_GAMEPAD_AXIS_LEFT_X 0
651+#define GLFW_GAMEPAD_AXIS_LEFT_Y 1
652+#define GLFW_GAMEPAD_AXIS_RIGHT_X 2
653+#define GLFW_GAMEPAD_AXIS_RIGHT_Y 3
654+#define GLFW_GAMEPAD_AXIS_LEFT_TRIGGER 4
655+#define GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER 5
656+#define GLFW_GAMEPAD_AXIS_LAST GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
657+/*! @} */
658+
659+/*! @defgroup errors Error codes
660+ * @brief Error codes.
661+ *
662+ * See [error handling](@ref error_handling) for how these are used.
663+ *
664+ * @ingroup init
665+ * @{ */
666+/*! @brief No error has occurred.
667+ *
668+ * No error has occurred.
669+ *
670+ * @analysis Yay.
671+ */
672+#define GLFW_NO_ERROR 0
673+/*! @brief GLFW has not been initialized.
674+ *
675+ * This occurs if a GLFW function was called that must not be called unless the
676+ * library is [initialized](@ref intro_init).
677+ *
678+ * @analysis Application programmer error. Initialize GLFW before calling any
679+ * function that requires initialization.
680+ */
681+#define GLFW_NOT_INITIALIZED 0x00010001
682+/*! @brief No context is current for this thread.
683+ *
684+ * This occurs if a GLFW function was called that needs and operates on the
685+ * current OpenGL or OpenGL ES context but no context is current on the calling
686+ * thread. One such function is @ref glfwSwapInterval.
687+ *
688+ * @analysis Application programmer error. Ensure a context is current before
689+ * calling functions that require a current context.
690+ */
691+#define GLFW_NO_CURRENT_CONTEXT 0x00010002
692+/*! @brief One of the arguments to the function was an invalid enum value.
693+ *
694+ * One of the arguments to the function was an invalid enum value, for example
695+ * requesting @ref GLFW_RED_BITS with @ref glfwGetWindowAttrib.
696+ *
697+ * @analysis Application programmer error. Fix the offending call.
698+ */
699+#define GLFW_INVALID_ENUM 0x00010003
700+/*! @brief One of the arguments to the function was an invalid value.
701+ *
702+ * One of the arguments to the function was an invalid value, for example
703+ * requesting a non-existent OpenGL or OpenGL ES version like 2.7.
704+ *
705+ * Requesting a valid but unavailable OpenGL or OpenGL ES version will instead
706+ * result in a @ref GLFW_VERSION_UNAVAILABLE error.
707+ *
708+ * @analysis Application programmer error. Fix the offending call.
709+ */
710+#define GLFW_INVALID_VALUE 0x00010004
711+/*! @brief A memory allocation failed.
712+ *
713+ * A memory allocation failed.
714+ *
715+ * @analysis A bug in GLFW or the underlying operating system. Report the bug
716+ * to our [issue tracker](https://github.com/glfw/glfw/issues).
717+ */
718+#define GLFW_OUT_OF_MEMORY 0x00010005
719+/*! @brief GLFW could not find support for the requested API on the system.
720+ *
721+ * GLFW could not find support for the requested API on the system.
722+ *
723+ * @analysis The installed graphics driver does not support the requested
724+ * API, or does not support it via the chosen context creation API.
725+ * Below are a few examples.
726+ *
727+ * @par
728+ * Some pre-installed Windows graphics drivers do not support OpenGL. AMD only
729+ * supports OpenGL ES via EGL, while Nvidia and Intel only support it via
730+ * a WGL or GLX extension. macOS does not provide OpenGL ES at all. The Mesa
731+ * EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary
732+ * driver. Older graphics drivers do not support Vulkan.
733+ */
734+#define GLFW_API_UNAVAILABLE 0x00010006
735+/*! @brief The requested OpenGL or OpenGL ES version is not available.
736+ *
737+ * The requested OpenGL or OpenGL ES version (including any requested context
738+ * or framebuffer hints) is not available on this machine.
739+ *
740+ * @analysis The machine does not support your requirements. If your
741+ * application is sufficiently flexible, downgrade your requirements and try
742+ * again. Otherwise, inform the user that their machine does not match your
743+ * requirements.
744+ *
745+ * @par
746+ * Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0
747+ * comes out before the 4.x series gets that far, also fail with this error and
748+ * not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions
749+ * will exist.
750+ */
751+#define GLFW_VERSION_UNAVAILABLE 0x00010007
752+/*! @brief A platform-specific error occurred that does not match any of the
753+ * more specific categories.
754+ *
755+ * A platform-specific error occurred that does not match any of the more
756+ * specific categories.
757+ *
758+ * @analysis A bug or configuration error in GLFW, the underlying operating
759+ * system or its drivers, or a lack of required resources. Report the issue to
760+ * our [issue tracker](https://github.com/glfw/glfw/issues).
761+ */
762+#define GLFW_PLATFORM_ERROR 0x00010008
763+/*! @brief The requested format is not supported or available.
764+ *
765+ * If emitted during window creation, the requested pixel format is not
766+ * supported.
767+ *
768+ * If emitted when querying the clipboard, the contents of the clipboard could
769+ * not be converted to the requested format.
770+ *
771+ * @analysis If emitted during window creation, one or more
772+ * [hard constraints](@ref window_hints_hard) did not match any of the
773+ * available pixel formats. If your application is sufficiently flexible,
774+ * downgrade your requirements and try again. Otherwise, inform the user that
775+ * their machine does not match your requirements.
776+ *
777+ * @par
778+ * If emitted when querying the clipboard, ignore the error or report it to
779+ * the user, as appropriate.
780+ */
781+#define GLFW_FORMAT_UNAVAILABLE 0x00010009
782+/*! @brief The specified window does not have an OpenGL or OpenGL ES context.
783+ *
784+ * A window that does not have an OpenGL or OpenGL ES context was passed to
785+ * a function that requires it to have one.
786+ *
787+ * @analysis Application programmer error. Fix the offending call.
788+ */
789+#define GLFW_NO_WINDOW_CONTEXT 0x0001000A
790+/*! @brief The specified cursor shape is not available.
791+ *
792+ * The specified standard cursor shape is not available, either because the
793+ * current platform cursor theme does not provide it or because it is not
794+ * available on the platform.
795+ *
796+ * @analysis Platform or system settings limitation. Pick another
797+ * [standard cursor shape](@ref shapes) or create a
798+ * [custom cursor](@ref cursor_custom).
799+ */
800+#define GLFW_CURSOR_UNAVAILABLE 0x0001000B
801+/*! @brief The requested feature is not provided by the platform.
802+ *
803+ * The requested feature is not provided by the platform, so GLFW is unable to
804+ * implement it. The documentation for each function notes if it could emit
805+ * this error.
806+ *
807+ * @analysis Platform or platform version limitation. The error can be ignored
808+ * unless the feature is critical to the application.
809+ *
810+ * @par
811+ * A function call that emits this error has no effect other than the error and
812+ * updating any existing out parameters.
813+ */
814+#define GLFW_FEATURE_UNAVAILABLE 0x0001000C
815+/*! @brief The requested feature is not implemented for the platform.
816+ *
817+ * The requested feature has not yet been implemented in GLFW for this platform.
818+ *
819+ * @analysis An incomplete implementation of GLFW for this platform, hopefully
820+ * fixed in a future release. The error can be ignored unless the feature is
821+ * critical to the application.
822+ *
823+ * @par
824+ * A function call that emits this error has no effect other than the error and
825+ * updating any existing out parameters.
826+ */
827+#define GLFW_FEATURE_UNIMPLEMENTED 0x0001000D
828+/*! @brief Platform unavailable or no matching platform was found.
829+ *
830+ * If emitted during initialization, no matching platform was found. If the @ref
831+ * GLFW_PLATFORM init hint was set to `GLFW_ANY_PLATFORM`, GLFW could not detect any of
832+ * the platforms supported by this library binary, except for the Null platform. If the
833+ * init hint was set to a specific platform, it is either not supported by this library
834+ * binary or GLFW was not able to detect it.
835+ *
836+ * If emitted by a native access function, GLFW was initialized for a different platform
837+ * than the function is for.
838+ *
839+ * @analysis Failure to detect any platform usually only happens on non-macOS Unix
840+ * systems, either when no window system is running or the program was run from
841+ * a terminal that does not have the necessary environment variables. Fall back to
842+ * a different platform if possible or notify the user that no usable platform was
843+ * detected.
844+ *
845+ * Failure to detect a specific platform may have the same cause as above or be because
846+ * support for that platform was not compiled in. Call @ref glfwPlatformSupported to
847+ * check whether a specific platform is supported by a library binary.
848+ */
849+#define GLFW_PLATFORM_UNAVAILABLE 0x0001000E
850+/*! @} */
851+
852+/*! @addtogroup window
853+ * @{ */
854+/*! @brief Input focus window hint and attribute
855+ *
856+ * Input focus [window hint](@ref GLFW_FOCUSED_hint) or
857+ * [window attribute](@ref GLFW_FOCUSED_attrib).
858+ */
859+#define GLFW_FOCUSED 0x00020001
860+/*! @brief Window iconification window attribute
861+ *
862+ * Window iconification [window attribute](@ref GLFW_ICONIFIED_attrib).
863+ */
864+#define GLFW_ICONIFIED 0x00020002
865+/*! @brief Window resize-ability window hint and attribute
866+ *
867+ * Window resize-ability [window hint](@ref GLFW_RESIZABLE_hint) and
868+ * [window attribute](@ref GLFW_RESIZABLE_attrib).
869+ */
870+#define GLFW_RESIZABLE 0x00020003
871+/*! @brief Window visibility window hint and attribute
872+ *
873+ * Window visibility [window hint](@ref GLFW_VISIBLE_hint) and
874+ * [window attribute](@ref GLFW_VISIBLE_attrib).
875+ */
876+#define GLFW_VISIBLE 0x00020004
877+/*! @brief Window decoration window hint and attribute
878+ *
879+ * Window decoration [window hint](@ref GLFW_DECORATED_hint) and
880+ * [window attribute](@ref GLFW_DECORATED_attrib).
881+ */
882+#define GLFW_DECORATED 0x00020005
883+/*! @brief Window auto-iconification window hint and attribute
884+ *
885+ * Window auto-iconification [window hint](@ref GLFW_AUTO_ICONIFY_hint) and
886+ * [window attribute](@ref GLFW_AUTO_ICONIFY_attrib).
887+ */
888+#define GLFW_AUTO_ICONIFY 0x00020006
889+/*! @brief Window decoration window hint and attribute
890+ *
891+ * Window decoration [window hint](@ref GLFW_FLOATING_hint) and
892+ * [window attribute](@ref GLFW_FLOATING_attrib).
893+ */
894+#define GLFW_FLOATING 0x00020007
895+/*! @brief Window maximization window hint and attribute
896+ *
897+ * Window maximization [window hint](@ref GLFW_MAXIMIZED_hint) and
898+ * [window attribute](@ref GLFW_MAXIMIZED_attrib).
899+ */
900+#define GLFW_MAXIMIZED 0x00020008
901+/*! @brief Cursor centering window hint
902+ *
903+ * Cursor centering [window hint](@ref GLFW_CENTER_CURSOR_hint).
904+ */
905+#define GLFW_CENTER_CURSOR 0x00020009
906+/*! @brief Window framebuffer transparency hint and attribute
907+ *
908+ * Window framebuffer transparency
909+ * [window hint](@ref GLFW_TRANSPARENT_FRAMEBUFFER_hint) and
910+ * [window attribute](@ref GLFW_TRANSPARENT_FRAMEBUFFER_attrib).
911+ */
912+#define GLFW_TRANSPARENT_FRAMEBUFFER 0x0002000A
913+/*! @brief Mouse cursor hover window attribute.
914+ *
915+ * Mouse cursor hover [window attribute](@ref GLFW_HOVERED_attrib).
916+ */
917+#define GLFW_HOVERED 0x0002000B
918+/*! @brief Input focus on calling show window hint and attribute
919+ *
920+ * Input focus [window hint](@ref GLFW_FOCUS_ON_SHOW_hint) or
921+ * [window attribute](@ref GLFW_FOCUS_ON_SHOW_attrib).
922+ */
923+#define GLFW_FOCUS_ON_SHOW 0x0002000C
924+
925+/*! @brief Mouse input transparency window hint and attribute
926+ *
927+ * Mouse input transparency [window hint](@ref GLFW_MOUSE_PASSTHROUGH_hint) or
928+ * [window attribute](@ref GLFW_MOUSE_PASSTHROUGH_attrib).
929+ */
930+#define GLFW_MOUSE_PASSTHROUGH 0x0002000D
931+
932+/*! @brief Initial position x-coordinate window hint.
933+ *
934+ * Initial position x-coordinate [window hint](@ref GLFW_POSITION_X).
935+ */
936+#define GLFW_POSITION_X 0x0002000E
937+
938+/*! @brief Initial position y-coordinate window hint.
939+ *
940+ * Initial position y-coordinate [window hint](@ref GLFW_POSITION_Y).
941+ */
942+#define GLFW_POSITION_Y 0x0002000F
943+
944+/*! @brief Framebuffer bit depth hint.
945+ *
946+ * Framebuffer bit depth [hint](@ref GLFW_RED_BITS).
947+ */
948+#define GLFW_RED_BITS 0x00021001
949+/*! @brief Framebuffer bit depth hint.
950+ *
951+ * Framebuffer bit depth [hint](@ref GLFW_GREEN_BITS).
952+ */
953+#define GLFW_GREEN_BITS 0x00021002
954+/*! @brief Framebuffer bit depth hint.
955+ *
956+ * Framebuffer bit depth [hint](@ref GLFW_BLUE_BITS).
957+ */
958+#define GLFW_BLUE_BITS 0x00021003
959+/*! @brief Framebuffer bit depth hint.
960+ *
961+ * Framebuffer bit depth [hint](@ref GLFW_ALPHA_BITS).
962+ */
963+#define GLFW_ALPHA_BITS 0x00021004
964+/*! @brief Framebuffer bit depth hint.
965+ *
966+ * Framebuffer bit depth [hint](@ref GLFW_DEPTH_BITS).
967+ */
968+#define GLFW_DEPTH_BITS 0x00021005
969+/*! @brief Framebuffer bit depth hint.
970+ *
971+ * Framebuffer bit depth [hint](@ref GLFW_STENCIL_BITS).
972+ */
973+#define GLFW_STENCIL_BITS 0x00021006
974+/*! @brief Framebuffer bit depth hint.
975+ *
976+ * Framebuffer bit depth [hint](@ref GLFW_ACCUM_RED_BITS).
977+ */
978+#define GLFW_ACCUM_RED_BITS 0x00021007
979+/*! @brief Framebuffer bit depth hint.
980+ *
981+ * Framebuffer bit depth [hint](@ref GLFW_ACCUM_GREEN_BITS).
982+ */
983+#define GLFW_ACCUM_GREEN_BITS 0x00021008
984+/*! @brief Framebuffer bit depth hint.
985+ *
986+ * Framebuffer bit depth [hint](@ref GLFW_ACCUM_BLUE_BITS).
987+ */
988+#define GLFW_ACCUM_BLUE_BITS 0x00021009
989+/*! @brief Framebuffer bit depth hint.
990+ *
991+ * Framebuffer bit depth [hint](@ref GLFW_ACCUM_ALPHA_BITS).
992+ */
993+#define GLFW_ACCUM_ALPHA_BITS 0x0002100A
994+/*! @brief Framebuffer auxiliary buffer hint.
995+ *
996+ * Framebuffer auxiliary buffer [hint](@ref GLFW_AUX_BUFFERS).
997+ */
998+#define GLFW_AUX_BUFFERS 0x0002100B
999+/*! @brief OpenGL stereoscopic rendering hint.
1000+ *
1001+ * OpenGL stereoscopic rendering [hint](@ref GLFW_STEREO).
1002+ */
1003+#define GLFW_STEREO 0x0002100C
1004+/*! @brief Framebuffer MSAA samples hint.
1005+ *
1006+ * Framebuffer MSAA samples [hint](@ref GLFW_SAMPLES).
1007+ */
1008+#define GLFW_SAMPLES 0x0002100D
1009+/*! @brief Framebuffer sRGB hint.
1010+ *
1011+ * Framebuffer sRGB [hint](@ref GLFW_SRGB_CAPABLE).
1012+ */
1013+#define GLFW_SRGB_CAPABLE 0x0002100E
1014+/*! @brief Monitor refresh rate hint.
1015+ *
1016+ * Monitor refresh rate [hint](@ref GLFW_REFRESH_RATE).
1017+ */
1018+#define GLFW_REFRESH_RATE 0x0002100F
1019+/*! @brief Framebuffer double buffering hint and attribute.
1020+ *
1021+ * Framebuffer double buffering [hint](@ref GLFW_DOUBLEBUFFER_hint) and
1022+ * [attribute](@ref GLFW_DOUBLEBUFFER_attrib).
1023+ */
1024+#define GLFW_DOUBLEBUFFER 0x00021010
1025+
1026+/*! @brief Context client API hint and attribute.
1027+ *
1028+ * Context client API [hint](@ref GLFW_CLIENT_API_hint) and
1029+ * [attribute](@ref GLFW_CLIENT_API_attrib).
1030+ */
1031+#define GLFW_CLIENT_API 0x00022001
1032+/*! @brief Context client API major version hint and attribute.
1033+ *
1034+ * Context client API major version [hint](@ref GLFW_CONTEXT_VERSION_MAJOR_hint)
1035+ * and [attribute](@ref GLFW_CONTEXT_VERSION_MAJOR_attrib).
1036+ */
1037+#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
1038+/*! @brief Context client API minor version hint and attribute.
1039+ *
1040+ * Context client API minor version [hint](@ref GLFW_CONTEXT_VERSION_MINOR_hint)
1041+ * and [attribute](@ref GLFW_CONTEXT_VERSION_MINOR_attrib).
1042+ */
1043+#define GLFW_CONTEXT_VERSION_MINOR 0x00022003
1044+/*! @brief Context client API revision number attribute.
1045+ *
1046+ * Context client API revision number
1047+ * [attribute](@ref GLFW_CONTEXT_REVISION_attrib).
1048+ */
1049+#define GLFW_CONTEXT_REVISION 0x00022004
1050+/*! @brief Context robustness hint and attribute.
1051+ *
1052+ * Context client API revision number [hint](@ref GLFW_CONTEXT_ROBUSTNESS_hint)
1053+ * and [attribute](@ref GLFW_CONTEXT_ROBUSTNESS_attrib).
1054+ */
1055+#define GLFW_CONTEXT_ROBUSTNESS 0x00022005
1056+/*! @brief OpenGL forward-compatibility hint and attribute.
1057+ *
1058+ * OpenGL forward-compatibility [hint](@ref GLFW_OPENGL_FORWARD_COMPAT_hint)
1059+ * and [attribute](@ref GLFW_OPENGL_FORWARD_COMPAT_attrib).
1060+ */
1061+#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
1062+/*! @brief Debug mode context hint and attribute.
1063+ *
1064+ * Debug mode context [hint](@ref GLFW_CONTEXT_DEBUG_hint) and
1065+ * [attribute](@ref GLFW_CONTEXT_DEBUG_attrib).
1066+ */
1067+#define GLFW_CONTEXT_DEBUG 0x00022007
1068+/*! @brief Legacy name for compatibility.
1069+ *
1070+ * This is an alias for compatibility with earlier versions.
1071+ */
1072+#define GLFW_OPENGL_DEBUG_CONTEXT GLFW_CONTEXT_DEBUG
1073+/*! @brief OpenGL profile hint and attribute.
1074+ *
1075+ * OpenGL profile [hint](@ref GLFW_OPENGL_PROFILE_hint) and
1076+ * [attribute](@ref GLFW_OPENGL_PROFILE_attrib).
1077+ */
1078+#define GLFW_OPENGL_PROFILE 0x00022008
1079+/*! @brief Context flush-on-release hint and attribute.
1080+ *
1081+ * Context flush-on-release [hint](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_hint) and
1082+ * [attribute](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_attrib).
1083+ */
1084+#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009
1085+/*! @brief Context error suppression hint and attribute.
1086+ *
1087+ * Context error suppression [hint](@ref GLFW_CONTEXT_NO_ERROR_hint) and
1088+ * [attribute](@ref GLFW_CONTEXT_NO_ERROR_attrib).
1089+ */
1090+#define GLFW_CONTEXT_NO_ERROR 0x0002200A
1091+/*! @brief Context creation API hint and attribute.
1092+ *
1093+ * Context creation API [hint](@ref GLFW_CONTEXT_CREATION_API_hint) and
1094+ * [attribute](@ref GLFW_CONTEXT_CREATION_API_attrib).
1095+ */
1096+#define GLFW_CONTEXT_CREATION_API 0x0002200B
1097+/*! @brief Window content area scaling window
1098+ * [window hint](@ref GLFW_SCALE_TO_MONITOR).
1099+ */
1100+#define GLFW_SCALE_TO_MONITOR 0x0002200C
1101+/*! @brief Window framebuffer scaling
1102+ * [window hint](@ref GLFW_SCALE_FRAMEBUFFER_hint).
1103+ */
1104+#define GLFW_SCALE_FRAMEBUFFER 0x0002200D
1105+/*! @brief Legacy name for compatibility.
1106+ *
1107+ * This is an alias for the
1108+ * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) window hint for
1109+ * compatibility with earlier versions.
1110+ */
1111+#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
1112+/*! @brief macOS specific
1113+ * [window hint](@ref GLFW_COCOA_FRAME_NAME_hint).
1114+ */
1115+#define GLFW_COCOA_FRAME_NAME 0x00023002
1116+/*! @brief macOS specific
1117+ * [window hint](@ref GLFW_COCOA_GRAPHICS_SWITCHING_hint).
1118+ */
1119+#define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003
1120+/*! @brief X11 specific
1121+ * [window hint](@ref GLFW_X11_CLASS_NAME_hint).
1122+ */
1123+#define GLFW_X11_CLASS_NAME 0x00024001
1124+/*! @brief X11 specific
1125+ * [window hint](@ref GLFW_X11_CLASS_NAME_hint).
1126+ */
1127+#define GLFW_X11_INSTANCE_NAME 0x00024002
1128+#define GLFW_WIN32_KEYBOARD_MENU 0x00025001
1129+/*! @brief Win32 specific [window hint](@ref GLFW_WIN32_SHOWDEFAULT_hint).
1130+ */
1131+#define GLFW_WIN32_SHOWDEFAULT 0x00025002
1132+/*! @brief Wayland specific
1133+ * [window hint](@ref GLFW_WAYLAND_APP_ID_hint).
1134+ *
1135+ * Allows specification of the Wayland app_id.
1136+ */
1137+#define GLFW_WAYLAND_APP_ID 0x00026001
1138+/*! @} */
1139+
1140+#define GLFW_NO_API 0
1141+#define GLFW_OPENGL_API 0x00030001
1142+#define GLFW_OPENGL_ES_API 0x00030002
1143+
1144+#define GLFW_NO_ROBUSTNESS 0
1145+#define GLFW_NO_RESET_NOTIFICATION 0x00031001
1146+#define GLFW_LOSE_CONTEXT_ON_RESET 0x00031002
1147+
1148+#define GLFW_OPENGL_ANY_PROFILE 0
1149+#define GLFW_OPENGL_CORE_PROFILE 0x00032001
1150+#define GLFW_OPENGL_COMPAT_PROFILE 0x00032002
1151+
1152+#define GLFW_CURSOR 0x00033001
1153+#define GLFW_STICKY_KEYS 0x00033002
1154+#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
1155+#define GLFW_LOCK_KEY_MODS 0x00033004
1156+#define GLFW_RAW_MOUSE_MOTION 0x00033005
1157+#define GLFW_UNLIMITED_MOUSE_BUTTONS 0x00033006
1158+
1159+#define GLFW_CURSOR_NORMAL 0x00034001
1160+#define GLFW_CURSOR_HIDDEN 0x00034002
1161+#define GLFW_CURSOR_DISABLED 0x00034003
1162+#define GLFW_CURSOR_CAPTURED 0x00034004
1163+
1164+#define GLFW_ANY_RELEASE_BEHAVIOR 0
1165+#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001
1166+#define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002
1167+
1168+#define GLFW_NATIVE_CONTEXT_API 0x00036001
1169+#define GLFW_EGL_CONTEXT_API 0x00036002
1170+#define GLFW_OSMESA_CONTEXT_API 0x00036003
1171+
1172+#define GLFW_ANGLE_PLATFORM_TYPE_NONE 0x00037001
1173+#define GLFW_ANGLE_PLATFORM_TYPE_OPENGL 0x00037002
1174+#define GLFW_ANGLE_PLATFORM_TYPE_OPENGLES 0x00037003
1175+#define GLFW_ANGLE_PLATFORM_TYPE_D3D9 0x00037004
1176+#define GLFW_ANGLE_PLATFORM_TYPE_D3D11 0x00037005
1177+#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007
1178+#define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008
1179+
1180+#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001
1181+#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002
1182+
1183+#define GLFW_ANY_POSITION 0x80000000
1184+
1185+/*! @defgroup shapes Standard cursor shapes
1186+ * @brief Standard system cursor shapes.
1187+ *
1188+ * These are the [standard cursor shapes](@ref cursor_standard) that can be
1189+ * requested from the platform (window system).
1190+ *
1191+ * @ingroup input
1192+ * @{ */
1193+
1194+/*! @brief The regular arrow cursor shape.
1195+ *
1196+ * The regular arrow cursor shape.
1197+ */
1198+#define GLFW_ARROW_CURSOR 0x00036001
1199+/*! @brief The text input I-beam cursor shape.
1200+ *
1201+ * The text input I-beam cursor shape.
1202+ */
1203+#define GLFW_IBEAM_CURSOR 0x00036002
1204+/*! @brief The crosshair cursor shape.
1205+ *
1206+ * The crosshair cursor shape.
1207+ */
1208+#define GLFW_CROSSHAIR_CURSOR 0x00036003
1209+/*! @brief The pointing hand cursor shape.
1210+ *
1211+ * The pointing hand cursor shape.
1212+ */
1213+#define GLFW_POINTING_HAND_CURSOR 0x00036004
1214+/*! @brief The horizontal resize/move arrow shape.
1215+ *
1216+ * The horizontal resize/move arrow shape. This is usually a horizontal
1217+ * double-headed arrow.
1218+ */
1219+#define GLFW_RESIZE_EW_CURSOR 0x00036005
1220+/*! @brief The vertical resize/move arrow shape.
1221+ *
1222+ * The vertical resize/move shape. This is usually a vertical double-headed
1223+ * arrow.
1224+ */
1225+#define GLFW_RESIZE_NS_CURSOR 0x00036006
1226+/*! @brief The top-left to bottom-right diagonal resize/move arrow shape.
1227+ *
1228+ * The top-left to bottom-right diagonal resize/move shape. This is usually
1229+ * a diagonal double-headed arrow.
1230+ *
1231+ * @note __macOS:__ This shape is provided by a private system API and may fail
1232+ * with @ref GLFW_CURSOR_UNAVAILABLE in the future.
1233+ *
1234+ * @note __Wayland:__ This shape is provided by a newer standard not supported by
1235+ * all cursor themes.
1236+ *
1237+ * @note __X11:__ This shape is provided by a newer standard not supported by all
1238+ * cursor themes.
1239+ */
1240+#define GLFW_RESIZE_NWSE_CURSOR 0x00036007
1241+/*! @brief The top-right to bottom-left diagonal resize/move arrow shape.
1242+ *
1243+ * The top-right to bottom-left diagonal resize/move shape. This is usually
1244+ * a diagonal double-headed arrow.
1245+ *
1246+ * @note __macOS:__ This shape is provided by a private system API and may fail
1247+ * with @ref GLFW_CURSOR_UNAVAILABLE in the future.
1248+ *
1249+ * @note __Wayland:__ This shape is provided by a newer standard not supported by
1250+ * all cursor themes.
1251+ *
1252+ * @note __X11:__ This shape is provided by a newer standard not supported by all
1253+ * cursor themes.
1254+ */
1255+#define GLFW_RESIZE_NESW_CURSOR 0x00036008
1256+/*! @brief The omni-directional resize/move cursor shape.
1257+ *
1258+ * The omni-directional resize cursor/move shape. This is usually either
1259+ * a combined horizontal and vertical double-headed arrow or a grabbing hand.
1260+ */
1261+#define GLFW_RESIZE_ALL_CURSOR 0x00036009
1262+/*! @brief The operation-not-allowed shape.
1263+ *
1264+ * The operation-not-allowed shape. This is usually a circle with a diagonal
1265+ * line through it.
1266+ *
1267+ * @note __Wayland:__ This shape is provided by a newer standard not supported by
1268+ * all cursor themes.
1269+ *
1270+ * @note __X11:__ This shape is provided by a newer standard not supported by all
1271+ * cursor themes.
1272+ */
1273+#define GLFW_NOT_ALLOWED_CURSOR 0x0003600A
1274+/*! @brief Legacy name for compatibility.
1275+ *
1276+ * This is an alias for compatibility with earlier versions.
1277+ */
1278+#define GLFW_HRESIZE_CURSOR GLFW_RESIZE_EW_CURSOR
1279+/*! @brief Legacy name for compatibility.
1280+ *
1281+ * This is an alias for compatibility with earlier versions.
1282+ */
1283+#define GLFW_VRESIZE_CURSOR GLFW_RESIZE_NS_CURSOR
1284+/*! @brief Legacy name for compatibility.
1285+ *
1286+ * This is an alias for compatibility with earlier versions.
1287+ */
1288+#define GLFW_HAND_CURSOR GLFW_POINTING_HAND_CURSOR
1289+/*! @} */
1290+
1291+#define GLFW_CONNECTED 0x00040001
1292+#define GLFW_DISCONNECTED 0x00040002
1293+
1294+/*! @addtogroup init
1295+ * @{ */
1296+/*! @brief Joystick hat buttons init hint.
1297+ *
1298+ * Joystick hat buttons [init hint](@ref GLFW_JOYSTICK_HAT_BUTTONS).
1299+ */
1300+#define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001
1301+/*! @brief ANGLE rendering backend init hint.
1302+ *
1303+ * ANGLE rendering backend [init hint](@ref GLFW_ANGLE_PLATFORM_TYPE_hint).
1304+ */
1305+#define GLFW_ANGLE_PLATFORM_TYPE 0x00050002
1306+/*! @brief Platform selection init hint.
1307+ *
1308+ * Platform selection [init hint](@ref GLFW_PLATFORM).
1309+ */
1310+#define GLFW_PLATFORM 0x00050003
1311+/*! @brief macOS specific init hint.
1312+ *
1313+ * macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint).
1314+ */
1315+#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001
1316+/*! @brief macOS specific init hint.
1317+ *
1318+ * macOS specific [init hint](@ref GLFW_COCOA_MENUBAR_hint).
1319+ */
1320+#define GLFW_COCOA_MENUBAR 0x00051002
1321+/*! @brief X11 specific init hint.
1322+ *
1323+ * X11 specific [init hint](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint).
1324+ */
1325+#define GLFW_X11_XCB_VULKAN_SURFACE 0x00052001
1326+/*! @brief Wayland specific init hint.
1327+ *
1328+ * Wayland specific [init hint](@ref GLFW_WAYLAND_LIBDECOR_hint).
1329+ */
1330+#define GLFW_WAYLAND_LIBDECOR 0x00053001
1331+/*! @} */
1332+
1333+/*! @addtogroup init
1334+ * @{ */
1335+/*! @brief Hint value that enables automatic platform selection.
1336+ *
1337+ * Hint value for @ref GLFW_PLATFORM that enables automatic platform selection.
1338+ */
1339+#define GLFW_ANY_PLATFORM 0x00060000
1340+#define GLFW_PLATFORM_WIN32 0x00060001
1341+#define GLFW_PLATFORM_COCOA 0x00060002
1342+#define GLFW_PLATFORM_WAYLAND 0x00060003
1343+#define GLFW_PLATFORM_X11 0x00060004
1344+#define GLFW_PLATFORM_NULL 0x00060005
1345+/*! @} */
1346+
1347+/* Reserved platform define for external Emscripten ports: 0x00060006
1348+ * See https://github.com/pongasoft/emscripten-glfw
1349+ */
1350+
1351+#define GLFW_DONT_CARE -1
1352+
1353+
1354+/*************************************************************************
1355+ * GLFW API types
1356+ *************************************************************************/
1357+
1358+/*! @brief Client API function pointer type.
1359+ *
1360+ * Generic function pointer used for returning client API function pointers
1361+ * without forcing a cast from a regular pointer.
1362+ *
1363+ * @sa @ref context_glext
1364+ * @sa @ref glfwGetProcAddress
1365+ *
1366+ * @since Added in version 3.0.
1367+ *
1368+ * @ingroup context
1369+ */
1370+typedef void (*GLFWglproc)(void);
1371+
1372+/*! @brief Vulkan API function pointer type.
1373+ *
1374+ * Generic function pointer used for returning Vulkan API function pointers
1375+ * without forcing a cast from a regular pointer.
1376+ *
1377+ * @sa @ref vulkan_proc
1378+ * @sa @ref glfwGetInstanceProcAddress
1379+ *
1380+ * @since Added in version 3.2.
1381+ *
1382+ * @ingroup vulkan
1383+ */
1384+typedef void (*GLFWvkproc)(void);
1385+
1386+/*! @brief Opaque monitor object.
1387+ *
1388+ * Opaque monitor object.
1389+ *
1390+ * @see @ref monitor_object
1391+ *
1392+ * @since Added in version 3.0.
1393+ *
1394+ * @ingroup monitor
1395+ */
1396+typedef struct GLFWmonitor GLFWmonitor;
1397+
1398+/*! @brief Opaque window object.
1399+ *
1400+ * Opaque window object.
1401+ *
1402+ * @see @ref window_object
1403+ *
1404+ * @since Added in version 3.0.
1405+ *
1406+ * @ingroup window
1407+ */
1408+typedef struct GLFWwindow GLFWwindow;
1409+
1410+/*! @brief Opaque cursor object.
1411+ *
1412+ * Opaque cursor object.
1413+ *
1414+ * @see @ref cursor_object
1415+ *
1416+ * @since Added in version 3.1.
1417+ *
1418+ * @ingroup input
1419+ */
1420+typedef struct GLFWcursor GLFWcursor;
1421+
1422+/*! @brief The function pointer type for memory allocation callbacks.
1423+ *
1424+ * This is the function pointer type for memory allocation callbacks. A memory
1425+ * allocation callback function has the following signature:
1426+ * @code
1427+ * void* function_name(size_t size, void* user)
1428+ * @endcode
1429+ *
1430+ * This function must return either a memory block at least `size` bytes long,
1431+ * or `NULL` if allocation failed. Note that not all parts of GLFW handle allocation
1432+ * failures gracefully yet.
1433+ *
1434+ * This function must support being called during @ref glfwInit but before the library is
1435+ * flagged as initialized, as well as during @ref glfwTerminate after the library is no
1436+ * longer flagged as initialized.
1437+ *
1438+ * Any memory allocated via this function will be deallocated via the same allocator
1439+ * during library termination or earlier.
1440+ *
1441+ * Any memory allocated via this function must be suitably aligned for any object type.
1442+ * If you are using C99 or earlier, this alignment is platform-dependent but will be the
1443+ * same as what `malloc` provides. If you are using C11 or later, this is the value of
1444+ * `alignof(max_align_t)`.
1445+ *
1446+ * The size will always be greater than zero. Allocations of size zero are filtered out
1447+ * before reaching the custom allocator.
1448+ *
1449+ * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY.
1450+ *
1451+ * This function must not call any GLFW function.
1452+ *
1453+ * @param[in] size The minimum size, in bytes, of the memory block.
1454+ * @param[in] user The user-defined pointer from the allocator.
1455+ * @return The address of the newly allocated memory block, or `NULL` if an
1456+ * error occurred.
1457+ *
1458+ * @pointer_lifetime The returned memory block must be valid at least until it
1459+ * is deallocated.
1460+ *
1461+ * @reentrancy This function should not call any GLFW function.
1462+ *
1463+ * @thread_safety This function must support being called from any thread that calls GLFW
1464+ * functions.
1465+ *
1466+ * @sa @ref init_allocator
1467+ * @sa @ref GLFWallocator
1468+ *
1469+ * @since Added in version 3.4.
1470+ *
1471+ * @ingroup init
1472+ */
1473+typedef void* (* GLFWallocatefun)(size_t size, void* user);
1474+
1475+/*! @brief The function pointer type for memory reallocation callbacks.
1476+ *
1477+ * This is the function pointer type for memory reallocation callbacks.
1478+ * A memory reallocation callback function has the following signature:
1479+ * @code
1480+ * void* function_name(void* block, size_t size, void* user)
1481+ * @endcode
1482+ *
1483+ * This function must return a memory block at least `size` bytes long, or
1484+ * `NULL` if allocation failed. Note that not all parts of GLFW handle allocation
1485+ * failures gracefully yet.
1486+ *
1487+ * This function must support being called during @ref glfwInit but before the library is
1488+ * flagged as initialized, as well as during @ref glfwTerminate after the library is no
1489+ * longer flagged as initialized.
1490+ *
1491+ * Any memory allocated via this function will be deallocated via the same allocator
1492+ * during library termination or earlier.
1493+ *
1494+ * Any memory allocated via this function must be suitably aligned for any object type.
1495+ * If you are using C99 or earlier, this alignment is platform-dependent but will be the
1496+ * same as what `realloc` provides. If you are using C11 or later, this is the value of
1497+ * `alignof(max_align_t)`.
1498+ *
1499+ * The block address will never be `NULL` and the size will always be greater than zero.
1500+ * Reallocations of a block to size zero are converted into deallocations before reaching
1501+ * the custom allocator. Reallocations of `NULL` to a non-zero size are converted into
1502+ * regular allocations before reaching the custom allocator.
1503+ *
1504+ * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY.
1505+ *
1506+ * This function must not call any GLFW function.
1507+ *
1508+ * @param[in] block The address of the memory block to reallocate.
1509+ * @param[in] size The new minimum size, in bytes, of the memory block.
1510+ * @param[in] user The user-defined pointer from the allocator.
1511+ * @return The address of the newly allocated or resized memory block, or
1512+ * `NULL` if an error occurred.
1513+ *
1514+ * @pointer_lifetime The returned memory block must be valid at least until it
1515+ * is deallocated.
1516+ *
1517+ * @reentrancy This function should not call any GLFW function.
1518+ *
1519+ * @thread_safety This function must support being called from any thread that calls GLFW
1520+ * functions.
1521+ *
1522+ * @sa @ref init_allocator
1523+ * @sa @ref GLFWallocator
1524+ *
1525+ * @since Added in version 3.4.
1526+ *
1527+ * @ingroup init
1528+ */
1529+typedef void* (* GLFWreallocatefun)(void* block, size_t size, void* user);
1530+
1531+/*! @brief The function pointer type for memory deallocation callbacks.
1532+ *
1533+ * This is the function pointer type for memory deallocation callbacks.
1534+ * A memory deallocation callback function has the following signature:
1535+ * @code
1536+ * void function_name(void* block, void* user)
1537+ * @endcode
1538+ *
1539+ * This function may deallocate the specified memory block. This memory block
1540+ * will have been allocated with the same allocator.
1541+ *
1542+ * This function must support being called during @ref glfwInit but before the library is
1543+ * flagged as initialized, as well as during @ref glfwTerminate after the library is no
1544+ * longer flagged as initialized.
1545+ *
1546+ * The block address will never be `NULL`. Deallocations of `NULL` are filtered out
1547+ * before reaching the custom allocator.
1548+ *
1549+ * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY.
1550+ *
1551+ * This function must not call any GLFW function.
1552+ *
1553+ * @param[in] block The address of the memory block to deallocate.
1554+ * @param[in] user The user-defined pointer from the allocator.
1555+ *
1556+ * @pointer_lifetime The specified memory block will not be accessed by GLFW
1557+ * after this function is called.
1558+ *
1559+ * @reentrancy This function should not call any GLFW function.
1560+ *
1561+ * @thread_safety This function must support being called from any thread that calls GLFW
1562+ * functions.
1563+ *
1564+ * @sa @ref init_allocator
1565+ * @sa @ref GLFWallocator
1566+ *
1567+ * @since Added in version 3.4.
1568+ *
1569+ * @ingroup init
1570+ */
1571+typedef void (* GLFWdeallocatefun)(void* block, void* user);
1572+
1573+/*! @brief The function pointer type for error callbacks.
1574+ *
1575+ * This is the function pointer type for error callbacks. An error callback
1576+ * function has the following signature:
1577+ * @code
1578+ * void callback_name(int error_code, const char* description)
1579+ * @endcode
1580+ *
1581+ * @param[in] error_code An [error code](@ref errors). Future releases may add
1582+ * more error codes.
1583+ * @param[in] description A UTF-8 encoded string describing the error.
1584+ *
1585+ * @pointer_lifetime The error description string is valid until the callback
1586+ * function returns.
1587+ *
1588+ * @sa @ref error_handling
1589+ * @sa @ref glfwSetErrorCallback
1590+ *
1591+ * @since Added in version 3.0.
1592+ *
1593+ * @ingroup init
1594+ */
1595+typedef void (* GLFWerrorfun)(int error_code, const char* description);
1596+
1597+/*! @brief The function pointer type for window position callbacks.
1598+ *
1599+ * This is the function pointer type for window position callbacks. A window
1600+ * position callback function has the following signature:
1601+ * @code
1602+ * void callback_name(GLFWwindow* window, int xpos, int ypos)
1603+ * @endcode
1604+ *
1605+ * @param[in] window The window that was moved.
1606+ * @param[in] xpos The new x-coordinate, in screen coordinates, of the
1607+ * upper-left corner of the content area of the window.
1608+ * @param[in] ypos The new y-coordinate, in screen coordinates, of the
1609+ * upper-left corner of the content area of the window.
1610+ *
1611+ * @sa @ref window_pos
1612+ * @sa @ref glfwSetWindowPosCallback
1613+ *
1614+ * @since Added in version 3.0.
1615+ *
1616+ * @ingroup window
1617+ */
1618+typedef void (* GLFWwindowposfun)(GLFWwindow* window, int xpos, int ypos);
1619+
1620+/*! @brief The function pointer type for window size callbacks.
1621+ *
1622+ * This is the function pointer type for window size callbacks. A window size
1623+ * callback function has the following signature:
1624+ * @code
1625+ * void callback_name(GLFWwindow* window, int width, int height)
1626+ * @endcode
1627+ *
1628+ * @param[in] window The window that was resized.
1629+ * @param[in] width The new width, in screen coordinates, of the window.
1630+ * @param[in] height The new height, in screen coordinates, of the window.
1631+ *
1632+ * @sa @ref window_size
1633+ * @sa @ref glfwSetWindowSizeCallback
1634+ *
1635+ * @since Added in version 1.0.
1636+ * __GLFW 3:__ Added window handle parameter.
1637+ *
1638+ * @ingroup window
1639+ */
1640+typedef void (* GLFWwindowsizefun)(GLFWwindow* window, int width, int height);
1641+
1642+/*! @brief The function pointer type for window close callbacks.
1643+ *
1644+ * This is the function pointer type for window close callbacks. A window
1645+ * close callback function has the following signature:
1646+ * @code
1647+ * void function_name(GLFWwindow* window)
1648+ * @endcode
1649+ *
1650+ * @param[in] window The window that the user attempted to close.
1651+ *
1652+ * @sa @ref window_close
1653+ * @sa @ref glfwSetWindowCloseCallback
1654+ *
1655+ * @since Added in version 2.5.
1656+ * __GLFW 3:__ Added window handle parameter.
1657+ *
1658+ * @ingroup window
1659+ */
1660+typedef void (* GLFWwindowclosefun)(GLFWwindow* window);
1661+
1662+/*! @brief The function pointer type for window content refresh callbacks.
1663+ *
1664+ * This is the function pointer type for window content refresh callbacks.
1665+ * A window content refresh callback function has the following signature:
1666+ * @code
1667+ * void function_name(GLFWwindow* window);
1668+ * @endcode
1669+ *
1670+ * @param[in] window The window whose content needs to be refreshed.
1671+ *
1672+ * @sa @ref window_refresh
1673+ * @sa @ref glfwSetWindowRefreshCallback
1674+ *
1675+ * @since Added in version 2.5.
1676+ * __GLFW 3:__ Added window handle parameter.
1677+ *
1678+ * @ingroup window
1679+ */
1680+typedef void (* GLFWwindowrefreshfun)(GLFWwindow* window);
1681+
1682+/*! @brief The function pointer type for window focus callbacks.
1683+ *
1684+ * This is the function pointer type for window focus callbacks. A window
1685+ * focus callback function has the following signature:
1686+ * @code
1687+ * void function_name(GLFWwindow* window, int focused)
1688+ * @endcode
1689+ *
1690+ * @param[in] window The window that gained or lost input focus.
1691+ * @param[in] focused `GLFW_TRUE` if the window was given input focus, or
1692+ * `GLFW_FALSE` if it lost it.
1693+ *
1694+ * @sa @ref window_focus
1695+ * @sa @ref glfwSetWindowFocusCallback
1696+ *
1697+ * @since Added in version 3.0.
1698+ *
1699+ * @ingroup window
1700+ */
1701+typedef void (* GLFWwindowfocusfun)(GLFWwindow* window, int focused);
1702+
1703+/*! @brief The function pointer type for window iconify callbacks.
1704+ *
1705+ * This is the function pointer type for window iconify callbacks. A window
1706+ * iconify callback function has the following signature:
1707+ * @code
1708+ * void function_name(GLFWwindow* window, int iconified)
1709+ * @endcode
1710+ *
1711+ * @param[in] window The window that was iconified or restored.
1712+ * @param[in] iconified `GLFW_TRUE` if the window was iconified, or
1713+ * `GLFW_FALSE` if it was restored.
1714+ *
1715+ * @sa @ref window_iconify
1716+ * @sa @ref glfwSetWindowIconifyCallback
1717+ *
1718+ * @since Added in version 3.0.
1719+ *
1720+ * @ingroup window
1721+ */
1722+typedef void (* GLFWwindowiconifyfun)(GLFWwindow* window, int iconified);
1723+
1724+/*! @brief The function pointer type for window maximize callbacks.
1725+ *
1726+ * This is the function pointer type for window maximize callbacks. A window
1727+ * maximize callback function has the following signature:
1728+ * @code
1729+ * void function_name(GLFWwindow* window, int maximized)
1730+ * @endcode
1731+ *
1732+ * @param[in] window The window that was maximized or restored.
1733+ * @param[in] maximized `GLFW_TRUE` if the window was maximized, or
1734+ * `GLFW_FALSE` if it was restored.
1735+ *
1736+ * @sa @ref window_maximize
1737+ * @sa glfwSetWindowMaximizeCallback
1738+ *
1739+ * @since Added in version 3.3.
1740+ *
1741+ * @ingroup window
1742+ */
1743+typedef void (* GLFWwindowmaximizefun)(GLFWwindow* window, int maximized);
1744+
1745+/*! @brief The function pointer type for framebuffer size callbacks.
1746+ *
1747+ * This is the function pointer type for framebuffer size callbacks.
1748+ * A framebuffer size callback function has the following signature:
1749+ * @code
1750+ * void function_name(GLFWwindow* window, int width, int height)
1751+ * @endcode
1752+ *
1753+ * @param[in] window The window whose framebuffer was resized.
1754+ * @param[in] width The new width, in pixels, of the framebuffer.
1755+ * @param[in] height The new height, in pixels, of the framebuffer.
1756+ *
1757+ * @sa @ref window_fbsize
1758+ * @sa @ref glfwSetFramebufferSizeCallback
1759+ *
1760+ * @since Added in version 3.0.
1761+ *
1762+ * @ingroup window
1763+ */
1764+typedef void (* GLFWframebuffersizefun)(GLFWwindow* window, int width, int height);
1765+
1766+/*! @brief The function pointer type for window content scale callbacks.
1767+ *
1768+ * This is the function pointer type for window content scale callbacks.
1769+ * A window content scale callback function has the following signature:
1770+ * @code
1771+ * void function_name(GLFWwindow* window, float xscale, float yscale)
1772+ * @endcode
1773+ *
1774+ * @param[in] window The window whose content scale changed.
1775+ * @param[in] xscale The new x-axis content scale of the window.
1776+ * @param[in] yscale The new y-axis content scale of the window.
1777+ *
1778+ * @sa @ref window_scale
1779+ * @sa @ref glfwSetWindowContentScaleCallback
1780+ *
1781+ * @since Added in version 3.3.
1782+ *
1783+ * @ingroup window
1784+ */
1785+typedef void (* GLFWwindowcontentscalefun)(GLFWwindow* window, float xscale, float yscale);
1786+
1787+/*! @brief The function pointer type for mouse button callbacks.
1788+ *
1789+ * This is the function pointer type for mouse button callback functions.
1790+ * A mouse button callback function has the following signature:
1791+ * @code
1792+ * void function_name(GLFWwindow* window, int button, int action, int mods)
1793+ * @endcode
1794+ *
1795+ * @param[in] window The window that received the event.
1796+ * @param[in] button The [mouse button](@ref buttons) that was pressed or
1797+ * released.
1798+ * @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`. Future releases
1799+ * may add more actions.
1800+ * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
1801+ * held down.
1802+ *
1803+ * @sa @ref input_mouse_button
1804+ * @sa @ref glfwSetMouseButtonCallback
1805+ *
1806+ * @since Added in version 1.0.
1807+ * __GLFW 3:__ Added window handle and modifier mask parameters.
1808+ *
1809+ * @ingroup input
1810+ */
1811+typedef void (* GLFWmousebuttonfun)(GLFWwindow* window, int button, int action, int mods);
1812+
1813+/*! @brief The function pointer type for cursor position callbacks.
1814+ *
1815+ * This is the function pointer type for cursor position callbacks. A cursor
1816+ * position callback function has the following signature:
1817+ * @code
1818+ * void function_name(GLFWwindow* window, double xpos, double ypos);
1819+ * @endcode
1820+ *
1821+ * @param[in] window The window that received the event.
1822+ * @param[in] xpos The new cursor x-coordinate, relative to the left edge of
1823+ * the content area.
1824+ * @param[in] ypos The new cursor y-coordinate, relative to the top edge of the
1825+ * content area.
1826+ *
1827+ * @sa @ref cursor_pos
1828+ * @sa @ref glfwSetCursorPosCallback
1829+ *
1830+ * @since Added in version 3.0. Replaces `GLFWmouseposfun`.
1831+ *
1832+ * @ingroup input
1833+ */
1834+typedef void (* GLFWcursorposfun)(GLFWwindow* window, double xpos, double ypos);
1835+
1836+/*! @brief The function pointer type for cursor enter/leave callbacks.
1837+ *
1838+ * This is the function pointer type for cursor enter/leave callbacks.
1839+ * A cursor enter/leave callback function has the following signature:
1840+ * @code
1841+ * void function_name(GLFWwindow* window, int entered)
1842+ * @endcode
1843+ *
1844+ * @param[in] window The window that received the event.
1845+ * @param[in] entered `GLFW_TRUE` if the cursor entered the window's content
1846+ * area, or `GLFW_FALSE` if it left it.
1847+ *
1848+ * @sa @ref cursor_enter
1849+ * @sa @ref glfwSetCursorEnterCallback
1850+ *
1851+ * @since Added in version 3.0.
1852+ *
1853+ * @ingroup input
1854+ */
1855+typedef void (* GLFWcursorenterfun)(GLFWwindow* window, int entered);
1856+
1857+/*! @brief The function pointer type for scroll callbacks.
1858+ *
1859+ * This is the function pointer type for scroll callbacks. A scroll callback
1860+ * function has the following signature:
1861+ * @code
1862+ * void function_name(GLFWwindow* window, double xoffset, double yoffset)
1863+ * @endcode
1864+ *
1865+ * @param[in] window The window that received the event.
1866+ * @param[in] xoffset The scroll offset along the x-axis.
1867+ * @param[in] yoffset The scroll offset along the y-axis.
1868+ *
1869+ * @sa @ref scrolling
1870+ * @sa @ref glfwSetScrollCallback
1871+ *
1872+ * @since Added in version 3.0. Replaces `GLFWmousewheelfun`.
1873+ *
1874+ * @ingroup input
1875+ */
1876+typedef void (* GLFWscrollfun)(GLFWwindow* window, double xoffset, double yoffset);
1877+
1878+/*! @brief The function pointer type for keyboard key callbacks.
1879+ *
1880+ * This is the function pointer type for keyboard key callbacks. A keyboard
1881+ * key callback function has the following signature:
1882+ * @code
1883+ * void function_name(GLFWwindow* window, int key, int scancode, int action, int mods)
1884+ * @endcode
1885+ *
1886+ * @param[in] window The window that received the event.
1887+ * @param[in] key The [keyboard key](@ref keys) that was pressed or released.
1888+ * @param[in] scancode The platform-specific scancode of the key.
1889+ * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`. Future
1890+ * releases may add more actions.
1891+ * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
1892+ * held down.
1893+ *
1894+ * @sa @ref input_key
1895+ * @sa @ref glfwSetKeyCallback
1896+ *
1897+ * @since Added in version 1.0.
1898+ * __GLFW 3:__ Added window handle, scancode and modifier mask parameters.
1899+ *
1900+ * @ingroup input
1901+ */
1902+typedef void (* GLFWkeyfun)(GLFWwindow* window, int key, int scancode, int action, int mods);
1903+
1904+/*! @brief The function pointer type for Unicode character callbacks.
1905+ *
1906+ * This is the function pointer type for Unicode character callbacks.
1907+ * A Unicode character callback function has the following signature:
1908+ * @code
1909+ * void function_name(GLFWwindow* window, unsigned int codepoint)
1910+ * @endcode
1911+ *
1912+ * @param[in] window The window that received the event.
1913+ * @param[in] codepoint The Unicode code point of the character.
1914+ *
1915+ * @sa @ref input_char
1916+ * @sa @ref glfwSetCharCallback
1917+ *
1918+ * @since Added in version 2.4.
1919+ * __GLFW 3:__ Added window handle parameter.
1920+ *
1921+ * @ingroup input
1922+ */
1923+typedef void (* GLFWcharfun)(GLFWwindow* window, unsigned int codepoint);
1924+
1925+/*! @brief The function pointer type for Unicode character with modifiers
1926+ * callbacks.
1927+ *
1928+ * This is the function pointer type for Unicode character with modifiers
1929+ * callbacks. It is called for each input character, regardless of what
1930+ * modifier keys are held down. A Unicode character with modifiers callback
1931+ * function has the following signature:
1932+ * @code
1933+ * void function_name(GLFWwindow* window, unsigned int codepoint, int mods)
1934+ * @endcode
1935+ *
1936+ * @param[in] window The window that received the event.
1937+ * @param[in] codepoint The Unicode code point of the character.
1938+ * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
1939+ * held down.
1940+ *
1941+ * @sa @ref input_char
1942+ * @sa @ref glfwSetCharModsCallback
1943+ *
1944+ * @deprecated Scheduled for removal in version 4.0.
1945+ *
1946+ * @since Added in version 3.1.
1947+ *
1948+ * @ingroup input
1949+ */
1950+typedef void (* GLFWcharmodsfun)(GLFWwindow* window, unsigned int codepoint, int mods);
1951+
1952+/*! @brief The function pointer type for path drop callbacks.
1953+ *
1954+ * This is the function pointer type for path drop callbacks. A path drop
1955+ * callback function has the following signature:
1956+ * @code
1957+ * void function_name(GLFWwindow* window, int path_count, const char* paths[])
1958+ * @endcode
1959+ *
1960+ * @param[in] window The window that received the event.
1961+ * @param[in] path_count The number of dropped paths.
1962+ * @param[in] paths The UTF-8 encoded file and/or directory path names.
1963+ *
1964+ * @pointer_lifetime The path array and its strings are valid until the
1965+ * callback function returns.
1966+ *
1967+ * @sa @ref path_drop
1968+ * @sa @ref glfwSetDropCallback
1969+ *
1970+ * @since Added in version 3.1.
1971+ *
1972+ * @ingroup input
1973+ */
1974+typedef void (* GLFWdropfun)(GLFWwindow* window, int path_count, const char* paths[]);
1975+
1976+/*! @brief The function pointer type for monitor configuration callbacks.
1977+ *
1978+ * This is the function pointer type for monitor configuration callbacks.
1979+ * A monitor callback function has the following signature:
1980+ * @code
1981+ * void function_name(GLFWmonitor* monitor, int event)
1982+ * @endcode
1983+ *
1984+ * @param[in] monitor The monitor that was connected or disconnected.
1985+ * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. Future
1986+ * releases may add more events.
1987+ *
1988+ * @sa @ref monitor_event
1989+ * @sa @ref glfwSetMonitorCallback
1990+ *
1991+ * @since Added in version 3.0.
1992+ *
1993+ * @ingroup monitor
1994+ */
1995+typedef void (* GLFWmonitorfun)(GLFWmonitor* monitor, int event);
1996+
1997+/*! @brief The function pointer type for joystick configuration callbacks.
1998+ *
1999+ * This is the function pointer type for joystick configuration callbacks.
2000+ * A joystick configuration callback function has the following signature:
2001+ * @code
2002+ * void function_name(int jid, int event)
2003+ * @endcode
2004+ *
2005+ * @param[in] jid The joystick that was connected or disconnected.
2006+ * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. Future
2007+ * releases may add more events.
2008+ *
2009+ * @sa @ref joystick_event
2010+ * @sa @ref glfwSetJoystickCallback
2011+ *
2012+ * @since Added in version 3.2.
2013+ *
2014+ * @ingroup input
2015+ */
2016+typedef void (* GLFWjoystickfun)(int jid, int event);
2017+
2018+/*! @brief Video mode type.
2019+ *
2020+ * This describes a single video mode.
2021+ *
2022+ * @sa @ref monitor_modes
2023+ * @sa @ref glfwGetVideoMode
2024+ * @sa @ref glfwGetVideoModes
2025+ *
2026+ * @since Added in version 1.0.
2027+ * __GLFW 3:__ Added refresh rate member.
2028+ *
2029+ * @ingroup monitor
2030+ */
2031+typedef struct GLFWvidmode
2032+{
2033+ /*! The width, in screen coordinates, of the video mode.
2034+ */
2035+ int width;
2036+ /*! The height, in screen coordinates, of the video mode.
2037+ */
2038+ int height;
2039+ /*! The bit depth of the red channel of the video mode.
2040+ */
2041+ int redBits;
2042+ /*! The bit depth of the green channel of the video mode.
2043+ */
2044+ int greenBits;
2045+ /*! The bit depth of the blue channel of the video mode.
2046+ */
2047+ int blueBits;
2048+ /*! The refresh rate, in Hz, of the video mode.
2049+ */
2050+ int refreshRate;
2051+} GLFWvidmode;
2052+
2053+/*! @brief Gamma ramp.
2054+ *
2055+ * This describes the gamma ramp for a monitor.
2056+ *
2057+ * @sa @ref monitor_gamma
2058+ * @sa @ref glfwGetGammaRamp
2059+ * @sa @ref glfwSetGammaRamp
2060+ *
2061+ * @since Added in version 3.0.
2062+ *
2063+ * @ingroup monitor
2064+ */
2065+typedef struct GLFWgammaramp
2066+{
2067+ /*! An array of value describing the response of the red channel.
2068+ */
2069+ unsigned short* red;
2070+ /*! An array of value describing the response of the green channel.
2071+ */
2072+ unsigned short* green;
2073+ /*! An array of value describing the response of the blue channel.
2074+ */
2075+ unsigned short* blue;
2076+ /*! The number of elements in each array.
2077+ */
2078+ unsigned int size;
2079+} GLFWgammaramp;
2080+
2081+/*! @brief Image data.
2082+ *
2083+ * This describes a single 2D image. See the documentation for each related
2084+ * function what the expected pixel format is.
2085+ *
2086+ * @sa @ref cursor_custom
2087+ * @sa @ref window_icon
2088+ *
2089+ * @since Added in version 2.1.
2090+ * __GLFW 3:__ Removed format and bytes-per-pixel members.
2091+ *
2092+ * @ingroup window
2093+ */
2094+typedef struct GLFWimage
2095+{
2096+ /*! The width, in pixels, of this image.
2097+ */
2098+ int width;
2099+ /*! The height, in pixels, of this image.
2100+ */
2101+ int height;
2102+ /*! The pixel data of this image, arranged left-to-right, top-to-bottom.
2103+ */
2104+ unsigned char* pixels;
2105+} GLFWimage;
2106+
2107+/*! @brief Gamepad input state
2108+ *
2109+ * This describes the input state of a gamepad.
2110+ *
2111+ * @sa @ref gamepad
2112+ * @sa @ref glfwGetGamepadState
2113+ *
2114+ * @since Added in version 3.3.
2115+ *
2116+ * @ingroup input
2117+ */
2118+typedef struct GLFWgamepadstate
2119+{
2120+ /*! The states of each [gamepad button](@ref gamepad_buttons), `GLFW_PRESS`
2121+ * or `GLFW_RELEASE`.
2122+ */
2123+ unsigned char buttons[15];
2124+ /*! The states of each [gamepad axis](@ref gamepad_axes), in the range -1.0
2125+ * to 1.0 inclusive.
2126+ */
2127+ float axes[6];
2128+} GLFWgamepadstate;
2129+
2130+/*! @brief Custom heap memory allocator.
2131+ *
2132+ * This describes a custom heap memory allocator for GLFW. To set an allocator, pass it
2133+ * to @ref glfwInitAllocator before initializing the library.
2134+ *
2135+ * @sa @ref init_allocator
2136+ * @sa @ref glfwInitAllocator
2137+ *
2138+ * @since Added in version 3.4.
2139+ *
2140+ * @ingroup init
2141+ */
2142+typedef struct GLFWallocator
2143+{
2144+ /*! The memory allocation function. See @ref GLFWallocatefun for details about
2145+ * allocation function.
2146+ */
2147+ GLFWallocatefun allocate;
2148+ /*! The memory reallocation function. See @ref GLFWreallocatefun for details about
2149+ * reallocation function.
2150+ */
2151+ GLFWreallocatefun reallocate;
2152+ /*! The memory deallocation function. See @ref GLFWdeallocatefun for details about
2153+ * deallocation function.
2154+ */
2155+ GLFWdeallocatefun deallocate;
2156+ /*! The user pointer for this custom allocator. This value will be passed to the
2157+ * allocator functions.
2158+ */
2159+ void* user;
2160+} GLFWallocator;
2161+
2162+
2163+/*************************************************************************
2164+ * GLFW API functions
2165+ *************************************************************************/
2166+
2167+/*! @brief Initializes the GLFW library.
2168+ *
2169+ * This function initializes the GLFW library. Before most GLFW functions can
2170+ * be used, GLFW must be initialized, and before an application terminates GLFW
2171+ * should be terminated in order to free any resources allocated during or
2172+ * after initialization.
2173+ *
2174+ * If this function fails, it calls @ref glfwTerminate before returning. If it
2175+ * succeeds, you should call @ref glfwTerminate before the application exits.
2176+ *
2177+ * Additional calls to this function after successful initialization but before
2178+ * termination will return `GLFW_TRUE` immediately.
2179+ *
2180+ * The @ref GLFW_PLATFORM init hint controls which platforms are considered during
2181+ * initialization. This also depends on which platforms the library was compiled to
2182+ * support.
2183+ *
2184+ * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
2185+ * [error](@ref error_handling) occurred.
2186+ *
2187+ * @errors Possible errors include @ref GLFW_PLATFORM_UNAVAILABLE and @ref
2188+ * GLFW_PLATFORM_ERROR.
2189+ *
2190+ * @remark __macOS:__ This function will change the current directory of the
2191+ * application to the `Contents/Resources` subdirectory of the application's
2192+ * bundle, if present. This can be disabled with the @ref
2193+ * GLFW_COCOA_CHDIR_RESOURCES init hint.
2194+ *
2195+ * @remark __macOS:__ This function will create the main menu and dock icon for the
2196+ * application. If GLFW finds a `MainMenu.nib` it is loaded and assumed to
2197+ * contain a menu bar. Otherwise a minimal menu bar is created manually with
2198+ * common commands like Hide, Quit and About. The About entry opens a minimal
2199+ * about dialog with information from the application's bundle. The menu bar
2200+ * and dock icon can be disabled entirely with the @ref GLFW_COCOA_MENUBAR init
2201+ * hint.
2202+ *
2203+ * @remark __Wayland, X11:__ If the library was compiled with support for both
2204+ * Wayland and X11, and the @ref GLFW_PLATFORM init hint is set to
2205+ * `GLFW_ANY_PLATFORM`, the `XDG_SESSION_TYPE` environment variable affects
2206+ * which platform is picked. If the environment variable is not set, or is set
2207+ * to something other than `wayland` or `x11`, the regular detection mechanism
2208+ * will be used instead.
2209+ *
2210+ * @remark __X11:__ This function will set the `LC_CTYPE` category of the
2211+ * application locale according to the current environment if that category is
2212+ * still "C". This is because the "C" locale breaks Unicode text input.
2213+ *
2214+ * @thread_safety This function must only be called from the main thread.
2215+ *
2216+ * @sa @ref intro_init
2217+ * @sa @ref glfwInitHint
2218+ * @sa @ref glfwInitAllocator
2219+ * @sa @ref glfwTerminate
2220+ *
2221+ * @since Added in version 1.0.
2222+ *
2223+ * @ingroup init
2224+ */
2225+GLFWAPI int glfwInit(void);
2226+
2227+/*! @brief Terminates the GLFW library.
2228+ *
2229+ * This function destroys all remaining windows and cursors, restores any
2230+ * modified gamma ramps and frees any other allocated resources. Once this
2231+ * function is called, you must again call @ref glfwInit successfully before
2232+ * you will be able to use most GLFW functions.
2233+ *
2234+ * If GLFW has been successfully initialized, this function should be called
2235+ * before the application exits. If initialization fails, there is no need to
2236+ * call this function, as it is called by @ref glfwInit before it returns
2237+ * failure.
2238+ *
2239+ * This function has no effect if GLFW is not initialized.
2240+ *
2241+ * @errors Possible errors include @ref GLFW_PLATFORM_ERROR.
2242+ *
2243+ * @remark This function may be called before @ref glfwInit.
2244+ *
2245+ * @warning The contexts of any remaining windows must not be current on any
2246+ * other thread when this function is called.
2247+ *
2248+ * @reentrancy This function must not be called from a callback.
2249+ *
2250+ * @thread_safety This function must only be called from the main thread.
2251+ *
2252+ * @sa @ref intro_init
2253+ * @sa @ref glfwInit
2254+ *
2255+ * @since Added in version 1.0.
2256+ *
2257+ * @ingroup init
2258+ */
2259+GLFWAPI void glfwTerminate(void);
2260+
2261+/*! @brief Sets the specified init hint to the desired value.
2262+ *
2263+ * This function sets hints for the next initialization of GLFW.
2264+ *
2265+ * The values you set hints to are never reset by GLFW, but they only take
2266+ * effect during initialization. Once GLFW has been initialized, any values
2267+ * you set will be ignored until the library is terminated and initialized
2268+ * again.
2269+ *
2270+ * Some hints are platform specific. These may be set on any platform but they
2271+ * will only affect their specific platform. Other platforms will ignore them.
2272+ * Setting these hints requires no platform specific headers or functions.
2273+ *
2274+ * @param[in] hint The [init hint](@ref init_hints) to set.
2275+ * @param[in] value The new value of the init hint.
2276+ *
2277+ * @errors Possible errors include @ref GLFW_INVALID_ENUM and @ref
2278+ * GLFW_INVALID_VALUE.
2279+ *
2280+ * @remarks This function may be called before @ref glfwInit.
2281+ *
2282+ * @thread_safety This function must only be called from the main thread.
2283+ *
2284+ * @sa init_hints
2285+ * @sa glfwInit
2286+ *
2287+ * @since Added in version 3.3.
2288+ *
2289+ * @ingroup init
2290+ */
2291+GLFWAPI void glfwInitHint(int hint, int value);
2292+
2293+/*! @brief Sets the init allocator to the desired value.
2294+ *
2295+ * To use the default allocator, call this function with a `NULL` argument.
2296+ *
2297+ * If you specify an allocator struct, every member must be a valid function
2298+ * pointer. If any member is `NULL`, this function will emit @ref
2299+ * GLFW_INVALID_VALUE and the init allocator will be unchanged.
2300+ *
2301+ * The functions in the allocator must fulfil a number of requirements. See the
2302+ * documentation for @ref GLFWallocatefun, @ref GLFWreallocatefun and @ref
2303+ * GLFWdeallocatefun for details.
2304+ *
2305+ * @param[in] allocator The allocator to use at the next initialization, or
2306+ * `NULL` to use the default one.
2307+ *
2308+ * @errors Possible errors include @ref GLFW_INVALID_VALUE.
2309+ *
2310+ * @pointer_lifetime The specified allocator is copied before this function
2311+ * returns.
2312+ *
2313+ * @thread_safety This function must only be called from the main thread.
2314+ *
2315+ * @sa @ref init_allocator
2316+ * @sa @ref glfwInit
2317+ *
2318+ * @since Added in version 3.4.
2319+ *
2320+ * @ingroup init
2321+ */
2322+GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator);
2323+
2324+#if defined(VK_VERSION_1_0)
2325+
2326+/*! @brief Sets the desired Vulkan `vkGetInstanceProcAddr` function.
2327+ *
2328+ * This function sets the `vkGetInstanceProcAddr` function that GLFW will use for all
2329+ * Vulkan related entry point queries.
2330+ *
2331+ * This feature is mostly useful on macOS, if your copy of the Vulkan loader is in
2332+ * a location where GLFW cannot find it through dynamic loading, or if you are still
2333+ * using the static library version of the loader.
2334+ *
2335+ * If set to `NULL`, GLFW will try to load the Vulkan loader dynamically by its standard
2336+ * name and get this function from there. This is the default behavior.
2337+ *
2338+ * The standard name of the loader is `vulkan-1.dll` on Windows, `libvulkan.so.1` on
2339+ * Linux and other Unix-like systems and `libvulkan.1.dylib` on macOS. If your code is
2340+ * also loading it via these names then you probably don't need to use this function.
2341+ *
2342+ * The function address you set is never reset by GLFW, but it only takes effect during
2343+ * initialization. Once GLFW has been initialized, any updates will be ignored until the
2344+ * library is terminated and initialized again.
2345+ *
2346+ * @param[in] loader The address of the function to use, or `NULL`.
2347+ *
2348+ * @par Loader function signature
2349+ * @code
2350+ * PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance instance, const char* name)
2351+ * @endcode
2352+ * For more information about this function, see the
2353+ * [Vulkan Registry](https://www.khronos.org/registry/vulkan/).
2354+ *
2355+ * @errors None.
2356+ *
2357+ * @remark This function may be called before @ref glfwInit.
2358+ *
2359+ * @thread_safety This function must only be called from the main thread.
2360+ *
2361+ * @sa @ref vulkan_loader
2362+ * @sa @ref glfwInit
2363+ *
2364+ * @since Added in version 3.4.
2365+ *
2366+ * @ingroup init
2367+ */
2368+GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader);
2369+
2370+#endif /*VK_VERSION_1_0*/
2371+
2372+/*! @brief Retrieves the version of the GLFW library.
2373+ *
2374+ * This function retrieves the major, minor and revision numbers of the GLFW
2375+ * library. It is intended for when you are using GLFW as a shared library and
2376+ * want to ensure that you are using the minimum required version.
2377+ *
2378+ * Any or all of the version arguments may be `NULL`.
2379+ *
2380+ * @param[out] major Where to store the major version number, or `NULL`.
2381+ * @param[out] minor Where to store the minor version number, or `NULL`.
2382+ * @param[out] rev Where to store the revision number, or `NULL`.
2383+ *
2384+ * @errors None.
2385+ *
2386+ * @remark This function may be called before @ref glfwInit.
2387+ *
2388+ * @thread_safety This function may be called from any thread.
2389+ *
2390+ * @sa @ref intro_version
2391+ * @sa @ref glfwGetVersionString
2392+ *
2393+ * @since Added in version 1.0.
2394+ *
2395+ * @ingroup init
2396+ */
2397+GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
2398+
2399+/*! @brief Returns a string describing the compile-time configuration.
2400+ *
2401+ * This function returns the compile-time generated
2402+ * [version string](@ref intro_version_string) of the GLFW library binary. It describes
2403+ * the version, platforms, compiler and any platform or operating system specific
2404+ * compile-time options. It should not be confused with the OpenGL or OpenGL ES version
2405+ * string, queried with `glGetString`.
2406+ *
2407+ * __Do not use the version string__ to parse the GLFW library version. The
2408+ * @ref glfwGetVersion function provides the version of the running library
2409+ * binary in numerical format.
2410+ *
2411+ * __Do not use the version string__ to parse what platforms are supported. The @ref
2412+ * glfwPlatformSupported function lets you query platform support.
2413+ *
2414+ * @return The ASCII encoded GLFW version string.
2415+ *
2416+ * @errors None.
2417+ *
2418+ * @remark This function may be called before @ref glfwInit.
2419+ *
2420+ * @pointer_lifetime The returned string is static and compile-time generated.
2421+ *
2422+ * @thread_safety This function may be called from any thread.
2423+ *
2424+ * @sa @ref intro_version
2425+ * @sa @ref glfwGetVersion
2426+ *
2427+ * @since Added in version 3.0.
2428+ *
2429+ * @ingroup init
2430+ */
2431+GLFWAPI const char* glfwGetVersionString(void);
2432+
2433+/*! @brief Returns and clears the last error for the calling thread.
2434+ *
2435+ * This function returns and clears the [error code](@ref errors) of the last
2436+ * error that occurred on the calling thread, and optionally a UTF-8 encoded
2437+ * human-readable description of it. If no error has occurred since the last
2438+ * call, it returns @ref GLFW_NO_ERROR (zero) and the description pointer is
2439+ * set to `NULL`.
2440+ *
2441+ * @param[in] description Where to store the error description pointer, or `NULL`.
2442+ * @return The last error code for the calling thread, or @ref GLFW_NO_ERROR
2443+ * (zero).
2444+ *
2445+ * @errors None.
2446+ *
2447+ * @pointer_lifetime The returned string is allocated and freed by GLFW. You
2448+ * should not free it yourself. It is guaranteed to be valid only until the
2449+ * next error occurs or the library is terminated.
2450+ *
2451+ * @remark This function may be called before @ref glfwInit.
2452+ *
2453+ * @thread_safety This function may be called from any thread.
2454+ *
2455+ * @sa @ref error_handling
2456+ * @sa @ref glfwSetErrorCallback
2457+ *
2458+ * @since Added in version 3.3.
2459+ *
2460+ * @ingroup init
2461+ */
2462+GLFWAPI int glfwGetError(const char** description);
2463+
2464+/*! @brief Sets the error callback.
2465+ *
2466+ * This function sets the error callback, which is called with an error code
2467+ * and a human-readable description each time a GLFW error occurs.
2468+ *
2469+ * The error code is set before the callback is called. Calling @ref
2470+ * glfwGetError from the error callback will return the same value as the error
2471+ * code argument.
2472+ *
2473+ * The error callback is called on the thread where the error occurred. If you
2474+ * are using GLFW from multiple threads, your error callback needs to be
2475+ * written accordingly.
2476+ *
2477+ * Because the description string may have been generated specifically for that
2478+ * error, it is not guaranteed to be valid after the callback has returned. If
2479+ * you wish to use it after the callback returns, you need to make a copy.
2480+ *
2481+ * Once set, the error callback remains set even after the library has been
2482+ * terminated.
2483+ *
2484+ * @param[in] callback The new callback, or `NULL` to remove the currently set
2485+ * callback.
2486+ * @return The previously set callback, or `NULL` if no callback was set.
2487+ *
2488+ * @callback_signature
2489+ * @code
2490+ * void callback_name(int error_code, const char* description)
2491+ * @endcode
2492+ * For more information about the callback parameters, see the
2493+ * [callback pointer type](@ref GLFWerrorfun).
2494+ *
2495+ * @errors None.
2496+ *
2497+ * @remark This function may be called before @ref glfwInit.
2498+ *
2499+ * @thread_safety This function must only be called from the main thread.
2500+ *
2501+ * @sa @ref error_handling
2502+ * @sa @ref glfwGetError
2503+ *
2504+ * @since Added in version 3.0.
2505+ *
2506+ * @ingroup init
2507+ */
2508+GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun callback);
2509+
2510+/*! @brief Returns the currently selected platform.
2511+ *
2512+ * This function returns the platform that was selected during initialization. The
2513+ * returned value will be one of `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`,
2514+ * `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` or `GLFW_PLATFORM_NULL`.
2515+ *
2516+ * @return The currently selected platform, or zero if an error occurred.
2517+ *
2518+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
2519+ *
2520+ * @thread_safety This function may be called from any thread.
2521+ *
2522+ * @sa @ref platform
2523+ * @sa @ref glfwPlatformSupported
2524+ *
2525+ * @since Added in version 3.4.
2526+ *
2527+ * @ingroup init
2528+ */
2529+GLFWAPI int glfwGetPlatform(void);
2530+
2531+/*! @brief Returns whether the library includes support for the specified platform.
2532+ *
2533+ * This function returns whether the library was compiled with support for the specified
2534+ * platform. The platform must be one of `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`,
2535+ * `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` or `GLFW_PLATFORM_NULL`.
2536+ *
2537+ * @param[in] platform The platform to query.
2538+ * @return `GLFW_TRUE` if the platform is supported, or `GLFW_FALSE` otherwise.
2539+ *
2540+ * @errors Possible errors include @ref GLFW_INVALID_ENUM.
2541+ *
2542+ * @remark This function may be called before @ref glfwInit.
2543+ *
2544+ * @thread_safety This function may be called from any thread.
2545+ *
2546+ * @sa @ref platform
2547+ * @sa @ref glfwGetPlatform
2548+ *
2549+ * @since Added in version 3.4.
2550+ *
2551+ * @ingroup init
2552+ */
2553+GLFWAPI int glfwPlatformSupported(int platform);
2554+
2555+/*! @brief Returns the currently connected monitors.
2556+ *
2557+ * This function returns an array of handles for all currently connected
2558+ * monitors. The primary monitor is always first in the returned array. If no
2559+ * monitors were found, this function returns `NULL`.
2560+ *
2561+ * @param[out] count Where to store the number of monitors in the returned
2562+ * array. This is set to zero if an error occurred.
2563+ * @return An array of monitor handles, or `NULL` if no monitors were found or
2564+ * if an [error](@ref error_handling) occurred.
2565+ *
2566+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
2567+ *
2568+ * @pointer_lifetime The returned array is allocated and freed by GLFW. You
2569+ * should not free it yourself. It is guaranteed to be valid only until the
2570+ * monitor configuration changes or the library is terminated.
2571+ *
2572+ * @thread_safety This function must only be called from the main thread.
2573+ *
2574+ * @sa @ref monitor_monitors
2575+ * @sa @ref monitor_event
2576+ * @sa @ref glfwGetPrimaryMonitor
2577+ *
2578+ * @since Added in version 3.0.
2579+ *
2580+ * @ingroup monitor
2581+ */
2582+GLFWAPI GLFWmonitor** glfwGetMonitors(int* count);
2583+
2584+/*! @brief Returns the primary monitor.
2585+ *
2586+ * This function returns the primary monitor. This is usually the monitor
2587+ * where elements like the task bar or global menu bar are located.
2588+ *
2589+ * @return The primary monitor, or `NULL` if no monitors were found or if an
2590+ * [error](@ref error_handling) occurred.
2591+ *
2592+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
2593+ *
2594+ * @thread_safety This function must only be called from the main thread.
2595+ *
2596+ * @remark The primary monitor is always first in the array returned by @ref
2597+ * glfwGetMonitors.
2598+ *
2599+ * @sa @ref monitor_monitors
2600+ * @sa @ref glfwGetMonitors
2601+ *
2602+ * @since Added in version 3.0.
2603+ *
2604+ * @ingroup monitor
2605+ */
2606+GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void);
2607+
2608+/*! @brief Returns the position of the monitor's viewport on the virtual screen.
2609+ *
2610+ * This function returns the position, in screen coordinates, of the upper-left
2611+ * corner of the specified monitor.
2612+ *
2613+ * Any or all of the position arguments may be `NULL`. If an error occurs, all
2614+ * non-`NULL` position arguments will be set to zero.
2615+ *
2616+ * @param[in] monitor The monitor to query.
2617+ * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`.
2618+ * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`.
2619+ *
2620+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
2621+ * GLFW_PLATFORM_ERROR.
2622+ *
2623+ * @thread_safety This function must only be called from the main thread.
2624+ *
2625+ * @sa @ref monitor_properties
2626+ *
2627+ * @since Added in version 3.0.
2628+ *
2629+ * @ingroup monitor
2630+ */
2631+GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);
2632+
2633+/*! @brief Retrieves the work area of the monitor.
2634+ *
2635+ * This function returns the position, in screen coordinates, of the upper-left
2636+ * corner of the work area of the specified monitor along with the work area
2637+ * size in screen coordinates. The work area is defined as the area of the
2638+ * monitor not occluded by the window system task bar where present. If no
2639+ * task bar exists then the work area is the monitor resolution in screen
2640+ * coordinates.
2641+ *
2642+ * Any or all of the position and size arguments may be `NULL`. If an error
2643+ * occurs, all non-`NULL` position and size arguments will be set to zero.
2644+ *
2645+ * @param[in] monitor The monitor to query.
2646+ * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`.
2647+ * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`.
2648+ * @param[out] width Where to store the monitor width, or `NULL`.
2649+ * @param[out] height Where to store the monitor height, or `NULL`.
2650+ *
2651+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
2652+ * GLFW_PLATFORM_ERROR.
2653+ *
2654+ * @thread_safety This function must only be called from the main thread.
2655+ *
2656+ * @sa @ref monitor_workarea
2657+ *
2658+ * @since Added in version 3.3.
2659+ *
2660+ * @ingroup monitor
2661+ */
2662+GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
2663+
2664+/*! @brief Returns the physical size of the monitor.
2665+ *
2666+ * This function returns the size, in millimetres, of the display area of the
2667+ * specified monitor.
2668+ *
2669+ * Some platforms do not provide accurate monitor size information, either
2670+ * because the monitor [EDID][] data is incorrect or because the driver does
2671+ * not report it accurately.
2672+ *
2673+ * [EDID]: https://en.wikipedia.org/wiki/Extended_display_identification_data
2674+ *
2675+ * Any or all of the size arguments may be `NULL`. If an error occurs, all
2676+ * non-`NULL` size arguments will be set to zero.
2677+ *
2678+ * @param[in] monitor The monitor to query.
2679+ * @param[out] widthMM Where to store the width, in millimetres, of the
2680+ * monitor's display area, or `NULL`.
2681+ * @param[out] heightMM Where to store the height, in millimetres, of the
2682+ * monitor's display area, or `NULL`.
2683+ *
2684+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
2685+ *
2686+ * @remark __Win32:__ On Windows 8 and earlier the physical size is calculated from
2687+ * the current resolution and system DPI instead of querying the monitor EDID data.
2688+ *
2689+ * @thread_safety This function must only be called from the main thread.
2690+ *
2691+ * @sa @ref monitor_properties
2692+ *
2693+ * @since Added in version 3.0.
2694+ *
2695+ * @ingroup monitor
2696+ */
2697+GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM);
2698+
2699+/*! @brief Retrieves the content scale for the specified monitor.
2700+ *
2701+ * This function retrieves the content scale for the specified monitor. The
2702+ * content scale is the ratio between the current DPI and the platform's
2703+ * default DPI. This is especially important for text and any UI elements. If
2704+ * the pixel dimensions of your UI scaled by this look appropriate on your
2705+ * machine then it should appear at a reasonable size on other machines
2706+ * regardless of their DPI and scaling settings. This relies on the system DPI
2707+ * and scaling settings being somewhat correct.
2708+ *
2709+ * The content scale may depend on both the monitor resolution and pixel
2710+ * density and on user settings. It may be very different from the raw DPI
2711+ * calculated from the physical size and current resolution.
2712+ *
2713+ * @param[in] monitor The monitor to query.
2714+ * @param[out] xscale Where to store the x-axis content scale, or `NULL`.
2715+ * @param[out] yscale Where to store the y-axis content scale, or `NULL`.
2716+ *
2717+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
2718+ * GLFW_PLATFORM_ERROR.
2719+ *
2720+ * @remark __Wayland:__ Fractional scaling information is not yet available for
2721+ * monitors, so this function only returns integer content scales.
2722+ *
2723+ * @thread_safety This function must only be called from the main thread.
2724+ *
2725+ * @sa @ref monitor_scale
2726+ * @sa @ref glfwGetWindowContentScale
2727+ *
2728+ * @since Added in version 3.3.
2729+ *
2730+ * @ingroup monitor
2731+ */
2732+GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* monitor, float* xscale, float* yscale);
2733+
2734+/*! @brief Returns the name of the specified monitor.
2735+ *
2736+ * This function returns a human-readable name, encoded as UTF-8, of the
2737+ * specified monitor. The name typically reflects the make and model of the
2738+ * monitor and is not guaranteed to be unique among the connected monitors.
2739+ *
2740+ * @param[in] monitor The monitor to query.
2741+ * @return The UTF-8 encoded name of the monitor, or `NULL` if an
2742+ * [error](@ref error_handling) occurred.
2743+ *
2744+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
2745+ *
2746+ * @pointer_lifetime The returned string is allocated and freed by GLFW. You
2747+ * should not free it yourself. It is valid until the specified monitor is
2748+ * disconnected or the library is terminated.
2749+ *
2750+ * @thread_safety This function must only be called from the main thread.
2751+ *
2752+ * @sa @ref monitor_properties
2753+ *
2754+ * @since Added in version 3.0.
2755+ *
2756+ * @ingroup monitor
2757+ */
2758+GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);
2759+
2760+/*! @brief Sets the user pointer of the specified monitor.
2761+ *
2762+ * This function sets the user-defined pointer of the specified monitor. The
2763+ * current value is retained until the monitor is disconnected. The initial
2764+ * value is `NULL`.
2765+ *
2766+ * This function may be called from the monitor callback, even for a monitor
2767+ * that is being disconnected.
2768+ *
2769+ * @param[in] monitor The monitor whose pointer to set.
2770+ * @param[in] pointer The new value.
2771+ *
2772+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
2773+ *
2774+ * @thread_safety This function may be called from any thread. Access is not
2775+ * synchronized.
2776+ *
2777+ * @sa @ref monitor_userptr
2778+ * @sa @ref glfwGetMonitorUserPointer
2779+ *
2780+ * @since Added in version 3.3.
2781+ *
2782+ * @ingroup monitor
2783+ */
2784+GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* monitor, void* pointer);
2785+
2786+/*! @brief Returns the user pointer of the specified monitor.
2787+ *
2788+ * This function returns the current value of the user-defined pointer of the
2789+ * specified monitor. The initial value is `NULL`.
2790+ *
2791+ * This function may be called from the monitor callback, even for a monitor
2792+ * that is being disconnected.
2793+ *
2794+ * @param[in] monitor The monitor whose pointer to return.
2795+ *
2796+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
2797+ *
2798+ * @thread_safety This function may be called from any thread. Access is not
2799+ * synchronized.
2800+ *
2801+ * @sa @ref monitor_userptr
2802+ * @sa @ref glfwSetMonitorUserPointer
2803+ *
2804+ * @since Added in version 3.3.
2805+ *
2806+ * @ingroup monitor
2807+ */
2808+GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* monitor);
2809+
2810+/*! @brief Sets the monitor configuration callback.
2811+ *
2812+ * This function sets the monitor configuration callback, or removes the
2813+ * currently set callback. This is called when a monitor is connected to or
2814+ * disconnected from the system.
2815+ *
2816+ * @param[in] callback The new callback, or `NULL` to remove the currently set
2817+ * callback.
2818+ * @return The previously set callback, or `NULL` if no callback was set or the
2819+ * library had not been [initialized](@ref intro_init).
2820+ *
2821+ * @callback_signature
2822+ * @code
2823+ * void function_name(GLFWmonitor* monitor, int event)
2824+ * @endcode
2825+ * For more information about the callback parameters, see the
2826+ * [function pointer type](@ref GLFWmonitorfun).
2827+ *
2828+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
2829+ *
2830+ * @thread_safety This function must only be called from the main thread.
2831+ *
2832+ * @sa @ref monitor_event
2833+ *
2834+ * @since Added in version 3.0.
2835+ *
2836+ * @ingroup monitor
2837+ */
2838+GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun callback);
2839+
2840+/*! @brief Returns the available video modes for the specified monitor.
2841+ *
2842+ * This function returns an array of all video modes supported by the specified
2843+ * monitor. The returned array is sorted in ascending order, first by color
2844+ * bit depth (the sum of all channel depths), then by resolution area (the
2845+ * product of width and height), then resolution width and finally by refresh
2846+ * rate.
2847+ *
2848+ * @param[in] monitor The monitor to query.
2849+ * @param[out] count Where to store the number of video modes in the returned
2850+ * array. This is set to zero if an error occurred.
2851+ * @return An array of video modes, or `NULL` if an
2852+ * [error](@ref error_handling) occurred.
2853+ *
2854+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
2855+ * GLFW_PLATFORM_ERROR.
2856+ *
2857+ * @pointer_lifetime The returned array is allocated and freed by GLFW. You
2858+ * should not free it yourself. It is valid until the specified monitor is
2859+ * disconnected, this function is called again for that monitor or the library
2860+ * is terminated.
2861+ *
2862+ * @thread_safety This function must only be called from the main thread.
2863+ *
2864+ * @sa @ref monitor_modes
2865+ * @sa @ref glfwGetVideoMode
2866+ *
2867+ * @since Added in version 1.0.
2868+ * __GLFW 3:__ Changed to return an array of modes for a specific monitor.
2869+ *
2870+ * @ingroup monitor
2871+ */
2872+GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);
2873+
2874+/*! @brief Returns the current mode of the specified monitor.
2875+ *
2876+ * This function returns the current video mode of the specified monitor. If
2877+ * you have created a full screen window for that monitor, the return value
2878+ * will depend on whether that window is iconified.
2879+ *
2880+ * @param[in] monitor The monitor to query.
2881+ * @return The current mode of the monitor, or `NULL` if an
2882+ * [error](@ref error_handling) occurred.
2883+ *
2884+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
2885+ * GLFW_PLATFORM_ERROR.
2886+ *
2887+ * @pointer_lifetime The returned array is allocated and freed by GLFW. You
2888+ * should not free it yourself. It is valid until the specified monitor is
2889+ * disconnected or the library is terminated.
2890+ *
2891+ * @thread_safety This function must only be called from the main thread.
2892+ *
2893+ * @sa @ref monitor_modes
2894+ * @sa @ref glfwGetVideoModes
2895+ *
2896+ * @since Added in version 3.0. Replaces `glfwGetDesktopMode`.
2897+ *
2898+ * @ingroup monitor
2899+ */
2900+GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
2901+
2902+/*! @brief Generates a gamma ramp and sets it for the specified monitor.
2903+ *
2904+ * This function generates an appropriately sized gamma ramp from the specified
2905+ * exponent and then calls @ref glfwSetGammaRamp with it. The value must be
2906+ * a finite number greater than zero.
2907+ *
2908+ * The software controlled gamma ramp is applied _in addition_ to the hardware
2909+ * gamma correction, which today is usually an approximation of sRGB gamma.
2910+ * This means that setting a perfectly linear ramp, or gamma 1.0, will produce
2911+ * the default (usually sRGB-like) behavior.
2912+ *
2913+ * For gamma correct rendering with OpenGL or OpenGL ES, see the @ref
2914+ * GLFW_SRGB_CAPABLE hint.
2915+ *
2916+ * @param[in] monitor The monitor whose gamma ramp to set.
2917+ * @param[in] gamma The desired exponent.
2918+ *
2919+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_INVALID_VALUE,
2920+ * @ref GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
2921+ *
2922+ * @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
2923+ * cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
2924+ *
2925+ * @thread_safety This function must only be called from the main thread.
2926+ *
2927+ * @sa @ref monitor_gamma
2928+ *
2929+ * @since Added in version 3.0.
2930+ *
2931+ * @ingroup monitor
2932+ */
2933+GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
2934+
2935+/*! @brief Returns the current gamma ramp for the specified monitor.
2936+ *
2937+ * This function returns the current gamma ramp of the specified monitor.
2938+ *
2939+ * @param[in] monitor The monitor to query.
2940+ * @return The current gamma ramp, or `NULL` if an
2941+ * [error](@ref error_handling) occurred.
2942+ *
2943+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR
2944+ * and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
2945+ *
2946+ * @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
2947+ * cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while
2948+ * returning `NULL`.
2949+ *
2950+ * @pointer_lifetime The returned structure and its arrays are allocated and
2951+ * freed by GLFW. You should not free them yourself. They are valid until the
2952+ * specified monitor is disconnected, this function is called again for that
2953+ * monitor or the library is terminated.
2954+ *
2955+ * @thread_safety This function must only be called from the main thread.
2956+ *
2957+ * @sa @ref monitor_gamma
2958+ *
2959+ * @since Added in version 3.0.
2960+ *
2961+ * @ingroup monitor
2962+ */
2963+GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
2964+
2965+/*! @brief Sets the current gamma ramp for the specified monitor.
2966+ *
2967+ * This function sets the current gamma ramp for the specified monitor. The
2968+ * original gamma ramp for that monitor is saved by GLFW the first time this
2969+ * function is called and is restored by @ref glfwTerminate.
2970+ *
2971+ * The software controlled gamma ramp is applied _in addition_ to the hardware
2972+ * gamma correction, which today is usually an approximation of sRGB gamma.
2973+ * This means that setting a perfectly linear ramp, or gamma 1.0, will produce
2974+ * the default (usually sRGB-like) behavior.
2975+ *
2976+ * For gamma correct rendering with OpenGL or OpenGL ES, see the @ref
2977+ * GLFW_SRGB_CAPABLE hint.
2978+ *
2979+ * @param[in] monitor The monitor whose gamma ramp to set.
2980+ * @param[in] ramp The gamma ramp to use.
2981+ *
2982+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR
2983+ * and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
2984+ *
2985+ * @remark The size of the specified gamma ramp should match the size of the
2986+ * current ramp for that monitor.
2987+ *
2988+ * @remark __Win32:__ The gamma ramp size must be 256.
2989+ *
2990+ * @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
2991+ * cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
2992+ *
2993+ * @pointer_lifetime The specified gamma ramp is copied before this function
2994+ * returns.
2995+ *
2996+ * @thread_safety This function must only be called from the main thread.
2997+ *
2998+ * @sa @ref monitor_gamma
2999+ *
3000+ * @since Added in version 3.0.
3001+ *
3002+ * @ingroup monitor
3003+ */
3004+GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);
3005+
3006+/*! @brief Resets all window hints to their default values.
3007+ *
3008+ * This function resets all window hints to their
3009+ * [default values](@ref window_hints_values).
3010+ *
3011+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
3012+ *
3013+ * @thread_safety This function must only be called from the main thread.
3014+ *
3015+ * @sa @ref window_hints
3016+ * @sa @ref glfwWindowHint
3017+ * @sa @ref glfwWindowHintString
3018+ *
3019+ * @since Added in version 3.0.
3020+ *
3021+ * @ingroup window
3022+ */
3023+GLFWAPI void glfwDefaultWindowHints(void);
3024+
3025+/*! @brief Sets the specified window hint to the desired value.
3026+ *
3027+ * This function sets hints for the next call to @ref glfwCreateWindow. The
3028+ * hints, once set, retain their values until changed by a call to this
3029+ * function or @ref glfwDefaultWindowHints, or until the library is terminated.
3030+ *
3031+ * Only integer value hints can be set with this function. String value hints
3032+ * are set with @ref glfwWindowHintString.
3033+ *
3034+ * This function does not check whether the specified hint values are valid.
3035+ * If you set hints to invalid values this will instead be reported by the next
3036+ * call to @ref glfwCreateWindow.
3037+ *
3038+ * Some hints are platform specific. These may be set on any platform but they
3039+ * will only affect their specific platform. Other platforms will ignore them.
3040+ * Setting these hints requires no platform specific headers or functions.
3041+ *
3042+ * @param[in] hint The [window hint](@ref window_hints) to set.
3043+ * @param[in] value The new value of the window hint.
3044+ *
3045+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3046+ * GLFW_INVALID_ENUM.
3047+ *
3048+ * @thread_safety This function must only be called from the main thread.
3049+ *
3050+ * @sa @ref window_hints
3051+ * @sa @ref glfwWindowHintString
3052+ * @sa @ref glfwDefaultWindowHints
3053+ *
3054+ * @since Added in version 3.0. Replaces `glfwOpenWindowHint`.
3055+ *
3056+ * @ingroup window
3057+ */
3058+GLFWAPI void glfwWindowHint(int hint, int value);
3059+
3060+/*! @brief Sets the specified window hint to the desired value.
3061+ *
3062+ * This function sets hints for the next call to @ref glfwCreateWindow. The
3063+ * hints, once set, retain their values until changed by a call to this
3064+ * function or @ref glfwDefaultWindowHints, or until the library is terminated.
3065+ *
3066+ * Only string type hints can be set with this function. Integer value hints
3067+ * are set with @ref glfwWindowHint.
3068+ *
3069+ * This function does not check whether the specified hint values are valid.
3070+ * If you set hints to invalid values this will instead be reported by the next
3071+ * call to @ref glfwCreateWindow.
3072+ *
3073+ * Some hints are platform specific. These may be set on any platform but they
3074+ * will only affect their specific platform. Other platforms will ignore them.
3075+ * Setting these hints requires no platform specific headers or functions.
3076+ *
3077+ * @param[in] hint The [window hint](@ref window_hints) to set.
3078+ * @param[in] value The new value of the window hint.
3079+ *
3080+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3081+ * GLFW_INVALID_ENUM.
3082+ *
3083+ * @pointer_lifetime The specified string is copied before this function
3084+ * returns.
3085+ *
3086+ * @thread_safety This function must only be called from the main thread.
3087+ *
3088+ * @sa @ref window_hints
3089+ * @sa @ref glfwWindowHint
3090+ * @sa @ref glfwDefaultWindowHints
3091+ *
3092+ * @since Added in version 3.3.
3093+ *
3094+ * @ingroup window
3095+ */
3096+GLFWAPI void glfwWindowHintString(int hint, const char* value);
3097+
3098+/*! @brief Creates a window and its associated context.
3099+ *
3100+ * This function creates a window and its associated OpenGL or OpenGL ES
3101+ * context. Most of the options controlling how the window and its context
3102+ * should be created are specified with [window hints](@ref window_hints).
3103+ *
3104+ * Successful creation does not change which context is current. Before you
3105+ * can use the newly created context, you need to
3106+ * [make it current](@ref context_current). For information about the `share`
3107+ * parameter, see @ref context_sharing.
3108+ *
3109+ * The created window, framebuffer and context may differ from what you
3110+ * requested, as not all parameters and hints are
3111+ * [hard constraints](@ref window_hints_hard). This includes the size of the
3112+ * window, especially for full screen windows. To query the actual attributes
3113+ * of the created window, framebuffer and context, see @ref
3114+ * glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize.
3115+ *
3116+ * To create a full screen window, you need to specify the monitor the window
3117+ * will cover. If no monitor is specified, the window will be windowed mode.
3118+ * Unless you have a way for the user to choose a specific monitor, it is
3119+ * recommended that you pick the primary monitor. For more information on how
3120+ * to query connected monitors, see @ref monitor_monitors.
3121+ *
3122+ * For full screen windows, the specified size becomes the resolution of the
3123+ * window's _desired video mode_. As long as a full screen window is not
3124+ * iconified, the supported video mode most closely matching the desired video
3125+ * mode is set for the specified monitor. For more information about full
3126+ * screen windows, including the creation of so called _windowed full screen_
3127+ * or _borderless full screen_ windows, see @ref window_windowed_full_screen.
3128+ *
3129+ * Once you have created the window, you can switch it between windowed and
3130+ * full screen mode with @ref glfwSetWindowMonitor. This will not affect its
3131+ * OpenGL or OpenGL ES context.
3132+ *
3133+ * By default, newly created windows use the placement recommended by the
3134+ * window system. To create the window at a specific position, set the @ref
3135+ * GLFW_POSITION_X and @ref GLFW_POSITION_Y window hints before creation. To
3136+ * restore the default behavior, set either or both hints back to
3137+ * `GLFW_ANY_POSITION`.
3138+ *
3139+ * As long as at least one full screen window is not iconified, the screensaver
3140+ * is prohibited from starting.
3141+ *
3142+ * Window systems put limits on window sizes. Very large or very small window
3143+ * dimensions may be overridden by the window system on creation. Check the
3144+ * actual [size](@ref window_size) after creation.
3145+ *
3146+ * The [swap interval](@ref buffer_swap) is not set during window creation and
3147+ * the initial value may vary depending on driver settings and defaults.
3148+ *
3149+ * @param[in] width The desired width, in screen coordinates, of the window.
3150+ * This must be greater than zero.
3151+ * @param[in] height The desired height, in screen coordinates, of the window.
3152+ * This must be greater than zero.
3153+ * @param[in] title The initial, UTF-8 encoded window title.
3154+ * @param[in] monitor The monitor to use for full screen mode, or `NULL` for
3155+ * windowed mode.
3156+ * @param[in] share The window whose context to share resources with, or `NULL`
3157+ * to not share resources.
3158+ * @return The handle of the created window, or `NULL` if an
3159+ * [error](@ref error_handling) occurred.
3160+ *
3161+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
3162+ * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref
3163+ * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE, @ref
3164+ * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
3165+ *
3166+ * @remark __Win32:__ Window creation will fail if the Microsoft GDI software
3167+ * OpenGL implementation is the only one available.
3168+ *
3169+ * @remark __Win32:__ If the executable has an icon resource named `GLFW_ICON,` it
3170+ * will be set as the initial icon for the window. If no such icon is present,
3171+ * the `IDI_APPLICATION` icon will be used instead. To set a different icon,
3172+ * see @ref glfwSetWindowIcon.
3173+ *
3174+ * @remark __Win32:__ The context to share resources with must not be current on
3175+ * any other thread.
3176+ *
3177+ * @remark __macOS:__ The OS only supports core profile contexts for OpenGL
3178+ * versions 3.2 and later. Before creating an OpenGL context of version 3.2 or
3179+ * later you must set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint)
3180+ * hint accordingly. OpenGL 3.0 and 3.1 contexts are not supported at all
3181+ * on macOS.
3182+ *
3183+ * @remark __macOS:__ The GLFW window has no icon, as it is not a document
3184+ * window, but the dock icon will be the same as the application bundle's icon.
3185+ * For more information on bundles, see the
3186+ * [Bundle Programming Guide][bundle-guide] in the Mac Developer Library.
3187+ *
3188+ * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/
3189+ *
3190+ * @remark __macOS:__ The window frame will not be rendered at full resolution
3191+ * on Retina displays unless the
3192+ * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint)
3193+ * hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the
3194+ * application bundle's `Info.plist`. For more information, see
3195+ * [High Resolution Guidelines for OS X][hidpi-guide] in the Mac Developer
3196+ * Library. The GLFW test and example programs use a custom `Info.plist`
3197+ * template for this, which can be found as `CMake/Info.plist.in` in the source
3198+ * tree.
3199+ *
3200+ * [hidpi-guide]: https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
3201+ *
3202+ * @remark __macOS:__ When activating frame autosaving with
3203+ * [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified
3204+ * window size and position may be overridden by previously saved values.
3205+ *
3206+ * @remark __Wayland:__ GLFW uses [libdecor][] where available to create its window
3207+ * decorations. This in turn uses server-side XDG decorations where available
3208+ * and provides high quality client-side decorations on compositors like GNOME.
3209+ * If both XDG decorations and libdecor are unavailable, GLFW falls back to
3210+ * a very simple set of window decorations that only support moving, resizing
3211+ * and the window manager's right-click menu.
3212+ *
3213+ * [libdecor]: https://gitlab.freedesktop.org/libdecor/libdecor
3214+ *
3215+ * @remark __X11:__ Some window managers will not respect the placement of
3216+ * initially hidden windows.
3217+ *
3218+ * @remark __X11:__ Due to the asynchronous nature of X11, it may take a moment for
3219+ * a window to reach its requested state. This means you may not be able to
3220+ * query the final size, position or other attributes directly after window
3221+ * creation.
3222+ *
3223+ * @remark __X11:__ The class part of the `WM_CLASS` window property will by
3224+ * default be set to the window title passed to this function. The instance
3225+ * part will use the contents of the `RESOURCE_NAME` environment variable, if
3226+ * present and not empty, or fall back to the window title. Set the
3227+ * [GLFW_X11_CLASS_NAME](@ref GLFW_X11_CLASS_NAME_hint) and
3228+ * [GLFW_X11_INSTANCE_NAME](@ref GLFW_X11_INSTANCE_NAME_hint) window hints to
3229+ * override this.
3230+ *
3231+ * @thread_safety This function must only be called from the main thread.
3232+ *
3233+ * @sa @ref window_creation
3234+ * @sa @ref glfwDestroyWindow
3235+ *
3236+ * @since Added in version 3.0. Replaces `glfwOpenWindow`.
3237+ *
3238+ * @ingroup window
3239+ */
3240+GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
3241+
3242+/*! @brief Destroys the specified window and its context.
3243+ *
3244+ * This function destroys the specified window and its context. On calling
3245+ * this function, no further callbacks will be called for that window.
3246+ *
3247+ * If the context of the specified window is current on the main thread, it is
3248+ * detached before being destroyed.
3249+ *
3250+ * @param[in] window The window to destroy.
3251+ *
3252+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3253+ * GLFW_PLATFORM_ERROR.
3254+ *
3255+ * @note The context of the specified window must not be current on any other
3256+ * thread when this function is called.
3257+ *
3258+ * @reentrancy This function must not be called from a callback.
3259+ *
3260+ * @thread_safety This function must only be called from the main thread.
3261+ *
3262+ * @sa @ref window_creation
3263+ * @sa @ref glfwCreateWindow
3264+ *
3265+ * @since Added in version 3.0. Replaces `glfwCloseWindow`.
3266+ *
3267+ * @ingroup window
3268+ */
3269+GLFWAPI void glfwDestroyWindow(GLFWwindow* window);
3270+
3271+/*! @brief Checks the close flag of the specified window.
3272+ *
3273+ * This function returns the value of the close flag of the specified window.
3274+ *
3275+ * @param[in] window The window to query.
3276+ * @return The value of the close flag.
3277+ *
3278+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
3279+ *
3280+ * @thread_safety This function may be called from any thread. Access is not
3281+ * synchronized.
3282+ *
3283+ * @sa @ref window_close
3284+ *
3285+ * @since Added in version 3.0.
3286+ *
3287+ * @ingroup window
3288+ */
3289+GLFWAPI int glfwWindowShouldClose(GLFWwindow* window);
3290+
3291+/*! @brief Sets the close flag of the specified window.
3292+ *
3293+ * This function sets the value of the close flag of the specified window.
3294+ * This can be used to override the user's attempt to close the window, or
3295+ * to signal that it should be closed.
3296+ *
3297+ * @param[in] window The window whose flag to change.
3298+ * @param[in] value The new value.
3299+ *
3300+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
3301+ *
3302+ * @thread_safety This function may be called from any thread. Access is not
3303+ * synchronized.
3304+ *
3305+ * @sa @ref window_close
3306+ *
3307+ * @since Added in version 3.0.
3308+ *
3309+ * @ingroup window
3310+ */
3311+GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);
3312+
3313+/*! @brief Returns the title of the specified window.
3314+ *
3315+ * This function returns the window title, encoded as UTF-8, of the specified
3316+ * window. This is the title set previously by @ref glfwCreateWindow
3317+ * or @ref glfwSetWindowTitle.
3318+ *
3319+ * @param[in] window The window to query.
3320+ * @return The UTF-8 encoded window title, or `NULL` if an
3321+ * [error](@ref error_handling) occurred.
3322+ *
3323+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
3324+ *
3325+ * @remark The returned title is currently a copy of the title last set by @ref
3326+ * glfwCreateWindow or @ref glfwSetWindowTitle. It does not include any
3327+ * additional text which may be appended by the platform or another program.
3328+ *
3329+ * @pointer_lifetime The returned string is allocated and freed by GLFW. You
3330+ * should not free it yourself. It is valid until the next call to @ref
3331+ * glfwGetWindowTitle or @ref glfwSetWindowTitle, or until the library is
3332+ * terminated.
3333+ *
3334+ * @thread_safety This function must only be called from the main thread.
3335+ *
3336+ * @sa @ref window_title
3337+ * @sa @ref glfwSetWindowTitle
3338+ *
3339+ * @since Added in version 3.4.
3340+ *
3341+ * @ingroup window
3342+ */
3343+GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window);
3344+
3345+/*! @brief Sets the title of the specified window.
3346+ *
3347+ * This function sets the window title, encoded as UTF-8, of the specified
3348+ * window.
3349+ *
3350+ * @param[in] window The window whose title to change.
3351+ * @param[in] title The UTF-8 encoded window title.
3352+ *
3353+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3354+ * GLFW_PLATFORM_ERROR.
3355+ *
3356+ * @remark __macOS:__ The window title will not be updated until the next time you
3357+ * process events.
3358+ *
3359+ * @thread_safety This function must only be called from the main thread.
3360+ *
3361+ * @sa @ref window_title
3362+ * @sa @ref glfwGetWindowTitle
3363+ *
3364+ * @since Added in version 1.0.
3365+ * __GLFW 3:__ Added window handle parameter.
3366+ *
3367+ * @ingroup window
3368+ */
3369+GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
3370+
3371+/*! @brief Sets the icon for the specified window.
3372+ *
3373+ * This function sets the icon of the specified window. If passed an array of
3374+ * candidate images, those of or closest to the sizes desired by the system are
3375+ * selected. If no images are specified, the window reverts to its default
3376+ * icon.
3377+ *
3378+ * The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight
3379+ * bits per channel with the red channel first. They are arranged canonically
3380+ * as packed sequential rows, starting from the top-left corner.
3381+ *
3382+ * The desired image sizes varies depending on platform and system settings.
3383+ * The selected images will be rescaled as needed. Good sizes include 16x16,
3384+ * 32x32 and 48x48.
3385+ *
3386+ * @param[in] window The window whose icon to set.
3387+ * @param[in] count The number of images in the specified array, or zero to
3388+ * revert to the default window icon.
3389+ * @param[in] images The images to create the icon from. This is ignored if
3390+ * count is zero.
3391+ *
3392+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
3393+ * GLFW_INVALID_VALUE, @ref GLFW_PLATFORM_ERROR and @ref
3394+ * GLFW_FEATURE_UNAVAILABLE (see remarks).
3395+ *
3396+ * @pointer_lifetime The specified image data is copied before this function
3397+ * returns.
3398+ *
3399+ * @remark __macOS:__ Regular windows do not have icons on macOS. This function
3400+ * will emit @ref GLFW_FEATURE_UNAVAILABLE. The dock icon will be the same as
3401+ * the application bundle's icon. For more information on bundles, see the
3402+ * [Bundle Programming Guide][bundle-guide] in the Mac Developer Library.
3403+ *
3404+ * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/
3405+ *
3406+ * @remark __Wayland:__ There is no existing protocol to change an icon, the
3407+ * window will thus inherit the one defined in the application's desktop file.
3408+ * This function will emit @ref GLFW_FEATURE_UNAVAILABLE.
3409+ *
3410+ * @thread_safety This function must only be called from the main thread.
3411+ *
3412+ * @sa @ref window_icon
3413+ *
3414+ * @since Added in version 3.2.
3415+ *
3416+ * @ingroup window
3417+ */
3418+GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images);
3419+
3420+/*! @brief Retrieves the position of the content area of the specified window.
3421+ *
3422+ * This function retrieves the position, in screen coordinates, of the
3423+ * upper-left corner of the content area of the specified window.
3424+ *
3425+ * Any or all of the position arguments may be `NULL`. If an error occurs, all
3426+ * non-`NULL` position arguments will be set to zero.
3427+ *
3428+ * @param[in] window The window to query.
3429+ * @param[out] xpos Where to store the x-coordinate of the upper-left corner of
3430+ * the content area, or `NULL`.
3431+ * @param[out] ypos Where to store the y-coordinate of the upper-left corner of
3432+ * the content area, or `NULL`.
3433+ *
3434+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
3435+ * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
3436+ *
3437+ * @remark __Wayland:__ Window positions are not currently part of any common
3438+ * Wayland protocol, so this function cannot be implemented and will emit @ref
3439+ * GLFW_FEATURE_UNAVAILABLE.
3440+ *
3441+ * @thread_safety This function must only be called from the main thread.
3442+ *
3443+ * @sa @ref window_pos
3444+ * @sa @ref glfwSetWindowPos
3445+ *
3446+ * @since Added in version 3.0.
3447+ *
3448+ * @ingroup window
3449+ */
3450+GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
3451+
3452+/*! @brief Sets the position of the content area of the specified window.
3453+ *
3454+ * This function sets the position, in screen coordinates, of the upper-left
3455+ * corner of the content area of the specified windowed mode window. If the
3456+ * window is a full screen window, this function does nothing.
3457+ *
3458+ * __Do not use this function__ to move an already visible window unless you
3459+ * have very good reasons for doing so, as it will confuse and annoy the user.
3460+ *
3461+ * The window manager may put limits on what positions are allowed. GLFW
3462+ * cannot and should not override these limits.
3463+ *
3464+ * @param[in] window The window to query.
3465+ * @param[in] xpos The x-coordinate of the upper-left corner of the content area.
3466+ * @param[in] ypos The y-coordinate of the upper-left corner of the content area.
3467+ *
3468+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
3469+ * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
3470+ *
3471+ * @remark __Wayland:__ Window positions are not currently part of any common
3472+ * Wayland protocol, so this function cannot be implemented and will emit @ref
3473+ * GLFW_FEATURE_UNAVAILABLE.
3474+ *
3475+ * @thread_safety This function must only be called from the main thread.
3476+ *
3477+ * @sa @ref window_pos
3478+ * @sa @ref glfwGetWindowPos
3479+ *
3480+ * @since Added in version 1.0.
3481+ * __GLFW 3:__ Added window handle parameter.
3482+ *
3483+ * @ingroup window
3484+ */
3485+GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
3486+
3487+/*! @brief Retrieves the size of the content area of the specified window.
3488+ *
3489+ * This function retrieves the size, in screen coordinates, of the content area
3490+ * of the specified window. If you wish to retrieve the size of the
3491+ * framebuffer of the window in pixels, see @ref glfwGetFramebufferSize.
3492+ *
3493+ * Any or all of the size arguments may be `NULL`. If an error occurs, all
3494+ * non-`NULL` size arguments will be set to zero.
3495+ *
3496+ * @param[in] window The window whose size to retrieve.
3497+ * @param[out] width Where to store the width, in screen coordinates, of the
3498+ * content area, or `NULL`.
3499+ * @param[out] height Where to store the height, in screen coordinates, of the
3500+ * content area, or `NULL`.
3501+ *
3502+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3503+ * GLFW_PLATFORM_ERROR.
3504+ *
3505+ * @thread_safety This function must only be called from the main thread.
3506+ *
3507+ * @sa @ref window_size
3508+ * @sa @ref glfwSetWindowSize
3509+ *
3510+ * @since Added in version 1.0.
3511+ * __GLFW 3:__ Added window handle parameter.
3512+ *
3513+ * @ingroup window
3514+ */
3515+GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
3516+
3517+/*! @brief Sets the size limits of the specified window.
3518+ *
3519+ * This function sets the size limits of the content area of the specified
3520+ * window. If the window is full screen, the size limits only take effect
3521+ * once it is made windowed. If the window is not resizable, this function
3522+ * does nothing.
3523+ *
3524+ * The size limits are applied immediately to a windowed mode window and may
3525+ * cause it to be resized.
3526+ *
3527+ * The maximum dimensions must be greater than or equal to the minimum
3528+ * dimensions and all must be greater than or equal to zero.
3529+ *
3530+ * @param[in] window The window to set limits for.
3531+ * @param[in] minwidth The minimum width, in screen coordinates, of the content
3532+ * area, or `GLFW_DONT_CARE`.
3533+ * @param[in] minheight The minimum height, in screen coordinates, of the
3534+ * content area, or `GLFW_DONT_CARE`.
3535+ * @param[in] maxwidth The maximum width, in screen coordinates, of the content
3536+ * area, or `GLFW_DONT_CARE`.
3537+ * @param[in] maxheight The maximum height, in screen coordinates, of the
3538+ * content area, or `GLFW_DONT_CARE`.
3539+ *
3540+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
3541+ * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
3542+ *
3543+ * @remark If you set size limits and an aspect ratio that conflict, the
3544+ * results are undefined.
3545+ *
3546+ * @remark __Wayland:__ The size limits will not be applied until the window is
3547+ * actually resized, either by the user or by the compositor.
3548+ *
3549+ * @thread_safety This function must only be called from the main thread.
3550+ *
3551+ * @sa @ref window_sizelimits
3552+ * @sa @ref glfwSetWindowAspectRatio
3553+ *
3554+ * @since Added in version 3.2.
3555+ *
3556+ * @ingroup window
3557+ */
3558+GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
3559+
3560+/*! @brief Sets the aspect ratio of the specified window.
3561+ *
3562+ * This function sets the required aspect ratio of the content area of the
3563+ * specified window. If the window is full screen, the aspect ratio only takes
3564+ * effect once it is made windowed. If the window is not resizable, this
3565+ * function does nothing.
3566+ *
3567+ * The aspect ratio is specified as a numerator and a denominator and both
3568+ * values must be greater than zero. For example, the common 16:9 aspect ratio
3569+ * is specified as 16 and 9, respectively.
3570+ *
3571+ * If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect
3572+ * ratio limit is disabled.
3573+ *
3574+ * The aspect ratio is applied immediately to a windowed mode window and may
3575+ * cause it to be resized.
3576+ *
3577+ * @param[in] window The window to set limits for.
3578+ * @param[in] numer The numerator of the desired aspect ratio, or
3579+ * `GLFW_DONT_CARE`.
3580+ * @param[in] denom The denominator of the desired aspect ratio, or
3581+ * `GLFW_DONT_CARE`.
3582+ *
3583+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
3584+ * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
3585+ *
3586+ * @remark If you set size limits and an aspect ratio that conflict, the
3587+ * results are undefined.
3588+ *
3589+ * @remark __Wayland:__ The aspect ratio will not be applied until the window is
3590+ * actually resized, either by the user or by the compositor.
3591+ *
3592+ * @thread_safety This function must only be called from the main thread.
3593+ *
3594+ * @sa @ref window_sizelimits
3595+ * @sa @ref glfwSetWindowSizeLimits
3596+ *
3597+ * @since Added in version 3.2.
3598+ *
3599+ * @ingroup window
3600+ */
3601+GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
3602+
3603+/*! @brief Sets the size of the content area of the specified window.
3604+ *
3605+ * This function sets the size, in screen coordinates, of the content area of
3606+ * the specified window.
3607+ *
3608+ * For full screen windows, this function updates the resolution of its desired
3609+ * video mode and switches to the video mode closest to it, without affecting
3610+ * the window's context. As the context is unaffected, the bit depths of the
3611+ * framebuffer remain unchanged.
3612+ *
3613+ * If you wish to update the refresh rate of the desired video mode in addition
3614+ * to its resolution, see @ref glfwSetWindowMonitor.
3615+ *
3616+ * The window manager may put limits on what sizes are allowed. GLFW cannot
3617+ * and should not override these limits.
3618+ *
3619+ * @param[in] window The window to resize.
3620+ * @param[in] width The desired width, in screen coordinates, of the window
3621+ * content area.
3622+ * @param[in] height The desired height, in screen coordinates, of the window
3623+ * content area.
3624+ *
3625+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3626+ * GLFW_PLATFORM_ERROR.
3627+ *
3628+ * @thread_safety This function must only be called from the main thread.
3629+ *
3630+ * @sa @ref window_size
3631+ * @sa @ref glfwGetWindowSize
3632+ * @sa @ref glfwSetWindowMonitor
3633+ *
3634+ * @since Added in version 1.0.
3635+ * __GLFW 3:__ Added window handle parameter.
3636+ *
3637+ * @ingroup window
3638+ */
3639+GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);
3640+
3641+/*! @brief Retrieves the size of the framebuffer of the specified window.
3642+ *
3643+ * This function retrieves the size, in pixels, of the framebuffer of the
3644+ * specified window. If you wish to retrieve the size of the window in screen
3645+ * coordinates, see @ref glfwGetWindowSize.
3646+ *
3647+ * Any or all of the size arguments may be `NULL`. If an error occurs, all
3648+ * non-`NULL` size arguments will be set to zero.
3649+ *
3650+ * @param[in] window The window whose framebuffer to query.
3651+ * @param[out] width Where to store the width, in pixels, of the framebuffer,
3652+ * or `NULL`.
3653+ * @param[out] height Where to store the height, in pixels, of the framebuffer,
3654+ * or `NULL`.
3655+ *
3656+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3657+ * GLFW_PLATFORM_ERROR.
3658+ *
3659+ * @thread_safety This function must only be called from the main thread.
3660+ *
3661+ * @sa @ref window_fbsize
3662+ * @sa @ref glfwSetFramebufferSizeCallback
3663+ *
3664+ * @since Added in version 3.0.
3665+ *
3666+ * @ingroup window
3667+ */
3668+GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height);
3669+
3670+/*! @brief Retrieves the size of the frame of the window.
3671+ *
3672+ * This function retrieves the size, in screen coordinates, of each edge of the
3673+ * frame of the specified window. This size includes the title bar, if the
3674+ * window has one. The size of the frame may vary depending on the
3675+ * [window-related hints](@ref window_hints_wnd) used to create it.
3676+ *
3677+ * Because this function retrieves the size of each window frame edge and not
3678+ * the offset along a particular coordinate axis, the retrieved values will
3679+ * always be zero or positive.
3680+ *
3681+ * Any or all of the size arguments may be `NULL`. If an error occurs, all
3682+ * non-`NULL` size arguments will be set to zero.
3683+ *
3684+ * @param[in] window The window whose frame size to query.
3685+ * @param[out] left Where to store the size, in screen coordinates, of the left
3686+ * edge of the window frame, or `NULL`.
3687+ * @param[out] top Where to store the size, in screen coordinates, of the top
3688+ * edge of the window frame, or `NULL`.
3689+ * @param[out] right Where to store the size, in screen coordinates, of the
3690+ * right edge of the window frame, or `NULL`.
3691+ * @param[out] bottom Where to store the size, in screen coordinates, of the
3692+ * bottom edge of the window frame, or `NULL`.
3693+ *
3694+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3695+ * GLFW_PLATFORM_ERROR.
3696+ *
3697+ * @thread_safety This function must only be called from the main thread.
3698+ *
3699+ * @sa @ref window_size
3700+ *
3701+ * @since Added in version 3.1.
3702+ *
3703+ * @ingroup window
3704+ */
3705+GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom);
3706+
3707+/*! @brief Retrieves the content scale for the specified window.
3708+ *
3709+ * This function retrieves the content scale for the specified window. The
3710+ * content scale is the ratio between the current DPI and the platform's
3711+ * default DPI. This is especially important for text and any UI elements. If
3712+ * the pixel dimensions of your UI scaled by this look appropriate on your
3713+ * machine then it should appear at a reasonable size on other machines
3714+ * regardless of their DPI and scaling settings. This relies on the system DPI
3715+ * and scaling settings being somewhat correct.
3716+ *
3717+ * On platforms where each monitors can have its own content scale, the window
3718+ * content scale will depend on which monitor the system considers the window
3719+ * to be on.
3720+ *
3721+ * @param[in] window The window to query.
3722+ * @param[out] xscale Where to store the x-axis content scale, or `NULL`.
3723+ * @param[out] yscale Where to store the y-axis content scale, or `NULL`.
3724+ *
3725+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3726+ * GLFW_PLATFORM_ERROR.
3727+ *
3728+ * @thread_safety This function must only be called from the main thread.
3729+ *
3730+ * @sa @ref window_scale
3731+ * @sa @ref glfwSetWindowContentScaleCallback
3732+ * @sa @ref glfwGetMonitorContentScale
3733+ *
3734+ * @since Added in version 3.3.
3735+ *
3736+ * @ingroup window
3737+ */
3738+GLFWAPI void glfwGetWindowContentScale(GLFWwindow* window, float* xscale, float* yscale);
3739+
3740+/*! @brief Returns the opacity of the whole window.
3741+ *
3742+ * This function returns the opacity of the window, including any decorations.
3743+ *
3744+ * The opacity (or alpha) value is a positive finite number between zero and
3745+ * one, where zero is fully transparent and one is fully opaque. If the system
3746+ * does not support whole window transparency, this function always returns one.
3747+ *
3748+ * The initial opacity value for newly created windows is one.
3749+ *
3750+ * @param[in] window The window to query.
3751+ * @return The opacity value of the specified window.
3752+ *
3753+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3754+ * GLFW_PLATFORM_ERROR.
3755+ *
3756+ * @thread_safety This function must only be called from the main thread.
3757+ *
3758+ * @sa @ref window_transparency
3759+ * @sa @ref glfwSetWindowOpacity
3760+ *
3761+ * @since Added in version 3.3.
3762+ *
3763+ * @ingroup window
3764+ */
3765+GLFWAPI float glfwGetWindowOpacity(GLFWwindow* window);
3766+
3767+/*! @brief Sets the opacity of the whole window.
3768+ *
3769+ * This function sets the opacity of the window, including any decorations.
3770+ *
3771+ * The opacity (or alpha) value is a positive finite number between zero and
3772+ * one, where zero is fully transparent and one is fully opaque.
3773+ *
3774+ * The initial opacity value for newly created windows is one.
3775+ *
3776+ * A window created with framebuffer transparency may not use whole window
3777+ * transparency. The results of doing this are undefined.
3778+ *
3779+ * @param[in] window The window to set the opacity for.
3780+ * @param[in] opacity The desired opacity of the specified window.
3781+ *
3782+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
3783+ * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
3784+ *
3785+ * @remark __Wayland:__ There is no way to set an opacity factor for a window.
3786+ * This function will emit @ref GLFW_FEATURE_UNAVAILABLE.
3787+ *
3788+ * @thread_safety This function must only be called from the main thread.
3789+ *
3790+ * @sa @ref window_transparency
3791+ * @sa @ref glfwGetWindowOpacity
3792+ *
3793+ * @since Added in version 3.3.
3794+ *
3795+ * @ingroup window
3796+ */
3797+GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
3798+
3799+/*! @brief Iconifies the specified window.
3800+ *
3801+ * This function iconifies (minimizes) the specified window if it was
3802+ * previously restored. If the window is already iconified, this function does
3803+ * nothing.
3804+ *
3805+ * If the specified window is a full screen window, GLFW restores the original
3806+ * video mode of the monitor. The window's desired video mode is set again
3807+ * when the window is restored.
3808+ *
3809+ * @param[in] window The window to iconify.
3810+ *
3811+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3812+ * GLFW_PLATFORM_ERROR.
3813+ *
3814+ * @thread_safety This function must only be called from the main thread.
3815+ *
3816+ * @sa @ref window_iconify
3817+ * @sa @ref glfwRestoreWindow
3818+ * @sa @ref glfwMaximizeWindow
3819+ *
3820+ * @since Added in version 2.1.
3821+ * __GLFW 3:__ Added window handle parameter.
3822+ *
3823+ * @ingroup window
3824+ */
3825+GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
3826+
3827+/*! @brief Restores the specified window.
3828+ *
3829+ * This function restores the specified window if it was previously iconified
3830+ * (minimized) or maximized. If the window is already restored, this function
3831+ * does nothing.
3832+ *
3833+ * If the specified window is an iconified full screen window, its desired
3834+ * video mode is set again for its monitor when the window is restored.
3835+ *
3836+ * @param[in] window The window to restore.
3837+ *
3838+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3839+ * GLFW_PLATFORM_ERROR.
3840+ *
3841+ * @remark __Wayland:__ Restoring a window from maximization is not currently
3842+ * part of any common Wayland protocol, so this function can only restore
3843+ * windows from maximization.
3844+ *
3845+ * @thread_safety This function must only be called from the main thread.
3846+ *
3847+ * @sa @ref window_iconify
3848+ * @sa @ref glfwIconifyWindow
3849+ * @sa @ref glfwMaximizeWindow
3850+ *
3851+ * @since Added in version 2.1.
3852+ * __GLFW 3:__ Added window handle parameter.
3853+ *
3854+ * @ingroup window
3855+ */
3856+GLFWAPI void glfwRestoreWindow(GLFWwindow* window);
3857+
3858+/*! @brief Maximizes the specified window.
3859+ *
3860+ * This function maximizes the specified window if it was previously not
3861+ * maximized. If the window is already maximized, this function does nothing.
3862+ *
3863+ * If the specified window is a full screen window, this function does nothing.
3864+ *
3865+ * @param[in] window The window to maximize.
3866+ *
3867+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3868+ * GLFW_PLATFORM_ERROR.
3869+ *
3870+ * @par Thread Safety
3871+ * This function may only be called from the main thread.
3872+ *
3873+ * @sa @ref window_iconify
3874+ * @sa @ref glfwIconifyWindow
3875+ * @sa @ref glfwRestoreWindow
3876+ *
3877+ * @since Added in GLFW 3.2.
3878+ *
3879+ * @ingroup window
3880+ */
3881+GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
3882+
3883+/*! @brief Makes the specified window visible.
3884+ *
3885+ * This function makes the specified window visible if it was previously
3886+ * hidden. If the window is already visible or is in full screen mode, this
3887+ * function does nothing.
3888+ *
3889+ * By default, windowed mode windows are focused when shown
3890+ * Set the [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) window hint
3891+ * to change this behavior for all newly created windows, or change the
3892+ * behavior for an existing window with @ref glfwSetWindowAttrib.
3893+ *
3894+ * @param[in] window The window to make visible.
3895+ *
3896+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3897+ * GLFW_PLATFORM_ERROR.
3898+ *
3899+ * @remark __Wayland:__ Because Wayland wants every frame of the desktop to be
3900+ * complete, this function does not immediately make the window visible.
3901+ * Instead it will become visible the next time the window framebuffer is
3902+ * updated after this call.
3903+ *
3904+ * @thread_safety This function must only be called from the main thread.
3905+ *
3906+ * @sa @ref window_hide
3907+ * @sa @ref glfwHideWindow
3908+ *
3909+ * @since Added in version 3.0.
3910+ *
3911+ * @ingroup window
3912+ */
3913+GLFWAPI void glfwShowWindow(GLFWwindow* window);
3914+
3915+/*! @brief Hides the specified window.
3916+ *
3917+ * This function hides the specified window if it was previously visible. If
3918+ * the window is already hidden or is in full screen mode, this function does
3919+ * nothing.
3920+ *
3921+ * @param[in] window The window to hide.
3922+ *
3923+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3924+ * GLFW_PLATFORM_ERROR.
3925+ *
3926+ * @thread_safety This function must only be called from the main thread.
3927+ *
3928+ * @sa @ref window_hide
3929+ * @sa @ref glfwShowWindow
3930+ *
3931+ * @since Added in version 3.0.
3932+ *
3933+ * @ingroup window
3934+ */
3935+GLFWAPI void glfwHideWindow(GLFWwindow* window);
3936+
3937+/*! @brief Brings the specified window to front and sets input focus.
3938+ *
3939+ * This function brings the specified window to front and sets input focus.
3940+ * The window should already be visible and not iconified.
3941+ *
3942+ * By default, both windowed and full screen mode windows are focused when
3943+ * initially created. Set the [GLFW_FOCUSED](@ref GLFW_FOCUSED_hint) to
3944+ * disable this behavior.
3945+ *
3946+ * Also by default, windowed mode windows are focused when shown
3947+ * with @ref glfwShowWindow. Set the
3948+ * [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) to disable this behavior.
3949+ *
3950+ * __Do not use this function__ to steal focus from other applications unless
3951+ * you are certain that is what the user wants. Focus stealing can be
3952+ * extremely disruptive.
3953+ *
3954+ * For a less disruptive way of getting the user's attention, see
3955+ * [attention requests](@ref window_attention).
3956+ *
3957+ * @param[in] window The window to give input focus.
3958+ *
3959+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3960+ * GLFW_PLATFORM_ERROR.
3961+ *
3962+ * @remark __Wayland:__ The compositor will likely ignore focus requests unless
3963+ * another window created by the same application already has input focus.
3964+ *
3965+ * @thread_safety This function must only be called from the main thread.
3966+ *
3967+ * @sa @ref window_focus
3968+ * @sa @ref window_attention
3969+ *
3970+ * @since Added in version 3.2.
3971+ *
3972+ * @ingroup window
3973+ */
3974+GLFWAPI void glfwFocusWindow(GLFWwindow* window);
3975+
3976+/*! @brief Requests user attention to the specified window.
3977+ *
3978+ * This function requests user attention to the specified window. On
3979+ * platforms where this is not supported, attention is requested to the
3980+ * application as a whole.
3981+ *
3982+ * Once the user has given attention, usually by focusing the window or
3983+ * application, the system will end the request automatically.
3984+ *
3985+ * @param[in] window The window to request attention to.
3986+ *
3987+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
3988+ * GLFW_PLATFORM_ERROR.
3989+ *
3990+ * @remark __macOS:__ Attention is requested to the application as a whole, not the
3991+ * specific window.
3992+ *
3993+ * @thread_safety This function must only be called from the main thread.
3994+ *
3995+ * @sa @ref window_attention
3996+ *
3997+ * @since Added in version 3.3.
3998+ *
3999+ * @ingroup window
4000+ */
4001+GLFWAPI void glfwRequestWindowAttention(GLFWwindow* window);
4002+
4003+/*! @brief Returns the monitor that the window uses for full screen mode.
4004+ *
4005+ * This function returns the handle of the monitor that the specified window is
4006+ * in full screen on.
4007+ *
4008+ * @param[in] window The window to query.
4009+ * @return The monitor, or `NULL` if the window is in windowed mode or an
4010+ * [error](@ref error_handling) occurred.
4011+ *
4012+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
4013+ *
4014+ * @thread_safety This function must only be called from the main thread.
4015+ *
4016+ * @sa @ref window_monitor
4017+ * @sa @ref glfwSetWindowMonitor
4018+ *
4019+ * @since Added in version 3.0.
4020+ *
4021+ * @ingroup window
4022+ */
4023+GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
4024+
4025+/*! @brief Sets the mode, monitor, video mode and placement of a window.
4026+ *
4027+ * This function sets the monitor that the window uses for full screen mode or,
4028+ * if the monitor is `NULL`, makes it windowed mode.
4029+ *
4030+ * When setting a monitor, this function updates the width, height and refresh
4031+ * rate of the desired video mode and switches to the video mode closest to it.
4032+ * The window position is ignored when setting a monitor.
4033+ *
4034+ * When the monitor is `NULL`, the position, width and height are used to
4035+ * place the window content area. The refresh rate is ignored when no monitor
4036+ * is specified.
4037+ *
4038+ * If you only wish to update the resolution of a full screen window or the
4039+ * size of a windowed mode window, see @ref glfwSetWindowSize.
4040+ *
4041+ * When a window transitions from full screen to windowed mode, this function
4042+ * restores any previous window settings such as whether it is decorated,
4043+ * floating, resizable, has size or aspect ratio limits, etc.
4044+ *
4045+ * @param[in] window The window whose monitor, size or video mode to set.
4046+ * @param[in] monitor The desired monitor, or `NULL` to set windowed mode.
4047+ * @param[in] xpos The desired x-coordinate of the upper-left corner of the
4048+ * content area.
4049+ * @param[in] ypos The desired y-coordinate of the upper-left corner of the
4050+ * content area.
4051+ * @param[in] width The desired with, in screen coordinates, of the content
4052+ * area or video mode.
4053+ * @param[in] height The desired height, in screen coordinates, of the content
4054+ * area or video mode.
4055+ * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode,
4056+ * or `GLFW_DONT_CARE`.
4057+ *
4058+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
4059+ * GLFW_PLATFORM_ERROR.
4060+ *
4061+ * @remark The OpenGL or OpenGL ES context will not be destroyed or otherwise
4062+ * affected by any resizing or mode switching, although you may need to update
4063+ * your viewport if the framebuffer size has changed.
4064+ *
4065+ * @remark __Wayland:__ Window positions are not currently part of any common
4066+ * Wayland protocol. The window position arguments are ignored.
4067+ *
4068+ * @thread_safety This function must only be called from the main thread.
4069+ *
4070+ * @sa @ref window_monitor
4071+ * @sa @ref window_full_screen
4072+ * @sa @ref glfwGetWindowMonitor
4073+ * @sa @ref glfwSetWindowSize
4074+ *
4075+ * @since Added in version 3.2.
4076+ *
4077+ * @ingroup window
4078+ */
4079+GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
4080+
4081+/*! @brief Returns an attribute of the specified window.
4082+ *
4083+ * This function returns the value of an attribute of the specified window or
4084+ * its OpenGL or OpenGL ES context.
4085+ *
4086+ * @param[in] window The window to query.
4087+ * @param[in] attrib The [window attribute](@ref window_attribs) whose value to
4088+ * return.
4089+ * @return The value of the attribute, or zero if an
4090+ * [error](@ref error_handling) occurred.
4091+ *
4092+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
4093+ * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
4094+ *
4095+ * @remark Framebuffer related hints are not window attributes. See @ref
4096+ * window_attribs_fb for more information.
4097+ *
4098+ * @remark Zero is a valid value for many window and context related
4099+ * attributes so you cannot use a return value of zero as an indication of
4100+ * errors. However, this function should not fail as long as it is passed
4101+ * valid arguments and the library has been [initialized](@ref intro_init).
4102+ *
4103+ * @remark __Wayland:__ Checking whether a window is iconified is not currently
4104+ * part of any common Wayland protocol, so the @ref GLFW_ICONIFIED attribute
4105+ * cannot be implemented and is always `GLFW_FALSE`.
4106+ *
4107+ * @thread_safety This function must only be called from the main thread.
4108+ *
4109+ * @sa @ref window_attribs
4110+ * @sa @ref glfwSetWindowAttrib
4111+ *
4112+ * @since Added in version 3.0. Replaces `glfwGetWindowParam` and
4113+ * `glfwGetGLVersion`.
4114+ *
4115+ * @ingroup window
4116+ */
4117+GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
4118+
4119+/*! @brief Sets an attribute of the specified window.
4120+ *
4121+ * This function sets the value of an attribute of the specified window.
4122+ *
4123+ * The supported attributes are [GLFW_DECORATED](@ref GLFW_DECORATED_attrib),
4124+ * [GLFW_RESIZABLE](@ref GLFW_RESIZABLE_attrib),
4125+ * [GLFW_FLOATING](@ref GLFW_FLOATING_attrib),
4126+ * [GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib) and
4127+ * [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_attrib).
4128+ * [GLFW_MOUSE_PASSTHROUGH](@ref GLFW_MOUSE_PASSTHROUGH_attrib)
4129+ *
4130+ * Some of these attributes are ignored for full screen windows. The new
4131+ * value will take effect if the window is later made windowed.
4132+ *
4133+ * Some of these attributes are ignored for windowed mode windows. The new
4134+ * value will take effect if the window is later made full screen.
4135+ *
4136+ * @param[in] window The window to set the attribute for.
4137+ * @param[in] attrib A supported window attribute.
4138+ * @param[in] value `GLFW_TRUE` or `GLFW_FALSE`.
4139+ *
4140+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
4141+ * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_PLATFORM_ERROR and @ref
4142+ * GLFW_FEATURE_UNAVAILABLE (see remarks).
4143+ *
4144+ * @remark Calling @ref glfwGetWindowAttrib will always return the latest
4145+ * value, even if that value is ignored by the current mode of the window.
4146+ *
4147+ * @remark __Wayland:__ The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window attribute is
4148+ * not supported. Setting this will emit @ref GLFW_FEATURE_UNAVAILABLE.
4149+ *
4150+ * @thread_safety This function must only be called from the main thread.
4151+ *
4152+ * @sa @ref window_attribs
4153+ * @sa @ref glfwGetWindowAttrib
4154+ *
4155+ * @since Added in version 3.3.
4156+ *
4157+ * @ingroup window
4158+ */
4159+GLFWAPI void glfwSetWindowAttrib(GLFWwindow* window, int attrib, int value);
4160+
4161+/*! @brief Sets the user pointer of the specified window.
4162+ *
4163+ * This function sets the user-defined pointer of the specified window. The
4164+ * current value is retained until the window is destroyed. The initial value
4165+ * is `NULL`.
4166+ *
4167+ * @param[in] window The window whose pointer to set.
4168+ * @param[in] pointer The new value.
4169+ *
4170+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
4171+ *
4172+ * @thread_safety This function may be called from any thread. Access is not
4173+ * synchronized.
4174+ *
4175+ * @sa @ref window_userptr
4176+ * @sa @ref glfwGetWindowUserPointer
4177+ *
4178+ * @since Added in version 3.0.
4179+ *
4180+ * @ingroup window
4181+ */
4182+GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer);
4183+
4184+/*! @brief Returns the user pointer of the specified window.
4185+ *
4186+ * This function returns the current value of the user-defined pointer of the
4187+ * specified window. The initial value is `NULL`.
4188+ *
4189+ * @param[in] window The window whose pointer to return.
4190+ *
4191+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
4192+ *
4193+ * @thread_safety This function may be called from any thread. Access is not
4194+ * synchronized.
4195+ *
4196+ * @sa @ref window_userptr
4197+ * @sa @ref glfwSetWindowUserPointer
4198+ *
4199+ * @since Added in version 3.0.
4200+ *
4201+ * @ingroup window
4202+ */
4203+GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
4204+
4205+/*! @brief Sets the position callback for the specified window.
4206+ *
4207+ * This function sets the position callback of the specified window, which is
4208+ * called when the window is moved. The callback is provided with the
4209+ * position, in screen coordinates, of the upper-left corner of the content
4210+ * area of the window.
4211+ *
4212+ * @param[in] window The window whose callback to set.
4213+ * @param[in] callback The new callback, or `NULL` to remove the currently set
4214+ * callback.
4215+ * @return The previously set callback, or `NULL` if no callback was set or the
4216+ * library had not been [initialized](@ref intro_init).
4217+ *
4218+ * @callback_signature
4219+ * @code
4220+ * void function_name(GLFWwindow* window, int xpos, int ypos)
4221+ * @endcode
4222+ * For more information about the callback parameters, see the
4223+ * [function pointer type](@ref GLFWwindowposfun).
4224+ *
4225+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
4226+ *
4227+ * @remark __Wayland:__ This callback will not be called. The Wayland protocol
4228+ * provides no way to be notified of when a window is moved.
4229+ *
4230+ * @thread_safety This function must only be called from the main thread.
4231+ *
4232+ * @sa @ref window_pos
4233+ *
4234+ * @since Added in version 3.0.
4235+ *
4236+ * @ingroup window
4237+ */
4238+GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun callback);
4239+
4240+/*! @brief Sets the size callback for the specified window.
4241+ *
4242+ * This function sets the size callback of the specified window, which is
4243+ * called when the window is resized. The callback is provided with the size,
4244+ * in screen coordinates, of the content area of the window.
4245+ *
4246+ * @param[in] window The window whose callback to set.
4247+ * @param[in] callback The new callback, or `NULL` to remove the currently set
4248+ * callback.
4249+ * @return The previously set callback, or `NULL` if no callback was set or the
4250+ * library had not been [initialized](@ref intro_init).
4251+ *
4252+ * @callback_signature
4253+ * @code
4254+ * void function_name(GLFWwindow* window, int width, int height)
4255+ * @endcode
4256+ * For more information about the callback parameters, see the
4257+ * [function pointer type](@ref GLFWwindowsizefun).
4258+ *
4259+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
4260+ *
4261+ * @thread_safety This function must only be called from the main thread.
4262+ *
4263+ * @sa @ref window_size
4264+ *
4265+ * @since Added in version 1.0.
4266+ * __GLFW 3:__ Added window handle parameter and return value.
4267+ *
4268+ * @ingroup window
4269+ */
4270+GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun callback);
4271+
4272+/*! @brief Sets the close callback for the specified window.
4273+ *
4274+ * This function sets the close callback of the specified window, which is
4275+ * called when the user attempts to close the window, for example by clicking
4276+ * the close widget in the title bar.
4277+ *
4278+ * The close flag is set before this callback is called, but you can modify it
4279+ * at any time with @ref glfwSetWindowShouldClose.
4280+ *
4281+ * The close callback is not triggered by @ref glfwDestroyWindow.
4282+ *
4283+ * @param[in] window The window whose callback to set.
4284+ * @param[in] callback The new callback, or `NULL` to remove the currently set
4285+ * callback.
4286+ * @return The previously set callback, or `NULL` if no callback was set or the
4287+ * library had not been [initialized](@ref intro_init).
4288+ *
4289+ * @callback_signature
4290+ * @code
4291+ * void function_name(GLFWwindow* window)
4292+ * @endcode
4293+ * For more information about the callback parameters, see the
4294+ * [function pointer type](@ref GLFWwindowclosefun).
4295+ *
4296+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
4297+ *
4298+ * @remark __macOS:__ Selecting Quit from the application menu will trigger the
4299+ * close callback for all windows.
4300+ *
4301+ * @thread_safety This function must only be called from the main thread.
4302+ *
4303+ * @sa @ref window_close
4304+ *
4305+ * @since Added in version 2.5.
4306+ * __GLFW 3:__ Added window handle parameter and return value.
4307+ *
4308+ * @ingroup window
4309+ */
4310+GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun callback);
4311+
4312+/*! @brief Sets the refresh callback for the specified window.
4313+ *
4314+ * This function sets the refresh callback of the specified window, which is
4315+ * called when the content area of the window needs to be redrawn, for example
4316+ * if the window has been exposed after having been covered by another window.
4317+ *
4318+ * On compositing window systems such as Aero, Compiz, Aqua or Wayland, where
4319+ * the window contents are saved off-screen, this callback may be called only
4320+ * very infrequently or never at all.
4321+ *
4322+ * @param[in] window The window whose callback to set.
4323+ * @param[in] callback The new callback, or `NULL` to remove the currently set
4324+ * callback.
4325+ * @return The previously set callback, or `NULL` if no callback was set or the
4326+ * library had not been [initialized](@ref intro_init).
4327+ *
4328+ * @callback_signature
4329+ * @code
4330+ * void function_name(GLFWwindow* window);
4331+ * @endcode
4332+ * For more information about the callback parameters, see the
4333+ * [function pointer type](@ref GLFWwindowrefreshfun).
4334+ *
4335+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
4336+ *
4337+ * @thread_safety This function must only be called from the main thread.
4338+ *
4339+ * @sa @ref window_refresh
4340+ *
4341+ * @since Added in version 2.5.
4342+ * __GLFW 3:__ Added window handle parameter and return value.
4343+ *
4344+ * @ingroup window
4345+ */
4346+GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun callback);
4347+
4348+/*! @brief Sets the focus callback for the specified window.
4349+ *
4350+ * This function sets the focus callback of the specified window, which is
4351+ * called when the window gains or loses input focus.
4352+ *
4353+ * After the focus callback is called for a window that lost input focus,
4354+ * synthetic key and mouse button release events will be generated for all such
4355+ * that had been pressed. For more information, see @ref glfwSetKeyCallback
4356+ * and @ref glfwSetMouseButtonCallback.
4357+ *
4358+ * @param[in] window The window whose callback to set.
4359+ * @param[in] callback The new callback, or `NULL` to remove the currently set
4360+ * callback.
4361+ * @return The previously set callback, or `NULL` if no callback was set or the
4362+ * library had not been [initialized](@ref intro_init).
4363+ *
4364+ * @callback_signature
4365+ * @code
4366+ * void function_name(GLFWwindow* window, int focused)
4367+ * @endcode
4368+ * For more information about the callback parameters, see the
4369+ * [function pointer type](@ref GLFWwindowfocusfun).
4370+ *
4371+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
4372+ *
4373+ * @thread_safety This function must only be called from the main thread.
4374+ *
4375+ * @sa @ref window_focus
4376+ *
4377+ * @since Added in version 3.0.
4378+ *
4379+ * @ingroup window
4380+ */
4381+GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun callback);
4382+
4383+/*! @brief Sets the iconify callback for the specified window.
4384+ *
4385+ * This function sets the iconification callback of the specified window, which
4386+ * is called when the window is iconified or restored.
4387+ *
4388+ * @param[in] window The window whose callback to set.
4389+ * @param[in] callback The new callback, or `NULL` to remove the currently set
4390+ * callback.
4391+ * @return The previously set callback, or `NULL` if no callback was set or the
4392+ * library had not been [initialized](@ref intro_init).
4393+ *
4394+ * @callback_signature
4395+ * @code
4396+ * void function_name(GLFWwindow* window, int iconified)
4397+ * @endcode
4398+ * For more information about the callback parameters, see the
4399+ * [function pointer type](@ref GLFWwindowiconifyfun).
4400+ *
4401+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
4402+ *
4403+ * @remark __Wayland:__ This callback will not be called. The Wayland protocol
4404+ * provides no way to be notified of when a window is iconified, and no way to
4405+ * check whether a window is currently iconified.
4406+ *
4407+ * @thread_safety This function must only be called from the main thread.
4408+ *
4409+ * @sa @ref window_iconify
4410+ *
4411+ * @since Added in version 3.0.
4412+ *
4413+ * @ingroup window
4414+ */
4415+GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun callback);
4416+
4417+/*! @brief Sets the maximize callback for the specified window.
4418+ *
4419+ * This function sets the maximization callback of the specified window, which
4420+ * is called when the window is maximized or restored.
4421+ *
4422+ * @param[in] window The window whose callback to set.
4423+ * @param[in] callback The new callback, or `NULL` to remove the currently set
4424+ * callback.
4425+ * @return The previously set callback, or `NULL` if no callback was set or the
4426+ * library had not been [initialized](@ref intro_init).
4427+ *
4428+ * @callback_signature
4429+ * @code
4430+ * void function_name(GLFWwindow* window, int maximized)
4431+ * @endcode
4432+ * For more information about the callback parameters, see the
4433+ * [function pointer type](@ref GLFWwindowmaximizefun).
4434+ *
4435+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
4436+ *
4437+ * @thread_safety This function must only be called from the main thread.
4438+ *
4439+ * @sa @ref window_maximize
4440+ *
4441+ * @since Added in version 3.3.
4442+ *
4443+ * @ingroup window
4444+ */
4445+GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* window, GLFWwindowmaximizefun callback);
4446+
4447+/*! @brief Sets the framebuffer resize callback for the specified window.
4448+ *
4449+ * This function sets the framebuffer resize callback of the specified window,
4450+ * which is called when the framebuffer of the specified window is resized.
4451+ *
4452+ * @param[in] window The window whose callback to set.
4453+ * @param[in] callback The new callback, or `NULL` to remove the currently set
4454+ * callback.
4455+ * @return The previously set callback, or `NULL` if no callback was set or the
4456+ * library had not been [initialized](@ref intro_init).
4457+ *
4458+ * @callback_signature
4459+ * @code
4460+ * void function_name(GLFWwindow* window, int width, int height)
4461+ * @endcode
4462+ * For more information about the callback parameters, see the
4463+ * [function pointer type](@ref GLFWframebuffersizefun).
4464+ *
4465+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
4466+ *
4467+ * @thread_safety This function must only be called from the main thread.
4468+ *
4469+ * @sa @ref window_fbsize
4470+ *
4471+ * @since Added in version 3.0.
4472+ *
4473+ * @ingroup window
4474+ */
4475+GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun callback);
4476+
4477+/*! @brief Sets the window content scale callback for the specified window.
4478+ *
4479+ * This function sets the window content scale callback of the specified window,
4480+ * which is called when the content scale of the specified window changes.
4481+ *
4482+ * @param[in] window The window whose callback to set.
4483+ * @param[in] callback The new callback, or `NULL` to remove the currently set
4484+ * callback.
4485+ * @return The previously set callback, or `NULL` if no callback was set or the
4486+ * library had not been [initialized](@ref intro_init).
4487+ *
4488+ * @callback_signature
4489+ * @code
4490+ * void function_name(GLFWwindow* window, float xscale, float yscale)
4491+ * @endcode
4492+ * For more information about the callback parameters, see the
4493+ * [function pointer type](@ref GLFWwindowcontentscalefun).
4494+ *
4495+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
4496+ *
4497+ * @thread_safety This function must only be called from the main thread.
4498+ *
4499+ * @sa @ref window_scale
4500+ * @sa @ref glfwGetWindowContentScale
4501+ *
4502+ * @since Added in version 3.3.
4503+ *
4504+ * @ingroup window
4505+ */
4506+GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* window, GLFWwindowcontentscalefun callback);
4507+
4508+/*! @brief Processes all pending events.
4509+ *
4510+ * This function processes only those events that are already in the event
4511+ * queue and then returns immediately. Processing events will cause the window
4512+ * and input callbacks associated with those events to be called.
4513+ *
4514+ * On some platforms, a window move, resize or menu operation will cause event
4515+ * processing to block. This is due to how event processing is designed on
4516+ * those platforms. You can use the
4517+ * [window refresh callback](@ref window_refresh) to redraw the contents of
4518+ * your window when necessary during such operations.
4519+ *
4520+ * Do not assume that callbacks you set will _only_ be called in response to
4521+ * event processing functions like this one. While it is necessary to poll for
4522+ * events, window systems that require GLFW to register callbacks of its own
4523+ * can pass events to GLFW in response to many window system function calls.
4524+ * GLFW will pass those events on to the application callbacks before
4525+ * returning.
4526+ *
4527+ * Event processing is not required to receive joystick input. Joystick state
4528+ * is polled when a joystick input or gamepad input function is called.
4529+ *
4530+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
4531+ * GLFW_PLATFORM_ERROR.
4532+ *
4533+ * @reentrancy This function must not be called from a callback.
4534+ *
4535+ * @thread_safety This function must only be called from the main thread.
4536+ *
4537+ * @sa @ref events
4538+ * @sa @ref glfwWaitEvents
4539+ * @sa @ref glfwWaitEventsTimeout
4540+ *
4541+ * @since Added in version 1.0.
4542+ *
4543+ * @ingroup window
4544+ */
4545+GLFWAPI void glfwPollEvents(void);
4546+
4547+/*! @brief Waits until events are queued and processes them.
4548+ *
4549+ * This function puts the calling thread to sleep until at least one event is
4550+ * available in the event queue. Once one or more events are available,
4551+ * it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue
4552+ * are processed and the function then returns immediately. Processing events
4553+ * will cause the window and input callbacks associated with those events to be
4554+ * called.
4555+ *
4556+ * Since not all events are associated with callbacks, this function may return
4557+ * without a callback having been called even if you are monitoring all
4558+ * callbacks.
4559+ *
4560+ * On some platforms, a window move, resize or menu operation will cause event
4561+ * processing to block. This is due to how event processing is designed on
4562+ * those platforms. You can use the
4563+ * [window refresh callback](@ref window_refresh) to redraw the contents of
4564+ * your window when necessary during such operations.
4565+ *
4566+ * Do not assume that callbacks you set will _only_ be called in response to
4567+ * event processing functions like this one. While it is necessary to poll for
4568+ * events, window systems that require GLFW to register callbacks of its own
4569+ * can pass events to GLFW in response to many window system function calls.
4570+ * GLFW will pass those events on to the application callbacks before
4571+ * returning.
4572+ *
4573+ * Event processing is not required to receive joystick input. Joystick state
4574+ * is polled when a joystick input or gamepad input function is called.
4575+ *
4576+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
4577+ * GLFW_PLATFORM_ERROR.
4578+ *
4579+ * @reentrancy This function must not be called from a callback.
4580+ *
4581+ * @thread_safety This function must only be called from the main thread.
4582+ *
4583+ * @sa @ref events
4584+ * @sa @ref glfwPollEvents
4585+ * @sa @ref glfwWaitEventsTimeout
4586+ *
4587+ * @since Added in version 2.5.
4588+ *
4589+ * @ingroup window
4590+ */
4591+GLFWAPI void glfwWaitEvents(void);
4592+
4593+/*! @brief Waits with timeout until events are queued and processes them.
4594+ *
4595+ * This function puts the calling thread to sleep until at least one event is
4596+ * available in the event queue, or until the specified timeout is reached. If
4597+ * one or more events are available, it behaves exactly like @ref
4598+ * glfwPollEvents, i.e. the events in the queue are processed and the function
4599+ * then returns immediately. Processing events will cause the window and input
4600+ * callbacks associated with those events to be called.
4601+ *
4602+ * The timeout value must be a positive finite number.
4603+ *
4604+ * Since not all events are associated with callbacks, this function may return
4605+ * without a callback having been called even if you are monitoring all
4606+ * callbacks.
4607+ *
4608+ * On some platforms, a window move, resize or menu operation will cause event
4609+ * processing to block. This is due to how event processing is designed on
4610+ * those platforms. You can use the
4611+ * [window refresh callback](@ref window_refresh) to redraw the contents of
4612+ * your window when necessary during such operations.
4613+ *
4614+ * Do not assume that callbacks you set will _only_ be called in response to
4615+ * event processing functions like this one. While it is necessary to poll for
4616+ * events, window systems that require GLFW to register callbacks of its own
4617+ * can pass events to GLFW in response to many window system function calls.
4618+ * GLFW will pass those events on to the application callbacks before
4619+ * returning.
4620+ *
4621+ * Event processing is not required to receive joystick input. Joystick state
4622+ * is polled when a joystick input or gamepad input function is called.
4623+ *
4624+ * @param[in] timeout The maximum amount of time, in seconds, to wait.
4625+ *
4626+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
4627+ * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
4628+ *
4629+ * @reentrancy This function must not be called from a callback.
4630+ *
4631+ * @thread_safety This function must only be called from the main thread.
4632+ *
4633+ * @sa @ref events
4634+ * @sa @ref glfwPollEvents
4635+ * @sa @ref glfwWaitEvents
4636+ *
4637+ * @since Added in version 3.2.
4638+ *
4639+ * @ingroup window
4640+ */
4641+GLFWAPI void glfwWaitEventsTimeout(double timeout);
4642+
4643+/*! @brief Posts an empty event to the event queue.
4644+ *
4645+ * This function posts an empty event from the current thread to the event
4646+ * queue, causing @ref glfwWaitEvents or @ref glfwWaitEventsTimeout to return.
4647+ *
4648+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
4649+ * GLFW_PLATFORM_ERROR.
4650+ *
4651+ * @thread_safety This function may be called from any thread.
4652+ *
4653+ * @sa @ref events
4654+ * @sa @ref glfwWaitEvents
4655+ * @sa @ref glfwWaitEventsTimeout
4656+ *
4657+ * @since Added in version 3.1.
4658+ *
4659+ * @ingroup window
4660+ */
4661+GLFWAPI void glfwPostEmptyEvent(void);
4662+
4663+/*! @brief Returns the value of an input option for the specified window.
4664+ *
4665+ * This function returns the value of an input option for the specified window.
4666+ * The mode must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS,
4667+ * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or
4668+ * @ref GLFW_RAW_MOUSE_MOTION.
4669+ *
4670+ * @param[in] window The window to query.
4671+ * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`,
4672+ * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or
4673+ * `GLFW_RAW_MOUSE_MOTION`.
4674+ *
4675+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
4676+ * GLFW_INVALID_ENUM.
4677+ *
4678+ * @thread_safety This function must only be called from the main thread.
4679+ *
4680+ * @sa @ref glfwSetInputMode
4681+ *
4682+ * @since Added in version 3.0.
4683+ *
4684+ * @ingroup input
4685+ */
4686+GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
4687+
4688+/*! @brief Sets an input option for the specified window.
4689+ *
4690+ * This function sets an input mode option for the specified window. The mode
4691+ * must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS,
4692+ * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS
4693+ * @ref GLFW_RAW_MOUSE_MOTION, or @ref GLFW_UNLIMITED_MOUSE_BUTTONS.
4694+ *
4695+ * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
4696+ * modes:
4697+ * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally.
4698+ * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the
4699+ * content area of the window but does not restrict the cursor from leaving.
4700+ * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual
4701+ * and unlimited cursor movement. This is useful for implementing for
4702+ * example 3D camera controls.
4703+ * - `GLFW_CURSOR_CAPTURED` makes the cursor visible and confines it to the
4704+ * content area of the window.
4705+ *
4706+ * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to
4707+ * enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are
4708+ * enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS`
4709+ * the next time it is called even if the key had been released before the
4710+ * call. This is useful when you are only interested in whether keys have been
4711+ * pressed but not when or in which order.
4712+ *
4713+ * If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either
4714+ * `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it.
4715+ * If sticky mouse buttons are enabled, a mouse button press will ensure that
4716+ * @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even
4717+ * if the mouse button had been released before the call. This is useful when
4718+ * you are only interested in whether mouse buttons have been pressed but not
4719+ * when or in which order.
4720+ *
4721+ * If the mode is `GLFW_LOCK_KEY_MODS`, the value must be either `GLFW_TRUE` to
4722+ * enable lock key modifier bits, or `GLFW_FALSE` to disable them. If enabled,
4723+ * callbacks that receive modifier bits will also have the @ref
4724+ * GLFW_MOD_CAPS_LOCK bit set when the event was generated with Caps Lock on,
4725+ * and the @ref GLFW_MOD_NUM_LOCK bit when Num Lock was on.
4726+ *
4727+ * If the mode is `GLFW_RAW_MOUSE_MOTION`, the value must be either `GLFW_TRUE`
4728+ * to enable raw (unscaled and unaccelerated) mouse motion when the cursor is
4729+ * disabled, or `GLFW_FALSE` to disable it. If raw motion is not supported,
4730+ * attempting to set this will emit @ref GLFW_FEATURE_UNAVAILABLE. Call @ref
4731+ * glfwRawMouseMotionSupported to check for support.
4732+ *
4733+ * If the mode is `GLFW_UNLIMITED_MOUSE_BUTTONS`, the value must be either
4734+ * `GLFW_TRUE` to disable the mouse button limit when calling the mouse button
4735+ * callback, or `GLFW_FALSE` to limit the mouse buttons sent to the callback
4736+ * to the mouse button token values up to `GLFW_MOUSE_BUTTON_LAST`.
4737+ *
4738+ * @param[in] window The window whose input mode to set.
4739+ * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`,
4740+ * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or
4741+ * `GLFW_RAW_MOUSE_MOTION`.
4742+ * @param[in] value The new value of the specified input mode.
4743+ *
4744+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
4745+ * GLFW_INVALID_ENUM, @ref GLFW_PLATFORM_ERROR and @ref
4746+ * GLFW_FEATURE_UNAVAILABLE (see above).
4747+ *
4748+ * @thread_safety This function must only be called from the main thread.
4749+ *
4750+ * @sa @ref glfwGetInputMode
4751+ *
4752+ * @since Added in version 3.0. Replaces `glfwEnable` and `glfwDisable`.
4753+ *
4754+ * @ingroup input
4755+ */
4756+GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);
4757+
4758+/*! @brief Returns whether raw mouse motion is supported.
4759+ *
4760+ * This function returns whether raw mouse motion is supported on the current
4761+ * system. This status does not change after GLFW has been initialized so you
4762+ * only need to check this once. If you attempt to enable raw motion on
4763+ * a system that does not support it, @ref GLFW_PLATFORM_ERROR will be emitted.
4764+ *
4765+ * Raw mouse motion is closer to the actual motion of the mouse across
4766+ * a surface. It is not affected by the scaling and acceleration applied to
4767+ * the motion of the desktop cursor. That processing is suitable for a cursor
4768+ * while raw motion is better for controlling for example a 3D camera. Because
4769+ * of this, raw mouse motion is only provided when the cursor is disabled.
4770+ *
4771+ * @return `GLFW_TRUE` if raw mouse motion is supported on the current machine,
4772+ * or `GLFW_FALSE` otherwise.
4773+ *
4774+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
4775+ *
4776+ * @thread_safety This function must only be called from the main thread.
4777+ *
4778+ * @sa @ref raw_mouse_motion
4779+ * @sa @ref glfwSetInputMode
4780+ *
4781+ * @since Added in version 3.3.
4782+ *
4783+ * @ingroup input
4784+ */
4785+GLFWAPI int glfwRawMouseMotionSupported(void);
4786+
4787+/*! @brief Returns the layout-specific name of the specified printable key.
4788+ *
4789+ * This function returns the name of the specified printable key, encoded as
4790+ * UTF-8. This is typically the character that key would produce without any
4791+ * modifier keys, intended for displaying key bindings to the user. For dead
4792+ * keys, it is typically the diacritic it would add to a character.
4793+ *
4794+ * __Do not use this function__ for [text input](@ref input_char). You will
4795+ * break text input for many languages even if it happens to work for yours.
4796+ *
4797+ * If the key is `GLFW_KEY_UNKNOWN`, the scancode is used to identify the key,
4798+ * otherwise the scancode is ignored. If you specify a non-printable key, or
4799+ * `GLFW_KEY_UNKNOWN` and a scancode that maps to a non-printable key, this
4800+ * function returns `NULL` but does not emit an error.
4801+ *
4802+ * This behavior allows you to always pass in the arguments in the
4803+ * [key callback](@ref input_key) without modification.
4804+ *
4805+ * The printable keys are:
4806+ * - `GLFW_KEY_APOSTROPHE`
4807+ * - `GLFW_KEY_COMMA`
4808+ * - `GLFW_KEY_MINUS`
4809+ * - `GLFW_KEY_PERIOD`
4810+ * - `GLFW_KEY_SLASH`
4811+ * - `GLFW_KEY_SEMICOLON`
4812+ * - `GLFW_KEY_EQUAL`
4813+ * - `GLFW_KEY_LEFT_BRACKET`
4814+ * - `GLFW_KEY_RIGHT_BRACKET`
4815+ * - `GLFW_KEY_BACKSLASH`
4816+ * - `GLFW_KEY_WORLD_1`
4817+ * - `GLFW_KEY_WORLD_2`
4818+ * - `GLFW_KEY_0` to `GLFW_KEY_9`
4819+ * - `GLFW_KEY_A` to `GLFW_KEY_Z`
4820+ * - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9`
4821+ * - `GLFW_KEY_KP_DECIMAL`
4822+ * - `GLFW_KEY_KP_DIVIDE`
4823+ * - `GLFW_KEY_KP_MULTIPLY`
4824+ * - `GLFW_KEY_KP_SUBTRACT`
4825+ * - `GLFW_KEY_KP_ADD`
4826+ * - `GLFW_KEY_KP_EQUAL`
4827+ *
4828+ * Names for printable keys depend on keyboard layout, while names for
4829+ * non-printable keys are the same across layouts but depend on the application
4830+ * language and should be localized along with other user interface text.
4831+ *
4832+ * @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`.
4833+ * @param[in] scancode The scancode of the key to query.
4834+ * @return The UTF-8 encoded, layout-specific name of the key, or `NULL`.
4835+ *
4836+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
4837+ * GLFW_INVALID_VALUE, @ref GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
4838+ *
4839+ * @remark The contents of the returned string may change when a keyboard
4840+ * layout change event is received.
4841+ *
4842+ * @pointer_lifetime The returned string is allocated and freed by GLFW. You
4843+ * should not free it yourself. It is valid until the library is terminated.
4844+ *
4845+ * @thread_safety This function must only be called from the main thread.
4846+ *
4847+ * @sa @ref input_key_name
4848+ *
4849+ * @since Added in version 3.2.
4850+ *
4851+ * @ingroup input
4852+ */
4853+GLFWAPI const char* glfwGetKeyName(int key, int scancode);
4854+
4855+/*! @brief Returns the platform-specific scancode of the specified key.
4856+ *
4857+ * This function returns the platform-specific scancode of the specified key.
4858+ *
4859+ * If the specified [key token](@ref keys) corresponds to a physical key not
4860+ * supported on the current platform then this method will return `-1`.
4861+ * Calling this function with anything other than a key token will return `-1`
4862+ * and generate a @ref GLFW_INVALID_ENUM error.
4863+ *
4864+ * @param[in] key Any [key token](@ref keys).
4865+ * @return The platform-specific scancode for the key, or `-1` if the key is
4866+ * not supported on the current platform or an [error](@ref error_handling)
4867+ * occurred.
4868+ *
4869+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
4870+ * GLFW_INVALID_ENUM.
4871+ *
4872+ * @thread_safety This function may be called from any thread.
4873+ *
4874+ * @sa @ref input_key
4875+ *
4876+ * @since Added in version 3.3.
4877+ *
4878+ * @ingroup input
4879+ */
4880+GLFWAPI int glfwGetKeyScancode(int key);
4881+
4882+/*! @brief Returns the last reported state of a keyboard key for the specified
4883+ * window.
4884+ *
4885+ * This function returns the last state reported for the specified key to the
4886+ * specified window. The returned state is one of `GLFW_PRESS` or
4887+ * `GLFW_RELEASE`. The action `GLFW_REPEAT` is only reported to the key callback.
4888+ *
4889+ * If the @ref GLFW_STICKY_KEYS input mode is enabled, this function returns
4890+ * `GLFW_PRESS` the first time you call it for a key that was pressed, even if
4891+ * that key has already been released.
4892+ *
4893+ * The key functions deal with physical keys, with [key tokens](@ref keys)
4894+ * named after their use on the standard US keyboard layout. If you want to
4895+ * input text, use the Unicode character callback instead.
4896+ *
4897+ * The [modifier key bit masks](@ref mods) are not key tokens and cannot be
4898+ * used with this function.
4899+ *
4900+ * __Do not use this function__ to implement [text input](@ref input_char).
4901+ *
4902+ * @param[in] window The desired window.
4903+ * @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is
4904+ * not a valid key for this function.
4905+ * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
4906+ *
4907+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
4908+ * GLFW_INVALID_ENUM.
4909+ *
4910+ * @thread_safety This function must only be called from the main thread.
4911+ *
4912+ * @sa @ref input_key
4913+ *
4914+ * @since Added in version 1.0.
4915+ * __GLFW 3:__ Added window handle parameter.
4916+ *
4917+ * @ingroup input
4918+ */
4919+GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
4920+
4921+/*! @brief Returns the last reported state of a mouse button for the specified
4922+ * window.
4923+ *
4924+ * This function returns the last state reported for the specified mouse button
4925+ * to the specified window. The returned state is one of `GLFW_PRESS` or
4926+ * `GLFW_RELEASE`.
4927+ *
4928+ * If the @ref GLFW_STICKY_MOUSE_BUTTONS input mode is enabled, this function
4929+ * returns `GLFW_PRESS` the first time you call it for a mouse button that was
4930+ * pressed, even if that mouse button has already been released.
4931+ *
4932+ * The @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode does not effect the
4933+ * limit on buttons which can be polled with this function.
4934+ *
4935+ * @param[in] window The desired window.
4936+ * @param[in] button The desired [mouse button token](@ref buttons).
4937+ * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
4938+ *
4939+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
4940+ * GLFW_INVALID_ENUM.
4941+ *
4942+ * @thread_safety This function must only be called from the main thread.
4943+ *
4944+ * @sa @ref input_mouse_button
4945+ *
4946+ * @since Added in version 1.0.
4947+ * __GLFW 3:__ Added window handle parameter.
4948+ *
4949+ * @ingroup input
4950+ */
4951+GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
4952+
4953+/*! @brief Retrieves the position of the cursor relative to the content area of
4954+ * the window.
4955+ *
4956+ * This function returns the position of the cursor, in screen coordinates,
4957+ * relative to the upper-left corner of the content area of the specified
4958+ * window.
4959+ *
4960+ * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor
4961+ * position is unbounded and limited only by the minimum and maximum values of
4962+ * a `double`.
4963+ *
4964+ * The coordinate can be converted to their integer equivalents with the
4965+ * `floor` function. Casting directly to an integer type works for positive
4966+ * coordinates, but fails for negative ones.
4967+ *
4968+ * Any or all of the position arguments may be `NULL`. If an error occurs, all
4969+ * non-`NULL` position arguments will be set to zero.
4970+ *
4971+ * @param[in] window The desired window.
4972+ * @param[out] xpos Where to store the cursor x-coordinate, relative to the
4973+ * left edge of the content area, or `NULL`.
4974+ * @param[out] ypos Where to store the cursor y-coordinate, relative to the to
4975+ * top edge of the content area, or `NULL`.
4976+ *
4977+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
4978+ * GLFW_PLATFORM_ERROR.
4979+ *
4980+ * @thread_safety This function must only be called from the main thread.
4981+ *
4982+ * @sa @ref cursor_pos
4983+ * @sa @ref glfwSetCursorPos
4984+ *
4985+ * @since Added in version 3.0. Replaces `glfwGetMousePos`.
4986+ *
4987+ * @ingroup input
4988+ */
4989+GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
4990+
4991+/*! @brief Sets the position of the cursor, relative to the content area of the
4992+ * window.
4993+ *
4994+ * This function sets the position, in screen coordinates, of the cursor
4995+ * relative to the upper-left corner of the content area of the specified
4996+ * window. The window must have input focus. If the window does not have
4997+ * input focus when this function is called, it fails silently.
4998+ *
4999+ * __Do not use this function__ to implement things like camera controls. GLFW
5000+ * already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the
5001+ * cursor, transparently re-centers it and provides unconstrained cursor
5002+ * motion. See @ref glfwSetInputMode for more information.
5003+ *
5004+ * If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is
5005+ * unconstrained and limited only by the minimum and maximum values of
5006+ * a `double`.
5007+ *
5008+ * @param[in] window The desired window.
5009+ * @param[in] xpos The desired x-coordinate, relative to the left edge of the
5010+ * content area.
5011+ * @param[in] ypos The desired y-coordinate, relative to the top edge of the
5012+ * content area.
5013+ *
5014+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
5015+ * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
5016+ *
5017+ * @remark __Wayland:__ This function will only work when the cursor mode is
5018+ * `GLFW_CURSOR_DISABLED`, otherwise it will emit @ref GLFW_FEATURE_UNAVAILABLE.
5019+ *
5020+ * @thread_safety This function must only be called from the main thread.
5021+ *
5022+ * @sa @ref cursor_pos
5023+ * @sa @ref glfwGetCursorPos
5024+ *
5025+ * @since Added in version 3.0. Replaces `glfwSetMousePos`.
5026+ *
5027+ * @ingroup input
5028+ */
5029+GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
5030+
5031+/*! @brief Creates a custom cursor.
5032+ *
5033+ * Creates a new custom cursor image that can be set for a window with @ref
5034+ * glfwSetCursor. The cursor can be destroyed with @ref glfwDestroyCursor.
5035+ * Any remaining cursors are destroyed by @ref glfwTerminate.
5036+ *
5037+ * The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight
5038+ * bits per channel with the red channel first. They are arranged canonically
5039+ * as packed sequential rows, starting from the top-left corner.
5040+ *
5041+ * The cursor hotspot is specified in pixels, relative to the upper-left corner
5042+ * of the cursor image. Like all other coordinate systems in GLFW, the X-axis
5043+ * points to the right and the Y-axis points down.
5044+ *
5045+ * @param[in] image The desired cursor image.
5046+ * @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot.
5047+ * @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot.
5048+ * @return The handle of the created cursor, or `NULL` if an
5049+ * [error](@ref error_handling) occurred.
5050+ *
5051+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
5052+ * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
5053+ *
5054+ * @pointer_lifetime The specified image data is copied before this function
5055+ * returns.
5056+ *
5057+ * @thread_safety This function must only be called from the main thread.
5058+ *
5059+ * @sa @ref cursor_object
5060+ * @sa @ref glfwDestroyCursor
5061+ * @sa @ref glfwCreateStandardCursor
5062+ *
5063+ * @since Added in version 3.1.
5064+ *
5065+ * @ingroup input
5066+ */
5067+GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);
5068+
5069+/*! @brief Creates a cursor with a standard shape.
5070+ *
5071+ * Returns a cursor with a standard shape, that can be set for a window with
5072+ * @ref glfwSetCursor. The images for these cursors come from the system
5073+ * cursor theme and their exact appearance will vary between platforms.
5074+ *
5075+ * Most of these shapes are guaranteed to exist on every supported platform but
5076+ * a few may not be present. See the table below for details.
5077+ *
5078+ * Cursor shape | Windows | macOS | X11 | Wayland
5079+ * ------------------------------ | ------- | ----- | ------ | -------
5080+ * @ref GLFW_ARROW_CURSOR | Yes | Yes | Yes | Yes
5081+ * @ref GLFW_IBEAM_CURSOR | Yes | Yes | Yes | Yes
5082+ * @ref GLFW_CROSSHAIR_CURSOR | Yes | Yes | Yes | Yes
5083+ * @ref GLFW_POINTING_HAND_CURSOR | Yes | Yes | Yes | Yes
5084+ * @ref GLFW_RESIZE_EW_CURSOR | Yes | Yes | Yes | Yes
5085+ * @ref GLFW_RESIZE_NS_CURSOR | Yes | Yes | Yes | Yes
5086+ * @ref GLFW_RESIZE_NWSE_CURSOR | Yes | Yes<sup>1</sup> | Maybe<sup>2</sup> | Maybe<sup>2</sup>
5087+ * @ref GLFW_RESIZE_NESW_CURSOR | Yes | Yes<sup>1</sup> | Maybe<sup>2</sup> | Maybe<sup>2</sup>
5088+ * @ref GLFW_RESIZE_ALL_CURSOR | Yes | Yes | Yes | Yes
5089+ * @ref GLFW_NOT_ALLOWED_CURSOR | Yes | Yes | Maybe<sup>2</sup> | Maybe<sup>2</sup>
5090+ *
5091+ * 1) This uses a private system API and may fail in the future.
5092+ *
5093+ * 2) This uses a newer standard that not all cursor themes support.
5094+ *
5095+ * If the requested shape is not available, this function emits a @ref
5096+ * GLFW_CURSOR_UNAVAILABLE error and returns `NULL`.
5097+ *
5098+ * @param[in] shape One of the [standard shapes](@ref shapes).
5099+ * @return A new cursor ready to use or `NULL` if an
5100+ * [error](@ref error_handling) occurred.
5101+ *
5102+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
5103+ * GLFW_INVALID_ENUM, @ref GLFW_CURSOR_UNAVAILABLE and @ref
5104+ * GLFW_PLATFORM_ERROR.
5105+ *
5106+ * @thread_safety This function must only be called from the main thread.
5107+ *
5108+ * @sa @ref cursor_standard
5109+ * @sa @ref glfwCreateCursor
5110+ *
5111+ * @since Added in version 3.1.
5112+ *
5113+ * @ingroup input
5114+ */
5115+GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);
5116+
5117+/*! @brief Destroys a cursor.
5118+ *
5119+ * This function destroys a cursor previously created with @ref
5120+ * glfwCreateCursor. Any remaining cursors will be destroyed by @ref
5121+ * glfwTerminate.
5122+ *
5123+ * If the specified cursor is current for any window, that window will be
5124+ * reverted to the default cursor. This does not affect the cursor mode.
5125+ *
5126+ * @param[in] cursor The cursor object to destroy.
5127+ *
5128+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
5129+ * GLFW_PLATFORM_ERROR.
5130+ *
5131+ * @reentrancy This function must not be called from a callback.
5132+ *
5133+ * @thread_safety This function must only be called from the main thread.
5134+ *
5135+ * @sa @ref cursor_object
5136+ * @sa @ref glfwCreateCursor
5137+ *
5138+ * @since Added in version 3.1.
5139+ *
5140+ * @ingroup input
5141+ */
5142+GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);
5143+
5144+/*! @brief Sets the cursor for the window.
5145+ *
5146+ * This function sets the cursor image to be used when the cursor is over the
5147+ * content area of the specified window. The set cursor will only be visible
5148+ * when the [cursor mode](@ref cursor_mode) of the window is
5149+ * `GLFW_CURSOR_NORMAL`.
5150+ *
5151+ * On some platforms, the set cursor may not be visible unless the window also
5152+ * has input focus.
5153+ *
5154+ * @param[in] window The window to set the cursor for.
5155+ * @param[in] cursor The cursor to set, or `NULL` to switch back to the default
5156+ * arrow cursor.
5157+ *
5158+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
5159+ * GLFW_PLATFORM_ERROR.
5160+ *
5161+ * @thread_safety This function must only be called from the main thread.
5162+ *
5163+ * @sa @ref cursor_object
5164+ *
5165+ * @since Added in version 3.1.
5166+ *
5167+ * @ingroup input
5168+ */
5169+GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
5170+
5171+/*! @brief Sets the key callback.
5172+ *
5173+ * This function sets the key callback of the specified window, which is called
5174+ * when a key is pressed, repeated or released.
5175+ *
5176+ * The key functions deal with physical keys, with layout independent
5177+ * [key tokens](@ref keys) named after their values in the standard US keyboard
5178+ * layout. If you want to input text, use the
5179+ * [character callback](@ref glfwSetCharCallback) instead.
5180+ *
5181+ * When a window loses input focus, it will generate synthetic key release
5182+ * events for all pressed keys with associated key tokens. You can tell these
5183+ * events from user-generated events by the fact that the synthetic ones are
5184+ * generated after the focus loss event has been processed, i.e. after the
5185+ * [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
5186+ *
5187+ * The scancode of a key is specific to that platform or sometimes even to that
5188+ * machine. Scancodes are intended to allow users to bind keys that don't have
5189+ * a GLFW key token. Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their
5190+ * state is not saved and so it cannot be queried with @ref glfwGetKey.
5191+ *
5192+ * Sometimes GLFW needs to generate synthetic key events, in which case the
5193+ * scancode may be zero.
5194+ *
5195+ * @param[in] window The window whose callback to set.
5196+ * @param[in] callback The new key callback, or `NULL` to remove the currently
5197+ * set callback.
5198+ * @return The previously set callback, or `NULL` if no callback was set or the
5199+ * library had not been [initialized](@ref intro_init).
5200+ *
5201+ * @callback_signature
5202+ * @code
5203+ * void function_name(GLFWwindow* window, int key, int scancode, int action, int mods)
5204+ * @endcode
5205+ * For more information about the callback parameters, see the
5206+ * [function pointer type](@ref GLFWkeyfun).
5207+ *
5208+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
5209+ *
5210+ * @thread_safety This function must only be called from the main thread.
5211+ *
5212+ * @sa @ref input_key
5213+ *
5214+ * @since Added in version 1.0.
5215+ * __GLFW 3:__ Added window handle parameter and return value.
5216+ *
5217+ * @ingroup input
5218+ */
5219+GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun callback);
5220+
5221+/*! @brief Sets the Unicode character callback.
5222+ *
5223+ * This function sets the character callback of the specified window, which is
5224+ * called when a Unicode character is input.
5225+ *
5226+ * The character callback is intended for Unicode text input. As it deals with
5227+ * characters, it is keyboard layout dependent, whereas the
5228+ * [key callback](@ref glfwSetKeyCallback) is not. Characters do not map 1:1
5229+ * to physical keys, as a key may produce zero, one or more characters. If you
5230+ * want to know whether a specific physical key was pressed or released, see
5231+ * the key callback instead.
5232+ *
5233+ * The character callback behaves as system text input normally does and will
5234+ * not be called if modifier keys are held down that would prevent normal text
5235+ * input on that platform, for example a Super (Command) key on macOS or Alt key
5236+ * on Windows.
5237+ *
5238+ * @param[in] window The window whose callback to set.
5239+ * @param[in] callback The new callback, or `NULL` to remove the currently set
5240+ * callback.
5241+ * @return The previously set callback, or `NULL` if no callback was set or the
5242+ * library had not been [initialized](@ref intro_init).
5243+ *
5244+ * @callback_signature
5245+ * @code
5246+ * void function_name(GLFWwindow* window, unsigned int codepoint)
5247+ * @endcode
5248+ * For more information about the callback parameters, see the
5249+ * [function pointer type](@ref GLFWcharfun).
5250+ *
5251+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
5252+ *
5253+ * @thread_safety This function must only be called from the main thread.
5254+ *
5255+ * @sa @ref input_char
5256+ *
5257+ * @since Added in version 2.4.
5258+ * __GLFW 3:__ Added window handle parameter and return value.
5259+ *
5260+ * @ingroup input
5261+ */
5262+GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun callback);
5263+
5264+/*! @brief Sets the Unicode character with modifiers callback.
5265+ *
5266+ * This function sets the character with modifiers callback of the specified
5267+ * window, which is called when a Unicode character is input regardless of what
5268+ * modifier keys are used.
5269+ *
5270+ * The character with modifiers callback is intended for implementing custom
5271+ * Unicode character input. For regular Unicode text input, see the
5272+ * [character callback](@ref glfwSetCharCallback). Like the character
5273+ * callback, the character with modifiers callback deals with characters and is
5274+ * keyboard layout dependent. Characters do not map 1:1 to physical keys, as
5275+ * a key may produce zero, one or more characters. If you want to know whether
5276+ * a specific physical key was pressed or released, see the
5277+ * [key callback](@ref glfwSetKeyCallback) instead.
5278+ *
5279+ * @param[in] window The window whose callback to set.
5280+ * @param[in] callback The new callback, or `NULL` to remove the currently set
5281+ * callback.
5282+ * @return The previously set callback, or `NULL` if no callback was set or an
5283+ * [error](@ref error_handling) occurred.
5284+ *
5285+ * @callback_signature
5286+ * @code
5287+ * void function_name(GLFWwindow* window, unsigned int codepoint, int mods)
5288+ * @endcode
5289+ * For more information about the callback parameters, see the
5290+ * [function pointer type](@ref GLFWcharmodsfun).
5291+ *
5292+ * @deprecated Scheduled for removal in version 4.0.
5293+ *
5294+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
5295+ *
5296+ * @thread_safety This function must only be called from the main thread.
5297+ *
5298+ * @sa @ref input_char
5299+ *
5300+ * @since Added in version 3.1.
5301+ *
5302+ * @ingroup input
5303+ */
5304+GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun callback);
5305+
5306+/*! @brief Sets the mouse button callback.
5307+ *
5308+ * This function sets the mouse button callback of the specified window, which
5309+ * is called when a mouse button is pressed or released.
5310+ *
5311+ * When a window loses input focus, it will generate synthetic mouse button
5312+ * release events for all pressed mouse buttons with associated button tokens.
5313+ * You can tell these events from user-generated events by the fact that the
5314+ * synthetic ones are generated after the focus loss event has been processed,
5315+ * i.e. after the [window focus callback](@ref glfwSetWindowFocusCallback) has
5316+ * been called.
5317+ *
5318+ * The reported `button` value can be higher than `GLFW_MOUSE_BUTTON_LAST` if
5319+ * the button does not have an associated [button token](@ref buttons) and the
5320+ * @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode is set.
5321+ *
5322+ * @param[in] window The window whose callback to set.
5323+ * @param[in] callback The new callback, or `NULL` to remove the currently set
5324+ * callback.
5325+ * @return The previously set callback, or `NULL` if no callback was set or the
5326+ * library had not been [initialized](@ref intro_init).
5327+ *
5328+ * @callback_signature
5329+ * @code
5330+ * void function_name(GLFWwindow* window, int button, int action, int mods)
5331+ * @endcode
5332+ * For more information about the callback parameters, see the
5333+ * [function pointer type](@ref GLFWmousebuttonfun).
5334+ *
5335+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
5336+ *
5337+ * @thread_safety This function must only be called from the main thread.
5338+ *
5339+ * @sa @ref input_mouse_button
5340+ *
5341+ * @since Added in version 1.0.
5342+ * __GLFW 3:__ Added window handle parameter and return value.
5343+ *
5344+ * @ingroup input
5345+ */
5346+GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun callback);
5347+
5348+/*! @brief Sets the cursor position callback.
5349+ *
5350+ * This function sets the cursor position callback of the specified window,
5351+ * which is called when the cursor is moved. The callback is provided with the
5352+ * position, in screen coordinates, relative to the upper-left corner of the
5353+ * content area of the window.
5354+ *
5355+ * @param[in] window The window whose callback to set.
5356+ * @param[in] callback The new callback, or `NULL` to remove the currently set
5357+ * callback.
5358+ * @return The previously set callback, or `NULL` if no callback was set or the
5359+ * library had not been [initialized](@ref intro_init).
5360+ *
5361+ * @callback_signature
5362+ * @code
5363+ * void function_name(GLFWwindow* window, double xpos, double ypos);
5364+ * @endcode
5365+ * For more information about the callback parameters, see the
5366+ * [function pointer type](@ref GLFWcursorposfun).
5367+ *
5368+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
5369+ *
5370+ * @thread_safety This function must only be called from the main thread.
5371+ *
5372+ * @sa @ref cursor_pos
5373+ *
5374+ * @since Added in version 3.0. Replaces `glfwSetMousePosCallback`.
5375+ *
5376+ * @ingroup input
5377+ */
5378+GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun callback);
5379+
5380+/*! @brief Sets the cursor enter/leave callback.
5381+ *
5382+ * This function sets the cursor boundary crossing callback of the specified
5383+ * window, which is called when the cursor enters or leaves the content area of
5384+ * the window.
5385+ *
5386+ * @param[in] window The window whose callback to set.
5387+ * @param[in] callback The new callback, or `NULL` to remove the currently set
5388+ * callback.
5389+ * @return The previously set callback, or `NULL` if no callback was set or the
5390+ * library had not been [initialized](@ref intro_init).
5391+ *
5392+ * @callback_signature
5393+ * @code
5394+ * void function_name(GLFWwindow* window, int entered)
5395+ * @endcode
5396+ * For more information about the callback parameters, see the
5397+ * [function pointer type](@ref GLFWcursorenterfun).
5398+ *
5399+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
5400+ *
5401+ * @thread_safety This function must only be called from the main thread.
5402+ *
5403+ * @sa @ref cursor_enter
5404+ *
5405+ * @since Added in version 3.0.
5406+ *
5407+ * @ingroup input
5408+ */
5409+GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun callback);
5410+
5411+/*! @brief Sets the scroll callback.
5412+ *
5413+ * This function sets the scroll callback of the specified window, which is
5414+ * called when a scrolling device is used, such as a mouse wheel or scrolling
5415+ * area of a touchpad.
5416+ *
5417+ * The scroll callback receives all scrolling input, like that from a mouse
5418+ * wheel or a touchpad scrolling area.
5419+ *
5420+ * @param[in] window The window whose callback to set.
5421+ * @param[in] callback The new scroll callback, or `NULL` to remove the
5422+ * currently set callback.
5423+ * @return The previously set callback, or `NULL` if no callback was set or the
5424+ * library had not been [initialized](@ref intro_init).
5425+ *
5426+ * @callback_signature
5427+ * @code
5428+ * void function_name(GLFWwindow* window, double xoffset, double yoffset)
5429+ * @endcode
5430+ * For more information about the callback parameters, see the
5431+ * [function pointer type](@ref GLFWscrollfun).
5432+ *
5433+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
5434+ *
5435+ * @thread_safety This function must only be called from the main thread.
5436+ *
5437+ * @sa @ref scrolling
5438+ *
5439+ * @since Added in version 3.0. Replaces `glfwSetMouseWheelCallback`.
5440+ *
5441+ * @ingroup input
5442+ */
5443+GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun callback);
5444+
5445+/*! @brief Sets the path drop callback.
5446+ *
5447+ * This function sets the path drop callback of the specified window, which is
5448+ * called when one or more dragged paths are dropped on the window.
5449+ *
5450+ * Because the path array and its strings may have been generated specifically
5451+ * for that event, they are not guaranteed to be valid after the callback has
5452+ * returned. If you wish to use them after the callback returns, you need to
5453+ * make a deep copy.
5454+ *
5455+ * @param[in] window The window whose callback to set.
5456+ * @param[in] callback The new file drop callback, or `NULL` to remove the
5457+ * currently set callback.
5458+ * @return The previously set callback, or `NULL` if no callback was set or the
5459+ * library had not been [initialized](@ref intro_init).
5460+ *
5461+ * @callback_signature
5462+ * @code
5463+ * void function_name(GLFWwindow* window, int path_count, const char* paths[])
5464+ * @endcode
5465+ * For more information about the callback parameters, see the
5466+ * [function pointer type](@ref GLFWdropfun).
5467+ *
5468+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
5469+ *
5470+ * @thread_safety This function must only be called from the main thread.
5471+ *
5472+ * @sa @ref path_drop
5473+ *
5474+ * @since Added in version 3.1.
5475+ *
5476+ * @ingroup input
5477+ */
5478+GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun callback);
5479+
5480+/*! @brief Returns whether the specified joystick is present.
5481+ *
5482+ * This function returns whether the specified joystick is present.
5483+ *
5484+ * There is no need to call this function before other functions that accept
5485+ * a joystick ID, as they all check for presence before performing any other
5486+ * work.
5487+ *
5488+ * @param[in] jid The [joystick](@ref joysticks) to query.
5489+ * @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise.
5490+ *
5491+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
5492+ * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
5493+ *
5494+ * @thread_safety This function must only be called from the main thread.
5495+ *
5496+ * @sa @ref joystick
5497+ *
5498+ * @since Added in version 3.0. Replaces `glfwGetJoystickParam`.
5499+ *
5500+ * @ingroup input
5501+ */
5502+GLFWAPI int glfwJoystickPresent(int jid);
5503+
5504+/*! @brief Returns the values of all axes of the specified joystick.
5505+ *
5506+ * This function returns the values of all axes of the specified joystick.
5507+ * Each element in the array is a value between -1.0 and 1.0.
5508+ *
5509+ * If the specified joystick is not present this function will return `NULL`
5510+ * but will not generate an error. This can be used instead of first calling
5511+ * @ref glfwJoystickPresent.
5512+ *
5513+ * @param[in] jid The [joystick](@ref joysticks) to query.
5514+ * @param[out] count Where to store the number of axis values in the returned
5515+ * array. This is set to zero if the joystick is not present or an error
5516+ * occurred.
5517+ * @return An array of axis values, or `NULL` if the joystick is not present or
5518+ * an [error](@ref error_handling) occurred.
5519+ *
5520+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
5521+ * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
5522+ *
5523+ * @pointer_lifetime The returned array is allocated and freed by GLFW. You
5524+ * should not free it yourself. It is valid until the specified joystick is
5525+ * disconnected or the library is terminated.
5526+ *
5527+ * @thread_safety This function must only be called from the main thread.
5528+ *
5529+ * @sa @ref joystick_axis
5530+ *
5531+ * @since Added in version 3.0. Replaces `glfwGetJoystickPos`.
5532+ *
5533+ * @ingroup input
5534+ */
5535+GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count);
5536+
5537+/*! @brief Returns the state of all buttons of the specified joystick.
5538+ *
5539+ * This function returns the state of all buttons of the specified joystick.
5540+ * Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`.
5541+ *
5542+ * For backward compatibility with earlier versions that did not have @ref
5543+ * glfwGetJoystickHats, the button array also includes all hats, each
5544+ * represented as four buttons. The hats are in the same order as returned by
5545+ * __glfwGetJoystickHats__ and are in the order _up_, _right_, _down_ and
5546+ * _left_. To disable these extra buttons, set the @ref
5547+ * GLFW_JOYSTICK_HAT_BUTTONS init hint before initialization.
5548+ *
5549+ * If the specified joystick is not present this function will return `NULL`
5550+ * but will not generate an error. This can be used instead of first calling
5551+ * @ref glfwJoystickPresent.
5552+ *
5553+ * @param[in] jid The [joystick](@ref joysticks) to query.
5554+ * @param[out] count Where to store the number of button states in the returned
5555+ * array. This is set to zero if the joystick is not present or an error
5556+ * occurred.
5557+ * @return An array of button states, or `NULL` if the joystick is not present
5558+ * or an [error](@ref error_handling) occurred.
5559+ *
5560+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
5561+ * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
5562+ *
5563+ * @pointer_lifetime The returned array is allocated and freed by GLFW. You
5564+ * should not free it yourself. It is valid until the specified joystick is
5565+ * disconnected or the library is terminated.
5566+ *
5567+ * @thread_safety This function must only be called from the main thread.
5568+ *
5569+ * @sa @ref joystick_button
5570+ *
5571+ * @since Added in version 2.2.
5572+ * __GLFW 3:__ Changed to return a dynamic array.
5573+ *
5574+ * @ingroup input
5575+ */
5576+GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count);
5577+
5578+/*! @brief Returns the state of all hats of the specified joystick.
5579+ *
5580+ * This function returns the state of all hats of the specified joystick.
5581+ * Each element in the array is one of the following values:
5582+ *
5583+ * Name | Value
5584+ * ---- | -----
5585+ * `GLFW_HAT_CENTERED` | 0
5586+ * `GLFW_HAT_UP` | 1
5587+ * `GLFW_HAT_RIGHT` | 2
5588+ * `GLFW_HAT_DOWN` | 4
5589+ * `GLFW_HAT_LEFT` | 8
5590+ * `GLFW_HAT_RIGHT_UP` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_UP`
5591+ * `GLFW_HAT_RIGHT_DOWN` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_DOWN`
5592+ * `GLFW_HAT_LEFT_UP` | `GLFW_HAT_LEFT` \| `GLFW_HAT_UP`
5593+ * `GLFW_HAT_LEFT_DOWN` | `GLFW_HAT_LEFT` \| `GLFW_HAT_DOWN`
5594+ *
5595+ * The diagonal directions are bitwise combinations of the primary (up, right,
5596+ * down and left) directions and you can test for these individually by ANDing
5597+ * it with the corresponding direction.
5598+ *
5599+ * @code
5600+ * if (hats[2] & GLFW_HAT_RIGHT)
5601+ * {
5602+ * // State of hat 2 could be right-up, right or right-down
5603+ * }
5604+ * @endcode
5605+ *
5606+ * If the specified joystick is not present this function will return `NULL`
5607+ * but will not generate an error. This can be used instead of first calling
5608+ * @ref glfwJoystickPresent.
5609+ *
5610+ * @param[in] jid The [joystick](@ref joysticks) to query.
5611+ * @param[out] count Where to store the number of hat states in the returned
5612+ * array. This is set to zero if the joystick is not present or an error
5613+ * occurred.
5614+ * @return An array of hat states, or `NULL` if the joystick is not present
5615+ * or an [error](@ref error_handling) occurred.
5616+ *
5617+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
5618+ * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
5619+ *
5620+ * @pointer_lifetime The returned array is allocated and freed by GLFW. You
5621+ * should not free it yourself. It is valid until the specified joystick is
5622+ * disconnected, this function is called again for that joystick or the library
5623+ * is terminated.
5624+ *
5625+ * @thread_safety This function must only be called from the main thread.
5626+ *
5627+ * @sa @ref joystick_hat
5628+ *
5629+ * @since Added in version 3.3.
5630+ *
5631+ * @ingroup input
5632+ */
5633+GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count);
5634+
5635+/*! @brief Returns the name of the specified joystick.
5636+ *
5637+ * This function returns the name, encoded as UTF-8, of the specified joystick.
5638+ * The returned string is allocated and freed by GLFW. You should not free it
5639+ * yourself.
5640+ *
5641+ * If the specified joystick is not present this function will return `NULL`
5642+ * but will not generate an error. This can be used instead of first calling
5643+ * @ref glfwJoystickPresent.
5644+ *
5645+ * @param[in] jid The [joystick](@ref joysticks) to query.
5646+ * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick
5647+ * is not present or an [error](@ref error_handling) occurred.
5648+ *
5649+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
5650+ * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
5651+ *
5652+ * @pointer_lifetime The returned string is allocated and freed by GLFW. You
5653+ * should not free it yourself. It is valid until the specified joystick is
5654+ * disconnected or the library is terminated.
5655+ *
5656+ * @thread_safety This function must only be called from the main thread.
5657+ *
5658+ * @sa @ref joystick_name
5659+ *
5660+ * @since Added in version 3.0.
5661+ *
5662+ * @ingroup input
5663+ */
5664+GLFWAPI const char* glfwGetJoystickName(int jid);
5665+
5666+/*! @brief Returns the SDL compatible GUID of the specified joystick.
5667+ *
5668+ * This function returns the SDL compatible GUID, as a UTF-8 encoded
5669+ * hexadecimal string, of the specified joystick. The returned string is
5670+ * allocated and freed by GLFW. You should not free it yourself.
5671+ *
5672+ * The GUID is what connects a joystick to a gamepad mapping. A connected
5673+ * joystick will always have a GUID even if there is no gamepad mapping
5674+ * assigned to it.
5675+ *
5676+ * If the specified joystick is not present this function will return `NULL`
5677+ * but will not generate an error. This can be used instead of first calling
5678+ * @ref glfwJoystickPresent.
5679+ *
5680+ * The GUID uses the format introduced in SDL 2.0.5. This GUID tries to
5681+ * uniquely identify the make and model of a joystick but does not identify
5682+ * a specific unit, e.g. all wired Xbox 360 controllers will have the same
5683+ * GUID on that platform. The GUID for a unit may vary between platforms
5684+ * depending on what hardware information the platform specific APIs provide.
5685+ *
5686+ * @param[in] jid The [joystick](@ref joysticks) to query.
5687+ * @return The UTF-8 encoded GUID of the joystick, or `NULL` if the joystick
5688+ * is not present or an [error](@ref error_handling) occurred.
5689+ *
5690+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
5691+ * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
5692+ *
5693+ * @pointer_lifetime The returned string is allocated and freed by GLFW. You
5694+ * should not free it yourself. It is valid until the specified joystick is
5695+ * disconnected or the library is terminated.
5696+ *
5697+ * @thread_safety This function must only be called from the main thread.
5698+ *
5699+ * @sa @ref gamepad
5700+ *
5701+ * @since Added in version 3.3.
5702+ *
5703+ * @ingroup input
5704+ */
5705+GLFWAPI const char* glfwGetJoystickGUID(int jid);
5706+
5707+/*! @brief Sets the user pointer of the specified joystick.
5708+ *
5709+ * This function sets the user-defined pointer of the specified joystick. The
5710+ * current value is retained until the joystick is disconnected. The initial
5711+ * value is `NULL`.
5712+ *
5713+ * This function may be called from the joystick callback, even for a joystick
5714+ * that is being disconnected.
5715+ *
5716+ * @param[in] jid The joystick whose pointer to set.
5717+ * @param[in] pointer The new value.
5718+ *
5719+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
5720+ *
5721+ * @thread_safety This function may be called from any thread. Access is not
5722+ * synchronized.
5723+ *
5724+ * @sa @ref joystick_userptr
5725+ * @sa @ref glfwGetJoystickUserPointer
5726+ *
5727+ * @since Added in version 3.3.
5728+ *
5729+ * @ingroup input
5730+ */
5731+GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer);
5732+
5733+/*! @brief Returns the user pointer of the specified joystick.
5734+ *
5735+ * This function returns the current value of the user-defined pointer of the
5736+ * specified joystick. The initial value is `NULL`.
5737+ *
5738+ * This function may be called from the joystick callback, even for a joystick
5739+ * that is being disconnected.
5740+ *
5741+ * @param[in] jid The joystick whose pointer to return.
5742+ *
5743+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
5744+ *
5745+ * @thread_safety This function may be called from any thread. Access is not
5746+ * synchronized.
5747+ *
5748+ * @sa @ref joystick_userptr
5749+ * @sa @ref glfwSetJoystickUserPointer
5750+ *
5751+ * @since Added in version 3.3.
5752+ *
5753+ * @ingroup input
5754+ */
5755+GLFWAPI void* glfwGetJoystickUserPointer(int jid);
5756+
5757+/*! @brief Returns whether the specified joystick has a gamepad mapping.
5758+ *
5759+ * This function returns whether the specified joystick is both present and has
5760+ * a gamepad mapping.
5761+ *
5762+ * If the specified joystick is present but does not have a gamepad mapping
5763+ * this function will return `GLFW_FALSE` but will not generate an error. Call
5764+ * @ref glfwJoystickPresent to check if a joystick is present regardless of
5765+ * whether it has a mapping.
5766+ *
5767+ * @param[in] jid The [joystick](@ref joysticks) to query.
5768+ * @return `GLFW_TRUE` if a joystick is both present and has a gamepad mapping,
5769+ * or `GLFW_FALSE` otherwise.
5770+ *
5771+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
5772+ * GLFW_INVALID_ENUM.
5773+ *
5774+ * @thread_safety This function must only be called from the main thread.
5775+ *
5776+ * @sa @ref gamepad
5777+ * @sa @ref glfwGetGamepadState
5778+ *
5779+ * @since Added in version 3.3.
5780+ *
5781+ * @ingroup input
5782+ */
5783+GLFWAPI int glfwJoystickIsGamepad(int jid);
5784+
5785+/*! @brief Sets the joystick configuration callback.
5786+ *
5787+ * This function sets the joystick configuration callback, or removes the
5788+ * currently set callback. This is called when a joystick is connected to or
5789+ * disconnected from the system.
5790+ *
5791+ * For joystick connection and disconnection events to be delivered on all
5792+ * platforms, you need to call one of the [event processing](@ref events)
5793+ * functions. Joystick disconnection may also be detected and the callback
5794+ * called by joystick functions. The function will then return whatever it
5795+ * returns if the joystick is not present.
5796+ *
5797+ * @param[in] callback The new callback, or `NULL` to remove the currently set
5798+ * callback.
5799+ * @return The previously set callback, or `NULL` if no callback was set or the
5800+ * library had not been [initialized](@ref intro_init).
5801+ *
5802+ * @callback_signature
5803+ * @code
5804+ * void function_name(int jid, int event)
5805+ * @endcode
5806+ * For more information about the callback parameters, see the
5807+ * [function pointer type](@ref GLFWjoystickfun).
5808+ *
5809+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
5810+ *
5811+ * @thread_safety This function must only be called from the main thread.
5812+ *
5813+ * @sa @ref joystick_event
5814+ *
5815+ * @since Added in version 3.2.
5816+ *
5817+ * @ingroup input
5818+ */
5819+GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun callback);
5820+
5821+/*! @brief Adds the specified SDL_GameControllerDB gamepad mappings.
5822+ *
5823+ * This function parses the specified ASCII encoded string and updates the
5824+ * internal list with any gamepad mappings it finds. This string may
5825+ * contain either a single gamepad mapping or many mappings separated by
5826+ * newlines. The parser supports the full format of the `gamecontrollerdb.txt`
5827+ * source file including empty lines and comments.
5828+ *
5829+ * See @ref gamepad_mapping for a description of the format.
5830+ *
5831+ * If there is already a gamepad mapping for a given GUID in the internal list,
5832+ * it will be replaced by the one passed to this function. If the library is
5833+ * terminated and re-initialized the internal list will revert to the built-in
5834+ * default.
5835+ *
5836+ * @param[in] string The string containing the gamepad mappings.
5837+ * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
5838+ * [error](@ref error_handling) occurred.
5839+ *
5840+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
5841+ * GLFW_INVALID_VALUE.
5842+ *
5843+ * @thread_safety This function must only be called from the main thread.
5844+ *
5845+ * @sa @ref gamepad
5846+ * @sa @ref glfwJoystickIsGamepad
5847+ * @sa @ref glfwGetGamepadName
5848+ *
5849+ * @since Added in version 3.3.
5850+ *
5851+ * @ingroup input
5852+ */
5853+GLFWAPI int glfwUpdateGamepadMappings(const char* string);
5854+
5855+/*! @brief Returns the human-readable gamepad name for the specified joystick.
5856+ *
5857+ * This function returns the human-readable name of the gamepad from the
5858+ * gamepad mapping assigned to the specified joystick.
5859+ *
5860+ * If the specified joystick is not present or does not have a gamepad mapping
5861+ * this function will return `NULL` but will not generate an error. Call
5862+ * @ref glfwJoystickPresent to check whether it is present regardless of
5863+ * whether it has a mapping.
5864+ *
5865+ * @param[in] jid The [joystick](@ref joysticks) to query.
5866+ * @return The UTF-8 encoded name of the gamepad, or `NULL` if the
5867+ * joystick is not present, does not have a mapping or an
5868+ * [error](@ref error_handling) occurred.
5869+ *
5870+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref GLFW_INVALID_ENUM.
5871+ *
5872+ * @pointer_lifetime The returned string is allocated and freed by GLFW. You
5873+ * should not free it yourself. It is valid until the specified joystick is
5874+ * disconnected, the gamepad mappings are updated or the library is terminated.
5875+ *
5876+ * @thread_safety This function must only be called from the main thread.
5877+ *
5878+ * @sa @ref gamepad
5879+ * @sa @ref glfwJoystickIsGamepad
5880+ *
5881+ * @since Added in version 3.3.
5882+ *
5883+ * @ingroup input
5884+ */
5885+GLFWAPI const char* glfwGetGamepadName(int jid);
5886+
5887+/*! @brief Retrieves the state of the specified joystick remapped as a gamepad.
5888+ *
5889+ * This function retrieves the state of the specified joystick remapped to
5890+ * an Xbox-like gamepad.
5891+ *
5892+ * If the specified joystick is not present or does not have a gamepad mapping
5893+ * this function will return `GLFW_FALSE` but will not generate an error. Call
5894+ * @ref glfwJoystickPresent to check whether it is present regardless of
5895+ * whether it has a mapping.
5896+ *
5897+ * The Guide button may not be available for input as it is often hooked by the
5898+ * system or the Steam client.
5899+ *
5900+ * Not all devices have all the buttons or axes provided by @ref
5901+ * GLFWgamepadstate. Unavailable buttons and axes will always report
5902+ * `GLFW_RELEASE` and 0.0 respectively.
5903+ *
5904+ * @param[in] jid The [joystick](@ref joysticks) to query.
5905+ * @param[out] state The gamepad input state of the joystick.
5906+ * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if no joystick is
5907+ * connected, it has no gamepad mapping or an [error](@ref error_handling)
5908+ * occurred.
5909+ *
5910+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
5911+ * GLFW_INVALID_ENUM.
5912+ *
5913+ * @thread_safety This function must only be called from the main thread.
5914+ *
5915+ * @sa @ref gamepad
5916+ * @sa @ref glfwUpdateGamepadMappings
5917+ * @sa @ref glfwJoystickIsGamepad
5918+ *
5919+ * @since Added in version 3.3.
5920+ *
5921+ * @ingroup input
5922+ */
5923+GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
5924+
5925+/*! @brief Sets the clipboard to the specified string.
5926+ *
5927+ * This function sets the system clipboard to the specified, UTF-8 encoded
5928+ * string.
5929+ *
5930+ * @param[in] window Deprecated. Any valid window or `NULL`.
5931+ * @param[in] string A UTF-8 encoded string.
5932+ *
5933+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
5934+ * GLFW_PLATFORM_ERROR.
5935+ *
5936+ * @remark __Win32:__ The clipboard on Windows has a single global lock for reading and
5937+ * writing. GLFW tries to acquire it a few times, which is almost always enough. If it
5938+ * cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns.
5939+ * It is safe to try this multiple times.
5940+ *
5941+ * @pointer_lifetime The specified string is copied before this function
5942+ * returns.
5943+ *
5944+ * @thread_safety This function must only be called from the main thread.
5945+ *
5946+ * @sa @ref clipboard
5947+ * @sa @ref glfwGetClipboardString
5948+ *
5949+ * @since Added in version 3.0.
5950+ *
5951+ * @ingroup input
5952+ */
5953+GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
5954+
5955+/*! @brief Returns the contents of the clipboard as a string.
5956+ *
5957+ * This function returns the contents of the system clipboard, if it contains
5958+ * or is convertible to a UTF-8 encoded string. If the clipboard is empty or
5959+ * if its contents cannot be converted, `NULL` is returned and a @ref
5960+ * GLFW_FORMAT_UNAVAILABLE error is generated.
5961+ *
5962+ * @param[in] window Deprecated. Any valid window or `NULL`.
5963+ * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL`
5964+ * if an [error](@ref error_handling) occurred.
5965+ *
5966+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
5967+ * GLFW_FORMAT_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
5968+ *
5969+ * @remark __Win32:__ The clipboard on Windows has a single global lock for reading and
5970+ * writing. GLFW tries to acquire it a few times, which is almost always enough. If it
5971+ * cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns.
5972+ * It is safe to try this multiple times.
5973+ *
5974+ * @pointer_lifetime The returned string is allocated and freed by GLFW. You
5975+ * should not free it yourself. It is valid until the next call to @ref
5976+ * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library
5977+ * is terminated.
5978+ *
5979+ * @thread_safety This function must only be called from the main thread.
5980+ *
5981+ * @sa @ref clipboard
5982+ * @sa @ref glfwSetClipboardString
5983+ *
5984+ * @since Added in version 3.0.
5985+ *
5986+ * @ingroup input
5987+ */
5988+GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
5989+
5990+/*! @brief Returns the GLFW time.
5991+ *
5992+ * This function returns the current GLFW time, in seconds. Unless the time
5993+ * has been set using @ref glfwSetTime it measures time elapsed since GLFW was
5994+ * initialized.
5995+ *
5996+ * This function and @ref glfwSetTime are helper functions on top of @ref
5997+ * glfwGetTimerFrequency and @ref glfwGetTimerValue.
5998+ *
5999+ * The resolution of the timer is system dependent, but is usually on the order
6000+ * of a few micro- or nanoseconds. It uses the highest-resolution monotonic
6001+ * time source on each operating system.
6002+ *
6003+ * @return The current time, in seconds, or zero if an
6004+ * [error](@ref error_handling) occurred.
6005+ *
6006+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
6007+ *
6008+ * @thread_safety This function may be called from any thread. Reading and
6009+ * writing of the internal base time is not atomic, so it needs to be
6010+ * externally synchronized with calls to @ref glfwSetTime.
6011+ *
6012+ * @sa @ref time
6013+ *
6014+ * @since Added in version 1.0.
6015+ *
6016+ * @ingroup input
6017+ */
6018+GLFWAPI double glfwGetTime(void);
6019+
6020+/*! @brief Sets the GLFW time.
6021+ *
6022+ * This function sets the current GLFW time, in seconds. The value must be
6023+ * a positive finite number less than or equal to 18446744073.0, which is
6024+ * approximately 584.5 years.
6025+ *
6026+ * This function and @ref glfwGetTime are helper functions on top of @ref
6027+ * glfwGetTimerFrequency and @ref glfwGetTimerValue.
6028+ *
6029+ * @param[in] time The new value, in seconds.
6030+ *
6031+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
6032+ * GLFW_INVALID_VALUE.
6033+ *
6034+ * @remark The upper limit of GLFW time is calculated as
6035+ * floor((2<sup>64</sup> - 1) / 10<sup>9</sup>) and is due to implementations
6036+ * storing nanoseconds in 64 bits. The limit may be increased in the future.
6037+ *
6038+ * @thread_safety This function may be called from any thread. Reading and
6039+ * writing of the internal base time is not atomic, so it needs to be
6040+ * externally synchronized with calls to @ref glfwGetTime.
6041+ *
6042+ * @sa @ref time
6043+ *
6044+ * @since Added in version 2.2.
6045+ *
6046+ * @ingroup input
6047+ */
6048+GLFWAPI void glfwSetTime(double time);
6049+
6050+/*! @brief Returns the current value of the raw timer.
6051+ *
6052+ * This function returns the current value of the raw timer, measured in
6053+ * 1&nbsp;/&nbsp;frequency seconds. To get the frequency, call @ref
6054+ * glfwGetTimerFrequency.
6055+ *
6056+ * @return The value of the timer, or zero if an
6057+ * [error](@ref error_handling) occurred.
6058+ *
6059+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
6060+ *
6061+ * @thread_safety This function may be called from any thread.
6062+ *
6063+ * @sa @ref time
6064+ * @sa @ref glfwGetTimerFrequency
6065+ *
6066+ * @since Added in version 3.2.
6067+ *
6068+ * @ingroup input
6069+ */
6070+GLFWAPI uint64_t glfwGetTimerValue(void);
6071+
6072+/*! @brief Returns the frequency, in Hz, of the raw timer.
6073+ *
6074+ * This function returns the frequency, in Hz, of the raw timer.
6075+ *
6076+ * @return The frequency of the timer, in Hz, or zero if an
6077+ * [error](@ref error_handling) occurred.
6078+ *
6079+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
6080+ *
6081+ * @thread_safety This function may be called from any thread.
6082+ *
6083+ * @sa @ref time
6084+ * @sa @ref glfwGetTimerValue
6085+ *
6086+ * @since Added in version 3.2.
6087+ *
6088+ * @ingroup input
6089+ */
6090+GLFWAPI uint64_t glfwGetTimerFrequency(void);
6091+
6092+/*! @brief Makes the context of the specified window current for the calling
6093+ * thread.
6094+ *
6095+ * This function makes the OpenGL or OpenGL ES context of the specified window
6096+ * current on the calling thread. It can also detach the current context from
6097+ * the calling thread without making a new one current by passing in `NULL`.
6098+ *
6099+ * A context must only be made current on a single thread at a time and each
6100+ * thread can have only a single current context at a time. Making a context
6101+ * current detaches any previously current context on the calling thread.
6102+ *
6103+ * When moving a context between threads, you must detach it (make it
6104+ * non-current) on the old thread before making it current on the new one.
6105+ *
6106+ * By default, making a context non-current implicitly forces a pipeline flush.
6107+ * On machines that support `GL_KHR_context_flush_control`, you can control
6108+ * whether a context performs this flush by setting the
6109+ * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_hint)
6110+ * hint.
6111+ *
6112+ * The specified window must have an OpenGL or OpenGL ES context. Specifying
6113+ * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT
6114+ * error.
6115+ *
6116+ * @param[in] window The window whose context to make current, or `NULL` to
6117+ * detach the current context.
6118+ *
6119+ * @remarks If the previously current context was created via a different
6120+ * context creation API than the one passed to this function, GLFW will still
6121+ * detach the previous one from its API before making the new one current.
6122+ *
6123+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
6124+ * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
6125+ *
6126+ * @thread_safety This function may be called from any thread.
6127+ *
6128+ * @sa @ref context_current
6129+ * @sa @ref glfwGetCurrentContext
6130+ *
6131+ * @since Added in version 3.0.
6132+ *
6133+ * @ingroup context
6134+ */
6135+GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window);
6136+
6137+/*! @brief Returns the window whose context is current on the calling thread.
6138+ *
6139+ * This function returns the window whose OpenGL or OpenGL ES context is
6140+ * current on the calling thread.
6141+ *
6142+ * @return The window whose context is current, or `NULL` if no window's
6143+ * context is current.
6144+ *
6145+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
6146+ *
6147+ * @thread_safety This function may be called from any thread.
6148+ *
6149+ * @sa @ref context_current
6150+ * @sa @ref glfwMakeContextCurrent
6151+ *
6152+ * @since Added in version 3.0.
6153+ *
6154+ * @ingroup context
6155+ */
6156+GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
6157+
6158+/*! @brief Swaps the front and back buffers of the specified window.
6159+ *
6160+ * This function swaps the front and back buffers of the specified window when
6161+ * rendering with OpenGL or OpenGL ES. If the swap interval is greater than
6162+ * zero, the GPU driver waits the specified number of screen updates before
6163+ * swapping the buffers.
6164+ *
6165+ * The specified window must have an OpenGL or OpenGL ES context. Specifying
6166+ * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT
6167+ * error.
6168+ *
6169+ * This function does not apply to Vulkan. If you are rendering with Vulkan,
6170+ * see `vkQueuePresentKHR` instead.
6171+ *
6172+ * @param[in] window The window whose buffers to swap.
6173+ *
6174+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
6175+ * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
6176+ *
6177+ * @remark __EGL:__ The context of the specified window must be current on the
6178+ * calling thread.
6179+ *
6180+ * @thread_safety This function may be called from any thread.
6181+ *
6182+ * @sa @ref buffer_swap
6183+ * @sa @ref glfwSwapInterval
6184+ *
6185+ * @since Added in version 1.0.
6186+ * __GLFW 3:__ Added window handle parameter.
6187+ *
6188+ * @ingroup window
6189+ */
6190+GLFWAPI void glfwSwapBuffers(GLFWwindow* window);
6191+
6192+/*! @brief Sets the swap interval for the current context.
6193+ *
6194+ * This function sets the swap interval for the current OpenGL or OpenGL ES
6195+ * context, i.e. the number of screen updates to wait from the time @ref
6196+ * glfwSwapBuffers was called before swapping the buffers and returning. This
6197+ * is sometimes called _vertical synchronization_, _vertical retrace
6198+ * synchronization_ or just _vsync_.
6199+ *
6200+ * A context that supports either of the `WGL_EXT_swap_control_tear` and
6201+ * `GLX_EXT_swap_control_tear` extensions also accepts _negative_ swap
6202+ * intervals, which allows the driver to swap immediately even if a frame
6203+ * arrives a little bit late. You can check for these extensions with @ref
6204+ * glfwExtensionSupported.
6205+ *
6206+ * A context must be current on the calling thread. Calling this function
6207+ * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
6208+ *
6209+ * This function does not apply to Vulkan. If you are rendering with Vulkan,
6210+ * see the present mode of your swapchain instead.
6211+ *
6212+ * @param[in] interval The minimum number of screen updates to wait for
6213+ * until the buffers are swapped by @ref glfwSwapBuffers.
6214+ *
6215+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
6216+ * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.
6217+ *
6218+ * @remark This function is not called during context creation, leaving the
6219+ * swap interval set to whatever is the default for that API. This is done
6220+ * because some swap interval extensions used by GLFW do not allow the swap
6221+ * interval to be reset to zero once it has been set to a non-zero value.
6222+ *
6223+ * @remark Some GPU drivers do not honor the requested swap interval, either
6224+ * because of a user setting that overrides the application's request or due to
6225+ * bugs in the driver.
6226+ *
6227+ * @thread_safety This function may be called from any thread.
6228+ *
6229+ * @sa @ref buffer_swap
6230+ * @sa @ref glfwSwapBuffers
6231+ *
6232+ * @since Added in version 1.0.
6233+ *
6234+ * @ingroup context
6235+ */
6236+GLFWAPI void glfwSwapInterval(int interval);
6237+
6238+/*! @brief Returns whether the specified extension is available.
6239+ *
6240+ * This function returns whether the specified
6241+ * [API extension](@ref context_glext) is supported by the current OpenGL or
6242+ * OpenGL ES context. It searches both for client API extension and context
6243+ * creation API extensions.
6244+ *
6245+ * A context must be current on the calling thread. Calling this function
6246+ * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
6247+ *
6248+ * As this functions retrieves and searches one or more extension strings each
6249+ * call, it is recommended that you cache its results if it is going to be used
6250+ * frequently. The extension strings will not change during the lifetime of
6251+ * a context, so there is no danger in doing this.
6252+ *
6253+ * This function does not apply to Vulkan. If you are using Vulkan, see @ref
6254+ * glfwGetRequiredInstanceExtensions, `vkEnumerateInstanceExtensionProperties`
6255+ * and `vkEnumerateDeviceExtensionProperties` instead.
6256+ *
6257+ * @param[in] extension The ASCII encoded name of the extension.
6258+ * @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE`
6259+ * otherwise.
6260+ *
6261+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
6262+ * GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref
6263+ * GLFW_PLATFORM_ERROR.
6264+ *
6265+ * @thread_safety This function may be called from any thread.
6266+ *
6267+ * @sa @ref context_glext
6268+ * @sa @ref glfwGetProcAddress
6269+ *
6270+ * @since Added in version 1.0.
6271+ *
6272+ * @ingroup context
6273+ */
6274+GLFWAPI int glfwExtensionSupported(const char* extension);
6275+
6276+/*! @brief Returns the address of the specified function for the current
6277+ * context.
6278+ *
6279+ * This function returns the address of the specified OpenGL or OpenGL ES
6280+ * [core or extension function](@ref context_glext), if it is supported
6281+ * by the current context.
6282+ *
6283+ * A context must be current on the calling thread. Calling this function
6284+ * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
6285+ *
6286+ * This function does not apply to Vulkan. If you are rendering with Vulkan,
6287+ * see @ref glfwGetInstanceProcAddress, `vkGetInstanceProcAddr` and
6288+ * `vkGetDeviceProcAddr` instead.
6289+ *
6290+ * @param[in] procname The ASCII encoded name of the function.
6291+ * @return The address of the function, or `NULL` if an
6292+ * [error](@ref error_handling) occurred.
6293+ *
6294+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
6295+ * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.
6296+ *
6297+ * @remark The address of a given function is not guaranteed to be the same
6298+ * between contexts.
6299+ *
6300+ * @remark This function may return a non-`NULL` address despite the
6301+ * associated version or extension not being available. Always check the
6302+ * context version or extension string first.
6303+ *
6304+ * @pointer_lifetime The returned function pointer is valid until the context
6305+ * is destroyed or the library is terminated.
6306+ *
6307+ * @thread_safety This function may be called from any thread.
6308+ *
6309+ * @sa @ref context_glext
6310+ * @sa @ref glfwExtensionSupported
6311+ *
6312+ * @since Added in version 1.0.
6313+ *
6314+ * @ingroup context
6315+ */
6316+GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
6317+
6318+/*! @brief Returns whether the Vulkan loader and an ICD have been found.
6319+ *
6320+ * This function returns whether the Vulkan loader and any minimally functional
6321+ * ICD have been found.
6322+ *
6323+ * The availability of a Vulkan loader and even an ICD does not by itself guarantee that
6324+ * surface creation or even instance creation is possible. Call @ref
6325+ * glfwGetRequiredInstanceExtensions to check whether the extensions necessary for Vulkan
6326+ * surface creation are available and @ref glfwGetPhysicalDevicePresentationSupport to
6327+ * check whether a queue family of a physical device supports image presentation.
6328+ *
6329+ * @return `GLFW_TRUE` if Vulkan is minimally available, or `GLFW_FALSE`
6330+ * otherwise.
6331+ *
6332+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
6333+ *
6334+ * @thread_safety This function may be called from any thread.
6335+ *
6336+ * @sa @ref vulkan_support
6337+ *
6338+ * @since Added in version 3.2.
6339+ *
6340+ * @ingroup vulkan
6341+ */
6342+GLFWAPI int glfwVulkanSupported(void);
6343+
6344+/*! @brief Returns the Vulkan instance extensions required by GLFW.
6345+ *
6346+ * This function returns an array of names of Vulkan instance extensions required
6347+ * by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the
6348+ * list will always contain `VK_KHR_surface`, so if you don't require any
6349+ * additional extensions you can pass this list directly to the
6350+ * `VkInstanceCreateInfo` struct.
6351+ *
6352+ * If Vulkan is not available on the machine, this function returns `NULL` and
6353+ * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
6354+ * to check whether Vulkan is at least minimally available.
6355+ *
6356+ * If Vulkan is available but no set of extensions allowing window surface
6357+ * creation was found, this function returns `NULL`. You may still use Vulkan
6358+ * for off-screen rendering and compute work.
6359+ *
6360+ * @param[out] count Where to store the number of extensions in the returned
6361+ * array. This is set to zero if an error occurred.
6362+ * @return An array of ASCII encoded extension names, or `NULL` if an
6363+ * [error](@ref error_handling) occurred.
6364+ *
6365+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
6366+ * GLFW_API_UNAVAILABLE.
6367+ *
6368+ * @remark Additional extensions may be required by future versions of GLFW.
6369+ * You should check if any extensions you wish to enable are already in the
6370+ * returned array, as it is an error to specify an extension more than once in
6371+ * the `VkInstanceCreateInfo` struct.
6372+ *
6373+ * @pointer_lifetime The returned array is allocated and freed by GLFW. You
6374+ * should not free it yourself. It is guaranteed to be valid only until the
6375+ * library is terminated.
6376+ *
6377+ * @thread_safety This function may be called from any thread.
6378+ *
6379+ * @sa @ref vulkan_ext
6380+ * @sa @ref glfwCreateWindowSurface
6381+ *
6382+ * @since Added in version 3.2.
6383+ *
6384+ * @ingroup vulkan
6385+ */
6386+GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count);
6387+
6388+#if defined(VK_VERSION_1_0)
6389+
6390+/*! @brief Returns the address of the specified Vulkan instance function.
6391+ *
6392+ * This function returns the address of the specified Vulkan core or extension
6393+ * function for the specified instance. If instance is set to `NULL` it can
6394+ * return any function exported from the Vulkan loader, including at least the
6395+ * following functions:
6396+ *
6397+ * - `vkEnumerateInstanceExtensionProperties`
6398+ * - `vkEnumerateInstanceLayerProperties`
6399+ * - `vkCreateInstance`
6400+ * - `vkGetInstanceProcAddr`
6401+ *
6402+ * If Vulkan is not available on the machine, this function returns `NULL` and
6403+ * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
6404+ * to check whether Vulkan is at least minimally available.
6405+ *
6406+ * This function is equivalent to calling `vkGetInstanceProcAddr` with
6407+ * a platform-specific query of the Vulkan loader as a fallback.
6408+ *
6409+ * @param[in] instance The Vulkan instance to query, or `NULL` to retrieve
6410+ * functions related to instance creation.
6411+ * @param[in] procname The ASCII encoded name of the function.
6412+ * @return The address of the function, or `NULL` if an
6413+ * [error](@ref error_handling) occurred.
6414+ *
6415+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
6416+ * GLFW_API_UNAVAILABLE.
6417+ *
6418+ * @pointer_lifetime The returned function pointer is valid until the library
6419+ * is terminated.
6420+ *
6421+ * @thread_safety This function may be called from any thread.
6422+ *
6423+ * @sa @ref vulkan_proc
6424+ *
6425+ * @since Added in version 3.2.
6426+ *
6427+ * @ingroup vulkan
6428+ */
6429+GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname);
6430+
6431+/*! @brief Returns whether the specified queue family can present images.
6432+ *
6433+ * This function returns whether the specified queue family of the specified
6434+ * physical device supports presentation to the platform GLFW was built for.
6435+ *
6436+ * If Vulkan or the required window surface creation instance extensions are
6437+ * not available on the machine, or if the specified instance was not created
6438+ * with the required extensions, this function returns `GLFW_FALSE` and
6439+ * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
6440+ * to check whether Vulkan is at least minimally available and @ref
6441+ * glfwGetRequiredInstanceExtensions to check what instance extensions are
6442+ * required.
6443+ *
6444+ * @param[in] instance The instance that the physical device belongs to.
6445+ * @param[in] device The physical device that the queue family belongs to.
6446+ * @param[in] queuefamily The index of the queue family to query.
6447+ * @return `GLFW_TRUE` if the queue family supports presentation, or
6448+ * `GLFW_FALSE` otherwise.
6449+ *
6450+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
6451+ * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
6452+ *
6453+ * @remark __macOS:__ This function currently always returns `GLFW_TRUE`, as the
6454+ * `VK_MVK_macos_surface` and `VK_EXT_metal_surface` extensions do not provide
6455+ * a `vkGetPhysicalDevice*PresentationSupport` type function.
6456+ *
6457+ * @thread_safety This function may be called from any thread. For
6458+ * synchronization details of Vulkan objects, see the Vulkan specification.
6459+ *
6460+ * @sa @ref vulkan_present
6461+ *
6462+ * @since Added in version 3.2.
6463+ *
6464+ * @ingroup vulkan
6465+ */
6466+GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
6467+
6468+/*! @brief Creates a Vulkan surface for the specified window.
6469+ *
6470+ * This function creates a Vulkan surface for the specified window.
6471+ *
6472+ * If the Vulkan loader or at least one minimally functional ICD were not found,
6473+ * this function returns `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref
6474+ * GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported to check whether
6475+ * Vulkan is at least minimally available.
6476+ *
6477+ * If the required window surface creation instance extensions are not
6478+ * available or if the specified instance was not created with these extensions
6479+ * enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and
6480+ * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref
6481+ * glfwGetRequiredInstanceExtensions to check what instance extensions are
6482+ * required.
6483+ *
6484+ * The window surface cannot be shared with another API so the window must
6485+ * have been created with the [client api hint](@ref GLFW_CLIENT_API_attrib)
6486+ * set to `GLFW_NO_API` otherwise it generates a @ref GLFW_INVALID_VALUE error
6487+ * and returns `VK_ERROR_NATIVE_WINDOW_IN_USE_KHR`.
6488+ *
6489+ * The window surface must be destroyed before the specified Vulkan instance.
6490+ * It is the responsibility of the caller to destroy the window surface. GLFW
6491+ * does not destroy it for you. Call `vkDestroySurfaceKHR` to destroy the
6492+ * surface.
6493+ *
6494+ * @param[in] instance The Vulkan instance to create the surface in.
6495+ * @param[in] window The window to create the surface for.
6496+ * @param[in] allocator The allocator to use, or `NULL` to use the default
6497+ * allocator.
6498+ * @param[out] surface Where to store the handle of the surface. This is set
6499+ * to `VK_NULL_HANDLE` if an error occurred.
6500+ * @return `VK_SUCCESS` if successful, or a Vulkan error code if an
6501+ * [error](@ref error_handling) occurred.
6502+ *
6503+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
6504+ * GLFW_API_UNAVAILABLE, @ref GLFW_PLATFORM_ERROR and @ref GLFW_INVALID_VALUE
6505+ *
6506+ * @remark If an error occurs before the creation call is made, GLFW returns
6507+ * the Vulkan error code most appropriate for the error. Appropriate use of
6508+ * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
6509+ * eliminate almost all occurrences of these errors.
6510+ *
6511+ * @remark __macOS:__ GLFW prefers the `VK_EXT_metal_surface` extension, with the
6512+ * `VK_MVK_macos_surface` extension as a fallback. The name of the selected
6513+ * extension, if any, is included in the array returned by @ref
6514+ * glfwGetRequiredInstanceExtensions.
6515+ *
6516+ * @remark __macOS:__ This function creates and sets a `CAMetalLayer` instance for
6517+ * the window content view, which is required for MoltenVK to function.
6518+ *
6519+ * @remark __X11:__ By default GLFW prefers the `VK_KHR_xcb_surface` extension,
6520+ * with the `VK_KHR_xlib_surface` extension as a fallback. You can make
6521+ * `VK_KHR_xlib_surface` the preferred extension by setting the
6522+ * [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init
6523+ * hint. The name of the selected extension, if any, is included in the array
6524+ * returned by @ref glfwGetRequiredInstanceExtensions.
6525+ *
6526+ * @thread_safety This function may be called from any thread. For
6527+ * synchronization details of Vulkan objects, see the Vulkan specification.
6528+ *
6529+ * @sa @ref vulkan_surface
6530+ * @sa @ref glfwGetRequiredInstanceExtensions
6531+ *
6532+ * @since Added in version 3.2.
6533+ *
6534+ * @ingroup vulkan
6535+ */
6536+GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
6537+
6538+#endif /*VK_VERSION_1_0*/
6539+
6540+
6541+/*************************************************************************
6542+ * Global definition cleanup
6543+ *************************************************************************/
6544+
6545+/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */
6546+
6547+#ifdef GLFW_WINGDIAPI_DEFINED
6548+ #undef WINGDIAPI
6549+ #undef GLFW_WINGDIAPI_DEFINED
6550+#endif
6551+
6552+#ifdef GLFW_CALLBACK_DEFINED
6553+ #undef CALLBACK
6554+ #undef GLFW_CALLBACK_DEFINED
6555+#endif
6556+
6557+/* Some OpenGL related headers need GLAPIENTRY, but it is unconditionally
6558+ * defined by some gl.h variants (OpenBSD) so define it after if needed.
6559+ */
6560+#ifndef GLAPIENTRY
6561+ #define GLAPIENTRY APIENTRY
6562+ #define GLFW_GLAPIENTRY_DEFINED
6563+#endif
6564+
6565+/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */
6566+
6567+
6568+#ifdef __cplusplus
6569+}
6570+#endif
6571+
6572+#endif /* _glfw3_h_ */
6573+
@@ -0,0 +1,709 @@
1+/*************************************************************************
2+ * GLFW 3.5 - www.glfw.org
3+ * A library for OpenGL, window and input
4+ *------------------------------------------------------------------------
5+ * Copyright (c) 2002-2006 Marcus Geelnard
6+ * Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
7+ *
8+ * This software is provided 'as-is', without any express or implied
9+ * warranty. In no event will the authors be held liable for any damages
10+ * arising from the use of this software.
11+ *
12+ * Permission is granted to anyone to use this software for any purpose,
13+ * including commercial applications, and to alter it and redistribute it
14+ * freely, subject to the following restrictions:
15+ *
16+ * 1. The origin of this software must not be misrepresented; you must not
17+ * claim that you wrote the original software. If you use this software
18+ * in a product, an acknowledgment in the product documentation would
19+ * be appreciated but is not required.
20+ *
21+ * 2. Altered source versions must be plainly marked as such, and must not
22+ * be misrepresented as being the original software.
23+ *
24+ * 3. This notice may not be removed or altered from any source
25+ * distribution.
26+ *
27+ *************************************************************************/
28+
29+#ifndef _glfw3_native_h_
30+#define _glfw3_native_h_
31+
32+#ifdef __cplusplus
33+extern "C" {
34+#endif
35+
36+
37+/*************************************************************************
38+ * Doxygen documentation
39+ *************************************************************************/
40+
41+/*! @file glfw3native.h
42+ * @brief The header of the native access functions.
43+ *
44+ * This is the header file of the native access functions. See @ref native for
45+ * more information.
46+ */
47+/*! @defgroup native Native access
48+ * @brief Functions related to accessing native handles.
49+ *
50+ * **By using the native access functions you assert that you know what you're
51+ * doing and how to fix problems caused by using them. If you don't, you
52+ * shouldn't be using them.**
53+ *
54+ * Before the inclusion of @ref glfw3native.h, you may define zero or more
55+ * window system API macro and zero or more context creation API macros.
56+ *
57+ * The chosen backends must match those the library was compiled for. Failure
58+ * to do this will cause a link-time error.
59+ *
60+ * The available window API macros are:
61+ * * `GLFW_EXPOSE_NATIVE_WIN32`
62+ * * `GLFW_EXPOSE_NATIVE_COCOA`
63+ * * `GLFW_EXPOSE_NATIVE_X11`
64+ * * `GLFW_EXPOSE_NATIVE_WAYLAND`
65+ *
66+ * The available context API macros are:
67+ * * `GLFW_EXPOSE_NATIVE_WGL`
68+ * * `GLFW_EXPOSE_NATIVE_NSGL`
69+ * * `GLFW_EXPOSE_NATIVE_GLX`
70+ * * `GLFW_EXPOSE_NATIVE_EGL`
71+ * * `GLFW_EXPOSE_NATIVE_OSMESA`
72+ *
73+ * These macros select which of the native access functions that are declared
74+ * and which platform-specific headers to include. It is then up your (by
75+ * definition platform-specific) code to handle which of these should be
76+ * defined.
77+ *
78+ * If you do not want the platform-specific headers to be included, define
79+ * `GLFW_NATIVE_INCLUDE_NONE` before including the @ref glfw3native.h header.
80+ *
81+ * @code
82+ * #define GLFW_EXPOSE_NATIVE_WIN32
83+ * #define GLFW_EXPOSE_NATIVE_WGL
84+ * #define GLFW_NATIVE_INCLUDE_NONE
85+ * #include <GLFW/glfw3native.h>
86+ * @endcode
87+ */
88+
89+
90+/*************************************************************************
91+ * System headers and types
92+ *************************************************************************/
93+
94+#if !defined(GLFW_NATIVE_INCLUDE_NONE)
95+
96+ #if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
97+ /* This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
98+ * example to allow applications to correctly declare a GL_KHR_debug callback)
99+ * but windows.h assumes no one will define APIENTRY before it does
100+ */
101+ #if defined(GLFW_APIENTRY_DEFINED)
102+ #undef APIENTRY
103+ #undef GLFW_APIENTRY_DEFINED
104+ #endif
105+ #include <windows.h>
106+ #endif
107+
108+ #if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
109+ #if defined(__OBJC__)
110+ #import <Cocoa/Cocoa.h>
111+ #else
112+ #include <ApplicationServices/ApplicationServices.h>
113+ #include <objc/objc.h>
114+ #endif
115+ #endif
116+
117+ #if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
118+ #include <X11/Xlib.h>
119+ #include <X11/extensions/Xrandr.h>
120+ #endif
121+
122+ #if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
123+ #include <wayland-client.h>
124+ #endif
125+
126+ #if defined(GLFW_EXPOSE_NATIVE_WGL)
127+ /* WGL is declared by windows.h */
128+ #endif
129+ #if defined(GLFW_EXPOSE_NATIVE_NSGL)
130+ /* NSGL is declared by Cocoa.h */
131+ #endif
132+ #if defined(GLFW_EXPOSE_NATIVE_GLX)
133+ /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
134+ * default it also acts as an OpenGL header
135+ * However, glx.h will include gl.h, which will define it unconditionally
136+ */
137+ #if defined(GLFW_GLAPIENTRY_DEFINED)
138+ #undef GLAPIENTRY
139+ #undef GLFW_GLAPIENTRY_DEFINED
140+ #endif
141+ #include <GL/glx.h>
142+ #endif
143+ #if defined(GLFW_EXPOSE_NATIVE_EGL)
144+ #include <EGL/egl.h>
145+ #endif
146+ #if defined(GLFW_EXPOSE_NATIVE_OSMESA)
147+ /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
148+ * default it also acts as an OpenGL header
149+ * However, osmesa.h will include gl.h, which will define it unconditionally
150+ */
151+ #if defined(GLFW_GLAPIENTRY_DEFINED)
152+ #undef GLAPIENTRY
153+ #undef GLFW_GLAPIENTRY_DEFINED
154+ #endif
155+ #include <GL/osmesa.h>
156+ #endif
157+
158+#endif /*GLFW_NATIVE_INCLUDE_NONE*/
159+
160+
161+/*************************************************************************
162+ * Functions
163+ *************************************************************************/
164+
165+#if defined(GLFW_EXPOSE_NATIVE_WIN32)
166+/*! @brief Returns the adapter device name of the specified monitor.
167+ *
168+ * @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
169+ * of the specified monitor, or `NULL` if an [error](@ref error_handling)
170+ * occurred.
171+ *
172+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
173+ * GLFW_PLATFORM_UNAVAILABLE.
174+ *
175+ * @thread_safety This function may be called from any thread. Access is not
176+ * synchronized.
177+ *
178+ * @since Added in version 3.1.
179+ *
180+ * @ingroup native
181+ */
182+GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
183+
184+/*! @brief Returns the display device name of the specified monitor.
185+ *
186+ * @return The UTF-8 encoded display device name (for example
187+ * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
188+ * [error](@ref error_handling) occurred.
189+ *
190+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
191+ * GLFW_PLATFORM_UNAVAILABLE.
192+ *
193+ * @thread_safety This function may be called from any thread. Access is not
194+ * synchronized.
195+ *
196+ * @since Added in version 3.1.
197+ *
198+ * @ingroup native
199+ */
200+GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
201+
202+/*! @brief Returns the `HWND` of the specified window.
203+ *
204+ * @return The `HWND` of the specified window, or `NULL` if an
205+ * [error](@ref error_handling) occurred.
206+ *
207+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
208+ * GLFW_PLATFORM_UNAVAILABLE.
209+ *
210+ * @remark The `HDC` associated with the window can be queried with the
211+ * [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
212+ * function.
213+ * @code
214+ * HDC dc = GetDC(glfwGetWin32Window(window));
215+ * @endcode
216+ * This DC is private and does not need to be released.
217+ *
218+ * @thread_safety This function may be called from any thread. Access is not
219+ * synchronized.
220+ *
221+ * @since Added in version 3.0.
222+ *
223+ * @ingroup native
224+ */
225+GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
226+#endif
227+
228+#if defined(GLFW_EXPOSE_NATIVE_WGL)
229+/*! @brief Returns the `HGLRC` of the specified window.
230+ *
231+ * @return The `HGLRC` of the specified window, or `NULL` if an
232+ * [error](@ref error_handling) occurred.
233+ *
234+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
235+ * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT.
236+ *
237+ * @remark The `HDC` associated with the window can be queried with the
238+ * [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
239+ * function.
240+ * @code
241+ * HDC dc = GetDC(glfwGetWin32Window(window));
242+ * @endcode
243+ * This DC is private and does not need to be released.
244+ *
245+ * @thread_safety This function may be called from any thread. Access is not
246+ * synchronized.
247+ *
248+ * @since Added in version 3.0.
249+ *
250+ * @ingroup native
251+ */
252+GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
253+#endif
254+
255+#if defined(GLFW_EXPOSE_NATIVE_COCOA)
256+/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
257+ *
258+ * @return The `CGDirectDisplayID` of the specified monitor, or
259+ * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
260+ *
261+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
262+ * GLFW_PLATFORM_UNAVAILABLE.
263+ *
264+ * @thread_safety This function may be called from any thread. Access is not
265+ * synchronized.
266+ *
267+ * @since Added in version 3.1.
268+ *
269+ * @ingroup native
270+ */
271+GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
272+
273+/*! @brief Returns the `NSWindow` of the specified window.
274+ *
275+ * @return The `NSWindow` of the specified window, or `nil` if an
276+ * [error](@ref error_handling) occurred.
277+ *
278+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
279+ * GLFW_PLATFORM_UNAVAILABLE.
280+ *
281+ * @thread_safety This function may be called from any thread. Access is not
282+ * synchronized.
283+ *
284+ * @since Added in version 3.0.
285+ *
286+ * @ingroup native
287+ */
288+GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
289+
290+/*! @brief Returns the `NSView` of the specified window.
291+ *
292+ * @return The `NSView` of the specified window, or `nil` if an
293+ * [error](@ref error_handling) occurred.
294+ *
295+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
296+ * GLFW_PLATFORM_UNAVAILABLE.
297+ *
298+ * @thread_safety This function may be called from any thread. Access is not
299+ * synchronized.
300+ *
301+ * @since Added in version 3.4.
302+ *
303+ * @ingroup native
304+ */
305+GLFWAPI id glfwGetCocoaView(GLFWwindow* window);
306+#endif
307+
308+#if defined(GLFW_EXPOSE_NATIVE_NSGL)
309+/*! @brief Returns the `NSOpenGLContext` of the specified window.
310+ *
311+ * @return The `NSOpenGLContext` of the specified window, or `nil` if an
312+ * [error](@ref error_handling) occurred.
313+ *
314+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
315+ * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT.
316+ *
317+ * @thread_safety This function may be called from any thread. Access is not
318+ * synchronized.
319+ *
320+ * @since Added in version 3.0.
321+ *
322+ * @ingroup native
323+ */
324+GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
325+#endif
326+
327+#if defined(GLFW_EXPOSE_NATIVE_X11)
328+/*! @brief Returns the `Display` used by GLFW.
329+ *
330+ * @return The `Display` used by GLFW, or `NULL` if an
331+ * [error](@ref error_handling) occurred.
332+ *
333+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
334+ * GLFW_PLATFORM_UNAVAILABLE.
335+ *
336+ * @thread_safety This function may be called from any thread. Access is not
337+ * synchronized.
338+ *
339+ * @since Added in version 3.0.
340+ *
341+ * @ingroup native
342+ */
343+GLFWAPI Display* glfwGetX11Display(void);
344+
345+/*! @brief Returns the `RRCrtc` of the specified monitor.
346+ *
347+ * @return The `RRCrtc` of the specified monitor, or `None` if an
348+ * [error](@ref error_handling) occurred.
349+ *
350+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
351+ * GLFW_PLATFORM_UNAVAILABLE.
352+ *
353+ * @thread_safety This function may be called from any thread. Access is not
354+ * synchronized.
355+ *
356+ * @since Added in version 3.1.
357+ *
358+ * @ingroup native
359+ */
360+GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
361+
362+/*! @brief Returns the `RROutput` of the specified monitor.
363+ *
364+ * @return The `RROutput` of the specified monitor, or `None` if an
365+ * [error](@ref error_handling) occurred.
366+ *
367+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
368+ * GLFW_PLATFORM_UNAVAILABLE.
369+ *
370+ * @thread_safety This function may be called from any thread. Access is not
371+ * synchronized.
372+ *
373+ * @since Added in version 3.1.
374+ *
375+ * @ingroup native
376+ */
377+GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
378+
379+/*! @brief Returns the `Window` of the specified window.
380+ *
381+ * @return The `Window` of the specified window, or `None` if an
382+ * [error](@ref error_handling) occurred.
383+ *
384+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
385+ * GLFW_PLATFORM_UNAVAILABLE.
386+ *
387+ * @thread_safety This function may be called from any thread. Access is not
388+ * synchronized.
389+ *
390+ * @since Added in version 3.0.
391+ *
392+ * @ingroup native
393+ */
394+GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
395+
396+/*! @brief Sets the current primary selection to the specified string.
397+ *
398+ * @param[in] string A UTF-8 encoded string.
399+ *
400+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
401+ * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
402+ *
403+ * @pointer_lifetime The specified string is copied before this function
404+ * returns.
405+ *
406+ * @thread_safety This function must only be called from the main thread.
407+ *
408+ * @sa @ref clipboard
409+ * @sa glfwGetX11SelectionString
410+ * @sa glfwSetClipboardString
411+ *
412+ * @since Added in version 3.3.
413+ *
414+ * @ingroup native
415+ */
416+GLFWAPI void glfwSetX11SelectionString(const char* string);
417+
418+/*! @brief Returns the contents of the current primary selection as a string.
419+ *
420+ * If the selection is empty or if its contents cannot be converted, `NULL`
421+ * is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated.
422+ *
423+ * @return The contents of the selection as a UTF-8 encoded string, or `NULL`
424+ * if an [error](@ref error_handling) occurred.
425+ *
426+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
427+ * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
428+ *
429+ * @pointer_lifetime The returned string is allocated and freed by GLFW. You
430+ * should not free it yourself. It is valid until the next call to @ref
431+ * glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the
432+ * library is terminated.
433+ *
434+ * @thread_safety This function must only be called from the main thread.
435+ *
436+ * @sa @ref clipboard
437+ * @sa glfwSetX11SelectionString
438+ * @sa glfwGetClipboardString
439+ *
440+ * @since Added in version 3.3.
441+ *
442+ * @ingroup native
443+ */
444+GLFWAPI const char* glfwGetX11SelectionString(void);
445+#endif
446+
447+#if defined(GLFW_EXPOSE_NATIVE_GLX)
448+/*! @brief Returns the `GLXContext` of the specified window.
449+ *
450+ * @return The `GLXContext` of the specified window, or `NULL` if an
451+ * [error](@ref error_handling) occurred.
452+ *
453+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
454+ * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE.
455+ *
456+ * @thread_safety This function may be called from any thread. Access is not
457+ * synchronized.
458+ *
459+ * @since Added in version 3.0.
460+ *
461+ * @ingroup native
462+ */
463+GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
464+
465+/*! @brief Returns the `GLXWindow` of the specified window.
466+ *
467+ * @return The `GLXWindow` of the specified window, or `None` if an
468+ * [error](@ref error_handling) occurred.
469+ *
470+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
471+ * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE.
472+ *
473+ * @thread_safety This function may be called from any thread. Access is not
474+ * synchronized.
475+ *
476+ * @since Added in version 3.2.
477+ *
478+ * @ingroup native
479+ */
480+GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
481+
482+/*! @brief Retrieves the `GLXFBConfig` of the specified window's `GLXWindow`.
483+ *
484+ * @param[in] window The window whose `GLXWindow` to query.
485+ * @param[out] config The `GLXFBConfig` of the window `GLXWindow`, if available.
486+ * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
487+ * [error](@ref error_handling) occurred.
488+ *
489+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
490+ * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE.
491+ *
492+ * @remark `GLXFBConfig` is an opaque type. Unlike other GLFW functions, the
493+ * @p config out parameter is not cleared on error, as core GLX does not define
494+ * any invalid value.
495+ *
496+ * @thread_safety This function may be called from any thread. Access is not
497+ * synchronized.
498+ *
499+ * @since Added in version 3.5
500+ *
501+ * @ingroup native
502+ */
503+GLFWAPI int glfwGetGLXFBConfig(GLFWwindow* window, GLXFBConfig* config);
504+#endif
505+
506+#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
507+/*! @brief Returns the `struct wl_display*` used by GLFW.
508+ *
509+ * @return The `struct wl_display*` used by GLFW, or `NULL` if an
510+ * [error](@ref error_handling) occurred.
511+ *
512+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
513+ * GLFW_PLATFORM_UNAVAILABLE.
514+ *
515+ * @thread_safety This function may be called from any thread. Access is not
516+ * synchronized.
517+ *
518+ * @since Added in version 3.2.
519+ *
520+ * @ingroup native
521+ */
522+GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
523+
524+/*! @brief Returns the `struct wl_output*` of the specified monitor.
525+ *
526+ * @return The `struct wl_output*` of the specified monitor, or `NULL` if an
527+ * [error](@ref error_handling) occurred.
528+ *
529+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
530+ * GLFW_PLATFORM_UNAVAILABLE.
531+ *
532+ * @thread_safety This function may be called from any thread. Access is not
533+ * synchronized.
534+ *
535+ * @since Added in version 3.2.
536+ *
537+ * @ingroup native
538+ */
539+GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
540+
541+/*! @brief Returns the main `struct wl_surface*` of the specified window.
542+ *
543+ * @return The main `struct wl_surface*` of the specified window, or `NULL` if
544+ * an [error](@ref error_handling) occurred.
545+ *
546+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
547+ * GLFW_PLATFORM_UNAVAILABLE.
548+ *
549+ * @thread_safety This function may be called from any thread. Access is not
550+ * synchronized.
551+ *
552+ * @since Added in version 3.2.
553+ *
554+ * @ingroup native
555+ */
556+GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
557+#endif
558+
559+#if defined(GLFW_EXPOSE_NATIVE_EGL)
560+/*! @brief Returns the `EGLDisplay` used by GLFW.
561+ *
562+ * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
563+ * [error](@ref error_handling) occurred.
564+ *
565+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
566+ *
567+ * @remark Because EGL is initialized on demand, this function will return
568+ * `EGL_NO_DISPLAY` until the first context has been created via EGL.
569+ *
570+ * @thread_safety This function may be called from any thread. Access is not
571+ * synchronized.
572+ *
573+ * @since Added in version 3.0.
574+ *
575+ * @ingroup native
576+ */
577+GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
578+
579+/*! @brief Returns the `EGLContext` of the specified window.
580+ *
581+ * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
582+ * [error](@ref error_handling) occurred.
583+ *
584+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
585+ * GLFW_NO_WINDOW_CONTEXT.
586+ *
587+ * @thread_safety This function may be called from any thread. Access is not
588+ * synchronized.
589+ *
590+ * @since Added in version 3.0.
591+ *
592+ * @ingroup native
593+ */
594+GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
595+
596+/*! @brief Returns the `EGLSurface` of the specified window.
597+ *
598+ * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
599+ * [error](@ref error_handling) occurred.
600+ *
601+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
602+ * GLFW_NO_WINDOW_CONTEXT.
603+ *
604+ * @thread_safety This function may be called from any thread. Access is not
605+ * synchronized.
606+ *
607+ * @since Added in version 3.0.
608+ *
609+ * @ingroup native
610+ */
611+GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
612+
613+/*! @brief Retrieves the `EGLConfig` of the specified window's `EGLSurface`.
614+ *
615+ * @param[in] window The window whose `EGLSurface` to query.
616+ * @param[out] config The `EGLConfig` of the window `EGLSurface`, if available.
617+ * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
618+ * [error](@ref error_handling) occurred.
619+ *
620+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
621+ * GLFW_NO_WINDOW_CONTEXT.
622+ *
623+ * @remark `EGLConfig` is an opaque type. Unlike other GLFW functions, the @p
624+ * config out parameter is not cleared on error, as core EGL does not define
625+ * any invalid value.
626+ *
627+ * @thread_safety This function may be called from any thread. Access is not
628+ * synchronized.
629+ *
630+ * @since Added in version 3.5.
631+ *
632+ * @ingroup native
633+ */
634+GLFWAPI int glfwGetEGLConfig(GLFWwindow* window, EGLConfig* config);
635+#endif
636+
637+#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
638+/*! @brief Retrieves the color buffer associated with the specified window.
639+ *
640+ * @param[in] window The window whose color buffer to retrieve.
641+ * @param[out] width Where to store the width of the color buffer, or `NULL`.
642+ * @param[out] height Where to store the height of the color buffer, or `NULL`.
643+ * @param[out] format Where to store the OSMesa pixel format of the color
644+ * buffer, or `NULL`.
645+ * @param[out] buffer Where to store the address of the color buffer, or
646+ * `NULL`.
647+ * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
648+ * [error](@ref error_handling) occurred.
649+ *
650+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
651+ * GLFW_NO_WINDOW_CONTEXT.
652+ *
653+ * @thread_safety This function may be called from any thread. Access is not
654+ * synchronized.
655+ *
656+ * @since Added in version 3.3.
657+ *
658+ * @ingroup native
659+ */
660+GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer);
661+
662+/*! @brief Retrieves the depth buffer associated with the specified window.
663+ *
664+ * @param[in] window The window whose depth buffer to retrieve.
665+ * @param[out] width Where to store the width of the depth buffer, or `NULL`.
666+ * @param[out] height Where to store the height of the depth buffer, or `NULL`.
667+ * @param[out] bytesPerValue Where to store the number of bytes per depth
668+ * buffer element, or `NULL`.
669+ * @param[out] buffer Where to store the address of the depth buffer, or
670+ * `NULL`.
671+ * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
672+ * [error](@ref error_handling) occurred.
673+ *
674+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
675+ * GLFW_NO_WINDOW_CONTEXT.
676+ *
677+ * @thread_safety This function may be called from any thread. Access is not
678+ * synchronized.
679+ *
680+ * @since Added in version 3.3.
681+ *
682+ * @ingroup native
683+ */
684+GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer);
685+
686+/*! @brief Returns the `OSMesaContext` of the specified window.
687+ *
688+ * @return The `OSMesaContext` of the specified window, or `NULL` if an
689+ * [error](@ref error_handling) occurred.
690+ *
691+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
692+ * GLFW_NO_WINDOW_CONTEXT.
693+ *
694+ * @thread_safety This function may be called from any thread. Access is not
695+ * synchronized.
696+ *
697+ * @since Added in version 3.3.
698+ *
699+ * @ingroup native
700+ */
701+GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window);
702+#endif
703+
704+#ifdef __cplusplus
705+}
706+#endif
707+
708+#endif /* _glfw3_native_h_ */
709+
@@ -0,0 +1,69 @@
1+file(GLOB ROOT_SOURCE *.cpp)
2+file(GLOB ROOT_INLINE *.inl)
3+file(GLOB ROOT_HEADER *.hpp)
4+file(GLOB ROOT_TEXT ../*.txt)
5+file(GLOB ROOT_MD ../*.md)
6+file(GLOB ROOT_NAT ../util/glm.natvis)
7+
8+file(GLOB_RECURSE CORE_SOURCE ./detail/*.cpp)
9+file(GLOB_RECURSE CORE_INLINE ./detail/*.inl)
10+file(GLOB_RECURSE CORE_HEADER ./detail/*.hpp)
11+
12+file(GLOB_RECURSE EXT_SOURCE ./ext/*.cpp)
13+file(GLOB_RECURSE EXT_INLINE ./ext/*.inl)
14+file(GLOB_RECURSE EXT_HEADER ./ext/*.hpp)
15+
16+file(GLOB_RECURSE GTC_SOURCE ./gtc/*.cpp)
17+file(GLOB_RECURSE GTC_INLINE ./gtc/*.inl)
18+file(GLOB_RECURSE GTC_HEADER ./gtc/*.hpp)
19+
20+file(GLOB_RECURSE GTX_SOURCE ./gtx/*.cpp)
21+file(GLOB_RECURSE GTX_INLINE ./gtx/*.inl)
22+file(GLOB_RECURSE GTX_HEADER ./gtx/*.hpp)
23+
24+file(GLOB_RECURSE SIMD_SOURCE ./simd/*.cpp)
25+file(GLOB_RECURSE SIMD_INLINE ./simd/*.inl)
26+file(GLOB_RECURSE SIMD_HEADER ./simd/*.h)
27+
28+source_group("Text Files" FILES ${ROOT_TEXT} ${ROOT_MD})
29+source_group("Core Files" FILES ${CORE_SOURCE})
30+source_group("Core Files" FILES ${CORE_INLINE})
31+source_group("Core Files" FILES ${CORE_HEADER})
32+source_group("EXT Files" FILES ${EXT_SOURCE})
33+source_group("EXT Files" FILES ${EXT_INLINE})
34+source_group("EXT Files" FILES ${EXT_HEADER})
35+source_group("GTC Files" FILES ${GTC_SOURCE})
36+source_group("GTC Files" FILES ${GTC_INLINE})
37+source_group("GTC Files" FILES ${GTC_HEADER})
38+source_group("GTX Files" FILES ${GTX_SOURCE})
39+source_group("GTX Files" FILES ${GTX_INLINE})
40+source_group("GTX Files" FILES ${GTX_HEADER})
41+source_group("SIMD Files" FILES ${SIMD_SOURCE})
42+source_group("SIMD Files" FILES ${SIMD_INLINE})
43+source_group("SIMD Files" FILES ${SIMD_HEADER})
44+
45+add_library(glm-header-only INTERFACE)
46+add_library(glm::glm-header-only ALIAS glm-header-only)
47+
48+target_include_directories(glm-header-only INTERFACE
49+ "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>"
50+ "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
51+)
52+
53+if (GLM_BUILD_LIBRARY)
54+ add_library(glm
55+ ${ROOT_TEXT} ${ROOT_MD} ${ROOT_NAT}
56+ ${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER}
57+ ${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER}
58+ ${EXT_SOURCE} ${EXT_INLINE} ${EXT_HEADER}
59+ ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER}
60+ ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER}
61+ ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER}
62+ )
63+ add_library(glm::glm ALIAS glm)
64+ target_link_libraries(glm PUBLIC glm-header-only)
65+else()
66+ add_library(glm INTERFACE)
67+ add_library(glm::glm ALIAS glm)
68+ target_link_libraries(glm INTERFACE glm-header-only)
69+endif()
@@ -0,0 +1,539 @@
1+/// @ref core
2+/// @file glm/common.hpp
3+///
4+/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
5+///
6+/// @defgroup core_func_common Common functions
7+/// @ingroup core
8+///
9+/// Provides GLSL common functions
10+///
11+/// These all operate component-wise. The description is per component.
12+///
13+/// Include <glm/common.hpp> to use these core features.
14+
15+#pragma once
16+
17+#include "detail/qualifier.hpp"
18+#include "detail/_fixes.hpp"
19+
20+namespace glm
21+{
22+ /// @addtogroup core_func_common
23+ /// @{
24+
25+ /// Returns x if x >= 0; otherwise, it returns -x.
26+ ///
27+ /// @tparam genType floating-point or signed integer; scalar or vector types.
28+ ///
29+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/abs.xml">GLSL abs man page</a>
30+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
31+ template<typename genType>
32+ GLM_FUNC_DECL GLM_CONSTEXPR genType abs(genType x);
33+
34+ /// Returns x if x >= 0; otherwise, it returns -x.
35+ ///
36+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
37+ /// @tparam T Floating-point or signed integer scalar types
38+ /// @tparam Q Value from qualifier enum
39+ ///
40+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/abs.xml">GLSL abs man page</a>
41+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
42+ template<length_t L, typename T, qualifier Q>
43+ GLM_FUNC_DECL GLM_CONSTEXPR vec<L, T, Q> abs(vec<L, T, Q> const& x);
44+
45+ /// Returns 1.0 if x > 0, 0.0 if x == 0, or -1.0 if x < 0.
46+ ///
47+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
48+ /// @tparam T Floating-point scalar types
49+ /// @tparam Q Value from qualifier enum
50+ ///
51+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sign.xml">GLSL sign man page</a>
52+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
53+ template<length_t L, typename T, qualifier Q>
54+ GLM_FUNC_DECL GLM_CONSTEXPR vec<L, T, Q> sign(vec<L, T, Q> const& x);
55+
56+ /// Returns a value equal to the nearest integer that is less then or equal to x.
57+ ///
58+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
59+ /// @tparam T Floating-point scalar types
60+ /// @tparam Q Value from qualifier enum
61+ ///
62+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floor.xml">GLSL floor man page</a>
63+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
64+ template<length_t L, typename T, qualifier Q>
65+ GLM_FUNC_DECL vec<L, T, Q> floor(vec<L, T, Q> const& x);
66+
67+ /// Returns a value equal to the nearest integer to x
68+ /// whose absolute value is not larger than the absolute value of x.
69+ ///
70+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
71+ /// @tparam T Floating-point scalar types
72+ /// @tparam Q Value from qualifier enum
73+ ///
74+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/trunc.xml">GLSL trunc man page</a>
75+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
76+ template<length_t L, typename T, qualifier Q>
77+ GLM_FUNC_DECL vec<L, T, Q> trunc(vec<L, T, Q> const& x);
78+
79+ /// Returns a value equal to the nearest integer to x.
80+ /// The fraction 0.5 will round in a direction chosen by the
81+ /// implementation, presumably the direction that is fastest.
82+ /// This includes the possibility that round(x) returns the
83+ /// same value as roundEven(x) for all values of x.
84+ ///
85+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
86+ /// @tparam T Floating-point scalar types
87+ /// @tparam Q Value from qualifier enum
88+ ///
89+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/round.xml">GLSL round man page</a>
90+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
91+ template<length_t L, typename T, qualifier Q>
92+ GLM_FUNC_DECL vec<L, T, Q> round(vec<L, T, Q> const& x);
93+
94+ /// Returns a value equal to the nearest integer to x.
95+ /// A fractional part of 0.5 will round toward the nearest even
96+ /// integer. (Both 3.5 and 4.5 for x will return 4.0.)
97+ ///
98+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
99+ /// @tparam T Floating-point scalar types
100+ /// @tparam Q Value from qualifier enum
101+ ///
102+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/roundEven.xml">GLSL roundEven man page</a>
103+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
104+ /// @see <a href="http://developer.amd.com/documentation/articles/pages/New-Round-to-Even-Technique.aspx">New round to even technique</a>
105+ template<length_t L, typename T, qualifier Q>
106+ GLM_FUNC_DECL vec<L, T, Q> roundEven(vec<L, T, Q> const& x);
107+
108+ /// Returns a value equal to the nearest integer
109+ /// that is greater than or equal to x.
110+ ///
111+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
112+ /// @tparam T Floating-point scalar types
113+ /// @tparam Q Value from qualifier enum
114+ ///
115+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/ceil.xml">GLSL ceil man page</a>
116+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
117+ template<length_t L, typename T, qualifier Q>
118+ GLM_FUNC_DECL vec<L, T, Q> ceil(vec<L, T, Q> const& x);
119+
120+ /// Return x - floor(x).
121+ ///
122+ /// @tparam genType Floating-point scalar or vector types.
123+ ///
124+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/fract.xml">GLSL fract man page</a>
125+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
126+ template<typename genType>
127+ GLM_FUNC_DECL genType fract(genType x);
128+
129+ /// Return x - floor(x).
130+ ///
131+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
132+ /// @tparam T Floating-point scalar types
133+ /// @tparam Q Value from qualifier enum
134+ ///
135+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/fract.xml">GLSL fract man page</a>
136+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
137+ template<length_t L, typename T, qualifier Q>
138+ GLM_FUNC_DECL vec<L, T, Q> fract(vec<L, T, Q> const& x);
139+
140+ template<typename genType>
141+ GLM_FUNC_DECL genType mod(genType x, genType y);
142+
143+ template<length_t L, typename T, qualifier Q>
144+ GLM_FUNC_DECL vec<L, T, Q> mod(vec<L, T, Q> const& x, T y);
145+
146+ /// Modulus. Returns x - y * floor(x / y)
147+ /// for each component in x using the floating point value y.
148+ ///
149+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
150+ /// @tparam T Floating-point scalar types, include glm/gtc/integer for integer scalar types support
151+ /// @tparam Q Value from qualifier enum
152+ ///
153+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml">GLSL mod man page</a>
154+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
155+ template<length_t L, typename T, qualifier Q>
156+ GLM_FUNC_DECL vec<L, T, Q> mod(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
157+
158+ /// Returns the fractional part of x and sets i to the integer
159+ /// part (as a whole number floating point value). Both the
160+ /// return value and the output parameter will have the same
161+ /// sign as x.
162+ ///
163+ /// @tparam genType Floating-point scalar or vector types.
164+ ///
165+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/modf.xml">GLSL modf man page</a>
166+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
167+ template<typename genType>
168+ GLM_FUNC_DECL genType modf(genType x, genType& i);
169+
170+ /// Returns y if y < x; otherwise, it returns x.
171+ ///
172+ /// @tparam genType Floating-point or integer; scalar or vector types.
173+ ///
174+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/min.xml">GLSL min man page</a>
175+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
176+ template<typename genType>
177+ GLM_FUNC_DECL GLM_CONSTEXPR genType min(genType x, genType y);
178+
179+ /// Returns y if y < x; otherwise, it returns x.
180+ ///
181+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
182+ /// @tparam T Floating-point or integer scalar types
183+ /// @tparam Q Value from qualifier enum
184+ ///
185+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/min.xml">GLSL min man page</a>
186+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
187+ template<length_t L, typename T, qualifier Q>
188+ GLM_FUNC_DECL GLM_CONSTEXPR vec<L, T, Q> min(vec<L, T, Q> const& x, T y);
189+
190+ /// Returns y if y < x; otherwise, it returns x.
191+ ///
192+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
193+ /// @tparam T Floating-point or integer scalar types
194+ /// @tparam Q Value from qualifier enum
195+ ///
196+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/min.xml">GLSL min man page</a>
197+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
198+ template<length_t L, typename T, qualifier Q>
199+ GLM_FUNC_DECL GLM_CONSTEXPR vec<L, T, Q> min(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
200+
201+ /// Returns y if x < y; otherwise, it returns x.
202+ ///
203+ /// @tparam genType Floating-point or integer; scalar or vector types.
204+ ///
205+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/max.xml">GLSL max man page</a>
206+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
207+ template<typename genType>
208+ GLM_FUNC_DECL GLM_CONSTEXPR genType max(genType x, genType y);
209+
210+ /// Returns y if x < y; otherwise, it returns x.
211+ ///
212+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
213+ /// @tparam T Floating-point or integer scalar types
214+ /// @tparam Q Value from qualifier enum
215+ ///
216+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/max.xml">GLSL max man page</a>
217+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
218+ template<length_t L, typename T, qualifier Q>
219+ GLM_FUNC_DECL GLM_CONSTEXPR vec<L, T, Q> max(vec<L, T, Q> const& x, T y);
220+
221+ /// Returns y if x < y; otherwise, it returns x.
222+ ///
223+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
224+ /// @tparam T Floating-point or integer scalar types
225+ /// @tparam Q Value from qualifier enum
226+ ///
227+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/max.xml">GLSL max man page</a>
228+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
229+ template<length_t L, typename T, qualifier Q>
230+ GLM_FUNC_DECL GLM_CONSTEXPR vec<L, T, Q> max(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
231+
232+ /// Returns min(max(x, minVal), maxVal) for each component in x
233+ /// using the floating-point values minVal and maxVal.
234+ ///
235+ /// @tparam genType Floating-point or integer; scalar or vector types.
236+ ///
237+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/clamp.xml">GLSL clamp man page</a>
238+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
239+ template<typename genType>
240+ GLM_FUNC_DECL GLM_CONSTEXPR genType clamp(genType x, genType minVal, genType maxVal);
241+
242+ /// Returns min(max(x, minVal), maxVal) for each component in x
243+ /// using the floating-point values minVal and maxVal.
244+ ///
245+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
246+ /// @tparam T Floating-point or integer scalar types
247+ /// @tparam Q Value from qualifier enum
248+ ///
249+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/clamp.xml">GLSL clamp man page</a>
250+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
251+ template<length_t L, typename T, qualifier Q>
252+ GLM_FUNC_DECL GLM_CONSTEXPR vec<L, T, Q> clamp(vec<L, T, Q> const& x, T minVal, T maxVal);
253+
254+ /// Returns min(max(x, minVal), maxVal) for each component in x
255+ /// using the floating-point values minVal and maxVal.
256+ ///
257+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
258+ /// @tparam T Floating-point or integer scalar types
259+ /// @tparam Q Value from qualifier enum
260+ ///
261+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/clamp.xml">GLSL clamp man page</a>
262+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
263+ template<length_t L, typename T, qualifier Q>
264+ GLM_FUNC_DECL GLM_CONSTEXPR vec<L, T, Q> clamp(vec<L, T, Q> const& x, vec<L, T, Q> const& minVal, vec<L, T, Q> const& maxVal);
265+
266+ /// If genTypeU is a floating scalar or vector:
267+ /// Returns x * (1.0 - a) + y * a, i.e., the linear blend of
268+ /// x and y using the floating-point value a.
269+ /// The value for a is not restricted to the range [0, 1].
270+ ///
271+ /// If genTypeU is a boolean scalar or vector:
272+ /// Selects which vector each returned component comes
273+ /// from. For a component of 'a' that is false, the
274+ /// corresponding component of 'x' is returned. For a
275+ /// component of 'a' that is true, the corresponding
276+ /// component of 'y' is returned. Components of 'x' and 'y' that
277+ /// are not selected are allowed to be invalid floating point
278+ /// values and will have no effect on the results. Thus, this
279+ /// provides different functionality than
280+ /// genType mix(genType x, genType y, genType(a))
281+ /// where a is a Boolean vector.
282+ ///
283+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mix.xml">GLSL mix man page</a>
284+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
285+ ///
286+ /// @param[in] x Value to interpolate.
287+ /// @param[in] y Value to interpolate.
288+ /// @param[in] a Interpolant.
289+ ///
290+ /// @tparam genTypeT Floating point scalar or vector.
291+ /// @tparam genTypeU Floating point or boolean scalar or vector. It can't be a vector if it is the length of genTypeT.
292+ ///
293+ /// @code
294+ /// #include <glm/glm.hpp>
295+ /// ...
296+ /// float a;
297+ /// bool b;
298+ /// glm::dvec3 e;
299+ /// glm::dvec3 f;
300+ /// glm::vec4 g;
301+ /// glm::vec4 h;
302+ /// ...
303+ /// glm::vec4 r = glm::mix(g, h, a); // Interpolate with a floating-point scalar two vectors.
304+ /// glm::vec4 s = glm::mix(g, h, b); // Returns g or h;
305+ /// glm::dvec3 t = glm::mix(e, f, a); // Types of the third parameter is not required to match with the first and the second.
306+ /// glm::vec4 u = glm::mix(g, h, r); // Interpolations can be perform per component with a vector for the last parameter.
307+ /// @endcode
308+ template<typename genTypeT, typename genTypeU>
309+ GLM_FUNC_DECL GLM_CONSTEXPR genTypeT mix(genTypeT x, genTypeT y, genTypeU a);
310+
311+ template<length_t L, typename T, typename U, qualifier Q>
312+ GLM_FUNC_DECL GLM_CONSTEXPR vec<L, T, Q> mix(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, U, Q> const& a);
313+
314+ template<length_t L, typename T, typename U, qualifier Q>
315+ GLM_FUNC_DECL GLM_CONSTEXPR vec<L, T, Q> mix(vec<L, T, Q> const& x, vec<L, T, Q> const& y, U a);
316+
317+ /// Returns 0.0 if x < edge, otherwise it returns 1.0 for each component of a genType.
318+ ///
319+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/step.xml">GLSL step man page</a>
320+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
321+ template<typename genType>
322+ GLM_FUNC_DECL genType step(genType edge, genType x);
323+
324+ /// Returns 0.0 if x < edge, otherwise it returns 1.0.
325+ ///
326+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
327+ /// @tparam T Floating-point scalar types
328+ /// @tparam Q Value from qualifier enum
329+ ///
330+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/step.xml">GLSL step man page</a>
331+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
332+ template<length_t L, typename T, qualifier Q>
333+ GLM_FUNC_DECL vec<L, T, Q> step(T edge, vec<L, T, Q> const& x);
334+
335+ /// Returns 0.0 if x < edge, otherwise it returns 1.0.
336+ ///
337+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
338+ /// @tparam T Floating-point scalar types
339+ /// @tparam Q Value from qualifier enum
340+ ///
341+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/step.xml">GLSL step man page</a>
342+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
343+ template<length_t L, typename T, qualifier Q>
344+ GLM_FUNC_DECL vec<L, T, Q> step(vec<L, T, Q> const& edge, vec<L, T, Q> const& x);
345+
346+ /// Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and
347+ /// performs smooth Hermite interpolation between 0 and 1
348+ /// when edge0 < x < edge1. This is useful in cases where
349+ /// you would want a threshold function with a smooth
350+ /// transition. This is equivalent to:
351+ /// genType t;
352+ /// t = clamp ((x - edge0) / (edge1 - edge0), 0, 1);
353+ /// return t * t * (3 - 2 * t);
354+ /// Results are undefined if edge0 >= edge1.
355+ ///
356+ /// @tparam genType Floating-point scalar or vector types.
357+ ///
358+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/smoothstep.xml">GLSL smoothstep man page</a>
359+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
360+ template<typename genType>
361+ GLM_FUNC_DECL genType smoothstep(genType edge0, genType edge1, genType x);
362+
363+ template<length_t L, typename T, qualifier Q>
364+ GLM_FUNC_DECL vec<L, T, Q> smoothstep(T edge0, T edge1, vec<L, T, Q> const& x);
365+
366+ template<length_t L, typename T, qualifier Q>
367+ GLM_FUNC_DECL vec<L, T, Q> smoothstep(vec<L, T, Q> const& edge0, vec<L, T, Q> const& edge1, vec<L, T, Q> const& x);
368+
369+ /// Returns true if x holds a NaN (not a number)
370+ /// representation in the underlying implementation's set of
371+ /// floating point representations. Returns false otherwise,
372+ /// including for implementations with no NaN
373+ /// representations.
374+ ///
375+ /// /!\ When using compiler fast math, this function may fail.
376+ ///
377+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
378+ /// @tparam T Floating-point scalar types
379+ /// @tparam Q Value from qualifier enum
380+ ///
381+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/isnan.xml">GLSL isnan man page</a>
382+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
383+ template<length_t L, typename T, qualifier Q>
384+ GLM_FUNC_DECL vec<L, bool, Q> isnan(vec<L, T, Q> const& x);
385+
386+ /// Returns true if x holds a positive infinity or negative
387+ /// infinity representation in the underlying implementation's
388+ /// set of floating point representations. Returns false
389+ /// otherwise, including for implementations with no infinity
390+ /// representations.
391+ ///
392+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
393+ /// @tparam T Floating-point scalar types
394+ /// @tparam Q Value from qualifier enum
395+ ///
396+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/isinf.xml">GLSL isinf man page</a>
397+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
398+ template<length_t L, typename T, qualifier Q>
399+ GLM_FUNC_DECL vec<L, bool, Q> isinf(vec<L, T, Q> const& x);
400+
401+ /// Returns a signed integer value representing
402+ /// the encoding of a floating-point value. The floating-point
403+ /// value's bit-level representation is preserved.
404+ ///
405+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floatBitsToInt.xml">GLSL floatBitsToInt man page</a>
406+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
407+ GLM_FUNC_DECL int floatBitsToInt(float v);
408+
409+ /// Returns a signed integer value representing
410+ /// the encoding of a floating-point value. The floatingpoint
411+ /// value's bit-level representation is preserved.
412+ ///
413+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
414+ /// @tparam Q Value from qualifier enum
415+ ///
416+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floatBitsToInt.xml">GLSL floatBitsToInt man page</a>
417+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
418+ template<length_t L, qualifier Q>
419+ GLM_FUNC_DECL vec<L, int, Q> floatBitsToInt(vec<L, float, Q> const& v);
420+
421+ /// Returns a unsigned integer value representing
422+ /// the encoding of a floating-point value. The floatingpoint
423+ /// value's bit-level representation is preserved.
424+ ///
425+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floatBitsToUint.xml">GLSL floatBitsToUint man page</a>
426+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
427+ GLM_FUNC_DECL uint floatBitsToUint(float v);
428+
429+ /// Returns a unsigned integer value representing
430+ /// the encoding of a floating-point value. The floatingpoint
431+ /// value's bit-level representation is preserved.
432+ ///
433+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
434+ /// @tparam Q Value from qualifier enum
435+ ///
436+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floatBitsToUint.xml">GLSL floatBitsToUint man page</a>
437+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
438+ template<length_t L, qualifier Q>
439+ GLM_FUNC_DECL vec<L, uint, Q> floatBitsToUint(vec<L, float, Q> const& v);
440+
441+ /// Returns a floating-point value corresponding to a signed
442+ /// integer encoding of a floating-point value.
443+ /// If an inf or NaN is passed in, it will not signal, and the
444+ /// resulting floating point value is unspecified. Otherwise,
445+ /// the bit-level representation is preserved.
446+ ///
447+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/intBitsToFloat.xml">GLSL intBitsToFloat man page</a>
448+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
449+ GLM_FUNC_DECL float intBitsToFloat(int v);
450+
451+ /// Returns a floating-point value corresponding to a signed
452+ /// integer encoding of a floating-point value.
453+ /// If an inf or NaN is passed in, it will not signal, and the
454+ /// resulting floating point value is unspecified. Otherwise,
455+ /// the bit-level representation is preserved.
456+ ///
457+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
458+ /// @tparam Q Value from qualifier enum
459+ ///
460+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/intBitsToFloat.xml">GLSL intBitsToFloat man page</a>
461+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
462+ template<length_t L, qualifier Q>
463+ GLM_FUNC_DECL vec<L, float, Q> intBitsToFloat(vec<L, int, Q> const& v);
464+
465+ /// Returns a floating-point value corresponding to a
466+ /// unsigned integer encoding of a floating-point value.
467+ /// If an inf or NaN is passed in, it will not signal, and the
468+ /// resulting floating point value is unspecified. Otherwise,
469+ /// the bit-level representation is preserved.
470+ ///
471+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/uintBitsToFloat.xml">GLSL uintBitsToFloat man page</a>
472+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
473+ GLM_FUNC_DECL float uintBitsToFloat(uint v);
474+
475+ /// Returns a floating-point value corresponding to a
476+ /// unsigned integer encoding of a floating-point value.
477+ /// If an inf or NaN is passed in, it will not signal, and the
478+ /// resulting floating point value is unspecified. Otherwise,
479+ /// the bit-level representation is preserved.
480+ ///
481+ /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
482+ /// @tparam Q Value from qualifier enum
483+ ///
484+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/uintBitsToFloat.xml">GLSL uintBitsToFloat man page</a>
485+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
486+ template<length_t L, qualifier Q>
487+ GLM_FUNC_DECL vec<L, float, Q> uintBitsToFloat(vec<L, uint, Q> const& v);
488+
489+ /// Computes and returns a * b + c.
490+ ///
491+ /// @tparam genType Floating-point scalar or vector types.
492+ ///
493+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/fma.xml">GLSL fma man page</a>
494+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
495+ template<typename genType>
496+ GLM_FUNC_DECL genType fma(genType const& a, genType const& b, genType const& c);
497+
498+ /// Splits x into a floating-point significand in the range
499+ /// [0.5, 1.0) and an integral exponent of two, such that:
500+ /// x = significand * exp(2, exponent)
501+ ///
502+ /// The significand is returned by the function and the
503+ /// exponent is returned in the parameter exp. For a
504+ /// floating-point value of zero, the significant and exponent
505+ /// are both zero. For a floating-point value that is an
506+ /// infinity or is not a number, the results are undefined.
507+ ///
508+ /// @tparam genType Floating-point scalar or vector types.
509+ ///
510+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/frexp.xml">GLSL frexp man page</a>
511+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
512+ template<typename genType>
513+ GLM_FUNC_DECL genType frexp(genType x, int& exp);
514+
515+ template<length_t L, typename T, qualifier Q>
516+ GLM_FUNC_DECL vec<L, T, Q> frexp(vec<L, T, Q> const& v, vec<L, int, Q>& exp);
517+
518+ /// Builds a floating-point number from x and the
519+ /// corresponding integral exponent of two in exp, returning:
520+ /// significand * exp(2, exponent)
521+ ///
522+ /// If this product is too large to be represented in the
523+ /// floating-point type, the result is undefined.
524+ ///
525+ /// @tparam genType Floating-point scalar or vector types.
526+ ///
527+ /// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/ldexp.xml">GLSL ldexp man page</a>;
528+ /// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
529+ template<typename genType>
530+ GLM_FUNC_DECL genType ldexp(genType const& x, int const& exp);
531+
532+ template<length_t L, typename T, qualifier Q>
533+ GLM_FUNC_DECL vec<L, T, Q> ldexp(vec<L, T, Q> const& v, vec<L, int, Q> const& exp);
534+
535+ /// @}
536+}//namespace glm
537+
538+#include "detail/func_common.inl"
539+
@@ -0,0 +1,27 @@
1+#include <cmath>
2+
3+//! Workaround for compatibility with other libraries
4+#ifdef max
5+#undef max
6+#endif
7+
8+//! Workaround for compatibility with other libraries
9+#ifdef min
10+#undef min
11+#endif
12+
13+//! Workaround for Android
14+#ifdef isnan
15+#undef isnan
16+#endif
17+
18+//! Workaround for Android
19+#ifdef isinf
20+#undef isinf
21+#endif
22+
23+//! Workaround for Chrone Native Client
24+#ifdef log2
25+#undef log2
26+#endif
27+
@@ -0,0 +1,81 @@
1+#pragma once
2+
3+#include "../common.hpp"
4+
5+namespace glm{
6+namespace detail
7+{
8+ template<typename T>
9+ GLM_FUNC_QUALIFIER T mod289(T const& x)
10+ {
11+ return x - floor(x * (static_cast<T>(1.0) / static_cast<T>(289.0))) * static_cast<T>(289.0);
12+ }
13+
14+ template<typename T>
15+ GLM_FUNC_QUALIFIER T permute(T const& x)
16+ {
17+ return mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);
18+ }
19+
20+ template<typename T, qualifier Q>
21+ GLM_FUNC_QUALIFIER vec<2, T, Q> permute(vec<2, T, Q> const& x)
22+ {
23+ return mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);
24+ }
25+
26+ template<typename T, qualifier Q>
27+ GLM_FUNC_QUALIFIER vec<3, T, Q> permute(vec<3, T, Q> const& x)
28+ {
29+ return mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);
30+ }
31+
32+ template<typename T, qualifier Q>
33+ GLM_FUNC_QUALIFIER vec<4, T, Q> permute(vec<4, T, Q> const& x)
34+ {
35+ return mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);
36+ }
37+
38+ template<typename T>
39+ GLM_FUNC_QUALIFIER T taylorInvSqrt(T const& r)
40+ {
41+ return static_cast<T>(1.79284291400159) - static_cast<T>(0.85373472095314) * r;
42+ }
43+
44+ template<typename T, qualifier Q>
45+ GLM_FUNC_QUALIFIER vec<2, T, Q> taylorInvSqrt(vec<2, T, Q> const& r)
46+ {
47+ return static_cast<T>(1.79284291400159) - static_cast<T>(0.85373472095314) * r;
48+ }
49+
50+ template<typename T, qualifier Q>
51+ GLM_FUNC_QUALIFIER vec<3, T, Q> taylorInvSqrt(vec<3, T, Q> const& r)
52+ {
53+ return static_cast<T>(1.79284291400159) - static_cast<T>(0.85373472095314) * r;
54+ }
55+
56+ template<typename T, qualifier Q>
57+ GLM_FUNC_QUALIFIER vec<4, T, Q> taylorInvSqrt(vec<4, T, Q> const& r)
58+ {
59+ return static_cast<T>(1.79284291400159) - static_cast<T>(0.85373472095314) * r;
60+ }
61+
62+ template<typename T, qualifier Q>
63+ GLM_FUNC_QUALIFIER vec<2, T, Q> fade(vec<2, T, Q> const& t)
64+ {
65+ return (t * t * t) * (t * (t * static_cast<T>(6) - static_cast<T>(15)) + static_cast<T>(10));
66+ }
67+
68+ template<typename T, qualifier Q>
69+ GLM_FUNC_QUALIFIER vec<3, T, Q> fade(vec<3, T, Q> const& t)
70+ {
71+ return (t * t * t) * (t * (t * static_cast<T>(6) - static_cast<T>(15)) + static_cast<T>(10));
72+ }
73+
74+ template<typename T, qualifier Q>
75+ GLM_FUNC_QUALIFIER vec<4, T, Q> fade(vec<4, T, Q> const& t)
76+ {
77+ return (t * t * t) * (t * (t * static_cast<T>(6) - static_cast<T>(15)) + static_cast<T>(10));
78+ }
79+}//namespace detail
80+}//namespace glm
81+
@@ -0,0 +1,809 @@
1+#pragma once
2+
3+namespace glm{
4+namespace detail
5+{
6+ // Internal class for implementing swizzle operators
7+ template<typename T, int N>
8+ struct _swizzle_base0
9+ {
10+ protected:
11+ GLM_FUNC_QUALIFIER T& elem(int i){ return (reinterpret_cast<T*>(_buffer))[i]; }
12+ GLM_FUNC_QUALIFIER T const& elem(int i) const{ return (reinterpret_cast<const T*>(_buffer))[i]; }
13+
14+ // Use an opaque buffer to *ensure* the compiler doesn't call a constructor.
15+ // The size 1 buffer is assumed to aligned to the actual members so that the
16+ // elem()
17+ char _buffer[1];
18+ };
19+
20+ template<length_t N, typename T, qualifier Q, int E0, int E1, int E2, int E3, bool UseSimd>
21+ struct _swizzle_base1 : public _swizzle_base0<T, N>
22+ {
23+ };
24+
25+ template<length_t N, typename T, qualifier Q, int E0, int E1, int E2, int E3>
26+ struct _swizzle_base1<N, T, Q, E0, E1, E2, E3, false> : public _swizzle_base0<T, N>
27+ {
28+ };
29+
30+ template<typename T, qualifier Q, int E0, int E1>
31+ struct _swizzle_base1<2, T, Q, E0,E1,-1,-2, false> : public _swizzle_base0<T, 2>
32+ {
33+ GLM_FUNC_QUALIFIER vec<2, T, Q> operator ()() const { return vec<2, T, Q>(this->elem(E0), this->elem(E1)); }
34+ };
35+
36+ template<typename T, qualifier Q, int E0, int E1, int E2>
37+ struct _swizzle_base1<3, T, Q, E0,E1,E2,3, false> : public _swizzle_base0<T, 3>
38+ {
39+ GLM_FUNC_QUALIFIER vec<3, T, Q> operator ()() const { return vec<3, T, Q>(this->elem(E0), this->elem(E1), this->elem(E2)); }
40+ };
41+
42+ template<typename T, qualifier Q, int E0, int E1, int E2, int E3>
43+ struct _swizzle_base1<4, T, Q, E0,E1,E2,E3, false> : public _swizzle_base0<T, 4>
44+ {
45+ GLM_FUNC_QUALIFIER vec<4, T, Q> operator ()() const { return vec<4, T, Q>(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); }
46+ };
47+
48+ // Internal class for implementing swizzle operators
49+ /*
50+ Template parameters:
51+
52+ T = type of scalar values (e.g. float, double)
53+ N = number of components in the vector (e.g. 3)
54+ E0...3 = what index the n-th element of this swizzle refers to in the unswizzled vec
55+
56+ DUPLICATE_ELEMENTS = 1 if there is a repeated element, 0 otherwise (used to specialize swizzles
57+ containing duplicate elements so that they cannot be used as r-values).
58+ */
59+ template<length_t N, typename T, qualifier Q, int E0, int E1, int E2, int E3, int DUPLICATE_ELEMENTS>
60+ struct _swizzle_base2 : public _swizzle_base1<N, T, Q, E0,E1,E2,E3, detail::is_aligned<Q>::value>
61+ {
62+ struct op_equal
63+ {
64+ GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e = t; }
65+ };
66+
67+ struct op_minus
68+ {
69+ GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e -= t; }
70+ };
71+
72+ struct op_plus
73+ {
74+ GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e += t; }
75+ };
76+
77+ struct op_mul
78+ {
79+ GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e *= t; }
80+ };
81+
82+ struct op_div
83+ {
84+ GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e /= t; }
85+ };
86+
87+ public:
88+ GLM_FUNC_QUALIFIER _swizzle_base2& operator= (const T& t)
89+ {
90+ for (int i = 0; i < N; ++i)
91+ (*this)[i] = t;
92+ return *this;
93+ }
94+
95+ GLM_FUNC_QUALIFIER _swizzle_base2& operator= (vec<N, T, Q> const& that)
96+ {
97+ _apply_op(that, op_equal());
98+ return *this;
99+ }
100+
101+ GLM_FUNC_QUALIFIER void operator -= (vec<N, T, Q> const& that)
102+ {
103+ _apply_op(that, op_minus());
104+ }
105+
106+ GLM_FUNC_QUALIFIER void operator += (vec<N, T, Q> const& that)
107+ {
108+ _apply_op(that, op_plus());
109+ }
110+
111+ GLM_FUNC_QUALIFIER void operator *= (vec<N, T, Q> const& that)
112+ {
113+ _apply_op(that, op_mul());
114+ }
115+
116+ GLM_FUNC_QUALIFIER void operator /= (vec<N, T, Q> const& that)
117+ {
118+ _apply_op(that, op_div());
119+ }
120+
121+ GLM_FUNC_QUALIFIER T& operator[](int i)
122+ {
123+ const int offset_dst[4] = { E0, E1, E2, E3 };
124+ return this->elem(offset_dst[i]);
125+ }
126+ GLM_FUNC_QUALIFIER T operator[](int i) const
127+ {
128+ const int offset_dst[4] = { E0, E1, E2, E3 };
129+ return this->elem(offset_dst[i]);
130+ }
131+
132+ protected:
133+ template<typename U>
134+ GLM_FUNC_QUALIFIER void _apply_op(vec<N, T, Q> const& that, const U& op)
135+ {
136+ // Make a copy of the data in this == &that.
137+ // The copier should optimize out the copy in cases where the function is
138+ // properly inlined and the copy is not necessary.
139+ T t[N];
140+ for (int i = 0; i < N; ++i)
141+ t[i] = that[i];
142+ for (int i = 0; i < N; ++i)
143+ op( (*this)[i], t[i] );
144+ }
145+ };
146+
147+ // Specialization for swizzles containing duplicate elements. These cannot be modified.
148+ template<length_t N, typename T, qualifier Q, int E0, int E1, int E2, int E3>
149+ struct _swizzle_base2<N, T, Q, E0,E1,E2,E3, 1> : public _swizzle_base1<N, T, Q, E0,E1,E2,E3, detail::is_aligned<Q>::value>
150+ {
151+ struct Stub {};
152+
153+ GLM_FUNC_QUALIFIER _swizzle_base2& operator= (Stub const&) { return *this; }
154+
155+ GLM_FUNC_QUALIFIER T operator[] (int i) const
156+ {
157+ const int offset_dst[4] = { E0, E1, E2, E3 };
158+ return this->elem(offset_dst[i]);
159+ }
160+ };
161+
162+ template<length_t N, typename T, qualifier Q, int E0, int E1, int E2, int E3>
163+ struct _swizzle : public _swizzle_base2<N, T, Q, E0, E1, E2, E3, (E0 == E1 || E0 == E2 || E0 == E3 || E1 == E2 || E1 == E3 || E2 == E3)>
164+ {
165+ typedef _swizzle_base2<N, T, Q, E0, E1, E2, E3, (E0 == E1 || E0 == E2 || E0 == E3 || E1 == E2 || E1 == E3 || E2 == E3)> base_type;
166+
167+ using base_type::operator=;
168+
169+ GLM_FUNC_QUALIFIER operator vec<N, T, Q> () const { return (*this)(); }
170+ };
171+
172+//
173+// To prevent the C++ syntax from getting entirely overwhelming, define some alias macros
174+//
175+#define GLM_SWIZZLE_TEMPLATE1 template<length_t N, typename T, qualifier Q, int E0, int E1, int E2, int E3>
176+#define GLM_SWIZZLE_TEMPLATE2 template<length_t N, typename T, qualifier Q, int E0, int E1, int E2, int E3, int F0, int F1, int F2, int F3>
177+#define GLM_SWIZZLE_TYPE1 _swizzle<N, T, Q, E0, E1, E2, E3>
178+#define GLM_SWIZZLE_TYPE2 _swizzle<N, T, Q, F0, F1, F2, F3>
179+
180+//
181+// Wrapper for a binary operator (e.g. u.yy + v.zy)
182+//
183+#define GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND) \
184+ GLM_SWIZZLE_TEMPLATE2 \
185+ GLM_FUNC_QUALIFIER vec<N, T, Q> operator OPERAND ( const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE2& b) \
186+ { \
187+ return a() OPERAND b(); \
188+ } \
189+ GLM_SWIZZLE_TEMPLATE1 \
190+ GLM_FUNC_QUALIFIER vec<N, T, Q> operator OPERAND ( const GLM_SWIZZLE_TYPE1& a, const vec<N, T, Q>& b) \
191+ { \
192+ return a() OPERAND b; \
193+ } \
194+ GLM_SWIZZLE_TEMPLATE1 \
195+ GLM_FUNC_QUALIFIER vec<N, T, Q> operator OPERAND ( const vec<N, T, Q>& a, const GLM_SWIZZLE_TYPE1& b) \
196+ { \
197+ return a OPERAND b(); \
198+ }
199+
200+//
201+// Wrapper for a operand between a swizzle and a binary (e.g. 1.0f - u.xyz)
202+//
203+#define GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND) \
204+ GLM_SWIZZLE_TEMPLATE1 \
205+ GLM_FUNC_QUALIFIER vec<N, T, Q> operator OPERAND ( const GLM_SWIZZLE_TYPE1& a, const T& b) \
206+ { \
207+ return a() OPERAND b; \
208+ } \
209+ GLM_SWIZZLE_TEMPLATE1 \
210+ GLM_FUNC_QUALIFIER vec<N, T, Q> operator OPERAND ( const T& a, const GLM_SWIZZLE_TYPE1& b) \
211+ { \
212+ return a OPERAND b(); \
213+ }
214+
215+//
216+// Macro for wrapping a function taking one argument (e.g. abs())
217+//
218+#define GLM_SWIZZLE_FUNCTION_1_ARGS(RETURN_TYPE,FUNCTION) \
219+ GLM_SWIZZLE_TEMPLATE1 \
220+ GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a) \
221+ { \
222+ return FUNCTION(a()); \
223+ }
224+
225+//
226+// Macro for wrapping a function taking two vector arguments (e.g. dot()).
227+//
228+#define GLM_SWIZZLE_FUNCTION_2_ARGS(RETURN_TYPE,FUNCTION) \
229+ GLM_SWIZZLE_TEMPLATE2 \
230+ GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE2& b) \
231+ { \
232+ return FUNCTION(a(), b()); \
233+ } \
234+ GLM_SWIZZLE_TEMPLATE1 \
235+ GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE1& b) \
236+ { \
237+ return FUNCTION(a(), b()); \
238+ } \
239+ GLM_SWIZZLE_TEMPLATE1 \
240+ GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const typename V& b) \
241+ { \
242+ return FUNCTION(a(), b); \
243+ } \
244+ GLM_SWIZZLE_TEMPLATE1 \
245+ GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const V& a, const GLM_SWIZZLE_TYPE1& b) \
246+ { \
247+ return FUNCTION(a, b()); \
248+ }
249+
250+//
251+// Macro for wrapping a function take 2 vec arguments followed by a scalar (e.g. mix()).
252+//
253+#define GLM_SWIZZLE_FUNCTION_2_ARGS_SCALAR(RETURN_TYPE,FUNCTION) \
254+ GLM_SWIZZLE_TEMPLATE2 \
255+ GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE2& b, const T& c) \
256+ { \
257+ return FUNCTION(a(), b(), c); \
258+ } \
259+ GLM_SWIZZLE_TEMPLATE1 \
260+ GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE1& b, const T& c) \
261+ { \
262+ return FUNCTION(a(), b(), c); \
263+ } \
264+ GLM_SWIZZLE_TEMPLATE1 \
265+ GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const typename S0::vec_type& b, const T& c)\
266+ { \
267+ return FUNCTION(a(), b, c); \
268+ } \
269+ GLM_SWIZZLE_TEMPLATE1 \
270+ GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const typename V& a, const GLM_SWIZZLE_TYPE1& b, const T& c) \
271+ { \
272+ return FUNCTION(a, b(), c); \
273+ }
274+
275+}//namespace detail
276+}//namespace glm
277+
278+namespace glm
279+{
280+ namespace detail
281+ {
282+ GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(-)
283+ GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(*)
284+ GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(+)
285+ GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(-)
286+ GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(*)
287+ GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(/)
288+ }
289+
290+ //
291+ // Swizzles are distinct types from the unswizzled type. The below macros will
292+ // provide template specializations for the swizzle types for the given functions
293+ // so that the compiler does not have any ambiguity to choosing how to handle
294+ // the function.
295+ //
296+ // The alternative is to use the operator()() when calling the function in order
297+ // to explicitly convert the swizzled type to the unswizzled type.
298+ //
299+
300+ //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, abs);
301+ //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, acos);
302+ //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, acosh);
303+ //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, all);
304+ //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, any);
305+
306+ //GLM_SWIZZLE_FUNCTION_2_ARGS(value_type, dot);
307+ //GLM_SWIZZLE_FUNCTION_2_ARGS(vec_type, cross);
308+ //GLM_SWIZZLE_FUNCTION_2_ARGS(vec_type, step);
309+ //GLM_SWIZZLE_FUNCTION_2_ARGS_SCALAR(vec_type, mix);
310+}
311+
312+#define GLM_SWIZZLE2_2_MEMBERS(T, Q, E0,E1) \
313+ struct { detail::_swizzle<2, T, Q, 0,0,-1,-2> E0 ## E0; }; \
314+ struct { detail::_swizzle<2, T, Q, 0,1,-1,-2> E0 ## E1; }; \
315+ struct { detail::_swizzle<2, T, Q, 1,0,-1,-2> E1 ## E0; }; \
316+ struct { detail::_swizzle<2, T, Q, 1,1,-1,-2> E1 ## E1; };
317+
318+#define GLM_SWIZZLE2_3_MEMBERS(T, Q, E0,E1) \
319+ struct { detail::_swizzle<3,T, Q, 0,0,0,-1> E0 ## E0 ## E0; }; \
320+ struct { detail::_swizzle<3,T, Q, 0,0,1,-1> E0 ## E0 ## E1; }; \
321+ struct { detail::_swizzle<3,T, Q, 0,1,0,-1> E0 ## E1 ## E0; }; \
322+ struct { detail::_swizzle<3,T, Q, 0,1,1,-1> E0 ## E1 ## E1; }; \
323+ struct { detail::_swizzle<3,T, Q, 1,0,0,-1> E1 ## E0 ## E0; }; \
324+ struct { detail::_swizzle<3,T, Q, 1,0,1,-1> E1 ## E0 ## E1; }; \
325+ struct { detail::_swizzle<3,T, Q, 1,1,0,-1> E1 ## E1 ## E0; }; \
326+ struct { detail::_swizzle<3,T, Q, 1,1,1,-1> E1 ## E1 ## E1; };
327+
328+#define GLM_SWIZZLE2_4_MEMBERS(T, Q, E0,E1) \
329+ struct { detail::_swizzle<4,T, Q, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \
330+ struct { detail::_swizzle<4,T, Q, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \
331+ struct { detail::_swizzle<4,T, Q, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \
332+ struct { detail::_swizzle<4,T, Q, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \
333+ struct { detail::_swizzle<4,T, Q, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \
334+ struct { detail::_swizzle<4,T, Q, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \
335+ struct { detail::_swizzle<4,T, Q, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \
336+ struct { detail::_swizzle<4,T, Q, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \
337+ struct { detail::_swizzle<4,T, Q, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \
338+ struct { detail::_swizzle<4,T, Q, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \
339+ struct { detail::_swizzle<4,T, Q, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \
340+ struct { detail::_swizzle<4,T, Q, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \
341+ struct { detail::_swizzle<4,T, Q, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \
342+ struct { detail::_swizzle<4,T, Q, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \
343+ struct { detail::_swizzle<4,T, Q, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \
344+ struct { detail::_swizzle<4,T, Q, 1,1,1,1> E1 ## E1 ## E1 ## E1; };
345+
346+#define GLM_SWIZZLE3_2_MEMBERS(T, Q, E0,E1,E2) \
347+ struct { detail::_swizzle<2,T, Q, 0,0,-1,-2> E0 ## E0; }; \
348+ struct { detail::_swizzle<2,T, Q, 0,1,-1,-2> E0 ## E1; }; \
349+ struct { detail::_swizzle<2,T, Q, 0,2,-1,-2> E0 ## E2; }; \
350+ struct { detail::_swizzle<2,T, Q, 1,0,-1,-2> E1 ## E0; }; \
351+ struct { detail::_swizzle<2,T, Q, 1,1,-1,-2> E1 ## E1; }; \
352+ struct { detail::_swizzle<2,T, Q, 1,2,-1,-2> E1 ## E2; }; \
353+ struct { detail::_swizzle<2,T, Q, 2,0,-1,-2> E2 ## E0; }; \
354+ struct { detail::_swizzle<2,T, Q, 2,1,-1,-2> E2 ## E1; }; \
355+ struct { detail::_swizzle<2,T, Q, 2,2,-1,-2> E2 ## E2; };
356+
357+#define GLM_SWIZZLE3_3_MEMBERS(T, Q ,E0,E1,E2) \
358+ struct { detail::_swizzle<3, T, Q, 0,0,0,3> E0 ## E0 ## E0; }; \
359+ struct { detail::_swizzle<3, T, Q, 0,0,1,3> E0 ## E0 ## E1; }; \
360+ struct { detail::_swizzle<3, T, Q, 0,0,2,3> E0 ## E0 ## E2; }; \
361+ struct { detail::_swizzle<3, T, Q, 0,1,0,3> E0 ## E1 ## E0; }; \
362+ struct { detail::_swizzle<3, T, Q, 0,1,1,3> E0 ## E1 ## E1; }; \
363+ struct { detail::_swizzle<3, T, Q, 0,1,2,3> E0 ## E1 ## E2; }; \
364+ struct { detail::_swizzle<3, T, Q, 0,2,0,3> E0 ## E2 ## E0; }; \
365+ struct { detail::_swizzle<3, T, Q, 0,2,1,3> E0 ## E2 ## E1; }; \
366+ struct { detail::_swizzle<3, T, Q, 0,2,2,3> E0 ## E2 ## E2; }; \
367+ struct { detail::_swizzle<3, T, Q, 1,0,0,3> E1 ## E0 ## E0; }; \
368+ struct { detail::_swizzle<3, T, Q, 1,0,1,3> E1 ## E0 ## E1; }; \
369+ struct { detail::_swizzle<3, T, Q, 1,0,2,3> E1 ## E0 ## E2; }; \
370+ struct { detail::_swizzle<3, T, Q, 1,1,0,3> E1 ## E1 ## E0; }; \
371+ struct { detail::_swizzle<3, T, Q, 1,1,1,3> E1 ## E1 ## E1; }; \
372+ struct { detail::_swizzle<3, T, Q, 1,1,2,3> E1 ## E1 ## E2; }; \
373+ struct { detail::_swizzle<3, T, Q, 1,2,0,3> E1 ## E2 ## E0; }; \
374+ struct { detail::_swizzle<3, T, Q, 1,2,1,3> E1 ## E2 ## E1; }; \
375+ struct { detail::_swizzle<3, T, Q, 1,2,2,3> E1 ## E2 ## E2; }; \
376+ struct { detail::_swizzle<3, T, Q, 2,0,0,3> E2 ## E0 ## E0; }; \
377+ struct { detail::_swizzle<3, T, Q, 2,0,1,3> E2 ## E0 ## E1; }; \
378+ struct { detail::_swizzle<3, T, Q, 2,0,2,3> E2 ## E0 ## E2; }; \
379+ struct { detail::_swizzle<3, T, Q, 2,1,0,3> E2 ## E1 ## E0; }; \
380+ struct { detail::_swizzle<3, T, Q, 2,1,1,3> E2 ## E1 ## E1; }; \
381+ struct { detail::_swizzle<3, T, Q, 2,1,2,3> E2 ## E1 ## E2; }; \
382+ struct { detail::_swizzle<3, T, Q, 2,2,0,3> E2 ## E2 ## E0; }; \
383+ struct { detail::_swizzle<3, T, Q, 2,2,1,3> E2 ## E2 ## E1; }; \
384+ struct { detail::_swizzle<3, T, Q, 2,2,2,3> E2 ## E2 ## E2; };
385+
386+#define GLM_SWIZZLE3_4_MEMBERS(T, Q, E0,E1,E2) \
387+ struct { detail::_swizzle<4,T, Q, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \
388+ struct { detail::_swizzle<4,T, Q, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \
389+ struct { detail::_swizzle<4,T, Q, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \
390+ struct { detail::_swizzle<4,T, Q, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \
391+ struct { detail::_swizzle<4,T, Q, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \
392+ struct { detail::_swizzle<4,T, Q, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \
393+ struct { detail::_swizzle<4,T, Q, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \
394+ struct { detail::_swizzle<4,T, Q, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \
395+ struct { detail::_swizzle<4,T, Q, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \
396+ struct { detail::_swizzle<4,T, Q, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \
397+ struct { detail::_swizzle<4,T, Q, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \
398+ struct { detail::_swizzle<4,T, Q, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \
399+ struct { detail::_swizzle<4,T, Q, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \
400+ struct { detail::_swizzle<4,T, Q, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \
401+ struct { detail::_swizzle<4,T, Q, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \
402+ struct { detail::_swizzle<4,T, Q, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \
403+ struct { detail::_swizzle<4,T, Q, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \
404+ struct { detail::_swizzle<4,T, Q, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \
405+ struct { detail::_swizzle<4,T, Q, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \
406+ struct { detail::_swizzle<4,T, Q, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \
407+ struct { detail::_swizzle<4,T, Q, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \
408+ struct { detail::_swizzle<4,T, Q, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \
409+ struct { detail::_swizzle<4,T, Q, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \
410+ struct { detail::_swizzle<4,T, Q, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \
411+ struct { detail::_swizzle<4,T, Q, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \
412+ struct { detail::_swizzle<4,T, Q, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \
413+ struct { detail::_swizzle<4,T, Q, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \
414+ struct { detail::_swizzle<4,T, Q, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \
415+ struct { detail::_swizzle<4,T, Q, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \
416+ struct { detail::_swizzle<4,T, Q, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \
417+ struct { detail::_swizzle<4,T, Q, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \
418+ struct { detail::_swizzle<4,T, Q, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \
419+ struct { detail::_swizzle<4,T, Q, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \
420+ struct { detail::_swizzle<4,T, Q, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \
421+ struct { detail::_swizzle<4,T, Q, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \
422+ struct { detail::_swizzle<4,T, Q, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \
423+ struct { detail::_swizzle<4,T, Q, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \
424+ struct { detail::_swizzle<4,T, Q, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \
425+ struct { detail::_swizzle<4,T, Q, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \
426+ struct { detail::_swizzle<4,T, Q, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \
427+ struct { detail::_swizzle<4,T, Q, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \
428+ struct { detail::_swizzle<4,T, Q, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \
429+ struct { detail::_swizzle<4,T, Q, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \
430+ struct { detail::_swizzle<4,T, Q, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \
431+ struct { detail::_swizzle<4,T, Q, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \
432+ struct { detail::_swizzle<4,T, Q, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \
433+ struct { detail::_swizzle<4,T, Q, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \
434+ struct { detail::_swizzle<4,T, Q, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \
435+ struct { detail::_swizzle<4,T, Q, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \
436+ struct { detail::_swizzle<4,T, Q, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \
437+ struct { detail::_swizzle<4,T, Q, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \
438+ struct { detail::_swizzle<4,T, Q, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \
439+ struct { detail::_swizzle<4,T, Q, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \
440+ struct { detail::_swizzle<4,T, Q, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \
441+ struct { detail::_swizzle<4,T, Q, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \
442+ struct { detail::_swizzle<4,T, Q, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \
443+ struct { detail::_swizzle<4,T, Q, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \
444+ struct { detail::_swizzle<4,T, Q, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \
445+ struct { detail::_swizzle<4,T, Q, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \
446+ struct { detail::_swizzle<4,T, Q, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \
447+ struct { detail::_swizzle<4,T, Q, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \
448+ struct { detail::_swizzle<4,T, Q, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \
449+ struct { detail::_swizzle<4,T, Q, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \
450+ struct { detail::_swizzle<4,T, Q, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \
451+ struct { detail::_swizzle<4,T, Q, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \
452+ struct { detail::_swizzle<4,T, Q, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \
453+ struct { detail::_swizzle<4,T, Q, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \
454+ struct { detail::_swizzle<4,T, Q, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \
455+ struct { detail::_swizzle<4,T, Q, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \
456+ struct { detail::_swizzle<4,T, Q, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \
457+ struct { detail::_swizzle<4,T, Q, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \
458+ struct { detail::_swizzle<4,T, Q, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \
459+ struct { detail::_swizzle<4,T, Q, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \
460+ struct { detail::_swizzle<4,T, Q, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \
461+ struct { detail::_swizzle<4,T, Q, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \
462+ struct { detail::_swizzle<4,T, Q, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \
463+ struct { detail::_swizzle<4,T, Q, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \
464+ struct { detail::_swizzle<4,T, Q, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \
465+ struct { detail::_swizzle<4,T, Q, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \
466+ struct { detail::_swizzle<4,T, Q, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \
467+ struct { detail::_swizzle<4,T, Q, 2,2,2,2> E2 ## E2 ## E2 ## E2; };
468+
469+#define GLM_SWIZZLE4_2_MEMBERS(T, Q, E0,E1,E2,E3) \
470+ struct { detail::_swizzle<2,T, Q, 0,0,-1,-2> E0 ## E0; }; \
471+ struct { detail::_swizzle<2,T, Q, 0,1,-1,-2> E0 ## E1; }; \
472+ struct { detail::_swizzle<2,T, Q, 0,2,-1,-2> E0 ## E2; }; \
473+ struct { detail::_swizzle<2,T, Q, 0,3,-1,-2> E0 ## E3; }; \
474+ struct { detail::_swizzle<2,T, Q, 1,0,-1,-2> E1 ## E0; }; \
475+ struct { detail::_swizzle<2,T, Q, 1,1,-1,-2> E1 ## E1; }; \
476+ struct { detail::_swizzle<2,T, Q, 1,2,-1,-2> E1 ## E2; }; \
477+ struct { detail::_swizzle<2,T, Q, 1,3,-1,-2> E1 ## E3; }; \
478+ struct { detail::_swizzle<2,T, Q, 2,0,-1,-2> E2 ## E0; }; \
479+ struct { detail::_swizzle<2,T, Q, 2,1,-1,-2> E2 ## E1; }; \
480+ struct { detail::_swizzle<2,T, Q, 2,2,-1,-2> E2 ## E2; }; \
481+ struct { detail::_swizzle<2,T, Q, 2,3,-1,-2> E2 ## E3; }; \
482+ struct { detail::_swizzle<2,T, Q, 3,0,-1,-2> E3 ## E0; }; \
483+ struct { detail::_swizzle<2,T, Q, 3,1,-1,-2> E3 ## E1; }; \
484+ struct { detail::_swizzle<2,T, Q, 3,2,-1,-2> E3 ## E2; }; \
485+ struct { detail::_swizzle<2,T, Q, 3,3,-1,-2> E3 ## E3; };
486+
487+#define GLM_SWIZZLE4_3_MEMBERS(T, Q, E0,E1,E2,E3) \
488+ struct { detail::_swizzle<3, T, Q, 0,0,0,3> E0 ## E0 ## E0; }; \
489+ struct { detail::_swizzle<3, T, Q, 0,0,1,3> E0 ## E0 ## E1; }; \
490+ struct { detail::_swizzle<3, T, Q, 0,0,2,3> E0 ## E0 ## E2; }; \
491+ struct { detail::_swizzle<3, T, Q, 0,0,3,3> E0 ## E0 ## E3; }; \
492+ struct { detail::_swizzle<3, T, Q, 0,1,0,3> E0 ## E1 ## E0; }; \
493+ struct { detail::_swizzle<3, T, Q, 0,1,1,3> E0 ## E1 ## E1; }; \
494+ struct { detail::_swizzle<3, T, Q, 0,1,2,3> E0 ## E1 ## E2; }; \
495+ struct { detail::_swizzle<3, T, Q, 0,1,3,3> E0 ## E1 ## E3; }; \
496+ struct { detail::_swizzle<3, T, Q, 0,2,0,3> E0 ## E2 ## E0; }; \
497+ struct { detail::_swizzle<3, T, Q, 0,2,1,3> E0 ## E2 ## E1; }; \
498+ struct { detail::_swizzle<3, T, Q, 0,2,2,3> E0 ## E2 ## E2; }; \
499+ struct { detail::_swizzle<3, T, Q, 0,2,3,3> E0 ## E2 ## E3; }; \
500+ struct { detail::_swizzle<3, T, Q, 0,3,0,3> E0 ## E3 ## E0; }; \
501+ struct { detail::_swizzle<3, T, Q, 0,3,1,3> E0 ## E3 ## E1; }; \
502+ struct { detail::_swizzle<3, T, Q, 0,3,2,3> E0 ## E3 ## E2; }; \
503+ struct { detail::_swizzle<3, T, Q, 0,3,3,3> E0 ## E3 ## E3; }; \
504+ struct { detail::_swizzle<3, T, Q, 1,0,0,3> E1 ## E0 ## E0; }; \
505+ struct { detail::_swizzle<3, T, Q, 1,0,1,3> E1 ## E0 ## E1; }; \
506+ struct { detail::_swizzle<3, T, Q, 1,0,2,3> E1 ## E0 ## E2; }; \
507+ struct { detail::_swizzle<3, T, Q, 1,0,3,3> E1 ## E0 ## E3; }; \
508+ struct { detail::_swizzle<3, T, Q, 1,1,0,3> E1 ## E1 ## E0; }; \
509+ struct { detail::_swizzle<3, T, Q, 1,1,1,3> E1 ## E1 ## E1; }; \
510+ struct { detail::_swizzle<3, T, Q, 1,1,2,3> E1 ## E1 ## E2; }; \
511+ struct { detail::_swizzle<3, T, Q, 1,1,3,3> E1 ## E1 ## E3; }; \
512+ struct { detail::_swizzle<3, T, Q, 1,2,0,3> E1 ## E2 ## E0; }; \
513+ struct { detail::_swizzle<3, T, Q, 1,2,1,3> E1 ## E2 ## E1; }; \
514+ struct { detail::_swizzle<3, T, Q, 1,2,2,3> E1 ## E2 ## E2; }; \
515+ struct { detail::_swizzle<3, T, Q, 1,2,3,3> E1 ## E2 ## E3; }; \
516+ struct { detail::_swizzle<3, T, Q, 1,3,0,3> E1 ## E3 ## E0; }; \
517+ struct { detail::_swizzle<3, T, Q, 1,3,1,3> E1 ## E3 ## E1; }; \
518+ struct { detail::_swizzle<3, T, Q, 1,3,2,3> E1 ## E3 ## E2; }; \
519+ struct { detail::_swizzle<3, T, Q, 1,3,3,3> E1 ## E3 ## E3; }; \
520+ struct { detail::_swizzle<3, T, Q, 2,0,0,3> E2 ## E0 ## E0; }; \
521+ struct { detail::_swizzle<3, T, Q, 2,0,1,3> E2 ## E0 ## E1; }; \
522+ struct { detail::_swizzle<3, T, Q, 2,0,2,3> E2 ## E0 ## E2; }; \
523+ struct { detail::_swizzle<3, T, Q, 2,0,3,3> E2 ## E0 ## E3; }; \
524+ struct { detail::_swizzle<3, T, Q, 2,1,0,3> E2 ## E1 ## E0; }; \
525+ struct { detail::_swizzle<3, T, Q, 2,1,1,3> E2 ## E1 ## E1; }; \
526+ struct { detail::_swizzle<3, T, Q, 2,1,2,3> E2 ## E1 ## E2; }; \
527+ struct { detail::_swizzle<3, T, Q, 2,1,3,3> E2 ## E1 ## E3; }; \
528+ struct { detail::_swizzle<3, T, Q, 2,2,0,3> E2 ## E2 ## E0; }; \
529+ struct { detail::_swizzle<3, T, Q, 2,2,1,3> E2 ## E2 ## E1; }; \
530+ struct { detail::_swizzle<3, T, Q, 2,2,2,3> E2 ## E2 ## E2; }; \
531+ struct { detail::_swizzle<3, T, Q, 2,2,3,3> E2 ## E2 ## E3; }; \
532+ struct { detail::_swizzle<3, T, Q, 2,3,0,3> E2 ## E3 ## E0; }; \
533+ struct { detail::_swizzle<3, T, Q, 2,3,1,3> E2 ## E3 ## E1; }; \
534+ struct { detail::_swizzle<3, T, Q, 2,3,2,3> E2 ## E3 ## E2; }; \
535+ struct { detail::_swizzle<3, T, Q, 2,3,3,3> E2 ## E3 ## E3; }; \
536+ struct { detail::_swizzle<3, T, Q, 3,0,0,3> E3 ## E0 ## E0; }; \
537+ struct { detail::_swizzle<3, T, Q, 3,0,1,3> E3 ## E0 ## E1; }; \
538+ struct { detail::_swizzle<3, T, Q, 3,0,2,3> E3 ## E0 ## E2; }; \
539+ struct { detail::_swizzle<3, T, Q, 3,0,3,3> E3 ## E0 ## E3; }; \
540+ struct { detail::_swizzle<3, T, Q, 3,1,0,3> E3 ## E1 ## E0; }; \
541+ struct { detail::_swizzle<3, T, Q, 3,1,1,3> E3 ## E1 ## E1; }; \
542+ struct { detail::_swizzle<3, T, Q, 3,1,2,3> E3 ## E1 ## E2; }; \
543+ struct { detail::_swizzle<3, T, Q, 3,1,3,3> E3 ## E1 ## E3; }; \
544+ struct { detail::_swizzle<3, T, Q, 3,2,0,3> E3 ## E2 ## E0; }; \
545+ struct { detail::_swizzle<3, T, Q, 3,2,1,3> E3 ## E2 ## E1; }; \
546+ struct { detail::_swizzle<3, T, Q, 3,2,2,3> E3 ## E2 ## E2; }; \
547+ struct { detail::_swizzle<3, T, Q, 3,2,3,3> E3 ## E2 ## E3; }; \
548+ struct { detail::_swizzle<3, T, Q, 3,3,0,3> E3 ## E3 ## E0; }; \
549+ struct { detail::_swizzle<3, T, Q, 3,3,1,3> E3 ## E3 ## E1; }; \
550+ struct { detail::_swizzle<3, T, Q, 3,3,2,3> E3 ## E3 ## E2; }; \
551+ struct { detail::_swizzle<3, T, Q, 3,3,3,3> E3 ## E3 ## E3; };
552+
553+#define GLM_SWIZZLE4_4_MEMBERS(T, Q, E0,E1,E2,E3) \
554+ struct { detail::_swizzle<4, T, Q, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \
555+ struct { detail::_swizzle<4, T, Q, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \
556+ struct { detail::_swizzle<4, T, Q, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \
557+ struct { detail::_swizzle<4, T, Q, 0,0,0,3> E0 ## E0 ## E0 ## E3; }; \
558+ struct { detail::_swizzle<4, T, Q, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \
559+ struct { detail::_swizzle<4, T, Q, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \
560+ struct { detail::_swizzle<4, T, Q, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \
561+ struct { detail::_swizzle<4, T, Q, 0,0,1,3> E0 ## E0 ## E1 ## E3; }; \
562+ struct { detail::_swizzle<4, T, Q, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \
563+ struct { detail::_swizzle<4, T, Q, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \
564+ struct { detail::_swizzle<4, T, Q, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \
565+ struct { detail::_swizzle<4, T, Q, 0,0,2,3> E0 ## E0 ## E2 ## E3; }; \
566+ struct { detail::_swizzle<4, T, Q, 0,0,3,0> E0 ## E0 ## E3 ## E0; }; \
567+ struct { detail::_swizzle<4, T, Q, 0,0,3,1> E0 ## E0 ## E3 ## E1; }; \
568+ struct { detail::_swizzle<4, T, Q, 0,0,3,2> E0 ## E0 ## E3 ## E2; }; \
569+ struct { detail::_swizzle<4, T, Q, 0,0,3,3> E0 ## E0 ## E3 ## E3; }; \
570+ struct { detail::_swizzle<4, T, Q, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \
571+ struct { detail::_swizzle<4, T, Q, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \
572+ struct { detail::_swizzle<4, T, Q, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \
573+ struct { detail::_swizzle<4, T, Q, 0,1,0,3> E0 ## E1 ## E0 ## E3; }; \
574+ struct { detail::_swizzle<4, T, Q, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \
575+ struct { detail::_swizzle<4, T, Q, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \
576+ struct { detail::_swizzle<4, T, Q, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \
577+ struct { detail::_swizzle<4, T, Q, 0,1,1,3> E0 ## E1 ## E1 ## E3; }; \
578+ struct { detail::_swizzle<4, T, Q, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \
579+ struct { detail::_swizzle<4, T, Q, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \
580+ struct { detail::_swizzle<4, T, Q, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \
581+ struct { detail::_swizzle<4, T, Q, 0,1,2,3> E0 ## E1 ## E2 ## E3; }; \
582+ struct { detail::_swizzle<4, T, Q, 0,1,3,0> E0 ## E1 ## E3 ## E0; }; \
583+ struct { detail::_swizzle<4, T, Q, 0,1,3,1> E0 ## E1 ## E3 ## E1; }; \
584+ struct { detail::_swizzle<4, T, Q, 0,1,3,2> E0 ## E1 ## E3 ## E2; }; \
585+ struct { detail::_swizzle<4, T, Q, 0,1,3,3> E0 ## E1 ## E3 ## E3; }; \
586+ struct { detail::_swizzle<4, T, Q, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \
587+ struct { detail::_swizzle<4, T, Q, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \
588+ struct { detail::_swizzle<4, T, Q, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \
589+ struct { detail::_swizzle<4, T, Q, 0,2,0,3> E0 ## E2 ## E0 ## E3; }; \
590+ struct { detail::_swizzle<4, T, Q, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \
591+ struct { detail::_swizzle<4, T, Q, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \
592+ struct { detail::_swizzle<4, T, Q, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \
593+ struct { detail::_swizzle<4, T, Q, 0,2,1,3> E0 ## E2 ## E1 ## E3; }; \
594+ struct { detail::_swizzle<4, T, Q, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \
595+ struct { detail::_swizzle<4, T, Q, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \
596+ struct { detail::_swizzle<4, T, Q, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \
597+ struct { detail::_swizzle<4, T, Q, 0,2,2,3> E0 ## E2 ## E2 ## E3; }; \
598+ struct { detail::_swizzle<4, T, Q, 0,2,3,0> E0 ## E2 ## E3 ## E0; }; \
599+ struct { detail::_swizzle<4, T, Q, 0,2,3,1> E0 ## E2 ## E3 ## E1; }; \
600+ struct { detail::_swizzle<4, T, Q, 0,2,3,2> E0 ## E2 ## E3 ## E2; }; \
601+ struct { detail::_swizzle<4, T, Q, 0,2,3,3> E0 ## E2 ## E3 ## E3; }; \
602+ struct { detail::_swizzle<4, T, Q, 0,3,0,0> E0 ## E3 ## E0 ## E0; }; \
603+ struct { detail::_swizzle<4, T, Q, 0,3,0,1> E0 ## E3 ## E0 ## E1; }; \
604+ struct { detail::_swizzle<4, T, Q, 0,3,0,2> E0 ## E3 ## E0 ## E2; }; \
605+ struct { detail::_swizzle<4, T, Q, 0,3,0,3> E0 ## E3 ## E0 ## E3; }; \
606+ struct { detail::_swizzle<4, T, Q, 0,3,1,0> E0 ## E3 ## E1 ## E0; }; \
607+ struct { detail::_swizzle<4, T, Q, 0,3,1,1> E0 ## E3 ## E1 ## E1; }; \
608+ struct { detail::_swizzle<4, T, Q, 0,3,1,2> E0 ## E3 ## E1 ## E2; }; \
609+ struct { detail::_swizzle<4, T, Q, 0,3,1,3> E0 ## E3 ## E1 ## E3; }; \
610+ struct { detail::_swizzle<4, T, Q, 0,3,2,0> E0 ## E3 ## E2 ## E0; }; \
611+ struct { detail::_swizzle<4, T, Q, 0,3,2,1> E0 ## E3 ## E2 ## E1; }; \
612+ struct { detail::_swizzle<4, T, Q, 0,3,2,2> E0 ## E3 ## E2 ## E2; }; \
613+ struct { detail::_swizzle<4, T, Q, 0,3,2,3> E0 ## E3 ## E2 ## E3; }; \
614+ struct { detail::_swizzle<4, T, Q, 0,3,3,0> E0 ## E3 ## E3 ## E0; }; \
615+ struct { detail::_swizzle<4, T, Q, 0,3,3,1> E0 ## E3 ## E3 ## E1; }; \
616+ struct { detail::_swizzle<4, T, Q, 0,3,3,2> E0 ## E3 ## E3 ## E2; }; \
617+ struct { detail::_swizzle<4, T, Q, 0,3,3,3> E0 ## E3 ## E3 ## E3; }; \
618+ struct { detail::_swizzle<4, T, Q, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \
619+ struct { detail::_swizzle<4, T, Q, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \
620+ struct { detail::_swizzle<4, T, Q, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \
621+ struct { detail::_swizzle<4, T, Q, 1,0,0,3> E1 ## E0 ## E0 ## E3; }; \
622+ struct { detail::_swizzle<4, T, Q, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \
623+ struct { detail::_swizzle<4, T, Q, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \
624+ struct { detail::_swizzle<4, T, Q, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \
625+ struct { detail::_swizzle<4, T, Q, 1,0,1,3> E1 ## E0 ## E1 ## E3; }; \
626+ struct { detail::_swizzle<4, T, Q, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \
627+ struct { detail::_swizzle<4, T, Q, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \
628+ struct { detail::_swizzle<4, T, Q, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \
629+ struct { detail::_swizzle<4, T, Q, 1,0,2,3> E1 ## E0 ## E2 ## E3; }; \
630+ struct { detail::_swizzle<4, T, Q, 1,0,3,0> E1 ## E0 ## E3 ## E0; }; \
631+ struct { detail::_swizzle<4, T, Q, 1,0,3,1> E1 ## E0 ## E3 ## E1; }; \
632+ struct { detail::_swizzle<4, T, Q, 1,0,3,2> E1 ## E0 ## E3 ## E2; }; \
633+ struct { detail::_swizzle<4, T, Q, 1,0,3,3> E1 ## E0 ## E3 ## E3; }; \
634+ struct { detail::_swizzle<4, T, Q, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \
635+ struct { detail::_swizzle<4, T, Q, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \
636+ struct { detail::_swizzle<4, T, Q, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \
637+ struct { detail::_swizzle<4, T, Q, 1,1,0,3> E1 ## E1 ## E0 ## E3; }; \
638+ struct { detail::_swizzle<4, T, Q, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \
639+ struct { detail::_swizzle<4, T, Q, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \
640+ struct { detail::_swizzle<4, T, Q, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \
641+ struct { detail::_swizzle<4, T, Q, 1,1,1,3> E1 ## E1 ## E1 ## E3; }; \
642+ struct { detail::_swizzle<4, T, Q, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \
643+ struct { detail::_swizzle<4, T, Q, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \
644+ struct { detail::_swizzle<4, T, Q, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \
645+ struct { detail::_swizzle<4, T, Q, 1,1,2,3> E1 ## E1 ## E2 ## E3; }; \
646+ struct { detail::_swizzle<4, T, Q, 1,1,3,0> E1 ## E1 ## E3 ## E0; }; \
647+ struct { detail::_swizzle<4, T, Q, 1,1,3,1> E1 ## E1 ## E3 ## E1; }; \
648+ struct { detail::_swizzle<4, T, Q, 1,1,3,2> E1 ## E1 ## E3 ## E2; }; \
649+ struct { detail::_swizzle<4, T, Q, 1,1,3,3> E1 ## E1 ## E3 ## E3; }; \
650+ struct { detail::_swizzle<4, T, Q, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \
651+ struct { detail::_swizzle<4, T, Q, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \
652+ struct { detail::_swizzle<4, T, Q, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \
653+ struct { detail::_swizzle<4, T, Q, 1,2,0,3> E1 ## E2 ## E0 ## E3; }; \
654+ struct { detail::_swizzle<4, T, Q, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \
655+ struct { detail::_swizzle<4, T, Q, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \
656+ struct { detail::_swizzle<4, T, Q, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \
657+ struct { detail::_swizzle<4, T, Q, 1,2,1,3> E1 ## E2 ## E1 ## E3; }; \
658+ struct { detail::_swizzle<4, T, Q, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \
659+ struct { detail::_swizzle<4, T, Q, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \
660+ struct { detail::_swizzle<4, T, Q, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \
661+ struct { detail::_swizzle<4, T, Q, 1,2,2,3> E1 ## E2 ## E2 ## E3; }; \
662+ struct { detail::_swizzle<4, T, Q, 1,2,3,0> E1 ## E2 ## E3 ## E0; }; \
663+ struct { detail::_swizzle<4, T, Q, 1,2,3,1> E1 ## E2 ## E3 ## E1; }; \
664+ struct { detail::_swizzle<4, T, Q, 1,2,3,2> E1 ## E2 ## E3 ## E2; }; \
665+ struct { detail::_swizzle<4, T, Q, 1,2,3,3> E1 ## E2 ## E3 ## E3; }; \
666+ struct { detail::_swizzle<4, T, Q, 1,3,0,0> E1 ## E3 ## E0 ## E0; }; \
667+ struct { detail::_swizzle<4, T, Q, 1,3,0,1> E1 ## E3 ## E0 ## E1; }; \
668+ struct { detail::_swizzle<4, T, Q, 1,3,0,2> E1 ## E3 ## E0 ## E2; }; \
669+ struct { detail::_swizzle<4, T, Q, 1,3,0,3> E1 ## E3 ## E0 ## E3; }; \
670+ struct { detail::_swizzle<4, T, Q, 1,3,1,0> E1 ## E3 ## E1 ## E0; }; \
671+ struct { detail::_swizzle<4, T, Q, 1,3,1,1> E1 ## E3 ## E1 ## E1; }; \
672+ struct { detail::_swizzle<4, T, Q, 1,3,1,2> E1 ## E3 ## E1 ## E2; }; \
673+ struct { detail::_swizzle<4, T, Q, 1,3,1,3> E1 ## E3 ## E1 ## E3; }; \
674+ struct { detail::_swizzle<4, T, Q, 1,3,2,0> E1 ## E3 ## E2 ## E0; }; \
675+ struct { detail::_swizzle<4, T, Q, 1,3,2,1> E1 ## E3 ## E2 ## E1; }; \
676+ struct { detail::_swizzle<4, T, Q, 1,3,2,2> E1 ## E3 ## E2 ## E2; }; \
677+ struct { detail::_swizzle<4, T, Q, 1,3,2,3> E1 ## E3 ## E2 ## E3; }; \
678+ struct { detail::_swizzle<4, T, Q, 1,3,3,0> E1 ## E3 ## E3 ## E0; }; \
679+ struct { detail::_swizzle<4, T, Q, 1,3,3,1> E1 ## E3 ## E3 ## E1; }; \
680+ struct { detail::_swizzle<4, T, Q, 1,3,3,2> E1 ## E3 ## E3 ## E2; }; \
681+ struct { detail::_swizzle<4, T, Q, 1,3,3,3> E1 ## E3 ## E3 ## E3; }; \
682+ struct { detail::_swizzle<4, T, Q, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \
683+ struct { detail::_swizzle<4, T, Q, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \
684+ struct { detail::_swizzle<4, T, Q, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \
685+ struct { detail::_swizzle<4, T, Q, 2,0,0,3> E2 ## E0 ## E0 ## E3; }; \
686+ struct { detail::_swizzle<4, T, Q, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \
687+ struct { detail::_swizzle<4, T, Q, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \
688+ struct { detail::_swizzle<4, T, Q, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \
689+ struct { detail::_swizzle<4, T, Q, 2,0,1,3> E2 ## E0 ## E1 ## E3; }; \
690+ struct { detail::_swizzle<4, T, Q, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \
691+ struct { detail::_swizzle<4, T, Q, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \
692+ struct { detail::_swizzle<4, T, Q, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \
693+ struct { detail::_swizzle<4, T, Q, 2,0,2,3> E2 ## E0 ## E2 ## E3; }; \
694+ struct { detail::_swizzle<4, T, Q, 2,0,3,0> E2 ## E0 ## E3 ## E0; }; \
695+ struct { detail::_swizzle<4, T, Q, 2,0,3,1> E2 ## E0 ## E3 ## E1; }; \
696+ struct { detail::_swizzle<4, T, Q, 2,0,3,2> E2 ## E0 ## E3 ## E2; }; \
697+ struct { detail::_swizzle<4, T, Q, 2,0,3,3> E2 ## E0 ## E3 ## E3; }; \
698+ struct { detail::_swizzle<4, T, Q, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \
699+ struct { detail::_swizzle<4, T, Q, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \
700+ struct { detail::_swizzle<4, T, Q, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \
701+ struct { detail::_swizzle<4, T, Q, 2,1,0,3> E2 ## E1 ## E0 ## E3; }; \
702+ struct { detail::_swizzle<4, T, Q, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \
703+ struct { detail::_swizzle<4, T, Q, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \
704+ struct { detail::_swizzle<4, T, Q, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \
705+ struct { detail::_swizzle<4, T, Q, 2,1,1,3> E2 ## E1 ## E1 ## E3; }; \
706+ struct { detail::_swizzle<4, T, Q, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \
707+ struct { detail::_swizzle<4, T, Q, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \
708+ struct { detail::_swizzle<4, T, Q, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \
709+ struct { detail::_swizzle<4, T, Q, 2,1,2,3> E2 ## E1 ## E2 ## E3; }; \
710+ struct { detail::_swizzle<4, T, Q, 2,1,3,0> E2 ## E1 ## E3 ## E0; }; \
711+ struct { detail::_swizzle<4, T, Q, 2,1,3,1> E2 ## E1 ## E3 ## E1; }; \
712+ struct { detail::_swizzle<4, T, Q, 2,1,3,2> E2 ## E1 ## E3 ## E2; }; \
713+ struct { detail::_swizzle<4, T, Q, 2,1,3,3> E2 ## E1 ## E3 ## E3; }; \
714+ struct { detail::_swizzle<4, T, Q, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \
715+ struct { detail::_swizzle<4, T, Q, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \
716+ struct { detail::_swizzle<4, T, Q, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \
717+ struct { detail::_swizzle<4, T, Q, 2,2,0,3> E2 ## E2 ## E0 ## E3; }; \
718+ struct { detail::_swizzle<4, T, Q, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \
719+ struct { detail::_swizzle<4, T, Q, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \
720+ struct { detail::_swizzle<4, T, Q, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \
721+ struct { detail::_swizzle<4, T, Q, 2,2,1,3> E2 ## E2 ## E1 ## E3; }; \
722+ struct { detail::_swizzle<4, T, Q, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \
723+ struct { detail::_swizzle<4, T, Q, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \
724+ struct { detail::_swizzle<4, T, Q, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; \
725+ struct { detail::_swizzle<4, T, Q, 2,2,2,3> E2 ## E2 ## E2 ## E3; }; \
726+ struct { detail::_swizzle<4, T, Q, 2,2,3,0> E2 ## E2 ## E3 ## E0; }; \
727+ struct { detail::_swizzle<4, T, Q, 2,2,3,1> E2 ## E2 ## E3 ## E1; }; \
728+ struct { detail::_swizzle<4, T, Q, 2,2,3,2> E2 ## E2 ## E3 ## E2; }; \
729+ struct { detail::_swizzle<4, T, Q, 2,2,3,3> E2 ## E2 ## E3 ## E3; }; \
730+ struct { detail::_swizzle<4, T, Q, 2,3,0,0> E2 ## E3 ## E0 ## E0; }; \
731+ struct { detail::_swizzle<4, T, Q, 2,3,0,1> E2 ## E3 ## E0 ## E1; }; \
732+ struct { detail::_swizzle<4, T, Q, 2,3,0,2> E2 ## E3 ## E0 ## E2; }; \
733+ struct { detail::_swizzle<4, T, Q, 2,3,0,3> E2 ## E3 ## E0 ## E3; }; \
734+ struct { detail::_swizzle<4, T, Q, 2,3,1,0> E2 ## E3 ## E1 ## E0; }; \
735+ struct { detail::_swizzle<4, T, Q, 2,3,1,1> E2 ## E3 ## E1 ## E1; }; \
736+ struct { detail::_swizzle<4, T, Q, 2,3,1,2> E2 ## E3 ## E1 ## E2; }; \
737+ struct { detail::_swizzle<4, T, Q, 2,3,1,3> E2 ## E3 ## E1 ## E3; }; \
738+ struct { detail::_swizzle<4, T, Q, 2,3,2,0> E2 ## E3 ## E2 ## E0; }; \
739+ struct { detail::_swizzle<4, T, Q, 2,3,2,1> E2 ## E3 ## E2 ## E1; }; \
740+ struct { detail::_swizzle<4, T, Q, 2,3,2,2> E2 ## E3 ## E2 ## E2; }; \
741+ struct { detail::_swizzle<4, T, Q, 2,3,2,3> E2 ## E3 ## E2 ## E3; }; \
742+ struct { detail::_swizzle<4, T, Q, 2,3,3,0> E2 ## E3 ## E3 ## E0; }; \
743+ struct { detail::_swizzle<4, T, Q, 2,3,3,1> E2 ## E3 ## E3 ## E1; }; \
744+ struct { detail::_swizzle<4, T, Q, 2,3,3,2> E2 ## E3 ## E3 ## E2; }; \
745+ struct { detail::_swizzle<4, T, Q, 2,3,3,3> E2 ## E3 ## E3 ## E3; }; \
746+ struct { detail::_swizzle<4, T, Q, 3,0,0,0> E3 ## E0 ## E0 ## E0; }; \
747+ struct { detail::_swizzle<4, T, Q, 3,0,0,1> E3 ## E0 ## E0 ## E1; }; \
748+ struct { detail::_swizzle<4, T, Q, 3,0,0,2> E3 ## E0 ## E0 ## E2; }; \
749+ struct { detail::_swizzle<4, T, Q, 3,0,0,3> E3 ## E0 ## E0 ## E3; }; \
750+ struct { detail::_swizzle<4, T, Q, 3,0,1,0> E3 ## E0 ## E1 ## E0; }; \
751+ struct { detail::_swizzle<4, T, Q, 3,0,1,1> E3 ## E0 ## E1 ## E1; }; \
752+ struct { detail::_swizzle<4, T, Q, 3,0,1,2> E3 ## E0 ## E1 ## E2; }; \
753+ struct { detail::_swizzle<4, T, Q, 3,0,1,3> E3 ## E0 ## E1 ## E3; }; \
754+ struct { detail::_swizzle<4, T, Q, 3,0,2,0> E3 ## E0 ## E2 ## E0; }; \
755+ struct { detail::_swizzle<4, T, Q, 3,0,2,1> E3 ## E0 ## E2 ## E1; }; \
756+ struct { detail::_swizzle<4, T, Q, 3,0,2,2> E3 ## E0 ## E2 ## E2; }; \
757+ struct { detail::_swizzle<4, T, Q, 3,0,2,3> E3 ## E0 ## E2 ## E3; }; \
758+ struct { detail::_swizzle<4, T, Q, 3,0,3,0> E3 ## E0 ## E3 ## E0; }; \
759+ struct { detail::_swizzle<4, T, Q, 3,0,3,1> E3 ## E0 ## E3 ## E1; }; \
760+ struct { detail::_swizzle<4, T, Q, 3,0,3,2> E3 ## E0 ## E3 ## E2; }; \
761+ struct { detail::_swizzle<4, T, Q, 3,0,3,3> E3 ## E0 ## E3 ## E3; }; \
762+ struct { detail::_swizzle<4, T, Q, 3,1,0,0> E3 ## E1 ## E0 ## E0; }; \
763+ struct { detail::_swizzle<4, T, Q, 3,1,0,1> E3 ## E1 ## E0 ## E1; }; \
764+ struct { detail::_swizzle<4, T, Q, 3,1,0,2> E3 ## E1 ## E0 ## E2; }; \
765+ struct { detail::_swizzle<4, T, Q, 3,1,0,3> E3 ## E1 ## E0 ## E3; }; \
766+ struct { detail::_swizzle<4, T, Q, 3,1,1,0> E3 ## E1 ## E1 ## E0; }; \
767+ struct { detail::_swizzle<4, T, Q, 3,1,1,1> E3 ## E1 ## E1 ## E1; }; \
768+ struct { detail::_swizzle<4, T, Q, 3,1,1,2> E3 ## E1 ## E1 ## E2; }; \
769+ struct { detail::_swizzle<4, T, Q, 3,1,1,3> E3 ## E1 ## E1 ## E3; }; \
770+ struct { detail::_swizzle<4, T, Q, 3,1,2,0> E3 ## E1 ## E2 ## E0; }; \
771+ struct { detail::_swizzle<4, T, Q, 3,1,2,1> E3 ## E1 ## E2 ## E1; }; \
772+ struct { detail::_swizzle<4, T, Q, 3,1,2,2> E3 ## E1 ## E2 ## E2; }; \
773+ struct { detail::_swizzle<4, T, Q, 3,1,2,3> E3 ## E1 ## E2 ## E3; }; \
774+ struct { detail::_swizzle<4, T, Q, 3,1,3,0> E3 ## E1 ## E3 ## E0; }; \
775+ struct { detail::_swizzle<4, T, Q, 3,1,3,1> E3 ## E1 ## E3 ## E1; }; \
776+ struct { detail::_swizzle<4, T, Q, 3,1,3,2> E3 ## E1 ## E3 ## E2; }; \
777+ struct { detail::_swizzle<4, T, Q, 3,1,3,3> E3 ## E1 ## E3 ## E3; }; \
778+ struct { detail::_swizzle<4, T, Q, 3,2,0,0> E3 ## E2 ## E0 ## E0; }; \
779+ struct { detail::_swizzle<4, T, Q, 3,2,0,1> E3 ## E2 ## E0 ## E1; }; \
780+ struct { detail::_swizzle<4, T, Q, 3,2,0,2> E3 ## E2 ## E0 ## E2; }; \
781+ struct { detail::_swizzle<4, T, Q, 3,2,0,3> E3 ## E2 ## E0 ## E3; }; \
782+ struct { detail::_swizzle<4, T, Q, 3,2,1,0> E3 ## E2 ## E1 ## E0; }; \
783+ struct { detail::_swizzle<4, T, Q, 3,2,1,1> E3 ## E2 ## E1 ## E1; }; \
784+ struct { detail::_swizzle<4, T, Q, 3,2,1,2> E3 ## E2 ## E1 ## E2; }; \
785+ struct { detail::_swizzle<4, T, Q, 3,2,1,3> E3 ## E2 ## E1 ## E3; }; \
786+ struct { detail::_swizzle<4, T, Q, 3,2,2,0> E3 ## E2 ## E2 ## E0; }; \
787+ struct { detail::_swizzle<4, T, Q, 3,2,2,1> E3 ## E2 ## E2 ## E1; }; \
788+ struct { detail::_swizzle<4, T, Q, 3,2,2,2> E3 ## E2 ## E2 ## E2; }; \
789+ struct { detail::_swizzle<4, T, Q, 3,2,2,3> E3 ## E2 ## E2 ## E3; }; \
790+ struct { detail::_swizzle<4, T, Q, 3,2,3,0> E3 ## E2 ## E3 ## E0; }; \
791+ struct { detail::_swizzle<4, T, Q, 3,2,3,1> E3 ## E2 ## E3 ## E1; }; \
792+ struct { detail::_swizzle<4, T, Q, 3,2,3,2> E3 ## E2 ## E3 ## E2; }; \
793+ struct { detail::_swizzle<4, T, Q, 3,2,3,3> E3 ## E2 ## E3 ## E3; }; \
794+ struct { detail::_swizzle<4, T, Q, 3,3,0,0> E3 ## E3 ## E0 ## E0; }; \
795+ struct { detail::_swizzle<4, T, Q, 3,3,0,1> E3 ## E3 ## E0 ## E1; }; \
796+ struct { detail::_swizzle<4, T, Q, 3,3,0,2> E3 ## E3 ## E0 ## E2; }; \
797+ struct { detail::_swizzle<4, T, Q, 3,3,0,3> E3 ## E3 ## E0 ## E3; }; \
798+ struct { detail::_swizzle<4, T, Q, 3,3,1,0> E3 ## E3 ## E1 ## E0; }; \
799+ struct { detail::_swizzle<4, T, Q, 3,3,1,1> E3 ## E3 ## E1 ## E1; }; \
800+ struct { detail::_swizzle<4, T, Q, 3,3,1,2> E3 ## E3 ## E1 ## E2; }; \
801+ struct { detail::_swizzle<4, T, Q, 3,3,1,3> E3 ## E3 ## E1 ## E3; }; \
802+ struct { detail::_swizzle<4, T, Q, 3,3,2,0> E3 ## E3 ## E2 ## E0; }; \
803+ struct { detail::_swizzle<4, T, Q, 3,3,2,1> E3 ## E3 ## E2 ## E1; }; \
804+ struct { detail::_swizzle<4, T, Q, 3,3,2,2> E3 ## E3 ## E2 ## E2; }; \
805+ struct { detail::_swizzle<4, T, Q, 3,3,2,3> E3 ## E3 ## E2 ## E3; }; \
806+ struct { detail::_swizzle<4, T, Q, 3,3,3,0> E3 ## E3 ## E3 ## E0; }; \
807+ struct { detail::_swizzle<4, T, Q, 3,3,3,1> E3 ## E3 ## E3 ## E1; }; \
808+ struct { detail::_swizzle<4, T, Q, 3,3,3,2> E3 ## E3 ## E3 ## E2; }; \
809+ struct { detail::_swizzle<4, T, Q, 3,3,3,3> E3 ## E3 ## E3 ## E3; };
@@ -0,0 +1,682 @@
1+#pragma once
2+
3+#define GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, CONST, A, B) \
4+ GLM_FUNC_QUALIFIER vec<2, T, Q> A ## B() CONST \
5+ { \
6+ return vec<2, T, Q>(this->A, this->B); \
7+ }
8+
9+#define GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, CONST, A, B, C) \
10+ GLM_FUNC_QUALIFIER vec<3, T, Q> A ## B ## C() CONST \
11+ { \
12+ return vec<3, T, Q>(this->A, this->B, this->C); \
13+ }
14+
15+#define GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, CONST, A, B, C, D) \
16+ GLM_FUNC_QUALIFIER vec<4, T, Q> A ## B ## C ## D() CONST \
17+ { \
18+ return vec<4, T, Q>(this->A, this->B, this->C, this->D); \
19+ }
20+
21+#define GLM_SWIZZLE_GEN_VEC2_ENTRY_DEF(T, P, L, CONST, A, B) \
22+ template<typename T> \
23+ GLM_FUNC_QUALIFIER vec<L, T, Q> vec<L, T, Q>::A ## B() CONST \
24+ { \
25+ return vec<2, T, Q>(this->A, this->B); \
26+ }
27+
28+#define GLM_SWIZZLE_GEN_VEC3_ENTRY_DEF(T, P, L, CONST, A, B, C) \
29+ template<typename T> \
30+ GLM_FUNC_QUALIFIER vec<3, T, Q> vec<L, T, Q>::A ## B ## C() CONST \
31+ { \
32+ return vec<3, T, Q>(this->A, this->B, this->C); \
33+ }
34+
35+#define GLM_SWIZZLE_GEN_VEC4_ENTRY_DEF(T, P, L, CONST, A, B, C, D) \
36+ template<typename T> \
37+ GLM_FUNC_QUALIFIER vec<4, T, Q> vec<L, T, Q>::A ## B ## C ## D() CONST \
38+ { \
39+ return vec<4, T, Q>(this->A, this->B, this->C, this->D); \
40+ }
41+
42+#define GLM_MUTABLE
43+
44+#define GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(T, P, A, B) \
45+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, 2, GLM_MUTABLE, A, B) \
46+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, 2, GLM_MUTABLE, B, A)
47+
48+#define GLM_SWIZZLE_GEN_REF_FROM_VEC2(T, P) \
49+ GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(T, P, x, y) \
50+ GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(T, P, r, g) \
51+ GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(T, P, s, t)
52+
53+#define GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(T, P, A, B, C) \
54+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, B) \
55+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, C) \
56+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, A) \
57+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, C) \
58+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, A) \
59+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, B)
60+
61+#define GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(T, P, A, B, C) \
62+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, A, B, C) \
63+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, A, C, B) \
64+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, B, A, C) \
65+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, B, C, A) \
66+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, C, A, B) \
67+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, C, B, A)
68+
69+#define GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(T, P, A, B, C) \
70+ GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(T, P, A, B, C) \
71+ GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(T, P, A, B, C)
72+
73+#define GLM_SWIZZLE_GEN_REF_FROM_VEC3(T, P) \
74+ GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(T, P, x, y, z) \
75+ GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(T, P, r, g, b) \
76+ GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(T, P, s, t, p)
77+
78+#define GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \
79+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, B) \
80+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, C) \
81+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, D) \
82+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, A) \
83+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, C) \
84+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, D) \
85+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, A) \
86+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, B) \
87+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, D) \
88+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, D, A) \
89+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, D, B) \
90+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, D, C)
91+
92+#define GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \
93+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, B, C) \
94+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, B, D) \
95+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, C, B) \
96+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, C, D) \
97+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, D, B) \
98+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, D, C) \
99+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, A, C) \
100+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, A, D) \
101+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, C, A) \
102+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, C, D) \
103+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, D, A) \
104+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, D, C) \
105+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, A, B) \
106+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, A, D) \
107+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, B, A) \
108+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, B, D) \
109+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, D, A) \
110+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, D, B) \
111+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, A, B) \
112+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, A, C) \
113+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, B, A) \
114+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, B, C) \
115+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, C, A) \
116+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, C, B)
117+
118+#define GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \
119+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, C, B, D) \
120+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, C, D, B) \
121+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, D, B, C) \
122+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, D, C, B) \
123+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, B, D, C) \
124+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, B, C, D) \
125+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, C, A, D) \
126+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, C, D, A) \
127+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, D, A, C) \
128+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, D, C, A) \
129+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, A, D, C) \
130+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, A, C, D) \
131+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, B, A, D) \
132+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, B, D, A) \
133+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, D, A, B) \
134+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, D, B, A) \
135+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, A, D, B) \
136+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, A, B, D) \
137+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, C, B, A) \
138+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, C, A, B) \
139+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, A, B, C) \
140+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, A, C, B) \
141+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, B, A, C) \
142+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, B, C, A)
143+
144+#define GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(T, P, A, B, C, D) \
145+ GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \
146+ GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \
147+ GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(T, P, A, B, C, D)
148+
149+#define GLM_SWIZZLE_GEN_REF_FROM_VEC4(T, P) \
150+ GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(T, P, x, y, z, w) \
151+ GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(T, P, r, g, b, a) \
152+ GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(T, P, s, t, p, q)
153+
154+#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(T, P, A, B) \
155+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, A) \
156+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, B) \
157+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, A) \
158+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, B)
159+
160+#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(T, P, A, B) \
161+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, A) \
162+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, B) \
163+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, A) \
164+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, B) \
165+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, A) \
166+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, B) \
167+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, A) \
168+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, B)
169+
170+#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(T, P, A, B) \
171+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, A) \
172+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, B) \
173+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, A) \
174+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, B) \
175+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, A) \
176+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, B) \
177+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, A) \
178+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, B) \
179+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, A) \
180+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, B) \
181+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, A) \
182+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, B) \
183+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, A) \
184+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, B) \
185+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, A) \
186+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, B)
187+
188+#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(T, P, A, B) \
189+ GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(T, P, A, B) \
190+ GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(T, P, A, B) \
191+ GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(T, P, A, B)
192+
193+#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2(T, P) \
194+ GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(T, P, x, y) \
195+ GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(T, P, r, g) \
196+ GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(T, P, s, t)
197+
198+#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(T, P, A, B, C) \
199+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, A) \
200+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, B) \
201+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, C) \
202+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, A) \
203+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, B) \
204+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, C) \
205+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, A) \
206+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, B) \
207+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, C)
208+
209+#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(T, P, A, B, C) \
210+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, A) \
211+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, B) \
212+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, C) \
213+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, A) \
214+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, B) \
215+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, C) \
216+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, A) \
217+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, B) \
218+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, C) \
219+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, A) \
220+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, B) \
221+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, C) \
222+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, A) \
223+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, B) \
224+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, C) \
225+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, A) \
226+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, B) \
227+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, C) \
228+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, A) \
229+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, B) \
230+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, C) \
231+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, A) \
232+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, B) \
233+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, C) \
234+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, A) \
235+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, B) \
236+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, C)
237+
238+#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(T, P, A, B, C) \
239+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, A) \
240+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, B) \
241+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, C) \
242+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, A) \
243+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, B) \
244+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, C) \
245+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, A) \
246+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, B) \
247+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, C) \
248+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, A) \
249+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, B) \
250+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, C) \
251+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, A) \
252+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, B) \
253+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, C) \
254+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, A) \
255+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, B) \
256+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, C) \
257+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, A) \
258+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, B) \
259+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, C) \
260+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, A) \
261+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, B) \
262+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, C) \
263+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, A) \
264+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, B) \
265+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, C) \
266+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, A) \
267+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, B) \
268+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, C) \
269+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, A) \
270+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, B) \
271+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, C) \
272+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, A) \
273+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, B) \
274+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, C) \
275+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, A) \
276+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, B) \
277+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, C) \
278+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, A) \
279+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, B) \
280+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, C) \
281+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, A) \
282+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, B) \
283+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, C) \
284+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, A) \
285+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, B) \
286+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, C) \
287+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, A) \
288+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, B) \
289+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, C) \
290+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, A) \
291+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, B) \
292+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, C) \
293+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, A) \
294+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, B) \
295+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, C) \
296+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, A) \
297+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, B) \
298+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, C) \
299+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, A) \
300+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, B) \
301+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, C) \
302+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, A) \
303+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, B) \
304+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, C) \
305+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, A) \
306+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, B) \
307+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, C) \
308+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, A) \
309+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, B) \
310+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, C) \
311+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, A) \
312+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, B) \
313+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, C) \
314+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, A) \
315+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, B) \
316+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, C) \
317+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, A) \
318+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, B) \
319+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, C)
320+
321+#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, P, A, B, C) \
322+ GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(T, P, A, B, C) \
323+ GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(T, P, A, B, C) \
324+ GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(T, P, A, B, C)
325+
326+#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3(T, P) \
327+ GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, P, x, y, z) \
328+ GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, P, r, g, b) \
329+ GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, P, s, t, p)
330+
331+#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \
332+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, A) \
333+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, B) \
334+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, C) \
335+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, D) \
336+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, A) \
337+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, B) \
338+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, C) \
339+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, D) \
340+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, A) \
341+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, B) \
342+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, C) \
343+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, D) \
344+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, D, A) \
345+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, D, B) \
346+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, D, C) \
347+ GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, D, D)
348+
349+#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \
350+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, A) \
351+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, B) \
352+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, C) \
353+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, D) \
354+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, A) \
355+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, B) \
356+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, C) \
357+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, D) \
358+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, A) \
359+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, B) \
360+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, C) \
361+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, D) \
362+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, D, A) \
363+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, D, B) \
364+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, D, C) \
365+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, D, D) \
366+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, A) \
367+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, B) \
368+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, C) \
369+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, D) \
370+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, A) \
371+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, B) \
372+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, C) \
373+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, D) \
374+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, A) \
375+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, B) \
376+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, C) \
377+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, D) \
378+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, D, A) \
379+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, D, B) \
380+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, D, C) \
381+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, D, D) \
382+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, A) \
383+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, B) \
384+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, C) \
385+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, D) \
386+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, A) \
387+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, B) \
388+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, C) \
389+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, D) \
390+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, A) \
391+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, B) \
392+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, C) \
393+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, D) \
394+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, D, A) \
395+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, D, B) \
396+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, D, C) \
397+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, D, D) \
398+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, A, A) \
399+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, A, B) \
400+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, A, C) \
401+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, A, D) \
402+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, B, A) \
403+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, B, B) \
404+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, B, C) \
405+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, B, D) \
406+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, C, A) \
407+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, C, B) \
408+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, C, C) \
409+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, C, D) \
410+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, D, A) \
411+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, D, B) \
412+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, D, C) \
413+ GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, D, D)
414+
415+#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \
416+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, A) \
417+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, B) \
418+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, C) \
419+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, D) \
420+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, A) \
421+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, B) \
422+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, C) \
423+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, D) \
424+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, A) \
425+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, B) \
426+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, C) \
427+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, D) \
428+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, D, A) \
429+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, D, B) \
430+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, D, C) \
431+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, D, D) \
432+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, A) \
433+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, B) \
434+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, C) \
435+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, D) \
436+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, A) \
437+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, B) \
438+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, C) \
439+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, D) \
440+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, A) \
441+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, B) \
442+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, C) \
443+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, D) \
444+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, D, A) \
445+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, D, B) \
446+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, D, C) \
447+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, D, D) \
448+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, A) \
449+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, B) \
450+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, C) \
451+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, D) \
452+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, A) \
453+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, B) \
454+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, C) \
455+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, D) \
456+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, A) \
457+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, B) \
458+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, C) \
459+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, D) \
460+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, D, A) \
461+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, D, B) \
462+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, D, C) \
463+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, D, D) \
464+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, A, A) \
465+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, A, B) \
466+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, A, C) \
467+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, A, D) \
468+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, B, A) \
469+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, B, B) \
470+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, B, C) \
471+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, B, D) \
472+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, C, A) \
473+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, C, B) \
474+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, C, C) \
475+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, C, D) \
476+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, D, A) \
477+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, D, B) \
478+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, D, C) \
479+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, D, D) \
480+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, A) \
481+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, B) \
482+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, C) \
483+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, D) \
484+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, A) \
485+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, B) \
486+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, C) \
487+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, D) \
488+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, A) \
489+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, B) \
490+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, C) \
491+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, D) \
492+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, D, A) \
493+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, D, B) \
494+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, D, C) \
495+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, D, D) \
496+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, A) \
497+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, B) \
498+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, C) \
499+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, D) \
500+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, A) \
501+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, B) \
502+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, C) \
503+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, D) \
504+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, A) \
505+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, B) \
506+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, C) \
507+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, D) \
508+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, D, A) \
509+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, D, B) \
510+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, D, C) \
511+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, D, D) \
512+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, A) \
513+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, B) \
514+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, C) \
515+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, D) \
516+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, A) \
517+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, B) \
518+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, C) \
519+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, D) \
520+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, A) \
521+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, B) \
522+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, C) \
523+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, D) \
524+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, D, A) \
525+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, D, B) \
526+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, D, C) \
527+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, D, D) \
528+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, A, A) \
529+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, A, B) \
530+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, A, C) \
531+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, A, D) \
532+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, B, A) \
533+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, B, B) \
534+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, B, C) \
535+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, B, D) \
536+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, C, A) \
537+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, C, B) \
538+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, C, C) \
539+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, C, D) \
540+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, D, A) \
541+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, D, B) \
542+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, D, C) \
543+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, D, D) \
544+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, A) \
545+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, B) \
546+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, C) \
547+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, D) \
548+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, A) \
549+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, B) \
550+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, C) \
551+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, D) \
552+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, A) \
553+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, B) \
554+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, C) \
555+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, D) \
556+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, D, A) \
557+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, D, B) \
558+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, D, C) \
559+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, D, D) \
560+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, A) \
561+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, B) \
562+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, C) \
563+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, D) \
564+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, A) \
565+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, B) \
566+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, C) \
567+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, D) \
568+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, A) \
569+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, B) \
570+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, C) \
571+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, D) \
572+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, D, A) \
573+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, D, B) \
574+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, D, C) \
575+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, D, D) \
576+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, A) \
577+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, B) \
578+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, C) \
579+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, D) \
580+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, A) \
581+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, B) \
582+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, C) \
583+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, D) \
584+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, A) \
585+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, B) \
586+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, C) \
587+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, D) \
588+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, D, A) \
589+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, D, B) \
590+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, D, C) \
591+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, D, D) \
592+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, A, A) \
593+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, A, B) \
594+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, A, C) \
595+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, A, D) \
596+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, B, A) \
597+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, B, B) \
598+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, B, C) \
599+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, B, D) \
600+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, C, A) \
601+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, C, B) \
602+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, C, C) \
603+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, C, D) \
604+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, D, A) \
605+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, D, B) \
606+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, D, C) \
607+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, D, D) \
608+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, A, A) \
609+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, A, B) \
610+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, A, C) \
611+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, A, D) \
612+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, B, A) \
613+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, B, B) \
614+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, B, C) \
615+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, B, D) \
616+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, C, A) \
617+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, C, B) \
618+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, C, C) \
619+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, C, D) \
620+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, D, A) \
621+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, D, B) \
622+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, D, C) \
623+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, D, D) \
624+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, A, A) \
625+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, A, B) \
626+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, A, C) \
627+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, A, D) \
628+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, B, A) \
629+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, B, B) \
630+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, B, C) \
631+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, B, D) \
632+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, C, A) \
633+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, C, B) \
634+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, C, C) \
635+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, C, D) \
636+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, D, A) \
637+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, D, B) \
638+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, D, C) \
639+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, D, D) \
640+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, A, A) \
641+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, A, B) \
642+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, A, C) \
643+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, A, D) \
644+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, B, A) \
645+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, B, B) \
646+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, B, C) \
647+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, B, D) \
648+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, C, A) \
649+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, C, B) \
650+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, C, C) \
651+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, C, D) \
652+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, D, A) \
653+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, D, B) \
654+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, D, C) \
655+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, D, D) \
656+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, A, A) \
657+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, A, B) \
658+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, A, C) \
659+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, A, D) \
660+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, B, A) \
661+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, B, B) \
662+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, B, C) \
663+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, B, D) \
664+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, C, A) \
665+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, C, B) \
666+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, C, C) \
667+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, C, D) \
668+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, D, A) \
669+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, D, B) \
670+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, D, C) \
671+ GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, D, D)
672+
673+#define GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, P, A, B, C, D) \
674+ GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \
675+ GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \
676+ GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(T, P, A, B, C, D)
677+
678+#define GLM_SWIZZLE_GEN_VEC_FROM_VEC4(T, P) \
679+ GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, P, x, y, z, w) \
680+ GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, P, r, g, b, a) \
681+ GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, P, s, t, p, q)
682+
@@ -0,0 +1,230 @@
1+#pragma once
2+
3+namespace glm{
4+namespace detail
5+{
6+ template<template<length_t L, typename T, qualifier Q> class vec, length_t L, typename R, typename T, qualifier Q>
7+ struct functor1{};
8+
9+ template<template<length_t L, typename T, qualifier Q> class vec, typename R, typename T, qualifier Q>
10+ struct functor1<vec, 1, R, T, Q>
11+ {
12+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<1, R, Q> call(R (*Func) (T x), vec<1, T, Q> const& v)
13+ {
14+ return vec<1, R, Q>(Func(v.x));
15+ }
16+ };
17+
18+ template<template<length_t L, typename T, qualifier Q> class vec, typename R, typename T, qualifier Q>
19+ struct functor1<vec, 2, R, T, Q>
20+ {
21+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<2, R, Q> call(R (*Func) (T x), vec<2, T, Q> const& v)
22+ {
23+ return vec<2, R, Q>(Func(v.x), Func(v.y));
24+ }
25+ };
26+
27+ template<template<length_t L, typename T, qualifier Q> class vec, typename R, typename T, qualifier Q>
28+ struct functor1<vec, 3, R, T, Q>
29+ {
30+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<3, R, Q> call(R (*Func) (T x), vec<3, T, Q> const& v)
31+ {
32+ return vec<3, R, Q>(Func(v.x), Func(v.y), Func(v.z));
33+ }
34+ };
35+
36+ template<template<length_t L, typename T, qualifier Q> class vec, typename R, typename T, qualifier Q>
37+ struct functor1<vec, 4, R, T, Q>
38+ {
39+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, R, Q> call(R (*Func) (T x), vec<4, T, Q> const& v)
40+ {
41+ return vec<4, R, Q>(Func(v.x), Func(v.y), Func(v.z), Func(v.w));
42+ }
43+ };
44+
45+ template<template<length_t L, typename T, qualifier Q> class vec, length_t L, typename T, qualifier Q>
46+ struct functor2{};
47+
48+ template<template<length_t L, typename T, qualifier Q> class vec, typename T, qualifier Q>
49+ struct functor2<vec, 1, T, Q>
50+ {
51+ GLM_FUNC_QUALIFIER static vec<1, T, Q> call(T (*Func) (T x, T y), vec<1, T, Q> const& a, vec<1, T, Q> const& b)
52+ {
53+ return vec<1, T, Q>(Func(a.x, b.x));
54+ }
55+
56+ template<typename Fct>
57+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<1, T, Q> call(Fct Func, vec<1, T, Q> const& a, vec<1, T, Q> const& b)
58+ {
59+ return vec<1, T, Q>(Func(a.x, b.x));
60+ }
61+ };
62+
63+ template<template<length_t L, typename T, qualifier Q> class vec, typename T, qualifier Q>
64+ struct functor2<vec, 2, T, Q>
65+ {
66+ GLM_FUNC_QUALIFIER static vec<2, T, Q> call(T (*Func) (T x, T y), vec<2, T, Q> const& a, vec<2, T, Q> const& b)
67+ {
68+ return vec<2, T, Q>(Func(a.x, b.x), Func(a.y, b.y));
69+ }
70+
71+ template<typename Fct>
72+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<2, T, Q> call(Fct Func, vec<2, T, Q> const& a, vec<2, T, Q> const& b)
73+ {
74+ return vec<2, T, Q>(Func(a.x, b.x), Func(a.y, b.y));
75+ }
76+ };
77+
78+ template<template<length_t L, typename T, qualifier Q> class vec, typename T, qualifier Q>
79+ struct functor2<vec, 3, T, Q>
80+ {
81+ GLM_FUNC_QUALIFIER static vec<3, T, Q> call(T (*Func) (T x, T y), vec<3, T, Q> const& a, vec<3, T, Q> const& b)
82+ {
83+ return vec<3, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z));
84+ }
85+
86+ template<class Fct>
87+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<3, T, Q> call(Fct Func, vec<3, T, Q> const& a, vec<3, T, Q> const& b)
88+ {
89+ return vec<3, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z));
90+ }
91+ };
92+
93+ template<template<length_t L, typename T, qualifier Q> class vec, typename T, qualifier Q>
94+ struct functor2<vec, 4, T, Q>
95+ {
96+ GLM_FUNC_QUALIFIER static vec<4, T, Q> call(T (*Func) (T x, T y), vec<4, T, Q> const& a, vec<4, T, Q> const& b)
97+ {
98+ return vec<4, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w));
99+ }
100+
101+ template<class Fct>
102+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(Fct Func, vec<4, T, Q> const& a, vec<4, T, Q> const& b)
103+ {
104+ return vec<4, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w));
105+ }
106+ };
107+
108+ template<template<length_t L, typename T, qualifier Q> class vec, length_t L, typename T, qualifier Q>
109+ struct functor2_vec_sca{};
110+
111+ template<template<length_t L, typename T, qualifier Q> class vec, typename T, qualifier Q>
112+ struct functor2_vec_sca<vec, 1, T, Q>
113+ {
114+ GLM_FUNC_QUALIFIER static vec<1, T, Q> call(T (*Func) (T x, T y), vec<1, T, Q> const& a, T b)
115+ {
116+ return vec<1, T, Q>(Func(a.x, b));
117+ }
118+ template<class Fct>
119+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<1, T, Q> call(Fct Func, vec<1, T, Q> const& a, T b)
120+ {
121+ return vec<1, T, Q>(Func(a.x, b));
122+ }
123+ };
124+
125+ template<template<length_t L, typename T, qualifier Q> class vec, typename T, qualifier Q>
126+ struct functor2_vec_sca<vec, 2, T, Q>
127+ {
128+ GLM_FUNC_QUALIFIER static vec<2, T, Q> call(T (*Func) (T x, T y), vec<2, T, Q> const& a, T b)
129+ {
130+ return vec<2, T, Q>(Func(a.x, b), Func(a.y, b));
131+ }
132+
133+ template<class Fct>
134+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<2, T, Q> call(Fct Func, vec<2, T, Q> const& a, T b)
135+ {
136+ return vec<2, T, Q>(Func(a.x, b), Func(a.y, b));
137+ }
138+ };
139+
140+ template<template<length_t L, typename T, qualifier Q> class vec, typename T, qualifier Q>
141+ struct functor2_vec_sca<vec, 3, T, Q>
142+ {
143+ GLM_FUNC_QUALIFIER static vec<3, T, Q> call(T (*Func) (T x, T y), vec<3, T, Q> const& a, T b)
144+ {
145+ return vec<3, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b));
146+ }
147+
148+ template<class Fct>
149+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<3, T, Q> call(Fct Func, vec<3, T, Q> const& a, T b)
150+ {
151+ return vec<3, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b));
152+ }
153+ };
154+
155+ template<template<length_t L, typename T, qualifier Q> class vec, typename T, qualifier Q>
156+ struct functor2_vec_sca<vec, 4, T, Q>
157+ {
158+ GLM_FUNC_QUALIFIER static vec<4, T, Q> call(T (*Func) (T x, T y), vec<4, T, Q> const& a, T b)
159+ {
160+ return vec<4, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b), Func(a.w, b));
161+ }
162+ template<class Fct>
163+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(Fct Func, vec<4, T, Q> const& a, T b)
164+ {
165+ return vec<4, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b), Func(a.w, b));
166+ }
167+ };
168+
169+ template<length_t L, typename T, qualifier Q>
170+ struct functor2_vec_int {};
171+
172+ template<typename T, qualifier Q>
173+ struct functor2_vec_int<1, T, Q>
174+ {
175+ GLM_FUNC_QUALIFIER static vec<1, int, Q> call(int (*Func) (T x, int y), vec<1, T, Q> const& a, vec<1, int, Q> const& b)
176+ {
177+ return vec<1, int, Q>(Func(a.x, b.x));
178+ }
179+
180+ template<class Fct>
181+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<1, int, Q> call(Fct Func, vec<1, T, Q> const& a, vec<1, int, Q> const& b)
182+ {
183+ return vec<1, int, Q>(Func(a.x, b.x));
184+ }
185+ };
186+
187+ template<typename T, qualifier Q>
188+ struct functor2_vec_int<2, T, Q>
189+ {
190+ GLM_FUNC_QUALIFIER static vec<2, int, Q> call(int (*Func) (T x, int y), vec<2, T, Q> const& a, vec<2, int, Q> const& b)
191+ {
192+ return vec<2, int, Q>(Func(a.x, b.x), Func(a.y, b.y));
193+ }
194+ template<class Fct>
195+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<2, int, Q> call(Fct Func, vec<2, T, Q> const& a, vec<2, int, Q> const& b)
196+ {
197+ return vec<2, int, Q>(Func(a.x, b.x), Func(a.y, b.y));
198+ }
199+ };
200+
201+ template<typename T, qualifier Q>
202+ struct functor2_vec_int<3, T, Q>
203+ {
204+ GLM_FUNC_QUALIFIER static vec<3, int, Q> call(int (*Func) (T x, int y), vec<3, T, Q> const& a, vec<3, int, Q> const& b)
205+ {
206+ return vec<3, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z));
207+ }
208+ template<class Fct>
209+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<3, int, Q> call(Fct Func, vec<3, T, Q> const& a, vec<3, int, Q> const& b)
210+ {
211+ return vec<3, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z));
212+ }
213+ };
214+
215+ template<typename T, qualifier Q>
216+ struct functor2_vec_int<4, T, Q>
217+ {
218+ GLM_FUNC_QUALIFIER static vec<4, int, Q> call(int (*Func) (T x, int y), vec<4, T, Q> const& a, vec<4, int, Q> const& b)
219+ {
220+ return vec<4, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w));
221+ }
222+
223+ template<class Fct>
224+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, int, Q> call(Fct Func, vec<4, T, Q> const& a, vec<4, int, Q> const& b)
225+ {
226+ return vec<4, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w));
227+ }
228+ };
229+}//namespace detail
230+}//namespace glm
@@ -0,0 +1,50 @@
1+#pragma once
2+
3+#include "setup.hpp"
4+#include <limits>
5+
6+namespace glm{
7+namespace detail
8+{
9+ template<typename genFIType, bool /*signed*/>
10+ struct compute_abs
11+ {};
12+
13+ template<typename genFIType>
14+ struct compute_abs<genFIType, true>
15+ {
16+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static genFIType call(genFIType x)
17+ {
18+ static_assert(
19+ std::numeric_limits<genFIType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || std::numeric_limits<genFIType>::is_signed,
20+ "'abs' only accept floating-point and integer scalar or vector inputs");
21+
22+ return x >= genFIType(0) ? x : -x;
23+ // TODO, perf comp with: *(((int *) &x) + 1) &= 0x7fffffff;
24+ }
25+ };
26+
27+#if (GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP)
28+ template<>
29+ struct compute_abs<float, true>
30+ {
31+ GLM_FUNC_QUALIFIER static float call(float x)
32+ {
33+ return fabsf(x);
34+ }
35+ };
36+#endif
37+
38+ template<typename genFIType>
39+ struct compute_abs<genFIType, false>
40+ {
41+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static genFIType call(genFIType x)
42+ {
43+ static_assert(
44+ (!std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer),
45+ "'abs' only accept floating-point and integer scalar or vector inputs");
46+ return x;
47+ }
48+ };
49+}//namespace detail
50+}//namespace glm
@@ -0,0 +1,134 @@
1+
2+#pragma once
3+#include <functional>
4+#include "_vectorize.hpp"
5+
6+namespace glm {
7+ namespace detail
8+ {
9+ template<length_t L, typename T, qualifier Q, bool UseSimd>
10+ struct compute_vec_add {
11+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
12+ {
13+ return detail::functor2<vec, L, T, Q>::call(std::plus<T>(), a, b);
14+ }
15+ };
16+
17+ template<length_t L, typename T, qualifier Q, bool UseSimd>
18+ struct compute_vec_sub {
19+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
20+ {
21+ return detail::functor2<vec, L, T, Q>::call(std::minus<T>(), a, b);
22+ }
23+ };
24+
25+ template<length_t L, typename T, qualifier Q, bool UseSimd>
26+ struct compute_vec_mul {
27+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
28+ {
29+ return detail::functor2<vec, L, T, Q>::call(std::multiplies<T>(), a, b);
30+ }
31+ };
32+
33+ template<length_t L, typename T, qualifier Q, bool UseSimd>
34+ struct compute_vec_div {
35+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
36+ {
37+ return detail::functor2<vec, L, T, Q>::call(std::divides<T>(), a, b);
38+ }
39+ };
40+
41+ template<length_t L, typename T, qualifier Q, bool UseSimd>
42+ struct compute_vec_mod {
43+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
44+ {
45+ return detail::functor2<vec, L, T, Q>::call(std::modulus<T>(), a, b);
46+ }
47+ };
48+
49+ template<length_t L, typename T, qualifier Q, int IsInt, std::size_t Size, bool UseSimd>
50+ struct compute_vec_and {
51+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
52+ {
53+ vec<L, T, Q> v(a);
54+ for (length_t i = 0; i < L; ++i)
55+ v[i] &= static_cast<T>(b[i]);
56+ return v;
57+ }
58+ };
59+
60+ template<length_t L, typename T, qualifier Q, int IsInt, std::size_t Size, bool UseSimd>
61+ struct compute_vec_or {
62+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
63+ {
64+ vec<L, T, Q> v(a);
65+ for (length_t i = 0; i < L; ++i)
66+ v[i] |= static_cast<T>(b[i]);
67+ return v;
68+ }
69+ };
70+
71+ template<length_t L, typename T, qualifier Q, int IsInt, std::size_t Size, bool UseSimd>
72+ struct compute_vec_xor {
73+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
74+ {
75+ vec<L, T, Q> v(a);
76+ for (length_t i = 0; i < L; ++i)
77+ v[i] ^= static_cast<T>(b[i]);
78+ return v;
79+ }
80+ };
81+
82+ template<length_t L, typename T, qualifier Q, int IsInt, std::size_t Size, bool UseSimd>
83+ struct compute_vec_shift_left {
84+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
85+ {
86+ vec<L, T, Q> v(a);
87+ for (length_t i = 0; i < L; ++i)
88+ v[i] <<= static_cast<T>(b[i]);
89+ return v;
90+ }
91+ };
92+
93+ template<length_t L, typename T, qualifier Q, int IsInt, std::size_t Size, bool UseSimd>
94+ struct compute_vec_shift_right {
95+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
96+ {
97+ vec<L, T, Q> v(a);
98+ for (length_t i = 0; i < L; ++i)
99+ v[i] >>= static_cast<T>(b[i]);
100+ return v;
101+ }
102+ };
103+
104+ template<length_t L, typename T, qualifier Q, int IsInt, std::size_t Size, bool UseSimd>
105+ struct compute_vec_equal {
106+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vec<L, T, Q> const& v1, vec<L, T, Q> const& v2)
107+ {
108+ bool b = true;
109+ for (length_t i = 0; b && i < L; ++i)
110+ b = detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(v1[i], v2[i]);
111+ return b;
112+ }
113+ };
114+
115+ template<length_t L, typename T, qualifier Q, int IsInt, std::size_t Size, bool UseSimd>
116+ struct compute_vec_nequal {
117+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2)
118+ {
119+ return !compute_vec_equal<L, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(v1, v2);
120+ }
121+ };
122+
123+ template<length_t L, typename T, qualifier Q, int IsInt, std::size_t Size, bool UseSimd>
124+ struct compute_vec_bitwise_not {
125+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& a)
126+ {
127+ vec<L, T, Q> v(a);
128+ for (length_t i = 0; i < L; ++i)
129+ v[i] = ~v[i];
130+ return v;
131+ }
132+ };
133+ }
134+}
@@ -0,0 +1,30 @@
1+#pragma once
2+
3+//#include "compute_common.hpp"
4+#include "setup.hpp"
5+#include <limits>
6+
7+namespace glm{
8+namespace detail
9+{
10+ template <typename T, bool isFloat>
11+ struct compute_equal
12+ {
13+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T a, T b)
14+ {
15+ return a == b;
16+ }
17+ };
18+/*
19+ template <typename T>
20+ struct compute_equal<T, true>
21+ {
22+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T a, T b)
23+ {
24+ return detail::compute_abs<T, std::numeric_limits<T>::is_signed>::call(b - a) <= static_cast<T>(0);
25+ //return std::memcmp(&a, &b, sizeof(T)) == 0;
26+ }
27+ };
28+*/
29+}//namespace detail
30+}//namespace glm
@@ -0,0 +1,849 @@
1+/// @ref core
2+/// @file glm/detail/func_common.inl
3+
4+#include "../vector_relational.hpp"
5+#include "compute_common.hpp"
6+#include "type_vec1.hpp"
7+#include "type_vec2.hpp"
8+#include "type_vec3.hpp"
9+#include "type_vec4.hpp"
10+#include "_vectorize.hpp"
11+#include <limits>
12+
13+namespace glm
14+{
15+ // min
16+ template<typename genType>
17+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType min(genType x, genType y)
18+ {
19+ static_assert(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || std::numeric_limits<genType>::is_integer, "'min' only accept floating-point or integer inputs");
20+ return (y < x) ? y : x;
21+ }
22+
23+ // max
24+ template<typename genType>
25+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType max(genType x, genType y)
26+ {
27+ static_assert(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || std::numeric_limits<genType>::is_integer, "'max' only accept floating-point or integer inputs");
28+
29+ return (x < y) ? y : x;
30+ }
31+
32+ using ::std::round;
33+
34+ using ::std::trunc;
35+
36+ // abs
37+ template<>
38+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR int abs(int x)
39+ {
40+ int const y = x >> (sizeof(int) * 8 - 1);
41+ return (x ^ y) - y;
42+ }
43+}//namespace glm
44+
45+namespace glm{
46+namespace detail
47+{
48+ template<typename T>
49+ struct TMin {
50+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR T operator()(const T& a, const T& b) { return min(a, b); }
51+ };
52+
53+ template<typename T>
54+ struct TMax {
55+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR T operator()(const T& a, const T& b) { return max(a, b); }
56+ };
57+
58+ template<typename T>
59+ struct TAbs {
60+ T operator()(const T& a) { return abs(a); }
61+ };
62+
63+ template<typename T>
64+ struct TRound {
65+ T operator()(const T& a) { return round(a); }
66+ };
67+
68+ template<typename T>
69+ struct TTrunc {
70+ T operator()(const T& a) { return trunc(a); }
71+ };
72+
73+ template<typename T>
74+ struct TFmod {
75+ T operator()(const T& a, const T& b) { return std::fmod(a, b); }
76+ };
77+
78+ template<length_t L, typename T, qualifier Q, bool Aligned>
79+ struct compute_abs_vector
80+ {
81+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x)
82+ {
83+ return detail::functor1<vec, L, T, T, Q>::call(abs, x);
84+ }
85+ };
86+
87+ template<length_t L, typename T, typename U, qualifier Q, bool Aligned>
88+ struct compute_mix_vector
89+ {
90+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, U, Q> const& a)
91+ {
92+ static_assert(std::numeric_limits<U>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a");
93+
94+ return vec<L, T, Q>(vec<L, U, Q>(x) * (static_cast<U>(1) - a) + vec<L, U, Q>(y) * a);
95+ }
96+ };
97+
98+ template<length_t L, typename T, qualifier Q, bool Aligned>
99+ struct compute_mix_vector<L, T, bool, Q, Aligned>
100+ {
101+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, bool, Q> const& a)
102+ {
103+ vec<L, T, Q> Result(0);
104+ for(length_t i = 0; i < x.length(); ++i)
105+ Result[i] = a[i] ? y[i] : x[i];
106+ return Result;
107+ }
108+ };
109+
110+ template<length_t L, typename T, typename U, qualifier Q, bool Aligned>
111+ struct compute_mix_scalar
112+ {
113+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, U const& a)
114+ {
115+ static_assert(std::numeric_limits<U>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a");
116+
117+ return vec<L, T, Q>(vec<L, U, Q>(x) * (static_cast<U>(1) - a) + vec<L, U, Q>(y) * a);
118+ }
119+ };
120+
121+ template<length_t L, typename T, qualifier Q, bool Aligned>
122+ struct compute_mix_scalar<L, T, bool, Q, Aligned>
123+ {
124+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, bool const& a)
125+ {
126+ return a ? y : x;
127+ }
128+ };
129+
130+ template<typename T, typename U>
131+ struct compute_mix
132+ {
133+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(T const& x, T const& y, U const& a)
134+ {
135+ static_assert(std::numeric_limits<U>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a");
136+
137+ return static_cast<T>(static_cast<U>(x) * (static_cast<U>(1) - a) + static_cast<U>(y) * a);
138+ }
139+ };
140+
141+ template<typename T>
142+ struct compute_mix<T, bool>
143+ {
144+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(T const& x, T const& y, bool const& a)
145+ {
146+ return a ? y : x;
147+ }
148+ };
149+
150+ template<length_t L, typename T, qualifier Q, bool isFloat, bool Aligned>
151+ struct compute_sign
152+ {
153+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x)
154+ {
155+ return vec<L, T, Q>(glm::lessThan(vec<L, T, Q>(0), x)) - vec<L, T, Q>(glm::lessThan(x, vec<L, T, Q>(0)));
156+ }
157+ };
158+
159+# if GLM_ARCH == GLM_ARCH_X86
160+ template<length_t L, typename T, qualifier Q, bool Aligned>
161+ struct compute_sign<L, T, Q, false, Aligned>
162+ {
163+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x)
164+ {
165+ T const Shift(static_cast<T>(sizeof(T) * 8 - 1));
166+ vec<L, T, Q> const y(vec<L, typename std::make_unsigned<T>::type, Q>(-x) >> typename std::make_unsigned<T>::type(Shift));
167+
168+ return (x >> Shift) | y;
169+ }
170+ };
171+# endif
172+
173+ template<length_t L, typename T, qualifier Q, bool Aligned>
174+ struct compute_floor
175+ {
176+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x)
177+ {
178+ return detail::functor1<vec, L, T, T, Q>::call(std::floor, x);
179+ }
180+ };
181+
182+ template<length_t L, typename T, qualifier Q, bool Aligned>
183+ struct compute_ceil
184+ {
185+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x)
186+ {
187+ return detail::functor1<vec, L, T, T, Q>::call(std::ceil, x);
188+ }
189+ };
190+
191+ template<length_t L, typename T, qualifier Q, bool Aligned>
192+ struct compute_fract
193+ {
194+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x)
195+ {
196+ return x - floor(x);
197+ }
198+ };
199+
200+ template<length_t L, typename T, qualifier Q, bool Aligned>
201+ struct compute_trunc
202+ {
203+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x)
204+ {
205+ return detail::functor1<vec, L, T, T, Q>::call(trunc, x);
206+ }
207+ };
208+
209+ template<length_t L, typename T, qualifier Q, bool Aligned>
210+ struct compute_round
211+ {
212+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x)
213+ {
214+ return detail::functor1<vec, L, T, T, Q>::call(round, x);
215+ }
216+ };
217+
218+ template<length_t L, typename T, qualifier Q, bool Aligned>
219+ struct compute_mod
220+ {
221+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
222+ {
223+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'mod' only accept floating-point inputs. Include <glm/gtc/integer.hpp> for integer inputs.");
224+ return a - b * floor(a / b);
225+ }
226+ };
227+
228+ template<length_t L, typename T, qualifier Q, bool Aligned>
229+ struct compute_fma
230+ {
231+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c)
232+ {
233+ return a * b + c;
234+ }
235+ };
236+
237+ template<length_t L, typename T, qualifier Q, bool Aligned>
238+ struct compute_min_vector
239+ {
240+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
241+ {
242+ return detail::functor2<vec, L, T, Q>::call(TMin<T>(), x, y);
243+ }
244+ };
245+
246+ template<length_t L, typename T, qualifier Q, bool Aligned>
247+ struct compute_max_vector
248+ {
249+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
250+ {
251+ return detail::functor2<vec, L, T, Q>::call(TMax<T>(), x, y);
252+ }
253+ };
254+
255+ template<length_t L, typename T, qualifier Q, bool Aligned>
256+ struct compute_clamp_vector
257+ {
258+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& minVal, vec<L, T, Q> const& maxVal)
259+ {
260+ return min(max(x, minVal), maxVal);
261+ }
262+ };
263+
264+ template<length_t L, typename T, qualifier Q, bool Aligned>
265+ struct compute_step_vector
266+ {
267+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& edge, vec<L, T, Q> const& x)
268+ {
269+ return mix(vec<L, T, Q>(1), vec<L, T, Q>(0), glm::lessThan(x, edge));
270+ }
271+ };
272+
273+ template<length_t L, typename T, qualifier Q, bool Aligned>
274+ struct compute_smoothstep_vector
275+ {
276+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& edge0, vec<L, T, Q> const& edge1, vec<L, T, Q> const& x)
277+ {
278+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'smoothstep' only accept floating-point inputs");
279+ vec<L, T, Q> const tmp(clamp((x - edge0) / (edge1 - edge0), static_cast<T>(0), static_cast<T>(1)));
280+ return tmp * tmp * (static_cast<T>(3) - static_cast<T>(2) * tmp);
281+ }
282+ };
283+
284+ template<typename T, qualifier Q, bool Aligned>
285+ struct convert_vec3_to_vec4W0
286+ {
287+ GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<3, T, Q> const& a)
288+ {
289+ return vec<4, T, Q>(a.x, a.y, a.z, 0.0f);
290+ }
291+ };
292+
293+ template<typename T, qualifier Q, bool Aligned>
294+ struct convert_vec3_to_vec4WZ
295+ {
296+ GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<3, T, Q> const& a)
297+ {
298+ return vec<4, T, Q>(a.x, a.y, a.z, a.z);
299+ }
300+ };
301+
302+ template<typename T, qualifier Q, bool Aligned>
303+ struct convert_vec3_to_vec4W1
304+ {
305+ GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<3, T, Q> const& a)
306+ {
307+ return vec<4, T, Q>(a.x, a.y, a.z, 1.0f);
308+ }
309+ };
310+
311+ template<typename T, qualifier Q, bool Aligned>
312+ struct convert_vec4_to_vec3
313+ {
314+ GLM_FUNC_QUALIFIER static vec<3, T, Q> call(vec<4, T, Q> const& a)
315+ {
316+ return vec<3, T, Q>(a.x, a.y, a.z);
317+ }
318+ };
319+
320+ template<length_t L, typename T, qualifier Q, bool Aligned>
321+ struct convert_splat {
322+ template<int c>
323+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& a)
324+ {
325+ vec<L, T, Q> v(T(0));
326+ for (int i = 0; i < L; ++i)
327+ v[i] = a[c];
328+ return v;
329+ }
330+ };
331+
332+
333+}//namespace detail
334+
335+ template<typename genFIType>
336+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR genFIType abs(genFIType x)
337+ {
338+ return detail::compute_abs<genFIType, std::numeric_limits<genFIType>::is_signed>::call(x);
339+ }
340+
341+ template<length_t L, typename T, qualifier Q>
342+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> abs(vec<L, T, Q> const& x)
343+ {
344+ return detail::compute_abs_vector<L, T, Q, detail::is_aligned<Q>::value>::call(x);
345+ }
346+
347+ // sign
348+ // fast and works for any type
349+ template<typename genFIType>
350+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR genFIType sign(genFIType x)
351+ {
352+ static_assert(
353+ std::numeric_limits<genFIType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || (std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer),
354+ "'sign' only accept signed inputs");
355+
356+ return detail::compute_sign<1, genFIType, defaultp,
357+ std::numeric_limits<genFIType>::is_iec559, detail::is_aligned<highp>::value>::call(vec<1, genFIType>(x)).x;
358+ }
359+
360+ template<length_t L, typename T, qualifier Q>
361+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> sign(vec<L, T, Q> const& x)
362+ {
363+ static_assert(
364+ std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || (std::numeric_limits<T>::is_signed && std::numeric_limits<T>::is_integer),
365+ "'sign' only accept signed inputs");
366+
367+ return detail::compute_sign<L, T, Q, std::numeric_limits<T>::is_iec559, detail::is_aligned<Q>::value>::call(x);
368+ }
369+
370+ // floor
371+ using ::std::floor;
372+ template<length_t L, typename T, qualifier Q>
373+ GLM_FUNC_QUALIFIER vec<L, T, Q> floor(vec<L, T, Q> const& x)
374+ {
375+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'floor' only accept floating-point inputs.");
376+ return detail::compute_floor<L, T, Q, detail::is_aligned<Q>::value>::call(x);
377+ }
378+
379+ template<length_t L, typename T, qualifier Q>
380+ GLM_FUNC_QUALIFIER vec<L, T, Q> trunc(vec<L, T, Q> const& x)
381+ {
382+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'trunc' only accept floating-point inputs");
383+ return detail::compute_trunc<L, T, Q, detail::is_aligned<Q>::value>::call(x);
384+ }
385+
386+ template<length_t L, typename T, qualifier Q>
387+ GLM_FUNC_QUALIFIER vec<L, T, Q> round(vec<L, T, Q> const& x)
388+ {
389+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'round' only accept floating-point inputs");
390+ return detail::compute_round<L, T, Q, detail::is_aligned<Q>::value>::call(x);
391+ }
392+
393+/*
394+ // roundEven
395+ template<typename genType>
396+ GLM_FUNC_QUALIFIER genType roundEven(genType const& x)
397+ {
398+ static_assert(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'roundEven' only accept floating-point inputs");
399+ return genType(int(x + genType(int(x) % 2)));
400+ }
401+*/
402+
403+ // roundEven
404+ template<typename genType>
405+ GLM_FUNC_QUALIFIER genType roundEven(genType x)
406+ {
407+ static_assert(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'roundEven' only accept floating-point inputs");
408+
409+ int Integer = static_cast<int>(x);
410+ genType IntegerPart = static_cast<genType>(Integer);
411+ genType FractionalPart = fract(x);
412+
413+ if(FractionalPart > static_cast<genType>(0.5) || FractionalPart < static_cast<genType>(0.5))
414+ {
415+ return round(x);
416+ }
417+ else if((Integer % 2) == 0)
418+ {
419+ return IntegerPart;
420+ }
421+ else if(x <= static_cast<genType>(0)) // Work around...
422+ {
423+ return IntegerPart - static_cast<genType>(1);
424+ }
425+ else
426+ {
427+ return IntegerPart + static_cast<genType>(1);
428+ }
429+ //else // Bug on MinGW 4.5.2
430+ //{
431+ // return mix(IntegerPart + genType(-1), IntegerPart + genType(1), x <= genType(0));
432+ //}
433+ }
434+
435+ template<length_t L, typename T, qualifier Q>
436+ GLM_FUNC_QUALIFIER vec<L, T, Q> roundEven(vec<L, T, Q> const& x)
437+ {
438+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'roundEven' only accept floating-point inputs");
439+ return detail::functor1<vec, L, T, T, Q>::call(roundEven, x);
440+ }
441+
442+ // ceil
443+ using ::std::ceil;
444+ template<length_t L, typename T, qualifier Q>
445+ GLM_FUNC_QUALIFIER vec<L, T, Q> ceil(vec<L, T, Q> const& x)
446+ {
447+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'ceil' only accept floating-point inputs");
448+ return detail::compute_ceil<L, T, Q, detail::is_aligned<Q>::value>::call(x);
449+ }
450+
451+ // fract
452+ template<typename genType>
453+ GLM_FUNC_QUALIFIER genType fract(genType x)
454+ {
455+ return fract(vec<1, genType>(x)).x;
456+ }
457+
458+ template<length_t L, typename T, qualifier Q>
459+ GLM_FUNC_QUALIFIER vec<L, T, Q> fract(vec<L, T, Q> const& x)
460+ {
461+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'fract' only accept floating-point inputs");
462+ return detail::compute_fract<L, T, Q, detail::is_aligned<Q>::value>::call(x);
463+ }
464+
465+ // mod
466+ template<typename genType>
467+ GLM_FUNC_QUALIFIER genType mod(genType x, genType y)
468+ {
469+# if (GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP)
470+ // Another Cuda compiler bug https://github.com/g-truc/glm/issues/530
471+ vec<1, genType, defaultp> Result(mod(vec<1, genType, defaultp>(x), y));
472+ return Result.x;
473+# else
474+ return mod(vec<1, genType, defaultp>(x), y).x;
475+# endif
476+ }
477+
478+ template<length_t L, typename T, qualifier Q>
479+ GLM_FUNC_QUALIFIER vec<L, T, Q> mod(vec<L, T, Q> const& x, T y)
480+ {
481+ return detail::compute_mod<L, T, Q, detail::is_aligned<Q>::value>::call(x, vec<L, T, Q>(y));
482+ }
483+
484+ template<length_t L, typename T, qualifier Q>
485+ GLM_FUNC_QUALIFIER vec<L, T, Q> mod(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
486+ {
487+ return detail::compute_mod<L, T, Q, detail::is_aligned<Q>::value>::call(x, y);
488+ }
489+
490+ template<length_t L, typename T, qualifier Q>
491+ GLM_FUNC_QUALIFIER vec<L, T, Q> fma(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c)
492+ {
493+ return detail::compute_fma<L, T, Q, detail::is_aligned<Q>::value>::call(a, b, c);
494+ }
495+
496+ template<typename T, qualifier Q>
497+ GLM_FUNC_QUALIFIER vec<4, T, Q> xyz0(vec<3, T, Q> const& a)
498+ {
499+ return detail::convert_vec3_to_vec4W0<T, Q, detail::is_aligned<Q>::value>::call(a);
500+ }
501+
502+ template<typename T, qualifier Q>
503+ GLM_FUNC_QUALIFIER vec<4, T, Q> xyz1(vec<3, T, Q> const& a)
504+ {
505+ return detail::convert_vec3_to_vec4W1<T, Q, detail::is_aligned<Q>::value>::call(a);
506+ }
507+
508+ template<typename T, qualifier Q>
509+ GLM_FUNC_QUALIFIER vec<4, T, Q> xyzz(vec<3, T, Q> const& a)
510+ {
511+ return detail::convert_vec3_to_vec4WZ<T, Q, detail::is_aligned<Q>::value>::call(a);
512+ }
513+
514+ template<typename T, qualifier Q>
515+ GLM_FUNC_QUALIFIER vec<3, T, Q> xyz(vec<4, T, Q> const& a)
516+ {
517+ return detail::convert_vec4_to_vec3<T, Q, detail::is_aligned<Q>::value>::call(a);
518+ }
519+
520+ template<length_t L, typename T, qualifier Q>
521+ GLM_FUNC_QUALIFIER vec<L, T, Q> splatX(vec<L, T, Q> const& a)
522+ {
523+ return detail::convert_splat<L, T, Q, detail::is_aligned<Q>::value>::template call<0>(a);
524+ }
525+
526+ template<length_t L, typename T, qualifier Q>
527+ GLM_FUNC_QUALIFIER vec<L, T, Q> splatY(vec<L, T, Q> const& a)
528+ {
529+ return detail::convert_splat<L, T, Q, detail::is_aligned<Q>::value>::template call<1>(a);
530+ }
531+
532+ template<length_t L, typename T, qualifier Q>
533+ GLM_FUNC_QUALIFIER vec<L, T, Q> splatZ(vec<L, T, Q> const& a)
534+ {
535+ return detail::convert_splat<L, T, Q, detail::is_aligned<Q>::value>::template call<2>(a);
536+ }
537+
538+ template<length_t L, typename T, qualifier Q>
539+ GLM_FUNC_QUALIFIER vec<L, T, Q> splatW(vec<L, T, Q> const& a)
540+ {
541+ return detail::convert_splat<L, T, Q, detail::is_aligned<Q>::value>::template call<3>(a);
542+ }
543+
544+
545+ // modf
546+ template<typename genType>
547+ GLM_FUNC_QUALIFIER genType modf(genType x, genType & i)
548+ {
549+ static_assert(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'modf' only accept floating-point inputs");
550+ return std::modf(x, &i);
551+ }
552+
553+ template<typename T, qualifier Q>
554+ GLM_FUNC_QUALIFIER vec<1, T, Q> modf(vec<1, T, Q> const& x, vec<1, T, Q> & i)
555+ {
556+ return vec<1, T, Q>(
557+ modf(x.x, i.x));
558+ }
559+
560+ template<typename T, qualifier Q>
561+ GLM_FUNC_QUALIFIER vec<2, T, Q> modf(vec<2, T, Q> const& x, vec<2, T, Q> & i)
562+ {
563+ return vec<2, T, Q>(
564+ modf(x.x, i.x),
565+ modf(x.y, i.y));
566+ }
567+
568+ template<typename T, qualifier Q>
569+ GLM_FUNC_QUALIFIER vec<3, T, Q> modf(vec<3, T, Q> const& x, vec<3, T, Q> & i)
570+ {
571+ return vec<3, T, Q>(
572+ modf(x.x, i.x),
573+ modf(x.y, i.y),
574+ modf(x.z, i.z));
575+ }
576+
577+ template<typename T, qualifier Q>
578+ GLM_FUNC_QUALIFIER vec<4, T, Q> modf(vec<4, T, Q> const& x, vec<4, T, Q> & i)
579+ {
580+ return vec<4, T, Q>(
581+ modf(x.x, i.x),
582+ modf(x.y, i.y),
583+ modf(x.z, i.z),
584+ modf(x.w, i.w));
585+ }
586+
587+ //// Only valid if (INT_MIN <= x-y <= INT_MAX)
588+ //// min(x,y)
589+ //r = y + ((x - y) & ((x - y) >> (sizeof(int) *
590+ //CHAR_BIT - 1)));
591+ //// max(x,y)
592+ //r = x - ((x - y) & ((x - y) >> (sizeof(int) *
593+ //CHAR_BIT - 1)));
594+
595+ // min
596+ template<length_t L, typename T, qualifier Q>
597+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> min(vec<L, T, Q> const& a, T b)
598+ {
599+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || std::numeric_limits<T>::is_integer, "'min' only accept floating-point or integer inputs");
600+ return detail::compute_min_vector<L, T, Q, detail::is_aligned<Q>::value>::call(a, vec<L, T, Q>(b));
601+ }
602+
603+ template<length_t L, typename T, qualifier Q>
604+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> min(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
605+ {
606+ return detail::compute_min_vector<L, T, Q, detail::is_aligned<Q>::value>::call(a, b);
607+ }
608+
609+ // max
610+ template<length_t L, typename T, qualifier Q>
611+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> max(vec<L, T, Q> const& a, T b)
612+ {
613+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || std::numeric_limits<T>::is_integer, "'max' only accept floating-point or integer inputs");
614+ return detail::compute_max_vector<L, T, Q, detail::is_aligned<Q>::value>::call(a, vec<L, T, Q>(b));
615+ }
616+
617+ template<length_t L, typename T, qualifier Q>
618+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> max(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
619+ {
620+ return detail::compute_max_vector<L, T, Q, detail::is_aligned<Q>::value>::call(a, b);
621+ }
622+
623+ // clamp
624+ template<typename genType>
625+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType clamp(genType x, genType minVal, genType maxVal)
626+ {
627+ static_assert(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || std::numeric_limits<genType>::is_integer, "'clamp' only accept floating-point or integer inputs");
628+ return min(max(x, minVal), maxVal);
629+ }
630+
631+ template<length_t L, typename T, qualifier Q>
632+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> clamp(vec<L, T, Q> const& x, T minVal, T maxVal)
633+ {
634+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || std::numeric_limits<T>::is_integer, "'clamp' only accept floating-point or integer inputs");
635+ return detail::compute_clamp_vector<L, T, Q, detail::is_aligned<Q>::value>::call(x, vec<L, T, Q>(minVal), vec<L, T, Q>(maxVal));
636+ }
637+
638+ template<length_t L, typename T, qualifier Q>
639+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> clamp(vec<L, T, Q> const& x, vec<L, T, Q> const& minVal, vec<L, T, Q> const& maxVal)
640+ {
641+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || std::numeric_limits<T>::is_integer, "'clamp' only accept floating-point or integer inputs");
642+ return detail::compute_clamp_vector<L, T, Q, detail::is_aligned<Q>::value>::call(x, minVal, maxVal);
643+ }
644+
645+ template<typename genTypeT, typename genTypeU>
646+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR genTypeT mix(genTypeT x, genTypeT y, genTypeU a)
647+ {
648+ return detail::compute_mix<genTypeT, genTypeU>::call(x, y, a);
649+ }
650+
651+ template<length_t L, typename T, typename U, qualifier Q>
652+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> mix(vec<L, T, Q> const& x, vec<L, T, Q> const& y, U a)
653+ {
654+ return detail::compute_mix_scalar<L, T, U, Q, detail::is_aligned<Q>::value>::call(x, y, a);
655+ }
656+
657+ template<length_t L, typename T, typename U, qualifier Q>
658+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> mix(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, U, Q> const& a)
659+ {
660+ return detail::compute_mix_vector<L, T, U, Q, detail::is_aligned<Q>::value>::call(x, y, a);
661+ }
662+
663+ // step
664+ template<typename genType>
665+ GLM_FUNC_QUALIFIER genType step(genType edge, genType x)
666+ {
667+ return mix(static_cast<genType>(1), static_cast<genType>(0), x < edge);
668+ }
669+
670+ template<length_t L, typename T, qualifier Q>
671+ GLM_FUNC_QUALIFIER vec<L, T, Q> step(T edge, vec<L, T, Q> const& x)
672+ {
673+ return detail::compute_step_vector<L, T, Q, detail::is_aligned<Q>::value>::call(vec<L, T, Q>(edge), x);
674+ }
675+
676+ template<length_t L, typename T, qualifier Q>
677+ GLM_FUNC_QUALIFIER vec<L, T, Q> step(vec<L, T, Q> const& edge, vec<L, T, Q> const& x)
678+ {
679+ return detail::compute_step_vector<L, T, Q, detail::is_aligned<Q>::value>::call(edge, x);
680+ }
681+
682+ // smoothstep
683+ template<typename genType>
684+ GLM_FUNC_QUALIFIER genType smoothstep(genType edge0, genType edge1, genType x)
685+ {
686+ static_assert(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'smoothstep' only accept floating-point inputs");
687+
688+ genType const tmp(clamp((x - edge0) / (edge1 - edge0), genType(0), genType(1)));
689+ return tmp * tmp * (genType(3) - genType(2) * tmp);
690+ }
691+
692+ template<length_t L, typename T, qualifier Q>
693+ GLM_FUNC_QUALIFIER vec<L, T, Q> smoothstep(T edge0, T edge1, vec<L, T, Q> const& x)
694+ {
695+ return detail::compute_smoothstep_vector<L, T, Q, detail::is_aligned<Q>::value>::call(vec<L, T, Q>(edge0), vec<L, T, Q>(edge1), x);
696+ }
697+
698+ template<length_t L, typename T, qualifier Q>
699+ GLM_FUNC_QUALIFIER vec<L, T, Q> smoothstep(vec<L, T, Q> const& edge0, vec<L, T, Q> const& edge1, vec<L, T, Q> const& x)
700+ {
701+ return detail::compute_smoothstep_vector<L, T, Q, detail::is_aligned<Q>::value>::call(edge0, edge1, x);
702+ }
703+
704+ using std::isnan;
705+
706+ template<length_t L, typename T, qualifier Q>
707+ GLM_FUNC_QUALIFIER vec<L, bool, Q> isnan(vec<L, T, Q> const& v)
708+ {
709+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'isnan' only accept floating-point inputs");
710+
711+ vec<L, bool, Q> Result(0);
712+ for (length_t l = 0; l < v.length(); ++l)
713+ Result[l] = glm::isnan(v[l]);
714+ return Result;
715+ }
716+
717+ using std::isinf;
718+
719+ template<length_t L, typename T, qualifier Q>
720+ GLM_FUNC_QUALIFIER vec<L, bool, Q> isinf(vec<L, T, Q> const& v)
721+ {
722+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'isinf' only accept floating-point inputs");
723+
724+ vec<L, bool, Q> Result(0);
725+ for (length_t l = 0; l < v.length(); ++l)
726+ Result[l] = glm::isinf(v[l]);
727+ return Result;
728+ }
729+
730+ GLM_FUNC_QUALIFIER int floatBitsToInt(float v)
731+ {
732+ union
733+ {
734+ float in;
735+ int out;
736+ } u;
737+
738+ u.in = v;
739+
740+ return u.out;
741+ }
742+
743+ template<length_t L, qualifier Q>
744+ GLM_FUNC_QUALIFIER vec<L, int, Q> floatBitsToInt(vec<L, float, Q> const& v)
745+ {
746+ return detail::functor1<vec, L, int, float, Q>::call(floatBitsToInt, v);
747+ }
748+
749+ GLM_FUNC_QUALIFIER uint floatBitsToUint(float v)
750+ {
751+ union
752+ {
753+ float in;
754+ uint out;
755+ } u;
756+
757+ u.in = v;
758+
759+ return u.out;
760+ }
761+
762+ template<length_t L, qualifier Q>
763+ GLM_FUNC_QUALIFIER vec<L, uint, Q> floatBitsToUint(vec<L, float, Q> const& v)
764+ {
765+ return detail::functor1<vec, L, uint, float, Q>::call(floatBitsToUint, v);
766+ }
767+
768+ GLM_FUNC_QUALIFIER float intBitsToFloat(int v)
769+ {
770+ union
771+ {
772+ int in;
773+ float out;
774+ } u;
775+
776+ u.in = v;
777+
778+ return u.out;
779+ }
780+
781+ template<length_t L, qualifier Q>
782+ GLM_FUNC_QUALIFIER vec<L, float, Q> intBitsToFloat(vec<L, int, Q> const& v)
783+ {
784+ return detail::functor1<vec, L, float, int, Q>::call(intBitsToFloat, v);
785+ }
786+
787+ GLM_FUNC_QUALIFIER float uintBitsToFloat(uint v)
788+ {
789+ union
790+ {
791+ uint in;
792+ float out;
793+ } u;
794+
795+ u.in = v;
796+
797+ return u.out;
798+ }
799+
800+ template<length_t L, qualifier Q>
801+ GLM_FUNC_QUALIFIER vec<L, float, Q> uintBitsToFloat(vec<L, uint, Q> const& v)
802+ {
803+ return reinterpret_cast<vec<L, float, Q>&>(const_cast<vec<L, uint, Q>&>(v));
804+ }
805+
806+ using std::fma;
807+
808+ template<typename genType>
809+ GLM_FUNC_QUALIFIER genType frexp(genType x, int& exp)
810+ {
811+ static_assert(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'frexp' only accept floating-point inputs");
812+
813+ return std::frexp(x, &exp);
814+ }
815+
816+ template<length_t L, typename T, qualifier Q>
817+ GLM_FUNC_QUALIFIER vec<L, T, Q> frexp(vec<L, T, Q> const& v, vec<L, int, Q>& exp)
818+ {
819+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'frexp' only accept floating-point inputs");
820+
821+ vec<L, T, Q> Result(0);
822+ for (length_t l = 0; l < v.length(); ++l)
823+ Result[l] = std::frexp(v[l], &exp[l]);
824+ return Result;
825+ }
826+
827+ template<typename genType>
828+ GLM_FUNC_QUALIFIER genType ldexp(genType const& x, int const& exp)
829+ {
830+ static_assert(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'ldexp' only accept floating-point inputs");
831+
832+ return std::ldexp(x, exp);
833+ }
834+
835+ template<length_t L, typename T, qualifier Q>
836+ GLM_FUNC_QUALIFIER vec<L, T, Q> ldexp(vec<L, T, Q> const& v, vec<L, int, Q> const& exp)
837+ {
838+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'ldexp' only accept floating-point inputs");
839+
840+ vec<L, T, Q> Result(0);
841+ for (length_t l = 0; l < v.length(); ++l)
842+ Result[l] = std::ldexp(v[l], exp[l]);
843+ return Result;
844+ }
845+}//namespace glm
846+
847+#if GLM_CONFIG_SIMD == GLM_ENABLE
848+# include "func_common_simd.inl"
849+#endif
@@ -0,0 +1,616 @@
1+/// @ref core
2+/// @file glm/detail/func_common_simd.inl
3+
4+#if GLM_ARCH & GLM_ARCH_SSE2_BIT
5+
6+#include "../simd/common.h"
7+
8+#include <immintrin.h>
9+
10+namespace glm{
11+namespace detail
12+{
13+ template<qualifier Q>
14+ struct compute_abs_vector<4, float, Q, true>
15+ {
16+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v)
17+ {
18+ vec<4, float, Q> result;
19+ result.data = glm_vec4_abs(v.data);
20+ return result;
21+ }
22+ };
23+
24+ template<qualifier Q>
25+ struct compute_abs_vector<4, int, Q, true>
26+ {
27+ GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& v)
28+ {
29+ vec<4, int, Q> result;
30+ result.data = glm_ivec4_abs(v.data);
31+ return result;
32+ }
33+ };
34+
35+ template<qualifier Q>
36+ struct compute_floor<4, float, Q, true>
37+ {
38+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v)
39+ {
40+ vec<4, float, Q> result;
41+ result.data = glm_vec4_floor(v.data);
42+ return result;
43+ }
44+ };
45+
46+ template<qualifier Q>
47+ struct compute_ceil<4, float, Q, true>
48+ {
49+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v)
50+ {
51+ vec<4, float, Q> result;
52+ result.data = glm_vec4_ceil(v.data);
53+ return result;
54+ }
55+ };
56+
57+ template<qualifier Q>
58+ struct compute_fract<4, float, Q, true>
59+ {
60+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v)
61+ {
62+ vec<4, float, Q> result;
63+ result.data = glm_vec4_fract(v.data);
64+ return result;
65+ }
66+ };
67+
68+ template<qualifier Q>
69+ struct compute_round<4, float, Q, true>
70+ {
71+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v)
72+ {
73+ vec<4, float, Q> result;
74+ result.data = glm_vec4_round(v.data);
75+ return result;
76+ }
77+ };
78+
79+ template<qualifier Q>
80+ struct compute_mod<4, float, Q, true>
81+ {
82+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& x, vec<4, float, Q> const& y)
83+ {
84+ vec<4, float, Q> result;
85+ result.data = glm_vec4_mod(x.data, y.data);
86+ return result;
87+ }
88+ };
89+
90+ template<qualifier Q>
91+ struct compute_min_vector<4, float, Q, true>
92+ {
93+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2)
94+ {
95+ vec<4, float, Q> result;
96+ result.data = _mm_min_ps(v1.data, v2.data);
97+ return result;
98+ }
99+ };
100+
101+ template<qualifier Q>
102+ struct compute_min_vector<4, int, Q, true>
103+ {
104+ GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2)
105+ {
106+ vec<4, int, Q> result;
107+ result.data = _mm_min_epi32(v1.data, v2.data);
108+ return result;
109+ }
110+ };
111+
112+ template<qualifier Q>
113+ struct compute_min_vector<4, uint, Q, true>
114+ {
115+ GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2)
116+ {
117+ vec<4, uint, Q> result;
118+ result.data = _mm_min_epu32(v1.data, v2.data);
119+ return result;
120+ }
121+ };
122+
123+ template<qualifier Q>
124+ struct compute_max_vector<4, float, Q, true>
125+ {
126+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2)
127+ {
128+ vec<4, float, Q> result;
129+ result.data = _mm_max_ps(v1.data, v2.data);
130+ return result;
131+ }
132+ };
133+
134+ template<qualifier Q>
135+ struct compute_max_vector<4, int, Q, true>
136+ {
137+ GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2)
138+ {
139+ vec<4, int, Q> result;
140+ result.data = _mm_max_epi32(v1.data, v2.data);
141+ return result;
142+ }
143+ };
144+
145+ template<qualifier Q>
146+ struct compute_max_vector<4, uint, Q, true>
147+ {
148+ GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2)
149+ {
150+ vec<4, uint, Q> result;
151+ result.data = _mm_max_epu32(v1.data, v2.data);
152+ return result;
153+ }
154+ };
155+
156+ template<qualifier Q>
157+ struct compute_clamp_vector<4, float, Q, true>
158+ {
159+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& x, vec<4, float, Q> const& minVal, vec<4, float, Q> const& maxVal)
160+ {
161+ vec<4, float, Q> result;
162+ result.data = _mm_min_ps(_mm_max_ps(x.data, minVal.data), maxVal.data);
163+ return result;
164+ }
165+ };
166+
167+ template<qualifier Q>
168+ struct compute_clamp_vector<4, int, Q, true>
169+ {
170+ GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& x, vec<4, int, Q> const& minVal, vec<4, int, Q> const& maxVal)
171+ {
172+ vec<4, int, Q> result;
173+ result.data = _mm_min_epi32(_mm_max_epi32(x.data, minVal.data), maxVal.data);
174+ return result;
175+ }
176+ };
177+
178+ template<qualifier Q>
179+ struct compute_clamp_vector<4, uint, Q, true>
180+ {
181+ GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& x, vec<4, uint, Q> const& minVal, vec<4, uint, Q> const& maxVal)
182+ {
183+ vec<4, uint, Q> result;
184+ result.data = _mm_min_epu32(_mm_max_epu32(x.data, minVal.data), maxVal.data);
185+ return result;
186+ }
187+ };
188+
189+ template<qualifier Q>
190+ struct compute_mix_vector<4, float, bool, Q, true>
191+ {
192+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& x, vec<4, float, Q> const& y, vec<4, bool, Q> const& a)
193+ {
194+ __m128i const Load = _mm_set_epi32(-static_cast<int>(a.w), -static_cast<int>(a.z), -static_cast<int>(a.y), -static_cast<int>(a.x));
195+ __m128 const Mask = _mm_castsi128_ps(Load);
196+
197+ vec<4, float, Q> Result;
198+# if 0 && GLM_ARCH & GLM_ARCH_AVX
199+ Result.data = _mm_blendv_ps(x.data, y.data, Mask);
200+# else
201+ Result.data = _mm_or_ps(_mm_and_ps(Mask, y.data), _mm_andnot_ps(Mask, x.data));
202+# endif
203+ return Result;
204+ }
205+ };
206+/* FIXME
207+ template<qualifier Q>
208+ struct compute_step_vector<float, Q, tvec4>
209+ {
210+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& edge, vec<4, float, Q> const& x)
211+ {
212+ vec<4, float, Q> Result;
213+ result.data = glm_vec4_step(edge.data, x.data);
214+ return result;
215+ }
216+ };
217+*/
218+ template<qualifier Q>
219+ struct compute_smoothstep_vector<4, float, Q, true>
220+ {
221+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& edge0, vec<4, float, Q> const& edge1, vec<4, float, Q> const& x)
222+ {
223+ vec<4, float, Q> Result;
224+ Result.data = glm_vec4_smoothstep(edge0.data, edge1.data, x.data);
225+ return Result;
226+ }
227+ };
228+
229+ template<qualifier Q>
230+ struct compute_fma<4, float, Q, true>
231+ {
232+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b, vec<4, float, Q> const& c)
233+ {
234+ vec<4, float, Q> Result;
235+ Result.data = glm_vec4_fma(a.data, b.data, c.data);
236+ return Result;
237+ }
238+ };
239+
240+ template<qualifier Q>
241+ struct compute_fma<3, float, Q, true>
242+ {
243+ GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<3, float, Q> const& a, vec<3, float, Q> const& b, vec<3, float, Q> const& c)
244+ {
245+ vec<3, float, Q> Result;
246+ Result.data = glm_vec4_fma(a.data, b.data, c.data);
247+ return Result;
248+ }
249+ };
250+
251+
252+ template<qualifier Q>
253+ struct compute_fma<4, double, Q, true>
254+ {
255+ GLM_FUNC_QUALIFIER static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b, vec<4, double, Q> const& c)
256+ {
257+ vec<4, double, Q> Result;
258+# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) && !(GLM_COMPILER & GLM_COMPILER_CLANG)
259+ Result.data = _mm256_fmadd_pd(a.data, b.data, c.data);
260+# elif (GLM_ARCH & GLM_ARCH_AVX_BIT)
261+ Result.data = _mm256_add_pd(_mm256_mul_pd(a.data, b.data), c.data);
262+# else
263+ Result.data.setv(0, _mm_add_pd(_mm_mul_pd(a.data.getv(0), b.data.getv(0)), c.data.getv(0)));
264+ Result.data.setv(1, _mm_add_pd(_mm_mul_pd(a.data.getv(1), b.data.getv(1)), c.data.getv(1)));
265+# endif
266+ return Result;
267+ }
268+ };
269+
270+ // copy vec3 to vec4 and set w to 0
271+ template<qualifier Q>
272+ struct convert_vec3_to_vec4W0<float, Q, true>
273+ {
274+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<3, float, Q> const& a)
275+ {
276+ vec<4, float, Q> v;
277+#if (GLM_ARCH & GLM_ARCH_SSE41_BIT)
278+ v.data = _mm_blend_ps(a.data, _mm_setzero_ps(), 8);
279+#else
280+ __m128i mask = _mm_set_epi32(0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
281+ __m128 v0 = _mm_castsi128_ps(_mm_and_si128(_mm_castps_si128(a.data), mask));
282+ v.data = v0;
283+#endif
284+ return v;
285+ }
286+ };
287+
288+ // copy vec3 to vec4 and set w to 1
289+ template<qualifier Q>
290+ struct convert_vec3_to_vec4W1<float, Q, true>
291+ {
292+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<3, float, Q> const& a)
293+ {
294+ vec<4, float, Q> v;
295+#if (GLM_ARCH & GLM_ARCH_SSE41_BIT)
296+ v.data = _mm_blend_ps(a.data, _mm_set1_ps(1.0f), 8);
297+#else
298+ __m128 t1 = _mm_shuffle_ps(a.data, a.data, _MM_SHUFFLE(0, 2, 1, 3)); //permute x, w
299+ __m128 t2 = _mm_move_ss(t1, _mm_set_ss(1.0f)); // set x to 1.0f
300+ v.data = _mm_shuffle_ps(t2, t2, _MM_SHUFFLE(0, 2, 1, 3)); //permute x, w
301+#endif
302+ return v;
303+ }
304+ };
305+
306+ // copy vec3 to vec4 and set w to vec3.z
307+ template<qualifier Q>
308+ struct convert_vec3_to_vec4WZ<float, Q, true>
309+ {
310+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<3, float, Q> const& a)
311+ {
312+ vec<4, float, Q> v;
313+ v.data = _mm_shuffle_ps(a.data, a.data, _MM_SHUFFLE(2, 2, 1, 0));
314+ return v;
315+ }
316+ };
317+
318+ // copy vec3 to vec4 and set w to 0
319+ template<qualifier Q>
320+ struct convert_vec3_to_vec4W0<double, Q, true>
321+ {
322+ GLM_FUNC_QUALIFIER static vec<4, double, Q> call(vec<3, double, Q> const& a)
323+ {
324+ vec<4, double, Q> v;
325+#if (GLM_ARCH & GLM_ARCH_AVX_BIT)
326+ v.data = _mm256_blend_pd(a.data, _mm256_setzero_pd(), 8);
327+#else
328+ v.data.setv(0, a.data.getv(0));
329+ glm_dvec2 av2 = a.data.getv(1);
330+ av2 = _mm_shuffle_pd(av2, _mm_setzero_pd(), 2);
331+ v.data.setv(1, av2);
332+#endif
333+ return v;
334+ }
335+ };
336+
337+ // copy vec3 to vec4 and set w to vec3.z
338+ template<qualifier Q>
339+ struct convert_vec3_to_vec4WZ<double, Q, true>
340+ {
341+ GLM_FUNC_QUALIFIER static vec<4, double, Q> call(vec<3, double, Q> const& a)
342+ {
343+ vec<4, double, Q> v;
344+#if (GLM_ARCH & GLM_ARCH_AVX_BIT)
345+ v.data = _mm256_permute_pd(a.data, 2);
346+#else
347+ v.data.setv(0, a.data.getv(0));
348+ glm_dvec2 av2 = a.data.getv(1);
349+ __m128d t1 = _mm_shuffle_pd(av2, av2, 0);
350+ v.data.setv(1, t1);
351+#endif
352+ return v;
353+ }
354+ };
355+
356+ // copy vec3 to vec4 and set w to 1
357+ template<qualifier Q>
358+ struct convert_vec3_to_vec4W1<double, Q, true>
359+ {
360+ GLM_FUNC_QUALIFIER static vec<4, double, Q> call(vec<3, double, Q> const& a)
361+ {
362+ vec<4, double, Q> v;
363+#if (GLM_ARCH & GLM_ARCH_AVX_BIT)
364+ v.data = _mm256_blend_pd(a.data, _mm256_set1_pd(1.0), 8);
365+#else
366+ v.data.setv(0, a.data.getv(0));
367+ glm_dvec2 av2 = a.data.getv(1);
368+ av2 = _mm_shuffle_pd(av2, _mm_set1_pd(1.), 2);
369+ v.data.setv(1, av2);
370+#endif
371+ return v;
372+ }
373+ };
374+
375+ template<qualifier Q>
376+ struct convert_vec4_to_vec3<float, Q, true> {
377+ GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<4, float, Q> const& a)
378+ {
379+ vec<3, float, Q> v;
380+ v.data = a.data;
381+ return v;
382+ }
383+ };
384+
385+ template<qualifier Q>
386+ struct convert_vec4_to_vec3<double, Q, true> {
387+ GLM_FUNC_QUALIFIER static vec<3, double, Q> call(vec<4, double, Q> const& a)
388+ {
389+ vec<3, double, Q> v;
390+#if GLM_ARCH & GLM_ARCH_AVX_BIT
391+ v.data = a.data;
392+#else
393+ v.data.setv(0, a.data.getv(0));
394+ v.data.setv(1, a.data.getv(1));
395+#endif
396+ return v;
397+ }
398+ };
399+
400+
401+ // set all coordinates to same value vec[c]
402+ template<length_t L, qualifier Q>
403+ struct convert_splat<L, float, Q, true> {
404+ template<int c>
405+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, float, Q> call(vec<L, float, Q> const& a)
406+ {
407+ vec<L, float, Q> Result;
408+ const int s = _MM_SHUFFLE(c, c, c, c);
409+ glm_f32vec4 va = static_cast<glm_f32vec4>(a.data);
410+# if GLM_ARCH & GLM_ARCH_AVX_BIT
411+ Result.data = _mm_permute_ps(va, s);
412+# else
413+ Result.data = _mm_shuffle_ps(va, va, s);
414+# endif
415+ return Result;
416+ }
417+ };
418+
419+ // set all coordinates to same value vec[c]
420+ template<length_t L, qualifier Q>
421+ struct convert_splat<L, double, Q, true> {
422+
423+ template<bool, int c>
424+ struct detailSSE
425+ {};
426+
427+ template<int c>
428+ struct detailSSE<true, c>
429+ {
430+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, double, Q> call(vec<L, double, Q> const& a)
431+ {
432+ vec<L, double, Q> Result;
433+ glm_f64vec2 r0 = _mm_shuffle_pd(a.data.getv(0), a.data.getv(0), c | c << 1);
434+ Result.data.setv(0, r0);
435+ Result.data.setv(1, r0);
436+ return Result;
437+ }
438+ };
439+
440+ template<int c>
441+ struct detailSSE<false, c>
442+ {
443+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, double, Q> call(vec<L, double, Q> const& a)
444+ {
445+ vec<L, double, Q> Result;
446+ const unsigned int d = static_cast<unsigned int>(c - 2);
447+ glm_f64vec2 r0 = _mm_shuffle_pd(a.data.getv(1), a.data.getv(1), d | d << 1);
448+ Result.data.setv(0, r0);
449+ Result.data.setv(1, r0);
450+ return Result;
451+ }
452+ };
453+
454+#if GLM_ARCH & GLM_ARCH_AVX_BIT
455+ template<bool, int c> //note: bool is useless but needed to compil on linux (gcc)
456+ struct detailAVX
457+ {};
458+
459+ template<bool b>
460+ struct detailAVX<b, 0>
461+ {
462+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, double, Q> call(vec<L, double, Q> const& a)
463+ {
464+ vec<L, double, Q> Result;
465+ __m256d t1 = _mm256_permute2f128_pd(a.data, a.data, 0x0);
466+ Result.data = _mm256_permute_pd(t1, 0);
467+ return Result;
468+ }
469+ };
470+
471+ template<bool b>
472+ struct detailAVX<b, 1>
473+ {
474+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, double, Q> call(vec<L, double, Q> const& a)
475+ {
476+ vec<L, double, Q> Result;
477+ __m256d t1 = _mm256_permute2f128_pd(a.data, a.data, 0x0);
478+ Result.data = _mm256_permute_pd(t1, 0xf);
479+ return Result;
480+ }
481+ };
482+
483+ template<bool b>
484+ struct detailAVX<b, 2>
485+ {
486+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, double, Q> call(vec<L, double, Q> const& a)
487+ {
488+ vec<L, double, Q> Result;
489+ __m256d t2 = _mm256_permute2f128_pd(a.data, a.data, 0x11);
490+ Result.data = _mm256_permute_pd(t2, 0x0);
491+ return Result;
492+ }
493+ };
494+
495+ template<bool b>
496+ struct detailAVX<b, 3>
497+ {
498+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, double, Q> call(vec<L, double, Q> const& a)
499+ {
500+ vec<L, double, Q> Result;
501+ __m256d t2 = _mm256_permute2f128_pd(a.data, a.data, 0x11);
502+ Result.data = _mm256_permute_pd(t2, 0xf);
503+ return Result;
504+ }
505+ };
506+#endif //GLM_ARCH & GLM_ARCH_AVX_BIT
507+
508+ template<int c>
509+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, double, Q> call(vec<L, double, Q> const& a)
510+ {
511+ //return compute_splat<L, double, Q, false>::call<c>(a);
512+ vec<L, double, Q> Result;
513+# if GLM_ARCH & GLM_ARCH_AVX2_BIT
514+ Result.data = _mm256_permute4x64_pd(a.data, _MM_SHUFFLE(c, c, c, c));
515+# elif GLM_ARCH & GLM_ARCH_AVX_BIT
516+ Result = detailAVX<true, c>::call(a);
517+# else
518+#if 1 //detail<(c <= 1), c>::call2(a) is equivalent to following code but without if constexpr usage
519+ Result = detailSSE<(c <= 1), c>::call(a);
520+#else
521+ if constexpr (c <= 1)
522+ {
523+ glm_f64vec2 r0 = _mm_shuffle_pd(a.data.getv(0), a.data.getv(0), c | c << 1);
524+ Result.data.setv(0, r0);
525+ Result.data.setv(1, r0);
526+ }
527+ else
528+ {
529+ const unsigned int d = (unsigned int)(c - 2);
530+ glm_f64vec2 r0 = _mm_shuffle_pd(a.data.getv(1), a.data.getv(1), d | d << 1);
531+ Result.data.setv(0, r0);
532+ Result.data.setv(1, r0);
533+ }
534+#endif
535+# endif
536+ return Result;
537+ }
538+ };
539+
540+
541+}//namespace detail
542+}//namespace glm
543+
544+#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT
545+
546+#if GLM_ARCH & GLM_ARCH_NEON_BIT
547+namespace glm {
548+namespace detail {
549+/* FIXME: Breaking Windows ARM Github C.I.
550+ template<qualifier Q>
551+ struct convert_vec3_to_vec4W0<float, Q, true>
552+ {
553+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<3, float, Q> const& a)
554+ {
555+ vec<4, float, Q> v;
556+ static const uint32x4_t mask = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0 };
557+ v.data = vbslq_f32(mask, a.data, vdupq_n_f32(0));
558+ return v;
559+ }
560+ };
561+*/
562+ template<qualifier Q>
563+ struct convert_vec4_to_vec3<float, Q, true> {
564+ GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<4, float, Q> const& a)
565+ {
566+ vec<3, float, Q> v;
567+ v.data = a.data;
568+ return v;
569+ }
570+ };
571+
572+/* compute_splat is never called?
573+ template<length_t L, qualifier Q>
574+ struct compute_splat<L, float, Q, true> {
575+ template<int c>
576+ GLM_FUNC_QUALIFIER static vec<L, float, Q> call(vec<L, float, Q> const& a)
577+ {
578+ (void)a;
579+ }
580+
581+ template<>
582+ GLM_FUNC_QUALIFIER static vec<L, float, Q> call<0>(vec<L, float, Q> const& a)
583+ {
584+ vec<L, float, Q> Result;
585+ Result.data = vdupq_lane_f32(vget_low_f32(a.data), 0);
586+ return Result;
587+ }
588+
589+ template<>
590+ GLM_FUNC_QUALIFIER static vec<L, float, Q> call<1>(vec<L, float, Q> const& a)
591+ {
592+ vec<L, float, Q> Result;
593+ Result.data = vdupq_lane_f32(vget_low_f32(a.data), 1);
594+ return Result;
595+ }
596+
597+ template<>
598+ GLM_FUNC_QUALIFIER static vec<L, float, Q> call<2>(vec<L, float, Q> const& a)
599+ {
600+ vec<L, float, Q> Result;
601+ Result.data = vdupq_lane_f32(vget_high_f32(a.data), 0);
602+ return Result;
603+ }
604+
605+ template<>
606+ GLM_FUNC_QUALIFIER static vec<L, float, Q> call<3>(vec<L, float, Q> const& a)
607+ {
608+ vec<L, float, Q> Result;
609+ Result.data = vdupq_lane_f32(vget_high_f32(a.data), 1);
610+ return Result;
611+ }
612+ };
613+*/
614+}//namespace detail
615+}//namespace glm
616+#endif //GLM_ARCH & GLM_ARCH_NEON_BIT
@@ -0,0 +1,133 @@
1+/// @ref core
2+/// @file glm/detail/func_exponential.inl
3+
4+#include "../vector_relational.hpp"
5+#include "_vectorize.hpp"
6+#include <limits>
7+#include <cmath>
8+#include <cassert>
9+
10+namespace glm{
11+namespace detail
12+{
13+ using std::log2;
14+
15+ template<length_t L, typename T, qualifier Q, bool isFloat, bool Aligned>
16+ struct compute_log2
17+ {
18+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& v)
19+ {
20+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'log2' only accept floating-point inputs. Include <glm/gtc/integer.hpp> for integer inputs.");
21+
22+ return detail::functor1<vec, L, T, T, Q>::call(log2, v);
23+ }
24+ };
25+
26+ template<length_t L, typename T, qualifier Q, bool Aligned>
27+ struct compute_sqrt
28+ {
29+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x)
30+ {
31+ return detail::functor1<vec, L, T, T, Q>::call(std::sqrt, x);
32+ }
33+ };
34+
35+ template<length_t L, typename T, qualifier Q, bool Aligned>
36+ struct compute_inversesqrt
37+ {
38+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x)
39+ {
40+ return static_cast<T>(1) / sqrt(x);
41+ }
42+ };
43+
44+ template<length_t L, bool Aligned>
45+ struct compute_inversesqrt<L, float, lowp, Aligned>
46+ {
47+ GLM_FUNC_QUALIFIER static vec<L, float, lowp> call(vec<L, float, lowp> const& x)
48+ {
49+ vec<L, float, lowp> tmp(x);
50+ vec<L, float, lowp> xhalf(tmp * 0.5f);
51+ vec<L, uint, lowp>* p = reinterpret_cast<vec<L, uint, lowp>*>(const_cast<vec<L, float, lowp>*>(&x));
52+ vec<L, uint, lowp> i = vec<L, uint, lowp>(0x5f375a86) - (*p >> vec<L, uint, lowp>(1));
53+ vec<L, float, lowp>* ptmp = reinterpret_cast<vec<L, float, lowp>*>(&i);
54+ tmp = *ptmp;
55+ tmp = tmp * (1.5f - xhalf * tmp * tmp);
56+ return tmp;
57+ }
58+ };
59+}//namespace detail
60+
61+ // pow
62+ using std::pow;
63+ template<length_t L, typename T, qualifier Q>
64+ GLM_FUNC_QUALIFIER vec<L, T, Q> pow(vec<L, T, Q> const& base, vec<L, T, Q> const& exponent)
65+ {
66+ return detail::functor2<vec, L, T, Q>::call(pow, base, exponent);
67+ }
68+
69+ // exp
70+ using std::exp;
71+ template<length_t L, typename T, qualifier Q>
72+ GLM_FUNC_QUALIFIER vec<L, T, Q> exp(vec<L, T, Q> const& x)
73+ {
74+ return detail::functor1<vec, L, T, T, Q>::call(exp, x);
75+ }
76+
77+ // log
78+ using std::log;
79+ template<length_t L, typename T, qualifier Q>
80+ GLM_FUNC_QUALIFIER vec<L, T, Q> log(vec<L, T, Q> const& x)
81+ {
82+ return detail::functor1<vec, L, T, T, Q>::call(log, x);
83+ }
84+
85+ using std::exp2;
86+
87+ template<length_t L, typename T, qualifier Q>
88+ GLM_FUNC_QUALIFIER vec<L, T, Q> exp2(vec<L, T, Q> const& x)
89+ {
90+ return detail::functor1<vec, L, T, T, Q>::call(exp2, x);
91+ }
92+
93+ // log2, ln2 = 0.69314718055994530941723212145818f
94+ template<typename genType>
95+ GLM_FUNC_QUALIFIER genType log2(genType x)
96+ {
97+ return log2(vec<1, genType>(x)).x;
98+ }
99+
100+ template<length_t L, typename T, qualifier Q>
101+ GLM_FUNC_QUALIFIER vec<L, T, Q> log2(vec<L, T, Q> const& x)
102+ {
103+ return detail::compute_log2<L, T, Q, std::numeric_limits<T>::is_iec559, detail::is_aligned<Q>::value>::call(x);
104+ }
105+
106+ // sqrt
107+ using std::sqrt;
108+ template<length_t L, typename T, qualifier Q>
109+ GLM_FUNC_QUALIFIER vec<L, T, Q> sqrt(vec<L, T, Q> const& x)
110+ {
111+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'sqrt' only accept floating-point inputs");
112+ return detail::compute_sqrt<L, T, Q, detail::is_aligned<Q>::value>::call(x);
113+ }
114+
115+ // inversesqrt
116+ template<typename genType>
117+ GLM_FUNC_QUALIFIER genType inversesqrt(genType x)
118+ {
119+ return static_cast<genType>(1) / sqrt(x);
120+ }
121+
122+ template<length_t L, typename T, qualifier Q>
123+ GLM_FUNC_QUALIFIER vec<L, T, Q> inversesqrt(vec<L, T, Q> const& x)
124+ {
125+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'inversesqrt' only accept floating-point inputs");
126+ return detail::compute_inversesqrt<L, T, Q, detail::is_aligned<Q>::value>::call(x);
127+ }
128+}//namespace glm
129+
130+#if GLM_CONFIG_SIMD == GLM_ENABLE
131+# include "func_exponential_simd.inl"
132+#endif
133+
@@ -0,0 +1,37 @@
1+/// @ref core
2+/// @file glm/detail/func_exponential_simd.inl
3+
4+#include "../simd/exponential.h"
5+
6+#if GLM_ARCH & GLM_ARCH_SSE2_BIT
7+
8+namespace glm{
9+namespace detail
10+{
11+ template<qualifier Q>
12+ struct compute_sqrt<4, float, Q, true>
13+ {
14+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v)
15+ {
16+ vec<4, float, Q> Result;
17+ Result.data = _mm_sqrt_ps(v.data);
18+ return Result;
19+ }
20+ };
21+
22+# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE
23+ template<>
24+ struct compute_sqrt<4, float, aligned_lowp, true>
25+ {
26+ GLM_FUNC_QUALIFIER static vec<4, float, aligned_lowp> call(vec<4, float, aligned_lowp> const& v)
27+ {
28+ vec<4, float, aligned_lowp> Result;
29+ Result.data = glm_vec4_sqrt_lowp(v.data);
30+ return Result;
31+ }
32+ };
33+# endif
34+}//namespace detail
35+}//namespace glm
36+
37+#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT
@@ -0,0 +1,259 @@
1+#include "../exponential.hpp"
2+#include "../common.hpp"
3+
4+namespace glm{
5+namespace detail
6+{
7+ template<length_t L, typename T, qualifier Q, bool Aligned>
8+ struct compute_length
9+ {
10+ GLM_FUNC_QUALIFIER static T call(vec<L, T, Q> const& v)
11+ {
12+ return sqrt(dot(v, v));
13+ }
14+ };
15+
16+ template<length_t L, typename T, qualifier Q, bool Aligned>
17+ struct compute_distance
18+ {
19+ GLM_FUNC_QUALIFIER static T call(vec<L, T, Q> const& p0, vec<L, T, Q> const& p1)
20+ {
21+ return length(p1 - p0);
22+ }
23+ };
24+
25+ template<typename V, typename T, bool Aligned>
26+ struct compute_dot{};
27+
28+ template<typename T, qualifier Q, bool Aligned>
29+ struct compute_dot<vec<1, T, Q>, T, Aligned>
30+ {
31+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(vec<1, T, Q> const& a, vec<1, T, Q> const& b)
32+ {
33+ return a.x * b.x;
34+ }
35+ };
36+
37+ template<typename T, qualifier Q, bool Aligned>
38+ struct compute_dot<vec<2, T, Q>, T, Aligned>
39+ {
40+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(vec<2, T, Q> const& a, vec<2, T, Q> const& b)
41+ {
42+ vec<2, T, Q> tmp(a * b);
43+ return tmp.x + tmp.y;
44+ }
45+ };
46+
47+ template<typename T, qualifier Q, bool Aligned>
48+ struct compute_dot<vec<3, T, Q>, T, Aligned>
49+ {
50+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(vec<3, T, Q> const& a, vec<3, T, Q> const& b)
51+ {
52+ vec<3, T, Q> tmp(a * b);
53+ return tmp.x + tmp.y + tmp.z;
54+ }
55+ };
56+
57+ template<typename T, qualifier Q, bool Aligned>
58+ struct compute_dot<vec<4, T, Q>, T, Aligned>
59+ {
60+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
61+ {
62+ // VS 17.7.4 generates longer assembly (~20 instructions vs 11 instructions)
63+ #if defined(_MSC_VER)
64+ return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
65+ #else
66+ vec<4, T, Q> tmp(a * b);
67+ return (tmp.x + tmp.y) + (tmp.z + tmp.w);
68+ #endif
69+ }
70+ };
71+
72+ template<typename T, qualifier Q, bool Aligned>
73+ struct compute_cross
74+ {
75+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<3, T, Q> call(vec<3, T, Q> const& x, vec<3, T, Q> const& y)
76+ {
77+ static_assert(std::numeric_limits<T>::is_iec559, "'cross' accepts only floating-point inputs");
78+
79+ return vec<3, T, Q>(
80+ x.y * y.z - y.y * x.z,
81+ x.z * y.x - y.z * x.x,
82+ x.x * y.y - y.x * x.y);
83+ }
84+
85+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& x, vec<4, T, Q> const& y)
86+ {
87+ static_assert(std::numeric_limits<T>::is_iec559, "'cross' accepts only floating-point inputs");
88+
89+ return vec<4, T, Q>(
90+ x.y * y.z - y.y * x.z,
91+ x.z * y.x - y.z * x.x,
92+ x.x * y.y - y.x * x.y,
93+ 0.0f);
94+ }
95+ };
96+
97+ template<length_t L, typename T, qualifier Q, bool Aligned>
98+ struct compute_normalize
99+ {
100+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& v)
101+ {
102+ static_assert(std::numeric_limits<T>::is_iec559, "'normalize' accepts only floating-point inputs");
103+
104+ return v * inversesqrt(dot(v, v));
105+ }
106+ };
107+
108+ template<length_t L, typename T, qualifier Q, bool Aligned>
109+ struct compute_faceforward
110+ {
111+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& N, vec<L, T, Q> const& I, vec<L, T, Q> const& Nref)
112+ {
113+ static_assert(std::numeric_limits<T>::is_iec559, "'normalize' accepts only floating-point inputs");
114+
115+ return dot(Nref, I) < static_cast<T>(0) ? N : -N;
116+ }
117+ };
118+
119+ template<length_t L, typename T, qualifier Q, bool Aligned>
120+ struct compute_reflect
121+ {
122+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& I, vec<L, T, Q> const& N)
123+ {
124+ return I - N * dot(N, I) * static_cast<T>(2);
125+ }
126+ };
127+
128+ template<length_t L, typename T, qualifier Q, bool Aligned>
129+ struct compute_refract
130+ {
131+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& I, vec<L, T, Q> const& N, T eta)
132+ {
133+ T const dotValue(dot(N, I));
134+ T const k(static_cast<T>(1) - eta * eta * (static_cast<T>(1) - dotValue * dotValue));
135+ vec<L, T, Q> const Result =
136+ (k >= static_cast<T>(0)) ? (eta * I - (eta * dotValue + std::sqrt(k)) * N) : vec<L, T, Q>(0);
137+ return Result;
138+ }
139+ };
140+}//namespace detail
141+
142+ // length
143+ template<typename genType>
144+ GLM_FUNC_QUALIFIER genType length(genType x)
145+ {
146+ static_assert(std::numeric_limits<genType>::is_iec559, "'length' accepts only floating-point inputs");
147+
148+ return abs(x);
149+ }
150+
151+ template<length_t L, typename T, qualifier Q>
152+ GLM_FUNC_QUALIFIER T length(vec<L, T, Q> const& v)
153+ {
154+ static_assert(std::numeric_limits<T>::is_iec559, "'length' accepts only floating-point inputs");
155+
156+ return detail::compute_length<L, T, Q, detail::is_aligned<Q>::value>::call(v);
157+ }
158+
159+ // distance
160+ template<typename genType>
161+ GLM_FUNC_QUALIFIER genType distance(genType const& p0, genType const& p1)
162+ {
163+ static_assert(std::numeric_limits<genType>::is_iec559, "'distance' accepts only floating-point inputs");
164+
165+ return length(p1 - p0);
166+ }
167+
168+ template<length_t L, typename T, qualifier Q>
169+ GLM_FUNC_QUALIFIER T distance(vec<L, T, Q> const& p0, vec<L, T, Q> const& p1)
170+ {
171+ return detail::compute_distance<L, T, Q, detail::is_aligned<Q>::value>::call(p0, p1);
172+ }
173+
174+ // dot
175+ template<typename T>
176+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR T dot(T x, T y)
177+ {
178+ static_assert(std::numeric_limits<T>::is_iec559, "'dot' accepts only floating-point inputs");
179+ return x * y;
180+ }
181+
182+ template<length_t L, typename T, qualifier Q>
183+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR T dot(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
184+ {
185+ static_assert(std::numeric_limits<T>::is_iec559, "'dot' accepts only floating-point inputs");
186+ return detail::compute_dot<vec<L, T, Q>, T, detail::is_aligned<Q>::value>::call(x, y);
187+ }
188+
189+ // cross
190+ template<typename T, qualifier Q>
191+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> cross(vec<3, T, Q> const& x, vec<3, T, Q> const& y)
192+ {
193+ return detail::compute_cross<T, Q, detail::is_aligned<Q>::value>::call(x, y);
194+ }
195+/*
196+ // normalize
197+ template<typename genType>
198+ GLM_FUNC_QUALIFIER genType normalize(genType const& x)
199+ {
200+ static_assert(std::numeric_limits<genType>::is_iec559, "'normalize' accepts only floating-point inputs");
201+
202+ return x < genType(0) ? genType(-1) : genType(1);
203+ }
204+*/
205+ template<length_t L, typename T, qualifier Q>
206+ GLM_FUNC_QUALIFIER vec<L, T, Q> normalize(vec<L, T, Q> const& x)
207+ {
208+ static_assert(std::numeric_limits<T>::is_iec559, "'normalize' accepts only floating-point inputs");
209+
210+ return detail::compute_normalize<L, T, Q, detail::is_aligned<Q>::value>::call(x);
211+ }
212+
213+ // faceforward
214+ template<typename genType>
215+ GLM_FUNC_QUALIFIER genType faceforward(genType const& N, genType const& I, genType const& Nref)
216+ {
217+ return dot(Nref, I) < static_cast<genType>(0) ? N : -N;
218+ }
219+
220+ template<length_t L, typename T, qualifier Q>
221+ GLM_FUNC_QUALIFIER vec<L, T, Q> faceforward(vec<L, T, Q> const& N, vec<L, T, Q> const& I, vec<L, T, Q> const& Nref)
222+ {
223+ return detail::compute_faceforward<L, T, Q, detail::is_aligned<Q>::value>::call(N, I, Nref);
224+ }
225+
226+ // reflect
227+ template<typename genType>
228+ GLM_FUNC_QUALIFIER genType reflect(genType const& I, genType const& N)
229+ {
230+ return I - N * dot(N, I) * genType(2);
231+ }
232+
233+ template<length_t L, typename T, qualifier Q>
234+ GLM_FUNC_QUALIFIER vec<L, T, Q> reflect(vec<L, T, Q> const& I, vec<L, T, Q> const& N)
235+ {
236+ return detail::compute_reflect<L, T, Q, detail::is_aligned<Q>::value>::call(I, N);
237+ }
238+
239+ // refract
240+ template<typename genType>
241+ GLM_FUNC_QUALIFIER genType refract(genType const& I, genType const& N, genType eta)
242+ {
243+ static_assert(std::numeric_limits<genType>::is_iec559, "'refract' accepts only floating-point inputs");
244+ genType const dotValue(dot(N, I));
245+ genType const k(static_cast<genType>(1) - eta * eta * (static_cast<genType>(1) - dotValue * dotValue));
246+ return (eta * I - (eta * dotValue + sqrt(k)) * N) * static_cast<genType>(k >= static_cast<genType>(0));
247+ }
248+
249+ template<length_t L, typename T, qualifier Q>
250+ GLM_FUNC_QUALIFIER vec<L, T, Q> refract(vec<L, T, Q> const& I, vec<L, T, Q> const& N, T eta)
251+ {
252+ static_assert(std::numeric_limits<T>::is_iec559, "'refract' accepts only floating-point inputs");
253+ return detail::compute_refract<L, T, Q, detail::is_aligned<Q>::value>::call(I, N, eta);
254+ }
255+}//namespace glm
256+
257+#if GLM_CONFIG_SIMD == GLM_ENABLE
258+# include "func_geometric_simd.inl"
259+#endif
@@ -0,0 +1,212 @@
1+/// @ref core
2+/// @file glm/detail/func_geometric_simd.inl
3+
4+#include "../simd/geometric.h"
5+
6+#if GLM_ARCH & GLM_ARCH_SSE2_BIT
7+
8+namespace glm{
9+namespace detail
10+{
11+ template<qualifier Q>
12+ struct compute_length<4, float, Q, true>
13+ {
14+ GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& v)
15+ {
16+ return _mm_cvtss_f32(glm_vec4_length(v.data));
17+ }
18+ };
19+
20+ template<qualifier Q>
21+ struct compute_distance<4, float, Q, true>
22+ {
23+ GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& p0, vec<4, float, Q> const& p1)
24+ {
25+ return _mm_cvtss_f32(glm_vec4_distance(p0.data, p1.data));
26+ }
27+ };
28+
29+ template<qualifier Q>
30+ struct compute_dot<vec<4, float, Q>, float, true>
31+ {
32+ GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& x, vec<4, float, Q> const& y)
33+ {
34+ return _mm_cvtss_f32(glm_vec1_dot(x.data, y.data));
35+ }
36+ };
37+
38+ template<qualifier Q>
39+ struct compute_dot<vec<3, float, Q>, float, true>
40+ {
41+ GLM_FUNC_QUALIFIER static float call(vec<3, float, Q> const& a, vec<3, float, Q> const& b)
42+ {
43+ return _mm_cvtss_f32(glm_vec3_dot(a.data, b.data)); // aligned as vec4
44+ }
45+ };
46+
47+ template<qualifier Q>
48+ struct compute_cross<float, Q, true>
49+ {
50+ GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<3, float, Q> const& a, vec<3, float, Q> const& b)
51+ {
52+ vec<4, float, Q> aa = xyzz(a);
53+ vec<4, float, Q> bb = xyzz(b);
54+ __m128 const xpd0 = glm_vec4_cross(aa.data, bb.data);
55+
56+ vec<3, float, Q> Result;
57+ Result.data = xpd0;
58+ return Result;
59+ }
60+
61+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
62+ {
63+ vec<4, float, Q> Result;
64+ Result.data = glm_vec4_cross(a.data, b.data);
65+ return Result;
66+ }
67+ };
68+
69+ template<>
70+ struct compute_normalize<4, float, aligned_lowp, true>
71+ {
72+ GLM_FUNC_QUALIFIER static vec<4, float, aligned_lowp> call(vec<4, float, aligned_lowp> const& v)
73+ {
74+ vec<4, float, aligned_lowp> Result;
75+ Result.data = glm_vec4_normalize(v.data);
76+ return Result;
77+ }
78+ };
79+
80+ template<>
81+ struct compute_normalize<3, float, aligned_lowp, true>
82+ {
83+ GLM_FUNC_QUALIFIER static vec<3, float, aligned_lowp> call(vec<3, float, aligned_lowp> const& v)
84+ {
85+ vec<3, float, aligned_lowp> Result;
86+ Result.data = glm_vec3_normalize_lowp(v.data);
87+ return Result;
88+ }
89+ };
90+
91+ template<qualifier Q>
92+ struct compute_normalize<4, float, Q, true>
93+ {
94+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v)
95+ {
96+ vec<4, float, Q> Result;
97+ Result.data = glm_vec4_normalize(v.data);
98+ return Result;
99+ }
100+ };
101+
102+ template<qualifier Q>
103+ struct compute_normalize<3, float, Q, true>
104+ {
105+ GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<3, float, Q> const& v)
106+ {
107+ vec<3, float, Q> Result;
108+ Result.data = glm_vec3_normalize(v.data);
109+ return Result;
110+ }
111+ };
112+
113+ template<qualifier Q>
114+ struct compute_faceforward<4, float, Q, true>
115+ {
116+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& N, vec<4, float, Q> const& I, vec<4, float, Q> const& Nref)
117+ {
118+ vec<4, float, Q> Result;
119+ Result.data = glm_vec4_faceforward(N.data, I.data, Nref.data);
120+ return Result;
121+ }
122+ };
123+
124+ template<qualifier Q>
125+ struct compute_reflect<4, float, Q, true>
126+ {
127+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& I, vec<4, float, Q> const& N)
128+ {
129+ vec<4, float, Q> Result;
130+ Result.data = glm_vec4_reflect(I.data, N.data);
131+ return Result;
132+ }
133+ };
134+
135+ template<qualifier Q>
136+ struct compute_refract<4, float, Q, true>
137+ {
138+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& I, vec<4, float, Q> const& N, float eta)
139+ {
140+ vec<4, float, Q> Result;
141+ Result.data = glm_vec4_refract(I.data, N.data, _mm_set1_ps(eta));
142+ return Result;
143+ }
144+ };
145+}//namespace detail
146+}//namespace glm
147+
148+#elif GLM_ARCH & GLM_ARCH_NEON_BIT
149+namespace glm{
150+namespace detail
151+{
152+ template<qualifier Q>
153+ struct compute_length<4, float, Q, true>
154+ {
155+ GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& v)
156+ {
157+ return sqrt(compute_dot<vec<4, float, Q>, float, true>::call(v, v));
158+ }
159+ };
160+
161+ template<qualifier Q>
162+ struct compute_distance<4, float, Q, true>
163+ {
164+ GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& p0, vec<4, float, Q> const& p1)
165+ {
166+ return compute_length<4, float, Q, true>::call(p1 - p0);
167+ }
168+ };
169+
170+
171+ template<qualifier Q>
172+ struct compute_dot<vec<4, float, Q>, float, true>
173+ {
174+ GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& x, vec<4, float, Q> const& y)
175+ {
176+#if GLM_ARCH & GLM_ARCH_ARMV8_BIT
177+ float32x4_t v = vmulq_f32(x.data, y.data);
178+ return vaddvq_f32(v);
179+#else // Armv7a with Neon
180+ float32x4_t p = vmulq_f32(x.data, y.data);
181+ float32x2_t v = vpadd_f32(vget_low_f32(p), vget_high_f32(p));
182+ v = vpadd_f32(v, v);
183+ return vget_lane_f32(v, 0);
184+#endif
185+ }
186+ };
187+
188+ template<qualifier Q>
189+ struct compute_normalize<4, float, Q, true>
190+ {
191+ GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v)
192+ {
193+ float32x4_t p = vmulq_f32(v.data, v.data);
194+#if GLM_ARCH & GLM_ARCH_ARMV8_BIT
195+ p = vpaddq_f32(p, p);
196+ p = vpaddq_f32(p, p);
197+#else
198+ float32x2_t t = vpadd_f32(vget_low_f32(p), vget_high_f32(p));
199+ t = vpadd_f32(t, t);
200+ p = vcombine_f32(t, t);
201+#endif
202+
203+ float32x4_t vd = vrsqrteq_f32(p);
204+ vec<4, float, Q> Result;
205+ Result.data = vmulq_f32(v.data, vd);
206+ return Result;
207+ }
208+ };
209+}//namespace detail
210+}//namespace glm
211+
212+#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT
@@ -0,0 +1,372 @@
1+/// @ref core
2+
3+#include "_vectorize.hpp"
4+#if(GLM_ARCH & GLM_ARCH_X86 && GLM_COMPILER & GLM_COMPILER_VC)
5+# include <intrin.h>
6+# pragma intrinsic(_BitScanReverse)
7+#endif//(GLM_ARCH & GLM_ARCH_X86 && GLM_COMPILER & GLM_COMPILER_VC)
8+#include <limits>
9+
10+namespace glm{
11+namespace detail
12+{
13+ template<typename T>
14+ GLM_FUNC_QUALIFIER T mask(T Bits)
15+ {
16+ return Bits >= static_cast<T>(sizeof(T) * 8) ? ~static_cast<T>(0) : (static_cast<T>(1) << Bits) - static_cast<T>(1);
17+ }
18+
19+ template<length_t L, typename T, qualifier Q, bool Aligned, bool EXEC>
20+ struct compute_bitfieldReverseStep
21+ {
22+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& v, T, T)
23+ {
24+ return v;
25+ }
26+ };
27+
28+ template<length_t L, typename T, qualifier Q, bool Aligned>
29+ struct compute_bitfieldReverseStep<L, T, Q, Aligned, true>
30+ {
31+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& v, T Mask, T Shift)
32+ {
33+ return (v & Mask) << Shift | (v & (~Mask)) >> Shift;
34+ }
35+ };
36+
37+ template<length_t L, typename T, qualifier Q, bool Aligned, bool EXEC>
38+ struct compute_bitfieldBitCountStep
39+ {
40+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& v, T, T)
41+ {
42+ return v;
43+ }
44+ };
45+
46+ template<length_t L, typename T, qualifier Q, bool Aligned>
47+ struct compute_bitfieldBitCountStep<L, T, Q, Aligned, true>
48+ {
49+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& v, T Mask, T Shift)
50+ {
51+ return (v & Mask) + ((v >> Shift) & Mask);
52+ }
53+ };
54+
55+ template<typename genIUType, size_t Bits>
56+ struct compute_findLSB
57+ {
58+ GLM_FUNC_QUALIFIER static int call(genIUType Value)
59+ {
60+ if(Value == 0)
61+ return -1;
62+
63+ return glm::bitCount(~Value & (Value - static_cast<genIUType>(1)));
64+ }
65+ };
66+
67+# if GLM_HAS_BITSCAN_WINDOWS
68+ template<typename genIUType>
69+ struct compute_findLSB<genIUType, 32>
70+ {
71+ GLM_FUNC_QUALIFIER static int call(genIUType Value)
72+ {
73+ unsigned long Result(0);
74+ unsigned char IsNotNull = _BitScanForward(&Result, *reinterpret_cast<unsigned long*>(&Value));
75+ return IsNotNull ? int(Result) : -1;
76+ }
77+ };
78+
79+# if !((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_MODEL == GLM_MODEL_32))
80+ template<typename genIUType>
81+ struct compute_findLSB<genIUType, 64>
82+ {
83+ GLM_FUNC_QUALIFIER static int call(genIUType Value)
84+ {
85+ unsigned long Result(0);
86+ unsigned char IsNotNull = _BitScanForward64(&Result, *reinterpret_cast<unsigned __int64*>(&Value));
87+ return IsNotNull ? int(Result) : -1;
88+ }
89+ };
90+# endif
91+# endif//GLM_HAS_BITSCAN_WINDOWS
92+
93+ template<length_t L, typename T, qualifier Q, bool EXEC = true>
94+ struct compute_findMSB_step_vec
95+ {
96+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, T Shift)
97+ {
98+ return x | (x >> Shift);
99+ }
100+ };
101+
102+ template<length_t L, typename T, qualifier Q>
103+ struct compute_findMSB_step_vec<L, T, Q, false>
104+ {
105+ GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, T)
106+ {
107+ return x;
108+ }
109+ };
110+
111+ template<length_t L, typename T, qualifier Q, int>
112+ struct compute_findMSB_vec
113+ {
114+ GLM_FUNC_QUALIFIER static vec<L, int, Q> call(vec<L, T, Q> const& v)
115+ {
116+ vec<L, T, Q> x(v);
117+ x = compute_findMSB_step_vec<L, T, Q, sizeof(T) * 8 >= 8>::call(x, static_cast<T>( 1));
118+ x = compute_findMSB_step_vec<L, T, Q, sizeof(T) * 8 >= 8>::call(x, static_cast<T>( 2));
119+ x = compute_findMSB_step_vec<L, T, Q, sizeof(T) * 8 >= 8>::call(x, static_cast<T>( 4));
120+ x = compute_findMSB_step_vec<L, T, Q, sizeof(T) * 8 >= 16>::call(x, static_cast<T>( 8));
121+ x = compute_findMSB_step_vec<L, T, Q, sizeof(T) * 8 >= 32>::call(x, static_cast<T>(16));
122+ x = compute_findMSB_step_vec<L, T, Q, sizeof(T) * 8 >= 64>::call(x, static_cast<T>(32));
123+ return vec<L, int, Q>(sizeof(T) * 8 - 1) - glm::bitCount(~x);
124+ }
125+ };
126+
127+# if GLM_HAS_BITSCAN_WINDOWS
128+ template<typename genIUType>
129+ GLM_FUNC_QUALIFIER int compute_findMSB_32(genIUType Value)
130+ {
131+ unsigned long Result(0);
132+ unsigned char IsNotNull = _BitScanReverse(&Result, *reinterpret_cast<unsigned long*>(&Value));
133+ return IsNotNull ? int(Result) : -1;
134+ }
135+
136+ template<length_t L, typename T, qualifier Q>
137+ struct compute_findMSB_vec<L, T, Q, 32>
138+ {
139+ GLM_FUNC_QUALIFIER static vec<L, int, Q> call(vec<L, T, Q> const& x)
140+ {
141+ return detail::functor1<vec, L, int, T, Q>::call(compute_findMSB_32, x);
142+ }
143+ };
144+
145+# if !((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_MODEL == GLM_MODEL_32))
146+ template<typename genIUType>
147+ GLM_FUNC_QUALIFIER int compute_findMSB_64(genIUType Value)
148+ {
149+ unsigned long Result(0);
150+ unsigned char IsNotNull = _BitScanReverse64(&Result, *reinterpret_cast<unsigned __int64*>(&Value));
151+ return IsNotNull ? int(Result) : -1;
152+ }
153+
154+ template<length_t L, typename T, qualifier Q>
155+ struct compute_findMSB_vec<L, T, Q, 64>
156+ {
157+ GLM_FUNC_QUALIFIER static vec<L, int, Q> call(vec<L, T, Q> const& x)
158+ {
159+ return detail::functor1<vec, L, int, T, Q>::call(compute_findMSB_64, x);
160+ }
161+ };
162+# endif
163+# endif//GLM_HAS_BITSCAN_WINDOWS
164+}//namespace detail
165+
166+ // uaddCarry
167+ GLM_FUNC_QUALIFIER uint uaddCarry(uint const& x, uint const& y, uint & Carry)
168+ {
169+ detail::uint64 const Value64(static_cast<detail::uint64>(x) + static_cast<detail::uint64>(y));
170+ detail::uint64 const Max32((static_cast<detail::uint64>(1) << static_cast<detail::uint64>(32)) - static_cast<detail::uint64>(1));
171+ Carry = Value64 > Max32 ? 1u : 0u;
172+ return static_cast<uint>(Value64 % (Max32 + static_cast<detail::uint64>(1)));
173+ }
174+
175+ template<length_t L, qualifier Q>
176+ GLM_FUNC_QUALIFIER vec<L, uint, Q> uaddCarry(vec<L, uint, Q> const& x, vec<L, uint, Q> const& y, vec<L, uint, Q>& Carry)
177+ {
178+ vec<L, detail::uint64, Q> Value64(vec<L, detail::uint64, Q>(x) + vec<L, detail::uint64, Q>(y));
179+ vec<L, detail::uint64, Q> Max32((static_cast<detail::uint64>(1) << static_cast<detail::uint64>(32)) - static_cast<detail::uint64>(1));
180+ Carry = mix(vec<L, uint, Q>(0), vec<L, uint, Q>(1), greaterThan(Value64, Max32));
181+ return vec<L, uint, Q>(Value64 % (Max32 + static_cast<detail::uint64>(1)));
182+ }
183+
184+ // usubBorrow
185+ GLM_FUNC_QUALIFIER uint usubBorrow(uint const& x, uint const& y, uint & Borrow)
186+ {
187+ Borrow = x >= y ? static_cast<uint>(0) : static_cast<uint>(1);
188+ if(x >= y)
189+ return x - y;
190+ else
191+ return static_cast<uint>((static_cast<detail::int64>(1) << static_cast<detail::int64>(32)) + (static_cast<detail::int64>(x) - static_cast<detail::int64>(y)));
192+ }
193+
194+ template<length_t L, qualifier Q>
195+ GLM_FUNC_QUALIFIER vec<L, uint, Q> usubBorrow(vec<L, uint, Q> const& x, vec<L, uint, Q> const& y, vec<L, uint, Q>& Borrow)
196+ {
197+ Borrow = mix(vec<L, uint, Q>(1), vec<L, uint, Q>(0), greaterThanEqual(x, y));
198+ vec<L, uint, Q> const XgeY(x - y);
199+ vec<L, uint, Q> const YgX(vec<L, uint, Q>((static_cast<detail::int64>(1) << static_cast<detail::int64>(32)) + (vec<L, detail::int64, Q>(x) - vec<L, detail::int64, Q>(y))));
200+ return mix(YgX, XgeY, greaterThanEqual(x, y));
201+ }
202+
203+ // umulExtended
204+ GLM_FUNC_QUALIFIER void umulExtended(uint const& x, uint const& y, uint & msb, uint & lsb)
205+ {
206+ detail::uint64 Value64 = static_cast<detail::uint64>(x) * static_cast<detail::uint64>(y);
207+ msb = static_cast<uint>(Value64 >> static_cast<detail::uint64>(32));
208+ lsb = static_cast<uint>(Value64);
209+ }
210+
211+ template<length_t L, qualifier Q>
212+ GLM_FUNC_QUALIFIER void umulExtended(vec<L, uint, Q> const& x, vec<L, uint, Q> const& y, vec<L, uint, Q>& msb, vec<L, uint, Q>& lsb)
213+ {
214+ vec<L, detail::uint64, Q> Value64(vec<L, detail::uint64, Q>(x) * vec<L, detail::uint64, Q>(y));
215+ msb = vec<L, uint, Q>(Value64 >> static_cast<detail::uint64>(32));
216+ lsb = vec<L, uint, Q>(Value64);
217+ }
218+
219+ // imulExtended
220+ GLM_FUNC_QUALIFIER void imulExtended(int x, int y, int& msb, int& lsb)
221+ {
222+ detail::int64 Value64 = static_cast<detail::int64>(x) * static_cast<detail::int64>(y);
223+ msb = static_cast<int>(Value64 >> static_cast<detail::int64>(32));
224+ lsb = static_cast<int>(Value64);
225+ }
226+
227+ template<length_t L, qualifier Q>
228+ GLM_FUNC_QUALIFIER void imulExtended(vec<L, int, Q> const& x, vec<L, int, Q> const& y, vec<L, int, Q>& msb, vec<L, int, Q>& lsb)
229+ {
230+ vec<L, detail::int64, Q> Value64(vec<L, detail::int64, Q>(x) * vec<L, detail::int64, Q>(y));
231+ lsb = vec<L, int, Q>(Value64 & static_cast<detail::int64>(0xFFFFFFFF));
232+ msb = vec<L, int, Q>((Value64 >> static_cast<detail::int64>(32)) & static_cast<detail::int64>(0xFFFFFFFF));
233+ }
234+
235+ // bitfieldExtract
236+ template<typename genIUType>
237+ GLM_FUNC_QUALIFIER genIUType bitfieldExtract(genIUType Value, int Offset, int Bits)
238+ {
239+ return bitfieldExtract(vec<1, genIUType>(Value), Offset, Bits).x;
240+ }
241+
242+ template<length_t L, typename T, qualifier Q>
243+ GLM_FUNC_QUALIFIER vec<L, T, Q> bitfieldExtract(vec<L, T, Q> const& Value, int Offset, int Bits)
244+ {
245+ static_assert(std::numeric_limits<T>::is_integer, "'bitfieldExtract' only accept integer inputs");
246+
247+ return (Value >> static_cast<T>(Offset)) & static_cast<T>(detail::mask(Bits));
248+ }
249+
250+ // bitfieldInsert
251+ template<typename genIUType>
252+ GLM_FUNC_QUALIFIER genIUType bitfieldInsert(genIUType const& Base, genIUType const& Insert, int Offset, int Bits)
253+ {
254+ static_assert(std::numeric_limits<genIUType>::is_integer, "'bitfieldInsert' only accept integer values");
255+
256+ return bitfieldInsert(vec<1, genIUType>(Base), vec<1, genIUType>(Insert), Offset, Bits).x;
257+ }
258+
259+ template<length_t L, typename T, qualifier Q>
260+ GLM_FUNC_QUALIFIER vec<L, T, Q> bitfieldInsert(vec<L, T, Q> const& Base, vec<L, T, Q> const& Insert, int Offset, int Bits)
261+ {
262+ static_assert(std::numeric_limits<T>::is_integer, "'bitfieldInsert' only accept integer values");
263+
264+ T const Mask = detail::mask(static_cast<T>(Bits)) << Offset;
265+ return (Base & ~Mask) | ((Insert << static_cast<T>(Offset)) & Mask);
266+ }
267+
268+#if GLM_COMPILER & GLM_COMPILER_VC
269+# pragma warning(push)
270+# pragma warning(disable : 4309)
271+#endif
272+
273+ // bitfieldReverse
274+ template<typename genIUType>
275+ GLM_FUNC_QUALIFIER genIUType bitfieldReverse(genIUType x)
276+ {
277+ static_assert(std::numeric_limits<genIUType>::is_integer, "'bitfieldReverse' only accept integer values");
278+
279+ return bitfieldReverse(glm::vec<1, genIUType, glm::defaultp>(x)).x;
280+ }
281+
282+ template<length_t L, typename T, qualifier Q>
283+ GLM_FUNC_QUALIFIER vec<L, T, Q> bitfieldReverse(vec<L, T, Q> const& v)
284+ {
285+ static_assert(std::numeric_limits<T>::is_integer, "'bitfieldReverse' only accept integer values");
286+
287+ vec<L, T, Q> x(v);
288+ x = detail::compute_bitfieldReverseStep<L, T, Q, detail::is_aligned<Q>::value, sizeof(T) * 8>= 2>::call(x, static_cast<T>(0x5555555555555555ull), static_cast<T>( 1));
289+ x = detail::compute_bitfieldReverseStep<L, T, Q, detail::is_aligned<Q>::value, sizeof(T) * 8>= 4>::call(x, static_cast<T>(0x3333333333333333ull), static_cast<T>( 2));
290+ x = detail::compute_bitfieldReverseStep<L, T, Q, detail::is_aligned<Q>::value, sizeof(T) * 8>= 8>::call(x, static_cast<T>(0x0F0F0F0F0F0F0F0Full), static_cast<T>( 4));
291+ x = detail::compute_bitfieldReverseStep<L, T, Q, detail::is_aligned<Q>::value, sizeof(T) * 8>= 16>::call(x, static_cast<T>(0x00FF00FF00FF00FFull), static_cast<T>( 8));
292+ x = detail::compute_bitfieldReverseStep<L, T, Q, detail::is_aligned<Q>::value, sizeof(T) * 8>= 32>::call(x, static_cast<T>(0x0000FFFF0000FFFFull), static_cast<T>(16));
293+ x = detail::compute_bitfieldReverseStep<L, T, Q, detail::is_aligned<Q>::value, sizeof(T) * 8>= 64>::call(x, static_cast<T>(0x00000000FFFFFFFFull), static_cast<T>(32));
294+ return x;
295+ }
296+
297+# if GLM_COMPILER & GLM_COMPILER_VC
298+# pragma warning(pop)
299+# endif
300+
301+ // bitCount
302+ template<typename genIUType>
303+ GLM_FUNC_QUALIFIER int bitCount(genIUType x)
304+ {
305+ static_assert(std::numeric_limits<genIUType>::is_integer, "'bitCount' only accept integer values");
306+
307+ return bitCount(glm::vec<1, genIUType, glm::defaultp>(x)).x;
308+ }
309+
310+ template<length_t L, typename T, qualifier Q>
311+ GLM_FUNC_QUALIFIER vec<L, int, Q> bitCount(vec<L, T, Q> const& v)
312+ {
313+ static_assert(std::numeric_limits<T>::is_integer, "'bitCount' only accept integer values");
314+
315+# if GLM_COMPILER & GLM_COMPILER_VC
316+# pragma warning(push)
317+# pragma warning(disable : 4310) //cast truncates constant value
318+# endif
319+
320+ vec<L, typename std::make_unsigned<T>::type, Q> x(v);
321+ x = detail::compute_bitfieldBitCountStep<L, typename std::make_unsigned<T>::type, Q, detail::is_aligned<Q>::value, sizeof(T) * 8>= 2>::call(x, typename std::make_unsigned<T>::type(0x5555555555555555ull), typename std::make_unsigned<T>::type( 1));
322+ x = detail::compute_bitfieldBitCountStep<L, typename std::make_unsigned<T>::type, Q, detail::is_aligned<Q>::value, sizeof(T) * 8>= 4>::call(x, typename std::make_unsigned<T>::type(0x3333333333333333ull), typename std::make_unsigned<T>::type( 2));
323+ x = detail::compute_bitfieldBitCountStep<L, typename std::make_unsigned<T>::type, Q, detail::is_aligned<Q>::value, sizeof(T) * 8>= 8>::call(x, typename std::make_unsigned<T>::type(0x0F0F0F0F0F0F0F0Full), typename std::make_unsigned<T>::type( 4));
324+ x = detail::compute_bitfieldBitCountStep<L, typename std::make_unsigned<T>::type, Q, detail::is_aligned<Q>::value, sizeof(T) * 8>= 16>::call(x, typename std::make_unsigned<T>::type(0x00FF00FF00FF00FFull), typename std::make_unsigned<T>::type( 8));
325+ x = detail::compute_bitfieldBitCountStep<L, typename std::make_unsigned<T>::type, Q, detail::is_aligned<Q>::value, sizeof(T) * 8>= 32>::call(x, typename std::make_unsigned<T>::type(0x0000FFFF0000FFFFull), typename std::make_unsigned<T>::type(16));
326+ x = detail::compute_bitfieldBitCountStep<L, typename std::make_unsigned<T>::type, Q, detail::is_aligned<Q>::value, sizeof(T) * 8>= 64>::call(x, typename std::make_unsigned<T>::type(0x00000000FFFFFFFFull), typename std::make_unsigned<T>::type(32));
327+ return vec<L, int, Q>(x);
328+
329+# if GLM_COMPILER & GLM_COMPILER_VC
330+# pragma warning(pop)
331+# endif
332+ }
333+
334+ // findLSB
335+ template<typename genIUType>
336+ GLM_FUNC_QUALIFIER int findLSB(genIUType Value)
337+ {
338+ static_assert(std::numeric_limits<genIUType>::is_integer, "'findLSB' only accept integer values");
339+
340+ return detail::compute_findLSB<genIUType, sizeof(genIUType) * 8>::call(Value);
341+ }
342+
343+ template<length_t L, typename T, qualifier Q>
344+ GLM_FUNC_QUALIFIER vec<L, int, Q> findLSB(vec<L, T, Q> const& x)
345+ {
346+ static_assert(std::numeric_limits<T>::is_integer, "'findLSB' only accept integer values");
347+
348+ return detail::functor1<vec, L, int, T, Q>::call(findLSB, x);
349+ }
350+
351+ // findMSB
352+ template<typename genIUType>
353+ GLM_FUNC_QUALIFIER int findMSB(genIUType v)
354+ {
355+ static_assert(std::numeric_limits<genIUType>::is_integer, "'findMSB' only accept integer values");
356+
357+ return findMSB(vec<1, genIUType>(v)).x;
358+ }
359+
360+ template<length_t L, typename T, qualifier Q>
361+ GLM_FUNC_QUALIFIER vec<L, int, Q> findMSB(vec<L, T, Q> const& v)
362+ {
363+ static_assert(std::numeric_limits<T>::is_integer, "'findMSB' only accept integer values");
364+
365+ return detail::compute_findMSB_vec<L, T, Q, static_cast<int>(sizeof(T) * 8)>::call(v);
366+ }
367+}//namespace glm
368+
369+#if GLM_CONFIG_SIMD == GLM_ENABLE
370+# include "func_integer_simd.inl"
371+#endif
372+
@@ -0,0 +1,65 @@
1+#include "../simd/integer.h"
2+
3+#if GLM_ARCH & GLM_ARCH_SSE2_BIT
4+
5+namespace glm{
6+namespace detail
7+{
8+ template<qualifier Q>
9+ struct compute_bitfieldReverseStep<4, uint, Q, true, true>
10+ {
11+ GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& v, uint Mask, uint Shift)
12+ {
13+ __m128i const set0 = v.data;
14+
15+ __m128i const set1 = _mm_set1_epi32(static_cast<int>(Mask));
16+ __m128i const and1 = _mm_and_si128(set0, set1);
17+ __m128i const sft1 = _mm_slli_epi32(and1, static_cast<int>(Shift));
18+
19+ __m128i const set2 = _mm_andnot_si128(set0, _mm_set1_epi32(-1));
20+ __m128i const and2 = _mm_and_si128(set0, set2);
21+ __m128i const sft2 = _mm_srai_epi32(and2, static_cast<int>(Shift));
22+
23+ __m128i const or0 = _mm_or_si128(sft1, sft2);
24+
25+ return or0;
26+ }
27+ };
28+
29+ template<qualifier Q>
30+ struct compute_bitfieldBitCountStep<4, uint, Q, true, true>
31+ {
32+ GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& v, uint Mask, uint Shift)
33+ {
34+ __m128i const set0 = v.data;
35+
36+ __m128i const set1 = _mm_set1_epi32(static_cast<int>(Mask));
37+ __m128i const and0 = _mm_and_si128(set0, set1);
38+ __m128i const sft0 = _mm_slli_epi32(set0, static_cast<int>(Shift));
39+ __m128i const and1 = _mm_and_si128(sft0, set1);
40+ __m128i const add0 = _mm_add_epi32(and0, and1);
41+
42+ return add0;
43+ }
44+ };
45+}//namespace detail
46+
47+# if GLM_ARCH & GLM_ARCH_AVX_BIT
48+ template<>
49+ GLM_FUNC_QUALIFIER int bitCount(uint x)
50+ {
51+ return _mm_popcnt_u32(x);
52+ }
53+
54+# if(GLM_MODEL == GLM_MODEL_64)
55+ template<>
56+ GLM_FUNC_QUALIFIER int bitCount(detail::uint64 x)
57+ {
58+ return static_cast<int>(_mm_popcnt_u64(x));
59+ }
60+# endif//GLM_MODEL
61+# endif//GLM_ARCH
62+
63+}//namespace glm
64+
65+#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT
@@ -0,0 +1,484 @@
1+#include "../geometric.hpp"
2+#include <limits>
3+
4+namespace glm{
5+namespace detail
6+{
7+ template<length_t C, length_t R, typename T, qualifier Q, bool Aligned>
8+ struct compute_matrixCompMult
9+ {
10+ GLM_FUNC_QUALIFIER static mat<C, R, T, Q> call(mat<C, R, T, Q> const& x, mat<C, R, T, Q> const& y)
11+ {
12+ mat<C, R, T, Q> Result(1);
13+ for(length_t i = 0; i < Result.length(); ++i)
14+ Result[i] = x[i] * y[i];
15+ return Result;
16+ }
17+ };
18+
19+ template<length_t C, length_t R, typename T, qualifier Q, bool IsFloat, bool Aligned>
20+ struct compute_matrixCompMult_type {
21+ GLM_FUNC_QUALIFIER static mat<C, R, T, Q> call(mat<C, R, T, Q> const& x, mat<C, R, T, Q> const& y)
22+ {
23+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE,
24+ "'matrixCompMult' only accept floating-point inputs, include <glm/ext/matrix_integer.hpp> to discard this restriction.");
25+ return detail::compute_matrixCompMult<C, R, T, Q, detail::is_aligned<Q>::value>::call(x, y);
26+ }
27+ };
28+
29+ template<length_t DA, length_t DB, typename T, qualifier Q>
30+ struct compute_outerProduct {
31+ GLM_FUNC_QUALIFIER static typename detail::outerProduct_trait<DA, DB, T, Q>::type call(vec<DA, T, Q> const& c, vec<DB, T, Q> const& r)
32+ {
33+ typename detail::outerProduct_trait<DA, DB, T, Q>::type m(0);
34+ for(length_t i = 0; i < m.length(); ++i)
35+ m[i] = c * r[i];
36+ return m;
37+ }
38+ };
39+
40+ template<length_t DA, length_t DB, typename T, qualifier Q, bool IsFloat>
41+ struct compute_outerProduct_type {
42+ GLM_FUNC_QUALIFIER static typename detail::outerProduct_trait<DA, DB, T, Q>::type call(vec<DA, T, Q> const& c, vec<DB, T, Q> const& r)
43+ {
44+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE,
45+ "'outerProduct' only accept floating-point inputs, include <glm/ext/matrix_integer.hpp> to discard this restriction.");
46+
47+ return detail::compute_outerProduct<DA, DB, T, Q>::call(c, r);
48+ }
49+ };
50+
51+ template<length_t C, length_t R, typename T, qualifier Q, bool Aligned>
52+ struct compute_transpose{};
53+
54+ template<typename T, qualifier Q, bool Aligned>
55+ struct compute_transpose<2, 2, T, Q, Aligned>
56+ {
57+ GLM_FUNC_QUALIFIER static mat<2, 2, T, Q> call(mat<2, 2, T, Q> const& m)
58+ {
59+ mat<2, 2, T, Q> Result(1);
60+ Result[0][0] = m[0][0];
61+ Result[0][1] = m[1][0];
62+ Result[1][0] = m[0][1];
63+ Result[1][1] = m[1][1];
64+ return Result;
65+ }
66+ };
67+
68+ template<typename T, qualifier Q, bool Aligned>
69+ struct compute_transpose<2, 3, T, Q, Aligned>
70+ {
71+ GLM_FUNC_QUALIFIER static mat<3, 2, T, Q> call(mat<2, 3, T, Q> const& m)
72+ {
73+ mat<3,2, T, Q> Result(1);
74+ Result[0][0] = m[0][0];
75+ Result[0][1] = m[1][0];
76+ Result[1][0] = m[0][1];
77+ Result[1][1] = m[1][1];
78+ Result[2][0] = m[0][2];
79+ Result[2][1] = m[1][2];
80+ return Result;
81+ }
82+ };
83+
84+ template<typename T, qualifier Q, bool Aligned>
85+ struct compute_transpose<2, 4, T, Q, Aligned>
86+ {
87+ GLM_FUNC_QUALIFIER static mat<4, 2, T, Q> call(mat<2, 4, T, Q> const& m)
88+ {
89+ mat<4, 2, T, Q> Result(1);
90+ Result[0][0] = m[0][0];
91+ Result[0][1] = m[1][0];
92+ Result[1][0] = m[0][1];
93+ Result[1][1] = m[1][1];
94+ Result[2][0] = m[0][2];
95+ Result[2][1] = m[1][2];
96+ Result[3][0] = m[0][3];
97+ Result[3][1] = m[1][3];
98+ return Result;
99+ }
100+ };
101+
102+ template<typename T, qualifier Q, bool Aligned>
103+ struct compute_transpose<3, 2, T, Q, Aligned>
104+ {
105+ GLM_FUNC_QUALIFIER static mat<2, 3, T, Q> call(mat<3, 2, T, Q> const& m)
106+ {
107+ mat<2, 3, T, Q> Result(1);
108+ Result[0][0] = m[0][0];
109+ Result[0][1] = m[1][0];
110+ Result[0][2] = m[2][0];
111+ Result[1][0] = m[0][1];
112+ Result[1][1] = m[1][1];
113+ Result[1][2] = m[2][1];
114+ return Result;
115+ }
116+ };
117+
118+ template<typename T, qualifier Q, bool Aligned>
119+ struct compute_transpose<3, 3, T, Q, Aligned>
120+ {
121+ GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m)
122+ {
123+ mat<3, 3, T, Q> Result(1);
124+ Result[0][0] = m[0][0];
125+ Result[0][1] = m[1][0];
126+ Result[0][2] = m[2][0];
127+
128+ Result[1][0] = m[0][1];
129+ Result[1][1] = m[1][1];
130+ Result[1][2] = m[2][1];
131+
132+ Result[2][0] = m[0][2];
133+ Result[2][1] = m[1][2];
134+ Result[2][2] = m[2][2];
135+ return Result;
136+ }
137+ };
138+
139+ template<typename T, qualifier Q, bool Aligned>
140+ struct compute_transpose<3, 4, T, Q, Aligned>
141+ {
142+ GLM_FUNC_QUALIFIER static mat<4, 3, T, Q> call(mat<3, 4, T, Q> const& m)
143+ {
144+ mat<4, 3, T, Q> Result(1);
145+ Result[0][0] = m[0][0];
146+ Result[0][1] = m[1][0];
147+ Result[0][2] = m[2][0];
148+ Result[1][0] = m[0][1];
149+ Result[1][1] = m[1][1];
150+ Result[1][2] = m[2][1];
151+ Result[2][0] = m[0][2];
152+ Result[2][1] = m[1][2];
153+ Result[2][2] = m[2][2];
154+ Result[3][0] = m[0][3];
155+ Result[3][1] = m[1][3];
156+ Result[3][2] = m[2][3];
157+ return Result;
158+ }
159+ };
160+
161+ template<typename T, qualifier Q, bool Aligned>
162+ struct compute_transpose<4, 2, T, Q, Aligned>
163+ {
164+ GLM_FUNC_QUALIFIER static mat<2, 4, T, Q> call(mat<4, 2, T, Q> const& m)
165+ {
166+ mat<2, 4, T, Q> Result(1);
167+ Result[0][0] = m[0][0];
168+ Result[0][1] = m[1][0];
169+ Result[0][2] = m[2][0];
170+ Result[0][3] = m[3][0];
171+ Result[1][0] = m[0][1];
172+ Result[1][1] = m[1][1];
173+ Result[1][2] = m[2][1];
174+ Result[1][3] = m[3][1];
175+ return Result;
176+ }
177+ };
178+
179+ template<typename T, qualifier Q, bool Aligned>
180+ struct compute_transpose<4, 3, T, Q, Aligned>
181+ {
182+ GLM_FUNC_QUALIFIER static mat<3, 4, T, Q> call(mat<4, 3, T, Q> const& m)
183+ {
184+ mat<3, 4, T, Q> Result(1);
185+ Result[0][0] = m[0][0];
186+ Result[0][1] = m[1][0];
187+ Result[0][2] = m[2][0];
188+ Result[0][3] = m[3][0];
189+ Result[1][0] = m[0][1];
190+ Result[1][1] = m[1][1];
191+ Result[1][2] = m[2][1];
192+ Result[1][3] = m[3][1];
193+ Result[2][0] = m[0][2];
194+ Result[2][1] = m[1][2];
195+ Result[2][2] = m[2][2];
196+ Result[2][3] = m[3][2];
197+ return Result;
198+ }
199+ };
200+
201+ template<typename T, qualifier Q, bool Aligned>
202+ struct compute_transpose<4, 4, T, Q, Aligned>
203+ {
204+ GLM_FUNC_QUALIFIER static mat<4, 4, T, Q> call(mat<4, 4, T, Q> const& m)
205+ {
206+ mat<4, 4, T, Q> Result(1);
207+ Result[0][0] = m[0][0];
208+ Result[0][1] = m[1][0];
209+ Result[0][2] = m[2][0];
210+ Result[0][3] = m[3][0];
211+
212+ Result[1][0] = m[0][1];
213+ Result[1][1] = m[1][1];
214+ Result[1][2] = m[2][1];
215+ Result[1][3] = m[3][1];
216+
217+ Result[2][0] = m[0][2];
218+ Result[2][1] = m[1][2];
219+ Result[2][2] = m[2][2];
220+ Result[2][3] = m[3][2];
221+
222+ Result[3][0] = m[0][3];
223+ Result[3][1] = m[1][3];
224+ Result[3][2] = m[2][3];
225+ Result[3][3] = m[3][3];
226+ return Result;
227+ }
228+ };
229+
230+ template<length_t C, length_t R, typename T, qualifier Q, bool IsFloat, bool Aligned>
231+ struct compute_transpose_type {
232+ GLM_FUNC_QUALIFIER static mat<R, C, T, Q> call(mat<C, R, T, Q> const& m)
233+ {
234+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE,
235+ "'transpose' only accept floating-point inputs, include <glm/ext/matrix_integer.hpp> to discard this restriction.");
236+ return detail::compute_transpose<C, R, T, Q, detail::is_aligned<Q>::value>::call(m);
237+ }
238+ };
239+
240+ template<length_t C, length_t R, typename T, qualifier Q, bool Aligned>
241+ struct compute_determinant{};
242+
243+ template<typename T, qualifier Q, bool Aligned>
244+ struct compute_determinant<2, 2, T, Q, Aligned>
245+ {
246+ GLM_FUNC_QUALIFIER static T call(mat<2, 2, T, Q> const& m)
247+ {
248+ return m[0][0] * m[1][1] - m[1][0] * m[0][1];
249+ }
250+ };
251+
252+ template<typename T, qualifier Q, bool Aligned>
253+ struct compute_determinant<3, 3, T, Q, Aligned>
254+ {
255+ GLM_FUNC_QUALIFIER static T call(mat<3, 3, T, Q> const& m)
256+ {
257+ return
258+ + m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])
259+ - m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2])
260+ + m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
261+ }
262+ };
263+
264+ template<typename T, qualifier Q, bool Aligned>
265+ struct compute_determinant<4, 4, T, Q, Aligned>
266+ {
267+ GLM_FUNC_QUALIFIER static T call(mat<4, 4, T, Q> const& m)
268+ {
269+ T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
270+ T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
271+ T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
272+ T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
273+ T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
274+ T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
275+
276+ vec<4, T, Q> DetCof(
277+ + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02),
278+ - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04),
279+ + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05),
280+ - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05));
281+
282+ return
283+ m[0][0] * DetCof[0] + m[0][1] * DetCof[1] +
284+ m[0][2] * DetCof[2] + m[0][3] * DetCof[3];
285+ }
286+ };
287+
288+ template<length_t C, length_t R, typename T, qualifier Q, bool IsFloat, bool Aligned>
289+ struct compute_determinant_type{
290+
291+ GLM_FUNC_QUALIFIER static T call(mat<C, R, T, Q> const& m)
292+ {
293+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE,
294+ "'determinant' only accept floating-point inputs, include <glm/ext/matrix_integer.hpp> to discard this restriction.");
295+ return detail::compute_determinant<C, R, T, Q, detail::is_aligned<Q>::value>::call(m);
296+ }
297+ };
298+
299+ template<length_t C, length_t R, typename T, qualifier Q, bool Aligned>
300+ struct compute_inverse{};
301+
302+ template<typename T, qualifier Q, bool Aligned>
303+ struct compute_inverse<2, 2, T, Q, Aligned>
304+ {
305+ GLM_FUNC_QUALIFIER static mat<2, 2, T, Q> call(mat<2, 2, T, Q> const& m)
306+ {
307+ T OneOverDeterminant = static_cast<T>(1) / (
308+ + m[0][0] * m[1][1]
309+ - m[1][0] * m[0][1]);
310+
311+ mat<2, 2, T, Q> Inverse(
312+ + m[1][1] * OneOverDeterminant,
313+ - m[0][1] * OneOverDeterminant,
314+ - m[1][0] * OneOverDeterminant,
315+ + m[0][0] * OneOverDeterminant);
316+
317+ return Inverse;
318+ }
319+ };
320+
321+ template<typename T, qualifier Q, bool is_aligned>
322+ struct inv3x3 {};
323+
324+ template<typename T, qualifier Q>
325+ struct inv3x3<T, Q, true>
326+ {
327+ GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m)
328+ {
329+ // see: https://www.onlinemathstutor.org/post/3x3_inverses
330+
331+ vec<4, T, Q> a = xyz0(m[0]);
332+ vec<4, T, Q> b = xyz0(m[1]);
333+ vec<4, T, Q> c = xyz0(m[2]);
334+
335+ vec<4, T, Q> i0 = compute_cross<T, Q, true>::call(b, c);
336+ vec<4, T, Q> i1 = compute_cross<T, Q, true>::call(c, a);
337+ vec<4, T, Q> i2 = compute_cross<T, Q, true>::call(a, b);
338+
339+ mat<3, 3, T, Q> Inverse;
340+ Inverse[0] = xyz(i0);
341+ Inverse[1] = xyz(i1);
342+ Inverse[2] = xyz(i2);
343+ Inverse = transpose(Inverse);
344+
345+ T Determinant = compute_dot<vec<4, T, Q>, T, true>::call(a, compute_cross<T, Q, true>::call(b, c));
346+ vec<3, T, Q> OneOverDeterminant(static_cast<T>(1) / Determinant);
347+ Inverse *= OneOverDeterminant;
348+ return Inverse;
349+ }
350+ };
351+
352+ template<typename T, qualifier Q>
353+ struct inv3x3<T, Q, false>
354+ {
355+ GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m)
356+ {
357+ T OneOverDeterminant = static_cast<T>(1) / (
358+ +m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])
359+ - m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2])
360+ + m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]));
361+
362+ mat<3, 3, T, Q> Inverse;
363+ Inverse[0][0] = +(m[1][1] * m[2][2] - m[2][1] * m[1][2]);
364+ Inverse[1][0] = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]);
365+ Inverse[2][0] = +(m[1][0] * m[2][1] - m[2][0] * m[1][1]);
366+ Inverse[0][1] = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]);
367+ Inverse[1][1] = +(m[0][0] * m[2][2] - m[2][0] * m[0][2]);
368+ Inverse[2][1] = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]);
369+ Inverse[0][2] = +(m[0][1] * m[1][2] - m[1][1] * m[0][2]);
370+ Inverse[1][2] = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]);
371+ Inverse[2][2] = +(m[0][0] * m[1][1] - m[1][0] * m[0][1]);
372+
373+ Inverse *= OneOverDeterminant;
374+ return Inverse;
375+ }
376+ };
377+
378+ template<typename T, qualifier Q, bool Aligned>
379+ struct compute_inverse<3, 3, T, Q, Aligned>
380+ {
381+ GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m)
382+ {
383+ return detail::inv3x3<T, Q, detail::is_aligned<Q>::value>::call(m);
384+ }
385+ };
386+
387+ template<typename T, qualifier Q, bool Aligned>
388+ struct compute_inverse<4, 4, T, Q, Aligned>
389+ {
390+ GLM_FUNC_QUALIFIER static mat<4, 4, T, Q> call(mat<4, 4, T, Q> const& m)
391+ {
392+ T Coef00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
393+ T Coef02 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
394+ T Coef03 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
395+
396+ T Coef04 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
397+ T Coef06 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
398+ T Coef07 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
399+
400+ T Coef08 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
401+ T Coef10 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
402+ T Coef11 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
403+
404+ T Coef12 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
405+ T Coef14 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
406+ T Coef15 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
407+
408+ T Coef16 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
409+ T Coef18 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
410+ T Coef19 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
411+
412+ T Coef20 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
413+ T Coef22 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
414+ T Coef23 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
415+
416+ vec<4, T, Q> Fac0(Coef00, Coef00, Coef02, Coef03);
417+ vec<4, T, Q> Fac1(Coef04, Coef04, Coef06, Coef07);
418+ vec<4, T, Q> Fac2(Coef08, Coef08, Coef10, Coef11);
419+ vec<4, T, Q> Fac3(Coef12, Coef12, Coef14, Coef15);
420+ vec<4, T, Q> Fac4(Coef16, Coef16, Coef18, Coef19);
421+ vec<4, T, Q> Fac5(Coef20, Coef20, Coef22, Coef23);
422+
423+ vec<4, T, Q> Vec0(m[1][0], m[0][0], m[0][0], m[0][0]);
424+ vec<4, T, Q> Vec1(m[1][1], m[0][1], m[0][1], m[0][1]);
425+ vec<4, T, Q> Vec2(m[1][2], m[0][2], m[0][2], m[0][2]);
426+ vec<4, T, Q> Vec3(m[1][3], m[0][3], m[0][3], m[0][3]);
427+
428+ vec<4, T, Q> Inv0(Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2);
429+ vec<4, T, Q> Inv1(Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4);
430+ vec<4, T, Q> Inv2(Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5);
431+ vec<4, T, Q> Inv3(Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5);
432+
433+ vec<4, T, Q> SignA(+1, -1, +1, -1);
434+ vec<4, T, Q> SignB(-1, +1, -1, +1);
435+ mat<4, 4, T, Q> Inverse(Inv0 * SignA, Inv1 * SignB, Inv2 * SignA, Inv3 * SignB);
436+
437+ vec<4, T, Q> Row0(Inverse[0][0], Inverse[1][0], Inverse[2][0], Inverse[3][0]);
438+
439+ vec<4, T, Q> Dot0(m[0] * Row0);
440+ T Dot1 = (Dot0.x + Dot0.y) + (Dot0.z + Dot0.w);
441+
442+ T OneOverDeterminant = static_cast<T>(1) / Dot1;
443+
444+ return Inverse * OneOverDeterminant;
445+ }
446+ };
447+}//namespace detail
448+
449+ template<length_t C, length_t R, typename T, qualifier Q>
450+ GLM_FUNC_QUALIFIER mat<C, R, T, Q> matrixCompMult(mat<C, R, T, Q> const& x, mat<C, R, T, Q> const& y)
451+ {
452+ return detail::compute_matrixCompMult_type<C, R, T, Q, std::numeric_limits<T>::is_iec559, detail::is_aligned<Q>::value>::call(x, y);
453+ }
454+
455+ template<length_t DA, length_t DB, typename T, qualifier Q>
456+ GLM_FUNC_QUALIFIER typename detail::outerProduct_trait<DA, DB, T, Q>::type outerProduct(vec<DA, T, Q> const& c, vec<DB, T, Q> const& r)
457+ {
458+ return detail::compute_outerProduct_type<DA, DB, T, Q, std::numeric_limits<T>::is_iec559>::call(c, r);
459+ }
460+
461+ template<length_t C, length_t R, typename T, qualifier Q>
462+ GLM_FUNC_QUALIFIER typename mat<C, R, T, Q>::transpose_type transpose(mat<C, R, T, Q> const& m)
463+ {
464+ return detail::compute_transpose_type<C, R, T, Q, std::numeric_limits<T>::is_iec559, detail::is_aligned<Q>::value>::call(m);
465+ }
466+
467+ template<length_t C, length_t R, typename T, qualifier Q>
468+ GLM_FUNC_QUALIFIER T determinant(mat<C, R, T, Q> const& m)
469+ {
470+ return detail::compute_determinant_type<C, R, T, Q, std::numeric_limits<T>::is_iec559, detail::is_aligned<Q>::value>::call(m);
471+ }
472+
473+ template<length_t C, length_t R, typename T, qualifier Q>
474+ GLM_FUNC_QUALIFIER mat<C, R, T, Q> inverse(mat<C, R, T, Q> const& m)
475+ {
476+ static_assert(std::numeric_limits<T>::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'inverse' only accept floating-point inputs");
477+ return detail::compute_inverse<C, R, T, Q, detail::is_aligned<Q>::value>::call(m);
478+ }
479+}//namespace glm
480+
481+#if GLM_CONFIG_SIMD == GLM_ENABLE
482+# include "func_matrix_simd.inl"
483+#endif
484+
@@ -0,0 +1,263 @@
1+#if GLM_ARCH & GLM_ARCH_SSE2_BIT
2+
3+#include "type_mat4x4.hpp"
4+#include "../geometric.hpp"
5+#include "../simd/matrix.h"
6+#include <cstring>
7+
8+namespace glm{
9+namespace detail
10+{
11+# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE
12+ template<qualifier Q>
13+ struct compute_matrixCompMult<4, 4, float, Q, true>
14+ {
15+ static_assert(detail::is_aligned<Q>::value, "Specialization requires aligned");
16+
17+ GLM_FUNC_QUALIFIER static mat<4, 4, float, Q> call(mat<4, 4, float, Q> const& x, mat<4, 4, float, Q> const& y)
18+ {
19+ mat<4, 4, float, Q> Result;
20+ glm_mat4_matrixCompMult(
21+ &x[0].data,
22+ &y[0].data,
23+ &Result[0].data);
24+ return Result;
25+ }
26+ };
27+# endif
28+
29+ template<qualifier Q>
30+ struct compute_transpose<4, 4, float, Q, true>
31+ {
32+ GLM_FUNC_QUALIFIER static mat<4, 4, float, Q> call(mat<4, 4, float, Q> const& m)
33+ {
34+ mat<4, 4, float, Q> Result;
35+ glm_mat4_transpose(&m[0].data, &Result[0].data);
36+ return Result;
37+ }
38+ };
39+
40+ template<qualifier Q>
41+ struct compute_transpose<3, 3, float, Q, true>
42+ {
43+ GLM_FUNC_QUALIFIER static mat<3, 3, float, Q> call(mat<3, 3, float, Q> const& m)
44+ {
45+ mat<3, 3, float, Q> Result;
46+ glm_mat3_transpose(&m[0].data, &Result[0].data);
47+ return Result;
48+ }
49+ };
50+
51+ template<qualifier Q>
52+ struct compute_determinant<4, 4, float, Q, true>
53+ {
54+ GLM_FUNC_QUALIFIER static float call(mat<4, 4, float, Q> const& m)
55+ {
56+ return _mm_cvtss_f32(glm_mat4_determinant(&m[0].data));
57+ }
58+ };
59+
60+ template<qualifier Q>
61+ struct compute_inverse<4, 4, float, Q, true>
62+ {
63+ GLM_FUNC_QUALIFIER static mat<4, 4, float, Q> call(mat<4, 4, float, Q> const& m)
64+ {
65+ mat<4, 4, float, Q> Result;
66+ glm_mat4_inverse(&m[0].data, &Result[0].data);
67+ return Result;
68+ }
69+ };
70+}//namespace detail
71+
72+# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE
73+ template<>
74+ GLM_FUNC_QUALIFIER mat<4, 4, float, aligned_lowp> outerProduct<4, 4, float, aligned_lowp>(vec<4, float, aligned_lowp> const& c, vec<4, float, aligned_lowp> const& r)
75+ {
76+ __m128 NativeResult[4];
77+ glm_mat4_outerProduct(c.data, r.data, NativeResult);
78+ mat<4, 4, float, aligned_lowp> Result;
79+ std::memcpy(&Result[0], &NativeResult[0], sizeof(Result));
80+ return Result;
81+ }
82+
83+ template<>
84+ GLM_FUNC_QUALIFIER mat<4, 4, float, aligned_mediump> outerProduct<4, 4, float, aligned_mediump>(vec<4, float, aligned_mediump> const& c, vec<4, float, aligned_mediump> const& r)
85+ {
86+ __m128 NativeResult[4];
87+ glm_mat4_outerProduct(c.data, r.data, NativeResult);
88+ mat<4, 4, float, aligned_mediump> Result;
89+ std::memcpy(&Result[0], &NativeResult[0], sizeof(Result));
90+ return Result;
91+ }
92+
93+ template<>
94+ GLM_FUNC_QUALIFIER mat<4, 4, float, aligned_highp> outerProduct<4, 4, float, aligned_highp>(vec<4, float, aligned_highp> const& c, vec<4, float, aligned_highp> const& r)
95+ {
96+ __m128 NativeResult[4];
97+ glm_mat4_outerProduct(c.data, r.data, NativeResult);
98+ mat<4, 4, float, aligned_highp> Result;
99+ std::memcpy(&Result[0], &NativeResult[0], sizeof(Result));
100+ return Result;
101+ }
102+# endif
103+}//namespace glm
104+
105+#elif GLM_ARCH & GLM_ARCH_NEON_BIT
106+
107+namespace glm {
108+#if GLM_LANG & GLM_LANG_CXX11_FLAG
109+ template <qualifier Q>
110+ GLM_FUNC_QUALIFIER
111+ typename std::enable_if<detail::is_aligned<Q>::value, mat<4, 4, float, Q>>::type
112+ operator*(mat<4, 4, float, Q> const & m1, mat<4, 4, float, Q> const & m2)
113+ {
114+ auto MulRow = [&](int l) {
115+ float32x4_t const SrcA = m2[l].data;
116+
117+ float32x4_t r = neon::mul_lane(m1[0].data, SrcA, 0);
118+ r = neon::madd_lane(r, m1[1].data, SrcA, 1);
119+ r = neon::madd_lane(r, m1[2].data, SrcA, 2);
120+ r = neon::madd_lane(r, m1[3].data, SrcA, 3);
121+
122+ return r;
123+ };
124+
125+ mat<4, 4, float, aligned_highp> Result;
126+ Result[0].data = MulRow(0);
127+ Result[1].data = MulRow(1);
128+ Result[2].data = MulRow(2);
129+ Result[3].data = MulRow(3);
130+
131+ return Result;
132+ }
133+#endif // CXX11
134+
135+namespace detail
136+{
137+ template<qualifier Q>
138+ struct compute_inverse<4, 4, float, Q, true>
139+ {
140+ GLM_FUNC_QUALIFIER static mat<4, 4, float, Q> call(mat<4, 4, float, Q> const& m)
141+ {
142+ float32x4_t const& m0 = m[0].data;
143+ float32x4_t const& m1 = m[1].data;
144+ float32x4_t const& m2 = m[2].data;
145+ float32x4_t const& m3 = m[3].data;
146+
147+ // m[2][2] * m[3][3] - m[3][2] * m[2][3];
148+ // m[2][2] * m[3][3] - m[3][2] * m[2][3];
149+ // m[1][2] * m[3][3] - m[3][2] * m[1][3];
150+ // m[1][2] * m[2][3] - m[2][2] * m[1][3];
151+
152+ float32x4_t Fac0;
153+ {
154+ float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 2), neon::dup_lane(m1, 2));
155+ float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 3), 3, m2, 3);
156+ float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 2), 3, m2, 2);
157+ float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 3), neon::dup_lane(m1, 3));
158+ Fac0 = w0 * w1 - w2 * w3;
159+ }
160+
161+ // m[2][1] * m[3][3] - m[3][1] * m[2][3];
162+ // m[2][1] * m[3][3] - m[3][1] * m[2][3];
163+ // m[1][1] * m[3][3] - m[3][1] * m[1][3];
164+ // m[1][1] * m[2][3] - m[2][1] * m[1][3];
165+
166+ float32x4_t Fac1;
167+ {
168+ float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 1), neon::dup_lane(m1, 1));
169+ float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 3), 3, m2, 3);
170+ float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 1), 3, m2, 1);
171+ float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 3), neon::dup_lane(m1, 3));
172+ Fac1 = w0 * w1 - w2 * w3;
173+ }
174+
175+ // m[2][1] * m[3][2] - m[3][1] * m[2][2];
176+ // m[2][1] * m[3][2] - m[3][1] * m[2][2];
177+ // m[1][1] * m[3][2] - m[3][1] * m[1][2];
178+ // m[1][1] * m[2][2] - m[2][1] * m[1][2];
179+
180+ float32x4_t Fac2;
181+ {
182+ float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 1), neon::dup_lane(m1, 1));
183+ float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 2), 3, m2, 2);
184+ float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 1), 3, m2, 1);
185+ float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 2), neon::dup_lane(m1, 2));
186+ Fac2 = w0 * w1 - w2 * w3;
187+ }
188+
189+ // m[2][0] * m[3][3] - m[3][0] * m[2][3];
190+ // m[2][0] * m[3][3] - m[3][0] * m[2][3];
191+ // m[1][0] * m[3][3] - m[3][0] * m[1][3];
192+ // m[1][0] * m[2][3] - m[2][0] * m[1][3];
193+
194+ float32x4_t Fac3;
195+ {
196+ float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 0), neon::dup_lane(m1, 0));
197+ float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 3), 3, m2, 3);
198+ float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 0), 3, m2, 0);
199+ float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 3), neon::dup_lane(m1, 3));
200+ Fac3 = w0 * w1 - w2 * w3;
201+ }
202+
203+ // m[2][0] * m[3][2] - m[3][0] * m[2][2];
204+ // m[2][0] * m[3][2] - m[3][0] * m[2][2];
205+ // m[1][0] * m[3][2] - m[3][0] * m[1][2];
206+ // m[1][0] * m[2][2] - m[2][0] * m[1][2];
207+
208+ float32x4_t Fac4;
209+ {
210+ float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 0), neon::dup_lane(m1, 0));
211+ float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 2), 3, m2, 2);
212+ float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 0), 3, m2, 0);
213+ float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 2), neon::dup_lane(m1, 2));
214+ Fac4 = w0 * w1 - w2 * w3;
215+ }
216+
217+ // m[2][0] * m[3][1] - m[3][0] * m[2][1];
218+ // m[2][0] * m[3][1] - m[3][0] * m[2][1];
219+ // m[1][0] * m[3][1] - m[3][0] * m[1][1];
220+ // m[1][0] * m[2][1] - m[2][0] * m[1][1];
221+
222+ float32x4_t Fac5;
223+ {
224+ float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 0), neon::dup_lane(m1, 0));
225+ float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 1), 3, m2, 1);
226+ float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 0), 3, m2, 0);
227+ float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 1), neon::dup_lane(m1, 1));
228+ Fac5 = w0 * w1 - w2 * w3;
229+ }
230+
231+ float32x4_t Vec0 = neon::copy_lane(neon::dupq_lane(m0, 0), 0, m1, 0); // (m[1][0], m[0][0], m[0][0], m[0][0]);
232+ float32x4_t Vec1 = neon::copy_lane(neon::dupq_lane(m0, 1), 0, m1, 1); // (m[1][1], m[0][1], m[0][1], m[0][1]);
233+ float32x4_t Vec2 = neon::copy_lane(neon::dupq_lane(m0, 2), 0, m1, 2); // (m[1][2], m[0][2], m[0][2], m[0][2]);
234+ float32x4_t Vec3 = neon::copy_lane(neon::dupq_lane(m0, 3), 0, m1, 3); // (m[1][3], m[0][3], m[0][3], m[0][3]);
235+
236+ float32x4_t Inv0 = Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2;
237+ float32x4_t Inv1 = Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4;
238+ float32x4_t Inv2 = Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5;
239+ float32x4_t Inv3 = Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5;
240+
241+ float32x4_t r0 = float32x4_t{-1, +1, -1, +1} * Inv0;
242+ float32x4_t r1 = float32x4_t{+1, -1, +1, -1} * Inv1;
243+ float32x4_t r2 = float32x4_t{-1, +1, -1, +1} * Inv2;
244+ float32x4_t r3 = float32x4_t{+1, -1, +1, -1} * Inv3;
245+
246+ float32x4_t det = neon::mul_lane(r0, m0, 0);
247+ det = neon::madd_lane(det, r1, m0, 1);
248+ det = neon::madd_lane(det, r2, m0, 2);
249+ det = neon::madd_lane(det, r3, m0, 3);
250+
251+ float32x4_t rdet = vdupq_n_f32(1 / vgetq_lane_f32(det, 0));
252+
253+ mat<4, 4, float, Q> r;
254+ r[0].data = vmulq_f32(r0, rdet);
255+ r[1].data = vmulq_f32(r1, rdet);
256+ r[2].data = vmulq_f32(r2, rdet);
257+ r[3].data = vmulq_f32(r3, rdet);
258+ return r;
259+ }
260+ };
261+}//namespace detail
262+}//namespace glm
263+#endif
@@ -0,0 +1,189 @@
1+/// @ref core
2+/// @file glm/detail/func_packing.inl
3+
4+#include "../common.hpp"
5+#include "type_half.hpp"
6+
7+namespace glm
8+{
9+ GLM_FUNC_QUALIFIER uint packUnorm2x16(vec2 const& v)
10+ {
11+ union
12+ {
13+ unsigned short in[2];
14+ uint out;
15+ } u;
16+
17+ vec<2, unsigned short, defaultp> result(round(clamp(v, 0.0f, 1.0f) * 65535.0f));
18+
19+ u.in[0] = result[0];
20+ u.in[1] = result[1];
21+
22+ return u.out;
23+ }
24+
25+ GLM_FUNC_QUALIFIER vec2 unpackUnorm2x16(uint p)
26+ {
27+ union
28+ {
29+ uint in;
30+ unsigned short out[2];
31+ } u;
32+
33+ u.in = p;
34+
35+ return vec2(u.out[0], u.out[1]) * 1.5259021896696421759365224689097e-5f;
36+ }
37+
38+ GLM_FUNC_QUALIFIER uint packSnorm2x16(vec2 const& v)
39+ {
40+ union
41+ {
42+ signed short in[2];
43+ uint out;
44+ } u;
45+
46+ vec<2, short, defaultp> result(round(clamp(v, -1.0f, 1.0f) * 32767.0f));
47+
48+ u.in[0] = result[0];
49+ u.in[1] = result[1];
50+
51+ return u.out;
52+ }
53+
54+ GLM_FUNC_QUALIFIER vec2 unpackSnorm2x16(uint p)
55+ {
56+ union
57+ {
58+ uint in;
59+ signed short out[2];
60+ } u;
61+
62+ u.in = p;
63+
64+ return clamp(vec2(u.out[0], u.out[1]) * 3.0518509475997192297128208258309e-5f, -1.0f, 1.0f);
65+ }
66+
67+ GLM_FUNC_QUALIFIER uint packUnorm4x8(vec4 const& v)
68+ {
69+ union
70+ {
71+ unsigned char in[4];
72+ uint out;
73+ } u;
74+
75+ vec<4, unsigned char, defaultp> result(round(clamp(v, 0.0f, 1.0f) * 255.0f));
76+
77+ u.in[0] = result[0];
78+ u.in[1] = result[1];
79+ u.in[2] = result[2];
80+ u.in[3] = result[3];
81+
82+ return u.out;
83+ }
84+
85+ GLM_FUNC_QUALIFIER vec4 unpackUnorm4x8(uint p)
86+ {
87+ union
88+ {
89+ uint in;
90+ unsigned char out[4];
91+ } u;
92+
93+ u.in = p;
94+
95+ return vec4(u.out[0], u.out[1], u.out[2], u.out[3]) * 0.0039215686274509803921568627451f;
96+ }
97+
98+ GLM_FUNC_QUALIFIER uint packSnorm4x8(vec4 const& v)
99+ {
100+ union
101+ {
102+ signed char in[4];
103+ uint out;
104+ } u;
105+
106+ vec<4, signed char, defaultp> result(round(clamp(v, -1.0f, 1.0f) * 127.0f));
107+
108+ u.in[0] = result[0];
109+ u.in[1] = result[1];
110+ u.in[2] = result[2];
111+ u.in[3] = result[3];
112+
113+ return u.out;
114+ }
115+
116+ GLM_FUNC_QUALIFIER glm::vec4 unpackSnorm4x8(uint p)
117+ {
118+ union
119+ {
120+ uint in;
121+ signed char out[4];
122+ } u;
123+
124+ u.in = p;
125+
126+ return clamp(vec4(u.out[0], u.out[1], u.out[2], u.out[3]) * 0.0078740157480315f, -1.0f, 1.0f);
127+ }
128+
129+ GLM_FUNC_QUALIFIER double packDouble2x32(uvec2 const& v)
130+ {
131+ union
132+ {
133+ uint in[2];
134+ double out;
135+ } u;
136+
137+ u.in[0] = v[0];
138+ u.in[1] = v[1];
139+
140+ return u.out;
141+ }
142+
143+ GLM_FUNC_QUALIFIER uvec2 unpackDouble2x32(double v)
144+ {
145+ union
146+ {
147+ double in;
148+ uint out[2];
149+ } u;
150+
151+ u.in = v;
152+
153+ return uvec2(u.out[0], u.out[1]);
154+ }
155+
156+ GLM_FUNC_QUALIFIER uint packHalf2x16(vec2 const& v)
157+ {
158+ union
159+ {
160+ signed short in[2];
161+ uint out;
162+ } u;
163+
164+ u.in[0] = detail::toFloat16(v.x);
165+ u.in[1] = detail::toFloat16(v.y);
166+
167+ return u.out;
168+ }
169+
170+ GLM_FUNC_QUALIFIER vec2 unpackHalf2x16(uint v)
171+ {
172+ union
173+ {
174+ uint in;
175+ signed short out[2];
176+ } u;
177+
178+ u.in = v;
179+
180+ return vec2(
181+ detail::toFloat32(u.out[0]),
182+ detail::toFloat32(u.out[1]));
183+ }
184+}//namespace glm
185+
186+#if GLM_CONFIG_SIMD == GLM_ENABLE
187+# include "func_packing_simd.inl"
188+#endif
189+
@@ -0,0 +1,6 @@
1+namespace glm{
2+namespace detail
3+{
4+
5+}//namespace detail
6+}//namespace glm
@@ -0,0 +1,163 @@
1+#include "_vectorize.hpp"
2+#include <cmath>
3+#include <limits>
4+
5+namespace glm
6+{
7+ // radians
8+ template<typename genType>
9+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType radians(genType degrees)
10+ {
11+ static_assert(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'radians' only accept floating-point input");
12+
13+ return degrees * static_cast<genType>(0.01745329251994329576923690768489);
14+ }
15+
16+ template<length_t L, typename T, qualifier Q>
17+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> radians(vec<L, T, Q> const& v)
18+ {
19+ return detail::functor1<vec, L, T, T, Q>::call(radians, v);
20+ }
21+
22+ // degrees
23+ template<typename genType>
24+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType degrees(genType radians)
25+ {
26+ static_assert(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'degrees' only accept floating-point input");
27+
28+ return radians * static_cast<genType>(57.295779513082320876798154814105);
29+ }
30+
31+ template<length_t L, typename T, qualifier Q>
32+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, T, Q> degrees(vec<L, T, Q> const& v)
33+ {
34+ return detail::functor1<vec, L, T, T, Q>::call(degrees, v);
35+ }
36+
37+ // sin
38+ using ::std::sin;
39+
40+ template<length_t L, typename T, qualifier Q>
41+ GLM_FUNC_QUALIFIER vec<L, T, Q> sin(vec<L, T, Q> const& v)
42+ {
43+ return detail::functor1<vec, L, T, T, Q>::call(sin, v);
44+ }
45+
46+ // cos
47+ using std::cos;
48+
49+ template<length_t L, typename T, qualifier Q>
50+ GLM_FUNC_QUALIFIER vec<L, T, Q> cos(vec<L, T, Q> const& v)
51+ {
52+ return detail::functor1<vec, L, T, T, Q>::call(cos, v);
53+ }
54+
55+ // tan
56+ using std::tan;
57+
58+ template<length_t L, typename T, qualifier Q>
59+ GLM_FUNC_QUALIFIER vec<L, T, Q> tan(vec<L, T, Q> const& v)
60+ {
61+ return detail::functor1<vec, L, T, T, Q>::call(tan, v);
62+ }
63+
64+ // asin
65+ using std::asin;
66+
67+ template<length_t L, typename T, qualifier Q>
68+ GLM_FUNC_QUALIFIER vec<L, T, Q> asin(vec<L, T, Q> const& v)
69+ {
70+ return detail::functor1<vec, L, T, T, Q>::call(asin, v);
71+ }
72+
73+ // acos
74+ using std::acos;
75+
76+ template<length_t L, typename T, qualifier Q>
77+ GLM_FUNC_QUALIFIER vec<L, T, Q> acos(vec<L, T, Q> const& v)
78+ {
79+ return detail::functor1<vec, L, T, T, Q>::call(acos, v);
80+ }
81+
82+ // atan
83+ template<typename genType>
84+ GLM_FUNC_QUALIFIER genType atan(genType y, genType x)
85+ {
86+ static_assert(std::numeric_limits<genType>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'atan' only accept floating-point input");
87+
88+ return ::std::atan2(y, x);
89+ }
90+
91+ template<length_t L, typename T, qualifier Q>
92+ GLM_FUNC_QUALIFIER vec<L, T, Q> atan(vec<L, T, Q> const& y, vec<L, T, Q> const& x)
93+ {
94+ return detail::functor2<vec, L, T, Q>::call(::std::atan2, y, x);
95+ }
96+
97+ using std::atan;
98+
99+ template<length_t L, typename T, qualifier Q>
100+ GLM_FUNC_QUALIFIER vec<L, T, Q> atan(vec<L, T, Q> const& v)
101+ {
102+ return detail::functor1<vec, L, T, T, Q>::call(atan, v);
103+ }
104+
105+ // sinh
106+ using std::sinh;
107+
108+ template<length_t L, typename T, qualifier Q>
109+ GLM_FUNC_QUALIFIER vec<L, T, Q> sinh(vec<L, T, Q> const& v)
110+ {
111+ return detail::functor1<vec, L, T, T, Q>::call(sinh, v);
112+ }
113+
114+ // cosh
115+ using std::cosh;
116+
117+ template<length_t L, typename T, qualifier Q>
118+ GLM_FUNC_QUALIFIER vec<L, T, Q> cosh(vec<L, T, Q> const& v)
119+ {
120+ return detail::functor1<vec, L, T, T, Q>::call(cosh, v);
121+ }
122+
123+ // tanh
124+ using std::tanh;
125+
126+ template<length_t L, typename T, qualifier Q>
127+ GLM_FUNC_QUALIFIER vec<L, T, Q> tanh(vec<L, T, Q> const& v)
128+ {
129+ return detail::functor1<vec, L, T, T, Q>::call(tanh, v);
130+ }
131+
132+ // asinh
133+ using std::asinh;
134+
135+ template<length_t L, typename T, qualifier Q>
136+ GLM_FUNC_QUALIFIER vec<L, T, Q> asinh(vec<L, T, Q> const& v)
137+ {
138+ return detail::functor1<vec, L, T, T, Q>::call(asinh, v);
139+ }
140+
141+ // acosh
142+ using std::acosh;
143+
144+ template<length_t L, typename T, qualifier Q>
145+ GLM_FUNC_QUALIFIER vec<L, T, Q> acosh(vec<L, T, Q> const& v)
146+ {
147+ return detail::functor1<vec, L, T, T, Q>::call(acosh, v);
148+ }
149+
150+ // atanh
151+ using std::atanh;
152+
153+ template<length_t L, typename T, qualifier Q>
154+ GLM_FUNC_QUALIFIER vec<L, T, Q> atanh(vec<L, T, Q> const& v)
155+ {
156+ return detail::functor1<vec, L, T, T, Q>::call(atanh, v);
157+ }
158+}//namespace glm
159+
160+#if GLM_CONFIG_SIMD == GLM_ENABLE
161+# include "func_trigonometric_simd.inl"
162+#endif
163+
@@ -0,0 +1,87 @@
1+namespace glm
2+{
3+ template<length_t L, typename T, qualifier Q>
4+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> lessThan(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
5+ {
6+ vec<L, bool, Q> Result(true);
7+ for(length_t i = 0; i < L; ++i)
8+ Result[i] = x[i] < y[i];
9+ return Result;
10+ }
11+
12+ template<length_t L, typename T, qualifier Q>
13+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> lessThanEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
14+ {
15+ vec<L, bool, Q> Result(true);
16+ for(length_t i = 0; i < L; ++i)
17+ Result[i] = x[i] <= y[i];
18+ return Result;
19+ }
20+
21+ template<length_t L, typename T, qualifier Q>
22+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> greaterThan(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
23+ {
24+ vec<L, bool, Q> Result(true);
25+ for(length_t i = 0; i < L; ++i)
26+ Result[i] = x[i] > y[i];
27+ return Result;
28+ }
29+
30+ template<length_t L, typename T, qualifier Q>
31+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> greaterThanEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
32+ {
33+ vec<L, bool, Q> Result(true);
34+ for(length_t i = 0; i < L; ++i)
35+ Result[i] = x[i] >= y[i];
36+ return Result;
37+ }
38+
39+ template<length_t L, typename T, qualifier Q>
40+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> equal(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
41+ {
42+ vec<L, bool, Q> Result(true);
43+ for(length_t i = 0; i < L; ++i)
44+ Result[i] = x[i] == y[i];
45+ return Result;
46+ }
47+
48+ template<length_t L, typename T, qualifier Q>
49+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> notEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
50+ {
51+ vec<L, bool, Q> Result(true);
52+ for(length_t i = 0; i < L; ++i)
53+ Result[i] = x[i] != y[i];
54+ return Result;
55+ }
56+
57+ template<length_t L, qualifier Q>
58+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool any(vec<L, bool, Q> const& v)
59+ {
60+ bool Result = false;
61+ for(length_t i = 0; i < L; ++i)
62+ Result = Result || v[i];
63+ return Result;
64+ }
65+
66+ template<length_t L, qualifier Q>
67+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool all(vec<L, bool, Q> const& v)
68+ {
69+ bool Result = true;
70+ for(length_t i = 0; i < L; ++i)
71+ Result = Result && v[i];
72+ return Result;
73+ }
74+
75+ template<length_t L, qualifier Q>
76+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> not_(vec<L, bool, Q> const& v)
77+ {
78+ vec<L, bool, Q> Result(true);
79+ for(length_t i = 0; i < L; ++i)
80+ Result[i] = !v[i];
81+ return Result;
82+ }
83+}//namespace glm
84+
85+#if GLM_CONFIG_SIMD == GLM_ENABLE
86+# include "func_vector_relational_simd.inl"
87+#endif
@@ -0,0 +1,6 @@
1+namespace glm{
2+namespace detail
3+{
4+
5+}//namespace detail
6+}//namespace glm
@@ -0,0 +1,264 @@
1+/// @ref core
2+/// @file glm/glm.cpp
3+
4+#ifndef GLM_ENABLE_EXPERIMENTAL
5+#define GLM_ENABLE_EXPERIMENTAL
6+#endif
7+#include "../gtx/dual_quaternion.hpp"
8+#include "../gtc/vec1.hpp"
9+#include "../gtc/quaternion.hpp"
10+#include "../ext/scalar_int_sized.hpp"
11+#include "../ext/scalar_uint_sized.hpp"
12+#include "../glm.hpp"
13+#include "../ext.hpp"
14+
15+namespace glm
16+{
17+// tvec1 type explicit instantiation
18+template struct vec<1, uint8, lowp>;
19+template struct vec<1, uint16, lowp>;
20+template struct vec<1, uint32, lowp>;
21+template struct vec<1, uint64, lowp>;
22+template struct vec<1, int8, lowp>;
23+template struct vec<1, int16, lowp>;
24+template struct vec<1, int32, lowp>;
25+template struct vec<1, int64, lowp>;
26+template struct vec<1, float32, lowp>;
27+template struct vec<1, float64, lowp>;
28+
29+template struct vec<1, uint8, mediump>;
30+template struct vec<1, uint16, mediump>;
31+template struct vec<1, uint32, mediump>;
32+template struct vec<1, uint64, mediump>;
33+template struct vec<1, int8, mediump>;
34+template struct vec<1, int16, mediump>;
35+template struct vec<1, int32, mediump>;
36+template struct vec<1, int64, mediump>;
37+template struct vec<1, float32, mediump>;
38+template struct vec<1, float64, mediump>;
39+
40+template struct vec<1, uint8, highp>;
41+template struct vec<1, uint16, highp>;
42+template struct vec<1, uint32, highp>;
43+template struct vec<1, uint64, highp>;
44+template struct vec<1, int8, highp>;
45+template struct vec<1, int16, highp>;
46+template struct vec<1, int32, highp>;
47+template struct vec<1, int64, highp>;
48+template struct vec<1, float32, highp>;
49+template struct vec<1, float64, highp>;
50+
51+// tvec2 type explicit instantiation
52+template struct vec<2, uint8, lowp>;
53+template struct vec<2, uint16, lowp>;
54+template struct vec<2, uint32, lowp>;
55+template struct vec<2, uint64, lowp>;
56+template struct vec<2, int8, lowp>;
57+template struct vec<2, int16, lowp>;
58+template struct vec<2, int32, lowp>;
59+template struct vec<2, int64, lowp>;
60+template struct vec<2, float32, lowp>;
61+template struct vec<2, float64, lowp>;
62+
63+template struct vec<2, uint8, mediump>;
64+template struct vec<2, uint16, mediump>;
65+template struct vec<2, uint32, mediump>;
66+template struct vec<2, uint64, mediump>;
67+template struct vec<2, int8, mediump>;
68+template struct vec<2, int16, mediump>;
69+template struct vec<2, int32, mediump>;
70+template struct vec<2, int64, mediump>;
71+template struct vec<2, float32, mediump>;
72+template struct vec<2, float64, mediump>;
73+
74+template struct vec<2, uint8, highp>;
75+template struct vec<2, uint16, highp>;
76+template struct vec<2, uint32, highp>;
77+template struct vec<2, uint64, highp>;
78+template struct vec<2, int8, highp>;
79+template struct vec<2, int16, highp>;
80+template struct vec<2, int32, highp>;
81+template struct vec<2, int64, highp>;
82+template struct vec<2, float32, highp>;
83+template struct vec<2, float64, highp>;
84+
85+// tvec3 type explicit instantiation
86+template struct vec<3, uint8, lowp>;
87+template struct vec<3, uint16, lowp>;
88+template struct vec<3, uint32, lowp>;
89+template struct vec<3, uint64, lowp>;
90+template struct vec<3, int8, lowp>;
91+template struct vec<3, int16, lowp>;
92+template struct vec<3, int32, lowp>;
93+template struct vec<3, int64, lowp>;
94+template struct vec<3, float32, lowp>;
95+template struct vec<3, float64, lowp>;
96+
97+template struct vec<3, uint8, mediump>;
98+template struct vec<3, uint16, mediump>;
99+template struct vec<3, uint32, mediump>;
100+template struct vec<3, uint64, mediump>;
101+template struct vec<3, int8, mediump>;
102+template struct vec<3, int16, mediump>;
103+template struct vec<3, int32, mediump>;
104+template struct vec<3, int64, mediump>;
105+template struct vec<3, float32, mediump>;
106+template struct vec<3, float64, mediump>;
107+
108+template struct vec<3, uint8, highp>;
109+template struct vec<3, uint16, highp>;
110+template struct vec<3, uint32, highp>;
111+template struct vec<3, uint64, highp>;
112+template struct vec<3, int8, highp>;
113+template struct vec<3, int16, highp>;
114+template struct vec<3, int32, highp>;
115+template struct vec<3, int64, highp>;
116+template struct vec<3, float32, highp>;
117+template struct vec<3, float64, highp>;
118+
119+// tvec4 type explicit instantiation
120+template struct vec<4, uint8, lowp>;
121+template struct vec<4, uint16, lowp>;
122+template struct vec<4, uint32, lowp>;
123+template struct vec<4, uint64, lowp>;
124+template struct vec<4, int8, lowp>;
125+template struct vec<4, int16, lowp>;
126+template struct vec<4, int32, lowp>;
127+template struct vec<4, int64, lowp>;
128+template struct vec<4, float32, lowp>;
129+template struct vec<4, float64, lowp>;
130+
131+template struct vec<4, uint8, mediump>;
132+template struct vec<4, uint16, mediump>;
133+template struct vec<4, uint32, mediump>;
134+template struct vec<4, uint64, mediump>;
135+template struct vec<4, int8, mediump>;
136+template struct vec<4, int16, mediump>;
137+template struct vec<4, int32, mediump>;
138+template struct vec<4, int64, mediump>;
139+template struct vec<4, float32, mediump>;
140+template struct vec<4, float64, mediump>;
141+
142+template struct vec<4, uint8, highp>;
143+template struct vec<4, uint16, highp>;
144+template struct vec<4, uint32, highp>;
145+template struct vec<4, uint64, highp>;
146+template struct vec<4, int8, highp>;
147+template struct vec<4, int16, highp>;
148+template struct vec<4, int32, highp>;
149+template struct vec<4, int64, highp>;
150+template struct vec<4, float32, highp>;
151+template struct vec<4, float64, highp>;
152+
153+// tmat2x2 type explicit instantiation
154+template struct mat<2, 2, float32, lowp>;
155+template struct mat<2, 2, float64, lowp>;
156+
157+template struct mat<2, 2, float32, mediump>;
158+template struct mat<2, 2, float64, mediump>;
159+
160+template struct mat<2, 2, float32, highp>;
161+template struct mat<2, 2, float64, highp>;
162+
163+// tmat2x3 type explicit instantiation
164+template struct mat<2, 3, float32, lowp>;
165+template struct mat<2, 3, float64, lowp>;
166+
167+template struct mat<2, 3, float32, mediump>;
168+template struct mat<2, 3, float64, mediump>;
169+
170+template struct mat<2, 3, float32, highp>;
171+template struct mat<2, 3, float64, highp>;
172+
173+// tmat2x4 type explicit instantiation
174+template struct mat<2, 4, float32, lowp>;
175+template struct mat<2, 4, float64, lowp>;
176+
177+template struct mat<2, 4, float32, mediump>;
178+template struct mat<2, 4, float64, mediump>;
179+
180+template struct mat<2, 4, float32, highp>;
181+template struct mat<2, 4, float64, highp>;
182+
183+// tmat3x2 type explicit instantiation
184+template struct mat<3, 2, float32, lowp>;
185+template struct mat<3, 2, float64, lowp>;
186+
187+template struct mat<3, 2, float32, mediump>;
188+template struct mat<3, 2, float64, mediump>;
189+
190+template struct mat<3, 2, float32, highp>;
191+template struct mat<3, 2, float64, highp>;
192+
193+// tmat3x3 type explicit instantiation
194+template struct mat<3, 3, float32, lowp>;
195+template struct mat<3, 3, float64, lowp>;
196+
197+template struct mat<3, 3, float32, mediump>;
198+template struct mat<3, 3, float64, mediump>;
199+
200+template struct mat<3, 3, float32, highp>;
201+template struct mat<3, 3, float64, highp>;
202+
203+// tmat3x4 type explicit instantiation
204+template struct mat<3, 4, float32, lowp>;
205+template struct mat<3, 4, float64, lowp>;
206+
207+template struct mat<3, 4, float32, mediump>;
208+template struct mat<3, 4, float64, mediump>;
209+
210+template struct mat<3, 4, float32, highp>;
211+template struct mat<3, 4, float64, highp>;
212+
213+// tmat4x2 type explicit instantiation
214+template struct mat<4, 2, float32, lowp>;
215+template struct mat<4, 2, float64, lowp>;
216+
217+template struct mat<4, 2, float32, mediump>;
218+template struct mat<4, 2, float64, mediump>;
219+
220+template struct mat<4, 2, float32, highp>;
221+template struct mat<4, 2, float64, highp>;
222+
223+// tmat4x3 type explicit instantiation
224+template struct mat<4, 3, float32, lowp>;
225+template struct mat<4, 3, float64, lowp>;
226+
227+template struct mat<4, 3, float32, mediump>;
228+template struct mat<4, 3, float64, mediump>;
229+
230+template struct mat<4, 3, float32, highp>;
231+template struct mat<4, 3, float64, highp>;
232+
233+// tmat4x4 type explicit instantiation
234+template struct mat<4, 4, float32, lowp>;
235+template struct mat<4, 4, float64, lowp>;
236+
237+template struct mat<4, 4, float32, mediump>;
238+template struct mat<4, 4, float64, mediump>;
239+
240+template struct mat<4, 4, float32, highp>;
241+template struct mat<4, 4, float64, highp>;
242+
243+// tquat type explicit instantiation
244+template struct qua<float32, lowp>;
245+template struct qua<float64, lowp>;
246+
247+template struct qua<float32, mediump>;
248+template struct qua<float64, mediump>;
249+
250+template struct qua<float32, highp>;
251+template struct qua<float64, highp>;
252+
253+//tdualquat type explicit instantiation
254+template struct tdualquat<float32, lowp>;
255+template struct tdualquat<float64, lowp>;
256+
257+template struct tdualquat<float32, mediump>;
258+template struct tdualquat<float64, mediump>;
259+
260+template struct tdualquat<float32, highp>;
261+template struct tdualquat<float64, highp>;
262+
263+}//namespace glm
264+
@@ -0,0 +1,289 @@
1+#pragma once
2+
3+#include "setup.hpp"
4+
5+namespace glm
6+{
7+ /// Qualify GLM types in term of alignment (packed, aligned) and precision in term of ULPs (lowp, mediump, highp)
8+ enum qualifier
9+ {
10+ packed_highp, ///< Typed data is tightly packed in memory and operations are executed with high precision in term of ULPs
11+ packed_mediump, ///< Typed data is tightly packed in memory and operations are executed with medium precision in term of ULPs for higher performance
12+ packed_lowp, ///< Typed data is tightly packed in memory and operations are executed with low precision in term of ULPs to maximize performance
13+
14+# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE
15+ aligned_highp, ///< Typed data is aligned in memory allowing SIMD optimizations and operations are executed with high precision in term of ULPs
16+ aligned_mediump, ///< Typed data is aligned in memory allowing SIMD optimizations and operations are executed with high precision in term of ULPs for higher performance
17+ aligned_lowp, // ///< Typed data is aligned in memory allowing SIMD optimizations and operations are executed with high precision in term of ULPs to maximize performance
18+ aligned = aligned_highp, ///< By default aligned qualifier is also high precision
19+# endif
20+
21+ highp = packed_highp, ///< By default highp qualifier is also packed
22+ mediump = packed_mediump, ///< By default mediump qualifier is also packed
23+ lowp = packed_lowp, ///< By default lowp qualifier is also packed
24+ packed = packed_highp, ///< By default packed qualifier is also high precision
25+
26+# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE && defined(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES)
27+ defaultp = aligned_highp
28+# else
29+ defaultp = highp
30+# endif
31+ };
32+
33+ typedef qualifier precision;
34+
35+ template<length_t L, typename T, qualifier Q = defaultp> struct vec;
36+ template<length_t C, length_t R, typename T, qualifier Q = defaultp> struct mat;
37+ template<typename T, qualifier Q = defaultp> struct qua;
38+
39+ template <typename T, qualifier Q = defaultp> using tvec1 = vec<1, T, Q>;
40+ template <typename T, qualifier Q = defaultp> using tvec2 = vec<2, T, Q>;
41+ template <typename T, qualifier Q = defaultp> using tvec3 = vec<3, T, Q>;
42+ template <typename T, qualifier Q = defaultp> using tvec4 = vec<4, T, Q>;
43+ template <typename T, qualifier Q = defaultp> using tmat2x2 = mat<2, 2, T, Q>;
44+ template <typename T, qualifier Q = defaultp> using tmat2x3 = mat<2, 3, T, Q>;
45+ template <typename T, qualifier Q = defaultp> using tmat2x4 = mat<2, 4, T, Q>;
46+ template <typename T, qualifier Q = defaultp> using tmat3x2 = mat<3, 2, T, Q>;
47+ template <typename T, qualifier Q = defaultp> using tmat3x3 = mat<3, 3, T, Q>;
48+ template <typename T, qualifier Q = defaultp> using tmat3x4 = mat<3, 4, T, Q>;
49+ template <typename T, qualifier Q = defaultp> using tmat4x2 = mat<4, 2, T, Q>;
50+ template <typename T, qualifier Q = defaultp> using tmat4x3 = mat<4, 3, T, Q>;
51+ template <typename T, qualifier Q = defaultp> using tmat4x4 = mat<4, 4, T, Q>;
52+ template <typename T, qualifier Q = defaultp> using tquat = qua<T, Q>;
53+
54+namespace detail
55+{
56+ template<glm::qualifier P>
57+ struct is_aligned
58+ {
59+ static const bool value = false;
60+ };
61+
62+# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE
63+ template<>
64+ struct is_aligned<glm::aligned_lowp>
65+ {
66+ static const bool value = true;
67+ };
68+
69+ template<>
70+ struct is_aligned<glm::aligned_mediump>
71+ {
72+ static const bool value = true;
73+ };
74+
75+ template<>
76+ struct is_aligned<glm::aligned_highp>
77+ {
78+ static const bool value = true;
79+ };
80+# endif
81+
82+ template<length_t L, typename T, bool is_aligned>
83+ struct storage
84+ {
85+ typedef struct type {
86+ T data[L];
87+ } type;
88+ };
89+
90+ template<length_t L, typename T>
91+ struct storage<L, T, true>
92+ {
93+ typedef struct alignas(L * sizeof(T)) type {
94+ T data[L];
95+ } type;
96+ };
97+
98+ template<typename T>
99+ struct storage<3, T, true>
100+ {
101+ typedef struct alignas(4 * sizeof(T)) type {
102+ T data[4];
103+ } type;
104+ };
105+
106+# if GLM_ARCH & GLM_ARCH_SSE2_BIT
107+ template<>
108+ struct storage<4, float, true>
109+ {
110+ typedef glm_f32vec4 type;
111+ };
112+
113+ template<>
114+ struct storage<4, int, true>
115+ {
116+ typedef glm_i32vec4 type;
117+ };
118+
119+ template<>
120+ struct storage<4, unsigned int, true>
121+ {
122+ typedef glm_u32vec4 type;
123+ };
124+
125+ template<>
126+ struct storage<3, float, true>
127+ {
128+ typedef glm_f32vec4 type;
129+ };
130+
131+ template<>
132+ struct storage<3, int, true>
133+ {
134+ typedef glm_i32vec4 type;
135+ };
136+
137+ template<>
138+ struct storage<3, unsigned int, true>
139+ {
140+ typedef glm_u32vec4 type;
141+ };
142+
143+ template<>
144+ struct storage<2, double, true>
145+ {
146+ typedef glm_f64vec2 type;
147+ };
148+
149+ template<>
150+ struct storage<2, detail::int64, true>
151+ {
152+ typedef glm_i64vec2 type;
153+ };
154+
155+ template<>
156+ struct storage<2, detail::uint64, true>
157+ {
158+ typedef glm_u64vec2 type;
159+ };
160+
161+
162+ template<>
163+ struct storage<3, detail::uint64, true>
164+ {
165+ typedef glm_u64vec2 type;
166+ };
167+
168+ template<>
169+ struct storage<4, double, true>
170+ {
171+# if (GLM_ARCH & GLM_ARCH_AVX_BIT)
172+ typedef glm_f64vec4 type;
173+# else
174+ struct type
175+ {
176+ glm_f64vec2 data[2];
177+ GLM_CONSTEXPR glm_f64vec2 getv(int i) const {
178+ return data[i];
179+ }
180+ GLM_CONSTEXPR void setv(int i, const glm_f64vec2& v) {
181+ data[i] = v;
182+ }
183+ };
184+# endif
185+ };
186+
187+
188+ template<>
189+ struct storage<3, double, true> : public storage<4, double, true>
190+ {};
191+
192+# endif
193+
194+# if (GLM_ARCH & GLM_ARCH_AVX2_BIT)
195+ template<>
196+ struct storage<4, detail::int64, true>
197+ {
198+ typedef glm_i64vec4 type;
199+ };
200+
201+ template<>
202+ struct storage<4, detail::uint64, true>
203+ {
204+ typedef glm_u64vec4 type;
205+ };
206+# endif
207+
208+# if GLM_ARCH & GLM_ARCH_NEON_BIT
209+ template<>
210+ struct storage<4, float, true>
211+ {
212+ typedef glm_f32vec4 type;
213+ };
214+
215+ template<>
216+ struct storage<3, float, true> : public storage<4, float, true>
217+ {};
218+
219+ template<>
220+ struct storage<4, int, true>
221+ {
222+ typedef glm_i32vec4 type;
223+ };
224+
225+ template<>
226+ struct storage<3, int, true> : public storage<4, int, true>
227+ {};
228+
229+ template<>
230+ struct storage<4, unsigned int, true>
231+ {
232+ typedef glm_u32vec4 type;
233+ };
234+/* TODO: Duplicate ?
235+ template<>
236+ struct storage<3, unsigned int, true> : public storage<4, unsigned int, true>
237+ {};
238+
239+ template<>
240+ struct storage<3, double, true>
241+ {
242+ typedef struct alignas(4 * sizeof(double)) type {
243+ double data[4];
244+ } type;
245+ };
246+*/
247+# endif
248+
249+ enum genTypeEnum
250+ {
251+ GENTYPE_VEC,
252+ GENTYPE_MAT,
253+ GENTYPE_QUAT
254+ };
255+
256+ template <typename genType>
257+ struct genTypeTrait
258+ {};
259+
260+ template <length_t C, length_t R, typename T>
261+ struct genTypeTrait<mat<C, R, T> >
262+ {
263+ static const genTypeEnum GENTYPE = GENTYPE_MAT;
264+ };
265+
266+ template<typename genType, genTypeEnum type>
267+ struct init_gentype
268+ {
269+ };
270+
271+ template<typename genType>
272+ struct init_gentype<genType, GENTYPE_QUAT>
273+ {
274+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static genType identity()
275+ {
276+ return genType(1, 0, 0, 0);
277+ }
278+ };
279+
280+ template<typename genType>
281+ struct init_gentype<genType, GENTYPE_MAT>
282+ {
283+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR static genType identity()
284+ {
285+ return genType(1);
286+ }
287+ };
288+}//namespace detail
289+}//namespace glm
@@ -0,0 +1,785 @@
1+#ifndef GLM_SETUP_INCLUDED
2+
3+#include <cassert>
4+#include <cstddef>
5+#include <type_traits>
6+
7+#define GLM_VERSION_MAJOR 1
8+#define GLM_VERSION_MINOR 1
9+#define GLM_VERSION_PATCH 0
10+#define GLM_VERSION_REVISION 0 // Deprecated
11+#define GLM_VERSION 1000 // Deprecated
12+
13+#define GLM_MAKE_API_VERSION(variant, major, minor, patch) \
14+ ((((uint32_t)(variant)) << 29U) | (((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch)))
15+
16+#define GLM_VERSION_COMPLETE GLM_MAKE_API_VERSION(0, GLM_VERSION_MAJOR, GLM_VERSION_MINOR, GLM_VERSION_PATCH)
17+
18+#define GLM_SETUP_INCLUDED GLM_VERSION
19+
20+#define GLM_GET_VERSION_VARIANT(version) ((uint32_t)(version) >> 29U)
21+#define GLM_GET_VERSION_MAJOR(version) (((uint32_t)(version) >> 22U) & 0x7FU)
22+#define GLM_GET_VERSION_MINOR(version) (((uint32_t)(version) >> 12U) & 0x3FFU)
23+#define GLM_GET_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU)
24+
25+///////////////////////////////////////////////////////////////////////////////////
26+// Active states
27+
28+#define GLM_DISABLE 0
29+#define GLM_ENABLE 1
30+
31+///////////////////////////////////////////////////////////////////////////////////
32+// Messages
33+
34+#if defined(GLM_FORCE_MESSAGES)
35+# define GLM_MESSAGES GLM_ENABLE
36+#else
37+# define GLM_MESSAGES GLM_DISABLE
38+#endif
39+
40+///////////////////////////////////////////////////////////////////////////////////
41+// Detect the platform
42+
43+#include "../simd/platform.h"
44+
45+///////////////////////////////////////////////////////////////////////////////////
46+// Build model
47+
48+#if defined(_M_ARM64) || defined(__LP64__) || defined(_M_X64) || defined(__ppc64__) || defined(__x86_64__)
49+# define GLM_MODEL GLM_MODEL_64
50+#elif defined(__i386__) || defined(__ppc__) || defined(__ILP32__) || defined(_M_ARM)
51+# define GLM_MODEL GLM_MODEL_32
52+#else
53+# define GLM_MODEL GLM_MODEL_32
54+#endif//
55+
56+#if !defined(GLM_MODEL) && GLM_COMPILER != 0
57+# error "GLM_MODEL undefined, your compiler may not be supported by GLM. Add #define GLM_MODEL 0 to ignore this message."
58+#endif//GLM_MODEL
59+
60+///////////////////////////////////////////////////////////////////////////////////
61+// C++ Version
62+
63+// User defines: GLM_FORCE_CXX98, GLM_FORCE_CXX03, GLM_FORCE_CXX11, GLM_FORCE_CXX14, GLM_FORCE_CXX17, GLM_FORCE_CXX2A
64+
65+#define GLM_LANG_CXX98_FLAG (1 << 1)
66+#define GLM_LANG_CXX03_FLAG (1 << 2)
67+#define GLM_LANG_CXX0X_FLAG (1 << 3)
68+#define GLM_LANG_CXX11_FLAG (1 << 4)
69+#define GLM_LANG_CXX14_FLAG (1 << 5)
70+#define GLM_LANG_CXX17_FLAG (1 << 6)
71+#define GLM_LANG_CXX20_FLAG (1 << 7)
72+#define GLM_LANG_CXX23_FLAG (1 << 8)
73+#define GLM_LANG_CXXMS_FLAG (1 << 9)
74+#define GLM_LANG_CXXGNU_FLAG (1 << 10)
75+
76+#define GLM_LANG_CXX98 GLM_LANG_CXX98_FLAG
77+#define GLM_LANG_CXX03 (GLM_LANG_CXX98 | GLM_LANG_CXX03_FLAG)
78+#define GLM_LANG_CXX0X (GLM_LANG_CXX03 | GLM_LANG_CXX0X_FLAG)
79+#define GLM_LANG_CXX11 (GLM_LANG_CXX0X | GLM_LANG_CXX11_FLAG)
80+#define GLM_LANG_CXX14 (GLM_LANG_CXX11 | GLM_LANG_CXX14_FLAG)
81+#define GLM_LANG_CXX17 (GLM_LANG_CXX14 | GLM_LANG_CXX17_FLAG)
82+#define GLM_LANG_CXX20 (GLM_LANG_CXX17 | GLM_LANG_CXX20_FLAG)
83+#define GLM_LANG_CXX23 (GLM_LANG_CXX20 | GLM_LANG_CXX23_FLAG)
84+#define GLM_LANG_CXXMS GLM_LANG_CXXMS_FLAG
85+#define GLM_LANG_CXXGNU GLM_LANG_CXXGNU_FLAG
86+
87+#if (defined(_MSC_EXTENSIONS))
88+# define GLM_LANG_EXT GLM_LANG_CXXMS_FLAG
89+#elif ((GLM_COMPILER & (GLM_COMPILER_CLANG | GLM_COMPILER_GCC)) && (GLM_ARCH & GLM_ARCH_SIMD_BIT))
90+# define GLM_LANG_EXT GLM_LANG_CXXMS_FLAG
91+#else
92+# define GLM_LANG_EXT 0
93+#endif
94+
95+#if (defined(GLM_FORCE_CXX_UNKNOWN))
96+# define GLM_LANG 0
97+#elif defined(GLM_FORCE_CXX20)
98+# define GLM_LANG (GLM_LANG_CXX20 | GLM_LANG_EXT)
99+#elif defined(GLM_FORCE_CXX17)
100+# define GLM_LANG (GLM_LANG_CXX17 | GLM_LANG_EXT)
101+#else
102+# if GLM_COMPILER & GLM_COMPILER_VC && defined(_MSVC_LANG)
103+# if GLM_COMPILER >= GLM_COMPILER_VC15_7
104+# define GLM_LANG_PLATFORM _MSVC_LANG
105+# elif GLM_COMPILER >= GLM_COMPILER_VC15
106+# if _MSVC_LANG > 201402L
107+# define GLM_LANG_PLATFORM 201402L
108+# else
109+# define GLM_LANG_PLATFORM _MSVC_LANG
110+# endif
111+# else
112+# define GLM_LANG_PLATFORM 0
113+# endif
114+# else
115+# define GLM_LANG_PLATFORM 0
116+# endif
117+
118+# if __cplusplus > 202302L || GLM_LANG_PLATFORM > 202302L
119+# define GLM_LANG (GLM_LANG_CXX23 | GLM_LANG_EXT)
120+# elif __cplusplus == 202302L || GLM_LANG_PLATFORM == 202302L
121+# define GLM_LANG (GLM_LANG_CXX23 | GLM_LANG_EXT)
122+# elif __cplusplus == 202002L || GLM_LANG_PLATFORM == 202002L
123+# define GLM_LANG (GLM_LANG_CXX20 | GLM_LANG_EXT)
124+# elif __cplusplus == 201703L || GLM_LANG_PLATFORM == 201703L
125+# define GLM_LANG (GLM_LANG_CXX17 | GLM_LANG_EXT)
126+# else
127+# define GLM_LANG (0 | GLM_LANG_EXT)
128+# endif
129+#endif
130+
131+///////////////////////////////////////////////////////////////////////////////////
132+// Has of C++ features
133+
134+// N2235 Generalized Constant Expressions http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf
135+// N3652 Extended Constant Expressions http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3652.html
136+#if (GLM_ARCH & GLM_ARCH_SIMD_BIT) // Compiler SIMD intrinsics don't support constexpr...
137+# define GLM_HAS_CONSTEXPR 0
138+#else
139+# define GLM_HAS_CONSTEXPR 1
140+#endif
141+
142+#if GLM_HAS_CONSTEXPR
143+# define GLM_CONSTEXPR constexpr
144+#else
145+# define GLM_CONSTEXPR
146+#endif
147+
148+//
149+#if defined(GLM_FORCE_INTRINSICS)
150+# define GLM_HAS_BITSCAN_WINDOWS ((GLM_PLATFORM & GLM_PLATFORM_WINDOWS) && (\
151+ ((GLM_COMPILER & GLM_COMPILER_INTEL)) || \
152+ ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC14) && (GLM_ARCH & GLM_ARCH_X86_BIT))))
153+#else
154+# define GLM_HAS_BITSCAN_WINDOWS 0
155+#endif
156+
157+///////////////////////////////////////////////////////////////////////////////////
158+// OpenMP
159+#ifdef _OPENMP
160+# if GLM_COMPILER & GLM_COMPILER_GCC
161+# if GLM_COMPILER >= GLM_COMPILER_GCC61
162+# define GLM_HAS_OPENMP 45
163+# elif GLM_COMPILER >= GLM_COMPILER_GCC49
164+# define GLM_HAS_OPENMP 40
165+# elif GLM_COMPILER >= GLM_COMPILER_GCC47
166+# define GLM_HAS_OPENMP 31
167+# else
168+# define GLM_HAS_OPENMP 0
169+# endif
170+# elif GLM_COMPILER & GLM_COMPILER_CLANG
171+# if GLM_COMPILER >= GLM_COMPILER_CLANG38
172+# define GLM_HAS_OPENMP 31
173+# else
174+# define GLM_HAS_OPENMP 0
175+# endif
176+# elif GLM_COMPILER & GLM_COMPILER_VC
177+# define GLM_HAS_OPENMP 20
178+# elif GLM_COMPILER & GLM_COMPILER_INTEL
179+# if GLM_COMPILER >= GLM_COMPILER_INTEL16
180+# define GLM_HAS_OPENMP 40
181+# else
182+# define GLM_HAS_OPENMP 0
183+# endif
184+# else
185+# define GLM_HAS_OPENMP 0
186+# endif
187+#else
188+# define GLM_HAS_OPENMP 0
189+#endif
190+
191+///////////////////////////////////////////////////////////////////////////////////
192+// Qualifiers
193+
194+// User defines: GLM_CUDA_FORCE_DEVICE_FUNC, GLM_CUDA_FORCE_HOST_FUNC
195+
196+#if (GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP)
197+# if defined(GLM_CUDA_FORCE_DEVICE_FUNC) && defined(GLM_CUDA_FORCE_HOST_FUNC)
198+# error "GLM error: GLM_CUDA_FORCE_DEVICE_FUNC and GLM_CUDA_FORCE_HOST_FUNC should not be defined at the same time, GLM by default generates both device and host code for CUDA compiler."
199+# endif//defined(GLM_CUDA_FORCE_DEVICE_FUNC) && defined(GLM_CUDA_FORCE_HOST_FUNC)
200+
201+# if defined(GLM_CUDA_FORCE_DEVICE_FUNC)
202+# define GLM_CUDA_FUNC_DEF __device__
203+# define GLM_CUDA_FUNC_DECL __device__
204+# elif defined(GLM_CUDA_FORCE_HOST_FUNC)
205+# define GLM_CUDA_FUNC_DEF __host__
206+# define GLM_CUDA_FUNC_DECL __host__
207+# else
208+# define GLM_CUDA_FUNC_DEF __device__ __host__
209+# define GLM_CUDA_FUNC_DECL __device__ __host__
210+# endif//defined(GLM_CUDA_FORCE_XXXX_FUNC)
211+#else
212+# define GLM_CUDA_FUNC_DEF
213+# define GLM_CUDA_FUNC_DECL
214+#endif
215+
216+#if defined(GLM_FORCE_INLINE)
217+# if GLM_COMPILER & GLM_COMPILER_VC
218+# define GLM_INLINE __forceinline
219+# define GLM_NEVER_INLINE __declspec(noinline)
220+# elif GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG)
221+# define GLM_INLINE inline __attribute__((__always_inline__))
222+# define GLM_NEVER_INLINE __attribute__((__noinline__))
223+# elif (GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP)
224+# define GLM_INLINE __forceinline__
225+# define GLM_NEVER_INLINE __noinline__
226+# else
227+# define GLM_INLINE inline
228+# define GLM_NEVER_INLINE
229+# endif//GLM_COMPILER
230+#else
231+# define GLM_INLINE inline
232+# define GLM_NEVER_INLINE
233+#endif//defined(GLM_FORCE_INLINE)
234+
235+#define GLM_CTOR_DECL GLM_CUDA_FUNC_DECL GLM_CONSTEXPR
236+#define GLM_FUNC_DISCARD_DECL GLM_CUDA_FUNC_DECL
237+#define GLM_FUNC_DECL [[nodiscard]] GLM_CUDA_FUNC_DECL
238+#define GLM_FUNC_QUALIFIER GLM_CUDA_FUNC_DEF GLM_INLINE
239+
240+// Do not use CUDA function qualifiers on CUDA compiler when functions are made default
241+
242+#if !defined(GLM_FORCE_CTOR_INIT)
243+# define GLM_DEFAULTED_DEFAULT_CTOR_DECL
244+# define GLM_DEFAULTED_DEFAULT_CTOR_QUALIFIER GLM_INLINE
245+#else
246+# define GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_FUNC_DISCARD_DECL
247+# define GLM_DEFAULTED_DEFAULT_CTOR_QUALIFIER GLM_FUNC_QUALIFIER
248+#endif//GLM_FORCE_CTOR_INIT
249+
250+///////////////////////////////////////////////////////////////////////////////////
251+// Swizzle operators
252+
253+// User defines: GLM_FORCE_SWIZZLE
254+
255+#define GLM_SWIZZLE_DISABLED 0
256+#define GLM_SWIZZLE_OPERATOR 1
257+#define GLM_SWIZZLE_FUNCTION 2
258+
259+#if defined(GLM_SWIZZLE)
260+# pragma message("GLM: GLM_SWIZZLE is deprecated, use GLM_FORCE_SWIZZLE instead.")
261+# define GLM_FORCE_SWIZZLE
262+#endif
263+
264+#if defined(GLM_FORCE_SWIZZLE) && (GLM_LANG & GLM_LANG_CXXMS_FLAG) && !defined(GLM_FORCE_XYZW_ONLY)
265+# define GLM_CONFIG_SWIZZLE GLM_SWIZZLE_OPERATOR
266+#elif defined(GLM_FORCE_SWIZZLE)
267+# define GLM_CONFIG_SWIZZLE GLM_SWIZZLE_FUNCTION
268+#else
269+# define GLM_CONFIG_SWIZZLE GLM_SWIZZLE_DISABLED
270+#endif
271+
272+///////////////////////////////////////////////////////////////////////////////////
273+// Allows using not basic types as genType
274+
275+// #define GLM_FORCE_UNRESTRICTED_GENTYPE
276+
277+#ifdef GLM_FORCE_UNRESTRICTED_GENTYPE
278+# define GLM_CONFIG_UNRESTRICTED_GENTYPE GLM_ENABLE
279+#else
280+# define GLM_CONFIG_UNRESTRICTED_GENTYPE GLM_DISABLE
281+#endif
282+
283+///////////////////////////////////////////////////////////////////////////////////
284+// Allows using any scaler as float
285+
286+// #define GLM_FORCE_UNRESTRICTED_FLOAT
287+
288+#ifdef GLM_FORCE_UNRESTRICTED_FLOAT
289+# define GLM_CONFIG_UNRESTRICTED_FLOAT GLM_ENABLE
290+#else
291+# define GLM_CONFIG_UNRESTRICTED_FLOAT GLM_DISABLE
292+#endif
293+
294+///////////////////////////////////////////////////////////////////////////////////
295+// Clip control, define GLM_FORCE_DEPTH_ZERO_TO_ONE before including GLM
296+// to use a clip space between 0 to 1.
297+// Coordinate system, define GLM_FORCE_LEFT_HANDED before including GLM
298+// to use left handed coordinate system by default.
299+
300+#define GLM_CLIP_CONTROL_ZO_BIT (1 << 0) // ZERO_TO_ONE
301+#define GLM_CLIP_CONTROL_NO_BIT (1 << 1) // NEGATIVE_ONE_TO_ONE
302+#define GLM_CLIP_CONTROL_LH_BIT (1 << 2) // LEFT_HANDED, For DirectX, Metal, Vulkan
303+#define GLM_CLIP_CONTROL_RH_BIT (1 << 3) // RIGHT_HANDED, For OpenGL, default in GLM
304+
305+#define GLM_CLIP_CONTROL_LH_ZO (GLM_CLIP_CONTROL_LH_BIT | GLM_CLIP_CONTROL_ZO_BIT)
306+#define GLM_CLIP_CONTROL_LH_NO (GLM_CLIP_CONTROL_LH_BIT | GLM_CLIP_CONTROL_NO_BIT)
307+#define GLM_CLIP_CONTROL_RH_ZO (GLM_CLIP_CONTROL_RH_BIT | GLM_CLIP_CONTROL_ZO_BIT)
308+#define GLM_CLIP_CONTROL_RH_NO (GLM_CLIP_CONTROL_RH_BIT | GLM_CLIP_CONTROL_NO_BIT)
309+
310+#ifdef GLM_FORCE_DEPTH_ZERO_TO_ONE
311+# ifdef GLM_FORCE_LEFT_HANDED
312+# define GLM_CONFIG_CLIP_CONTROL GLM_CLIP_CONTROL_LH_ZO
313+# else
314+# define GLM_CONFIG_CLIP_CONTROL GLM_CLIP_CONTROL_RH_ZO
315+# endif
316+#else
317+# ifdef GLM_FORCE_LEFT_HANDED
318+# define GLM_CONFIG_CLIP_CONTROL GLM_CLIP_CONTROL_LH_NO
319+# else
320+# define GLM_CONFIG_CLIP_CONTROL GLM_CLIP_CONTROL_RH_NO
321+# endif
322+#endif
323+
324+///////////////////////////////////////////////////////////////////////////////////
325+// Qualifiers
326+
327+#if (GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))
328+# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef __declspec(align(alignment)) type name
329+#elif GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG | GLM_COMPILER_INTEL)
330+# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef type name __attribute__((aligned(alignment)))
331+#elif (GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP)
332+# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef type name __align__(x)
333+#else
334+# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef type name
335+#endif
336+
337+///////////////////////////////////////////////////////////////////////////////////
338+
339+#ifdef GLM_FORCE_EXPLICIT_CTOR
340+# define GLM_EXPLICIT explicit
341+#else
342+# define GLM_EXPLICIT
343+#endif
344+
345+///////////////////////////////////////////////////////////////////////////////////
346+// Length type: all length functions returns a length_t type.
347+// When GLM_FORCE_SIZE_T_LENGTH is defined, length_t is a typedef of size_t otherwise
348+// length_t is a typedef of int like GLSL defines it.
349+
350+#define GLM_LENGTH_INT 1
351+#define GLM_LENGTH_SIZE_T 2
352+
353+#ifdef GLM_FORCE_SIZE_T_LENGTH
354+# define GLM_CONFIG_LENGTH_TYPE GLM_LENGTH_SIZE_T
355+# define GLM_ASSERT_LENGTH(l, max) (assert ((l) < (max)))
356+#else
357+# define GLM_CONFIG_LENGTH_TYPE GLM_LENGTH_INT
358+# define GLM_ASSERT_LENGTH(l, max) (assert ((l) >= 0 && (l) < (max)))
359+#endif
360+
361+namespace glm
362+{
363+ using std::size_t;
364+# if GLM_CONFIG_LENGTH_TYPE == GLM_LENGTH_SIZE_T
365+ typedef size_t length_t;
366+# else
367+ typedef int length_t;
368+# endif
369+}//namespace glm
370+
371+///////////////////////////////////////////////////////////////////////////////////
372+// uint
373+
374+#include <cstdint>
375+
376+namespace glm{
377+namespace detail
378+{
379+ typedef std::int8_t int8;
380+ typedef std::int16_t int16;
381+ typedef std::int32_t int32;
382+ typedef std::int64_t int64;
383+
384+ typedef std::uint8_t uint8;
385+ typedef std::uint16_t uint16;
386+ typedef std::uint32_t uint32;
387+ typedef std::uint64_t uint64;
388+
389+ template<typename T>
390+ struct is_int
391+ {
392+ enum test {value = 0};
393+ };
394+
395+ template<>
396+ struct is_int<int8>
397+ {
398+ enum test {value = ~0};
399+ };
400+
401+ template<>
402+ struct is_int<int16>
403+ {
404+ enum test {value = ~0};
405+ };
406+
407+ template<>
408+ struct is_int<int32>
409+ {
410+ enum test {value = ~0};
411+ };
412+
413+ template<>
414+ struct is_int<int64>
415+ {
416+ enum test {value = ~0};
417+ };
418+
419+ template<>
420+ struct is_int<uint8>
421+ {
422+ enum test {value = ~0};
423+ };
424+
425+ template<>
426+ struct is_int<uint16>
427+ {
428+ enum test {value = ~0};
429+ };
430+
431+ template<>
432+ struct is_int<uint32>
433+ {
434+ enum test {value = ~0};
435+ };
436+
437+ template<>
438+ struct is_int<uint64>
439+ {
440+ enum test {value = ~0};
441+ };
442+}//namespace detail
443+
444+ typedef unsigned int uint;
445+}//namespace glm
446+
447+///////////////////////////////////////////////////////////////////////////////////
448+// Only use x, y, z, w as vector type components
449+
450+#ifdef GLM_FORCE_XYZW_ONLY
451+# define GLM_CONFIG_XYZW_ONLY GLM_ENABLE
452+#else
453+# define GLM_CONFIG_XYZW_ONLY GLM_DISABLE
454+#endif
455+
456+///////////////////////////////////////////////////////////////////////////////////
457+// Use SIMD instruction sets
458+
459+#if (GLM_LANG & GLM_LANG_CXXMS_FLAG) && (GLM_ARCH & GLM_ARCH_SIMD_BIT)
460+# define GLM_CONFIG_SIMD GLM_ENABLE
461+#else
462+# define GLM_CONFIG_SIMD GLM_DISABLE
463+#endif
464+
465+///////////////////////////////////////////////////////////////////////////////////
466+// Configure the use of defaulted initialized types
467+
468+#if defined(GLM_FORCE_CTOR_INIT)
469+# define GLM_CONFIG_CTOR_INIT GLM_ENABLE
470+#else
471+# define GLM_CONFIG_CTOR_INIT GLM_DISABLE
472+#endif
473+
474+///////////////////////////////////////////////////////////////////////////////////
475+// Configure the use of defaulted function
476+
477+#define GLM_DEFAULT = default
478+
479+#if GLM_CONFIG_CTOR_INIT == GLM_DISABLE
480+# define GLM_DEFAULT_CTOR GLM_DEFAULT
481+#else
482+# define GLM_DEFAULT_CTOR
483+#endif
484+
485+///////////////////////////////////////////////////////////////////////////////////
486+// Configure the use of aligned gentypes
487+
488+#ifdef GLM_FORCE_ALIGNED // Legacy define
489+# define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES
490+#endif
491+
492+#ifdef GLM_FORCE_DEFAULT_ALIGNED_GENTYPES
493+# define GLM_FORCE_ALIGNED_GENTYPES
494+#endif
495+
496+#if (GLM_LANG & GLM_LANG_CXXMS_FLAG) && (defined(GLM_FORCE_ALIGNED_GENTYPES) || (GLM_CONFIG_SIMD == GLM_ENABLE))
497+# define GLM_CONFIG_ALIGNED_GENTYPES GLM_ENABLE
498+#else
499+# define GLM_CONFIG_ALIGNED_GENTYPES GLM_DISABLE
500+#endif
501+
502+///////////////////////////////////////////////////////////////////////////////////
503+// Configure the use of anonymous structure as implementation detail
504+
505+#if ((GLM_CONFIG_SIMD == GLM_ENABLE) || (GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR) || (GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE))
506+# define GLM_CONFIG_ANONYMOUS_STRUCT GLM_ENABLE
507+#else
508+# define GLM_CONFIG_ANONYMOUS_STRUCT GLM_DISABLE
509+#endif
510+
511+///////////////////////////////////////////////////////////////////////////////////
512+// Silent warnings
513+
514+#ifdef GLM_FORCE_WARNINGS
515+# define GLM_SILENT_WARNINGS GLM_DISABLE
516+#else
517+# define GLM_SILENT_WARNINGS GLM_ENABLE
518+#endif
519+
520+///////////////////////////////////////////////////////////////////////////////////
521+// Precision
522+
523+#define GLM_HIGHP 1
524+#define GLM_MEDIUMP 2
525+#define GLM_LOWP 3
526+
527+#if defined(GLM_FORCE_PRECISION_HIGHP_BOOL) || defined(GLM_PRECISION_HIGHP_BOOL)
528+# define GLM_CONFIG_PRECISION_BOOL GLM_HIGHP
529+#elif defined(GLM_FORCE_PRECISION_MEDIUMP_BOOL) || defined(GLM_PRECISION_MEDIUMP_BOOL)
530+# define GLM_CONFIG_PRECISION_BOOL GLM_MEDIUMP
531+#elif defined(GLM_FORCE_PRECISION_LOWP_BOOL) || defined(GLM_PRECISION_LOWP_BOOL)
532+# define GLM_CONFIG_PRECISION_BOOL GLM_LOWP
533+#else
534+# define GLM_CONFIG_PRECISION_BOOL GLM_HIGHP
535+#endif
536+
537+#if defined(GLM_FORCE_PRECISION_HIGHP_INT) || defined(GLM_PRECISION_HIGHP_INT)
538+# define GLM_CONFIG_PRECISION_INT GLM_HIGHP
539+#elif defined(GLM_FORCE_PRECISION_MEDIUMP_INT) || defined(GLM_PRECISION_MEDIUMP_INT)
540+# define GLM_CONFIG_PRECISION_INT GLM_MEDIUMP
541+#elif defined(GLM_FORCE_PRECISION_LOWP_INT) || defined(GLM_PRECISION_LOWP_INT)
542+# define GLM_CONFIG_PRECISION_INT GLM_LOWP
543+#else
544+# define GLM_CONFIG_PRECISION_INT GLM_HIGHP
545+#endif
546+
547+#if defined(GLM_FORCE_PRECISION_HIGHP_UINT) || defined(GLM_PRECISION_HIGHP_UINT)
548+# define GLM_CONFIG_PRECISION_UINT GLM_HIGHP
549+#elif defined(GLM_FORCE_PRECISION_MEDIUMP_UINT) || defined(GLM_PRECISION_MEDIUMP_UINT)
550+# define GLM_CONFIG_PRECISION_UINT GLM_MEDIUMP
551+#elif defined(GLM_FORCE_PRECISION_LOWP_UINT) || defined(GLM_PRECISION_LOWP_UINT)
552+# define GLM_CONFIG_PRECISION_UINT GLM_LOWP
553+#else
554+# define GLM_CONFIG_PRECISION_UINT GLM_HIGHP
555+#endif
556+
557+#if defined(GLM_FORCE_PRECISION_HIGHP_FLOAT) || defined(GLM_PRECISION_HIGHP_FLOAT)
558+# define GLM_CONFIG_PRECISION_FLOAT GLM_HIGHP
559+#elif defined(GLM_FORCE_PRECISION_MEDIUMP_FLOAT) || defined(GLM_PRECISION_MEDIUMP_FLOAT)
560+# define GLM_CONFIG_PRECISION_FLOAT GLM_MEDIUMP
561+#elif defined(GLM_FORCE_PRECISION_LOWP_FLOAT) || defined(GLM_PRECISION_LOWP_FLOAT)
562+# define GLM_CONFIG_PRECISION_FLOAT GLM_LOWP
563+#else
564+# define GLM_CONFIG_PRECISION_FLOAT GLM_HIGHP
565+#endif
566+
567+#if defined(GLM_FORCE_PRECISION_HIGHP_DOUBLE) || defined(GLM_PRECISION_HIGHP_DOUBLE)
568+# define GLM_CONFIG_PRECISION_DOUBLE GLM_HIGHP
569+#elif defined(GLM_FORCE_PRECISION_MEDIUMP_DOUBLE) || defined(GLM_PRECISION_MEDIUMP_DOUBLE)
570+# define GLM_CONFIG_PRECISION_DOUBLE GLM_MEDIUMP
571+#elif defined(GLM_FORCE_PRECISION_LOWP_DOUBLE) || defined(GLM_PRECISION_LOWP_DOUBLE)
572+# define GLM_CONFIG_PRECISION_DOUBLE GLM_LOWP
573+#else
574+# define GLM_CONFIG_PRECISION_DOUBLE GLM_HIGHP
575+#endif
576+
577+///////////////////////////////////////////////////////////////////////////////////
578+// Check inclusions of different versions of GLM
579+
580+#elif ((GLM_SETUP_INCLUDED != GLM_VERSION) && !defined(GLM_FORCE_IGNORE_VERSION))
581+# error "GLM error: A different version of GLM is already included. Define GLM_FORCE_IGNORE_VERSION before including GLM headers to ignore this error."
582+#elif GLM_SETUP_INCLUDED == GLM_VERSION
583+
584+///////////////////////////////////////////////////////////////////////////////////
585+// Messages
586+
587+#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_MESSAGE_DISPLAYED)
588+# define GLM_MESSAGE_DISPLAYED
589+# define GLM_STR_HELPER(x) #x
590+# define GLM_STR(x) GLM_STR_HELPER(x)
591+
592+ // Report GLM version
593+# pragma message ("GLM: version " GLM_STR(GLM_VERSION_MAJOR) "." GLM_STR(GLM_VERSION_MINOR) "." GLM_STR(GLM_VERSION_PATCH))
594+
595+ // Report C++ language
596+# if (GLM_LANG & GLM_LANG_CXX23_FLAG) && (GLM_LANG & GLM_LANG_EXT)
597+# pragma message("GLM: C++ 23 with extensions")
598+# elif (GLM_LANG & GLM_LANG_CXX23_FLAG)
599+# pragma message("GLM: C++ 23")
600+# elif (GLM_LANG & GLM_LANG_CXX20_FLAG) && (GLM_LANG & GLM_LANG_EXT)
601+# pragma message("GLM: C++ 20 with extensions")
602+# elif (GLM_LANG & GLM_LANG_CXX20_FLAG)
603+# pragma message("GLM: C++ 20")
604+# elif (GLM_LANG & GLM_LANG_CXX17_FLAG) && (GLM_LANG & GLM_LANG_EXT)
605+# pragma message("GLM: C++ 17 with extensions")
606+# elif (GLM_LANG & GLM_LANG_CXX17_FLAG)
607+# pragma message("GLM: C++ 17")
608+# else
609+# pragma message("GLM: C++ language undetected")
610+# endif//GLM_LANG
611+
612+ // Report compiler detection
613+# if GLM_COMPILER & GLM_COMPILER_CUDA
614+# pragma message("GLM: CUDA compiler detected")
615+# elif GLM_COMPILER & GLM_COMPILER_HIP
616+# pragma message("GLM: HIP compiler detected")
617+# elif GLM_COMPILER & GLM_COMPILER_VC
618+# pragma message("GLM: Visual C++ compiler detected")
619+# elif GLM_COMPILER & GLM_COMPILER_CLANG
620+# pragma message("GLM: Clang compiler detected")
621+# elif GLM_COMPILER & GLM_COMPILER_INTEL
622+# pragma message("GLM: Intel Compiler detected")
623+# elif GLM_COMPILER & GLM_COMPILER_GCC
624+# pragma message("GLM: GCC compiler detected")
625+# else
626+# pragma message("GLM: Compiler not detected")
627+# endif
628+
629+ // Report build target
630+# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) && (GLM_MODEL == GLM_MODEL_64)
631+# pragma message("GLM: x86 64 bits with AVX2 instruction set build target")
632+# elif (GLM_ARCH & GLM_ARCH_AVX2_BIT) && (GLM_MODEL == GLM_MODEL_32)
633+# pragma message("GLM: x86 32 bits with AVX2 instruction set build target")
634+
635+# elif (GLM_ARCH & GLM_ARCH_AVX_BIT) && (GLM_MODEL == GLM_MODEL_64)
636+# pragma message("GLM: x86 64 bits with AVX instruction set build target")
637+# elif (GLM_ARCH & GLM_ARCH_AVX_BIT) && (GLM_MODEL == GLM_MODEL_32)
638+# pragma message("GLM: x86 32 bits with AVX instruction set build target")
639+
640+# elif (GLM_ARCH & GLM_ARCH_SSE42_BIT) && (GLM_MODEL == GLM_MODEL_64)
641+# pragma message("GLM: x86 64 bits with SSE4.2 instruction set build target")
642+# elif (GLM_ARCH & GLM_ARCH_SSE42_BIT) && (GLM_MODEL == GLM_MODEL_32)
643+# pragma message("GLM: x86 32 bits with SSE4.2 instruction set build target")
644+
645+# elif (GLM_ARCH & GLM_ARCH_SSE41_BIT) && (GLM_MODEL == GLM_MODEL_64)
646+# pragma message("GLM: x86 64 bits with SSE4.1 instruction set build target")
647+# elif (GLM_ARCH & GLM_ARCH_SSE41_BIT) && (GLM_MODEL == GLM_MODEL_32)
648+# pragma message("GLM: x86 32 bits with SSE4.1 instruction set build target")
649+
650+# elif (GLM_ARCH & GLM_ARCH_SSSE3_BIT) && (GLM_MODEL == GLM_MODEL_64)
651+# pragma message("GLM: x86 64 bits with SSSE3 instruction set build target")
652+# elif (GLM_ARCH & GLM_ARCH_SSSE3_BIT) && (GLM_MODEL == GLM_MODEL_32)
653+# pragma message("GLM: x86 32 bits with SSSE3 instruction set build target")
654+
655+# elif (GLM_ARCH & GLM_ARCH_SSE3_BIT) && (GLM_MODEL == GLM_MODEL_64)
656+# pragma message("GLM: x86 64 bits with SSE3 instruction set build target")
657+# elif (GLM_ARCH & GLM_ARCH_SSE3_BIT) && (GLM_MODEL == GLM_MODEL_32)
658+# pragma message("GLM: x86 32 bits with SSE3 instruction set build target")
659+
660+# elif (GLM_ARCH & GLM_ARCH_SSE2_BIT) && (GLM_MODEL == GLM_MODEL_64)
661+# pragma message("GLM: x86 64 bits with SSE2 instruction set build target")
662+# elif (GLM_ARCH & GLM_ARCH_SSE2_BIT) && (GLM_MODEL == GLM_MODEL_32)
663+# pragma message("GLM: x86 32 bits with SSE2 instruction set build target")
664+
665+# elif (GLM_ARCH & GLM_ARCH_X86_BIT) && (GLM_MODEL == GLM_MODEL_64)
666+# pragma message("GLM: x86 64 bits build target")
667+# elif (GLM_ARCH & GLM_ARCH_X86_BIT) && (GLM_MODEL == GLM_MODEL_32)
668+# pragma message("GLM: x86 32 bits build target")
669+
670+# elif (GLM_ARCH & GLM_ARCH_NEON_BIT) && (GLM_MODEL == GLM_MODEL_64)
671+# pragma message("GLM: ARM 64 bits with Neon instruction set build target")
672+# elif (GLM_ARCH & GLM_ARCH_NEON_BIT) && (GLM_MODEL == GLM_MODEL_32)
673+# pragma message("GLM: ARM 32 bits with Neon instruction set build target")
674+
675+# elif (GLM_ARCH & GLM_ARCH_ARM_BIT) && (GLM_MODEL == GLM_MODEL_64)
676+# pragma message("GLM: ARM 64 bits build target")
677+# elif (GLM_ARCH & GLM_ARCH_ARM_BIT) && (GLM_MODEL == GLM_MODEL_32)
678+# pragma message("GLM: ARM 32 bits build target")
679+
680+# elif (GLM_ARCH & GLM_ARCH_MIPS_BIT) && (GLM_MODEL == GLM_MODEL_64)
681+# pragma message("GLM: MIPS 64 bits build target")
682+# elif (GLM_ARCH & GLM_ARCH_MIPS_BIT) && (GLM_MODEL == GLM_MODEL_32)
683+# pragma message("GLM: MIPS 32 bits build target")
684+
685+# elif (GLM_ARCH & GLM_ARCH_PPC_BIT) && (GLM_MODEL == GLM_MODEL_64)
686+# pragma message("GLM: PowerPC 64 bits build target")
687+# elif (GLM_ARCH & GLM_ARCH_PPC_BIT) && (GLM_MODEL == GLM_MODEL_32)
688+# pragma message("GLM: PowerPC 32 bits build target")
689+# else
690+# pragma message("GLM: Unknown build target")
691+# endif//GLM_ARCH
692+
693+ // Report platform name
694+# if(GLM_PLATFORM & GLM_PLATFORM_QNXNTO)
695+# pragma message("GLM: QNX platform detected")
696+//# elif(GLM_PLATFORM & GLM_PLATFORM_IOS)
697+//# pragma message("GLM: iOS platform detected")
698+# elif(GLM_PLATFORM & GLM_PLATFORM_APPLE)
699+# pragma message("GLM: Apple platform detected")
700+# elif(GLM_PLATFORM & GLM_PLATFORM_WINCE)
701+# pragma message("GLM: WinCE platform detected")
702+# elif(GLM_PLATFORM & GLM_PLATFORM_WINDOWS)
703+# pragma message("GLM: Windows platform detected")
704+# elif(GLM_PLATFORM & GLM_PLATFORM_CHROME_NACL)
705+# pragma message("GLM: Native Client detected")
706+# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID)
707+# pragma message("GLM: Android platform detected")
708+# elif(GLM_PLATFORM & GLM_PLATFORM_LINUX)
709+# pragma message("GLM: Linux platform detected")
710+# elif(GLM_PLATFORM & GLM_PLATFORM_UNIX)
711+# pragma message("GLM: UNIX platform detected")
712+# elif(GLM_PLATFORM & GLM_PLATFORM_UNKNOWN)
713+# pragma message("GLM: platform unknown")
714+# else
715+# pragma message("GLM: platform not detected")
716+# endif
717+
718+ // Report whether only xyzw component are used
719+# if defined GLM_FORCE_XYZW_ONLY
720+# pragma message("GLM: GLM_FORCE_XYZW_ONLY is defined. Only x, y, z and w component are available in vector type. This define disables swizzle operators and SIMD instruction sets.")
721+# endif
722+
723+ // Report swizzle operator support
724+# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR
725+# pragma message("GLM: GLM_FORCE_SWIZZLE is defined, swizzling operators enabled.")
726+# elif GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION
727+# pragma message("GLM: GLM_FORCE_SWIZZLE is defined, swizzling functions enabled. Enable compiler C++ language extensions to enable swizzle operators.")
728+# else
729+# pragma message("GLM: GLM_FORCE_SWIZZLE is undefined. swizzling functions or operators are disabled.")
730+# endif
731+
732+ // Report .length() type
733+# if GLM_CONFIG_LENGTH_TYPE == GLM_LENGTH_SIZE_T
734+# pragma message("GLM: GLM_FORCE_SIZE_T_LENGTH is defined. .length() returns a glm::length_t, a typedef of std::size_t.")
735+# else
736+# pragma message("GLM: GLM_FORCE_SIZE_T_LENGTH is undefined. .length() returns a glm::length_t, a typedef of int following GLSL.")
737+# endif
738+
739+# if GLM_CONFIG_UNRESTRICTED_GENTYPE == GLM_ENABLE
740+# pragma message("GLM: GLM_FORCE_UNRESTRICTED_GENTYPE is defined. Removes GLSL restrictions on valid function genTypes.")
741+# else
742+# pragma message("GLM: GLM_FORCE_UNRESTRICTED_GENTYPE is undefined. Follows strictly GLSL on valid function genTypes.")
743+# endif
744+
745+# if GLM_SILENT_WARNINGS == GLM_ENABLE
746+# pragma message("GLM: GLM_FORCE_SILENT_WARNINGS is defined. Ignores C++ warnings from using C++ language extensions.")
747+# else
748+# pragma message("GLM: GLM_FORCE_SILENT_WARNINGS is undefined. Shows C++ warnings from using C++ language extensions.")
749+# endif
750+
751+# ifdef GLM_FORCE_SINGLE_ONLY
752+# pragma message("GLM: GLM_FORCE_SINGLE_ONLY is defined. Using only single precision floating-point types.")
753+# endif
754+
755+# if defined(GLM_FORCE_ALIGNED_GENTYPES) && (GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE)
756+# undef GLM_FORCE_ALIGNED_GENTYPES
757+# pragma message("GLM: GLM_FORCE_ALIGNED_GENTYPES is defined, allowing aligned types. This prevents the use of C++ constexpr.")
758+# elif defined(GLM_FORCE_ALIGNED_GENTYPES) && (GLM_CONFIG_ALIGNED_GENTYPES == GLM_DISABLE)
759+# undef GLM_FORCE_ALIGNED_GENTYPES
760+# pragma message("GLM: GLM_FORCE_ALIGNED_GENTYPES is defined but is disabled. It requires C++11 and language extensions.")
761+# endif
762+
763+# if defined(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES)
764+# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_DISABLE
765+# undef GLM_FORCE_DEFAULT_ALIGNED_GENTYPES
766+# pragma message("GLM: GLM_FORCE_DEFAULT_ALIGNED_GENTYPES is defined but is disabled. It requires C++11 and language extensions.")
767+# elif GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE
768+# pragma message("GLM: GLM_FORCE_DEFAULT_ALIGNED_GENTYPES is defined. All gentypes (e.g. vec3) will be aligned and padded by default.")
769+# endif
770+# endif
771+
772+# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
773+# pragma message("GLM: GLM_FORCE_DEPTH_ZERO_TO_ONE is defined. Using zero to one depth clip space.")
774+# else
775+# pragma message("GLM: GLM_FORCE_DEPTH_ZERO_TO_ONE is undefined. Using negative one to one depth clip space.")
776+# endif
777+
778+# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
779+# pragma message("GLM: GLM_FORCE_LEFT_HANDED is defined. Using left handed coordinate system.")
780+# else
781+# pragma message("GLM: GLM_FORCE_LEFT_HANDED is undefined. Using right handed coordinate system.")
782+# endif
783+#endif//GLM_MESSAGES
784+
785+#endif//GLM_SETUP_INCLUDED
@@ -0,0 +1,68 @@
1+#pragma once
2+
3+#include "setup.hpp"
4+
5+#if GLM_COMPILER == GLM_COMPILER_VC12
6+# pragma warning(push)
7+# pragma warning(disable: 4512) // assignment operator could not be generated
8+#endif
9+
10+namespace glm{
11+namespace detail
12+{
13+ template <typename T>
14+ union float_t
15+ {};
16+
17+ // https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
18+ template <>
19+ union float_t<float>
20+ {
21+ typedef int int_type;
22+ typedef float float_type;
23+
24+ GLM_CONSTEXPR float_t(float_type Num = 0.0f) : f(Num) {}
25+
26+ GLM_CONSTEXPR float_t& operator=(float_t const& x)
27+ {
28+ f = x.f;
29+ return *this;
30+ }
31+
32+ // Portable extraction of components.
33+ GLM_CONSTEXPR bool negative() const { return i < 0; }
34+ GLM_CONSTEXPR int_type mantissa() const { return i & ((1 << 23) - 1); }
35+ GLM_CONSTEXPR int_type exponent() const { return (i >> 23) & ((1 << 8) - 1); }
36+
37+ int_type i;
38+ float_type f;
39+ };
40+
41+ template <>
42+ union float_t<double>
43+ {
44+ typedef detail::int64 int_type;
45+ typedef double float_type;
46+
47+ GLM_CONSTEXPR float_t(float_type Num = static_cast<float_type>(0)) : f(Num) {}
48+
49+ GLM_CONSTEXPR float_t& operator=(float_t const& x)
50+ {
51+ f = x.f;
52+ return *this;
53+ }
54+
55+ // Portable extraction of components.
56+ GLM_CONSTEXPR bool negative() const { return i < 0; }
57+ GLM_CONSTEXPR int_type mantissa() const { return i & ((int_type(1) << 52) - 1); }
58+ GLM_CONSTEXPR int_type exponent() const { return (i >> 52) & ((int_type(1) << 11) - 1); }
59+
60+ int_type i;
61+ float_type f;
62+ };
63+}//namespace detail
64+}//namespace glm
65+
66+#if GLM_COMPILER == GLM_COMPILER_VC12
67+# pragma warning(pop)
68+#endif
@@ -0,0 +1,16 @@
1+#pragma once
2+
3+#include "setup.hpp"
4+
5+namespace glm{
6+namespace detail
7+{
8+ typedef short hdata;
9+
10+ GLM_FUNC_DECL float toFloat32(hdata value);
11+ GLM_FUNC_DECL hdata toFloat16(float const& value);
12+
13+}//namespace detail
14+}//namespace glm
15+
16+#include "type_half.inl"
@@ -0,0 +1,258 @@
1+namespace glm{
2+namespace detail
3+{
4+#if (GLM_COMPILER & GLM_COMPILER_VC)
5+# pragma warning(push)
6+# pragma warning(disable: 4746) // volatile access of 'f' is subject to /volatile:<iso|ms> setting; consider using __iso_volatile_load/store intrinsic functions
7+#endif
8+
9+// This function cause a build error on Github C.I.
10+#if (!(GLM_COMPILER & GLM_COMPILER_VC) && (GLM_ARCH & GLM_ARCH_ARM_BIT))
11+ GLM_FUNC_QUALIFIER float overflow()
12+ {
13+ volatile float f = 1e10;
14+
15+ for(int i = 0; i < 10; ++i)
16+ f = f * f; // this will overflow before the for loop terminates
17+ return f;
18+ }
19+#else
20+ GLM_FUNC_QUALIFIER float overflow()
21+ {
22+ return 0.0f;
23+ }
24+#endif//
25+
26+#if (GLM_COMPILER & GLM_COMPILER_VC)
27+# pragma warning(pop)
28+#endif
29+
30+ union uif32
31+ {
32+ GLM_FUNC_QUALIFIER uif32() :
33+ i(0)
34+ {}
35+
36+ GLM_FUNC_QUALIFIER uif32(float f_) :
37+ f(f_)
38+ {}
39+
40+ GLM_FUNC_QUALIFIER uif32(unsigned int i_) :
41+ i(i_)
42+ {}
43+
44+ float f;
45+ unsigned int i;
46+ };
47+
48+ GLM_FUNC_QUALIFIER float toFloat32(hdata value)
49+ {
50+ int s = (value >> 15) & 0x00000001;
51+ int e = (value >> 10) & 0x0000001f;
52+ int m = value & 0x000003ff;
53+
54+ if(e == 0)
55+ {
56+ if(m == 0)
57+ {
58+ //
59+ // Plus or minus zero
60+ //
61+
62+ detail::uif32 result;
63+ result.i = static_cast<unsigned int>(s << 31);
64+ return result.f;
65+ }
66+ else
67+ {
68+ //
69+ // Denormalized number -- renormalize it
70+ //
71+
72+ while(!(m & 0x00000400))
73+ {
74+ m <<= 1;
75+ e -= 1;
76+ }
77+
78+ e += 1;
79+ m &= ~0x00000400;
80+ }
81+ }
82+ else if(e == 31)
83+ {
84+ if(m == 0)
85+ {
86+ //
87+ // Positive or negative infinity
88+ //
89+
90+ uif32 result;
91+ result.i = static_cast<unsigned int>((s << 31) | 0x7f800000);
92+ return result.f;
93+ }
94+ else
95+ {
96+ //
97+ // Nan -- preserve sign and significand bits
98+ //
99+
100+ uif32 result;
101+ result.i = static_cast<unsigned int>((s << 31) | 0x7f800000 | (m << 13));
102+ return result.f;
103+ }
104+ }
105+
106+ //
107+ // Normalized number
108+ //
109+
110+ e = e + (127 - 15);
111+ m = m << 13;
112+
113+ //
114+ // Assemble s, e and m.
115+ //
116+
117+ uif32 Result;
118+ Result.i = static_cast<unsigned int>((s << 31) | (e << 23) | m);
119+ return Result.f;
120+ }
121+
122+ GLM_FUNC_QUALIFIER hdata toFloat16(float const& f)
123+ {
124+ uif32 Entry;
125+ Entry.f = f;
126+ int i = static_cast<int>(Entry.i);
127+
128+ //
129+ // Our floating point number, f, is represented by the bit
130+ // pattern in integer i. Disassemble that bit pattern into
131+ // the sign, s, the exponent, e, and the significand, m.
132+ // Shift s into the position where it will go in the
133+ // resulting half number.
134+ // Adjust e, accounting for the different exponent bias
135+ // of float and half (127 versus 15).
136+ //
137+
138+ int s = (i >> 16) & 0x00008000;
139+ int e = ((i >> 23) & 0x000000ff) - (127 - 15);
140+ int m = i & 0x007fffff;
141+
142+ //
143+ // Now reassemble s, e and m into a half:
144+ //
145+
146+ if(e <= 0)
147+ {
148+ if(e < -10)
149+ {
150+ //
151+ // E is less than -10. The absolute value of f is
152+ // less than half_MIN (f may be a small normalized
153+ // float, a denormalized float or a zero).
154+ //
155+ // We convert f to a half zero.
156+ //
157+
158+ return hdata(s);
159+ }
160+
161+ //
162+ // E is between -10 and 0. F is a normalized float,
163+ // whose magnitude is less than __half_NRM_MIN.
164+ //
165+ // We convert f to a denormalized half.
166+ //
167+
168+ m = (m | 0x00800000) >> (1 - e);
169+
170+ //
171+ // Round to nearest, round "0.5" up.
172+ //
173+ // Rounding may cause the significand to overflow and make
174+ // our number normalized. Because of the way a half's bits
175+ // are laid out, we don't have to treat this case separately;
176+ // the code below will handle it correctly.
177+ //
178+
179+ if(m & 0x00001000)
180+ m += 0x00002000;
181+
182+ //
183+ // Assemble the half from s, e (zero) and m.
184+ //
185+
186+ return hdata(s | (m >> 13));
187+ }
188+ else if(e == 0xff - (127 - 15))
189+ {
190+ if(m == 0)
191+ {
192+ //
193+ // F is an infinity; convert f to a half
194+ // infinity with the same sign as f.
195+ //
196+
197+ return hdata(s | 0x7c00);
198+ }
199+ else
200+ {
201+ //
202+ // F is a NAN; we produce a half NAN that preserves
203+ // the sign bit and the 10 leftmost bits of the
204+ // significand of f, with one exception: If the 10
205+ // leftmost bits are all zero, the NAN would turn
206+ // into an infinity, so we have to set at least one
207+ // bit in the significand.
208+ //
209+
210+ m >>= 13;
211+
212+ return hdata(s | 0x7c00 | m | (m == 0));
213+ }
214+ }
215+ else
216+ {
217+ //
218+ // E is greater than zero. F is a normalized float.
219+ // We try to convert f to a normalized half.
220+ //
221+
222+ //
223+ // Round to nearest, round "0.5" up
224+ //
225+
226+ if(m & 0x00001000)
227+ {
228+ m += 0x00002000;
229+
230+ if(m & 0x00800000)
231+ {
232+ m = 0; // overflow in significand,
233+ e += 1; // adjust exponent
234+ }
235+ }
236+
237+ //
238+ // Handle exponent overflow
239+ //
240+
241+ if (e > 30)
242+ {
243+ overflow(); // Cause a hardware floating point overflow;
244+
245+ return hdata(s | 0x7c00);
246+ // if this returns, the half becomes an
247+ } // infinity with the same sign as f.
248+
249+ //
250+ // Assemble the half from s, e and m.
251+ //
252+
253+ return hdata(s | (e << 10) | (m >> 13));
254+ }
255+ }
256+
257+}//namespace detail
258+}//namespace glm
@@ -0,0 +1,180 @@
1+/// @ref core
2+/// @file glm/detail/type_mat2x2.hpp
3+
4+#pragma once
5+
6+#include "type_vec2.hpp"
7+#include <limits>
8+#include <cstddef>
9+
10+namespace glm
11+{
12+ template<typename T, qualifier Q>
13+ struct mat<2, 2, T, Q>
14+ {
15+ typedef vec<2, T, Q> col_type;
16+ typedef vec<2, T, Q> row_type;
17+ typedef mat<2, 2, T, Q> type;
18+ typedef mat<2, 2, T, Q> transpose_type;
19+ typedef T value_type;
20+
21+ private:
22+ col_type value[2];
23+
24+ public:
25+ // -- Accesses --
26+
27+ typedef length_t length_type;
28+ GLM_FUNC_DECL static constexpr length_type length() { return 2; }
29+
30+ GLM_FUNC_DECL GLM_CONSTEXPR col_type & operator[](length_type i) noexcept;
31+ GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const noexcept;
32+
33+ // -- Constructors --
34+
35+ GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR;
36+ GLM_CTOR_DECL mat(mat<2, 2, T, Q> const& m) = default;
37+ template<qualifier P>
38+ GLM_CTOR_DECL mat(mat<2, 2, T, P> const& m);
39+
40+ GLM_CTOR_DECL GLM_EXPLICIT mat(T scalar);
41+ GLM_CTOR_DECL mat(
42+ T const& x1, T const& y1,
43+ T const& x2, T const& y2);
44+ GLM_CTOR_DECL mat(
45+ col_type const& v1,
46+ col_type const& v2);
47+
48+ // -- Conversions --
49+
50+ template<typename U, typename V, typename M, typename N>
51+ GLM_CTOR_DECL mat(
52+ U const& x1, V const& y1,
53+ M const& x2, N const& y2);
54+
55+ template<typename U, typename V>
56+ GLM_CTOR_DECL mat(
57+ vec<2, U, Q> const& v1,
58+ vec<2, V, Q> const& v2);
59+
60+ // -- Matrix conversions --
61+
62+ template<typename U, qualifier P>
63+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 2, U, P> const& m);
64+
65+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 3, T, Q> const& x);
66+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 4, T, Q> const& x);
67+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 3, T, Q> const& x);
68+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 2, T, Q> const& x);
69+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 4, T, Q> const& x);
70+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 2, T, Q> const& x);
71+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 4, T, Q> const& x);
72+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 3, T, Q> const& x);
73+
74+ // -- Unary arithmetic operators --
75+
76+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q>& operator=(mat<2, 2, T, Q> const& m) = default;
77+
78+ template<typename U>
79+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q>& operator=(mat<2, 2, U, Q> const& m);
80+ template<typename U>
81+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q>& operator+=(U s);
82+ template<typename U>
83+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q>& operator+=(mat<2, 2, U, Q> const& m);
84+ template<typename U>
85+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q>& operator-=(U s);
86+ template<typename U>
87+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q>& operator-=(mat<2, 2, U, Q> const& m);
88+ template<typename U>
89+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q>& operator*=(U s);
90+ template<typename U>
91+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q>& operator*=(mat<2, 2, U, Q> const& m);
92+ template<typename U>
93+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q>& operator/=(U s);
94+ template<typename U>
95+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q>& operator/=(mat<2, 2, U, Q> const& m);
96+
97+ // -- Increment and decrement operators --
98+
99+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q> & operator++ ();
100+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q> & operator-- ();
101+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator++(int);
102+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator--(int);
103+ };
104+
105+ // -- Unary operators --
106+
107+ template<typename T, qualifier Q>
108+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m);
109+
110+ template<typename T, qualifier Q>
111+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m);
112+
113+ // -- Binary operators --
114+
115+ template<typename T, qualifier Q>
116+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m, T scalar);
117+
118+ template<typename T, qualifier Q>
119+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator+(T scalar, mat<2, 2, T, Q> const& m);
120+
121+ template<typename T, qualifier Q>
122+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2);
123+
124+ template<typename T, qualifier Q>
125+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m, T scalar);
126+
127+ template<typename T, qualifier Q>
128+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator-(T scalar, mat<2, 2, T, Q> const& m);
129+
130+ template<typename T, qualifier Q>
131+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2);
132+
133+ template<typename T, qualifier Q>
134+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator*(mat<2, 2, T, Q> const& m, T scalar);
135+
136+ template<typename T, qualifier Q>
137+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator*(T scalar, mat<2, 2, T, Q> const& m);
138+
139+ template<typename T, qualifier Q>
140+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<2, 2, T, Q>::col_type operator*(mat<2, 2, T, Q> const& m, typename mat<2, 2, T, Q>::row_type const& v);
141+
142+ template<typename T, qualifier Q>
143+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<2, 2, T, Q>::row_type operator*(typename mat<2, 2, T, Q>::col_type const& v, mat<2, 2, T, Q> const& m);
144+
145+ template<typename T, qualifier Q>
146+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2);
147+
148+ template<typename T, qualifier Q>
149+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2);
150+
151+ template<typename T, qualifier Q>
152+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2);
153+
154+ template<typename T, qualifier Q>
155+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator/(mat<2, 2, T, Q> const& m, T scalar);
156+
157+ template<typename T, qualifier Q>
158+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator/(T scalar, mat<2, 2, T, Q> const& m);
159+
160+ template<typename T, qualifier Q>
161+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<2, 2, T, Q>::col_type operator/(mat<2, 2, T, Q> const& m, typename mat<2, 2, T, Q>::row_type const& v);
162+
163+ template<typename T, qualifier Q>
164+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<2, 2, T, Q>::row_type operator/(typename mat<2, 2, T, Q>::col_type const& v, mat<2, 2, T, Q> const& m);
165+
166+ template<typename T, qualifier Q>
167+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator/(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2);
168+
169+ // -- Boolean operators --
170+
171+ template<typename T, qualifier Q>
172+ GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2);
173+
174+ template<typename T, qualifier Q>
175+ GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2);
176+} //namespace glm
177+
178+#ifndef GLM_EXTERNAL_TEMPLATE
179+#include "type_mat2x2.inl"
180+#endif
@@ -0,0 +1,424 @@
1+#include "../matrix.hpp"
2+
3+namespace glm
4+{
5+ // -- Constructors --
6+
7+# if GLM_CONFIG_CTOR_INIT == GLM_ENABLE
8+ template<typename T, qualifier Q>
9+ GLM_DEFAULTED_DEFAULT_CTOR_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat()
10+ : value{col_type(1, 0), col_type(0, 1)}
11+ {}
12+# endif
13+
14+ template<typename T, qualifier Q>
15+ template<qualifier P>
16+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<2, 2, T, P> const& m)
17+ : value{col_type(m[0]), col_type(m[1])}
18+ {}
19+
20+ template<typename T, qualifier Q>
21+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(T scalar)
22+ : value{col_type(scalar, 0), col_type(0, scalar)}
23+ {}
24+
25+ template<typename T, qualifier Q>
26+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat
27+ (
28+ T const& x0, T const& y0,
29+ T const& x1, T const& y1
30+ )
31+ : value{col_type(x0, y0), col_type(x1, y1)}
32+ {}
33+
34+ template<typename T, qualifier Q>
35+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(col_type const& v0, col_type const& v1)
36+ : value{v0, v1}
37+ {}
38+
39+ // -- Conversion constructors --
40+
41+ template<typename T, qualifier Q>
42+ template<typename X1, typename Y1, typename X2, typename Y2>
43+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat
44+ (
45+ X1 const& x1, Y1 const& y1,
46+ X2 const& x2, Y2 const& y2
47+ )
48+ : value{col_type(static_cast<T>(x1), value_type(y1)), col_type(static_cast<T>(x2), value_type(y2)) }
49+ {}
50+
51+ template<typename T, qualifier Q>
52+ template<typename V1, typename V2>
53+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(vec<2, V1, Q> const& v1, vec<2, V2, Q> const& v2)
54+ : value{col_type(v1), col_type(v2)}
55+ {}
56+
57+ // -- mat2x2 matrix conversions --
58+
59+ template<typename T, qualifier Q>
60+ template<typename U, qualifier P>
61+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<2, 2, U, P> const& m)
62+ : value{col_type(m[0]), col_type(m[1])}
63+ {}
64+
65+ template<typename T, qualifier Q>
66+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<3, 3, T, Q> const& m)
67+ : value{col_type(m[0]), col_type(m[1])}
68+ {}
69+
70+ template<typename T, qualifier Q>
71+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<4, 4, T, Q> const& m)
72+ : value{col_type(m[0]), col_type(m[1])}
73+ {}
74+
75+ template<typename T, qualifier Q>
76+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<2, 3, T, Q> const& m)
77+ : value{col_type(m[0]), col_type(m[1])}
78+ {}
79+
80+ template<typename T, qualifier Q>
81+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<3, 2, T, Q> const& m)
82+ : value{col_type(m[0]), col_type(m[1])}
83+ {}
84+
85+ template<typename T, qualifier Q>
86+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<2, 4, T, Q> const& m)
87+ : value{col_type(m[0]), col_type(m[1])}
88+ {}
89+
90+ template<typename T, qualifier Q>
91+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<4, 2, T, Q> const& m)
92+ : value{col_type(m[0]), col_type(m[1])}
93+ {}
94+
95+ template<typename T, qualifier Q>
96+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<3, 4, T, Q> const& m)
97+ : value{col_type(m[0]), col_type(m[1])}
98+ {}
99+
100+ template<typename T, qualifier Q>
101+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<4, 3, T, Q> const& m)
102+ : value{col_type(m[0]), col_type(m[1])}
103+ {}
104+
105+ // -- Accesses --
106+
107+ template<typename T, qualifier Q>
108+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 2, T, Q>::col_type& mat<2, 2, T, Q>::operator[](typename mat<2, 2, T, Q>::length_type i) noexcept
109+ {
110+ GLM_ASSERT_LENGTH(i, this->length());
111+ return this->value[i];
112+ }
113+
114+ template<typename T, qualifier Q>
115+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 2, T, Q>::col_type const& mat<2, 2, T, Q>::operator[](typename mat<2, 2, T, Q>::length_type i) const noexcept
116+ {
117+ GLM_ASSERT_LENGTH(i, this->length());
118+ return this->value[i];
119+ }
120+
121+ // -- Unary updatable operators --
122+
123+ template<typename T, qualifier Q>
124+ template<typename U>
125+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator=(mat<2, 2, U, Q> const& m)
126+ {
127+ this->value[0] = m[0];
128+ this->value[1] = m[1];
129+ return *this;
130+ }
131+
132+ template<typename T, qualifier Q>
133+ template<typename U>
134+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator+=(U scalar)
135+ {
136+ this->value[0] += scalar;
137+ this->value[1] += scalar;
138+ return *this;
139+ }
140+
141+ template<typename T, qualifier Q>
142+ template<typename U>
143+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator+=(mat<2, 2, U, Q> const& m)
144+ {
145+ this->value[0] += m[0];
146+ this->value[1] += m[1];
147+ return *this;
148+ }
149+
150+ template<typename T, qualifier Q>
151+ template<typename U>
152+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator-=(U scalar)
153+ {
154+ this->value[0] -= scalar;
155+ this->value[1] -= scalar;
156+ return *this;
157+ }
158+
159+ template<typename T, qualifier Q>
160+ template<typename U>
161+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator-=(mat<2, 2, U, Q> const& m)
162+ {
163+ this->value[0] -= m[0];
164+ this->value[1] -= m[1];
165+ return *this;
166+ }
167+
168+ template<typename T, qualifier Q>
169+ template<typename U>
170+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator*=(U scalar)
171+ {
172+ this->value[0] *= scalar;
173+ this->value[1] *= scalar;
174+ return *this;
175+ }
176+
177+ template<typename T, qualifier Q>
178+ template<typename U>
179+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator*=(mat<2, 2, U, Q> const& m)
180+ {
181+ return (*this = *this * m);
182+ }
183+
184+ template<typename T, qualifier Q>
185+ template<typename U>
186+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator/=(U scalar)
187+ {
188+ this->value[0] /= scalar;
189+ this->value[1] /= scalar;
190+ return *this;
191+ }
192+
193+ template<typename T, qualifier Q>
194+ template<typename U>
195+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator/=(mat<2, 2, U, Q> const& m)
196+ {
197+ return *this *= inverse(m);
198+ }
199+
200+ // -- Increment and decrement operators --
201+
202+ template<typename T, qualifier Q>
203+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator++()
204+ {
205+ ++this->value[0];
206+ ++this->value[1];
207+ return *this;
208+ }
209+
210+ template<typename T, qualifier Q>
211+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator--()
212+ {
213+ --this->value[0];
214+ --this->value[1];
215+ return *this;
216+ }
217+
218+ template<typename T, qualifier Q>
219+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> mat<2, 2, T, Q>::operator++(int)
220+ {
221+ mat<2, 2, T, Q> Result(*this);
222+ ++*this;
223+ return Result;
224+ }
225+
226+ template<typename T, qualifier Q>
227+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> mat<2, 2, T, Q>::operator--(int)
228+ {
229+ mat<2, 2, T, Q> Result(*this);
230+ --*this;
231+ return Result;
232+ }
233+
234+ // -- Unary arithmetic operators --
235+
236+ template<typename T, qualifier Q>
237+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m)
238+ {
239+ return m;
240+ }
241+
242+ template<typename T, qualifier Q>
243+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m)
244+ {
245+ return mat<2, 2, T, Q>(
246+ -m[0],
247+ -m[1]);
248+ }
249+
250+ // -- Binary arithmetic operators --
251+
252+ template<typename T, qualifier Q>
253+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m, T scalar)
254+ {
255+ return mat<2, 2, T, Q>(
256+ m[0] + scalar,
257+ m[1] + scalar);
258+ }
259+
260+ template<typename T, qualifier Q>
261+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator+(T scalar, mat<2, 2, T, Q> const& m)
262+ {
263+ return mat<2, 2, T, Q>(
264+ m[0] + scalar,
265+ m[1] + scalar);
266+ }
267+
268+ template<typename T, qualifier Q>
269+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2)
270+ {
271+ return mat<2, 2, T, Q>(
272+ m1[0] + m2[0],
273+ m1[1] + m2[1]);
274+ }
275+
276+ template<typename T, qualifier Q>
277+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m, T scalar)
278+ {
279+ return mat<2, 2, T, Q>(
280+ m[0] - scalar,
281+ m[1] - scalar);
282+ }
283+
284+ template<typename T, qualifier Q>
285+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator-(T scalar, mat<2, 2, T, Q> const& m)
286+ {
287+ return mat<2, 2, T, Q>(
288+ scalar - m[0],
289+ scalar - m[1]);
290+ }
291+
292+ template<typename T, qualifier Q>
293+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2)
294+ {
295+ return mat<2, 2, T, Q>(
296+ m1[0] - m2[0],
297+ m1[1] - m2[1]);
298+ }
299+
300+ template<typename T, qualifier Q>
301+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator*(mat<2, 2, T, Q> const& m, T scalar)
302+ {
303+ return mat<2, 2, T, Q>(
304+ m[0] * scalar,
305+ m[1] * scalar);
306+ }
307+
308+ template<typename T, qualifier Q>
309+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator*(T scalar, mat<2, 2, T, Q> const& m)
310+ {
311+ return mat<2, 2, T, Q>(
312+ m[0] * scalar,
313+ m[1] * scalar);
314+ }
315+
316+ template<typename T, qualifier Q>
317+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 2, T, Q>::col_type operator*
318+ (
319+ mat<2, 2, T, Q> const& m,
320+ typename mat<2, 2, T, Q>::row_type const& v
321+ )
322+ {
323+ return vec<2, T, Q>(
324+ m[0][0] * v.x + m[1][0] * v.y,
325+ m[0][1] * v.x + m[1][1] * v.y);
326+ }
327+
328+ template<typename T, qualifier Q>
329+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 2, T, Q>::row_type operator*
330+ (
331+ typename mat<2, 2, T, Q>::col_type const& v,
332+ mat<2, 2, T, Q> const& m
333+ )
334+ {
335+ return vec<2, T, Q>(
336+ v.x * m[0][0] + v.y * m[0][1],
337+ v.x * m[1][0] + v.y * m[1][1]);
338+ }
339+
340+ template<typename T, qualifier Q>
341+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2)
342+ {
343+ return mat<2, 2, T, Q>(
344+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
345+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
346+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
347+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1]);
348+ }
349+
350+ template<typename T, qualifier Q>
351+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2)
352+ {
353+ return mat<3, 2, T, Q>(
354+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
355+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
356+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
357+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
358+ m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1],
359+ m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1]);
360+ }
361+
362+ template<typename T, qualifier Q>
363+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2)
364+ {
365+ return mat<4, 2, T, Q>(
366+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
367+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
368+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
369+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
370+ m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1],
371+ m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1],
372+ m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1],
373+ m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1]);
374+ }
375+
376+ template<typename T, qualifier Q>
377+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator/(mat<2, 2, T, Q> const& m, T scalar)
378+ {
379+ return mat<2, 2, T, Q>(
380+ m[0] / scalar,
381+ m[1] / scalar);
382+ }
383+
384+ template<typename T, qualifier Q>
385+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator/(T scalar, mat<2, 2, T, Q> const& m)
386+ {
387+ return mat<2, 2, T, Q>(
388+ scalar / m[0],
389+ scalar / m[1]);
390+ }
391+
392+ template<typename T, qualifier Q>
393+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 2, T, Q>::col_type operator/(mat<2, 2, T, Q> const& m, typename mat<2, 2, T, Q>::row_type const& v)
394+ {
395+ return inverse(m) * v;
396+ }
397+
398+ template<typename T, qualifier Q>
399+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 2, T, Q>::row_type operator/(typename mat<2, 2, T, Q>::col_type const& v, mat<2, 2, T, Q> const& m)
400+ {
401+ return v * inverse(m);
402+ }
403+
404+ template<typename T, qualifier Q>
405+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator/(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2)
406+ {
407+ mat<2, 2, T, Q> m1_copy(m1);
408+ return m1_copy /= m2;
409+ }
410+
411+ // -- Boolean operators --
412+
413+ template<typename T, qualifier Q>
414+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2)
415+ {
416+ return (m1[0] == m2[0]) && (m1[1] == m2[1]);
417+ }
418+
419+ template<typename T, qualifier Q>
420+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2)
421+ {
422+ return (m1[0] != m2[0]) || (m1[1] != m2[1]);
423+ }
424+} //namespace glm
@@ -0,0 +1,162 @@
1+/// @ref core
2+/// @file glm/detail/type_mat2x3.hpp
3+
4+#pragma once
5+
6+#include "type_vec2.hpp"
7+#include "type_vec3.hpp"
8+#include <limits>
9+#include <cstddef>
10+
11+namespace glm
12+{
13+ template<typename T, qualifier Q>
14+ struct mat<2, 3, T, Q>
15+ {
16+ typedef vec<3, T, Q> col_type;
17+ typedef vec<2, T, Q> row_type;
18+ typedef mat<2, 3, T, Q> type;
19+ typedef mat<3, 2, T, Q> transpose_type;
20+ typedef T value_type;
21+
22+ private:
23+ col_type value[2];
24+
25+ public:
26+ // -- Accesses --
27+
28+ typedef length_t length_type;
29+ GLM_FUNC_DECL static constexpr length_type length() { return 2; }
30+
31+ GLM_FUNC_DECL GLM_CONSTEXPR col_type & operator[](length_type i) noexcept;
32+ GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const noexcept;
33+
34+ // -- Constructors --
35+
36+ GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR;
37+ GLM_CTOR_DECL mat(mat<2, 3, T, Q> const& m) = default;
38+ template<qualifier P>
39+ GLM_CTOR_DECL mat(mat<2, 3, T, P> const& m);
40+
41+ GLM_CTOR_DECL GLM_EXPLICIT mat(T scalar);
42+ GLM_CTOR_DECL mat(
43+ T x0, T y0, T z0,
44+ T x1, T y1, T z1);
45+ GLM_CTOR_DECL mat(
46+ col_type const& v0,
47+ col_type const& v1);
48+
49+ // -- Conversions --
50+
51+ template<typename X1, typename Y1, typename Z1, typename X2, typename Y2, typename Z2>
52+ GLM_CTOR_DECL mat(
53+ X1 x1, Y1 y1, Z1 z1,
54+ X2 x2, Y2 y2, Z2 z2);
55+
56+ template<typename U, typename V>
57+ GLM_CTOR_DECL mat(
58+ vec<3, U, Q> const& v1,
59+ vec<3, V, Q> const& v2);
60+
61+ // -- Matrix conversions --
62+
63+ template<typename U, qualifier P>
64+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 3, U, P> const& m);
65+
66+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 2, T, Q> const& x);
67+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 3, T, Q> const& x);
68+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 4, T, Q> const& x);
69+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 4, T, Q> const& x);
70+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 2, T, Q> const& x);
71+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 4, T, Q> const& x);
72+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 2, T, Q> const& x);
73+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 3, T, Q> const& x);
74+
75+ // -- Unary arithmetic operators --
76+
77+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q>& operator=(mat<2, 3, T, Q> const& m) = default;
78+
79+ template<typename U>
80+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator=(mat<2, 3, U, Q> const& m);
81+ template<typename U>
82+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator+=(U s);
83+ template<typename U>
84+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator+=(mat<2, 3, U, Q> const& m);
85+ template<typename U>
86+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator-=(U s);
87+ template<typename U>
88+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator-=(mat<2, 3, U, Q> const& m);
89+ template<typename U>
90+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator*=(U s);
91+ template<typename U>
92+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator/=(U s);
93+
94+ // -- Increment and decrement operators --
95+
96+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator++ ();
97+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator-- ();
98+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator++(int);
99+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator--(int);
100+ };
101+
102+ // -- Unary operators --
103+
104+ template<typename T, qualifier Q>
105+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m);
106+
107+ template<typename T, qualifier Q>
108+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m);
109+
110+ // -- Binary operators --
111+
112+ template<typename T, qualifier Q>
113+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m, T scalar);
114+
115+ template<typename T, qualifier Q>
116+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2);
117+
118+ template<typename T, qualifier Q>
119+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m, T scalar);
120+
121+ template<typename T, qualifier Q>
122+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2);
123+
124+ template<typename T, qualifier Q>
125+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator*(mat<2, 3, T, Q> const& m, T scalar);
126+
127+ template<typename T, qualifier Q>
128+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator*(T scalar, mat<2, 3, T, Q> const& m);
129+
130+ template<typename T, qualifier Q>
131+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<2, 3, T, Q>::col_type operator*(mat<2, 3, T, Q> const& m, typename mat<2, 3, T, Q>::row_type const& v);
132+
133+ template<typename T, qualifier Q>
134+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<2, 3, T, Q>::row_type operator*(typename mat<2, 3, T, Q>::col_type const& v, mat<2, 3, T, Q> const& m);
135+
136+ template<typename T, qualifier Q>
137+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<2, 2, T, Q> const& m2);
138+
139+ template<typename T, qualifier Q>
140+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<3, 2, T, Q> const& m2);
141+
142+ template<typename T, qualifier Q>
143+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<4, 2, T, Q> const& m2);
144+
145+ template<typename T, qualifier Q>
146+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator/(mat<2, 3, T, Q> const& m, T scalar);
147+
148+ template<typename T, qualifier Q>
149+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator/(T scalar, mat<2, 3, T, Q> const& m);
150+
151+ // -- Boolean operators --
152+
153+ template<typename T, qualifier Q>
154+ GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2);
155+
156+ template<typename T, qualifier Q>
157+ GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2);
158+}//namespace glm
159+
160+#ifndef GLM_EXTERNAL_TEMPLATE
161+#include "type_mat2x3.inl"
162+#endif
@@ -0,0 +1,383 @@
1+namespace glm
2+{
3+ // -- Constructors --
4+
5+# if GLM_CONFIG_CTOR_INIT == GLM_ENABLE
6+ template<typename T, qualifier Q>
7+ GLM_DEFAULTED_DEFAULT_CTOR_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat()
8+ : value{col_type(1, 0, 0), col_type(0, 1, 0)}
9+ {}
10+# endif
11+
12+ template<typename T, qualifier Q>
13+ template<qualifier P>
14+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<2, 3, T, P> const& m)
15+ : value{col_type(m[0]), col_type(m[1])}
16+ {}
17+
18+ template<typename T, qualifier Q>
19+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(T scalar)
20+ : value{col_type(scalar, 0, 0), col_type(0, scalar, 0)}
21+ {}
22+
23+ template<typename T, qualifier Q>
24+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat
25+ (
26+ T x0, T y0, T z0,
27+ T x1, T y1, T z1
28+ )
29+ : value{col_type(x0, y0, z0), col_type(x1, y1, z1)}
30+ {}
31+
32+ template<typename T, qualifier Q>
33+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(col_type const& v0, col_type const& v1)
34+ : value{col_type(v0), col_type(v1)}
35+ {}
36+
37+ // -- Conversion constructors --
38+
39+ template<typename T, qualifier Q>
40+ template<
41+ typename X1, typename Y1, typename Z1,
42+ typename X2, typename Y2, typename Z2>
43+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat
44+ (
45+ X1 x1, Y1 y1, Z1 z1,
46+ X2 x2, Y2 y2, Z2 z2
47+ )
48+ : value{col_type(x1, y1, z1), col_type(x2, y2, z2)}
49+ {}
50+
51+ template<typename T, qualifier Q>
52+ template<typename V1, typename V2>
53+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(vec<3, V1, Q> const& v1, vec<3, V2, Q> const& v2)
54+ : value{col_type(v1), col_type(v2)}
55+ {}
56+
57+ // -- Matrix conversions --
58+
59+ template<typename T, qualifier Q>
60+ template<typename U, qualifier P>
61+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<2, 3, U, P> const& m)
62+ : value{col_type(m[0]), col_type(m[1])}
63+ {}
64+
65+ template<typename T, qualifier Q>
66+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<2, 2, T, Q> const& m)
67+ : value{col_type(m[0], 0), col_type(m[1], 0)}
68+ {}
69+
70+ template<typename T, qualifier Q>
71+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<3, 3, T, Q> const& m)
72+ : value{col_type(m[0]), col_type(m[1])}
73+ {}
74+
75+ template<typename T, qualifier Q>
76+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<4, 4, T, Q> const& m)
77+ : value{col_type(m[0]), col_type(m[1])}
78+ {}
79+
80+ template<typename T, qualifier Q>
81+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<2, 4, T, Q> const& m)
82+ : value{col_type(m[0]), col_type(m[1])}
83+ {}
84+
85+ template<typename T, qualifier Q>
86+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<3, 2, T, Q> const& m)
87+ : value{col_type(m[0], 0), col_type(m[1], 0)}
88+ {}
89+
90+ template<typename T, qualifier Q>
91+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<3, 4, T, Q> const& m)
92+ : value{col_type(m[0]), col_type(m[1])}
93+ {}
94+
95+ template<typename T, qualifier Q>
96+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<4, 2, T, Q> const& m)
97+ : value{col_type(m[0], 0), col_type(m[1], 0)}
98+ {}
99+
100+ template<typename T, qualifier Q>
101+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<4, 3, T, Q> const& m)
102+ : value{col_type(m[0]), col_type(m[1])}
103+ {}
104+
105+ // -- Accesses --
106+
107+ template<typename T, qualifier Q>
108+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 3, T, Q>::col_type & mat<2, 3, T, Q>::operator[](typename mat<2, 3, T, Q>::length_type i) noexcept
109+ {
110+ GLM_ASSERT_LENGTH(i, this->length());
111+ return this->value[i];
112+ }
113+
114+ template<typename T, qualifier Q>
115+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 3, T, Q>::col_type const& mat<2, 3, T, Q>::operator[](typename mat<2, 3, T, Q>::length_type i) const noexcept
116+ {
117+ GLM_ASSERT_LENGTH(i, this->length());
118+ return this->value[i];
119+ }
120+
121+ // -- Unary updatable operators --
122+
123+ template<typename T, qualifier Q>
124+ template<typename U>
125+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator=(mat<2, 3, U, Q> const& m)
126+ {
127+ this->value[0] = m[0];
128+ this->value[1] = m[1];
129+ return *this;
130+ }
131+
132+ template<typename T, qualifier Q>
133+ template<typename U>
134+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> & mat<2, 3, T, Q>::operator+=(U s)
135+ {
136+ this->value[0] += s;
137+ this->value[1] += s;
138+ return *this;
139+ }
140+
141+ template<typename T, qualifier Q>
142+ template<typename U>
143+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator+=(mat<2, 3, U, Q> const& m)
144+ {
145+ this->value[0] += m[0];
146+ this->value[1] += m[1];
147+ return *this;
148+ }
149+
150+ template<typename T, qualifier Q>
151+ template<typename U>
152+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator-=(U s)
153+ {
154+ this->value[0] -= s;
155+ this->value[1] -= s;
156+ return *this;
157+ }
158+
159+ template<typename T, qualifier Q>
160+ template<typename U>
161+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator-=(mat<2, 3, U, Q> const& m)
162+ {
163+ this->value[0] -= m[0];
164+ this->value[1] -= m[1];
165+ return *this;
166+ }
167+
168+ template<typename T, qualifier Q>
169+ template<typename U>
170+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator*=(U s)
171+ {
172+ this->value[0] *= s;
173+ this->value[1] *= s;
174+ return *this;
175+ }
176+
177+ template<typename T, qualifier Q>
178+ template<typename U>
179+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> & mat<2, 3, T, Q>::operator/=(U s)
180+ {
181+ this->value[0] /= s;
182+ this->value[1] /= s;
183+ return *this;
184+ }
185+
186+ // -- Increment and decrement operators --
187+
188+ template<typename T, qualifier Q>
189+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> & mat<2, 3, T, Q>::operator++()
190+ {
191+ ++this->value[0];
192+ ++this->value[1];
193+ return *this;
194+ }
195+
196+ template<typename T, qualifier Q>
197+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> & mat<2, 3, T, Q>::operator--()
198+ {
199+ --this->value[0];
200+ --this->value[1];
201+ return *this;
202+ }
203+
204+ template<typename T, qualifier Q>
205+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> mat<2, 3, T, Q>::operator++(int)
206+ {
207+ mat<2, 3, T, Q> Result(*this);
208+ ++*this;
209+ return Result;
210+ }
211+
212+ template<typename T, qualifier Q>
213+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> mat<2, 3, T, Q>::operator--(int)
214+ {
215+ mat<2, 3, T, Q> Result(*this);
216+ --*this;
217+ return Result;
218+ }
219+
220+ // -- Unary arithmetic operators --
221+
222+ template<typename T, qualifier Q>
223+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m)
224+ {
225+ return m;
226+ }
227+
228+ template<typename T, qualifier Q>
229+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m)
230+ {
231+ return mat<2, 3, T, Q>(
232+ -m[0],
233+ -m[1]);
234+ }
235+
236+ // -- Binary arithmetic operators --
237+
238+ template<typename T, qualifier Q>
239+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m, T scalar)
240+ {
241+ return mat<2, 3, T, Q>(
242+ m[0] + scalar,
243+ m[1] + scalar);
244+ }
245+
246+ template<typename T, qualifier Q>
247+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2)
248+ {
249+ return mat<2, 3, T, Q>(
250+ m1[0] + m2[0],
251+ m1[1] + m2[1]);
252+ }
253+
254+ template<typename T, qualifier Q>
255+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m, T scalar)
256+ {
257+ return mat<2, 3, T, Q>(
258+ m[0] - scalar,
259+ m[1] - scalar);
260+ }
261+
262+ template<typename T, qualifier Q>
263+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2)
264+ {
265+ return mat<2, 3, T, Q>(
266+ m1[0] - m2[0],
267+ m1[1] - m2[1]);
268+ }
269+
270+ template<typename T, qualifier Q>
271+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> operator*(mat<2, 3, T, Q> const& m, T scalar)
272+ {
273+ return mat<2, 3, T, Q>(
274+ m[0] * scalar,
275+ m[1] * scalar);
276+ }
277+
278+ template<typename T, qualifier Q>
279+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> operator*(T scalar, mat<2, 3, T, Q> const& m)
280+ {
281+ return mat<2, 3, T, Q>(
282+ m[0] * scalar,
283+ m[1] * scalar);
284+ }
285+
286+ template<typename T, qualifier Q>
287+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 3, T, Q>::col_type operator*
288+ (
289+ mat<2, 3, T, Q> const& m,
290+ typename mat<2, 3, T, Q>::row_type const& v)
291+ {
292+ return typename mat<2, 3, T, Q>::col_type(
293+ m[0][0] * v.x + m[1][0] * v.y,
294+ m[0][1] * v.x + m[1][1] * v.y,
295+ m[0][2] * v.x + m[1][2] * v.y);
296+ }
297+
298+ template<typename T, qualifier Q>
299+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 3, T, Q>::row_type operator*
300+ (
301+ typename mat<2, 3, T, Q>::col_type const& v,
302+ mat<2, 3, T, Q> const& m)
303+ {
304+ return typename mat<2, 3, T, Q>::row_type(
305+ v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2],
306+ v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2]);
307+ }
308+
309+ template<typename T, qualifier Q>
310+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<2, 2, T, Q> const& m2)
311+ {
312+ return mat<2, 3, T, Q>(
313+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
314+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
315+ m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1],
316+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
317+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
318+ m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1]);
319+ }
320+
321+ template<typename T, qualifier Q>
322+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<3, 2, T, Q> const& m2)
323+ {
324+ return mat<3, 3, T, Q>(
325+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
326+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
327+ m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1],
328+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
329+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
330+ m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1],
331+ m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1],
332+ m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1],
333+ m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1]);
334+ }
335+
336+ template<typename T, qualifier Q>
337+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<4, 2, T, Q> const& m2)
338+ {
339+ return mat<4, 3, T, Q>(
340+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
341+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
342+ m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1],
343+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
344+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
345+ m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1],
346+ m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1],
347+ m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1],
348+ m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1],
349+ m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1],
350+ m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1],
351+ m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1]);
352+ }
353+
354+ template<typename T, qualifier Q>
355+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> operator/(mat<2, 3, T, Q> const& m, T scalar)
356+ {
357+ return mat<2, 3, T, Q>(
358+ m[0] / scalar,
359+ m[1] / scalar);
360+ }
361+
362+ template<typename T, qualifier Q>
363+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> operator/(T scalar, mat<2, 3, T, Q> const& m)
364+ {
365+ return mat<2, 3, T, Q>(
366+ scalar / m[0],
367+ scalar / m[1]);
368+ }
369+
370+ // -- Boolean operators --
371+
372+ template<typename T, qualifier Q>
373+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2)
374+ {
375+ return (m1[0] == m2[0]) && (m1[1] == m2[1]);
376+ }
377+
378+ template<typename T, qualifier Q>
379+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2)
380+ {
381+ return (m1[0] != m2[0]) || (m1[1] != m2[1]);
382+ }
383+} //namespace glm
@@ -0,0 +1,164 @@
1+/// @ref core
2+/// @file glm/detail/type_mat2x4.hpp
3+
4+#pragma once
5+
6+#include "type_vec2.hpp"
7+#include "type_vec4.hpp"
8+#include <limits>
9+#include <cstddef>
10+
11+namespace glm
12+{
13+ template<typename T, qualifier Q>
14+ struct mat<2, 4, T, Q>
15+ {
16+ typedef vec<4, T, Q> col_type;
17+ typedef vec<2, T, Q> row_type;
18+ typedef mat<2, 4, T, Q> type;
19+ typedef mat<4, 2, T, Q> transpose_type;
20+ typedef T value_type;
21+
22+ private:
23+ col_type value[2];
24+
25+ public:
26+ // -- Accesses --
27+
28+ typedef length_t length_type;
29+ GLM_FUNC_DECL static constexpr length_type length() { return 2; }
30+
31+ GLM_FUNC_DECL GLM_CONSTEXPR col_type & operator[](length_type i) noexcept;
32+ GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const noexcept;
33+
34+ // -- Constructors --
35+
36+ GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR;
37+ GLM_CTOR_DECL mat(mat<2, 4, T, Q> const& m) = default;
38+ template<qualifier P>
39+ GLM_CTOR_DECL mat(mat<2, 4, T, P> const& m);
40+
41+ GLM_CTOR_DECL GLM_EXPLICIT mat(T scalar);
42+ GLM_CTOR_DECL mat(
43+ T x0, T y0, T z0, T w0,
44+ T x1, T y1, T z1, T w1);
45+ GLM_CTOR_DECL mat(
46+ col_type const& v0,
47+ col_type const& v1);
48+
49+ // -- Conversions --
50+
51+ template<
52+ typename X1, typename Y1, typename Z1, typename W1,
53+ typename X2, typename Y2, typename Z2, typename W2>
54+ GLM_CTOR_DECL mat(
55+ X1 x1, Y1 y1, Z1 z1, W1 w1,
56+ X2 x2, Y2 y2, Z2 z2, W2 w2);
57+
58+ template<typename U, typename V>
59+ GLM_CTOR_DECL mat(
60+ vec<4, U, Q> const& v1,
61+ vec<4, V, Q> const& v2);
62+
63+ // -- Matrix conversions --
64+
65+ template<typename U, qualifier P>
66+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 4, U, P> const& m);
67+
68+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 2, T, Q> const& x);
69+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 3, T, Q> const& x);
70+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 4, T, Q> const& x);
71+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 3, T, Q> const& x);
72+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 2, T, Q> const& x);
73+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 4, T, Q> const& x);
74+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 2, T, Q> const& x);
75+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 3, T, Q> const& x);
76+
77+ // -- Unary arithmetic operators --
78+
79+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q>& operator=(mat<2, 4, T, Q> const& m) = default;
80+
81+ template<typename U>
82+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q>& operator=(mat<2, 4, U, Q> const& m);
83+ template<typename U>
84+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q>& operator+=(U s);
85+ template<typename U>
86+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q>& operator+=(mat<2, 4, U, Q> const& m);
87+ template<typename U>
88+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q>& operator-=(U s);
89+ template<typename U>
90+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q>& operator-=(mat<2, 4, U, Q> const& m);
91+ template<typename U>
92+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q>& operator*=(U s);
93+ template<typename U>
94+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q>& operator/=(U s);
95+
96+ // -- Increment and decrement operators --
97+
98+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q>& operator++ ();
99+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q>& operator-- ();
100+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator++(int);
101+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator--(int);
102+ };
103+
104+ // -- Unary operators --
105+
106+ template<typename T, qualifier Q>
107+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m);
108+
109+ template<typename T, qualifier Q>
110+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m);
111+
112+ // -- Binary operators --
113+
114+ template<typename T, qualifier Q>
115+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m, T scalar);
116+
117+ template<typename T, qualifier Q>
118+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2);
119+
120+ template<typename T, qualifier Q>
121+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m, T scalar);
122+
123+ template<typename T, qualifier Q>
124+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2);
125+
126+ template<typename T, qualifier Q>
127+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator*(mat<2, 4, T, Q> const& m, T scalar);
128+
129+ template<typename T, qualifier Q>
130+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator*(T scalar, mat<2, 4, T, Q> const& m);
131+
132+ template<typename T, qualifier Q>
133+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<2, 4, T, Q>::col_type operator*(mat<2, 4, T, Q> const& m, typename mat<2, 4, T, Q>::row_type const& v);
134+
135+ template<typename T, qualifier Q>
136+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<2, 4, T, Q>::row_type operator*(typename mat<2, 4, T, Q>::col_type const& v, mat<2, 4, T, Q> const& m);
137+
138+ template<typename T, qualifier Q>
139+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<4, 2, T, Q> const& m2);
140+
141+ template<typename T, qualifier Q>
142+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<2, 2, T, Q> const& m2);
143+
144+ template<typename T, qualifier Q>
145+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<3, 2, T, Q> const& m2);
146+
147+ template<typename T, qualifier Q>
148+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator/(mat<2, 4, T, Q> const& m, T scalar);
149+
150+ template<typename T, qualifier Q>
151+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator/(T scalar, mat<2, 4, T, Q> const& m);
152+
153+ // -- Boolean operators --
154+
155+ template<typename T, qualifier Q>
156+ GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2);
157+
158+ template<typename T, qualifier Q>
159+ GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2);
160+}//namespace glm
161+
162+#ifndef GLM_EXTERNAL_TEMPLATE
163+#include "type_mat2x4.inl"
164+#endif
@@ -0,0 +1,389 @@
1+namespace glm
2+{
3+ // -- Constructors --
4+
5+# if GLM_CONFIG_CTOR_INIT == GLM_ENABLE
6+ template<typename T, qualifier Q>
7+ GLM_DEFAULTED_DEFAULT_CTOR_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat()
8+ : value{col_type(1, 0, 0, 0), col_type(0, 1, 0, 0)}
9+ {}
10+# endif
11+
12+ template<typename T, qualifier Q>
13+ template<qualifier P>
14+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<2, 4, T, P> const& m)
15+ : value{col_type(m[0]), col_type(m[1])}
16+ {}
17+
18+ template<typename T, qualifier Q>
19+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(T s)
20+ : value{col_type(s, 0, 0, 0), col_type(0, s, 0, 0)}
21+ {}
22+
23+ template<typename T, qualifier Q>
24+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat
25+ (
26+ T x0, T y0, T z0, T w0,
27+ T x1, T y1, T z1, T w1
28+ )
29+ : value{col_type(x0, y0, z0, w0), col_type(x1, y1, z1, w1)}
30+ {}
31+
32+ template<typename T, qualifier Q>
33+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(col_type const& v0, col_type const& v1)
34+ : value{col_type(v0), col_type(v1)}
35+ {}
36+
37+ // -- Conversion constructors --
38+
39+ template<typename T, qualifier Q>
40+ template<
41+ typename X1, typename Y1, typename Z1, typename W1,
42+ typename X2, typename Y2, typename Z2, typename W2>
43+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat
44+ (
45+ X1 x1, Y1 y1, Z1 z1, W1 w1,
46+ X2 x2, Y2 y2, Z2 z2, W2 w2
47+ )
48+ : value{
49+ col_type(x1, y1, z1, w1),
50+ col_type(x2, y2, z2, w2)}
51+ {}
52+
53+ template<typename T, qualifier Q>
54+ template<typename V1, typename V2>
55+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(vec<4, V1, Q> const& v1, vec<4, V2, Q> const& v2)
56+ : value{col_type(v1), col_type(v2)}
57+ {}
58+
59+ // -- Matrix conversions --
60+
61+ template<typename T, qualifier Q>
62+ template<typename U, qualifier P>
63+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<2, 4, U, P> const& m)
64+ : value{col_type(m[0]), col_type(m[1])}
65+ {}
66+
67+ template<typename T, qualifier Q>
68+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<2, 2, T, Q> const& m)
69+ : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0)}
70+ {}
71+
72+ template<typename T, qualifier Q>
73+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<3, 3, T, Q> const& m)
74+ : value{col_type(m[0], 0), col_type(m[1], 0)}
75+ {}
76+
77+ template<typename T, qualifier Q>
78+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<4, 4, T, Q> const& m)
79+ : value{col_type(m[0]), col_type(m[1])}
80+ {}
81+
82+ template<typename T, qualifier Q>
83+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<2, 3, T, Q> const& m)
84+ : value{col_type(m[0], 0), col_type(m[1], 0)}
85+ {}
86+
87+ template<typename T, qualifier Q>
88+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<3, 2, T, Q> const& m)
89+ : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0)}
90+ {}
91+
92+ template<typename T, qualifier Q>
93+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<3, 4, T, Q> const& m)
94+ : value{col_type(m[0]), col_type(m[1])}
95+ {}
96+
97+ template<typename T, qualifier Q>
98+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<4, 2, T, Q> const& m)
99+ : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0)}
100+ {}
101+
102+ template<typename T, qualifier Q>
103+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<4, 3, T, Q> const& m)
104+ : value{col_type(m[0], 0), col_type(m[1], 0)}
105+ {}
106+
107+ // -- Accesses --
108+
109+ template<typename T, qualifier Q>
110+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 4, T, Q>::col_type & mat<2, 4, T, Q>::operator[](typename mat<2, 4, T, Q>::length_type i) noexcept
111+ {
112+ GLM_ASSERT_LENGTH(i, this->length());
113+ return this->value[i];
114+ }
115+
116+ template<typename T, qualifier Q>
117+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 4, T, Q>::col_type const& mat<2, 4, T, Q>::operator[](typename mat<2, 4, T, Q>::length_type i) const noexcept
118+ {
119+ GLM_ASSERT_LENGTH(i, this->length());
120+ return this->value[i];
121+ }
122+
123+ // -- Unary updatable operators --
124+
125+ template<typename T, qualifier Q>
126+ template<typename U>
127+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator=(mat<2, 4, U, Q> const& m)
128+ {
129+ this->value[0] = m[0];
130+ this->value[1] = m[1];
131+ return *this;
132+ }
133+
134+ template<typename T, qualifier Q>
135+ template<typename U>
136+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator+=(U s)
137+ {
138+ this->value[0] += s;
139+ this->value[1] += s;
140+ return *this;
141+ }
142+
143+ template<typename T, qualifier Q>
144+ template<typename U>
145+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator+=(mat<2, 4, U, Q> const& m)
146+ {
147+ this->value[0] += m[0];
148+ this->value[1] += m[1];
149+ return *this;
150+ }
151+
152+ template<typename T, qualifier Q>
153+ template<typename U>
154+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator-=(U s)
155+ {
156+ this->value[0] -= s;
157+ this->value[1] -= s;
158+ return *this;
159+ }
160+
161+ template<typename T, qualifier Q>
162+ template<typename U>
163+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator-=(mat<2, 4, U, Q> const& m)
164+ {
165+ this->value[0] -= m[0];
166+ this->value[1] -= m[1];
167+ return *this;
168+ }
169+
170+ template<typename T, qualifier Q>
171+ template<typename U>
172+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator*=(U s)
173+ {
174+ this->value[0] *= s;
175+ this->value[1] *= s;
176+ return *this;
177+ }
178+
179+ template<typename T, qualifier Q>
180+ template<typename U>
181+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> & mat<2, 4, T, Q>::operator/=(U s)
182+ {
183+ this->value[0] /= s;
184+ this->value[1] /= s;
185+ return *this;
186+ }
187+
188+ // -- Increment and decrement operators --
189+
190+ template<typename T, qualifier Q>
191+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator++()
192+ {
193+ ++this->value[0];
194+ ++this->value[1];
195+ return *this;
196+ }
197+
198+ template<typename T, qualifier Q>
199+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator--()
200+ {
201+ --this->value[0];
202+ --this->value[1];
203+ return *this;
204+ }
205+
206+ template<typename T, qualifier Q>
207+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> mat<2, 4, T, Q>::operator++(int)
208+ {
209+ mat<2, 4, T, Q> Result(*this);
210+ ++*this;
211+ return Result;
212+ }
213+
214+ template<typename T, qualifier Q>
215+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> mat<2, 4, T, Q>::operator--(int)
216+ {
217+ mat<2, 4, T, Q> Result(*this);
218+ --*this;
219+ return Result;
220+ }
221+
222+ // -- Unary arithmetic operators --
223+
224+ template<typename T, qualifier Q>
225+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m)
226+ {
227+ return m;
228+ }
229+
230+ template<typename T, qualifier Q>
231+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m)
232+ {
233+ return mat<2, 4, T, Q>(
234+ -m[0],
235+ -m[1]);
236+ }
237+
238+ // -- Binary arithmetic operators --
239+
240+ template<typename T, qualifier Q>
241+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m, T scalar)
242+ {
243+ return mat<2, 4, T, Q>(
244+ m[0] + scalar,
245+ m[1] + scalar);
246+ }
247+
248+ template<typename T, qualifier Q>
249+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2)
250+ {
251+ return mat<2, 4, T, Q>(
252+ m1[0] + m2[0],
253+ m1[1] + m2[1]);
254+ }
255+
256+ template<typename T, qualifier Q>
257+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m, T scalar)
258+ {
259+ return mat<2, 4, T, Q>(
260+ m[0] - scalar,
261+ m[1] - scalar);
262+ }
263+
264+ template<typename T, qualifier Q>
265+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2)
266+ {
267+ return mat<2, 4, T, Q>(
268+ m1[0] - m2[0],
269+ m1[1] - m2[1]);
270+ }
271+
272+ template<typename T, qualifier Q>
273+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> operator*(mat<2, 4, T, Q> const& m, T scalar)
274+ {
275+ return mat<2, 4, T, Q>(
276+ m[0] * scalar,
277+ m[1] * scalar);
278+ }
279+
280+ template<typename T, qualifier Q>
281+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> operator*(T scalar, mat<2, 4, T, Q> const& m)
282+ {
283+ return mat<2, 4, T, Q>(
284+ m[0] * scalar,
285+ m[1] * scalar);
286+ }
287+
288+ template<typename T, qualifier Q>
289+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 4, T, Q>::col_type operator*(mat<2, 4, T, Q> const& m, typename mat<2, 4, T, Q>::row_type const& v)
290+ {
291+ return typename mat<2, 4, T, Q>::col_type(
292+ m[0][0] * v.x + m[1][0] * v.y,
293+ m[0][1] * v.x + m[1][1] * v.y,
294+ m[0][2] * v.x + m[1][2] * v.y,
295+ m[0][3] * v.x + m[1][3] * v.y);
296+ }
297+
298+ template<typename T, qualifier Q>
299+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 4, T, Q>::row_type operator*(typename mat<2, 4, T, Q>::col_type const& v, mat<2, 4, T, Q> const& m)
300+ {
301+ return typename mat<2, 4, T, Q>::row_type(
302+ v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2] + v.w * m[0][3],
303+ v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2] + v.w * m[1][3]);
304+ }
305+
306+ template<typename T, qualifier Q>
307+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<4, 2, T, Q> const& m2)
308+ {
309+ return mat<4, 4, T, Q>(
310+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
311+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
312+ m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1],
313+ m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1],
314+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
315+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
316+ m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1],
317+ m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1],
318+ m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1],
319+ m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1],
320+ m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1],
321+ m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1],
322+ m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1],
323+ m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1],
324+ m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1],
325+ m1[0][3] * m2[3][0] + m1[1][3] * m2[3][1]);
326+ }
327+
328+ template<typename T, qualifier Q>
329+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<2, 2, T, Q> const& m2)
330+ {
331+ return mat<2, 4, T, Q>(
332+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
333+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
334+ m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1],
335+ m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1],
336+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
337+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
338+ m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1],
339+ m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1]);
340+ }
341+
342+ template<typename T, qualifier Q>
343+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<3, 2, T, Q> const& m2)
344+ {
345+ return mat<3, 4, T, Q>(
346+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
347+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
348+ m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1],
349+ m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1],
350+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
351+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
352+ m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1],
353+ m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1],
354+ m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1],
355+ m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1],
356+ m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1],
357+ m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1]);
358+ }
359+
360+ template<typename T, qualifier Q>
361+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> operator/(mat<2, 4, T, Q> const& m, T scalar)
362+ {
363+ return mat<2, 4, T, Q>(
364+ m[0] / scalar,
365+ m[1] / scalar);
366+ }
367+
368+ template<typename T, qualifier Q>
369+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> operator/(T scalar, mat<2, 4, T, Q> const& m)
370+ {
371+ return mat<2, 4, T, Q>(
372+ scalar / m[0],
373+ scalar / m[1]);
374+ }
375+
376+ // -- Boolean operators --
377+
378+ template<typename T, qualifier Q>
379+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2)
380+ {
381+ return (m1[0] == m2[0]) && (m1[1] == m2[1]);
382+ }
383+
384+ template<typename T, qualifier Q>
385+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2)
386+ {
387+ return (m1[0] != m2[0]) || (m1[1] != m2[1]);
388+ }
389+} //namespace glm
@@ -0,0 +1,170 @@
1+/// @ref core
2+/// @file glm/detail/type_mat3x2.hpp
3+
4+#pragma once
5+
6+#include "type_vec2.hpp"
7+#include "type_vec3.hpp"
8+#include <limits>
9+#include <cstddef>
10+
11+namespace glm
12+{
13+ template<typename T, qualifier Q>
14+ struct mat<3, 2, T, Q>
15+ {
16+ typedef vec<2, T, Q> col_type;
17+ typedef vec<3, T, Q> row_type;
18+ typedef mat<3, 2, T, Q> type;
19+ typedef mat<2, 3, T, Q> transpose_type;
20+ typedef T value_type;
21+
22+ private:
23+ col_type value[3];
24+
25+ public:
26+ // -- Accesses --
27+
28+ typedef length_t length_type;
29+ GLM_FUNC_DECL static constexpr length_type length() { return 3; }
30+
31+ GLM_FUNC_DECL GLM_CONSTEXPR col_type & operator[](length_type i) noexcept;
32+ GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const noexcept;
33+
34+ // -- Constructors --
35+
36+ GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR;
37+ GLM_CTOR_DECL mat(mat<3, 2, T, Q> const& m) = default;
38+ template<qualifier P>
39+ GLM_CTOR_DECL mat(mat<3, 2, T, P> const& m);
40+
41+ GLM_CTOR_DECL GLM_EXPLICIT mat(T scalar);
42+ GLM_CTOR_DECL mat(
43+ T x0, T y0,
44+ T x1, T y1,
45+ T x2, T y2);
46+ GLM_CTOR_DECL mat(
47+ col_type const& v0,
48+ col_type const& v1,
49+ col_type const& v2);
50+
51+ // -- Conversions --
52+
53+ template<
54+ typename X1, typename Y1,
55+ typename X2, typename Y2,
56+ typename X3, typename Y3>
57+ GLM_CTOR_DECL mat(
58+ X1 x1, Y1 y1,
59+ X2 x2, Y2 y2,
60+ X3 x3, Y3 y3);
61+
62+ template<typename V1, typename V2, typename V3>
63+ GLM_CTOR_DECL mat(
64+ vec<2, V1, Q> const& v1,
65+ vec<2, V2, Q> const& v2,
66+ vec<2, V3, Q> const& v3);
67+
68+ // -- Matrix conversions --
69+
70+ template<typename U, qualifier P>
71+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 2, U, P> const& m);
72+
73+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 2, T, Q> const& x);
74+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 3, T, Q> const& x);
75+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 4, T, Q> const& x);
76+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 3, T, Q> const& x);
77+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 4, T, Q> const& x);
78+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 4, T, Q> const& x);
79+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 2, T, Q> const& x);
80+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 3, T, Q> const& x);
81+
82+ // -- Unary arithmetic operators --
83+
84+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q>& operator=(mat<3, 2, T, Q> const& m) = default;
85+
86+ template<typename U>
87+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator=(mat<3, 2, U, Q> const& m);
88+ template<typename U>
89+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator+=(U s);
90+ template<typename U>
91+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator+=(mat<3, 2, U, Q> const& m);
92+ template<typename U>
93+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator-=(U s);
94+ template<typename U>
95+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator-=(mat<3, 2, U, Q> const& m);
96+ template<typename U>
97+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator*=(U s);
98+ template<typename U>
99+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator/=(U s);
100+
101+ // -- Increment and decrement operators --
102+
103+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator++ ();
104+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator-- ();
105+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator++(int);
106+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator--(int);
107+ };
108+
109+ // -- Unary operators --
110+
111+ template<typename T, qualifier Q>
112+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m);
113+
114+ template<typename T, qualifier Q>
115+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m);
116+
117+ // -- Binary operators --
118+
119+ template<typename T, qualifier Q>
120+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m, T scalar);
121+
122+ template<typename T, qualifier Q>
123+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2);
124+
125+ template<typename T, qualifier Q>
126+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m, T scalar);
127+
128+ template<typename T, qualifier Q>
129+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2);
130+
131+ template<typename T, qualifier Q>
132+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator*(mat<3, 2, T, Q> const& m, T scalar);
133+
134+ template<typename T, qualifier Q>
135+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator*(T scalar, mat<3, 2, T, Q> const& m);
136+
137+ template<typename T, qualifier Q>
138+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<3, 2, T, Q>::col_type operator*(mat<3, 2, T, Q> const& m, typename mat<3, 2, T, Q>::row_type const& v);
139+
140+ template<typename T, qualifier Q>
141+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<3, 2, T, Q>::row_type operator*(typename mat<3, 2, T, Q>::col_type const& v, mat<3, 2, T, Q> const& m);
142+
143+ template<typename T, qualifier Q>
144+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<2, 3, T, Q> const& m2);
145+
146+ template<typename T, qualifier Q>
147+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<3, 3, T, Q> const& m2);
148+
149+ template<typename T, qualifier Q>
150+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<4, 3, T, Q> const& m2);
151+
152+ template<typename T, qualifier Q>
153+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator/(mat<3, 2, T, Q> const& m, T scalar);
154+
155+ template<typename T, qualifier Q>
156+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator/(T scalar, mat<3, 2, T, Q> const& m);
157+
158+ // -- Boolean operators --
159+
160+ template<typename T, qualifier Q>
161+ GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2);
162+
163+ template<typename T, qualifier Q>
164+ GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2);
165+
166+}//namespace glm
167+
168+#ifndef GLM_EXTERNAL_TEMPLATE
169+#include "type_mat3x2.inl"
170+#endif
@@ -0,0 +1,389 @@
1+namespace glm
2+{
3+ // -- Constructors --
4+
5+# if GLM_CONFIG_CTOR_INIT == GLM_ENABLE
6+ template<typename T, qualifier Q>
7+ GLM_DEFAULTED_DEFAULT_CTOR_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat()
8+ : value{col_type(1, 0), col_type(0, 1), col_type(0, 0)}
9+ {}
10+# endif
11+
12+ template<typename T, qualifier Q>
13+ template<qualifier P>
14+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<3, 2, T, P> const& m)
15+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
16+ {}
17+
18+ template<typename T, qualifier Q>
19+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(T s)
20+ : value{col_type(s, 0), col_type(0, s), col_type(0, 0)}
21+ {}
22+
23+ template<typename T, qualifier Q>
24+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat
25+ (
26+ T x0, T y0,
27+ T x1, T y1,
28+ T x2, T y2
29+ )
30+ : value{col_type(x0, y0), col_type(x1, y1), col_type(x2, y2)}
31+ {}
32+
33+ template<typename T, qualifier Q>
34+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2)
35+ : value{col_type(v0), col_type(v1), col_type(v2)}
36+ {}
37+
38+ // -- Conversion constructors --
39+
40+ template<typename T, qualifier Q>
41+ template<
42+ typename X0, typename Y0,
43+ typename X1, typename Y1,
44+ typename X2, typename Y2>
45+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat
46+ (
47+ X0 x0, Y0 y0,
48+ X1 x1, Y1 y1,
49+ X2 x2, Y2 y2
50+ )
51+ : value{col_type(x0, y0), col_type(x1, y1), col_type(x2, y2)}
52+ {}
53+
54+ template<typename T, qualifier Q>
55+ template<typename V0, typename V1, typename V2>
56+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(vec<2, V0, Q> const& v0, vec<2, V1, Q> const& v1, vec<2, V2, Q> const& v2)
57+ : value{col_type(v0), col_type(v1), col_type(v2)}
58+ {}
59+
60+ // -- Matrix conversions --
61+
62+ template<typename T, qualifier Q>
63+ template<typename U, qualifier P>
64+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<3, 2, U, P> const& m)
65+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
66+ {}
67+
68+ template<typename T, qualifier Q>
69+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<2, 2, T, Q> const& m)
70+ : value{col_type(m[0]), col_type(m[1]), col_type(0)}
71+ {}
72+
73+ template<typename T, qualifier Q>
74+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<3, 3, T, Q> const& m)
75+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
76+ {}
77+
78+ template<typename T, qualifier Q>
79+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<4, 4, T, Q> const& m)
80+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
81+ {}
82+
83+ template<typename T, qualifier Q>
84+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<2, 3, T, Q> const& m)
85+ : value{col_type(m[0]), col_type(m[1]), col_type(0)}
86+ {}
87+
88+ template<typename T, qualifier Q>
89+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<2, 4, T, Q> const& m)
90+ : value{col_type(m[0]), col_type(m[1]), col_type(0)}
91+ {}
92+
93+ template<typename T, qualifier Q>
94+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<3, 4, T, Q> const& m)
95+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
96+ {}
97+
98+ template<typename T, qualifier Q>
99+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<4, 2, T, Q> const& m)
100+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
101+ {}
102+
103+ template<typename T, qualifier Q>
104+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<4, 3, T, Q> const& m)
105+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
106+ {}
107+
108+ // -- Accesses --
109+
110+ template<typename T, qualifier Q>
111+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 2, T, Q>::col_type & mat<3, 2, T, Q>::operator[](typename mat<3, 2, T, Q>::length_type i) noexcept
112+ {
113+ GLM_ASSERT_LENGTH(i, this->length());
114+ return this->value[i];
115+ }
116+
117+ template<typename T, qualifier Q>
118+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 2, T, Q>::col_type const& mat<3, 2, T, Q>::operator[](typename mat<3, 2, T, Q>::length_type i) const noexcept
119+ {
120+ GLM_ASSERT_LENGTH(i, this->length());
121+ return this->value[i];
122+ }
123+
124+ // -- Unary updatable operators --
125+
126+ template<typename T, qualifier Q>
127+ template<typename U>
128+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator=(mat<3, 2, U, Q> const& m)
129+ {
130+ this->value[0] = m[0];
131+ this->value[1] = m[1];
132+ this->value[2] = m[2];
133+ return *this;
134+ }
135+
136+ template<typename T, qualifier Q>
137+ template<typename U>
138+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator+=(U s)
139+ {
140+ this->value[0] += s;
141+ this->value[1] += s;
142+ this->value[2] += s;
143+ return *this;
144+ }
145+
146+ template<typename T, qualifier Q>
147+ template<typename U>
148+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator+=(mat<3, 2, U, Q> const& m)
149+ {
150+ this->value[0] += m[0];
151+ this->value[1] += m[1];
152+ this->value[2] += m[2];
153+ return *this;
154+ }
155+
156+ template<typename T, qualifier Q>
157+ template<typename U>
158+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator-=(U s)
159+ {
160+ this->value[0] -= s;
161+ this->value[1] -= s;
162+ this->value[2] -= s;
163+ return *this;
164+ }
165+
166+ template<typename T, qualifier Q>
167+ template<typename U>
168+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator-=(mat<3, 2, U, Q> const& m)
169+ {
170+ this->value[0] -= m[0];
171+ this->value[1] -= m[1];
172+ this->value[2] -= m[2];
173+ return *this;
174+ }
175+
176+ template<typename T, qualifier Q>
177+ template<typename U>
178+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator*=(U s)
179+ {
180+ this->value[0] *= s;
181+ this->value[1] *= s;
182+ this->value[2] *= s;
183+ return *this;
184+ }
185+
186+ template<typename T, qualifier Q>
187+ template<typename U>
188+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> & mat<3, 2, T, Q>::operator/=(U s)
189+ {
190+ this->value[0] /= s;
191+ this->value[1] /= s;
192+ this->value[2] /= s;
193+ return *this;
194+ }
195+
196+ // -- Increment and decrement operators --
197+
198+ template<typename T, qualifier Q>
199+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator++()
200+ {
201+ ++this->value[0];
202+ ++this->value[1];
203+ ++this->value[2];
204+ return *this;
205+ }
206+
207+ template<typename T, qualifier Q>
208+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator--()
209+ {
210+ --this->value[0];
211+ --this->value[1];
212+ --this->value[2];
213+ return *this;
214+ }
215+
216+ template<typename T, qualifier Q>
217+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> mat<3, 2, T, Q>::operator++(int)
218+ {
219+ mat<3, 2, T, Q> Result(*this);
220+ ++*this;
221+ return Result;
222+ }
223+
224+ template<typename T, qualifier Q>
225+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> mat<3, 2, T, Q>::operator--(int)
226+ {
227+ mat<3, 2, T, Q> Result(*this);
228+ --*this;
229+ return Result;
230+ }
231+
232+ // -- Unary arithmetic operators --
233+
234+ template<typename T, qualifier Q>
235+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m)
236+ {
237+ return m;
238+ }
239+
240+ template<typename T, qualifier Q>
241+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m)
242+ {
243+ return mat<3, 2, T, Q>(
244+ -m[0],
245+ -m[1],
246+ -m[2]);
247+ }
248+
249+ // -- Binary arithmetic operators --
250+
251+ template<typename T, qualifier Q>
252+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m, T scalar)
253+ {
254+ return mat<3, 2, T, Q>(
255+ m[0] + scalar,
256+ m[1] + scalar,
257+ m[2] + scalar);
258+ }
259+
260+ template<typename T, qualifier Q>
261+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2)
262+ {
263+ return mat<3, 2, T, Q>(
264+ m1[0] + m2[0],
265+ m1[1] + m2[1],
266+ m1[2] + m2[2]);
267+ }
268+
269+ template<typename T, qualifier Q>
270+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m, T scalar)
271+ {
272+ return mat<3, 2, T, Q>(
273+ m[0] - scalar,
274+ m[1] - scalar,
275+ m[2] - scalar);
276+ }
277+
278+ template<typename T, qualifier Q>
279+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2)
280+ {
281+ return mat<3, 2, T, Q>(
282+ m1[0] - m2[0],
283+ m1[1] - m2[1],
284+ m1[2] - m2[2]);
285+ }
286+
287+ template<typename T, qualifier Q>
288+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> operator*(mat<3, 2, T, Q> const& m, T scalar)
289+ {
290+ return mat<3, 2, T, Q>(
291+ m[0] * scalar,
292+ m[1] * scalar,
293+ m[2] * scalar);
294+ }
295+
296+ template<typename T, qualifier Q>
297+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> operator*(T scalar, mat<3, 2, T, Q> const& m)
298+ {
299+ return mat<3, 2, T, Q>(
300+ m[0] * scalar,
301+ m[1] * scalar,
302+ m[2] * scalar);
303+ }
304+
305+ template<typename T, qualifier Q>
306+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 2, T, Q>::col_type operator*(mat<3, 2, T, Q> const& m, typename mat<3, 2, T, Q>::row_type const& v)
307+ {
308+ return typename mat<3, 2, T, Q>::col_type(
309+ m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z,
310+ m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z);
311+ }
312+
313+ template<typename T, qualifier Q>
314+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 2, T, Q>::row_type operator*(typename mat<3, 2, T, Q>::col_type const& v, mat<3, 2, T, Q> const& m)
315+ {
316+ return typename mat<3, 2, T, Q>::row_type(
317+ v.x * m[0][0] + v.y * m[0][1],
318+ v.x * m[1][0] + v.y * m[1][1],
319+ v.x * m[2][0] + v.y * m[2][1]);
320+ }
321+
322+ template<typename T, qualifier Q>
323+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<2, 3, T, Q> const& m2)
324+ {
325+ return mat<2, 2, T, Q>(
326+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
327+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
328+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2],
329+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2]);
330+ }
331+
332+ template<typename T, qualifier Q>
333+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<3, 3, T, Q> const& m2)
334+ {
335+ return mat<3, 2, T, Q>(
336+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
337+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
338+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2],
339+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2],
340+ m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2],
341+ m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2]);
342+ }
343+
344+ template<typename T, qualifier Q>
345+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<4, 3, T, Q> const& m2)
346+ {
347+ return mat<4, 2, T, Q>(
348+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
349+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
350+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2],
351+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2],
352+ m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2],
353+ m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2],
354+ m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1] + m1[2][0] * m2[3][2],
355+ m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1] + m1[2][1] * m2[3][2]);
356+ }
357+
358+ template<typename T, qualifier Q>
359+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> operator/(mat<3, 2, T, Q> const& m, T scalar)
360+ {
361+ return mat<3, 2, T, Q>(
362+ m[0] / scalar,
363+ m[1] / scalar,
364+ m[2] / scalar);
365+ }
366+
367+ template<typename T, qualifier Q>
368+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q> operator/(T scalar, mat<3, 2, T, Q> const& m)
369+ {
370+ return mat<3, 2, T, Q>(
371+ scalar / m[0],
372+ scalar / m[1],
373+ scalar / m[2]);
374+ }
375+
376+ // -- Boolean operators --
377+
378+ template<typename T, qualifier Q>
379+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2)
380+ {
381+ return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]);
382+ }
383+
384+ template<typename T, qualifier Q>
385+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2)
386+ {
387+ return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]);
388+ }
389+} //namespace glm
@@ -0,0 +1,187 @@
1+/// @ref core
2+/// @file glm/detail/type_mat3x3.hpp
3+
4+#pragma once
5+
6+#include "type_vec3.hpp"
7+#include <limits>
8+#include <cstddef>
9+
10+namespace glm
11+{
12+ template<typename T, qualifier Q>
13+ struct mat<3, 3, T, Q>
14+ {
15+ typedef vec<3, T, Q> col_type;
16+ typedef vec<3, T, Q> row_type;
17+ typedef mat<3, 3, T, Q> type;
18+ typedef mat<3, 3, T, Q> transpose_type;
19+ typedef T value_type;
20+
21+ private:
22+ col_type value[3];
23+
24+ public:
25+ // -- Accesses --
26+
27+ typedef length_t length_type;
28+ GLM_FUNC_DECL static constexpr length_type length() { return 3; }
29+
30+ GLM_FUNC_DECL GLM_CONSTEXPR col_type & operator[](length_type i) noexcept;
31+ GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const noexcept;
32+
33+ // -- Constructors --
34+
35+ GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR;
36+ GLM_CTOR_DECL mat(mat<3, 3, T, Q> const& m) = default;
37+ template<qualifier P>
38+ GLM_CTOR_DECL mat(mat<3, 3, T, P> const& m);
39+
40+ GLM_CTOR_DECL GLM_EXPLICIT mat(T scalar);
41+ GLM_CTOR_DECL mat(
42+ T x0, T y0, T z0,
43+ T x1, T y1, T z1,
44+ T x2, T y2, T z2);
45+ GLM_CTOR_DECL mat(
46+ col_type const& v0,
47+ col_type const& v1,
48+ col_type const& v2);
49+
50+ // -- Conversions --
51+
52+ template<
53+ typename X1, typename Y1, typename Z1,
54+ typename X2, typename Y2, typename Z2,
55+ typename X3, typename Y3, typename Z3>
56+ GLM_CTOR_DECL mat(
57+ X1 x1, Y1 y1, Z1 z1,
58+ X2 x2, Y2 y2, Z2 z2,
59+ X3 x3, Y3 y3, Z3 z3);
60+
61+ template<typename V1, typename V2, typename V3>
62+ GLM_CTOR_DECL mat(
63+ vec<3, V1, Q> const& v1,
64+ vec<3, V2, Q> const& v2,
65+ vec<3, V3, Q> const& v3);
66+
67+ // -- Matrix conversions --
68+
69+ template<typename U, qualifier P>
70+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 3, U, P> const& m);
71+
72+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 2, T, Q> const& x);
73+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 4, T, Q> const& x);
74+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 3, T, Q> const& x);
75+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 2, T, Q> const& x);
76+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 4, T, Q> const& x);
77+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 2, T, Q> const& x);
78+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 4, T, Q> const& x);
79+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 3, T, Q> const& x);
80+
81+ // -- Unary arithmetic operators --
82+
83+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q>& operator=(mat<3, 3, T, Q> const& m) = default;
84+
85+ template<typename U>
86+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q>& operator=(mat<3, 3, U, Q> const& m);
87+ template<typename U>
88+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q>& operator+=(U s);
89+ template<typename U>
90+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q>& operator+=(mat<3, 3, U, Q> const& m);
91+ template<typename U>
92+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q>& operator-=(U s);
93+ template<typename U>
94+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q>& operator-=(mat<3, 3, U, Q> const& m);
95+ template<typename U>
96+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q>& operator*=(U s);
97+ template<typename U>
98+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q>& operator*=(mat<3, 3, U, Q> const& m);
99+ template<typename U>
100+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q>& operator/=(U s);
101+ template<typename U>
102+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q>& operator/=(mat<3, 3, U, Q> const& m);
103+
104+ // -- Increment and decrement operators --
105+
106+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q>& operator++();
107+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q>& operator--();
108+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator++(int);
109+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator--(int);
110+ };
111+
112+ // -- Unary operators --
113+
114+ template<typename T, qualifier Q>
115+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m);
116+
117+ template<typename T, qualifier Q>
118+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m);
119+
120+ // -- Binary operators --
121+
122+ template<typename T, qualifier Q>
123+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m, T scalar);
124+
125+ template<typename T, qualifier Q>
126+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator+(T scalar, mat<3, 3, T, Q> const& m);
127+
128+ template<typename T, qualifier Q>
129+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2);
130+
131+ template<typename T, qualifier Q>
132+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m, T scalar);
133+
134+ template<typename T, qualifier Q>
135+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator-(T scalar, mat<3, 3, T, Q> const& m);
136+
137+ template<typename T, qualifier Q>
138+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2);
139+
140+ template<typename T, qualifier Q>
141+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m, T scalar);
142+
143+ template<typename T, qualifier Q>
144+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator*(T scalar, mat<3, 3, T, Q> const& m);
145+
146+ template<typename T, qualifier Q>
147+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<3, 3, T, Q>::col_type operator*(mat<3, 3, T, Q> const& m, typename mat<3, 3, T, Q>::row_type const& v);
148+
149+ template<typename T, qualifier Q>
150+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<3, 3, T, Q>::row_type operator*(typename mat<3, 3, T, Q>::col_type const& v, mat<3, 3, T, Q> const& m);
151+
152+ template<typename T, qualifier Q>
153+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2);
154+
155+ template<typename T, qualifier Q>
156+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2);
157+
158+ template<typename T, qualifier Q>
159+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2);
160+
161+ template<typename T, qualifier Q>
162+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator/(mat<3, 3, T, Q> const& m, T scalar);
163+
164+ template<typename T, qualifier Q>
165+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator/(T scalar, mat<3, 3, T, Q> const& m);
166+
167+ template<typename T, qualifier Q>
168+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<3, 3, T, Q>::col_type operator/(mat<3, 3, T, Q> const& m, typename mat<3, 3, T, Q>::row_type const& v);
169+
170+ template<typename T, qualifier Q>
171+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<3, 3, T, Q>::row_type operator/(typename mat<3, 3, T, Q>::col_type const& v, mat<3, 3, T, Q> const& m);
172+
173+ template<typename T, qualifier Q>
174+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator/(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2);
175+
176+ // -- Boolean operators --
177+
178+ template<typename T, qualifier Q>
179+ GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2);
180+
181+ template<typename T, qualifier Q>
182+ GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2);
183+}//namespace glm
184+
185+#ifndef GLM_EXTERNAL_TEMPLATE
186+#include "type_mat3x3.inl"
187+#endif
@@ -0,0 +1,503 @@
1+#include "../matrix.hpp"
2+#include "../common.hpp"
3+
4+namespace glm
5+{
6+ // -- Constructors --
7+
8+# if GLM_CONFIG_CTOR_INIT == GLM_ENABLE
9+ template<typename T, qualifier Q>
10+ GLM_DEFAULTED_DEFAULT_CTOR_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat()
11+ : value{col_type(1, 0, 0), col_type(0, 1, 0), col_type(0, 0, 1)}
12+ {}
13+# endif
14+
15+ template<typename T, qualifier Q>
16+ template<qualifier P>
17+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<3, 3, T, P> const& m)
18+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
19+ {}
20+
21+ template<typename T, qualifier Q>
22+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(T s)
23+ : value{col_type(s, 0, 0), col_type(0, s, 0), col_type(0, 0, s)}
24+ {}
25+
26+ template<typename T, qualifier Q>
27+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat
28+ (
29+ T x0, T y0, T z0,
30+ T x1, T y1, T z1,
31+ T x2, T y2, T z2
32+ )
33+ : value{col_type(x0, y0, z0), col_type(x1, y1, z1), col_type(x2, y2, z2)}
34+ {}
35+
36+ template<typename T, qualifier Q>
37+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2)
38+ : value{col_type(v0), col_type(v1), col_type(v2)}
39+ {}
40+
41+ // -- Conversion constructors --
42+
43+ template<typename T, qualifier Q>
44+ template<
45+ typename X1, typename Y1, typename Z1,
46+ typename X2, typename Y2, typename Z2,
47+ typename X3, typename Y3, typename Z3>
48+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat
49+ (
50+ X1 x1, Y1 y1, Z1 z1,
51+ X2 x2, Y2 y2, Z2 z2,
52+ X3 x3, Y3 y3, Z3 z3
53+ )
54+ : value{col_type(x1, y1, z1), col_type(x2, y2, z2), col_type(x3, y3, z3)}
55+ {}
56+
57+ template<typename T, qualifier Q>
58+ template<typename V1, typename V2, typename V3>
59+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(vec<3, V1, Q> const& v1, vec<3, V2, Q> const& v2, vec<3, V3, Q> const& v3)
60+ : value{col_type(v1), col_type(v2), col_type(v3)}
61+ {}
62+
63+ // -- Matrix conversions --
64+
65+ template<typename T, qualifier Q>
66+ template<typename U, qualifier P>
67+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<3, 3, U, P> const& m)
68+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
69+ {}
70+
71+ template<typename T, qualifier Q>
72+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<2, 2, T, Q> const& m)
73+ : value{col_type(m[0], 0), col_type(m[1], 0), col_type(0, 0, 1)}
74+ {}
75+
76+ template<typename T, qualifier Q>
77+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<4, 4, T, Q> const& m)
78+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
79+ {}
80+
81+ template<typename T, qualifier Q>
82+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<2, 3, T, Q> const& m)
83+ : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1)}
84+ {}
85+
86+ template<typename T, qualifier Q>
87+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<3, 2, T, Q> const& m)
88+ : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 1)}
89+ {}
90+
91+ template<typename T, qualifier Q>
92+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<2, 4, T, Q> const& m)
93+ : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1)}
94+ {}
95+
96+ template<typename T, qualifier Q>
97+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<4, 2, T, Q> const& m)
98+ : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 1)}
99+ {}
100+
101+ template<typename T, qualifier Q>
102+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<3, 4, T, Q> const& m)
103+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
104+ {}
105+
106+ template<typename T, qualifier Q>
107+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<4, 3, T, Q> const& m)
108+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
109+ {}
110+
111+ // -- Accesses --
112+
113+ template<typename T, qualifier Q>
114+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 3, T, Q>::col_type & mat<3, 3, T, Q>::operator[](typename mat<3, 3, T, Q>::length_type i) noexcept
115+ {
116+ GLM_ASSERT_LENGTH(i, this->length());
117+ return this->value[i];
118+ }
119+
120+ template<typename T, qualifier Q>
121+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 3, T, Q>::col_type const& mat<3, 3, T, Q>::operator[](typename mat<3, 3, T, Q>::length_type i) const noexcept
122+ {
123+ GLM_ASSERT_LENGTH(i, this->length());
124+ return this->value[i];
125+ }
126+
127+ // -- Unary updatable operators --
128+
129+ template<typename T, qualifier Q>
130+ template<typename U>
131+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator=(mat<3, 3, U, Q> const& m)
132+ {
133+ this->value[0] = m[0];
134+ this->value[1] = m[1];
135+ this->value[2] = m[2];
136+ return *this;
137+ }
138+
139+ template<typename T, qualifier Q>
140+ template<typename U>
141+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator+=(U s)
142+ {
143+ this->value[0] += s;
144+ this->value[1] += s;
145+ this->value[2] += s;
146+ return *this;
147+ }
148+
149+ template<typename T, qualifier Q>
150+ template<typename U>
151+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator+=(mat<3, 3, U, Q> const& m)
152+ {
153+ this->value[0] += m[0];
154+ this->value[1] += m[1];
155+ this->value[2] += m[2];
156+ return *this;
157+ }
158+
159+ template<typename T, qualifier Q>
160+ template<typename U>
161+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator-=(U s)
162+ {
163+ this->value[0] -= s;
164+ this->value[1] -= s;
165+ this->value[2] -= s;
166+ return *this;
167+ }
168+
169+ template<typename T, qualifier Q>
170+ template<typename U>
171+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator-=(mat<3, 3, U, Q> const& m)
172+ {
173+ this->value[0] -= m[0];
174+ this->value[1] -= m[1];
175+ this->value[2] -= m[2];
176+ return *this;
177+ }
178+
179+ template<typename T, qualifier Q>
180+ template<typename U>
181+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator*=(U s)
182+ {
183+ col_type sv(s);
184+ this->value[0] *= sv;
185+ this->value[1] *= sv;
186+ this->value[2] *= sv;
187+ return *this;
188+ }
189+
190+ template<typename T, qualifier Q>
191+ template<typename U>
192+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator*=(mat<3, 3, U, Q> const& m)
193+ {
194+ return (*this = *this * m);
195+ }
196+
197+ template<typename T, qualifier Q>
198+ template<typename U>
199+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator/=(U s)
200+ {
201+ this->value[0] /= s;
202+ this->value[1] /= s;
203+ this->value[2] /= s;
204+ return *this;
205+ }
206+
207+ template<typename T, qualifier Q>
208+ template<typename U>
209+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator/=(mat<3, 3, U, Q> const& m)
210+ {
211+ return *this *= inverse(m);
212+ }
213+
214+ // -- Increment and decrement operators --
215+
216+ template<typename T, qualifier Q>
217+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator++()
218+ {
219+ ++this->value[0];
220+ ++this->value[1];
221+ ++this->value[2];
222+ return *this;
223+ }
224+
225+ template<typename T, qualifier Q>
226+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator--()
227+ {
228+ --this->value[0];
229+ --this->value[1];
230+ --this->value[2];
231+ return *this;
232+ }
233+
234+ template<typename T, qualifier Q>
235+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> mat<3, 3, T, Q>::operator++(int)
236+ {
237+ mat<3, 3, T, Q> Result(*this);
238+ ++*this;
239+ return Result;
240+ }
241+
242+ template<typename T, qualifier Q>
243+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> mat<3, 3, T, Q>::operator--(int)
244+ {
245+ mat<3, 3, T, Q> Result(*this);
246+ --*this;
247+ return Result;
248+ }
249+
250+ // -- Unary arithmetic operators --
251+
252+ template<typename T, qualifier Q>
253+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m)
254+ {
255+ return m;
256+ }
257+
258+ template<typename T, qualifier Q>
259+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m)
260+ {
261+ return mat<3, 3, T, Q>(
262+ -m[0],
263+ -m[1],
264+ -m[2]);
265+ }
266+
267+ // -- Binary arithmetic operators --
268+
269+ template<typename T, qualifier Q>
270+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m, T scalar)
271+ {
272+ return mat<3, 3, T, Q>(
273+ m[0] + scalar,
274+ m[1] + scalar,
275+ m[2] + scalar);
276+ }
277+
278+ template<typename T, qualifier Q>
279+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator+(T scalar, mat<3, 3, T, Q> const& m)
280+ {
281+ return mat<3, 3, T, Q>(
282+ m[0] + scalar,
283+ m[1] + scalar,
284+ m[2] + scalar);
285+ }
286+
287+ template<typename T, qualifier Q>
288+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2)
289+ {
290+ return mat<3, 3, T, Q>(
291+ m1[0] + m2[0],
292+ m1[1] + m2[1],
293+ m1[2] + m2[2]);
294+ }
295+
296+ template<typename T, qualifier Q>
297+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m, T scalar)
298+ {
299+ return mat<3, 3, T, Q>(
300+ m[0] - scalar,
301+ m[1] - scalar,
302+ m[2] - scalar);
303+ }
304+
305+ template<typename T, qualifier Q>
306+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator-(T scalar, mat<3, 3, T, Q> const& m)
307+ {
308+ return mat<3, 3, T, Q>(
309+ scalar - m[0],
310+ scalar - m[1],
311+ scalar - m[2]);
312+ }
313+
314+ template<typename T, qualifier Q>
315+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2)
316+ {
317+ return mat<3, 3, T, Q>(
318+ m1[0] - m2[0],
319+ m1[1] - m2[1],
320+ m1[2] - m2[2]);
321+ }
322+
323+ template<typename T, qualifier Q>
324+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m, T scalar)
325+ {
326+ return mat<3, 3, T, Q>(
327+ m[0] * scalar,
328+ m[1] * scalar,
329+ m[2] * scalar);
330+ }
331+
332+ template<typename T, qualifier Q>
333+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator*(T scalar, mat<3, 3, T, Q> const& m)
334+ {
335+ return mat<3, 3, T, Q>(
336+ m[0] * scalar,
337+ m[1] * scalar,
338+ m[2] * scalar);
339+ }
340+
341+ template<typename T, qualifier Q>
342+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 3, T, Q>::col_type operator*(mat<3, 3, T, Q> const& m, typename mat<3, 3, T, Q>::row_type const& v)
343+ {
344+ return typename mat<3, 3, T, Q>::col_type(
345+ m[0] * splatX(v) + m[1] * splatY(v) + m[2] * splatZ(v));
346+ }
347+
348+ template<typename T, qualifier Q>
349+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 3, T, Q>::row_type operator*(typename mat<3, 3, T, Q>::col_type const& v, mat<3, 3, T, Q> const& m)
350+ {
351+ return typename mat<3, 3, T, Q>::row_type(
352+ dot(m[0], v),
353+ dot(m[1], v),
354+ dot(m[2], v));
355+ }
356+
357+ namespace detail
358+ {
359+ template<typename T, qualifier Q, bool is_aligned>
360+ struct mul3x3 {};
361+
362+#if GLM_CONFIG_SIMD == GLM_ENABLE
363+ template<typename T, qualifier Q>
364+ struct mul3x3<T, Q, true>
365+ {
366+ GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2)
367+ {
368+ typename mat<4, 4, T, Q>::col_type const SrcA0 = xyzz(m1[0]);
369+ typename mat<4, 4, T, Q>::col_type const SrcA1 = xyzz(m1[1]);
370+ typename mat<4, 4, T, Q>::col_type const SrcA2 = xyzz(m1[2]);
371+
372+ typename mat<4, 4, T, Q>::col_type const SrcB0 = xyzz(m2[0]);
373+ typename mat<4, 4, T, Q>::col_type const SrcB1 = xyzz(m2[1]);
374+ typename mat<4, 4, T, Q>::col_type const SrcB2 = xyzz(m2[2]);
375+
376+ typename mat<3, 3, T, Q>::col_type const tmp0 = xyz(glm::fma(SrcA2, splatZ(SrcB0), glm::fma(SrcA1, splatY(SrcB0), SrcA0 * splatX(SrcB0))));
377+ typename mat<3, 3, T, Q>::col_type const tmp1 = xyz(glm::fma(SrcA2, splatZ(SrcB1), glm::fma(SrcA1, splatY(SrcB1), SrcA0 * splatX(SrcB1))));
378+ typename mat<3, 3, T, Q>::col_type const tmp2 = xyz(glm::fma(SrcA2, splatZ(SrcB2), glm::fma(SrcA1, splatY(SrcB2), SrcA0 * splatX(SrcB2))));
379+
380+ return mat<3, 3, T, Q>(tmp0, tmp1, tmp2);
381+ }
382+ };
383+#endif
384+ template<typename T, qualifier Q>
385+ struct mul3x3<T, Q, false>
386+ {
387+ GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2)
388+ {
389+ typename mat<3, 3, T, Q>::col_type const& SrcA0 = m1[0];
390+ typename mat<3, 3, T, Q>::col_type const& SrcA1 = m1[1];
391+ typename mat<3, 3, T, Q>::col_type const& SrcA2 = m1[2];
392+
393+ typename mat<3, 3, T, Q>::col_type const& SrcB0 = m2[0];
394+ typename mat<3, 3, T, Q>::col_type const& SrcB1 = m2[1];
395+ typename mat<3, 3, T, Q>::col_type const& SrcB2 = m2[2];
396+
397+ // note: the following lines are decomposed to have consistent results between simd and non simd code (prevent rounding error because of operation order)
398+ //Result[0] = SrcA2 * SrcB0.z + SrcA1 * SrcB0.y + SrcA0 * SrcB0.x;
399+ //Result[1] = SrcA2 * SrcB1.z + SrcA1 * SrcB1.y + SrcA0 * SrcB1.x;
400+ //Result[2] = SrcA2 * SrcB2.z + SrcA1 * SrcB2.y + SrcA0 * SrcB2.x;
401+
402+ typename mat<3, 3, T, Q>::col_type tmp0 = SrcA0 * SrcB0.x;
403+ tmp0 += SrcA1 * SrcB0.y;
404+ tmp0 += SrcA2 * SrcB0.z;
405+ typename mat<3, 3, T, Q>::col_type tmp1 = SrcA0 * SrcB1.x;
406+ tmp1 += SrcA1 * SrcB1.y;
407+ tmp1 += SrcA2 * SrcB1.z;
408+ typename mat<3, 3, T, Q>::col_type tmp2 = SrcA0 * SrcB2.x;
409+ tmp2 += SrcA1 * SrcB2.y;
410+ tmp2 += SrcA2 * SrcB2.z;
411+
412+ return mat<3, 3, T, Q>(tmp0, tmp1, tmp2);
413+ }
414+ };
415+ }
416+
417+ template<typename T, qualifier Q>
418+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2)
419+ {
420+ return detail::mul3x3<T, Q, detail::is_aligned<Q>::value>::call(m1, m2);
421+ }
422+
423+ template<typename T, qualifier Q>
424+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2)
425+ {
426+ return mat<2, 3, T, Q>(
427+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
428+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
429+ m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2],
430+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2],
431+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2],
432+ m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2]);
433+ }
434+
435+ template<typename T, qualifier Q>
436+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2)
437+ {
438+ return mat<4, 3, T, Q>(
439+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
440+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
441+ m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2],
442+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2],
443+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2],
444+ m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2],
445+ m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2],
446+ m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2],
447+ m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2],
448+ m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1] + m1[2][0] * m2[3][2],
449+ m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1] + m1[2][1] * m2[3][2],
450+ m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1] + m1[2][2] * m2[3][2]);
451+ }
452+
453+ template<typename T, qualifier Q>
454+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator/(mat<3, 3, T, Q> const& m, T scalar)
455+ {
456+ return mat<3, 3, T, Q>(
457+ m[0] / scalar,
458+ m[1] / scalar,
459+ m[2] / scalar);
460+ }
461+
462+ template<typename T, qualifier Q>
463+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator/(T scalar, mat<3, 3, T, Q> const& m)
464+ {
465+ return mat<3, 3, T, Q>(
466+ scalar / m[0],
467+ scalar / m[1],
468+ scalar / m[2]);
469+ }
470+
471+ template<typename T, qualifier Q>
472+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 3, T, Q>::col_type operator/(mat<3, 3, T, Q> const& m, typename mat<3, 3, T, Q>::row_type const& v)
473+ {
474+ return inverse(m) * v;
475+ }
476+
477+ template<typename T, qualifier Q>
478+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 3, T, Q>::row_type operator/(typename mat<3, 3, T, Q>::col_type const& v, mat<3, 3, T, Q> const& m)
479+ {
480+ return v * inverse(m);
481+ }
482+
483+ template<typename T, qualifier Q>
484+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator/(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2)
485+ {
486+ mat<3, 3, T, Q> m1_copy(m1);
487+ return m1_copy /= m2;
488+ }
489+
490+ // -- Boolean operators --
491+
492+ template<typename T, qualifier Q>
493+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2)
494+ {
495+ return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]);
496+ }
497+
498+ template<typename T, qualifier Q>
499+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2)
500+ {
501+ return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]);
502+ }
503+} //namespace glm
@@ -0,0 +1,169 @@
1+/// @ref core
2+/// @file glm/detail/type_mat3x4.hpp
3+
4+#pragma once
5+
6+#include "type_vec3.hpp"
7+#include "type_vec4.hpp"
8+#include <limits>
9+#include <cstddef>
10+
11+namespace glm
12+{
13+ template<typename T, qualifier Q>
14+ struct mat<3, 4, T, Q>
15+ {
16+ typedef vec<4, T, Q> col_type;
17+ typedef vec<3, T, Q> row_type;
18+ typedef mat<3, 4, T, Q> type;
19+ typedef mat<4, 3, T, Q> transpose_type;
20+ typedef T value_type;
21+
22+ private:
23+ col_type value[3];
24+
25+ public:
26+ // -- Accesses --
27+
28+ typedef length_t length_type;
29+ GLM_FUNC_DECL static constexpr length_type length() { return 3; }
30+
31+ GLM_FUNC_DECL GLM_CONSTEXPR col_type & operator[](length_type i) noexcept;
32+ GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const noexcept;
33+
34+ // -- Constructors --
35+
36+ GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR;
37+ GLM_CTOR_DECL mat(mat<3, 4, T, Q> const& m) = default;
38+ template<qualifier P>
39+ GLM_CTOR_DECL mat(mat<3, 4, T, P> const& m);
40+
41+ GLM_CTOR_DECL GLM_EXPLICIT mat(T scalar);
42+ GLM_CTOR_DECL mat(
43+ T x0, T y0, T z0, T w0,
44+ T x1, T y1, T z1, T w1,
45+ T x2, T y2, T z2, T w2);
46+ GLM_CTOR_DECL mat(
47+ col_type const& v0,
48+ col_type const& v1,
49+ col_type const& v2);
50+
51+ // -- Conversions --
52+
53+ template<
54+ typename X1, typename Y1, typename Z1, typename W1,
55+ typename X2, typename Y2, typename Z2, typename W2,
56+ typename X3, typename Y3, typename Z3, typename W3>
57+ GLM_CTOR_DECL mat(
58+ X1 x1, Y1 y1, Z1 z1, W1 w1,
59+ X2 x2, Y2 y2, Z2 z2, W2 w2,
60+ X3 x3, Y3 y3, Z3 z3, W3 w3);
61+
62+ template<typename V1, typename V2, typename V3>
63+ GLM_CTOR_DECL mat(
64+ vec<4, V1, Q> const& v1,
65+ vec<4, V2, Q> const& v2,
66+ vec<4, V3, Q> const& v3);
67+
68+ // -- Matrix conversions --
69+
70+ template<typename U, qualifier P>
71+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 4, U, P> const& m);
72+
73+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 2, T, Q> const& x);
74+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 3, T, Q> const& x);
75+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 4, T, Q> const& x);
76+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 3, T, Q> const& x);
77+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 2, T, Q> const& x);
78+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 4, T, Q> const& x);
79+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 2, T, Q> const& x);
80+ GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 3, T, Q> const& x);
81+
82+ // -- Unary arithmetic operators --
83+
84+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q>& operator=(mat<3, 4, T, Q> const& m) = default;
85+
86+ template<typename U>
87+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q>& operator=(mat<3, 4, U, Q> const& m);
88+ template<typename U>
89+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q>& operator+=(U s);
90+ template<typename U>
91+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q>& operator+=(mat<3, 4, U, Q> const& m);
92+ template<typename U>
93+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q>& operator-=(U s);
94+ template<typename U>
95+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q>& operator-=(mat<3, 4, U, Q> const& m);
96+ template<typename U>
97+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q>& operator*=(U s);
98+ template<typename U>
99+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q>& operator/=(U s);
100+
101+ // -- Increment and decrement operators --
102+
103+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q>& operator++();
104+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q>& operator--();
105+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator++(int);
106+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator--(int);
107+ };
108+
109+ // -- Unary operators --
110+
111+ template<typename T, qualifier Q>
112+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m);
113+
114+ template<typename T, qualifier Q>
115+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m);
116+
117+ // -- Binary operators --
118+
119+ template<typename T, qualifier Q>
120+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m, T scalar);
121+
122+ template<typename T, qualifier Q>
123+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2);
124+
125+ template<typename T, qualifier Q>
126+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m, T scalar);
127+
128+ template<typename T, qualifier Q>
129+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2);
130+
131+ template<typename T, qualifier Q>
132+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator*(mat<3, 4, T, Q> const& m, T scalar);
133+
134+ template<typename T, qualifier Q>
135+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator*(T scalar, mat<3, 4, T, Q> const& m);
136+
137+ template<typename T, qualifier Q>
138+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<3, 4, T, Q>::col_type operator*(mat<3, 4, T, Q> const& m, typename mat<3, 4, T, Q>::row_type const& v);
139+
140+ template<typename T, qualifier Q>
141+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<3, 4, T, Q>::row_type operator*(typename mat<3, 4, T, Q>::col_type const& v, mat<3, 4, T, Q> const& m);
142+
143+ template<typename T, qualifier Q>
144+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<4, 3, T, Q> const& m2);
145+
146+ template<typename T, qualifier Q>
147+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<2, 3, T, Q> const& m2);
148+
149+ template<typename T, qualifier Q>
150+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<3, 3, T, Q> const& m2);
151+
152+ template<typename T, qualifier Q>
153+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator/(mat<3, 4, T, Q> const& m, T scalar);
154+
155+ template<typename T, qualifier Q>
156+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator/(T scalar, mat<3, 4, T, Q> const& m);
157+
158+ // -- Boolean operators --
159+
160+ template<typename T, qualifier Q>
161+ GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2);
162+
163+ template<typename T, qualifier Q>
164+ GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2);
165+}//namespace glm
166+
167+#ifndef GLM_EXTERNAL_TEMPLATE
168+#include "type_mat3x4.inl"
169+#endif
@@ -0,0 +1,423 @@
1+namespace glm
2+{
3+ // -- Constructors --
4+
5+# if GLM_CONFIG_CTOR_INIT == GLM_ENABLE
6+ template<typename T, qualifier Q>
7+ GLM_DEFAULTED_DEFAULT_CTOR_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat()
8+ : value{col_type(1, 0, 0, 0), col_type(0, 1, 0, 0), col_type(0, 0, 1, 0)}
9+ {}
10+# endif
11+
12+ template<typename T, qualifier Q>
13+ template<qualifier P>
14+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<3, 4, T, P> const& m)
15+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
16+ {}
17+
18+ template<typename T, qualifier Q>
19+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(T s)
20+ : value{col_type(s, 0, 0, 0), col_type(0, s, 0, 0), col_type(0, 0, s, 0)}
21+ {}
22+
23+ template<typename T, qualifier Q>
24+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat
25+ (
26+ T x0, T y0, T z0, T w0,
27+ T x1, T y1, T z1, T w1,
28+ T x2, T y2, T z2, T w2
29+ )
30+ : value{
31+ col_type(x0, y0, z0, w0),
32+ col_type(x1, y1, z1, w1),
33+ col_type(x2, y2, z2, w2)}
34+ {}
35+
36+ template<typename T, qualifier Q>
37+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2)
38+ : value{col_type(v0), col_type(v1), col_type(v2)}
39+ {}
40+
41+ // -- Conversion constructors --
42+
43+ template<typename T, qualifier Q>
44+ template<
45+ typename X0, typename Y0, typename Z0, typename W0,
46+ typename X1, typename Y1, typename Z1, typename W1,
47+ typename X2, typename Y2, typename Z2, typename W2>
48+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat
49+ (
50+ X0 x0, Y0 y0, Z0 z0, W0 w0,
51+ X1 x1, Y1 y1, Z1 z1, W1 w1,
52+ X2 x2, Y2 y2, Z2 z2, W2 w2
53+ )
54+ : value{
55+ col_type(x0, y0, z0, w0),
56+ col_type(x1, y1, z1, w1),
57+ col_type(x2, y2, z2, w2)}
58+ {}
59+
60+ template<typename T, qualifier Q>
61+ template<typename V1, typename V2, typename V3>
62+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(vec<4, V1, Q> const& v0, vec<4, V2, Q> const& v1, vec<4, V3, Q> const& v2)
63+ : value{col_type(v0), col_type(v1), col_type(v2)}
64+ {}
65+
66+ // -- Matrix conversions --
67+
68+ template<typename T, qualifier Q>
69+ template<typename U, qualifier P>
70+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<3, 4, U, P> const& m)
71+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
72+ {}
73+
74+ template<typename T, qualifier Q>
75+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<2, 2, T, Q> const& m)
76+ : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(0, 0, 1, 0)}
77+ {}
78+
79+ template<typename T, qualifier Q>
80+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<3, 3, T, Q> const& m)
81+ : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 0)}
82+ {}
83+
84+ template<typename T, qualifier Q>
85+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<4, 4, T, Q> const& m)
86+ : value{col_type(m[0]), col_type(m[1]), col_type(m[2])}
87+ {}
88+
89+ template<typename T, qualifier Q>
90+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<2, 3, T, Q> const& m)
91+ : value{col_type(m[0], 0), col_type(m[1], 0), col_type(0, 0, 1, 0)}
92+ {}
93+
94+ template<typename T, qualifier Q>
95+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<3, 2, T, Q> const& m)
96+ : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(m[2], 1, 0)}
97+ {}
98+
99+ template<typename T, qualifier Q>
100+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<2, 4, T, Q> const& m)
101+ : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1, 0)}
102+ {}
103+
104+ template<typename T, qualifier Q>
105+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<4, 2, T, Q> const& m)
106+ : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(m[2], 1, 0)}
107+ {}
108+
109+ template<typename T, qualifier Q>
110+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<4, 3, T, Q> const& m)
111+ : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 0)}
112+ {}
113+
114+ // -- Accesses --
115+
116+ template<typename T, qualifier Q>
117+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 4, T, Q>::col_type & mat<3, 4, T, Q>::operator[](typename mat<3, 4, T, Q>::length_type i) noexcept
118+ {
119+ GLM_ASSERT_LENGTH(i, this->length());
120+ return this->value[i];
121+ }
122+
123+ template<typename T, qualifier Q>
124+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 4, T, Q>::col_type const& mat<3, 4, T, Q>::operator[](typename mat<3, 4, T, Q>::length_type i) const noexcept
125+ {
126+ GLM_ASSERT_LENGTH(i, this->length());
127+ return this->value[i];
128+ }
129+
130+ // -- Unary updatable operators --
131+
132+ template<typename T, qualifier Q>
133+ template<typename U>
134+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator=(mat<3, 4, U, Q> const& m)
135+ {
136+ this->value[0] = m[0];
137+ this->value[1] = m[1];
138+ this->value[2] = m[2];
139+ return *this;
140+ }
141+
142+ template<typename T, qualifier Q>
143+ template<typename U>
144+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator+=(U s)
145+ {
146+ this->value[0] += s;
147+ this->value[1] += s;
148+ this->value[2] += s;
149+ return *this;
150+ }
151+
152+ template<typename T, qualifier Q>
153+ template<typename U>
154+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator+=(mat<3, 4, U, Q> const& m)
155+ {
156+ this->value[0] += m[0];
157+ this->value[1] += m[1];
158+ this->value[2] += m[2];
159+ return *this;
160+ }
161+
162+ template<typename T, qualifier Q>
163+ template<typename U>
164+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator-=(U s)
165+ {
166+ this->value[0] -= s;
167+ this->value[1] -= s;
168+ this->value[2] -= s;
169+ return *this;
170+ }
171+
172+ template<typename T, qualifier Q>
173+ template<typename U>
174+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator-=(mat<3, 4, U, Q> const& m)
175+ {
176+ this->value[0] -= m[0];
177+ this->value[1] -= m[1];
178+ this->value[2] -= m[2];
179+ return *this;
180+ }
181+
182+ template<typename T, qualifier Q>
183+ template<typename U>
184+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator*=(U s)
185+ {
186+ this->value[0] *= s;
187+ this->value[1] *= s;
188+ this->value[2] *= s;
189+ return *this;
190+ }
191+
192+ template<typename T, qualifier Q>
193+ template<typename U>
194+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> & mat<3, 4, T, Q>::operator/=(U s)
195+ {
196+ this->value[0] /= s;
197+ this->value[1] /= s;
198+ this->value[2] /= s;
199+ return *this;
200+ }
201+
202+ // -- Increment and decrement operators --
203+
204+ template<typename T, qualifier Q>
205+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator++()
206+ {
207+ ++this->value[0];
208+ ++this->value[1];
209+ ++this->value[2];
210+ return *this;
211+ }
212+
213+ template<typename T, qualifier Q>
214+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator--()
215+ {
216+ --this->value[0];
217+ --this->value[1];
218+ --this->value[2];
219+ return *this;
220+ }
221+
222+ template<typename T, qualifier Q>
223+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> mat<3, 4, T, Q>::operator++(int)
224+ {
225+ mat<3, 4, T, Q> Result(*this);
226+ ++*this;
227+ return Result;
228+ }
229+
230+ template<typename T, qualifier Q>
231+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> mat<3, 4, T, Q>::operator--(int)
232+ {
233+ mat<3, 4, T, Q> Result(*this);
234+ --*this;
235+ return Result;
236+ }
237+
238+ // -- Unary arithmetic operators --
239+
240+ template<typename T, qualifier Q>
241+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m)
242+ {
243+ return m;
244+ }
245+
246+ template<typename T, qualifier Q>
247+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m)
248+ {
249+ return mat<3, 4, T, Q>(
250+ -m[0],
251+ -m[1],
252+ -m[2]);
253+ }
254+
255+ // -- Binary arithmetic operators --
256+
257+ template<typename T, qualifier Q>
258+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m, T scalar)
259+ {
260+ return mat<3, 4, T, Q>(
261+ m[0] + scalar,
262+ m[1] + scalar,
263+ m[2] + scalar);
264+ }
265+
266+ template<typename T, qualifier Q>
267+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2)
268+ {
269+ return mat<3, 4, T, Q>(
270+ m1[0] + m2[0],
271+ m1[1] + m2[1],
272+ m1[2] + m2[2]);
273+ }
274+
275+ template<typename T, qualifier Q>
276+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m, T scalar)
277+ {
278+ return mat<3, 4, T, Q>(
279+ m[0] - scalar,
280+ m[1] - scalar,
281+ m[2] - scalar);
282+ }
283+
284+ template<typename T, qualifier Q>
285+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2)
286+ {
287+ return mat<3, 4, T, Q>(
288+ m1[0] - m2[0],
289+ m1[1] - m2[1],
290+ m1[2] - m2[2]);
291+ }
292+
293+ template<typename T, qualifier Q>
294+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> operator*(mat<3, 4, T, Q> const& m, T scalar)
295+ {
296+ return mat<3, 4, T, Q>(
297+ m[0] * scalar,
298+ m[1] * scalar,
299+ m[2] * scalar);
300+ }
301+
302+ template<typename T, qualifier Q>
303+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> operator*(T scalar, mat<3, 4, T, Q> const& m)
304+ {
305+ return mat<3, 4, T, Q>(
306+ m[0] * scalar,
307+ m[1] * scalar,
308+ m[2] * scalar);
309+ }
310+
311+ template<typename T, qualifier Q>
312+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 4, T, Q>::col_type operator*
313+ (
314+ mat<3, 4, T, Q> const& m,
315+ typename mat<3, 4, T, Q>::row_type const& v
316+ )
317+ {
318+ return typename mat<3, 4, T, Q>::col_type(
319+ m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z,
320+ m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z,
321+ m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z,
322+ m[0][3] * v.x + m[1][3] * v.y + m[2][3] * v.z);
323+ }
324+
325+ template<typename T, qualifier Q>
326+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 4, T, Q>::row_type operator*
327+ (
328+ typename mat<3, 4, T, Q>::col_type const& v,
329+ mat<3, 4, T, Q> const& m
330+ )
331+ {
332+ return typename mat<3, 4, T, Q>::row_type(
333+ v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2] + v.w * m[0][3],
334+ v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2] + v.w * m[1][3],
335+ v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2] + v.w * m[2][3]);
336+ }
337+
338+ template<typename T, qualifier Q>
339+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<4, 3, T, Q> const& m2)
340+ {
341+ return mat<4, 4, T, Q>(
342+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
343+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
344+ m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2],
345+ m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2],
346+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2],
347+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2],
348+ m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2],
349+ m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2],
350+ m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2],
351+ m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2],
352+ m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2],
353+ m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2],
354+ m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1] + m1[2][0] * m2[3][2],
355+ m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1] + m1[2][1] * m2[3][2],
356+ m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1] + m1[2][2] * m2[3][2],
357+ m1[0][3] * m2[3][0] + m1[1][3] * m2[3][1] + m1[2][3] * m2[3][2]);
358+ }
359+
360+ template<typename T, qualifier Q>
361+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<2, 3, T, Q> const& m2)
362+ {
363+ return mat<2, 4, T, Q>(
364+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
365+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
366+ m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2],
367+ m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2],
368+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2],
369+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2],
370+ m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2],
371+ m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2]);
372+ }
373+
374+ template<typename T, qualifier Q>
375+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<3, 3, T, Q> const& m2)
376+ {
377+ return mat<3, 4, T, Q>(
378+ m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
379+ m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
380+ m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2],
381+ m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2],
382+ m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2],
383+ m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2],
384+ m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2],
385+ m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2],
386+ m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2],
387+ m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2],
388+ m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2],
389+ m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2]);
390+ }
391+
392+ template<typename T, qualifier Q>
393+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> operator/(mat<3, 4, T, Q> const& m, T scalar)
394+ {
395+ return mat<3, 4, T, Q>(
396+ m[0] / scalar,
397+ m[1] / scalar,
398+ m[2] / scalar);
399+ }
400+
401+ template<typename T, qualifier Q>
402+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q> operator/(T scalar, mat<3, 4, T, Q> const& m)
403+ {
404+ return mat<3, 4, T, Q>(
405+ scalar / m[0],
406+ scalar / m[1],
407+ scalar / m[2]);
408+ }
409+
410+ // -- Boolean operators --
411+
412+ template<typename T, qualifier Q>
413+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2)
414+ {
415+ return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]);
416+ }
417+
418+ template<typename T, qualifier Q>
419+ GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2)
420+ {
421+ return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]);
422+ }
423+} //namespace glm

長いので途中までです

@@ -0,0 +1,174 @@
1+/// @ref core
2+/// @file glm/detail/type_mat4x2.hpp
3+
4+#pragma once
5+
6+#include "type_vec2.hpp"
7+#include "type_vec4.hpp"
8+#include <limits>
9+#include <cstddef>
10+
11+namespace glm
12+{
13+ template<typename T, qualifier Q>
14+ struct mat<4, 2, T, Q>
15+ {
16+ typedef vec<2, T, Q> col_type;
17+ typedef vec<4, T, Q> row_type;
18+ typedef mat<4, 2, T, Q> type;
19+ typedef mat<2, 4, T, Q> transpose_type;
20+ typedef T value_type;
21+
22+ private:
23+ col_type value[4];
24+
25+ public:
26+ // -- Accesses --
27+
28+ typedef length_t length_type;
29+ GLM_FUNC_DECL static constexpr length_type length() { return 4; }
30+
31+ GLM_FUNC_DECL GLM_CONSTEXPR col_type & operator[](length_type i) noexcept;
32+ GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const noexcept;
33+
34+ // -- Constructors --
35+
36+ GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR;
37+ GLM_CTOR_DECL mat(mat<4, 2, T, Q> const& m) = default;
38+ template<qualifier P>
39+ GLM_CTOR_DECL mat(mat<4, 2, T, P> const& m);
40+
41+ GLM_CTOR_DECL mat(T scalar);
42+ GLM_CTOR_DECL mat(
43+ T x0, T y0,
44+ T x1, T y1,
45+ T x2, T y2,
46+ T x3, T y3);
47+ GLM_CTOR_DECL mat(
48+ col_type const& v0,
49+ col_type const& v1,
50+ col_type const& v2,
51+ col_type const& v3);
52+
53+ // -- Conversions --
54+
55+ template<
56+ typename X0, typename Y0,
57+ typename X1, typename Y1,
58+ typename X2, typename Y2,
59+ typename X3, typename Y3>
60+ GLM_CTOR_DECL mat(
61+ X0 x0, Y0 y0,
62+ X1 x1, Y1 y1,
63+ X2 x2, Y2 y2,
64+ X3 x3, Y3 y3);
65+
66+ template<typename V1, typename V2, typename V3, typename V4>
67+ GLM_CTOR_DECL mat(
68+ vec<2, V1, Q> const& v1,
69+ vec<2, V2, Q> const& v2,
70+ vec<2, V3, Q> const& v3,
71+ vec<2, V4, Q> const& v4);
72+
73+ // -- Matrix conversions --
74+
75+ template<typename U, qualifier P>
76+ GLM_CTOR_DECL mat(mat<4, 2, U, P> const& m);
77+
78+ GLM_CTOR_DECL mat(mat<2, 2, T, Q> const& x);
79+ GLM_CTOR_DECL mat(mat<3, 3, T, Q> const& x);
80+ GLM_CTOR_DECL mat(mat<4, 4, T, Q> const& x);
81+ GLM_CTOR_DECL mat(mat<2, 3, T, Q> const& x);
82+ GLM_CTOR_DECL mat(mat<3, 2, T, Q> const& x);
83+ GLM_CTOR_DECL mat(mat<2, 4, T, Q> const& x);
84+ GLM_CTOR_DECL mat(mat<4, 3, T, Q> const& x);
85+ GLM_CTOR_DECL mat(mat<3, 4, T, Q> const& x);
86+
87+ // -- Unary arithmetic operators --
88+
89+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q>& operator=(mat<4, 2, T, Q> const& m) = default;
90+
91+ template<typename U>
92+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q>& operator=(mat<4, 2, U, Q> const& m);
93+ template<typename U>
94+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q>& operator+=(U s);
95+ template<typename U>
96+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q>& operator+=(mat<4, 2, U, Q> const& m);
97+ template<typename U>
98+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q>& operator-=(U s);
99+ template<typename U>
100+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q>& operator-=(mat<4, 2, U, Q> const& m);
101+ template<typename U>
102+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q>& operator*=(U s);
103+ template<typename U>
104+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q>& operator/=(U s);
105+
106+ // -- Increment and decrement operators --
107+
108+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q>& operator++ ();
109+ GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q>& operator-- ();
110+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator++(int);
111+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator--(int);
112+ };
113+
114+ // -- Unary operators --
115+
116+ template<typename T, qualifier Q>
117+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m);
118+
119+ template<typename T, qualifier Q>
120+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m);
121+
122+ // -- Binary operators --
123+
124+ template<typename T, qualifier Q>
125+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m, T scalar);
126+
127+ template<typename T, qualifier Q>
128+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2);
129+
130+ template<typename T, qualifier Q>
131+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m, T scalar);
132+
133+ template<typename T, qualifier Q>
134+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2);
135+
136+ template<typename T, qualifier Q>
137+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator*(mat<4, 2, T, Q> const& m, T scalar);
138+
139+ template<typename T, qualifier Q>
140+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator*(T scalar, mat<4, 2, T, Q> const& m);
141+
142+ template<typename T, qualifier Q>
143+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<4, 2, T, Q>::col_type operator*(mat<4, 2, T, Q> const& m, typename mat<4, 2, T, Q>::row_type const& v);
144+
145+ template<typename T, qualifier Q>
146+ GLM_FUNC_DECL GLM_CONSTEXPR typename mat<4, 2, T, Q>::row_type operator*(typename mat<4, 2, T, Q>::col_type const& v, mat<4, 2, T, Q> const& m);
147+
148+ template<typename T, qualifier Q>
149+ GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<2, 4, T, Q> const& m2);
150+
151+ template<typename T, qualifier Q>
152+ GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<3, 4, T, Q> const& m2);
153+
154+ template<typename T, qualifier Q>
155+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<4, 4, T, Q> const& m2);
156+
157+ template<typename T, qualifier Q>
158+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator/(mat<4, 2, T, Q> const& m, T scalar);
159+
160+ template<typename T, qualifier Q>
161+ GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator/(T scalar, mat<4, 2, T, Q> const& m);
162+
163+ // -- Boolean operators --
164+
165+ template<typename T, qualifier Q>
166+ GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2);
167+
168+ template<typename T, qualifier Q>
169+ GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2);
170+}//namespace glm
171+
172+#ifndef GLM_EXTERNAL_TEMPLATE
173+#include "type_mat4x2.inl"
174+#endif

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません

差分が多過ぎるので表示しません