diff --git a/enginecustom/applicationclass.cpp b/enginecustom/applicationclass.cpp index 9cbe31c..7e4bee4 100644 --- a/enginecustom/applicationclass.cpp +++ b/enginecustom/applicationclass.cpp @@ -51,7 +51,6 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) char spriteFilename[128]; char fpsString[32]; bool result; - std::vector Filename; m_screenWidth = screenWidth; m_screenHeight = screenHeight; @@ -174,18 +173,32 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) // Set the file name of the model. strcpy_s(modelFilename, "cube.txt"); - // Set the file name of the textures. - Filename.push_back("stone01.tga"); - Filename.push_back("normal01.tga"); - Filename.push_back("spec02.tga"); - Filename.push_back("alpha01.tga"); - Filename.push_back("light01.tga"); - Filename.push_back("moss01.tga"); + // Charger les textures + std::vector textureFilenames = { + L"stone01.tga", + L"normal01.tga", + L"spec02.tga", + L"alpha01.tga", + L"light01.tga", + L"moss01.tga" + }; + + for (const auto& textureFilename : textureFilenames) + { + ID3D11ShaderResourceView* texture = nullptr; + result = DirectX::CreateWICTextureFromFile(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), textureFilename.c_str(), nullptr, &texture); + if (FAILED(result)) + { + Logger::Get().Log("Failed to load texture: " + std::string(textureFilename.begin(), textureFilename.end()), __FILE__, __LINE__, Logger::LogLevel::Error); + return false; + } + textures.push_back(texture); + } // Create and initialize the model object. m_Model = new ModelClass; - result = m_Model->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, Filename); + result = m_Model->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textures); if (!result) { Logger::Get().Log("Could not initialize the model object", __FILE__, __LINE__, Logger::LogLevel::Error); @@ -267,13 +280,36 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) // Set the file names of the bath model. strcpy_s(modelFilename, "bath.txt"); - // replace first element with the new filename - Filename[0] = "marble01.tga"; + // Charger les textures initiales pour m_BathModel + std::vector bathTextures = { + L"marble01.tga", + L"normal01.tga", + L"spec02.tga", + L"alpha01.tga", + L"light01.tga", + L"moss01.tga" + }; + + textures.clear(); + for (const auto& textureFilename : bathTextures) + { + ID3D11ShaderResourceView* texture = nullptr; + result = DirectX::CreateWICTextureFromFile(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), textureFilename.c_str(), nullptr, &texture); + if (FAILED(result)) + { + Logger::Get().Log("Failed to load texture: " + std::string(textureFilename.begin(), textureFilename.end()), __FILE__, __LINE__, Logger::LogLevel::Error); + return false; + } + textures.push_back(texture); + } + + // Set the file name of the bath model. + strcpy_s(modelFilename, "bath.txt"); // Create and initialize the bath model object. m_BathModel = new ModelClass; - result = m_BathModel->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, Filename); + result = m_BathModel->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textures); if (!result) { MessageBox(hwnd, L"Could not initialize the bath model object.", L"Error", MB_OK); @@ -283,12 +319,32 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) // Set the file names of the water model. strcpy_s(modelFilename, "water.txt"); // replace first element with the new filename - Filename[1] = "water01.tga"; + std::vector waterTextures = { + L"water01.tga", + L"normal01.tga", + L"spec02.tga", + L"alpha01.tga", + L"light01.tga", + L"moss01.tga" + }; + + textures.clear(); + for (const auto& textureFilename : waterTextures) + { + ID3D11ShaderResourceView* texture = nullptr; + result = DirectX::CreateWICTextureFromFile(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), textureFilename.c_str(), nullptr, &texture); + if (FAILED(result)) + { + Logger::Get().Log("Failed to load texture: " + std::string(textureFilename.begin(), textureFilename.end()), __FILE__, __LINE__, Logger::LogLevel::Error); + return false; + } + textures.push_back(texture); + } // Create and initialize the water model object. m_WaterModel = new ModelClass; - result = m_WaterModel->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, Filename); + result = m_WaterModel->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textures); if (!result) { MessageBox(hwnd, L"Could not initialize the water model object.", L"Error", MB_OK); @@ -1051,7 +1107,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t if (!m_enableCelShading) { - result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), cube->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, cube->GetTexture(0), + result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), cube->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, cube->GetTexture(), diffuseColor, lightPosition, ambientColor); if (!result) { @@ -1062,7 +1118,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t // Render cel shading globally to the scene using the cel shader if the checkbox is checked. if (m_enableCelShading) { - result = m_ShaderManager->RenderCelShadingShader(m_Direct3D->GetDeviceContext(), cube->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, cube->GetTexture(0), + result = m_ShaderManager->RenderCelShadingShader(m_Direct3D->GetDeviceContext(), cube->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, cube->GetTexture(), m_Lights[0]->GetDirection(), m_Lights[0]->GetDiffuseColor(), TrueLightPosition); if (!result) { @@ -1089,7 +1145,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t object->Render(m_Direct3D->GetDeviceContext()); if (!m_enableCelShading) { - result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), object->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, object->GetTexture(0), + result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), object->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, object->GetTexture(), diffuseColor, lightPosition, ambientColor); if (!result) @@ -1101,7 +1157,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t // Render cel shading globally to the scene using the cel shader if the checkbox is checked. if (m_enableCelShading) { - result = m_ShaderManager->RenderCelShadingShader(m_Direct3D->GetDeviceContext(), object->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, object->GetTexture(0), + result = m_ShaderManager->RenderCelShadingShader(m_Direct3D->GetDeviceContext(), object->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, object->GetTexture(), m_Lights[0]->GetDirection(), m_Lights[0]->GetDiffuseColor(), TrueLightPosition); if (!result) { @@ -1124,7 +1180,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t chunk->Render(m_Direct3D->GetDeviceContext()); if (!m_enableCelShading) { - result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), chunk->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, chunk->GetTexture(5), + result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), chunk->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, chunk->GetTexture(), diffuseColor, lightPosition, ambientColor); if (!result) @@ -1137,7 +1193,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t // Render cel shading globally to the scene using the cel shader if the checkbox is checked. if (m_enableCelShading) { - result = m_ShaderManager->RenderCelShadingShader(m_Direct3D->GetDeviceContext(), chunk->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, chunk->GetTexture(5), + result = m_ShaderManager->RenderCelShadingShader(m_Direct3D->GetDeviceContext(), chunk->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, chunk->GetTexture(), m_Lights[0]->GetDirection(), m_Lights[0]->GetDiffuseColor(), TrueLightPosition); if (!result) { @@ -1526,6 +1582,7 @@ void ApplicationClass::GenerateTerrain() char modelFilename[128]; std::vector Filename; + bool result; XMMATRIX scaleMatrix; float scaleX, scaleY, scaleZ; @@ -1539,23 +1596,41 @@ void ApplicationClass::GenerateTerrain() // Set the file name of the model. strcpy_s(modelFilename, "plane.txt"); - Filename.push_back("stone01.tga"); - Filename.push_back("normal01.tga"); - Filename.push_back("spec02.tga"); - Filename.push_back("alpha01.tga"); - Filename.push_back("light01.tga"); - Filename.push_back("moss01.tga"); + // Liste des fichiers de texture + std::vector terrainTexture = { + L"moss01.tga", + L"normal01.tga", + L"spec02.tga", + L"alpha01.tga", + L"light01.tga" + }; + + + textures.clear(); + for (const auto& textureFilename : terrainTexture) + { + ID3D11ShaderResourceView* texture = nullptr; + result = DirectX::CreateWICTextureFromFile(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), textureFilename.c_str(), nullptr, &texture); + if (FAILED(result)) + { + Logger::Get().Log("Failed to load texture: " + std::string(textureFilename.begin(), textureFilename.end()), __FILE__, __LINE__, Logger::LogLevel::Error); + return ; + } + textures.push_back(texture); + } std::filesystem::path p(modelFilename); std::string filenameWithoutExtension = p.stem().string(); + + // for loop to generate terrain chunks for a 10x10 grid for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { Object* newTerrain = new Object(); - newTerrain->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, Filename); + newTerrain->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textures); newTerrain->SetScaleMatrix(scaleMatrix); @@ -1577,6 +1652,7 @@ void ApplicationClass::AddKobject(WCHAR* filepath) char modelFilename[128]; vector Filename; + bool result; filesystem::path p(filepath); string filename = p.stem().string(); @@ -1585,16 +1661,32 @@ void ApplicationClass::AddKobject(WCHAR* filepath) wcstombs_s(&convertedChars, modelFilename, sizeof(modelFilename), filepath, _TRUNCATE); - // Set the name of the texture file that we will be loading. - Filename.push_back("stone01.tga"); - Filename.push_back("normal01.tga"); - Filename.push_back("spec02.tga"); - Filename.push_back("alpha01.tga"); - Filename.push_back("light01.tga"); - Filename.push_back("moss01.tga"); + /// Liste des fichiers de texture + std::vector kobjTexture = { + L"moss01.tga", + L"normal01.tga", + L"spec02.tga", + L"alpha01.tga", + L"light01.tga" + }; + + + textures.clear(); + for (const auto& textureFilename : kobjTexture) + { + ID3D11ShaderResourceView* texture = nullptr; + result = DirectX::CreateWICTextureFromFile(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), textureFilename.c_str(), nullptr, &texture); + if (FAILED(result)) + { + Logger::Get().Log("Failed to load texture: " + std::string(textureFilename.begin(), textureFilename.end()), __FILE__, __LINE__, Logger::LogLevel::Error); + return; + } + textures.push_back(texture); + } + Object* newObject = new Object(); - newObject->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, Filename); + newObject->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textures); newObject->SetMass(1.0f); newObject->SetTranslateMatrix(XMMatrixTranslation(0.0f, 50.0f, 0.0f)); newObject->SetName(filename); @@ -1611,23 +1703,38 @@ void ApplicationClass::AddCube() Logger::Get().Log("Adding cube", __FILE__, __LINE__); char modelFilename[128]; - vector Filename; + bool result; // Set the file name of the model. strcpy_s(modelFilename, "cube.txt"); - // Set the name of the texture file that we will be loading. - Filename.push_back("stone01.tga"); - Filename.push_back("normal01.tga"); - Filename.push_back("spec02.tga"); - Filename.push_back("alpha01.tga"); - Filename.push_back("light01.tga"); - Filename.push_back("moss01.tga"); + // Liste des fichiers de texture + std::vector cubeTexture = { + L"moss01.tga", + L"normal01.tga", + L"spec02.tga", + L"alpha01.tga", + L"light01.tga" + }; + + + textures.clear(); + for (const auto& textureFilename : cubeTexture) + { + ID3D11ShaderResourceView* texture = nullptr; + result = DirectX::CreateWICTextureFromFile(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), textureFilename.c_str(), nullptr, &texture); + if (FAILED(result)) + { + Logger::Get().Log("Failed to load texture: " + std::string(textureFilename.begin(), textureFilename.end()), __FILE__, __LINE__, Logger::LogLevel::Error); + return; + } + textures.push_back(texture); + } static int cubeCount = 0; float position = cubeCount * 2.0f; Object* newCube = new Object(); - newCube->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, Filename); + newCube->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), modelFilename, textures); newCube->SetTranslateMatrix(XMMatrixTranslation(position, 0.0f, 0.0f)); diff --git a/enginecustom/applicationclass.h b/enginecustom/applicationclass.h index fccdea5..231607a 100644 --- a/enginecustom/applicationclass.h +++ b/enginecustom/applicationclass.h @@ -30,6 +30,8 @@ #include "reflectionshaderclass.h" #include "physics.h" +#include + ///////////// // GLOBALS // @@ -85,6 +87,8 @@ public: void SetCelShading(bool enable) { m_enableCelShading = enable; }; + std::vector textures; + private: bool Render(float, float, float, float, float); bool UpdateMouseStrings(int, int, bool); diff --git a/enginecustom/enginecustom.vcxproj b/enginecustom/enginecustom.vcxproj index 95b3754..b2bee4b 100644 --- a/enginecustom/enginecustom.vcxproj +++ b/enginecustom/enginecustom.vcxproj @@ -22,6 +22,11 @@ + + + + + @@ -70,6 +75,11 @@ + + + + + @@ -360,7 +370,7 @@ true _DEBUG;_WINDOWS;%(PreprocessorDefinitions) true - $(SolutionDir)enginecustom\include\backends;$(SolutionDir)enginecustom\include;%(AdditionalIncludeDirectories) + $(SolutionDir)enginecustom\include\backends;$(SolutionDir)enginecustom\include\Inc;$(SolutionDir)enginecustom\include;%(AdditionalIncludeDirectories) stdcpp17 @@ -377,7 +387,7 @@ NDEBUG;_WINDOWS;%(PreprocessorDefinitions) true stdcpp17 - $(SolutionDir)enginecustom\include\backends;$(SolutionDir)enginecustom\include;%(AdditionalIncludeDirectories) + $(SolutionDir)enginecustom\include\backends;$(SolutionDir)enginecustom\include\Inc;$(SolutionDir)enginecustom\include;%(AdditionalIncludeDirectories) Windows diff --git a/enginecustom/enginecustom.vcxproj.filters b/enginecustom/enginecustom.vcxproj.filters index b273a41..d6fdb80 100644 --- a/enginecustom/enginecustom.vcxproj.filters +++ b/enginecustom/enginecustom.vcxproj.filters @@ -31,6 +31,12 @@ {2978535b-193d-4876-83be-1c3c4470db62} + + {3bfbc604-3b39-4e49-bee2-b942fc5dce8c} + + + {d710c862-b37d-4ad5-aa92-2456f9745881} + @@ -174,6 +180,21 @@ Fichiers sources + + Fichiers sources\DirectX Tool Kit + + + Fichiers sources\DirectX Tool Kit + + + Fichiers sources\DirectX Tool Kit + + + Fichiers sources\DirectX Tool Kit + + + Fichiers sources\DirectX Tool Kit + @@ -323,6 +344,21 @@ Fichiers d%27en-tête + + Fichiers d%27en-tête\DirectX Tool Kit + + + Fichiers d%27en-tête\DirectX Tool Kit + + + Fichiers d%27en-tête\DirectX Tool Kit + + + Fichiers d%27en-tête\DirectX Tool Kit + + + Fichiers d%27en-tête\DirectX Tool Kit + diff --git a/enginecustom/imgui.ini b/enginecustom/imgui.ini index 45d976f..d85c6d3 100644 --- a/enginecustom/imgui.ini +++ b/enginecustom/imgui.ini @@ -3,7 +3,7 @@ Pos=60,60 Size=400,400 [Window][Khaotic Engine] -Pos=509,25 +Pos=1129,39 Size=392,273 [Window][Objects] diff --git a/enginecustom/imguiManager.cpp b/enginecustom/imguiManager.cpp index 002e579..e9581b5 100644 --- a/enginecustom/imguiManager.cpp +++ b/enginecustom/imguiManager.cpp @@ -167,7 +167,7 @@ void imguiManager::WidgetObjectWindow(ApplicationClass* app) for (int count = 0; count < 6; count++) { std::string textureLabel = "Texture##" + std::to_string(index); - ID3D11ShaderResourceView* texture = object->GetTexture(count); + ID3D11ShaderResourceView* texture = object->GetTexture(); if (texture != nullptr) { // Set the cursor position @@ -188,7 +188,7 @@ void imguiManager::WidgetObjectWindow(ApplicationClass* app) for (int count = 0; count < 6; count++) { std::string textureLabel = "Texture##" + std::to_string(index); - ID3D11ShaderResourceView* texture = object->GetTexture(count); + ID3D11ShaderResourceView* texture = object->GetTexture(); if (texture != nullptr) { // Set the cursor position diff --git a/enginecustom/include/Inc/Audio.h b/enginecustom/include/Inc/Audio.h new file mode 100644 index 0000000..2877bca --- /dev/null +++ b/enginecustom/include/Inc/Audio.h @@ -0,0 +1,832 @@ +//-------------------------------------------------------------------------------------- +// File: Audio.h +// +// DirectXTK for Audio header +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +// http://go.microsoft.com/fwlink/?LinkID=615561 +//-------------------------------------------------------------------------------------- + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX) +#include +#ifdef _MSC_VER +#pragma comment(lib,"acphal.lib") +#endif +#endif + +#ifndef XAUDIO2_HELPER_FUNCTIONS +#define XAUDIO2_HELPER_FUNCTIONS +#endif + +#if defined(USING_XAUDIO2_REDIST) || (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/) || defined(_XBOX_ONE) +#define USING_XAUDIO2_9 +#elif (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) +#define USING_XAUDIO2_8 +#elif (_WIN32_WINNT >= 0x0601 /*_WIN32_WINNT_WIN7*/) +#error Windows 7 SP1 requires the XAudio2Redist NuGet package https://aka.ms/xaudio2redist +#else +#error DirectX Tool Kit for Audio not supported on this platform +#endif + +#include +#include + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4619 4616 5246) +#endif +#include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include + +#if !defined(USING_XAUDIO2_REDIST) && defined(_MSC_VER) +#if defined(USING_XAUDIO2_8) && defined(NTDDI_WIN10) && !defined(_M_IX86) +// The xaudio2_8.lib in the Windows 10 SDK for x86 is incorrectly annotated as __cdecl instead of __stdcall, so avoid using it in this case. +#pragma comment(lib,"xaudio2_8.lib") +#else +#pragma comment(lib,"xaudio2.lib") +#endif +#endif + +#include + + +namespace DirectX +{ + class SoundEffectInstance; + class SoundStreamInstance; + + //---------------------------------------------------------------------------------- + struct AudioStatistics + { + size_t playingOneShots; // Number of one-shot sounds currently playing + size_t playingInstances; // Number of sound effect instances currently playing + size_t allocatedInstances; // Number of SoundEffectInstance allocated + size_t allocatedVoices; // Number of XAudio2 voices allocated (standard, 3D, one-shots, and idle one-shots) + size_t allocatedVoices3d; // Number of XAudio2 voices allocated for 3D + size_t allocatedVoicesOneShot; // Number of XAudio2 voices allocated for one-shot sounds + size_t allocatedVoicesIdle; // Number of XAudio2 voices allocated for one-shot sounds but not currently in use + size_t audioBytes; // Total wave data (in bytes) in SoundEffects and in-memory WaveBanks + #if (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX) + size_t xmaAudioBytes; // Total wave data (in bytes) in SoundEffects and in-memory WaveBanks allocated with ApuAlloc + #endif + size_t streamingBytes; // Total size of streaming buffers (in bytes) in streaming WaveBanks + }; + + + //---------------------------------------------------------------------------------- + class IVoiceNotify + { + public: + virtual ~IVoiceNotify() = default; + + IVoiceNotify(const IVoiceNotify&) = delete; + IVoiceNotify& operator=(const IVoiceNotify&) = delete; + + IVoiceNotify(IVoiceNotify&&) = default; + IVoiceNotify& operator=(IVoiceNotify&&) = default; + + virtual void __cdecl OnBufferEnd() = 0; + // Notfication that a voice buffer has finished + // Note this is called from XAudio2's worker thread, so it should perform very minimal and thread-safe operations + + virtual void __cdecl OnCriticalError() = 0; + // Notification that the audio engine encountered a critical error + + virtual void __cdecl OnReset() = 0; + // Notification of an audio engine reset + + virtual void __cdecl OnUpdate() = 0; + // Notification of an audio engine per-frame update (opt-in) + + virtual void __cdecl OnDestroyEngine() noexcept = 0; + // Notification that the audio engine is being destroyed + + virtual void __cdecl OnTrim() = 0; + // Notification of a request to trim the voice pool + + virtual void __cdecl GatherStatistics(AudioStatistics& stats) const = 0; + // Contribute to statistics request + + virtual void __cdecl OnDestroyParent() noexcept = 0; + // Optional notification used by some objects + + protected: + IVoiceNotify() = default; + }; + + //---------------------------------------------------------------------------------- + enum AUDIO_ENGINE_FLAGS : uint32_t + { + AudioEngine_Default = 0x0, + + AudioEngine_EnvironmentalReverb = 0x1, + AudioEngine_ReverbUseFilters = 0x2, + AudioEngine_UseMasteringLimiter = 0x4, + + AudioEngine_Debug = 0x10000, + AudioEngine_ThrowOnNoAudioHW = 0x20000, + AudioEngine_DisableVoiceReuse = 0x40000, + }; + + enum SOUND_EFFECT_INSTANCE_FLAGS : uint32_t + { + SoundEffectInstance_Default = 0x0, + + SoundEffectInstance_Use3D = 0x1, + SoundEffectInstance_ReverbUseFilters = 0x2, + SoundEffectInstance_NoSetPitch = 0x4, + + SoundEffectInstance_UseRedirectLFE = 0x10000, + }; + + enum AUDIO_ENGINE_REVERB : unsigned int + { + Reverb_Off, + Reverb_Default, + Reverb_Generic, + Reverb_Forest, + Reverb_PaddedCell, + Reverb_Room, + Reverb_Bathroom, + Reverb_LivingRoom, + Reverb_StoneRoom, + Reverb_Auditorium, + Reverb_ConcertHall, + Reverb_Cave, + Reverb_Arena, + Reverb_Hangar, + Reverb_CarpetedHallway, + Reverb_Hallway, + Reverb_StoneCorridor, + Reverb_Alley, + Reverb_City, + Reverb_Mountains, + Reverb_Quarry, + Reverb_Plain, + Reverb_ParkingLot, + Reverb_SewerPipe, + Reverb_Underwater, + Reverb_SmallRoom, + Reverb_MediumRoom, + Reverb_LargeRoom, + Reverb_MediumHall, + Reverb_LargeHall, + Reverb_Plate, + Reverb_MAX + }; + + enum SoundState + { + STOPPED = 0, + PLAYING, + PAUSED + }; + + + //---------------------------------------------------------------------------------- + class AudioEngine + { + public: + explicit AudioEngine( + AUDIO_ENGINE_FLAGS flags = AudioEngine_Default, + _In_opt_ const WAVEFORMATEX* wfx = nullptr, + _In_opt_z_ const wchar_t* deviceId = nullptr, + AUDIO_STREAM_CATEGORY category = AudioCategory_GameEffects) noexcept(false); + + AudioEngine(AudioEngine&&) noexcept; + AudioEngine& operator= (AudioEngine&&) noexcept; + + AudioEngine(AudioEngine const&) = delete; + AudioEngine& operator= (AudioEngine const&) = delete; + + virtual ~AudioEngine(); + + bool __cdecl Update(); + // Performs per-frame processing for the audio engine, returns false if in 'silent mode' + + bool __cdecl Reset(_In_opt_ const WAVEFORMATEX* wfx = nullptr, _In_opt_z_ const wchar_t* deviceId = nullptr); + // Reset audio engine from critical error/silent mode using a new device; can also 'migrate' the graph + // Returns true if succesfully reset, false if in 'silent mode' due to no default device + // Note: One shots are lost, all SoundEffectInstances are in the STOPPED state after successful reset + + void __cdecl Suspend() noexcept; + void __cdecl Resume(); + // Suspend/resumes audio processing (i.e. global pause/resume) + + float __cdecl GetMasterVolume() const noexcept; + void __cdecl SetMasterVolume(float volume); + // Master volume property for all sounds + + void __cdecl SetReverb(AUDIO_ENGINE_REVERB reverb); + void __cdecl SetReverb(_In_opt_ const XAUDIO2FX_REVERB_PARAMETERS* native); + // Sets environmental reverb for 3D positional audio (if active) + + void __cdecl SetMasteringLimit(int release, int loudness); + // Sets the mastering volume limiter properties (if active) + + AudioStatistics __cdecl GetStatistics() const; + // Gathers audio engine statistics + + WAVEFORMATEXTENSIBLE __cdecl GetOutputFormat() const noexcept; + // Returns the format of the audio output device associated with the mastering voice. + + uint32_t __cdecl GetChannelMask() const noexcept; + // Returns the output channel mask + + int __cdecl GetOutputSampleRate() const noexcept; + // Returns the sample rate going into the mastering voice + + unsigned int __cdecl GetOutputChannels() const noexcept; + // Returns the number of channels going into the mastering voice + + bool __cdecl IsAudioDevicePresent() const noexcept; + // Returns true if the audio graph is operating normally, false if in 'silent mode' + + bool __cdecl IsCriticalError() const noexcept; + // Returns true if the audio graph is halted due to a critical error (which also places the engine into 'silent mode') + + // Voice pool management. + void __cdecl SetDefaultSampleRate(int sampleRate); + // Sample rate for voices in the reuse pool (defaults to 44100) + + void __cdecl SetMaxVoicePool(size_t maxOneShots, size_t maxInstances); + // Maximum number of voices to allocate for one-shots and instances + // Note: one-shots over this limit are ignored; too many instance voices throws an exception + + void __cdecl TrimVoicePool(); + // Releases any currently unused voices + + // Internal-use functions + void __cdecl AllocateVoice(_In_ const WAVEFORMATEX* wfx, + SOUND_EFFECT_INSTANCE_FLAGS flags, bool oneshot, _Outptr_result_maybenull_ IXAudio2SourceVoice** voice); + + void __cdecl DestroyVoice(_In_ IXAudio2SourceVoice* voice) noexcept; + // Should only be called for instance voices, not one-shots + + void __cdecl RegisterNotify(_In_ IVoiceNotify* notify, bool usesUpdate); + void __cdecl UnregisterNotify(_In_ IVoiceNotify* notify, bool usesOneShots, bool usesUpdate); + + // XAudio2 interface access + IXAudio2* __cdecl GetInterface() const noexcept; + IXAudio2MasteringVoice* __cdecl GetMasterVoice() const noexcept; + IXAudio2SubmixVoice* __cdecl GetReverbVoice() const noexcept; + X3DAUDIO_HANDLE& __cdecl Get3DHandle() const noexcept; + + // Static functions + struct RendererDetail + { + std::wstring deviceId; + std::wstring description; + }; + + static std::vector __cdecl GetRendererDetails(); + // Returns a list of valid audio endpoint devices + +#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED) + explicit AudioEngine( + AUDIO_ENGINE_FLAGS flags = AudioEngine_Default, + _In_opt_ const WAVEFORMATEX* wfx = nullptr, + _In_opt_z_ const __wchar_t* deviceId = nullptr, + AUDIO_STREAM_CATEGORY category = AudioCategory_GameEffects) noexcept(false); + + bool __cdecl Reset(_In_opt_ const WAVEFORMATEX* wfx = nullptr, _In_opt_z_ const __wchar_t* deviceId = nullptr); +#endif + + private: + // Private implementation. + class Impl; + std::unique_ptr pImpl; + }; + + + //---------------------------------------------------------------------------------- + class WaveBank + { + public: + WaveBank(_In_ AudioEngine* engine, _In_z_ const wchar_t* wbFileName); + + WaveBank(WaveBank&&) noexcept; + WaveBank& operator= (WaveBank&&) noexcept; + + WaveBank(WaveBank const&) = delete; + WaveBank& operator= (WaveBank const&) = delete; + + virtual ~WaveBank(); + + void __cdecl Play(unsigned int index); + void __cdecl Play(unsigned int index, float volume, float pitch, float pan); + + void __cdecl Play(_In_z_ const char* name); + void __cdecl Play(_In_z_ const char* name, float volume, float pitch, float pan); + + std::unique_ptr __cdecl CreateInstance(unsigned int index, + SOUND_EFFECT_INSTANCE_FLAGS flags = SoundEffectInstance_Default); + std::unique_ptr __cdecl CreateInstance(_In_z_ const char* name, + SOUND_EFFECT_INSTANCE_FLAGS flags = SoundEffectInstance_Default); + + std::unique_ptr __cdecl CreateStreamInstance(unsigned int index, + SOUND_EFFECT_INSTANCE_FLAGS flags = SoundEffectInstance_Default); + std::unique_ptr __cdecl CreateStreamInstance(_In_z_ const char* name, + SOUND_EFFECT_INSTANCE_FLAGS flags = SoundEffectInstance_Default); + + bool __cdecl IsPrepared() const noexcept; + bool __cdecl IsInUse() const noexcept; + bool __cdecl IsStreamingBank() const noexcept; + bool __cdecl IsAdvancedFormat() const noexcept; + + size_t __cdecl GetSampleSizeInBytes(unsigned int index) const noexcept; + // Returns size of wave audio data + + size_t __cdecl GetSampleDuration(unsigned int index) const noexcept; + // Returns the duration in samples + + size_t __cdecl GetSampleDurationMS(unsigned int index) const noexcept; + // Returns the duration in milliseconds + + const WAVEFORMATEX* __cdecl GetFormat(unsigned int index, _Out_writes_bytes_(maxsize) WAVEFORMATEX* wfx, size_t maxsize) const noexcept; + + int __cdecl Find(_In_z_ const char* name) const; + + #ifdef USING_XAUDIO2_9 + bool __cdecl FillSubmitBuffer(unsigned int index, _Out_ XAUDIO2_BUFFER& buffer, _Out_ XAUDIO2_BUFFER_WMA& wmaBuffer) const; + #else + void __cdecl FillSubmitBuffer(unsigned int index, _Out_ XAUDIO2_BUFFER& buffer) const; + #endif + + void __cdecl UnregisterInstance(_In_ IVoiceNotify* instance); + + HANDLE __cdecl GetAsyncHandle() const noexcept; + + bool __cdecl GetPrivateData(unsigned int index, _Out_writes_bytes_(datasize) void* data, size_t datasize); + +#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED) + WaveBank(_In_ AudioEngine* engine, _In_z_ const __wchar_t* wbFileName); +#endif + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; + + + //---------------------------------------------------------------------------------- + class SoundEffect + { + public: + SoundEffect(_In_ AudioEngine* engine, _In_z_ const wchar_t* waveFileName); + + SoundEffect(_In_ AudioEngine* engine, _Inout_ std::unique_ptr& wavData, + _In_ const WAVEFORMATEX* wfx, _In_reads_bytes_(audioBytes) const uint8_t* startAudio, size_t audioBytes); + + SoundEffect(_In_ AudioEngine* engine, _Inout_ std::unique_ptr& wavData, + _In_ const WAVEFORMATEX* wfx, _In_reads_bytes_(audioBytes) const uint8_t* startAudio, size_t audioBytes, + uint32_t loopStart, uint32_t loopLength); + + #ifdef USING_XAUDIO2_9 + + SoundEffect(_In_ AudioEngine* engine, _Inout_ std::unique_ptr& wavData, + _In_ const WAVEFORMATEX* wfx, _In_reads_bytes_(audioBytes) const uint8_t* startAudio, size_t audioBytes, + _In_reads_(seekCount) const uint32_t* seekTable, size_t seekCount); + + #endif + + SoundEffect(SoundEffect&&) noexcept; + SoundEffect& operator= (SoundEffect&&) noexcept; + + SoundEffect(SoundEffect const&) = delete; + SoundEffect& operator= (SoundEffect const&) = delete; + + virtual ~SoundEffect(); + + void __cdecl Play(); + void __cdecl Play(float volume, float pitch, float pan); + + std::unique_ptr __cdecl CreateInstance(SOUND_EFFECT_INSTANCE_FLAGS flags = SoundEffectInstance_Default); + + bool __cdecl IsInUse() const noexcept; + + size_t __cdecl GetSampleSizeInBytes() const noexcept; + // Returns size of wave audio data + + size_t __cdecl GetSampleDuration() const noexcept; + // Returns the duration in samples + + size_t __cdecl GetSampleDurationMS() const noexcept; + // Returns the duration in milliseconds + + const WAVEFORMATEX* __cdecl GetFormat() const noexcept; + + #ifdef USING_XAUDIO2_9 + bool __cdecl FillSubmitBuffer(_Out_ XAUDIO2_BUFFER& buffer, _Out_ XAUDIO2_BUFFER_WMA& wmaBuffer) const; + #else + void __cdecl FillSubmitBuffer(_Out_ XAUDIO2_BUFFER& buffer) const; + #endif + + void __cdecl UnregisterInstance(_In_ IVoiceNotify* instance); + +#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED) + SoundEffect(_In_ AudioEngine* engine, _In_z_ const __wchar_t* waveFileName); +#endif + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; + + + //---------------------------------------------------------------------------------- + struct AudioListener : public X3DAUDIO_LISTENER + { + X3DAUDIO_CONE ListenerCone; + + AudioListener() noexcept : + X3DAUDIO_LISTENER{}, + ListenerCone{} + { + OrientFront.z = -1.f; + + OrientTop.y = 1.f; + } + + void XM_CALLCONV SetPosition(FXMVECTOR v) noexcept + { + XMStoreFloat3(reinterpret_cast(&Position), v); + } + void __cdecl SetPosition(const XMFLOAT3& pos) noexcept + { + Position.x = pos.x; + Position.y = pos.y; + Position.z = pos.z; + } + + void XM_CALLCONV SetVelocity(FXMVECTOR v) noexcept + { + XMStoreFloat3(reinterpret_cast(&Velocity), v); + } + void __cdecl SetVelocity(const XMFLOAT3& vel) noexcept + { + Velocity.x = vel.x; + Velocity.y = vel.y; + Velocity.z = vel.z; + } + + void XM_CALLCONV SetOrientation(FXMVECTOR forward, FXMVECTOR up) noexcept + { + XMStoreFloat3(reinterpret_cast(&OrientFront), forward); + XMStoreFloat3(reinterpret_cast(&OrientTop), up); + } + void __cdecl SetOrientation(const XMFLOAT3& forward, const XMFLOAT3& up) noexcept + { + OrientFront.x = forward.x; OrientTop.x = up.x; + OrientFront.y = forward.y; OrientTop.y = up.y; + OrientFront.z = forward.z; OrientTop.z = up.z; + } + + void XM_CALLCONV SetOrientationFromQuaternion(FXMVECTOR quat) noexcept + { + const XMVECTOR forward = XMVector3Rotate(g_XMIdentityR2, quat); + XMStoreFloat3(reinterpret_cast(&OrientFront), forward); + + const XMVECTOR up = XMVector3Rotate(g_XMIdentityR1, quat); + XMStoreFloat3(reinterpret_cast(&OrientTop), up); + } + + // Updates velocity and orientation by tracking changes in position over time. + void XM_CALLCONV Update(FXMVECTOR newPos, XMVECTOR upDir, float dt) noexcept + { + if (dt > 0.f) + { + const XMVECTOR lastPos = XMLoadFloat3(reinterpret_cast(&Position)); + + XMVECTOR vDelta = XMVectorSubtract(newPos, lastPos); + const XMVECTOR vt = XMVectorReplicate(dt); + XMVECTOR v = XMVectorDivide(vDelta, vt); + XMStoreFloat3(reinterpret_cast(&Velocity), v); + + vDelta = XMVector3Normalize(vDelta); + XMStoreFloat3(reinterpret_cast(&OrientFront), vDelta); + + v = XMVector3Cross(upDir, vDelta); + v = XMVector3Normalize(v); + + v = XMVector3Cross(vDelta, v); + v = XMVector3Normalize(v); + XMStoreFloat3(reinterpret_cast(&OrientTop), v); + + XMStoreFloat3(reinterpret_cast(&Position), newPos); + } + } + + void __cdecl SetOmnidirectional() noexcept + { + pCone = nullptr; + } + + void __cdecl SetCone(const X3DAUDIO_CONE& listenerCone); + + bool __cdecl IsValid() const; + }; + + + //---------------------------------------------------------------------------------- + struct AudioEmitter : public X3DAUDIO_EMITTER + { + X3DAUDIO_CONE EmitterCone; + float EmitterAzimuths[XAUDIO2_MAX_AUDIO_CHANNELS]; + + AudioEmitter() noexcept : + X3DAUDIO_EMITTER{}, + EmitterCone{}, + EmitterAzimuths{} + { + OrientFront.z = -1.f; + + OrientTop.y = + ChannelRadius = + CurveDistanceScaler = + DopplerScaler = 1.f; + + ChannelCount = 1; + pChannelAzimuths = EmitterAzimuths; + + InnerRadiusAngle = X3DAUDIO_PI / 4.0f; + } + + void XM_CALLCONV SetPosition(FXMVECTOR v) noexcept + { + XMStoreFloat3(reinterpret_cast(&Position), v); + } + void __cdecl SetPosition(const XMFLOAT3& pos) noexcept + { + Position.x = pos.x; + Position.y = pos.y; + Position.z = pos.z; + } + + void XM_CALLCONV SetVelocity(FXMVECTOR v) noexcept + { + XMStoreFloat3(reinterpret_cast(&Velocity), v); + } + void __cdecl SetVelocity(const XMFLOAT3& vel) noexcept + { + Velocity.x = vel.x; + Velocity.y = vel.y; + Velocity.z = vel.z; + } + + void XM_CALLCONV SetOrientation(FXMVECTOR forward, FXMVECTOR up) noexcept + { + XMStoreFloat3(reinterpret_cast(&OrientFront), forward); + XMStoreFloat3(reinterpret_cast(&OrientTop), up); + } + void __cdecl SetOrientation(const XMFLOAT3& forward, const XMFLOAT3& up) noexcept + { + OrientFront.x = forward.x; OrientTop.x = up.x; + OrientFront.y = forward.y; OrientTop.y = up.y; + OrientFront.z = forward.z; OrientTop.z = up.z; + } + + void XM_CALLCONV SetOrientationFromQuaternion(FXMVECTOR quat) noexcept + { + const XMVECTOR forward = XMVector3Rotate(g_XMIdentityR2, quat); + XMStoreFloat3(reinterpret_cast(&OrientFront), forward); + + const XMVECTOR up = XMVector3Rotate(g_XMIdentityR1, quat); + XMStoreFloat3(reinterpret_cast(&OrientTop), up); + } + + // Updates velocity and orientation by tracking changes in position over time. + void XM_CALLCONV Update(FXMVECTOR newPos, XMVECTOR upDir, float dt) noexcept + { + if (dt > 0.f) + { + const XMVECTOR lastPos = XMLoadFloat3(reinterpret_cast(&Position)); + + XMVECTOR vDelta = XMVectorSubtract(newPos, lastPos); + const XMVECTOR vt = XMVectorReplicate(dt); + XMVECTOR v = XMVectorDivide(vDelta, vt); + XMStoreFloat3(reinterpret_cast(&Velocity), v); + + vDelta = XMVector3Normalize(vDelta); + XMStoreFloat3(reinterpret_cast(&OrientFront), vDelta); + + v = XMVector3Cross(upDir, vDelta); + v = XMVector3Normalize(v); + + v = XMVector3Cross(vDelta, v); + v = XMVector3Normalize(v); + XMStoreFloat3(reinterpret_cast(&OrientTop), v); + + XMStoreFloat3(reinterpret_cast(&Position), newPos); + } + } + + void __cdecl SetOmnidirectional() noexcept + { + pCone = nullptr; + } + + // Only used for single-channel emitters. + void __cdecl SetCone(const X3DAUDIO_CONE& emitterCone); + + // Set multi-channel emitter azimuths based on speaker configuration geometry. + void __cdecl EnableDefaultMultiChannel(unsigned int channels, float radius = 1.f); + + // Set default volume, LFE, LPF, and reverb curves. + void __cdecl EnableDefaultCurves() noexcept; + void __cdecl EnableLinearCurves() noexcept; + + void __cdecl EnableInverseSquareCurves() noexcept + { + pVolumeCurve = nullptr; + pLFECurve = nullptr; + pLPFDirectCurve = nullptr; + pLPFReverbCurve = nullptr; + pReverbCurve = nullptr; + } + + bool __cdecl IsValid() const; + }; + + + //---------------------------------------------------------------------------------- + class SoundEffectInstance + { + public: + SoundEffectInstance(SoundEffectInstance&&) noexcept; + SoundEffectInstance& operator= (SoundEffectInstance&&) noexcept; + + SoundEffectInstance(SoundEffectInstance const&) = delete; + SoundEffectInstance& operator= (SoundEffectInstance const&) = delete; + + virtual ~SoundEffectInstance(); + + void __cdecl Play(bool loop = false); + void __cdecl Stop(bool immediate = true) noexcept; + void __cdecl Pause() noexcept; + void __cdecl Resume(); + + void __cdecl SetVolume(float volume); + void __cdecl SetPitch(float pitch); + void __cdecl SetPan(float pan); + + void __cdecl Apply3D(const X3DAUDIO_LISTENER& listener, const X3DAUDIO_EMITTER& emitter, bool rhcoords = true); + + bool __cdecl IsLooped() const noexcept; + + SoundState __cdecl GetState() noexcept; + + unsigned int __cdecl GetChannelCount() const noexcept; + + IVoiceNotify* __cdecl GetVoiceNotify() const noexcept; + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + + // Private constructors + SoundEffectInstance(_In_ AudioEngine* engine, _In_ SoundEffect* effect, SOUND_EFFECT_INSTANCE_FLAGS flags); + SoundEffectInstance(_In_ AudioEngine* engine, _In_ WaveBank* effect, unsigned int index, SOUND_EFFECT_INSTANCE_FLAGS flags); + + friend std::unique_ptr __cdecl SoundEffect::CreateInstance(SOUND_EFFECT_INSTANCE_FLAGS); + friend std::unique_ptr __cdecl WaveBank::CreateInstance(unsigned int, SOUND_EFFECT_INSTANCE_FLAGS); + }; + + + //---------------------------------------------------------------------------------- + class SoundStreamInstance + { + public: + SoundStreamInstance(SoundStreamInstance&&) noexcept; + SoundStreamInstance& operator= (SoundStreamInstance&&) noexcept; + + SoundStreamInstance(SoundStreamInstance const&) = delete; + SoundStreamInstance& operator= (SoundStreamInstance const&) = delete; + + virtual ~SoundStreamInstance(); + + void __cdecl Play(bool loop = false); + void __cdecl Stop(bool immediate = true) noexcept; + void __cdecl Pause() noexcept; + void __cdecl Resume(); + + void __cdecl SetVolume(float volume); + void __cdecl SetPitch(float pitch); + void __cdecl SetPan(float pan); + + void __cdecl Apply3D(const X3DAUDIO_LISTENER& listener, const X3DAUDIO_EMITTER& emitter, bool rhcoords = true); + + bool __cdecl IsLooped() const noexcept; + + SoundState __cdecl GetState() noexcept; + + unsigned int __cdecl GetChannelCount() const noexcept; + + IVoiceNotify* __cdecl GetVoiceNotify() const noexcept; + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + + // Private constructors + SoundStreamInstance(_In_ AudioEngine* engine, _In_ WaveBank* effect, unsigned int index, SOUND_EFFECT_INSTANCE_FLAGS flags); + + friend std::unique_ptr __cdecl WaveBank::CreateStreamInstance(unsigned int, SOUND_EFFECT_INSTANCE_FLAGS); + }; + + + //---------------------------------------------------------------------------------- + class DynamicSoundEffectInstance + { + public: + DynamicSoundEffectInstance(_In_ AudioEngine* engine, + _In_ std::function bufferNeeded, + int sampleRate, int channels, int sampleBits = 16, + SOUND_EFFECT_INSTANCE_FLAGS flags = SoundEffectInstance_Default); + + DynamicSoundEffectInstance(DynamicSoundEffectInstance&&) noexcept; + DynamicSoundEffectInstance& operator= (DynamicSoundEffectInstance&&) noexcept; + + DynamicSoundEffectInstance(DynamicSoundEffectInstance const&) = delete; + DynamicSoundEffectInstance& operator= (DynamicSoundEffectInstance const&) = delete; + + virtual ~DynamicSoundEffectInstance(); + + void __cdecl Play(); + void __cdecl Stop(bool immediate = true) noexcept; + void __cdecl Pause() noexcept; + void __cdecl Resume(); + + void __cdecl SetVolume(float volume); + void __cdecl SetPitch(float pitch); + void __cdecl SetPan(float pan); + + void __cdecl Apply3D(const X3DAUDIO_LISTENER& listener, const X3DAUDIO_EMITTER& emitter, bool rhcoords = true); + + void __cdecl SubmitBuffer(_In_reads_bytes_(audioBytes) const uint8_t* pAudioData, size_t audioBytes); + void __cdecl SubmitBuffer(_In_reads_bytes_(audioBytes) const uint8_t* pAudioData, uint32_t offset, size_t audioBytes); + + SoundState __cdecl GetState() noexcept; + + size_t __cdecl GetSampleDuration(size_t bytes) const noexcept; + // Returns duration in samples of a buffer of a given size + + size_t __cdecl GetSampleDurationMS(size_t bytes) const noexcept; + // Returns duration in milliseconds of a buffer of a given size + + size_t __cdecl GetSampleSizeInBytes(uint64_t duration) const noexcept; + // Returns size of a buffer for a duration given in milliseconds + + int __cdecl GetPendingBufferCount() const noexcept; + + const WAVEFORMATEX* __cdecl GetFormat() const noexcept; + + unsigned int __cdecl GetChannelCount() const noexcept; + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-dynamic-exception-spec" +#endif + + DEFINE_ENUM_FLAG_OPERATORS(AUDIO_ENGINE_FLAGS); + DEFINE_ENUM_FLAG_OPERATORS(SOUND_EFFECT_INSTANCE_FLAGS); + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +} diff --git a/enginecustom/include/Inc/BufferHelpers.h b/enginecustom/include/Inc/BufferHelpers.h new file mode 100644 index 0000000..a78f620 --- /dev/null +++ b/enginecustom/include/Inc/BufferHelpers.h @@ -0,0 +1,164 @@ +//-------------------------------------------------------------------------------------- +// File: BufferHelpers.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#include +#include + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#include "GraphicsMemory.h" +#else +#include +#endif + +#include + + +namespace DirectX +{ + // Helpers for creating initialized Direct3D buffer resources. + HRESULT __cdecl CreateStaticBuffer(_In_ ID3D11Device* device, + _In_reads_bytes_(count* stride) const void* ptr, + size_t count, + size_t stride, + unsigned int bindFlags, + _COM_Outptr_ ID3D11Buffer** pBuffer) noexcept; + + template + HRESULT CreateStaticBuffer(_In_ ID3D11Device* device, + _In_reads_(count) T const* data, + size_t count, + unsigned int bindFlags, + _COM_Outptr_ ID3D11Buffer** pBuffer) noexcept + { + return CreateStaticBuffer(device, data, count, sizeof(T), bindFlags, pBuffer); + } + + template + HRESULT CreateStaticBuffer(_In_ ID3D11Device* device, + T const& data, + unsigned int bindFlags, + _COM_Outptr_ ID3D11Buffer** pBuffer) noexcept + { + return CreateStaticBuffer(device, data.data(), data.size(), sizeof(typename T::value_type), bindFlags, pBuffer); + } + + // Helpers for creating texture from memory arrays. + HRESULT __cdecl CreateTextureFromMemory(_In_ ID3D11Device* device, + size_t width, + DXGI_FORMAT format, + const D3D11_SUBRESOURCE_DATA& initData, + _COM_Outptr_opt_ ID3D11Texture1D** texture, + _COM_Outptr_opt_ ID3D11ShaderResourceView** textureView, + unsigned int bindFlags = D3D11_BIND_SHADER_RESOURCE) noexcept; + + HRESULT __cdecl CreateTextureFromMemory(_In_ ID3D11Device* device, + size_t width, size_t height, + DXGI_FORMAT format, + const D3D11_SUBRESOURCE_DATA& initData, + _COM_Outptr_opt_ ID3D11Texture2D** texture, + _COM_Outptr_opt_ ID3D11ShaderResourceView** textureView, + unsigned int bindFlags = D3D11_BIND_SHADER_RESOURCE) noexcept; + + HRESULT __cdecl CreateTextureFromMemory( + #if defined(_XBOX_ONE) && defined(_TITLE) + _In_ ID3D11DeviceX* d3dDeviceX, + _In_ ID3D11DeviceContextX* d3dContextX, + #else + _In_ ID3D11Device* device, + _In_ ID3D11DeviceContext* d3dContext, + #endif + size_t width, size_t height, + DXGI_FORMAT format, + const D3D11_SUBRESOURCE_DATA& initData, + _COM_Outptr_opt_ ID3D11Texture2D** texture, + _COM_Outptr_opt_ ID3D11ShaderResourceView** textureView) noexcept; + + HRESULT __cdecl CreateTextureFromMemory(_In_ ID3D11Device* device, + size_t width, size_t height, size_t depth, + DXGI_FORMAT format, + const D3D11_SUBRESOURCE_DATA& initData, + _COM_Outptr_opt_ ID3D11Texture3D** texture, + _COM_Outptr_opt_ ID3D11ShaderResourceView** textureView, + unsigned int bindFlags = D3D11_BIND_SHADER_RESOURCE) noexcept; + + // Strongly typed wrapper around a Direct3D constant buffer. + inline namespace DX11 + { + namespace Private + { + // Base class, not to be used directly: clients should access this via the derived PrimitiveBatch. + class ConstantBufferBase + { + protected: + void __cdecl CreateBuffer(_In_ ID3D11Device* device, size_t bytes, _Outptr_ ID3D11Buffer** pBuffer); + }; + } + } + + template + class ConstantBuffer : public DX11::Private::ConstantBufferBase + { + public: + // Constructor. + ConstantBuffer() = default; + explicit ConstantBuffer(_In_ ID3D11Device* device) noexcept(false) + { + CreateBuffer(device, sizeof(T), mConstantBuffer.GetAddressOf()); + } + + ConstantBuffer(ConstantBuffer&&) = default; + ConstantBuffer& operator= (ConstantBuffer&&) = default; + + ConstantBuffer(ConstantBuffer const&) = delete; + ConstantBuffer& operator= (ConstantBuffer const&) = delete; + + void Create(_In_ ID3D11Device* device) + { + CreateBuffer(device, sizeof(T), mConstantBuffer.ReleaseAndGetAddressOf()); + } + + // Writes new data into the constant buffer. + #if defined(_XBOX_ONE) && defined(_TITLE) + void __cdecl SetData(_In_ ID3D11DeviceContext* deviceContext, T const& value, void** grfxMemory) + { + assert(grfxMemory != nullptr); + + void* ptr = GraphicsMemory::Get().Allocate(deviceContext, sizeof(T), 64); + assert(ptr != nullptr); + + *(T*)ptr = value; + + *grfxMemory = ptr; + } + #else + + void __cdecl SetData(_In_ ID3D11DeviceContext* deviceContext, T const& value) noexcept + { + assert(mConstantBuffer); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + if (SUCCEEDED(deviceContext->Map(mConstantBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource))) + { + *static_cast(mappedResource.pData) = value; + + deviceContext->Unmap(mConstantBuffer.Get(), 0); + } + } + #endif // _XBOX_ONE && _TITLE + + // Looks up the underlying D3D constant buffer. + ID3D11Buffer* GetBuffer() const noexcept { return mConstantBuffer.Get(); } + + private: + Microsoft::WRL::ComPtr mConstantBuffer; + }; +} diff --git a/enginecustom/include/Inc/CommonStates.h b/enginecustom/include/Inc/CommonStates.h new file mode 100644 index 0000000..fab2ddf --- /dev/null +++ b/enginecustom/include/Inc/CommonStates.h @@ -0,0 +1,72 @@ +//-------------------------------------------------------------------------------------- +// File: CommonStates.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +#include + + +namespace DirectX +{ + inline namespace DX11 + { + class CommonStates + { + public: + explicit CommonStates(_In_ ID3D11Device* device); + + CommonStates(CommonStates&&) noexcept; + CommonStates& operator= (CommonStates&&) noexcept; + + CommonStates(CommonStates const&) = delete; + CommonStates& operator= (CommonStates const&) = delete; + + virtual ~CommonStates(); + + // Blend states. + ID3D11BlendState* __cdecl Opaque() const; + ID3D11BlendState* __cdecl AlphaBlend() const; + ID3D11BlendState* __cdecl Additive() const; + ID3D11BlendState* __cdecl NonPremultiplied() const; + + // Depth stencil states. + ID3D11DepthStencilState* __cdecl DepthNone() const; + ID3D11DepthStencilState* __cdecl DepthDefault() const; + ID3D11DepthStencilState* __cdecl DepthRead() const; + ID3D11DepthStencilState* __cdecl DepthReverseZ() const; + ID3D11DepthStencilState* __cdecl DepthReadReverseZ() const; + + // Rasterizer states. + ID3D11RasterizerState* __cdecl CullNone() const; + ID3D11RasterizerState* __cdecl CullClockwise() const; + ID3D11RasterizerState* __cdecl CullCounterClockwise() const; + ID3D11RasterizerState* __cdecl Wireframe() const; + + // Sampler states. + ID3D11SamplerState* __cdecl PointWrap() const; + ID3D11SamplerState* __cdecl PointClamp() const; + ID3D11SamplerState* __cdecl LinearWrap() const; + ID3D11SamplerState* __cdecl LinearClamp() const; + ID3D11SamplerState* __cdecl AnisotropicWrap() const; + ID3D11SamplerState* __cdecl AnisotropicClamp() const; + + private: + // Private implementation. + class Impl; + + std::shared_ptr pImpl; + }; + } +} diff --git a/enginecustom/include/Inc/DDSTextureLoader.h b/enginecustom/include/Inc/DDSTextureLoader.h new file mode 100644 index 0000000..5e0f941 --- /dev/null +++ b/enginecustom/include/Inc/DDSTextureLoader.h @@ -0,0 +1,182 @@ +//-------------------------------------------------------------------------------------- +// File: DDSTextureLoader.h +// +// Functions for loading a DDS texture and creating a Direct3D runtime resource for it +// +// Note these functions are useful as a light-weight runtime loader for DDS files. For +// a full-featured DDS file reader, writer, and texture processing pipeline see +// the 'Texconv' sample and the 'DirectXTex' library. +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248926 +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +#include +#include + + +namespace DirectX +{ +#ifndef DDS_ALPHA_MODE_DEFINED +#define DDS_ALPHA_MODE_DEFINED + enum DDS_ALPHA_MODE : uint32_t + { + DDS_ALPHA_MODE_UNKNOWN = 0, + DDS_ALPHA_MODE_STRAIGHT = 1, + DDS_ALPHA_MODE_PREMULTIPLIED = 2, + DDS_ALPHA_MODE_OPAQUE = 3, + DDS_ALPHA_MODE_CUSTOM = 4, + }; +#endif + + inline namespace DX11 + { + enum DDS_LOADER_FLAGS : uint32_t + { + DDS_LOADER_DEFAULT = 0, + DDS_LOADER_FORCE_SRGB = 0x1, + DDS_LOADER_IGNORE_SRGB = 0x2, + }; + } + + // Standard version + HRESULT __cdecl CreateDDSTextureFromMemory( + _In_ ID3D11Device* d3dDevice, + _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, + _In_ size_t ddsDataSize, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr) noexcept; + + HRESULT __cdecl CreateDDSTextureFromFile( + _In_ ID3D11Device* d3dDevice, + _In_z_ const wchar_t* szFileName, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr) noexcept; + + // Standard version with optional auto-gen mipmap support + HRESULT __cdecl CreateDDSTextureFromMemory( + #if defined(_XBOX_ONE) && defined(_TITLE) + _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, + _In_ size_t ddsDataSize, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr) noexcept; + + HRESULT __cdecl CreateDDSTextureFromFile( + #if defined(_XBOX_ONE) && defined(_TITLE) + _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_z_ const wchar_t* szFileName, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr) noexcept; + + // Extended version + HRESULT __cdecl CreateDDSTextureFromMemoryEx( + _In_ ID3D11Device* d3dDevice, + _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, + _In_ size_t ddsDataSize, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ DDS_LOADER_FLAGS loadFlags, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr) noexcept; + + HRESULT __cdecl CreateDDSTextureFromFileEx( + _In_ ID3D11Device* d3dDevice, + _In_z_ const wchar_t* szFileName, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ DDS_LOADER_FLAGS loadFlags, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr) noexcept; + + // Extended version with optional auto-gen mipmap support + HRESULT __cdecl CreateDDSTextureFromMemoryEx( + #if defined(_XBOX_ONE) && defined(_TITLE) + _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, + _In_ size_t ddsDataSize, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ DDS_LOADER_FLAGS loadFlags, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr) noexcept; + + HRESULT __cdecl CreateDDSTextureFromFileEx( + #if defined(_XBOX_ONE) && defined(_TITLE) + _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_z_ const wchar_t* szFileName, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ DDS_LOADER_FLAGS loadFlags, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr) noexcept; + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-dynamic-exception-spec" +#endif + + inline namespace DX11 + { + DEFINE_ENUM_FLAG_OPERATORS(DDS_LOADER_FLAGS); + } + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +} diff --git a/enginecustom/include/Inc/DirectXHelpers.h b/enginecustom/include/Inc/DirectXHelpers.h new file mode 100644 index 0000000..5497f8e --- /dev/null +++ b/enginecustom/include/Inc/DirectXHelpers.h @@ -0,0 +1,232 @@ +//-------------------------------------------------------------------------------------- +// File: DirectXHelpers.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +#ifdef _MSC_VER +#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) +#if !defined(_XBOX_ONE) || !defined(_TITLE) +#pragma comment(lib,"dxguid.lib") +#endif +#endif +#endif + +#ifndef IID_GRAPHICS_PPV_ARGS +#define IID_GRAPHICS_PPV_ARGS(x) IID_PPV_ARGS(x) +#endif + +#include +#include +#include +#include +#include + +// +// The core Direct3D headers provide the following helper C++ classes +// CD3D11_RECT +// CD3D11_BOX +// CD3D11_DEPTH_STENCIL_DESC +// CD3D11_BLEND_DESC, CD3D11_BLEND_DESC1 +// CD3D11_RASTERIZER_DESC, CD3D11_RASTERIZER_DESC1 +// CD3D11_BUFFER_DESC +// CD3D11_TEXTURE1D_DESC +// CD3D11_TEXTURE2D_DESC +// CD3D11_TEXTURE3D_DESC +// CD3D11_SHADER_RESOURCE_VIEW_DESC +// CD3D11_RENDER_TARGET_VIEW_DESC +// CD3D11_VIEWPORT +// CD3D11_DEPTH_STENCIL_VIEW_DESC +// CD3D11_UNORDERED_ACCESS_VIEW_DESC +// CD3D11_SAMPLER_DESC +// CD3D11_QUERY_DESC +// CD3D11_COUNTER_DESC +// + + +namespace DirectX +{ + inline namespace DX11 + { + class IEffect; + } + + // simliar to std::lock_guard for exception-safe Direct3D resource locking + class MapGuard : public D3D11_MAPPED_SUBRESOURCE + { + public: + MapGuard(_In_ ID3D11DeviceContext* context, + _In_ ID3D11Resource *resource, + _In_ unsigned int subresource, + _In_ D3D11_MAP mapType, + _In_ unsigned int mapFlags) noexcept(false) + : mContext(context), mResource(resource), mSubresource(subresource) + { + HRESULT hr = mContext->Map(resource, subresource, mapType, mapFlags, this); + if (FAILED(hr)) + { + throw std::exception(); + } + } + + MapGuard(MapGuard&&) = delete; + MapGuard& operator= (MapGuard&&) = delete; + + MapGuard(MapGuard const&) = delete; + MapGuard& operator= (MapGuard const&) = delete; + + ~MapGuard() + { + mContext->Unmap(mResource, mSubresource); + } + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-warning-option" +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" +#endif + + uint8_t* get() const noexcept + { + return static_cast(pData); + } + uint8_t* get(size_t slice) const noexcept + { + return static_cast(pData) + (slice * DepthPitch); + } + + uint8_t* scanline(size_t row) const noexcept + { + return static_cast(pData) + (row * RowPitch); + } + uint8_t* scanline(size_t slice, size_t row) const noexcept + { + return static_cast(pData) + (slice * DepthPitch) + (row * RowPitch); + } + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + + template + void copy(_In_reads_(count) T const* data, size_t count) noexcept + { + memcpy(pData, data, count * sizeof(T)); + } + + template + void copy(T const& data) noexcept + { + memcpy(pData, data.data(), data.size() * sizeof(typename T::value_type)); + } + + private: + ID3D11DeviceContext* mContext; + ID3D11Resource* mResource; + unsigned int mSubresource; + }; + + + // Helper sets a D3D resource name string (used by PIX and debug layer leak reporting). + #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) + template + inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_z_ const char(&name)[TNameLength]) noexcept + { + #if defined(_XBOX_ONE) && defined(_TITLE) + wchar_t wname[MAX_PATH]; + int result = MultiByteToWideChar(CP_UTF8, 0, name, TNameLength, wname, MAX_PATH); + if (result > 0) + { + resource->SetName(wname); + } + #else + resource->SetPrivateData(WKPDID_D3DDebugObjectName, TNameLength - 1, name); + #endif + } + #else + template + inline void SetDebugObjectName(_In_ ID3D11DeviceChild*, _In_z_ const char(&)[TNameLength]) noexcept + { + } + #endif + +#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) + template + inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_z_ const wchar_t(&name)[TNameLength]) + { + #if defined(_XBOX_ONE) && defined(_TITLE) + resource->SetName(name); + #else + char aname[MAX_PATH]; + int result = WideCharToMultiByte(CP_UTF8, 0, name, TNameLength, aname, MAX_PATH, nullptr, nullptr); + if (result > 0) + { + resource->SetPrivateData(WKPDID_D3DDebugObjectName, TNameLength - 1, aname); + } + #endif + } +#else + template + inline void SetDebugObjectName(_In_ ID3D11DeviceChild*, _In_z_ const wchar_t(&)[TNameLength]) + { + } +#endif + + inline namespace DX11 + { + // Helper to check for power-of-2 + template + constexpr bool IsPowerOf2(T x) noexcept { return ((x != 0) && !(x & (x - 1))); } + + // Helpers for aligning values by a power of 2 + template + inline T AlignDown(T size, size_t alignment) noexcept + { + if (alignment > 0) + { + assert(((alignment - 1) & alignment) == 0); + auto mask = static_cast(alignment - 1); + return size & ~mask; + } + return size; + } + + template + inline T AlignUp(T size, size_t alignment) noexcept + { + if (alignment > 0) + { + assert(((alignment - 1) & alignment) == 0); + auto mask = static_cast(alignment - 1); + return (size + mask) & ~mask; + } + return size; + } + } + + // Helper for creating a Direct3D input layout to match a shader from an IEffect + HRESULT __cdecl CreateInputLayoutFromEffect(_In_ ID3D11Device* device, + _In_ IEffect* effect, + _In_reads_(count) const D3D11_INPUT_ELEMENT_DESC* desc, + size_t count, + _COM_Outptr_ ID3D11InputLayout** pInputLayout) noexcept; + + template + HRESULT CreateInputLayoutFromEffect(_In_ ID3D11Device* device, + _In_ IEffect* effect, + _COM_Outptr_ ID3D11InputLayout** pInputLayout) noexcept + { + return CreateInputLayoutFromEffect(device, effect, T::InputElements, T::InputElementCount, pInputLayout); + } +} diff --git a/enginecustom/include/Inc/Effects.h b/enginecustom/include/Inc/Effects.h new file mode 100644 index 0000000..811d0a1 --- /dev/null +++ b/enginecustom/include/Inc/Effects.h @@ -0,0 +1,1040 @@ +//-------------------------------------------------------------------------------------- +// File: Effects.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#ifndef __DIRECTXTK_EFFECTS_H__ +#define __DIRECTXTK_EFFECTS_H__ + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +#include +#include + +#include + + +namespace DirectX +{ + inline namespace DX11 + { + //------------------------------------------------------------------------------ + // Abstract interface representing any effect which can be applied onto a D3D device context. + class IEffect + { + public: + virtual ~IEffect() = default; + + IEffect(const IEffect&) = delete; + IEffect& operator=(const IEffect&) = delete; + + virtual void __cdecl Apply(_In_ ID3D11DeviceContext* deviceContext) = 0; + + virtual void __cdecl GetVertexShaderBytecode(_Out_ void const** pShaderByteCode, _Out_ size_t* pByteCodeLength) = 0; + + protected: + IEffect() = default; + IEffect(IEffect&&) = default; + IEffect& operator=(IEffect&&) = default; + }; + + + // Abstract interface for effects with world, view, and projection matrices. + class IEffectMatrices + { + public: + virtual ~IEffectMatrices() = default; + + IEffectMatrices(const IEffectMatrices&) = delete; + IEffectMatrices& operator=(const IEffectMatrices&) = delete; + + virtual void XM_CALLCONV SetWorld(FXMMATRIX value) = 0; + virtual void XM_CALLCONV SetView(FXMMATRIX value) = 0; + virtual void XM_CALLCONV SetProjection(FXMMATRIX value) = 0; + virtual void XM_CALLCONV SetMatrices(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection); + + protected: + IEffectMatrices() = default; + IEffectMatrices(IEffectMatrices&&) = default; + IEffectMatrices& operator=(IEffectMatrices&&) = default; + }; + + + // Abstract interface for effects which support directional lighting. + class IEffectLights + { + public: + virtual ~IEffectLights() = default; + + IEffectLights(const IEffectLights&) = delete; + IEffectLights& operator=(const IEffectLights&) = delete; + + virtual void __cdecl SetLightingEnabled(bool value) = 0; + virtual void __cdecl SetPerPixelLighting(bool value) = 0; + virtual void XM_CALLCONV SetAmbientLightColor(FXMVECTOR value) = 0; + + virtual void __cdecl SetLightEnabled(int whichLight, bool value) = 0; + virtual void XM_CALLCONV SetLightDirection(int whichLight, FXMVECTOR value) = 0; + virtual void XM_CALLCONV SetLightDiffuseColor(int whichLight, FXMVECTOR value) = 0; + virtual void XM_CALLCONV SetLightSpecularColor(int whichLight, FXMVECTOR value) = 0; + + virtual void __cdecl EnableDefaultLighting() = 0; + + static constexpr int MaxDirectionalLights = 3; + + protected: + IEffectLights() = default; + IEffectLights(IEffectLights&&) = default; + IEffectLights& operator=(IEffectLights&&) = default; + }; + + + // Abstract interface for effects which support fog. + class IEffectFog + { + public: + virtual ~IEffectFog() = default; + + IEffectFog(const IEffectFog&) = delete; + IEffectFog& operator=(const IEffectFog&) = delete; + + virtual void __cdecl SetFogEnabled(bool value) = 0; + virtual void __cdecl SetFogStart(float value) = 0; + virtual void __cdecl SetFogEnd(float value) = 0; + virtual void XM_CALLCONV SetFogColor(FXMVECTOR value) = 0; + + protected: + IEffectFog() = default; + IEffectFog(IEffectFog&&) = default; + IEffectFog& operator=(IEffectFog&&) = default; + }; + + + // Abstract interface for effects which support skinning + class IEffectSkinning + { + public: + virtual ~IEffectSkinning() = default; + + IEffectSkinning(const IEffectSkinning&) = delete; + IEffectSkinning& operator=(const IEffectSkinning&) = delete; + + virtual void __cdecl SetWeightsPerVertex(int value) = 0; + virtual void __cdecl SetBoneTransforms(_In_reads_(count) XMMATRIX const* value, size_t count) = 0; + virtual void __cdecl ResetBoneTransforms() = 0; + + static constexpr int MaxBones = 72; + + protected: + IEffectSkinning() = default; + IEffectSkinning(IEffectSkinning&&) = default; + IEffectSkinning& operator=(IEffectSkinning&&) = default; + }; + + //------------------------------------------------------------------------------ + // Built-in shader supports optional texture mapping, vertex coloring, directional lighting, and fog. + class BasicEffect : public IEffect, public IEffectMatrices, public IEffectLights, public IEffectFog + { + public: + explicit BasicEffect(_In_ ID3D11Device* device); + + BasicEffect(BasicEffect&&) noexcept; + BasicEffect& operator= (BasicEffect&&) noexcept; + + BasicEffect(BasicEffect const&) = delete; + BasicEffect& operator= (BasicEffect const&) = delete; + + ~BasicEffect() override; + + // IEffect methods. + void __cdecl Apply(_In_ ID3D11DeviceContext* deviceContext) override; + + void __cdecl GetVertexShaderBytecode(_Out_ void const** pShaderByteCode, _Out_ size_t* pByteCodeLength) override; + + // Camera settings. + void XM_CALLCONV SetWorld(FXMMATRIX value) override; + void XM_CALLCONV SetView(FXMMATRIX value) override; + void XM_CALLCONV SetProjection(FXMMATRIX value) override; + void XM_CALLCONV SetMatrices(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection) override; + + // Material settings. + void XM_CALLCONV SetDiffuseColor(FXMVECTOR value); + void XM_CALLCONV SetEmissiveColor(FXMVECTOR value); + void XM_CALLCONV SetSpecularColor(FXMVECTOR value); + void __cdecl SetSpecularPower(float value); + void __cdecl DisableSpecular(); + void __cdecl SetAlpha(float value); + void XM_CALLCONV SetColorAndAlpha(FXMVECTOR value); + + // Light settings. + void __cdecl SetLightingEnabled(bool value) override; + void __cdecl SetPerPixelLighting(bool value) override; + void XM_CALLCONV SetAmbientLightColor(FXMVECTOR value) override; + + void __cdecl SetLightEnabled(int whichLight, bool value) override; + void XM_CALLCONV SetLightDirection(int whichLight, FXMVECTOR value) override; + void XM_CALLCONV SetLightDiffuseColor(int whichLight, FXMVECTOR value) override; + void XM_CALLCONV SetLightSpecularColor(int whichLight, FXMVECTOR value) override; + + void __cdecl EnableDefaultLighting() override; + + // Fog settings. + void __cdecl SetFogEnabled(bool value) override; + void __cdecl SetFogStart(float value) override; + void __cdecl SetFogEnd(float value) override; + void XM_CALLCONV SetFogColor(FXMVECTOR value) override; + + // Vertex color setting. + void __cdecl SetVertexColorEnabled(bool value); + + // Texture setting. + void __cdecl SetTextureEnabled(bool value); + void __cdecl SetTexture(_In_opt_ ID3D11ShaderResourceView* value); + + // Normal compression settings. + void __cdecl SetBiasedVertexNormals(bool value); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; + + + + // Built-in shader supports per-pixel alpha testing. + class AlphaTestEffect : public IEffect, public IEffectMatrices, public IEffectFog + { + public: + explicit AlphaTestEffect(_In_ ID3D11Device* device); + + AlphaTestEffect(AlphaTestEffect&&) noexcept; + AlphaTestEffect& operator= (AlphaTestEffect&&) noexcept; + + AlphaTestEffect(AlphaTestEffect const&) = delete; + AlphaTestEffect& operator= (AlphaTestEffect const&) = delete; + + ~AlphaTestEffect() override; + + // IEffect methods. + void __cdecl Apply(_In_ ID3D11DeviceContext* deviceContext) override; + + void __cdecl GetVertexShaderBytecode(_Out_ void const** pShaderByteCode, _Out_ size_t* pByteCodeLength) override; + + // Camera settings. + void XM_CALLCONV SetWorld(FXMMATRIX value) override; + void XM_CALLCONV SetView(FXMMATRIX value) override; + void XM_CALLCONV SetProjection(FXMMATRIX value) override; + void XM_CALLCONV SetMatrices(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection) override; + + // Material settings. + void XM_CALLCONV SetDiffuseColor(FXMVECTOR value); + void __cdecl SetAlpha(float value); + void XM_CALLCONV SetColorAndAlpha(FXMVECTOR value); + + // Fog settings. + void __cdecl SetFogEnabled(bool value) override; + void __cdecl SetFogStart(float value) override; + void __cdecl SetFogEnd(float value) override; + void XM_CALLCONV SetFogColor(FXMVECTOR value) override; + + // Vertex color setting. + void __cdecl SetVertexColorEnabled(bool value); + + // Texture setting. + void __cdecl SetTexture(_In_opt_ ID3D11ShaderResourceView* value); + + // Alpha test settings. + void __cdecl SetAlphaFunction(D3D11_COMPARISON_FUNC value); + void __cdecl SetReferenceAlpha(int value); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; + + + + // Built-in shader supports two layer multitexturing (eg. for lightmaps or detail textures). + class DualTextureEffect : public IEffect, public IEffectMatrices, public IEffectFog + { + public: + explicit DualTextureEffect(_In_ ID3D11Device* device); + + DualTextureEffect(DualTextureEffect&&) noexcept; + DualTextureEffect& operator= (DualTextureEffect&&) noexcept; + + DualTextureEffect(DualTextureEffect const&) = delete; + DualTextureEffect& operator= (DualTextureEffect const&) = delete; + + ~DualTextureEffect() override; + + // IEffect methods. + void __cdecl Apply(_In_ ID3D11DeviceContext* deviceContext) override; + + void __cdecl GetVertexShaderBytecode(_Out_ void const** pShaderByteCode, _Out_ size_t* pByteCodeLength) override; + + // Camera settings. + void XM_CALLCONV SetWorld(FXMMATRIX value) override; + void XM_CALLCONV SetView(FXMMATRIX value) override; + void XM_CALLCONV SetProjection(FXMMATRIX value) override; + void XM_CALLCONV SetMatrices(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection) override; + + // Material settings. + void XM_CALLCONV SetDiffuseColor(FXMVECTOR value); + void __cdecl SetAlpha(float value); + void XM_CALLCONV SetColorAndAlpha(FXMVECTOR value); + + // Fog settings. + void __cdecl SetFogEnabled(bool value) override; + void __cdecl SetFogStart(float value) override; + void __cdecl SetFogEnd(float value) override; + void XM_CALLCONV SetFogColor(FXMVECTOR value) override; + + // Vertex color setting. + void __cdecl SetVertexColorEnabled(bool value); + + // Texture settings. + void __cdecl SetTexture(_In_opt_ ID3D11ShaderResourceView* value); + void __cdecl SetTexture2(_In_opt_ ID3D11ShaderResourceView* value); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; + + + + // Built-in shader supports cubic environment mapping. + class EnvironmentMapEffect : public IEffect, public IEffectMatrices, public IEffectLights, public IEffectFog + { + public: + enum Mapping + { + Mapping_Cube = 0, // Cubic environment map + Mapping_Sphere, // Spherical environment map + Mapping_DualParabola, // Dual-parabola environment map (requires Feature Level 10.0) + }; + + explicit EnvironmentMapEffect(_In_ ID3D11Device* device); + + EnvironmentMapEffect(EnvironmentMapEffect&&) noexcept; + EnvironmentMapEffect& operator= (EnvironmentMapEffect&&) noexcept; + + EnvironmentMapEffect(EnvironmentMapEffect const&) = delete; + EnvironmentMapEffect& operator= (EnvironmentMapEffect const&) = delete; + + ~EnvironmentMapEffect() override; + + // IEffect methods. + void __cdecl Apply(_In_ ID3D11DeviceContext* deviceContext) override; + + void __cdecl GetVertexShaderBytecode(_Out_ void const** pShaderByteCode, _Out_ size_t* pByteCodeLength) override; + + // Camera settings. + void XM_CALLCONV SetWorld(FXMMATRIX value) override; + void XM_CALLCONV SetView(FXMMATRIX value) override; + void XM_CALLCONV SetProjection(FXMMATRIX value) override; + void XM_CALLCONV SetMatrices(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection) override; + + // Material settings. + void XM_CALLCONV SetDiffuseColor(FXMVECTOR value); + void XM_CALLCONV SetEmissiveColor(FXMVECTOR value); + void __cdecl SetAlpha(float value); + void XM_CALLCONV SetColorAndAlpha(FXMVECTOR value); + + // Light settings. + void XM_CALLCONV SetAmbientLightColor(FXMVECTOR value) override; + + void __cdecl SetPerPixelLighting(bool value) override; + void __cdecl SetLightEnabled(int whichLight, bool value) override; + void XM_CALLCONV SetLightDirection(int whichLight, FXMVECTOR value) override; + void XM_CALLCONV SetLightDiffuseColor(int whichLight, FXMVECTOR value) override; + + void __cdecl EnableDefaultLighting() override; + + // Fog settings. + void __cdecl SetFogEnabled(bool value) override; + void __cdecl SetFogStart(float value) override; + void __cdecl SetFogEnd(float value) override; + void XM_CALLCONV SetFogColor(FXMVECTOR value) override; + + // Texture setting. + void __cdecl SetTexture(_In_opt_ ID3D11ShaderResourceView* value); + void __cdecl SetEnvironmentMap(_In_opt_ ID3D11ShaderResourceView* value); + + // Environment map settings. + void __cdecl SetMode(Mapping mapping); + void __cdecl SetEnvironmentMapAmount(float value); + void XM_CALLCONV SetEnvironmentMapSpecular(FXMVECTOR value); + void __cdecl SetFresnelFactor(float value); + + // Normal compression settings. + void __cdecl SetBiasedVertexNormals(bool value); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + + // Unsupported interface methods. + void __cdecl SetLightingEnabled(bool value) override; + void XM_CALLCONV SetLightSpecularColor(int whichLight, FXMVECTOR value) override; + }; + + + + // Built-in shader supports skinned animation. + class SkinnedEffect : public IEffect, public IEffectMatrices, public IEffectLights, public IEffectFog, public IEffectSkinning + { + public: + explicit SkinnedEffect(_In_ ID3D11Device* device); + + SkinnedEffect(SkinnedEffect&&) noexcept; + SkinnedEffect& operator= (SkinnedEffect&&) noexcept; + + SkinnedEffect(SkinnedEffect const&) = delete; + SkinnedEffect& operator= (SkinnedEffect const&) = delete; + + ~SkinnedEffect() override; + + // IEffect methods. + void __cdecl Apply(_In_ ID3D11DeviceContext* deviceContext) override; + + void __cdecl GetVertexShaderBytecode(_Out_ void const** pShaderByteCode, _Out_ size_t* pByteCodeLength) override; + + // Camera settings. + void XM_CALLCONV SetWorld(FXMMATRIX value) override; + void XM_CALLCONV SetView(FXMMATRIX value) override; + void XM_CALLCONV SetProjection(FXMMATRIX value) override; + void XM_CALLCONV SetMatrices(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection) override; + + // Material settings. + void XM_CALLCONV SetDiffuseColor(FXMVECTOR value); + void XM_CALLCONV SetEmissiveColor(FXMVECTOR value); + void XM_CALLCONV SetSpecularColor(FXMVECTOR value); + void __cdecl SetSpecularPower(float value); + void __cdecl DisableSpecular(); + void __cdecl SetAlpha(float value); + void XM_CALLCONV SetColorAndAlpha(FXMVECTOR value); + + // Light settings. + void __cdecl SetPerPixelLighting(bool value) override; + void XM_CALLCONV SetAmbientLightColor(FXMVECTOR value) override; + + void __cdecl SetLightEnabled(int whichLight, bool value) override; + void XM_CALLCONV SetLightDirection(int whichLight, FXMVECTOR value) override; + void XM_CALLCONV SetLightDiffuseColor(int whichLight, FXMVECTOR value) override; + void XM_CALLCONV SetLightSpecularColor(int whichLight, FXMVECTOR value) override; + + void __cdecl EnableDefaultLighting() override; + + // Fog settings. + void __cdecl SetFogEnabled(bool value) override; + void __cdecl SetFogStart(float value) override; + void __cdecl SetFogEnd(float value) override; + void XM_CALLCONV SetFogColor(FXMVECTOR value) override; + + // Texture setting. + void __cdecl SetTexture(_In_opt_ ID3D11ShaderResourceView* value); + + // Animation settings. + void __cdecl SetWeightsPerVertex(int value) override; + void __cdecl SetBoneTransforms(_In_reads_(count) XMMATRIX const* value, size_t count) override; + void __cdecl ResetBoneTransforms() override; + + // Normal compression settings. + void __cdecl SetBiasedVertexNormals(bool value); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + + // Unsupported interface method. + void __cdecl SetLightingEnabled(bool value) override; + }; + + //------------------------------------------------------------------------------ + // Built-in effect for Visual Studio Shader Designer (DGSL) shaders + class DGSLEffect : public IEffect, public IEffectMatrices, public IEffectLights + { + public: + explicit DGSLEffect(_In_ ID3D11Device* device, _In_opt_ ID3D11PixelShader* pixelShader = nullptr) : + DGSLEffect(device, pixelShader, false) + { + } + + DGSLEffect(DGSLEffect&&) noexcept; + DGSLEffect& operator= (DGSLEffect&&) noexcept; + + DGSLEffect(DGSLEffect const&) = delete; + DGSLEffect& operator= (DGSLEffect const&) = delete; + + ~DGSLEffect() override; + + // IEffect methods. + void __cdecl Apply(_In_ ID3D11DeviceContext* deviceContext) override; + + void __cdecl GetVertexShaderBytecode(_Out_ void const** pShaderByteCode, _Out_ size_t* pByteCodeLength) override; + + // Camera settings. + void XM_CALLCONV SetWorld(FXMMATRIX value) override; + void XM_CALLCONV SetView(FXMMATRIX value) override; + void XM_CALLCONV SetProjection(FXMMATRIX value) override; + void XM_CALLCONV SetMatrices(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection) override; + + // Material settings. + void XM_CALLCONV SetAmbientColor(FXMVECTOR value); + void XM_CALLCONV SetDiffuseColor(FXMVECTOR value); + void XM_CALLCONV SetEmissiveColor(FXMVECTOR value); + void XM_CALLCONV SetSpecularColor(FXMVECTOR value); + void __cdecl SetSpecularPower(float value); + void __cdecl DisableSpecular(); + void __cdecl SetAlpha(float value); + void XM_CALLCONV SetColorAndAlpha(FXMVECTOR value); + + // Additional settings. + void XM_CALLCONV SetUVTransform(FXMMATRIX value); + void __cdecl SetViewport(float width, float height); + void __cdecl SetTime(float time); + void __cdecl SetAlphaDiscardEnable(bool value); + + // Light settings. + void __cdecl SetLightingEnabled(bool value) override; + void XM_CALLCONV SetAmbientLightColor(FXMVECTOR value) override; + + void __cdecl SetLightEnabled(int whichLight, bool value) override; + void XM_CALLCONV SetLightDirection(int whichLight, FXMVECTOR value) override; + void XM_CALLCONV SetLightDiffuseColor(int whichLight, FXMVECTOR value) override; + void XM_CALLCONV SetLightSpecularColor(int whichLight, FXMVECTOR value) override; + + void __cdecl EnableDefaultLighting() override; + + static constexpr int MaxDirectionalLights = 4; + + // Vertex color setting. + void __cdecl SetVertexColorEnabled(bool value); + + // Texture settings. + void __cdecl SetTextureEnabled(bool value); + void __cdecl SetTexture(_In_opt_ ID3D11ShaderResourceView* value); + void __cdecl SetTexture(int whichTexture, _In_opt_ ID3D11ShaderResourceView* value); + + static constexpr int MaxTextures = 8; + + protected: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + + DGSLEffect(_In_ ID3D11Device* device, _In_opt_ ID3D11PixelShader* pixelShader, bool skinningEnabled); + + // Unsupported interface methods. + void __cdecl SetPerPixelLighting(bool value) override; + }; + + class SkinnedDGSLEffect : public DGSLEffect, public IEffectSkinning + { + public: + explicit SkinnedDGSLEffect(_In_ ID3D11Device* device, _In_opt_ ID3D11PixelShader* pixelShader = nullptr) : + DGSLEffect(device, pixelShader, true) + { + } + + SkinnedDGSLEffect(SkinnedDGSLEffect&&) = default; + SkinnedDGSLEffect& operator= (SkinnedDGSLEffect&&) = default; + + SkinnedDGSLEffect(SkinnedDGSLEffect const&) = delete; + SkinnedDGSLEffect& operator= (SkinnedDGSLEffect const&) = delete; + + ~SkinnedDGSLEffect() override; + + // Animation setting. + void __cdecl SetWeightsPerVertex(int value) override; + void __cdecl SetBoneTransforms(_In_reads_(count) XMMATRIX const* value, size_t count) override; + void __cdecl ResetBoneTransforms() override; + }; + + //------------------------------------------------------------------------------ + // Built-in shader extends BasicEffect with normal maps and optional specular maps + class NormalMapEffect : public IEffect, public IEffectMatrices, public IEffectLights, public IEffectFog + { + public: + explicit NormalMapEffect(_In_ ID3D11Device* device) : + NormalMapEffect(device, false) + { + } + + NormalMapEffect(NormalMapEffect&&) noexcept; + NormalMapEffect& operator= (NormalMapEffect&&) noexcept; + + NormalMapEffect(NormalMapEffect const&) = delete; + NormalMapEffect& operator= (NormalMapEffect const&) = delete; + + ~NormalMapEffect() override; + + // IEffect methods. + void __cdecl Apply(_In_ ID3D11DeviceContext* deviceContext) override; + + void __cdecl GetVertexShaderBytecode(_Out_ void const** pShaderByteCode, _Out_ size_t* pByteCodeLength) override; + + // Camera settings. + void XM_CALLCONV SetWorld(FXMMATRIX value) override; + void XM_CALLCONV SetView(FXMMATRIX value) override; + void XM_CALLCONV SetProjection(FXMMATRIX value) override; + void XM_CALLCONV SetMatrices(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection) override; + + // Material settings. + void XM_CALLCONV SetDiffuseColor(FXMVECTOR value); + void XM_CALLCONV SetEmissiveColor(FXMVECTOR value); + void XM_CALLCONV SetSpecularColor(FXMVECTOR value); + void __cdecl SetSpecularPower(float value); + void __cdecl DisableSpecular(); + void __cdecl SetAlpha(float value); + void XM_CALLCONV SetColorAndAlpha(FXMVECTOR value); + + // Light settings. + void XM_CALLCONV SetAmbientLightColor(FXMVECTOR value) override; + + void __cdecl SetLightEnabled(int whichLight, bool value) override; + void XM_CALLCONV SetLightDirection(int whichLight, FXMVECTOR value) override; + void XM_CALLCONV SetLightDiffuseColor(int whichLight, FXMVECTOR value) override; + void XM_CALLCONV SetLightSpecularColor(int whichLight, FXMVECTOR value) override; + + void __cdecl EnableDefaultLighting() override; + + // Fog settings. + void __cdecl SetFogEnabled(bool value) override; + void __cdecl SetFogStart(float value) override; + void __cdecl SetFogEnd(float value) override; + void XM_CALLCONV SetFogColor(FXMVECTOR value) override; + + // Vertex color setting. + void __cdecl SetVertexColorEnabled(bool value); + + // Texture setting - albedo, normal and specular intensity + void __cdecl SetTexture(_In_opt_ ID3D11ShaderResourceView* value); + void __cdecl SetNormalTexture(_In_opt_ ID3D11ShaderResourceView* value); + void __cdecl SetSpecularTexture(_In_opt_ ID3D11ShaderResourceView* value); + + // Normal compression settings. + void __cdecl SetBiasedVertexNormals(bool value); + + // Instancing settings. + void __cdecl SetInstancingEnabled(bool value); + + protected: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + + NormalMapEffect(_In_ ID3D11Device* device, bool skinningEnabled); + + // Unsupported interface methods. + void __cdecl SetLightingEnabled(bool value) override; + void __cdecl SetPerPixelLighting(bool value) override; + }; + + class SkinnedNormalMapEffect : public NormalMapEffect, public IEffectSkinning + { + public: + explicit SkinnedNormalMapEffect(_In_ ID3D11Device* device) : + NormalMapEffect(device, true) + { + } + + SkinnedNormalMapEffect(SkinnedNormalMapEffect&&) = default; + SkinnedNormalMapEffect& operator= (SkinnedNormalMapEffect&&) = default; + + SkinnedNormalMapEffect(SkinnedNormalMapEffect const&) = delete; + SkinnedNormalMapEffect& operator= (SkinnedNormalMapEffect const&) = delete; + + ~SkinnedNormalMapEffect() override; + + // Animation settings. + void __cdecl SetWeightsPerVertex(int value) override; + void __cdecl SetBoneTransforms(_In_reads_(count) XMMATRIX const* value, size_t count) override; + void __cdecl ResetBoneTransforms() override; + }; + + //------------------------------------------------------------------------------ + // Built-in shader for Physically-Based Rendering (Roughness/Metalness) with Image-based lighting + class PBREffect : public IEffect, public IEffectMatrices, public IEffectLights + { + public: + explicit PBREffect(_In_ ID3D11Device* device) : + PBREffect(device, false) + { + } + + PBREffect(PBREffect&&) noexcept; + PBREffect& operator= (PBREffect&&) noexcept; + + PBREffect(PBREffect const&) = delete; + PBREffect& operator= (PBREffect const&) = delete; + + ~PBREffect() override; + + // IEffect methods. + void __cdecl Apply(_In_ ID3D11DeviceContext* deviceContext) override; + + void __cdecl GetVertexShaderBytecode(_Out_ void const** pShaderByteCode, _Out_ size_t* pByteCodeLength) override; + + // Camera settings. + void XM_CALLCONV SetWorld(FXMMATRIX value) override; + void XM_CALLCONV SetView(FXMMATRIX value) override; + void XM_CALLCONV SetProjection(FXMMATRIX value) override; + void XM_CALLCONV SetMatrices(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection) override; + + // Light settings. + void __cdecl SetLightEnabled(int whichLight, bool value) override; + void XM_CALLCONV SetLightDirection(int whichLight, FXMVECTOR value) override; + void XM_CALLCONV SetLightDiffuseColor(int whichLight, FXMVECTOR value) override; + + void __cdecl EnableDefaultLighting() override; + + // PBR Settings. + void __cdecl SetAlpha(float value); + void XM_CALLCONV SetConstantAlbedo(FXMVECTOR value); + void __cdecl SetConstantMetallic(float value); + void __cdecl SetConstantRoughness(float value); + + // Texture settings. + void __cdecl SetAlbedoTexture(_In_opt_ ID3D11ShaderResourceView* value); + void __cdecl SetNormalTexture(_In_opt_ ID3D11ShaderResourceView* value); + void __cdecl SetRMATexture(_In_opt_ ID3D11ShaderResourceView* value); + + void __cdecl SetEmissiveTexture(_In_opt_ ID3D11ShaderResourceView* value); + + void __cdecl SetSurfaceTextures( + _In_opt_ ID3D11ShaderResourceView* albedo, + _In_opt_ ID3D11ShaderResourceView* normal, + _In_opt_ ID3D11ShaderResourceView* roughnessMetallicAmbientOcclusion); + + void __cdecl SetIBLTextures( + _In_opt_ ID3D11ShaderResourceView* radiance, + int numRadianceMips, + _In_opt_ ID3D11ShaderResourceView* irradiance); + + // Normal compression settings. + void __cdecl SetBiasedVertexNormals(bool value); + + // Instancing settings. + void __cdecl SetInstancingEnabled(bool value); + + // Velocity buffer settings. + void __cdecl SetVelocityGeneration(bool value); + + // Render target size, required for velocity buffer output. + void __cdecl SetRenderTargetSizeInPixels(int width, int height); + + protected: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + + PBREffect(_In_ ID3D11Device* device, bool skinningEnabled); + + // Unsupported interface methods. + void __cdecl SetLightingEnabled(bool value) override; + void __cdecl SetPerPixelLighting(bool value) override; + void XM_CALLCONV SetAmbientLightColor(FXMVECTOR value) override; + void XM_CALLCONV SetLightSpecularColor(int whichLight, FXMVECTOR value) override; + }; + + class SkinnedPBREffect : public PBREffect, public IEffectSkinning + { + public: + explicit SkinnedPBREffect(_In_ ID3D11Device* device) : + PBREffect(device, true) + { + } + + SkinnedPBREffect(SkinnedPBREffect&&) = default; + SkinnedPBREffect& operator= (SkinnedPBREffect&&) = default; + + SkinnedPBREffect(SkinnedPBREffect const&) = delete; + SkinnedPBREffect& operator= (SkinnedPBREffect const&) = delete; + + ~SkinnedPBREffect() override; + + // Animation settings. + void __cdecl SetWeightsPerVertex(int value) override; + void __cdecl SetBoneTransforms(_In_reads_(count) XMMATRIX const* value, size_t count) override; + void __cdecl ResetBoneTransforms() override; + }; + + //------------------------------------------------------------------------------ + // Built-in shader for debug visualization of normals, tangents, etc. + class DebugEffect : public IEffect, public IEffectMatrices + { + public: + enum Mode + { + Mode_Default = 0, // Hemispherical ambient lighting + Mode_Normals, // RGB normals + Mode_Tangents, // RGB tangents + Mode_BiTangents, // RGB bi-tangents + }; + + explicit DebugEffect(_In_ ID3D11Device* device); + + DebugEffect(DebugEffect&&) noexcept; + DebugEffect& operator= (DebugEffect&&) noexcept; + + DebugEffect(DebugEffect const&) = delete; + DebugEffect& operator= (DebugEffect const&) = delete; + + ~DebugEffect() override; + + // IEffect methods. + void __cdecl Apply(_In_ ID3D11DeviceContext* deviceContext) override; + + void __cdecl GetVertexShaderBytecode(_Out_ void const** pShaderByteCode, _Out_ size_t* pByteCodeLength) override; + + // Camera settings. + void XM_CALLCONV SetWorld(FXMMATRIX value) override; + void XM_CALLCONV SetView(FXMMATRIX value) override; + void XM_CALLCONV SetProjection(FXMMATRIX value) override; + void XM_CALLCONV SetMatrices(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection) override; + + // Debug Settings. + void __cdecl SetMode(Mode debugMode); + void XM_CALLCONV SetHemisphericalAmbientColor(FXMVECTOR upper, FXMVECTOR lower); + void __cdecl SetAlpha(float value); + + // Vertex color setting. + void __cdecl SetVertexColorEnabled(bool value); + + // Normal compression settings. + void __cdecl SetBiasedVertexNormals(bool value); + + // Instancing settings. + void __cdecl SetInstancingEnabled(bool value); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; + + //------------------------------------------------------------------------------ + // Abstract interface to factory for sharing effects and texture resources + class IEffectFactory + { + public: + virtual ~IEffectFactory() = default; + + IEffectFactory(const IEffectFactory&) = delete; + IEffectFactory& operator=(const IEffectFactory&) = delete; + + struct EffectInfo + { + const wchar_t* name; + bool perVertexColor; + bool enableSkinning; + bool enableDualTexture; + bool enableNormalMaps; + bool biasedVertexNormals; + float specularPower; + float alpha; + XMFLOAT3 ambientColor; + XMFLOAT3 diffuseColor; + XMFLOAT3 specularColor; + XMFLOAT3 emissiveColor; + const wchar_t* diffuseTexture; + const wchar_t* specularTexture; + const wchar_t* normalTexture; + const wchar_t* emissiveTexture; + + EffectInfo() noexcept : + name(nullptr), + perVertexColor(false), + enableSkinning(false), + enableDualTexture(false), + enableNormalMaps(false), + biasedVertexNormals(false), + specularPower(0), + alpha(0), + ambientColor(0, 0, 0), + diffuseColor(0, 0, 0), + specularColor(0, 0, 0), + emissiveColor(0, 0, 0), + diffuseTexture(nullptr), + specularTexture(nullptr), + normalTexture(nullptr), + emissiveTexture(nullptr) + { + } + }; + + virtual std::shared_ptr __cdecl CreateEffect(_In_ const EffectInfo& info, _In_opt_ ID3D11DeviceContext* deviceContext) = 0; + + virtual void __cdecl CreateTexture(_In_z_ const wchar_t* name, _In_opt_ ID3D11DeviceContext* deviceContext, _Outptr_ ID3D11ShaderResourceView** textureView) = 0; + + protected: + IEffectFactory() = default; + IEffectFactory(IEffectFactory&&) = default; + IEffectFactory& operator=(IEffectFactory&&) = default; + }; + + + // Factory for sharing effects and texture resources + class EffectFactory : public IEffectFactory + { + public: + explicit EffectFactory(_In_ ID3D11Device* device); + + EffectFactory(EffectFactory&&) noexcept; + EffectFactory& operator= (EffectFactory&&) noexcept; + + EffectFactory(EffectFactory const&) = delete; + EffectFactory& operator= (EffectFactory const&) = delete; + + ~EffectFactory() override; + + // IEffectFactory methods. + std::shared_ptr __cdecl CreateEffect(_In_ const EffectInfo& info, _In_opt_ ID3D11DeviceContext* deviceContext) override; + void __cdecl CreateTexture(_In_z_ const wchar_t* name, _In_opt_ ID3D11DeviceContext* deviceContext, _Outptr_ ID3D11ShaderResourceView** textureView) override; + + // Settings. + void __cdecl ReleaseCache(); + + void __cdecl SetSharing(bool enabled) noexcept; + + void __cdecl EnableNormalMapEffect(bool enabled) noexcept; + void __cdecl EnableForceSRGB(bool forceSRGB) noexcept; + + void __cdecl SetDirectory(_In_opt_z_ const wchar_t* path) noexcept; + + // Properties. + ID3D11Device* GetDevice() const noexcept; + + private: + // Private implementation. + class Impl; + + std::shared_ptr pImpl; + }; + + + // Factory for Physically Based Rendering (PBR) + class PBREffectFactory : public IEffectFactory + { + public: + explicit PBREffectFactory(_In_ ID3D11Device* device); + + PBREffectFactory(PBREffectFactory&&) noexcept; + PBREffectFactory& operator= (PBREffectFactory&&) noexcept; + + PBREffectFactory(PBREffectFactory const&) = delete; + PBREffectFactory& operator= (PBREffectFactory const&) = delete; + + ~PBREffectFactory() override; + + // IEffectFactory methods. + std::shared_ptr __cdecl CreateEffect(_In_ const EffectInfo& info, _In_opt_ ID3D11DeviceContext* deviceContext) override; + void __cdecl CreateTexture(_In_z_ const wchar_t* name, _In_opt_ ID3D11DeviceContext* deviceContext, _Outptr_ ID3D11ShaderResourceView** textureView) override; + + // Settings. + void __cdecl ReleaseCache(); + + void __cdecl SetSharing(bool enabled) noexcept; + + void __cdecl EnableForceSRGB(bool forceSRGB) noexcept; + + void __cdecl SetDirectory(_In_opt_z_ const wchar_t* path) noexcept; + + // Properties. + ID3D11Device* GetDevice() const noexcept; + + private: + // Private implementation. + class Impl; + + std::shared_ptr pImpl; + }; + + + // Factory for sharing Visual Studio Shader Designer (DGSL) shaders and texture resources + class DGSLEffectFactory : public IEffectFactory + { + public: + explicit DGSLEffectFactory(_In_ ID3D11Device* device); + + DGSLEffectFactory(DGSLEffectFactory&&) noexcept; + DGSLEffectFactory& operator= (DGSLEffectFactory&&) noexcept; + + DGSLEffectFactory(DGSLEffectFactory const&) = delete; + DGSLEffectFactory& operator= (DGSLEffectFactory const&) = delete; + + ~DGSLEffectFactory() override; + + // IEffectFactory methods. + std::shared_ptr __cdecl CreateEffect(_In_ const EffectInfo& info, _In_opt_ ID3D11DeviceContext* deviceContext) override; + void __cdecl CreateTexture(_In_z_ const wchar_t* name, _In_opt_ ID3D11DeviceContext* deviceContext, _Outptr_ ID3D11ShaderResourceView** textureView) override; + + // DGSL methods. + struct DGSLEffectInfo : public EffectInfo + { + static constexpr int BaseTextureOffset = 4; + + const wchar_t* textures[DGSLEffect::MaxTextures - BaseTextureOffset]; + const wchar_t* pixelShader; + + DGSLEffectInfo() noexcept : + EffectInfo(), + textures{}, + pixelShader(nullptr) + { + } + }; + + virtual std::shared_ptr __cdecl CreateDGSLEffect(_In_ const DGSLEffectInfo& info, _In_opt_ ID3D11DeviceContext* deviceContext); + + virtual void __cdecl CreatePixelShader(_In_z_ const wchar_t* shader, _Outptr_ ID3D11PixelShader** pixelShader); + + // Settings. + void __cdecl ReleaseCache(); + + void __cdecl SetSharing(bool enabled) noexcept; + + void __cdecl EnableForceSRGB(bool forceSRGB) noexcept; + + void __cdecl SetDirectory(_In_opt_z_ const wchar_t* path) noexcept; + + // Properties. + ID3D11Device* GetDevice() const noexcept; + + private: + // Private implementation. + class Impl; + + std::shared_ptr pImpl; + }; + } +} + +#endif // __DIRECTXTK_EFFECTS_H__ diff --git a/enginecustom/include/Inc/GamePad.h b/enginecustom/include/Inc/GamePad.h new file mode 100644 index 0000000..37f342c --- /dev/null +++ b/enginecustom/include/Inc/GamePad.h @@ -0,0 +1,329 @@ +//-------------------------------------------------------------------------------------- +// File: GamePad.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +// http://go.microsoft.com/fwlink/?LinkID=615561 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if !defined(USING_XINPUT) && !defined(USING_GAMEINPUT) && !defined(USING_WINDOWS_GAMING_INPUT) + +#ifdef _GAMING_DESKTOP +#include +#endif + +#if (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_GAMES)) || (defined(_GAMING_DESKTOP) && (_GRDK_EDITION >= 220600)) +#define USING_GAMEINPUT +#elif (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/) && !defined(_GAMING_DESKTOP) && !defined(__MINGW32__) +#define USING_WINDOWS_GAMING_INPUT +#elif !defined(_XBOX_ONE) +#define USING_XINPUT +#endif + +#endif // !USING_XINPUT && !USING_GAMEINPUT && !USING_WINDOWS_GAMING_INPUT + +#ifdef USING_GAMEINPUT +#include +#if !defined(_GAMING_XBOX) && defined(_MSC_VER) +#pragma comment(lib,"gameinput.lib") +#endif + +#elif defined(USING_WINDOWS_GAMING_INPUT) +#ifdef _MSC_VER +#pragma comment(lib,"runtimeobject.lib") +#endif +#include + +#elif defined(_XBOX_ONE) +// Legacy Xbox One XDK uses Windows::Xbox::Input + +#elif defined(USING_XINPUT) +#ifdef _MSC_VER +#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/ ) +#pragma comment(lib,"xinput.lib") +#else +#pragma comment(lib,"xinput9_1_0.lib") +#endif +#endif +#endif + +#include +#include + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#endif + + +namespace DirectX +{ + class GamePad + { + public: + GamePad() noexcept(false); + + GamePad(GamePad&&) noexcept; + GamePad& operator= (GamePad&&) noexcept; + + GamePad(GamePad const&) = delete; + GamePad& operator=(GamePad const&) = delete; + + virtual ~GamePad(); + + #if defined(USING_GAMEINPUT) || defined(USING_WINDOWS_GAMING_INPUT) || defined(_XBOX_ONE) + static constexpr int MAX_PLAYER_COUNT = 8; + #else + static constexpr int MAX_PLAYER_COUNT = 4; + #endif + + static constexpr int c_MostRecent = -1; + + #ifdef USING_GAMEINPUT + static constexpr int c_MergedInput = -2; + #endif + + enum DeadZone + { + DEAD_ZONE_INDEPENDENT_AXES = 0, + DEAD_ZONE_CIRCULAR, + DEAD_ZONE_NONE, + }; + + struct Buttons + { + bool a; + bool b; + bool x; + bool y; + bool leftStick; + bool rightStick; + bool leftShoulder; + bool rightShoulder; + union + { + bool back; + bool view; + }; + union + { + bool start; + bool menu; + }; + }; + + struct DPad + { + bool up; + bool down; + bool right; + bool left; + }; + + struct ThumbSticks + { + float leftX; + float leftY; + float rightX; + float rightY; + }; + + struct Triggers + { + float left; + float right; + }; + + struct State + { + bool connected; + uint64_t packet; + Buttons buttons; + DPad dpad; + ThumbSticks thumbSticks; + Triggers triggers; + + bool __cdecl IsConnected() const noexcept { return connected; } + + // Is the button pressed currently? + bool __cdecl IsAPressed() const noexcept { return buttons.a; } + bool __cdecl IsBPressed() const noexcept { return buttons.b; } + bool __cdecl IsXPressed() const noexcept { return buttons.x; } + bool __cdecl IsYPressed() const noexcept { return buttons.y; } + + bool __cdecl IsLeftStickPressed() const noexcept { return buttons.leftStick; } + bool __cdecl IsRightStickPressed() const noexcept { return buttons.rightStick; } + + bool __cdecl IsLeftShoulderPressed() const noexcept { return buttons.leftShoulder; } + bool __cdecl IsRightShoulderPressed() const noexcept { return buttons.rightShoulder; } + + bool __cdecl IsBackPressed() const noexcept { return buttons.back; } + bool __cdecl IsViewPressed() const noexcept { return buttons.view; } + bool __cdecl IsStartPressed() const noexcept { return buttons.start; } + bool __cdecl IsMenuPressed() const noexcept { return buttons.menu; } + + bool __cdecl IsDPadDownPressed() const noexcept { return dpad.down; } + bool __cdecl IsDPadUpPressed() const noexcept { return dpad.up; } + bool __cdecl IsDPadLeftPressed() const noexcept { return dpad.left; } + bool __cdecl IsDPadRightPressed() const noexcept { return dpad.right; } + + bool __cdecl IsLeftThumbStickUp() const noexcept { return (thumbSticks.leftY > 0.5f) != 0; } + bool __cdecl IsLeftThumbStickDown() const noexcept { return (thumbSticks.leftY < -0.5f) != 0; } + bool __cdecl IsLeftThumbStickLeft() const noexcept { return (thumbSticks.leftX < -0.5f) != 0; } + bool __cdecl IsLeftThumbStickRight() const noexcept { return (thumbSticks.leftX > 0.5f) != 0; } + + bool __cdecl IsRightThumbStickUp() const noexcept { return (thumbSticks.rightY > 0.5f) != 0; } + bool __cdecl IsRightThumbStickDown() const noexcept { return (thumbSticks.rightY < -0.5f) != 0; } + bool __cdecl IsRightThumbStickLeft() const noexcept { return (thumbSticks.rightX < -0.5f) != 0; } + bool __cdecl IsRightThumbStickRight() const noexcept { return (thumbSticks.rightX > 0.5f) != 0; } + + bool __cdecl IsLeftTriggerPressed() const noexcept { return (triggers.left > 0.5f) != 0; } + bool __cdecl IsRightTriggerPressed() const noexcept { return (triggers.right > 0.5f) != 0; } + }; + + struct Capabilities + { + enum Type + { + UNKNOWN = 0, + GAMEPAD, + WHEEL, + ARCADE_STICK, + FLIGHT_STICK, + DANCE_PAD, + GUITAR, + GUITAR_ALTERNATE, + DRUM_KIT, + GUITAR_BASS = 11, + ARCADE_PAD = 19, + }; + + bool connected; + Type gamepadType; + #ifdef USING_GAMEINPUT + APP_LOCAL_DEVICE_ID id; + #elif defined(USING_WINDOWS_GAMING_INPUT) + std::wstring id; + #else + uint64_t id; + #endif + uint16_t vid; + uint16_t pid; + + Capabilities() noexcept : connected(false), gamepadType(UNKNOWN), id{}, vid(0), pid(0) {} + + bool __cdecl IsConnected() const noexcept { return connected; } + }; + + class ButtonStateTracker + { + public: + enum ButtonState + { + UP = 0, // Button is up + HELD = 1, // Button is held down + RELEASED = 2, // Button was just released + PRESSED = 3, // Buton was just pressed + }; + + ButtonState a; + ButtonState b; + ButtonState x; + ButtonState y; + + ButtonState leftStick; + ButtonState rightStick; + + ButtonState leftShoulder; + ButtonState rightShoulder; + + union + { + ButtonState back; + ButtonState view; + }; + + union + { + ButtonState start; + ButtonState menu; + }; + + ButtonState dpadUp; + ButtonState dpadDown; + ButtonState dpadLeft; + ButtonState dpadRight; + + ButtonState leftStickUp; + ButtonState leftStickDown; + ButtonState leftStickLeft; + ButtonState leftStickRight; + + ButtonState rightStickUp; + ButtonState rightStickDown; + ButtonState rightStickLeft; + ButtonState rightStickRight; + + ButtonState leftTrigger; + ButtonState rightTrigger; + + #ifdef _PREFAST_ + #pragma prefast(push) + #pragma prefast(disable : 26495, "Reset() performs the initialization") + #endif + ButtonStateTracker() noexcept { Reset(); } + #ifdef _PREFAST_ + #pragma prefast(pop) + #endif + + void __cdecl Update(const State& state) noexcept; + + void __cdecl Reset() noexcept; + + State __cdecl GetLastState() const noexcept { return lastState; } + + private: + State lastState; + }; + + // Retrieve the current state of the gamepad of the associated player index + State __cdecl GetState(int player, DeadZone deadZoneMode = DEAD_ZONE_INDEPENDENT_AXES); + + // Retrieve the current capabilities of the gamepad of the associated player index + Capabilities __cdecl GetCapabilities(int player); + + // Set the vibration motor speeds of the gamepad + bool __cdecl SetVibration(int player, float leftMotor, float rightMotor, float leftTrigger = 0.f, float rightTrigger = 0.f) noexcept; + + // Handle suspending/resuming + void __cdecl Suspend() noexcept; + void __cdecl Resume() noexcept; + + #ifdef USING_GAMEINPUT + void __cdecl RegisterEvents(void* ctrlChanged) noexcept; + + // Underlying device access + _Success_(return) + bool __cdecl GetDevice(int player, _Outptr_ IGameInputDevice * *device) noexcept; + #elif defined(USING_WINDOWS_GAMING_INPUT) || defined(_XBOX_ONE) + void __cdecl RegisterEvents(void* ctrlChanged, void* userChanged) noexcept; + #endif + + // Singleton + static GamePad& __cdecl Get(); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif diff --git a/enginecustom/include/Inc/GeometricPrimitive.h b/enginecustom/include/Inc/GeometricPrimitive.h new file mode 100644 index 0000000..01cdd02 --- /dev/null +++ b/enginecustom/include/Inc/GeometricPrimitive.h @@ -0,0 +1,111 @@ +//-------------------------------------------------------------------------------------- +// File: GeometricPrimitive.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#include "VertexTypes.h" + +#include +#include +#include +#include +#include + +#include + + +namespace DirectX +{ + inline namespace DX11 + { + class IEffect; + + class GeometricPrimitive + { + public: + GeometricPrimitive(GeometricPrimitive&&) = default; + GeometricPrimitive& operator= (GeometricPrimitive&&) = default; + + GeometricPrimitive(GeometricPrimitive const&) = delete; + GeometricPrimitive& operator= (GeometricPrimitive const&) = delete; + + using VertexType = VertexPositionNormalTexture; + using VertexCollection = std::vector; + using IndexCollection = std::vector; + + virtual ~GeometricPrimitive(); + + // Factory methods. + static std::unique_ptr __cdecl CreateCube(_In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true); + static std::unique_ptr __cdecl CreateBox(_In_ ID3D11DeviceContext* deviceContext, const XMFLOAT3& size, bool rhcoords = true, bool invertn = false); + static std::unique_ptr __cdecl CreateSphere(_In_ ID3D11DeviceContext* deviceContext, float diameter = 1, size_t tessellation = 16, bool rhcoords = true, bool invertn = false); + static std::unique_ptr __cdecl CreateGeoSphere(_In_ ID3D11DeviceContext* deviceContext, float diameter = 1, size_t tessellation = 3, bool rhcoords = true); + static std::unique_ptr __cdecl CreateCylinder(_In_ ID3D11DeviceContext* deviceContext, float height = 1, float diameter = 1, size_t tessellation = 32, bool rhcoords = true); + static std::unique_ptr __cdecl CreateCone(_In_ ID3D11DeviceContext* deviceContext, float diameter = 1, float height = 1, size_t tessellation = 32, bool rhcoords = true); + static std::unique_ptr __cdecl CreateTorus(_In_ ID3D11DeviceContext* deviceContext, float diameter = 1, float thickness = 0.333f, size_t tessellation = 32, bool rhcoords = true); + static std::unique_ptr __cdecl CreateTetrahedron(_In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true); + static std::unique_ptr __cdecl CreateOctahedron(_In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true); + static std::unique_ptr __cdecl CreateDodecahedron(_In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true); + static std::unique_ptr __cdecl CreateIcosahedron(_In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true); + static std::unique_ptr __cdecl CreateTeapot(_In_ ID3D11DeviceContext* deviceContext, float size = 1, size_t tessellation = 8, bool rhcoords = true); + static std::unique_ptr __cdecl CreateCustom(_In_ ID3D11DeviceContext* deviceContext, const VertexCollection& vertices, const IndexCollection& indices); + + static void __cdecl CreateCube(VertexCollection& vertices, IndexCollection& indices, float size = 1, bool rhcoords = true); + static void __cdecl CreateBox(VertexCollection& vertices, IndexCollection& indices, const XMFLOAT3& size, bool rhcoords = true, bool invertn = false); + static void __cdecl CreateSphere(VertexCollection& vertices, IndexCollection& indices, float diameter = 1, size_t tessellation = 16, bool rhcoords = true, bool invertn = false); + static void __cdecl CreateGeoSphere(VertexCollection& vertices, IndexCollection& indices, float diameter = 1, size_t tessellation = 3, bool rhcoords = true); + static void __cdecl CreateCylinder(VertexCollection& vertices, IndexCollection& indices, float height = 1, float diameter = 1, size_t tessellation = 32, bool rhcoords = true); + static void __cdecl CreateCone(VertexCollection& vertices, IndexCollection& indices, float diameter = 1, float height = 1, size_t tessellation = 32, bool rhcoords = true); + static void __cdecl CreateTorus(VertexCollection& vertices, IndexCollection& indices, float diameter = 1, float thickness = 0.333f, size_t tessellation = 32, bool rhcoords = true); + static void __cdecl CreateTetrahedron(VertexCollection& vertices, IndexCollection& indices, float size = 1, bool rhcoords = true); + static void __cdecl CreateOctahedron(VertexCollection& vertices, IndexCollection& indices, float size = 1, bool rhcoords = true); + static void __cdecl CreateDodecahedron(VertexCollection& vertices, IndexCollection& indices, float size = 1, bool rhcoords = true); + static void __cdecl CreateIcosahedron(VertexCollection& vertices, IndexCollection& indices, float size = 1, bool rhcoords = true); + static void __cdecl CreateTeapot(VertexCollection& vertices, IndexCollection& indices, float size = 1, size_t tessellation = 8, bool rhcoords = true); + + // Draw the primitive. + void XM_CALLCONV Draw(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection, + FXMVECTOR color = Colors::White, + _In_opt_ ID3D11ShaderResourceView* texture = nullptr, + bool wireframe = false, + _In_ std::function setCustomState = nullptr) const; + + // Draw the primitive using a custom effect. + void __cdecl Draw(_In_ IEffect* effect, + _In_ ID3D11InputLayout* inputLayout, + bool alpha = false, bool wireframe = false, + _In_ std::function setCustomState = nullptr) const; + + void __cdecl DrawInstanced(_In_ IEffect* effect, + _In_ ID3D11InputLayout* inputLayout, + uint32_t instanceCount, + bool alpha = false, bool wireframe = false, + uint32_t startInstanceLocation = 0, + _In_ std::function setCustomState = nullptr) const; + + // Create input layout for drawing with a custom effect. + void __cdecl CreateInputLayout(_In_ IEffect* effect, _Outptr_ ID3D11InputLayout** inputLayout) const; + + static void SetDepthBufferMode(bool reverseZ) + { + s_reversez = reverseZ; + } + + private: + static bool s_reversez; + + GeometricPrimitive() noexcept(false); + + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; + } +} diff --git a/enginecustom/include/Inc/GraphicsMemory.h b/enginecustom/include/Inc/GraphicsMemory.h new file mode 100644 index 0000000..828b71e --- /dev/null +++ b/enginecustom/include/Inc/GraphicsMemory.h @@ -0,0 +1,57 @@ +//-------------------------------------------------------------------------------------- +// File: GraphicsMemory.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +#include +#include + + +namespace DirectX +{ + inline namespace DX11 + { + class GraphicsMemory + { + public: + #if defined(_XBOX_ONE) && defined(_TITLE) + GraphicsMemory(_In_ ID3D11DeviceX* device, unsigned int backBufferCount = 2); + #else + GraphicsMemory(_In_ ID3D11Device* device, unsigned int backBufferCount = 2); + #endif + + GraphicsMemory(GraphicsMemory&&) noexcept; + GraphicsMemory& operator= (GraphicsMemory&&) noexcept; + + GraphicsMemory(GraphicsMemory const&) = delete; + GraphicsMemory& operator=(GraphicsMemory const&) = delete; + + virtual ~GraphicsMemory(); + + void* __cdecl Allocate(_In_opt_ ID3D11DeviceContext* context, size_t size, int alignment); + + void __cdecl Commit(); + + // Singleton + static GraphicsMemory& __cdecl Get(); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; + } +} diff --git a/enginecustom/include/Inc/Keyboard.h b/enginecustom/include/Inc/Keyboard.h new file mode 100644 index 0000000..b92c217 --- /dev/null +++ b/enginecustom/include/Inc/Keyboard.h @@ -0,0 +1,532 @@ +//-------------------------------------------------------------------------------------- +// File: Keyboard.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +// http://go.microsoft.com/fwlink/?LinkID=615561 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if !defined(USING_XINPUT) && !defined(USING_GAMEINPUT) && !defined(USING_COREWINDOW) + +#ifdef _GAMING_DESKTOP +#include +#endif + +#if (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_GAMES)) || (defined(_GAMING_DESKTOP) && (_GRDK_EDITION >= 220600)) +#define USING_GAMEINPUT +#elif (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) || (defined(_XBOX_ONE) && defined(_TITLE)) +#define USING_COREWINDOW +#endif + +#endif // !USING_XINPUT && !USING_GAMEINPUT && !USING_WINDOWS_GAMING_INPUT + +#if defined(USING_GAMEINPUT) && !defined(_GAMING_XBOX) && defined(_MSC_VER) +#pragma comment(lib,"gameinput.lib") +#endif + +#include +#include + +#ifdef USING_COREWINDOW +namespace ABI { namespace Windows { namespace UI { namespace Core { struct ICoreWindow; } } } } +#endif + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#endif + + +namespace DirectX +{ + class Keyboard + { + public: + Keyboard() noexcept(false); + + Keyboard(Keyboard&&) noexcept; + Keyboard& operator= (Keyboard&&) noexcept; + + Keyboard(Keyboard const&) = delete; + Keyboard& operator=(Keyboard const&) = delete; + + virtual ~Keyboard(); + + enum Keys : unsigned char + { + None = 0, + + Back = 0x8, + Tab = 0x9, + + Enter = 0xd, + + Pause = 0x13, + CapsLock = 0x14, + Kana = 0x15, + ImeOn = 0x16, + + Kanji = 0x19, + + ImeOff = 0x1a, + Escape = 0x1b, + ImeConvert = 0x1c, + ImeNoConvert = 0x1d, + + Space = 0x20, + PageUp = 0x21, + PageDown = 0x22, + End = 0x23, + Home = 0x24, + Left = 0x25, + Up = 0x26, + Right = 0x27, + Down = 0x28, + Select = 0x29, + Print = 0x2a, + Execute = 0x2b, + PrintScreen = 0x2c, + Insert = 0x2d, + Delete = 0x2e, + Help = 0x2f, + D0 = 0x30, + D1 = 0x31, + D2 = 0x32, + D3 = 0x33, + D4 = 0x34, + D5 = 0x35, + D6 = 0x36, + D7 = 0x37, + D8 = 0x38, + D9 = 0x39, + + A = 0x41, + B = 0x42, + C = 0x43, + D = 0x44, + E = 0x45, + F = 0x46, + G = 0x47, + H = 0x48, + I = 0x49, + J = 0x4a, + K = 0x4b, + L = 0x4c, + M = 0x4d, + N = 0x4e, + O = 0x4f, + P = 0x50, + Q = 0x51, + R = 0x52, + S = 0x53, + T = 0x54, + U = 0x55, + V = 0x56, + W = 0x57, + X = 0x58, + Y = 0x59, + Z = 0x5a, + LeftWindows = 0x5b, + RightWindows = 0x5c, + Apps = 0x5d, + + Sleep = 0x5f, + NumPad0 = 0x60, + NumPad1 = 0x61, + NumPad2 = 0x62, + NumPad3 = 0x63, + NumPad4 = 0x64, + NumPad5 = 0x65, + NumPad6 = 0x66, + NumPad7 = 0x67, + NumPad8 = 0x68, + NumPad9 = 0x69, + Multiply = 0x6a, + Add = 0x6b, + Separator = 0x6c, + Subtract = 0x6d, + + Decimal = 0x6e, + Divide = 0x6f, + F1 = 0x70, + F2 = 0x71, + F3 = 0x72, + F4 = 0x73, + F5 = 0x74, + F6 = 0x75, + F7 = 0x76, + F8 = 0x77, + F9 = 0x78, + F10 = 0x79, + F11 = 0x7a, + F12 = 0x7b, + F13 = 0x7c, + F14 = 0x7d, + F15 = 0x7e, + F16 = 0x7f, + F17 = 0x80, + F18 = 0x81, + F19 = 0x82, + F20 = 0x83, + F21 = 0x84, + F22 = 0x85, + F23 = 0x86, + F24 = 0x87, + + NumLock = 0x90, + Scroll = 0x91, + + LeftShift = 0xa0, + RightShift = 0xa1, + LeftControl = 0xa2, + RightControl = 0xa3, + LeftAlt = 0xa4, + RightAlt = 0xa5, + BrowserBack = 0xa6, + BrowserForward = 0xa7, + BrowserRefresh = 0xa8, + BrowserStop = 0xa9, + BrowserSearch = 0xaa, + BrowserFavorites = 0xab, + BrowserHome = 0xac, + VolumeMute = 0xad, + VolumeDown = 0xae, + VolumeUp = 0xaf, + MediaNextTrack = 0xb0, + MediaPreviousTrack = 0xb1, + MediaStop = 0xb2, + MediaPlayPause = 0xb3, + LaunchMail = 0xb4, + SelectMedia = 0xb5, + LaunchApplication1 = 0xb6, + LaunchApplication2 = 0xb7, + + OemSemicolon = 0xba, + OemPlus = 0xbb, + OemComma = 0xbc, + OemMinus = 0xbd, + OemPeriod = 0xbe, + OemQuestion = 0xbf, + OemTilde = 0xc0, + + OemOpenBrackets = 0xdb, + OemPipe = 0xdc, + OemCloseBrackets = 0xdd, + OemQuotes = 0xde, + Oem8 = 0xdf, + + OemBackslash = 0xe2, + + ProcessKey = 0xe5, + + OemCopy = 0xf2, + OemAuto = 0xf3, + OemEnlW = 0xf4, + + Attn = 0xf6, + Crsel = 0xf7, + Exsel = 0xf8, + EraseEof = 0xf9, + Play = 0xfa, + Zoom = 0xfb, + + Pa1 = 0xfd, + OemClear = 0xfe, + }; + + struct State + { + bool Reserved0 : 8; + bool Back : 1; // VK_BACK, 0x8 + bool Tab : 1; // VK_TAB, 0x9 + bool Reserved1 : 3; + bool Enter : 1; // VK_RETURN, 0xD + bool Reserved2 : 2; + bool Reserved3 : 3; + bool Pause : 1; // VK_PAUSE, 0x13 + bool CapsLock : 1; // VK_CAPITAL, 0x14 + bool Kana : 1; // VK_KANA, 0x15 + bool ImeOn : 1; // VK_IME_ON, 0x16 + bool Reserved4 : 1; + bool Reserved5 : 1; + bool Kanji : 1; // VK_KANJI, 0x19 + bool ImeOff : 1; // VK_IME_OFF, 0X1A + bool Escape : 1; // VK_ESCAPE, 0x1B + bool ImeConvert : 1; // VK_CONVERT, 0x1C + bool ImeNoConvert : 1; // VK_NONCONVERT, 0x1D + bool Reserved7 : 2; + bool Space : 1; // VK_SPACE, 0x20 + bool PageUp : 1; // VK_PRIOR, 0x21 + bool PageDown : 1; // VK_NEXT, 0x22 + bool End : 1; // VK_END, 0x23 + bool Home : 1; // VK_HOME, 0x24 + bool Left : 1; // VK_LEFT, 0x25 + bool Up : 1; // VK_UP, 0x26 + bool Right : 1; // VK_RIGHT, 0x27 + bool Down : 1; // VK_DOWN, 0x28 + bool Select : 1; // VK_SELECT, 0x29 + bool Print : 1; // VK_PRINT, 0x2A + bool Execute : 1; // VK_EXECUTE, 0x2B + bool PrintScreen : 1; // VK_SNAPSHOT, 0x2C + bool Insert : 1; // VK_INSERT, 0x2D + bool Delete : 1; // VK_DELETE, 0x2E + bool Help : 1; // VK_HELP, 0x2F + bool D0 : 1; // 0x30 + bool D1 : 1; // 0x31 + bool D2 : 1; // 0x32 + bool D3 : 1; // 0x33 + bool D4 : 1; // 0x34 + bool D5 : 1; // 0x35 + bool D6 : 1; // 0x36 + bool D7 : 1; // 0x37 + bool D8 : 1; // 0x38 + bool D9 : 1; // 0x39 + bool Reserved8 : 6; + bool Reserved9 : 1; + bool A : 1; // 0x41 + bool B : 1; // 0x42 + bool C : 1; // 0x43 + bool D : 1; // 0x44 + bool E : 1; // 0x45 + bool F : 1; // 0x46 + bool G : 1; // 0x47 + bool H : 1; // 0x48 + bool I : 1; // 0x49 + bool J : 1; // 0x4A + bool K : 1; // 0x4B + bool L : 1; // 0x4C + bool M : 1; // 0x4D + bool N : 1; // 0x4E + bool O : 1; // 0x4F + bool P : 1; // 0x50 + bool Q : 1; // 0x51 + bool R : 1; // 0x52 + bool S : 1; // 0x53 + bool T : 1; // 0x54 + bool U : 1; // 0x55 + bool V : 1; // 0x56 + bool W : 1; // 0x57 + bool X : 1; // 0x58 + bool Y : 1; // 0x59 + bool Z : 1; // 0x5A + bool LeftWindows : 1; // VK_LWIN, 0x5B + bool RightWindows : 1; // VK_RWIN, 0x5C + bool Apps : 1; // VK_APPS, 0x5D + bool Reserved10 : 1; + bool Sleep : 1; // VK_SLEEP, 0x5F + bool NumPad0 : 1; // VK_NUMPAD0, 0x60 + bool NumPad1 : 1; // VK_NUMPAD1, 0x61 + bool NumPad2 : 1; // VK_NUMPAD2, 0x62 + bool NumPad3 : 1; // VK_NUMPAD3, 0x63 + bool NumPad4 : 1; // VK_NUMPAD4, 0x64 + bool NumPad5 : 1; // VK_NUMPAD5, 0x65 + bool NumPad6 : 1; // VK_NUMPAD6, 0x66 + bool NumPad7 : 1; // VK_NUMPAD7, 0x67 + bool NumPad8 : 1; // VK_NUMPAD8, 0x68 + bool NumPad9 : 1; // VK_NUMPAD9, 0x69 + bool Multiply : 1; // VK_MULTIPLY, 0x6A + bool Add : 1; // VK_ADD, 0x6B + bool Separator : 1; // VK_SEPARATOR, 0x6C + bool Subtract : 1; // VK_SUBTRACT, 0x6D + bool Decimal : 1; // VK_DECIMANL, 0x6E + bool Divide : 1; // VK_DIVIDE, 0x6F + bool F1 : 1; // VK_F1, 0x70 + bool F2 : 1; // VK_F2, 0x71 + bool F3 : 1; // VK_F3, 0x72 + bool F4 : 1; // VK_F4, 0x73 + bool F5 : 1; // VK_F5, 0x74 + bool F6 : 1; // VK_F6, 0x75 + bool F7 : 1; // VK_F7, 0x76 + bool F8 : 1; // VK_F8, 0x77 + bool F9 : 1; // VK_F9, 0x78 + bool F10 : 1; // VK_F10, 0x79 + bool F11 : 1; // VK_F11, 0x7A + bool F12 : 1; // VK_F12, 0x7B + bool F13 : 1; // VK_F13, 0x7C + bool F14 : 1; // VK_F14, 0x7D + bool F15 : 1; // VK_F15, 0x7E + bool F16 : 1; // VK_F16, 0x7F + bool F17 : 1; // VK_F17, 0x80 + bool F18 : 1; // VK_F18, 0x81 + bool F19 : 1; // VK_F19, 0x82 + bool F20 : 1; // VK_F20, 0x83 + bool F21 : 1; // VK_F21, 0x84 + bool F22 : 1; // VK_F22, 0x85 + bool F23 : 1; // VK_F23, 0x86 + bool F24 : 1; // VK_F24, 0x87 + bool Reserved11 : 8; + bool NumLock : 1; // VK_NUMLOCK, 0x90 + bool Scroll : 1; // VK_SCROLL, 0x91 + bool Reserved12 : 6; + bool Reserved13 : 8; + bool LeftShift : 1; // VK_LSHIFT, 0xA0 + bool RightShift : 1; // VK_RSHIFT, 0xA1 + bool LeftControl : 1; // VK_LCONTROL, 0xA2 + bool RightControl : 1; // VK_RCONTROL, 0xA3 + bool LeftAlt : 1; // VK_LMENU, 0xA4 + bool RightAlt : 1; // VK_RMENU, 0xA5 + bool BrowserBack : 1; // VK_BROWSER_BACK, 0xA6 + bool BrowserForward : 1; // VK_BROWSER_FORWARD, 0xA7 + bool BrowserRefresh : 1; // VK_BROWSER_REFRESH, 0xA8 + bool BrowserStop : 1; // VK_BROWSER_STOP, 0xA9 + bool BrowserSearch : 1; // VK_BROWSER_SEARCH, 0xAA + bool BrowserFavorites : 1; // VK_BROWSER_FAVORITES, 0xAB + bool BrowserHome : 1; // VK_BROWSER_HOME, 0xAC + bool VolumeMute : 1; // VK_VOLUME_MUTE, 0xAD + bool VolumeDown : 1; // VK_VOLUME_DOWN, 0xAE + bool VolumeUp : 1; // VK_VOLUME_UP, 0xAF + bool MediaNextTrack : 1; // VK_MEDIA_NEXT_TRACK, 0xB0 + bool MediaPreviousTrack : 1;// VK_MEDIA_PREV_TRACK, 0xB1 + bool MediaStop : 1; // VK_MEDIA_STOP, 0xB2 + bool MediaPlayPause : 1; // VK_MEDIA_PLAY_PAUSE, 0xB3 + bool LaunchMail : 1; // VK_LAUNCH_MAIL, 0xB4 + bool SelectMedia : 1; // VK_LAUNCH_MEDIA_SELECT, 0xB5 + bool LaunchApplication1 : 1;// VK_LAUNCH_APP1, 0xB6 + bool LaunchApplication2 : 1;// VK_LAUNCH_APP2, 0xB7 + bool Reserved14 : 2; + bool OemSemicolon : 1; // VK_OEM_1, 0xBA + bool OemPlus : 1; // VK_OEM_PLUS, 0xBB + bool OemComma : 1; // VK_OEM_COMMA, 0xBC + bool OemMinus : 1; // VK_OEM_MINUS, 0xBD + bool OemPeriod : 1; // VK_OEM_PERIOD, 0xBE + bool OemQuestion : 1; // VK_OEM_2, 0xBF + bool OemTilde : 1; // VK_OEM_3, 0xC0 + bool Reserved15 : 7; + bool Reserved16 : 8; + bool Reserved17 : 8; + bool Reserved18 : 3; + bool OemOpenBrackets : 1; // VK_OEM_4, 0xDB + bool OemPipe : 1; // VK_OEM_5, 0xDC + bool OemCloseBrackets : 1; // VK_OEM_6, 0xDD + bool OemQuotes : 1; // VK_OEM_7, 0xDE + bool Oem8 : 1; // VK_OEM_8, 0xDF + bool Reserved19 : 2; + bool OemBackslash : 1; // VK_OEM_102, 0xE2 + bool Reserved20 : 2; + bool ProcessKey : 1; // VK_PROCESSKEY, 0xE5 + bool Reserved21 : 2; + bool Reserved22 : 8; + bool Reserved23 : 2; + bool OemCopy : 1; // 0XF2 + bool OemAuto : 1; // 0xF3 + bool OemEnlW : 1; // 0xF4 + bool Reserved24 : 1; + bool Attn : 1; // VK_ATTN, 0xF6 + bool Crsel : 1; // VK_CRSEL, 0xF7 + bool Exsel : 1; // VK_EXSEL, 0xF8 + bool EraseEof : 1; // VK_EREOF, 0xF9 + bool Play : 1; // VK_PLAY, 0xFA + bool Zoom : 1; // VK_ZOOM, 0xFB + bool Reserved25 : 1; + bool Pa1 : 1; // VK_PA1, 0xFD + bool OemClear : 1; // VK_OEM_CLEAR, 0xFE + bool Reserved26 : 1; + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-warning-option" +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" +#endif + + bool __cdecl IsKeyDown(Keys key) const noexcept + { + if (key <= 0xfe) + { + auto ptr = reinterpret_cast(this); + const unsigned int bf = 1u << (key & 0x1f); + return (ptr[(key >> 5)] & bf) != 0; + } + return false; + } + + bool __cdecl IsKeyUp(Keys key) const noexcept + { + if (key <= 0xfe) + { + auto ptr = reinterpret_cast(this); + const unsigned int bf = 1u << (key & 0x1f); + return (ptr[(key >> 5)] & bf) == 0; + } + return false; + } + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + }; + + class KeyboardStateTracker + { + public: + State released; + State pressed; + + #ifdef _PREFAST_ + #pragma prefast(push) + #pragma prefast(disable : 26495, "Reset() performs the initialization") + #endif + KeyboardStateTracker() noexcept { Reset(); } + #ifdef _PREFAST_ + #pragma prefast(pop) + #endif + + void __cdecl Update(const State& state) noexcept; + + void __cdecl Reset() noexcept; + + bool __cdecl IsKeyPressed(Keys key) const noexcept { return pressed.IsKeyDown(key); } + bool __cdecl IsKeyReleased(Keys key) const noexcept { return released.IsKeyDown(key); } + + State __cdecl GetLastState() const noexcept { return lastState; } + + public: + State lastState; + }; + + // Retrieve the current state of the keyboard + State __cdecl GetState() const; + + // Reset the keyboard state + void __cdecl Reset() noexcept; + + // Feature detection + bool __cdecl IsConnected() const; + + #ifdef USING_COREWINDOW + void __cdecl SetWindow(ABI::Windows::UI::Core::ICoreWindow* window); + #ifdef __cplusplus_winrt + void __cdecl SetWindow(Windows::UI::Core::CoreWindow^ window) + { + // See https://msdn.microsoft.com/en-us/library/hh755802.aspx + SetWindow(reinterpret_cast(window)); + } + #endif + #ifdef CPPWINRT_VERSION + void __cdecl SetWindow(winrt::Windows::UI::Core::CoreWindow window) + { + // See https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/interop-winrt-abi + SetWindow(reinterpret_cast(winrt::get_abi(window))); + } + #endif + #elif defined(WM_USER) + static void __cdecl ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam); + #endif + + // Singleton + static Keyboard& __cdecl Get(); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif diff --git a/enginecustom/include/Inc/Model.h b/enginecustom/include/Inc/Model.h new file mode 100644 index 0000000..8ead411 --- /dev/null +++ b/enginecustom/include/Inc/Model.h @@ -0,0 +1,372 @@ +//-------------------------------------------------------------------------------------- +// File: Model.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + + +namespace DirectX +{ + inline namespace DX11 + { + class IEffect; + class IEffectFactory; + class CommonStates; + class ModelMesh; + + //------------------------------------------------------------------------------ + // Model loading options + enum ModelLoaderFlags : uint32_t + { + ModelLoader_Clockwise = 0x0, + ModelLoader_CounterClockwise = 0x1, + ModelLoader_PremultipledAlpha = 0x2, + ModelLoader_MaterialColorsSRGB = 0x4, + ModelLoader_AllowLargeModels = 0x8, + ModelLoader_IncludeBones = 0x10, + ModelLoader_DisableSkinning = 0x20, + }; + + //------------------------------------------------------------------------------ + // Frame hierarchy for rigid body and skeletal animation + struct ModelBone + { + ModelBone() noexcept : + parentIndex(c_Invalid), + childIndex(c_Invalid), + siblingIndex(c_Invalid) + { + } + + ModelBone(uint32_t parent, uint32_t child, uint32_t sibling) noexcept : + parentIndex(parent), + childIndex(child), + siblingIndex(sibling) + { + } + + uint32_t parentIndex; + uint32_t childIndex; + uint32_t siblingIndex; + std::wstring name; + + using Collection = std::vector; + + static constexpr uint32_t c_Invalid = uint32_t(-1); + + struct aligned_deleter { void operator()(void* p) noexcept { _aligned_free(p); } }; + + using TransformArray = std::unique_ptr; + + static TransformArray MakeArray(size_t count) + { + void* temp = _aligned_malloc(sizeof(XMMATRIX) * count, 16); + if (!temp) + throw std::bad_alloc(); + return TransformArray(static_cast(temp)); + } + }; + + + //------------------------------------------------------------------------------ + // Each mesh part is a submesh with a single effect + class ModelMeshPart + { + public: + ModelMeshPart() noexcept; + + ModelMeshPart(ModelMeshPart&&) = default; + ModelMeshPart& operator= (ModelMeshPart&&) = default; + + ModelMeshPart(ModelMeshPart const&) = default; + ModelMeshPart& operator= (ModelMeshPart const&) = default; + + virtual ~ModelMeshPart(); + + using Collection = std::vector>; + using InputLayoutCollection = std::vector; + + uint32_t indexCount; + uint32_t startIndex; + int32_t vertexOffset; + uint32_t vertexStride; + D3D_PRIMITIVE_TOPOLOGY primitiveType; + DXGI_FORMAT indexFormat; + Microsoft::WRL::ComPtr inputLayout; + Microsoft::WRL::ComPtr indexBuffer; + Microsoft::WRL::ComPtr vertexBuffer; + std::shared_ptr effect; + std::shared_ptr vbDecl; + bool isAlpha; + + // Draw mesh part with custom effect + void __cdecl Draw( + _In_ ID3D11DeviceContext* deviceContext, + _In_ IEffect* ieffect, + _In_ ID3D11InputLayout* iinputLayout, + _In_ std::function setCustomState = nullptr) const; + + void __cdecl DrawInstanced( + _In_ ID3D11DeviceContext* deviceContext, + _In_ IEffect* ieffect, + _In_ ID3D11InputLayout* iinputLayout, + uint32_t instanceCount, + uint32_t startInstanceLocation = 0, + _In_ std::function setCustomState = nullptr) const; + + // Create input layout for drawing with a custom effect. + void __cdecl CreateInputLayout(_In_ ID3D11Device* device, _In_ IEffect* ieffect, _Outptr_ ID3D11InputLayout** iinputLayout) const; + + // Change effect used by part and regenerate input layout (be sure to call Model::Modified as well) + void __cdecl ModifyEffect(_In_ ID3D11Device* device, _In_ const std::shared_ptr& ieffect, bool isalpha = false); + }; + + + //------------------------------------------------------------------------------ + // A mesh consists of one or more model mesh parts + class ModelMesh + { + public: + ModelMesh() noexcept; + + ModelMesh(ModelMesh&&) = default; + ModelMesh& operator= (ModelMesh&&) = default; + + ModelMesh(ModelMesh const&) = default; + ModelMesh& operator= (ModelMesh const&) = default; + + virtual ~ModelMesh(); + + BoundingSphere boundingSphere; + BoundingBox boundingBox; + ModelMeshPart::Collection meshParts; + uint32_t boneIndex; + std::vector boneInfluences; + std::wstring name; + bool ccw; + bool pmalpha; + + using Collection = std::vector>; + + // Setup states for drawing mesh + void __cdecl PrepareForRendering( + _In_ ID3D11DeviceContext* deviceContext, + const CommonStates& states, + bool alpha = false, + bool wireframe = false) const; + + // Draw the mesh + void XM_CALLCONV Draw( + _In_ ID3D11DeviceContext* deviceContext, + FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection, + bool alpha = false, + _In_ std::function setCustomState = nullptr) const; + + // Draw the mesh using model bones + void XM_CALLCONV Draw( + _In_ ID3D11DeviceContext* deviceContext, + size_t nbones, _In_reads_(nbones) const XMMATRIX* boneTransforms, + FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection, + bool alpha = false, + _In_ std::function setCustomState = nullptr) const; + + // Draw the mesh using skinning + void XM_CALLCONV DrawSkinned( + _In_ ID3D11DeviceContext* deviceContext, + size_t nbones, _In_reads_(nbones) const XMMATRIX* boneTransforms, + FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection, + bool alpha = false, + _In_ std::function setCustomState = nullptr) const; + + static void SetDepthBufferMode(bool reverseZ) + { + s_reversez = reverseZ; + } + + private: + static bool s_reversez; + }; + + + //------------------------------------------------------------------------------ + // A model consists of one or more meshes + class Model + { + public: + Model() = default; + + Model(Model&&) = default; + Model& operator= (Model&&) = default; + + Model(Model const& other); + Model& operator= (Model const& rhs); + + virtual ~Model(); + + ModelMesh::Collection meshes; + ModelBone::Collection bones; + ModelBone::TransformArray boneMatrices; + ModelBone::TransformArray invBindPoseMatrices; + std::wstring name; + + // Draw all the meshes in the model + void XM_CALLCONV Draw( + _In_ ID3D11DeviceContext* deviceContext, + const CommonStates& states, + FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection, + bool wireframe = false, + _In_ std::function setCustomState = nullptr) const; + + // Draw all the meshes using model bones + void XM_CALLCONV Draw( + _In_ ID3D11DeviceContext* deviceContext, + const CommonStates& states, + size_t nbones, _In_reads_(nbones) const XMMATRIX* boneTransforms, + FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection, + bool wireframe = false, + _In_ std::function setCustomState = nullptr) const; + + // Draw all the meshes using skinning + void XM_CALLCONV DrawSkinned( + _In_ ID3D11DeviceContext* deviceContext, + const CommonStates& states, + size_t nbones, _In_reads_(nbones) const XMMATRIX* boneTransforms, + FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection, + bool wireframe = false, + _In_ std::function setCustomState = nullptr) const; + + // Compute bone positions based on heirarchy and transform matrices + void __cdecl CopyAbsoluteBoneTransformsTo( + size_t nbones, + _Out_writes_(nbones) XMMATRIX* boneTransforms) const; + + void __cdecl CopyAbsoluteBoneTransforms( + size_t nbones, + _In_reads_(nbones) const XMMATRIX* inBoneTransforms, + _Out_writes_(nbones) XMMATRIX* outBoneTransforms) const; + + // Set bone matrices to a set of relative tansforms + void __cdecl CopyBoneTransformsFrom( + size_t nbones, + _In_reads_(nbones) const XMMATRIX* boneTransforms); + + // Copies the relative bone matrices to a transform array + void __cdecl CopyBoneTransformsTo( + size_t nbones, + _Out_writes_(nbones) XMMATRIX* boneTransforms) const; + + // Notify model that effects, parts list, or mesh list has changed + void __cdecl Modified() noexcept { mEffectCache.clear(); } + + // Update all effects used by the model + void __cdecl UpdateEffects(_In_ std::function setEffect); + + // Loads a model from a Visual Studio Starter Kit .CMO file + static std::unique_ptr __cdecl CreateFromCMO( + _In_ ID3D11Device* device, + _In_reads_bytes_(dataSize) const uint8_t* meshData, size_t dataSize, + _In_ IEffectFactory& fxFactory, + ModelLoaderFlags flags = ModelLoader_CounterClockwise, + _Out_opt_ size_t* animsOffset = nullptr); + static std::unique_ptr __cdecl CreateFromCMO( + _In_ ID3D11Device* device, + _In_z_ const wchar_t* szFileName, + _In_ IEffectFactory& fxFactory, + ModelLoaderFlags flags = ModelLoader_CounterClockwise, + _Out_opt_ size_t* animsOffset = nullptr); + + // Loads a model from a DirectX SDK .SDKMESH file + static std::unique_ptr __cdecl CreateFromSDKMESH( + _In_ ID3D11Device* device, + _In_reads_bytes_(dataSize) const uint8_t* meshData, _In_ size_t dataSize, + _In_ IEffectFactory& fxFactory, + ModelLoaderFlags flags = ModelLoader_Clockwise); + static std::unique_ptr __cdecl CreateFromSDKMESH( + _In_ ID3D11Device* device, + _In_z_ const wchar_t* szFileName, + _In_ IEffectFactory& fxFactory, + ModelLoaderFlags flags = ModelLoader_Clockwise); + + // Loads a model from a .VBO file + static std::unique_ptr __cdecl CreateFromVBO( + _In_ ID3D11Device* device, + _In_reads_bytes_(dataSize) const uint8_t* meshData, _In_ size_t dataSize, + _In_ std::shared_ptr ieffect = nullptr, + ModelLoaderFlags flags = ModelLoader_Clockwise); + static std::unique_ptr __cdecl CreateFromVBO( + _In_ ID3D11Device* device, + _In_z_ const wchar_t* szFileName, + _In_ std::shared_ptr ieffect = nullptr, + ModelLoaderFlags flags = ModelLoader_Clockwise); + +#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED) + static std::unique_ptr __cdecl CreateFromCMO( + _In_ ID3D11Device* device, + _In_z_ const __wchar_t* szFileName, + _In_ IEffectFactory& fxFactory, + ModelLoaderFlags flags = ModelLoader_CounterClockwise, + _Out_opt_ size_t* animsOffset = nullptr); + + static std::unique_ptr __cdecl CreateFromSDKMESH( + _In_ ID3D11Device* device, + _In_z_ const __wchar_t* szFileName, + _In_ IEffectFactory& fxFactory, + ModelLoaderFlags flags = ModelLoader_Clockwise); + + static std::unique_ptr __cdecl CreateFromVBO( + _In_ ID3D11Device* device, + _In_z_ const __wchar_t* szFileName, + _In_ std::shared_ptr ieffect = nullptr, + ModelLoaderFlags flags = ModelLoader_Clockwise); +#endif // !_NATIVE_WCHAR_T_DEFINED + + private: + std::set mEffectCache; + + void __cdecl ComputeAbsolute(uint32_t index, + CXMMATRIX local, size_t nbones, + _In_reads_(nbones) const XMMATRIX* inBoneTransforms, + _Inout_updates_(nbones) XMMATRIX* outBoneTransforms, + size_t& visited) const; + }; + + #ifdef __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-dynamic-exception-spec" + #endif + + DEFINE_ENUM_FLAG_OPERATORS(ModelLoaderFlags); + + #ifdef __clang__ + #pragma clang diagnostic pop + #endif + } +} diff --git a/enginecustom/include/Inc/Mouse.h b/enginecustom/include/Inc/Mouse.h new file mode 100644 index 0000000..60d0bfe --- /dev/null +++ b/enginecustom/include/Inc/Mouse.h @@ -0,0 +1,172 @@ +//-------------------------------------------------------------------------------------- +// File: Mouse.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +// http://go.microsoft.com/fwlink/?LinkID=615561 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if !defined(USING_XINPUT) && !defined(USING_GAMEINPUT) && !defined(USING_COREWINDOW) + +#ifdef _GAMING_DESKTOP +#include +#endif + +#if (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_GAMES)) || (defined(_GAMING_DESKTOP) && (_GRDK_EDITION >= 220600)) +#define USING_GAMEINPUT +#elif (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) || (defined(_XBOX_ONE) && defined(_TITLE)) +#define USING_COREWINDOW +#endif + +#endif // !USING_XINPUT && !USING_GAMEINPUT && !USING_WINDOWS_GAMING_INPUT + +#if defined(USING_GAMEINPUT) && !defined(_GAMING_XBOX) && defined(_MSC_VER) +#pragma comment(lib,"gameinput.lib") +#endif + +#include + +#ifdef USING_COREWINDOW +namespace ABI { namespace Windows { namespace UI { namespace Core { struct ICoreWindow; } } } } +#endif + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#endif + + +namespace DirectX +{ + class Mouse + { + public: + Mouse() noexcept(false); + + Mouse(Mouse&&) noexcept; + Mouse& operator= (Mouse&&) noexcept; + + Mouse(Mouse const&) = delete; + Mouse& operator=(Mouse const&) = delete; + + virtual ~Mouse(); + + enum Mode + { + MODE_ABSOLUTE = 0, + MODE_RELATIVE, + }; + + struct State + { + bool leftButton; + bool middleButton; + bool rightButton; + bool xButton1; + bool xButton2; + int x; + int y; + int scrollWheelValue; + Mode positionMode; + }; + + class ButtonStateTracker + { + public: + enum ButtonState + { + UP = 0, // Button is up + HELD = 1, // Button is held down + RELEASED = 2, // Button was just released + PRESSED = 3, // Buton was just pressed + }; + + ButtonState leftButton; + ButtonState middleButton; + ButtonState rightButton; + ButtonState xButton1; + ButtonState xButton2; + + #ifdef _PREFAST_ + #pragma prefast(push) + #pragma prefast(disable : 26495, "Reset() performs the initialization") + #endif + ButtonStateTracker() noexcept { Reset(); } + #ifdef _PREFAST_ + #pragma prefast(pop) + #endif + + void __cdecl Update(const State& state) noexcept; + + void __cdecl Reset() noexcept; + + State __cdecl GetLastState() const noexcept { return lastState; } + + private: + State lastState; + }; + + // Retrieve the current state of the mouse + State __cdecl GetState() const; + + // Resets the accumulated scroll wheel value + void __cdecl ResetScrollWheelValue() noexcept; + + // Sets mouse mode (defaults to absolute) + void __cdecl SetMode(Mode mode); + + // Signals the end of frame (recommended, but optional) + void __cdecl EndOfInputFrame() noexcept; + + // Feature detection + bool __cdecl IsConnected() const; + + // Cursor visibility + bool __cdecl IsVisible() const noexcept; + void __cdecl SetVisible(bool visible); + + #ifdef USING_COREWINDOW + void __cdecl SetWindow(ABI::Windows::UI::Core::ICoreWindow* window); + #ifdef __cplusplus_winrt + void __cdecl SetWindow(Windows::UI::Core::CoreWindow^ window) + { + // See https://msdn.microsoft.com/en-us/library/hh755802.aspx + SetWindow(reinterpret_cast(window)); + } + #endif + #ifdef CPPWINRT_VERSION + void __cdecl SetWindow(winrt::Windows::UI::Core::CoreWindow window) + { + // See https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/interop-winrt-abi + SetWindow(reinterpret_cast(winrt::get_abi(window))); + } + #endif + + static void __cdecl SetDpi(float dpi); + #elif defined(WM_USER) + void __cdecl SetWindow(HWND window); + static void __cdecl ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam); + + #ifdef _GAMING_XBOX + static void __cdecl SetResolution(float scale); + #endif + #endif + + // Singleton + static Mouse& __cdecl Get(); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif diff --git a/enginecustom/include/Inc/PostProcess.h b/enginecustom/include/Inc/PostProcess.h new file mode 100644 index 0000000..0e91f4a --- /dev/null +++ b/enginecustom/include/Inc/PostProcess.h @@ -0,0 +1,227 @@ +//-------------------------------------------------------------------------------------- +// File: PostProcess.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +#include +#include + +#include + + +namespace DirectX +{ + inline namespace DX11 + { + //------------------------------------------------------------------------------ + // Abstract interface representing a post-process pass + class IPostProcess + { + public: + virtual ~IPostProcess() = default; + + IPostProcess(const IPostProcess&) = delete; + IPostProcess& operator=(const IPostProcess&) = delete; + + virtual void __cdecl Process(_In_ ID3D11DeviceContext* deviceContext, + _In_ std::function setCustomState = nullptr) = 0; + + protected: + IPostProcess() = default; + IPostProcess(IPostProcess&&) = default; + IPostProcess& operator=(IPostProcess&&) = default; + }; + + + //------------------------------------------------------------------------------ + // Basic post-process + class BasicPostProcess : public IPostProcess + { + public: + enum Effect : unsigned int + { + Copy, + Monochrome, + Sepia, + DownScale_2x2, + DownScale_4x4, + GaussianBlur_5x5, + BloomExtract, + BloomBlur, + Effect_Max + }; + + explicit BasicPostProcess(_In_ ID3D11Device* device); + + BasicPostProcess(BasicPostProcess&&) noexcept; + BasicPostProcess& operator= (BasicPostProcess&&) noexcept; + + BasicPostProcess(BasicPostProcess const&) = delete; + BasicPostProcess& operator= (BasicPostProcess const&) = delete; + + ~BasicPostProcess() override; + + // IPostProcess methods. + void __cdecl Process( + _In_ ID3D11DeviceContext* deviceContext, + _In_ std::function setCustomState = nullptr) override; + + // Shader control + void __cdecl SetEffect(Effect fx); + + // Properties + void __cdecl SetSourceTexture(_In_opt_ ID3D11ShaderResourceView* value); + + // Sets multiplier for GaussianBlur_5x5 + void __cdecl SetGaussianParameter(float multiplier); + + // Sets parameters for BloomExtract + void __cdecl SetBloomExtractParameter(float threshold); + + // Sets parameters for BloomBlur + void __cdecl SetBloomBlurParameters(bool horizontal, float size, float brightness); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; + + + //------------------------------------------------------------------------------ + // Dual-texure post-process + class DualPostProcess : public IPostProcess + { + public: + enum Effect : unsigned int + { + Merge, + BloomCombine, + Effect_Max + }; + + explicit DualPostProcess(_In_ ID3D11Device* device); + + DualPostProcess(DualPostProcess&&) noexcept; + DualPostProcess& operator= (DualPostProcess&&) noexcept; + + DualPostProcess(DualPostProcess const&) = delete; + DualPostProcess& operator= (DualPostProcess const&) = delete; + + ~DualPostProcess() override; + + // IPostProcess methods. + void __cdecl Process(_In_ ID3D11DeviceContext* deviceContext, + _In_ std::function setCustomState = nullptr) override; + + // Shader control + void __cdecl SetEffect(Effect fx); + + // Properties + void __cdecl SetSourceTexture(_In_opt_ ID3D11ShaderResourceView* value); + void __cdecl SetSourceTexture2(_In_opt_ ID3D11ShaderResourceView* value); + + // Sets parameters for Merge + void __cdecl SetMergeParameters(float weight1, float weight2); + + // Sets parameters for BloomCombine + void __cdecl SetBloomCombineParameters(float bloom, float base, float bloomSaturation, float baseSaturation); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; + + + //------------------------------------------------------------------------------ + // Tone-map post-process + class ToneMapPostProcess : public IPostProcess + { + public: + // Tone-mapping operator + enum Operator : unsigned int + { + None, // Pass-through + Saturate, // Clamp [0,1] + Reinhard, // x/(1+x) + ACESFilmic, + Operator_Max + }; + + // Electro-Optical Transfer Function (EOTF) + enum TransferFunction : unsigned int + { + Linear, // Pass-through + SRGB, // sRGB (Rec.709 and approximate sRGB display curve) + ST2084, // HDR10 (Rec.2020 color primaries and ST.2084 display curve) + TransferFunction_Max + }; + + // Color Rotation Transform for HDR10 + enum ColorPrimaryRotation : unsigned int + { + HDTV_to_UHDTV, // Rec.709 to Rec.2020 + DCI_P3_D65_to_UHDTV, // DCI-P3-D65 (a.k.a Display P3 or P3D65) to Rec.2020 + HDTV_to_DCI_P3_D65, // Rec.709 to DCI-P3-D65 (a.k.a Display P3 or P3D65) + }; + + explicit ToneMapPostProcess(_In_ ID3D11Device* device); + + ToneMapPostProcess(ToneMapPostProcess&&) noexcept; + ToneMapPostProcess& operator= (ToneMapPostProcess&&) noexcept; + + ToneMapPostProcess(ToneMapPostProcess const&) = delete; + ToneMapPostProcess& operator= (ToneMapPostProcess const&) = delete; + + ~ToneMapPostProcess() override; + + // IPostProcess methods. + void __cdecl Process(_In_ ID3D11DeviceContext* deviceContext, + _In_ std::function setCustomState = nullptr) override; + + // Shader control + void __cdecl SetOperator(Operator op); + + void __cdecl SetTransferFunction(TransferFunction func); + + #if defined(_XBOX_ONE) && defined(_TITLE) + // Uses Multiple Render Targets to generate both HDR10 and GameDVR SDR signals + void __cdecl SetMRTOutput(bool value = true); + #endif + + // Properties + void __cdecl SetHDRSourceTexture(_In_opt_ ID3D11ShaderResourceView* value); + + // Sets the Color Rotation Transform for HDR10 signal output + void __cdecl SetColorRotation(ColorPrimaryRotation value); + void __cdecl SetColorRotation(CXMMATRIX value); + + // Sets exposure value for LDR tonemap operators + void __cdecl SetExposure(float exposureValue); + + // Sets ST.2084 parameter for how bright white should be in nits + void __cdecl SetST2084Parameter(float paperWhiteNits); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; + } +} diff --git a/enginecustom/include/Inc/PrimitiveBatch.h b/enginecustom/include/Inc/PrimitiveBatch.h new file mode 100644 index 0000000..9a51049 --- /dev/null +++ b/enginecustom/include/Inc/PrimitiveBatch.h @@ -0,0 +1,140 @@ +//-------------------------------------------------------------------------------------- +// File: PrimitiveBatch.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +#include +#include +#include +#include +#include + + +namespace DirectX +{ + inline namespace DX11 + { + namespace Private + { + // Base class, not to be used directly: clients should access this via the derived PrimitiveBatch. + class PrimitiveBatchBase + { + protected: + PrimitiveBatchBase(_In_ ID3D11DeviceContext* deviceContext, size_t maxIndices, size_t maxVertices, size_t vertexSize); + + PrimitiveBatchBase(PrimitiveBatchBase&&) noexcept; + PrimitiveBatchBase& operator= (PrimitiveBatchBase&&) noexcept; + + PrimitiveBatchBase(PrimitiveBatchBase const&) = delete; + PrimitiveBatchBase& operator= (PrimitiveBatchBase const&) = delete; + + virtual ~PrimitiveBatchBase(); + + public: + // Begin/End a batch of primitive drawing operations. + void __cdecl Begin(); + void __cdecl End(); + + protected: + // Internal, untyped drawing method. + void __cdecl Draw(D3D11_PRIMITIVE_TOPOLOGY topology, bool isIndexed, _In_opt_count_(indexCount) uint16_t const* indices, size_t indexCount, size_t vertexCount, _Out_ void** pMappedVertices); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; + } + + // Template makes the API typesafe, eg. PrimitiveBatch. + template + class PrimitiveBatch : public Private::PrimitiveBatchBase + { + static constexpr size_t DefaultBatchSize = 2048; + + public: + explicit PrimitiveBatch(_In_ ID3D11DeviceContext* deviceContext, size_t maxIndices = DefaultBatchSize * 3, size_t maxVertices = DefaultBatchSize) + : PrimitiveBatchBase(deviceContext, maxIndices, maxVertices, sizeof(TVertex)) + { + } + + PrimitiveBatch(PrimitiveBatch&&) = default; + PrimitiveBatch& operator= (PrimitiveBatch&&) = default; + + PrimitiveBatch(PrimitiveBatch const&) = delete; + PrimitiveBatch& operator= (PrimitiveBatch const&) = delete; + + // Similar to the D3D9 API DrawPrimitiveUP. + void Draw(D3D11_PRIMITIVE_TOPOLOGY topology, _In_reads_(vertexCount) TVertex const* vertices, size_t vertexCount) + { + void* mappedVertices; + + PrimitiveBatchBase::Draw(topology, false, nullptr, 0, vertexCount, &mappedVertices); + + memcpy(mappedVertices, vertices, vertexCount * sizeof(TVertex)); + } + + + // Similar to the D3D9 API DrawIndexedPrimitiveUP. + void DrawIndexed(D3D11_PRIMITIVE_TOPOLOGY topology, _In_reads_(indexCount) uint16_t const* indices, size_t indexCount, _In_reads_(vertexCount) TVertex const* vertices, size_t vertexCount) + { + void* mappedVertices; + + PrimitiveBatchBase::Draw(topology, true, indices, indexCount, vertexCount, &mappedVertices); + + memcpy(mappedVertices, vertices, vertexCount * sizeof(TVertex)); + } + + + void DrawLine(TVertex const& v1, TVertex const& v2) + { + TVertex* mappedVertices; + + PrimitiveBatchBase::Draw(D3D11_PRIMITIVE_TOPOLOGY_LINELIST, false, nullptr, 0, 2, reinterpret_cast(&mappedVertices)); + + mappedVertices[0] = v1; + mappedVertices[1] = v2; + } + + + void DrawTriangle(TVertex const& v1, TVertex const& v2, TVertex const& v3) + { + TVertex* mappedVertices; + + PrimitiveBatchBase::Draw(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, false, nullptr, 0, 3, reinterpret_cast(&mappedVertices)); + + mappedVertices[0] = v1; + mappedVertices[1] = v2; + mappedVertices[2] = v3; + } + + + void DrawQuad(TVertex const& v1, TVertex const& v2, TVertex const& v3, TVertex const& v4) + { + static const uint16_t quadIndices[] = { 0, 1, 2, 0, 2, 3 }; + + TVertex* mappedVertices; + + PrimitiveBatchBase::Draw(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, true, quadIndices, 6, 4, reinterpret_cast(&mappedVertices)); + + mappedVertices[0] = v1; + mappedVertices[1] = v2; + mappedVertices[2] = v3; + mappedVertices[3] = v4; + } + }; + } +} diff --git a/enginecustom/include/Inc/ScreenGrab.h b/enginecustom/include/Inc/ScreenGrab.h new file mode 100644 index 0000000..106d2e0 --- /dev/null +++ b/enginecustom/include/Inc/ScreenGrab.h @@ -0,0 +1,54 @@ +//-------------------------------------------------------------------------------------- +// File: ScreenGrab.h +// +// Function for capturing a 2D texture and saving it to a file (aka a 'screenshot' +// when used on a Direct3D Render Target). +// +// Note these functions are useful as a light-weight runtime screen grabber. For +// full-featured texture capture, DDS writer, and texture processing pipeline, +// see the 'Texconv' sample and the 'DirectXTex' library. +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248926 +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +#include + +#if defined(NTDDI_WIN10_FE) || defined(__MINGW32__) +#include +#else +#include +#endif + +#ifdef _MSC_VER +#pragma comment(lib,"uuid.lib") +#endif + + +namespace DirectX +{ + HRESULT __cdecl SaveDDSTextureToFile( + _In_ ID3D11DeviceContext* pContext, + _In_ ID3D11Resource* pSource, + _In_z_ const wchar_t* fileName) noexcept; + + HRESULT __cdecl SaveWICTextureToFile( + _In_ ID3D11DeviceContext* pContext, + _In_ ID3D11Resource* pSource, + _In_ REFGUID guidContainerFormat, + _In_z_ const wchar_t* fileName, + _In_opt_ const GUID* targetFormat = nullptr, + _In_ std::function setCustomProps = nullptr, + _In_ bool forceSRGB = false); +} diff --git a/enginecustom/include/Inc/SimpleMath.h b/enginecustom/include/Inc/SimpleMath.h new file mode 100644 index 0000000..37381bb --- /dev/null +++ b/enginecustom/include/Inc/SimpleMath.h @@ -0,0 +1,1142 @@ +//------------------------------------------------------------------------------------- +// SimpleMath.h -- Simplified C++ Math wrapper for DirectXMath +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +// http://go.microsoft.com/fwlink/?LinkID=615561 +//------------------------------------------------------------------------------------- + +#pragma once + +#if (defined(_WIN32) || defined(WINAPI_FAMILY)) && !(defined(_XBOX_ONE) && defined(_TITLE)) && !defined(_GAMING_XBOX) +#include +#endif + +#include +#include +#include +#include + +#if (__cplusplus >= 202002L) +#include +#endif + +#include +#include +#include + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wfloat-equal" +#pragma clang diagnostic ignored "-Wunknown-warning-option" +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" +#endif + + +namespace DirectX +{ + namespace SimpleMath + { + struct Vector2; + struct Vector4; + struct Matrix; + struct Quaternion; + struct Plane; + + //------------------------------------------------------------------------------ + // 2D rectangle + struct Rectangle + { + long x; + long y; + long width; + long height; + + // Creators + Rectangle() noexcept : x(0), y(0), width(0), height(0) {} + constexpr Rectangle(long ix, long iy, long iw, long ih) noexcept : x(ix), y(iy), width(iw), height(ih) {} + explicit Rectangle(const RECT& rct) noexcept : x(rct.left), y(rct.top), width(rct.right - rct.left), height(rct.bottom - rct.top) {} + + Rectangle(const Rectangle&) = default; + Rectangle& operator=(const Rectangle&) = default; + + Rectangle(Rectangle&&) = default; + Rectangle& operator=(Rectangle&&) = default; + + operator RECT() noexcept { RECT rct; rct.left = x; rct.top = y; rct.right = (x + width); rct.bottom = (y + height); return rct; } + #ifdef __cplusplus_winrt + operator Windows::Foundation::Rect() noexcept { return Windows::Foundation::Rect(float(x), float(y), float(width), float(height)); } + #endif + + // Comparison operators + #if (__cplusplus >= 202002L) + bool operator == (const Rectangle&) const = default; + auto operator <=> (const Rectangle&) const = default; + #else + bool operator == (const Rectangle& r) const noexcept { return (x == r.x) && (y == r.y) && (width == r.width) && (height == r.height); } + bool operator != (const Rectangle& r) const noexcept { return (x != r.x) || (y != r.y) || (width != r.width) || (height != r.height); } + #endif + bool operator == (const RECT& rct) const noexcept { return (x == rct.left) && (y == rct.top) && (width == (rct.right - rct.left)) && (height == (rct.bottom - rct.top)); } + bool operator != (const RECT& rct) const noexcept { return (x != rct.left) || (y != rct.top) || (width != (rct.right - rct.left)) || (height != (rct.bottom - rct.top)); } + + // Assignment operators + Rectangle& operator=(_In_ const RECT& rct) noexcept { x = rct.left; y = rct.top; width = (rct.right - rct.left); height = (rct.bottom - rct.top); return *this; } + + // Rectangle operations + Vector2 Location() const noexcept; + Vector2 Center() const noexcept; + + bool IsEmpty() const noexcept { return (width == 0 && height == 0 && x == 0 && y == 0); } + + bool Contains(long ix, long iy) const noexcept { return (x <= ix) && (ix < (x + width)) && (y <= iy) && (iy < (y + height)); } + bool Contains(const Vector2& point) const noexcept; + bool Contains(const Rectangle& r) const noexcept { return (x <= r.x) && ((r.x + r.width) <= (x + width)) && (y <= r.y) && ((r.y + r.height) <= (y + height)); } + bool Contains(const RECT& rct) const noexcept { return (x <= rct.left) && (rct.right <= (x + width)) && (y <= rct.top) && (rct.bottom <= (y + height)); } + + void Inflate(long horizAmount, long vertAmount) noexcept; + + bool Intersects(const Rectangle& r) const noexcept { return (r.x < (x + width)) && (x < (r.x + r.width)) && (r.y < (y + height)) && (y < (r.y + r.height)); } + bool Intersects(const RECT& rct) const noexcept { return (rct.left < (x + width)) && (x < rct.right) && (rct.top < (y + height)) && (y < rct.bottom); } + + void Offset(long ox, long oy) noexcept { x += ox; y += oy; } + + // Static functions + static Rectangle Intersect(const Rectangle& ra, const Rectangle& rb) noexcept; + static RECT Intersect(const RECT& rcta, const RECT& rctb) noexcept; + + static Rectangle Union(const Rectangle& ra, const Rectangle& rb) noexcept; + static RECT Union(const RECT& rcta, const RECT& rctb) noexcept; + }; + + //------------------------------------------------------------------------------ + // 2D vector + struct Vector2 : public XMFLOAT2 + { + Vector2() noexcept : XMFLOAT2(0.f, 0.f) {} + constexpr explicit Vector2(float ix) noexcept : XMFLOAT2(ix, ix) {} + constexpr Vector2(float ix, float iy) noexcept : XMFLOAT2(ix, iy) {} + explicit Vector2(_In_reads_(2) const float *pArray) noexcept : XMFLOAT2(pArray) {} + Vector2(FXMVECTOR V) noexcept { XMStoreFloat2(this, V); } + Vector2(const XMFLOAT2& V) noexcept { this->x = V.x; this->y = V.y; } + explicit Vector2(const XMVECTORF32& F) noexcept { this->x = F.f[0]; this->y = F.f[1]; } + + Vector2(const Vector2&) = default; + Vector2& operator=(const Vector2&) = default; + + Vector2(Vector2&&) = default; + Vector2& operator=(Vector2&&) = default; + + operator XMVECTOR() const noexcept { return XMLoadFloat2(this); } + + // Comparison operators + bool operator == (const Vector2& V) const noexcept; + bool operator != (const Vector2& V) const noexcept; + + // Assignment operators + Vector2& operator= (const XMVECTORF32& F) noexcept { x = F.f[0]; y = F.f[1]; return *this; } + Vector2& operator+= (const Vector2& V) noexcept; + Vector2& operator-= (const Vector2& V) noexcept; + Vector2& operator*= (const Vector2& V) noexcept; + Vector2& operator*= (float S) noexcept; + Vector2& operator/= (float S) noexcept; + + // Unary operators + Vector2 operator+ () const noexcept { return *this; } + Vector2 operator- () const noexcept { return Vector2(-x, -y); } + + // Vector operations + bool InBounds(const Vector2& Bounds) const noexcept; + + float Length() const noexcept; + float LengthSquared() const noexcept; + + float Dot(const Vector2& V) const noexcept; + void Cross(const Vector2& V, Vector2& result) const noexcept; + Vector2 Cross(const Vector2& V) const noexcept; + + void Normalize() noexcept; + void Normalize(Vector2& result) const noexcept; + + void Clamp(const Vector2& vmin, const Vector2& vmax) noexcept; + void Clamp(const Vector2& vmin, const Vector2& vmax, Vector2& result) const noexcept; + + // Static functions + static float Distance(const Vector2& v1, const Vector2& v2) noexcept; + static float DistanceSquared(const Vector2& v1, const Vector2& v2) noexcept; + + static void Min(const Vector2& v1, const Vector2& v2, Vector2& result) noexcept; + static Vector2 Min(const Vector2& v1, const Vector2& v2) noexcept; + + static void Max(const Vector2& v1, const Vector2& v2, Vector2& result) noexcept; + static Vector2 Max(const Vector2& v1, const Vector2& v2) noexcept; + + static void Lerp(const Vector2& v1, const Vector2& v2, float t, Vector2& result) noexcept; + static Vector2 Lerp(const Vector2& v1, const Vector2& v2, float t) noexcept; + + static void SmoothStep(const Vector2& v1, const Vector2& v2, float t, Vector2& result) noexcept; + static Vector2 SmoothStep(const Vector2& v1, const Vector2& v2, float t) noexcept; + + static void Barycentric(const Vector2& v1, const Vector2& v2, const Vector2& v3, float f, float g, Vector2& result) noexcept; + static Vector2 Barycentric(const Vector2& v1, const Vector2& v2, const Vector2& v3, float f, float g) noexcept; + + static void CatmullRom(const Vector2& v1, const Vector2& v2, const Vector2& v3, const Vector2& v4, float t, Vector2& result) noexcept; + static Vector2 CatmullRom(const Vector2& v1, const Vector2& v2, const Vector2& v3, const Vector2& v4, float t) noexcept; + + static void Hermite(const Vector2& v1, const Vector2& t1, const Vector2& v2, const Vector2& t2, float t, Vector2& result) noexcept; + static Vector2 Hermite(const Vector2& v1, const Vector2& t1, const Vector2& v2, const Vector2& t2, float t) noexcept; + + static void Reflect(const Vector2& ivec, const Vector2& nvec, Vector2& result) noexcept; + static Vector2 Reflect(const Vector2& ivec, const Vector2& nvec) noexcept; + + static void Refract(const Vector2& ivec, const Vector2& nvec, float refractionIndex, Vector2& result) noexcept; + static Vector2 Refract(const Vector2& ivec, const Vector2& nvec, float refractionIndex) noexcept; + + static void Transform(const Vector2& v, const Quaternion& quat, Vector2& result) noexcept; + static Vector2 Transform(const Vector2& v, const Quaternion& quat) noexcept; + + static void Transform(const Vector2& v, const Matrix& m, Vector2& result) noexcept; + static Vector2 Transform(const Vector2& v, const Matrix& m) noexcept; + static void Transform(_In_reads_(count) const Vector2* varray, size_t count, const Matrix& m, _Out_writes_(count) Vector2* resultArray) noexcept; + + static void Transform(const Vector2& v, const Matrix& m, Vector4& result) noexcept; + static void Transform(_In_reads_(count) const Vector2* varray, size_t count, const Matrix& m, _Out_writes_(count) Vector4* resultArray) noexcept; + + static void TransformNormal(const Vector2& v, const Matrix& m, Vector2& result) noexcept; + static Vector2 TransformNormal(const Vector2& v, const Matrix& m) noexcept; + static void TransformNormal(_In_reads_(count) const Vector2* varray, size_t count, const Matrix& m, _Out_writes_(count) Vector2* resultArray) noexcept; + + // Constants + static const Vector2 Zero; + static const Vector2 One; + static const Vector2 UnitX; + static const Vector2 UnitY; + }; + + // Binary operators + Vector2 operator+ (const Vector2& V1, const Vector2& V2) noexcept; + Vector2 operator- (const Vector2& V1, const Vector2& V2) noexcept; + Vector2 operator* (const Vector2& V1, const Vector2& V2) noexcept; + Vector2 operator* (const Vector2& V, float S) noexcept; + Vector2 operator/ (const Vector2& V1, const Vector2& V2) noexcept; + Vector2 operator/ (const Vector2& V, float S) noexcept; + Vector2 operator* (float S, const Vector2& V) noexcept; + + //------------------------------------------------------------------------------ + // 3D vector + struct Vector3 : public XMFLOAT3 + { + Vector3() noexcept : XMFLOAT3(0.f, 0.f, 0.f) {} + constexpr explicit Vector3(float ix) noexcept : XMFLOAT3(ix, ix, ix) {} + constexpr Vector3(float ix, float iy, float iz) noexcept : XMFLOAT3(ix, iy, iz) {} + explicit Vector3(_In_reads_(3) const float *pArray) noexcept : XMFLOAT3(pArray) {} + Vector3(FXMVECTOR V) noexcept { XMStoreFloat3(this, V); } + Vector3(const XMFLOAT3& V) noexcept { this->x = V.x; this->y = V.y; this->z = V.z; } + explicit Vector3(const XMVECTORF32& F) noexcept { this->x = F.f[0]; this->y = F.f[1]; this->z = F.f[2]; } + + Vector3(const Vector3&) = default; + Vector3& operator=(const Vector3&) = default; + + Vector3(Vector3&&) = default; + Vector3& operator=(Vector3&&) = default; + + operator XMVECTOR() const noexcept { return XMLoadFloat3(this); } + + // Comparison operators + bool operator == (const Vector3& V) const noexcept; + bool operator != (const Vector3& V) const noexcept; + + // Assignment operators + Vector3& operator= (const XMVECTORF32& F) noexcept { x = F.f[0]; y = F.f[1]; z = F.f[2]; return *this; } + Vector3& operator+= (const Vector3& V) noexcept; + Vector3& operator-= (const Vector3& V) noexcept; + Vector3& operator*= (const Vector3& V) noexcept; + Vector3& operator*= (float S) noexcept; + Vector3& operator/= (float S) noexcept; + + // Unary operators + Vector3 operator+ () const noexcept { return *this; } + Vector3 operator- () const noexcept; + + // Vector operations + bool InBounds(const Vector3& Bounds) const noexcept; + + float Length() const noexcept; + float LengthSquared() const noexcept; + + float Dot(const Vector3& V) const noexcept; + void Cross(const Vector3& V, Vector3& result) const noexcept; + Vector3 Cross(const Vector3& V) const noexcept; + + void Normalize() noexcept; + void Normalize(Vector3& result) const noexcept; + + void Clamp(const Vector3& vmin, const Vector3& vmax) noexcept; + void Clamp(const Vector3& vmin, const Vector3& vmax, Vector3& result) const noexcept; + + // Static functions + static float Distance(const Vector3& v1, const Vector3& v2) noexcept; + static float DistanceSquared(const Vector3& v1, const Vector3& v2) noexcept; + + static void Min(const Vector3& v1, const Vector3& v2, Vector3& result) noexcept; + static Vector3 Min(const Vector3& v1, const Vector3& v2) noexcept; + + static void Max(const Vector3& v1, const Vector3& v2, Vector3& result) noexcept; + static Vector3 Max(const Vector3& v1, const Vector3& v2) noexcept; + + static void Lerp(const Vector3& v1, const Vector3& v2, float t, Vector3& result) noexcept; + static Vector3 Lerp(const Vector3& v1, const Vector3& v2, float t) noexcept; + + static void SmoothStep(const Vector3& v1, const Vector3& v2, float t, Vector3& result) noexcept; + static Vector3 SmoothStep(const Vector3& v1, const Vector3& v2, float t) noexcept; + + static void Barycentric(const Vector3& v1, const Vector3& v2, const Vector3& v3, float f, float g, Vector3& result) noexcept; + static Vector3 Barycentric(const Vector3& v1, const Vector3& v2, const Vector3& v3, float f, float g) noexcept; + + static void CatmullRom(const Vector3& v1, const Vector3& v2, const Vector3& v3, const Vector3& v4, float t, Vector3& result) noexcept; + static Vector3 CatmullRom(const Vector3& v1, const Vector3& v2, const Vector3& v3, const Vector3& v4, float t) noexcept; + + static void Hermite(const Vector3& v1, const Vector3& t1, const Vector3& v2, const Vector3& t2, float t, Vector3& result) noexcept; + static Vector3 Hermite(const Vector3& v1, const Vector3& t1, const Vector3& v2, const Vector3& t2, float t) noexcept; + + static void Reflect(const Vector3& ivec, const Vector3& nvec, Vector3& result) noexcept; + static Vector3 Reflect(const Vector3& ivec, const Vector3& nvec) noexcept; + + static void Refract(const Vector3& ivec, const Vector3& nvec, float refractionIndex, Vector3& result) noexcept; + static Vector3 Refract(const Vector3& ivec, const Vector3& nvec, float refractionIndex) noexcept; + + static void Transform(const Vector3& v, const Quaternion& quat, Vector3& result) noexcept; + static Vector3 Transform(const Vector3& v, const Quaternion& quat) noexcept; + + static void Transform(const Vector3& v, const Matrix& m, Vector3& result) noexcept; + static Vector3 Transform(const Vector3& v, const Matrix& m) noexcept; + static void Transform(_In_reads_(count) const Vector3* varray, size_t count, const Matrix& m, _Out_writes_(count) Vector3* resultArray) noexcept; + + static void Transform(const Vector3& v, const Matrix& m, Vector4& result) noexcept; + static void Transform(_In_reads_(count) const Vector3* varray, size_t count, const Matrix& m, _Out_writes_(count) Vector4* resultArray) noexcept; + + static void TransformNormal(const Vector3& v, const Matrix& m, Vector3& result) noexcept; + static Vector3 TransformNormal(const Vector3& v, const Matrix& m) noexcept; + static void TransformNormal(_In_reads_(count) const Vector3* varray, size_t count, const Matrix& m, _Out_writes_(count) Vector3* resultArray) noexcept; + + // Constants + static const Vector3 Zero; + static const Vector3 One; + static const Vector3 UnitX; + static const Vector3 UnitY; + static const Vector3 UnitZ; + static const Vector3 Up; + static const Vector3 Down; + static const Vector3 Right; + static const Vector3 Left; + static const Vector3 Forward; + static const Vector3 Backward; + }; + + // Binary operators + Vector3 operator+ (const Vector3& V1, const Vector3& V2) noexcept; + Vector3 operator- (const Vector3& V1, const Vector3& V2) noexcept; + Vector3 operator* (const Vector3& V1, const Vector3& V2) noexcept; + Vector3 operator* (const Vector3& V, float S) noexcept; + Vector3 operator/ (const Vector3& V1, const Vector3& V2) noexcept; + Vector3 operator/ (const Vector3& V, float S) noexcept; + Vector3 operator* (float S, const Vector3& V) noexcept; + + //------------------------------------------------------------------------------ + // 4D vector + struct Vector4 : public XMFLOAT4 + { + Vector4() noexcept : XMFLOAT4(0.f, 0.f, 0.f, 0.f) {} + constexpr explicit Vector4(float ix) noexcept : XMFLOAT4(ix, ix, ix, ix) {} + constexpr Vector4(float ix, float iy, float iz, float iw) noexcept : XMFLOAT4(ix, iy, iz, iw) {} + explicit Vector4(_In_reads_(4) const float *pArray) noexcept : XMFLOAT4(pArray) {} + Vector4(FXMVECTOR V) noexcept { XMStoreFloat4(this, V); } + Vector4(const XMFLOAT4& V) noexcept { this->x = V.x; this->y = V.y; this->z = V.z; this->w = V.w; } + explicit Vector4(const XMVECTORF32& F) noexcept { this->x = F.f[0]; this->y = F.f[1]; this->z = F.f[2]; this->w = F.f[3]; } + + Vector4(const Vector4&) = default; + Vector4& operator=(const Vector4&) = default; + + Vector4(Vector4&&) = default; + Vector4& operator=(Vector4&&) = default; + + operator XMVECTOR() const noexcept { return XMLoadFloat4(this); } + + // Comparison operators + bool operator == (const Vector4& V) const noexcept; + bool operator != (const Vector4& V) const noexcept; + + // Assignment operators + Vector4& operator= (const XMVECTORF32& F) noexcept { x = F.f[0]; y = F.f[1]; z = F.f[2]; w = F.f[3]; return *this; } + Vector4& operator+= (const Vector4& V) noexcept; + Vector4& operator-= (const Vector4& V) noexcept; + Vector4& operator*= (const Vector4& V) noexcept; + Vector4& operator*= (float S) noexcept; + Vector4& operator/= (float S) noexcept; + + // Unary operators + Vector4 operator+ () const noexcept { return *this; } + Vector4 operator- () const noexcept; + + // Vector operations + bool InBounds(const Vector4& Bounds) const noexcept; + + float Length() const noexcept; + float LengthSquared() const noexcept; + + float Dot(const Vector4& V) const noexcept; + void Cross(const Vector4& v1, const Vector4& v2, Vector4& result) const noexcept; + Vector4 Cross(const Vector4& v1, const Vector4& v2) const noexcept; + + void Normalize() noexcept; + void Normalize(Vector4& result) const noexcept; + + void Clamp(const Vector4& vmin, const Vector4& vmax) noexcept; + void Clamp(const Vector4& vmin, const Vector4& vmax, Vector4& result) const noexcept; + + // Static functions + static float Distance(const Vector4& v1, const Vector4& v2) noexcept; + static float DistanceSquared(const Vector4& v1, const Vector4& v2) noexcept; + + static void Min(const Vector4& v1, const Vector4& v2, Vector4& result) noexcept; + static Vector4 Min(const Vector4& v1, const Vector4& v2) noexcept; + + static void Max(const Vector4& v1, const Vector4& v2, Vector4& result) noexcept; + static Vector4 Max(const Vector4& v1, const Vector4& v2) noexcept; + + static void Lerp(const Vector4& v1, const Vector4& v2, float t, Vector4& result) noexcept; + static Vector4 Lerp(const Vector4& v1, const Vector4& v2, float t) noexcept; + + static void SmoothStep(const Vector4& v1, const Vector4& v2, float t, Vector4& result) noexcept; + static Vector4 SmoothStep(const Vector4& v1, const Vector4& v2, float t) noexcept; + + static void Barycentric(const Vector4& v1, const Vector4& v2, const Vector4& v3, float f, float g, Vector4& result) noexcept; + static Vector4 Barycentric(const Vector4& v1, const Vector4& v2, const Vector4& v3, float f, float g) noexcept; + + static void CatmullRom(const Vector4& v1, const Vector4& v2, const Vector4& v3, const Vector4& v4, float t, Vector4& result) noexcept; + static Vector4 CatmullRom(const Vector4& v1, const Vector4& v2, const Vector4& v3, const Vector4& v4, float t) noexcept; + + static void Hermite(const Vector4& v1, const Vector4& t1, const Vector4& v2, const Vector4& t2, float t, Vector4& result) noexcept; + static Vector4 Hermite(const Vector4& v1, const Vector4& t1, const Vector4& v2, const Vector4& t2, float t) noexcept; + + static void Reflect(const Vector4& ivec, const Vector4& nvec, Vector4& result) noexcept; + static Vector4 Reflect(const Vector4& ivec, const Vector4& nvec) noexcept; + + static void Refract(const Vector4& ivec, const Vector4& nvec, float refractionIndex, Vector4& result) noexcept; + static Vector4 Refract(const Vector4& ivec, const Vector4& nvec, float refractionIndex) noexcept; + + static void Transform(const Vector2& v, const Quaternion& quat, Vector4& result) noexcept; + static Vector4 Transform(const Vector2& v, const Quaternion& quat) noexcept; + + static void Transform(const Vector3& v, const Quaternion& quat, Vector4& result) noexcept; + static Vector4 Transform(const Vector3& v, const Quaternion& quat) noexcept; + + static void Transform(const Vector4& v, const Quaternion& quat, Vector4& result) noexcept; + static Vector4 Transform(const Vector4& v, const Quaternion& quat) noexcept; + + static void Transform(const Vector4& v, const Matrix& m, Vector4& result) noexcept; + static Vector4 Transform(const Vector4& v, const Matrix& m) noexcept; + static void Transform(_In_reads_(count) const Vector4* varray, size_t count, const Matrix& m, _Out_writes_(count) Vector4* resultArray) noexcept; + + // Constants + static const Vector4 Zero; + static const Vector4 One; + static const Vector4 UnitX; + static const Vector4 UnitY; + static const Vector4 UnitZ; + static const Vector4 UnitW; + }; + + // Binary operators + Vector4 operator+ (const Vector4& V1, const Vector4& V2) noexcept; + Vector4 operator- (const Vector4& V1, const Vector4& V2) noexcept; + Vector4 operator* (const Vector4& V1, const Vector4& V2) noexcept; + Vector4 operator* (const Vector4& V, float S) noexcept; + Vector4 operator/ (const Vector4& V1, const Vector4& V2) noexcept; + Vector4 operator/ (const Vector4& V, float S) noexcept; + Vector4 operator* (float S, const Vector4& V) noexcept; + + //------------------------------------------------------------------------------ + // 4x4 Matrix (assumes right-handed cooordinates) + struct Matrix : public XMFLOAT4X4 + { + Matrix() noexcept + : XMFLOAT4X4(1.f, 0, 0, 0, + 0, 1.f, 0, 0, + 0, 0, 1.f, 0, + 0, 0, 0, 1.f) + { + } + constexpr Matrix(float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33) noexcept + : XMFLOAT4X4(m00, m01, m02, m03, + m10, m11, m12, m13, + m20, m21, m22, m23, + m30, m31, m32, m33) + { + } + explicit Matrix(const Vector3& r0, const Vector3& r1, const Vector3& r2) noexcept + : XMFLOAT4X4(r0.x, r0.y, r0.z, 0, + r1.x, r1.y, r1.z, 0, + r2.x, r2.y, r2.z, 0, + 0, 0, 0, 1.f) + { + } + explicit Matrix(const Vector4& r0, const Vector4& r1, const Vector4& r2, const Vector4& r3) noexcept + : XMFLOAT4X4(r0.x, r0.y, r0.z, r0.w, + r1.x, r1.y, r1.z, r1.w, + r2.x, r2.y, r2.z, r2.w, + r3.x, r3.y, r3.z, r3.w) + { + } + Matrix(const XMFLOAT4X4& M) noexcept { memcpy(this, &M, sizeof(XMFLOAT4X4)); } + Matrix(const XMFLOAT3X3& M) noexcept; + Matrix(const XMFLOAT4X3& M) noexcept; + + explicit Matrix(_In_reads_(16) const float *pArray) noexcept : XMFLOAT4X4(pArray) {} + Matrix(CXMMATRIX M) noexcept { XMStoreFloat4x4(this, M); } + + Matrix(const Matrix&) = default; + Matrix& operator=(const Matrix&) = default; + + Matrix(Matrix&&) = default; + Matrix& operator=(Matrix&&) = default; + + operator XMMATRIX() const noexcept { return XMLoadFloat4x4(this); } + + // Comparison operators + bool operator == (const Matrix& M) const noexcept; + bool operator != (const Matrix& M) const noexcept; + + // Assignment operators + Matrix& operator= (const XMFLOAT3X3& M) noexcept; + Matrix& operator= (const XMFLOAT4X3& M) noexcept; + Matrix& operator+= (const Matrix& M) noexcept; + Matrix& operator-= (const Matrix& M) noexcept; + Matrix& operator*= (const Matrix& M) noexcept; + Matrix& operator*= (float S) noexcept; + Matrix& operator/= (float S) noexcept; + + Matrix& operator/= (const Matrix& M) noexcept; + // Element-wise divide + + // Unary operators + Matrix operator+ () const noexcept { return *this; } + Matrix operator- () const noexcept; + + // Properties + Vector3 Up() const noexcept { return Vector3(_21, _22, _23); } + void Up(const Vector3& v) noexcept { _21 = v.x; _22 = v.y; _23 = v.z; } + + Vector3 Down() const noexcept { return Vector3(-_21, -_22, -_23); } + void Down(const Vector3& v) noexcept { _21 = -v.x; _22 = -v.y; _23 = -v.z; } + + Vector3 Right() const noexcept { return Vector3(_11, _12, _13); } + void Right(const Vector3& v) noexcept { _11 = v.x; _12 = v.y; _13 = v.z; } + + Vector3 Left() const noexcept { return Vector3(-_11, -_12, -_13); } + void Left(const Vector3& v) noexcept { _11 = -v.x; _12 = -v.y; _13 = -v.z; } + + Vector3 Forward() const noexcept { return Vector3(-_31, -_32, -_33); } + void Forward(const Vector3& v) noexcept { _31 = -v.x; _32 = -v.y; _33 = -v.z; } + + Vector3 Backward() const noexcept { return Vector3(_31, _32, _33); } + void Backward(const Vector3& v) noexcept { _31 = v.x; _32 = v.y; _33 = v.z; } + + Vector3 Translation() const noexcept { return Vector3(_41, _42, _43); } + void Translation(const Vector3& v) noexcept { _41 = v.x; _42 = v.y; _43 = v.z; } + + // Matrix operations + bool Decompose(Vector3& scale, Quaternion& rotation, Vector3& translation) noexcept; + + Matrix Transpose() const noexcept; + void Transpose(Matrix& result) const noexcept; + + Matrix Invert() const noexcept; + void Invert(Matrix& result) const noexcept; + + float Determinant() const noexcept; + + // Computes rotation about y-axis (y), then x-axis (x), then z-axis (z) + Vector3 ToEuler() const noexcept; + + // Static functions + static Matrix CreateBillboard( + const Vector3& object, const Vector3& cameraPosition, const Vector3& cameraUp, _In_opt_ const Vector3* cameraForward = nullptr) noexcept; + + static Matrix CreateConstrainedBillboard( + const Vector3& object, const Vector3& cameraPosition, const Vector3& rotateAxis, + _In_opt_ const Vector3* cameraForward = nullptr, _In_opt_ const Vector3* objectForward = nullptr) noexcept; + + static Matrix CreateTranslation(const Vector3& position) noexcept; + static Matrix CreateTranslation(float x, float y, float z) noexcept; + + static Matrix CreateScale(const Vector3& scales) noexcept; + static Matrix CreateScale(float xs, float ys, float zs) noexcept; + static Matrix CreateScale(float scale) noexcept; + + static Matrix CreateRotationX(float radians) noexcept; + static Matrix CreateRotationY(float radians) noexcept; + static Matrix CreateRotationZ(float radians) noexcept; + + static Matrix CreateFromAxisAngle(const Vector3& axis, float angle) noexcept; + + static Matrix CreatePerspectiveFieldOfView(float fov, float aspectRatio, float nearPlane, float farPlane) noexcept; + static Matrix CreatePerspective(float width, float height, float nearPlane, float farPlane) noexcept; + static Matrix CreatePerspectiveOffCenter(float left, float right, float bottom, float top, float nearPlane, float farPlane) noexcept; + static Matrix CreateOrthographic(float width, float height, float zNearPlane, float zFarPlane) noexcept; + static Matrix CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNearPlane, float zFarPlane) noexcept; + + static Matrix CreateLookAt(const Vector3& position, const Vector3& target, const Vector3& up) noexcept; + static Matrix CreateWorld(const Vector3& position, const Vector3& forward, const Vector3& up) noexcept; + + static Matrix CreateFromQuaternion(const Quaternion& quat) noexcept; + + // Rotates about y-axis (yaw), then x-axis (pitch), then z-axis (roll) + static Matrix CreateFromYawPitchRoll(float yaw, float pitch, float roll) noexcept; + + // Rotates about y-axis (angles.y), then x-axis (angles.x), then z-axis (angles.z) + static Matrix CreateFromYawPitchRoll(const Vector3& angles) noexcept; + + static Matrix CreateShadow(const Vector3& lightDir, const Plane& plane) noexcept; + + static Matrix CreateReflection(const Plane& plane) noexcept; + + static void Lerp(const Matrix& M1, const Matrix& M2, float t, Matrix& result) noexcept; + static Matrix Lerp(const Matrix& M1, const Matrix& M2, float t) noexcept; + + static void Transform(const Matrix& M, const Quaternion& rotation, Matrix& result) noexcept; + static Matrix Transform(const Matrix& M, const Quaternion& rotation) noexcept; + + // Constants + static const Matrix Identity; + }; + + // Binary operators + Matrix operator+ (const Matrix& M1, const Matrix& M2) noexcept; + Matrix operator- (const Matrix& M1, const Matrix& M2) noexcept; + Matrix operator* (const Matrix& M1, const Matrix& M2) noexcept; + Matrix operator* (const Matrix& M, float S) noexcept; + Matrix operator/ (const Matrix& M, float S) noexcept; + Matrix operator/ (const Matrix& M1, const Matrix& M2) noexcept; + // Element-wise divide + Matrix operator* (float S, const Matrix& M) noexcept; + + + //----------------------------------------------------------------------------- + // Plane + struct Plane : public XMFLOAT4 + { + Plane() noexcept : XMFLOAT4(0.f, 1.f, 0.f, 0.f) {} + constexpr Plane(float ix, float iy, float iz, float iw) noexcept : XMFLOAT4(ix, iy, iz, iw) {} + Plane(const Vector3& normal, float d) noexcept : XMFLOAT4(normal.x, normal.y, normal.z, d) {} + Plane(const Vector3& point1, const Vector3& point2, const Vector3& point3) noexcept; + Plane(const Vector3& point, const Vector3& normal) noexcept; + explicit Plane(const Vector4& v) noexcept : XMFLOAT4(v.x, v.y, v.z, v.w) {} + explicit Plane(_In_reads_(4) const float *pArray) noexcept : XMFLOAT4(pArray) {} + Plane(FXMVECTOR V) noexcept { XMStoreFloat4(this, V); } + Plane(const XMFLOAT4& p) noexcept { this->x = p.x; this->y = p.y; this->z = p.z; this->w = p.w; } + explicit Plane(const XMVECTORF32& F) noexcept { this->x = F.f[0]; this->y = F.f[1]; this->z = F.f[2]; this->w = F.f[3]; } + + Plane(const Plane&) = default; + Plane& operator=(const Plane&) = default; + + Plane(Plane&&) = default; + Plane& operator=(Plane&&) = default; + + operator XMVECTOR() const noexcept { return XMLoadFloat4(this); } + + // Comparison operators + bool operator == (const Plane& p) const noexcept; + bool operator != (const Plane& p) const noexcept; + + // Assignment operators + Plane& operator= (const XMVECTORF32& F) noexcept { x = F.f[0]; y = F.f[1]; z = F.f[2]; w = F.f[3]; return *this; } + + // Properties + Vector3 Normal() const noexcept { return Vector3(x, y, z); } + void Normal(const Vector3& normal) noexcept { x = normal.x; y = normal.y; z = normal.z; } + + float D() const noexcept { return w; } + void D(float d) noexcept { w = d; } + + // Plane operations + void Normalize() noexcept; + void Normalize(Plane& result) const noexcept; + + float Dot(const Vector4& v) const noexcept; + float DotCoordinate(const Vector3& position) const noexcept; + float DotNormal(const Vector3& normal) const noexcept; + + // Static functions + static void Transform(const Plane& plane, const Matrix& M, Plane& result) noexcept; + static Plane Transform(const Plane& plane, const Matrix& M) noexcept; + + static void Transform(const Plane& plane, const Quaternion& rotation, Plane& result) noexcept; + static Plane Transform(const Plane& plane, const Quaternion& rotation) noexcept; + // Input quaternion must be the inverse transpose of the transformation + }; + + //------------------------------------------------------------------------------ + // Quaternion + struct Quaternion : public XMFLOAT4 + { + Quaternion() noexcept : XMFLOAT4(0, 0, 0, 1.f) {} + constexpr Quaternion(float ix, float iy, float iz, float iw) noexcept : XMFLOAT4(ix, iy, iz, iw) {} + Quaternion(const Vector3& v, float scalar) noexcept : XMFLOAT4(v.x, v.y, v.z, scalar) {} + explicit Quaternion(const Vector4& v) noexcept : XMFLOAT4(v.x, v.y, v.z, v.w) {} + explicit Quaternion(_In_reads_(4) const float *pArray) noexcept : XMFLOAT4(pArray) {} + Quaternion(FXMVECTOR V) noexcept { XMStoreFloat4(this, V); } + Quaternion(const XMFLOAT4& q) noexcept { this->x = q.x; this->y = q.y; this->z = q.z; this->w = q.w; } + explicit Quaternion(const XMVECTORF32& F) noexcept { this->x = F.f[0]; this->y = F.f[1]; this->z = F.f[2]; this->w = F.f[3]; } + + Quaternion(const Quaternion&) = default; + Quaternion& operator=(const Quaternion&) = default; + + Quaternion(Quaternion&&) = default; + Quaternion& operator=(Quaternion&&) = default; + + operator XMVECTOR() const noexcept { return XMLoadFloat4(this); } + + // Comparison operators + bool operator == (const Quaternion& q) const noexcept; + bool operator != (const Quaternion& q) const noexcept; + + // Assignment operators + Quaternion& operator= (const XMVECTORF32& F) noexcept { x = F.f[0]; y = F.f[1]; z = F.f[2]; w = F.f[3]; return *this; } + Quaternion& operator+= (const Quaternion& q) noexcept; + Quaternion& operator-= (const Quaternion& q) noexcept; + Quaternion& operator*= (const Quaternion& q) noexcept; + Quaternion& operator*= (float S) noexcept; + Quaternion& operator/= (const Quaternion& q) noexcept; + + // Unary operators + Quaternion operator+ () const noexcept { return *this; } + Quaternion operator- () const noexcept; + + // Quaternion operations + float Length() const noexcept; + float LengthSquared() const noexcept; + + void Normalize() noexcept; + void Normalize(Quaternion& result) const noexcept; + + void Conjugate() noexcept; + void Conjugate(Quaternion& result) const noexcept; + + void Inverse(Quaternion& result) const noexcept; + + float Dot(const Quaternion& Q) const noexcept; + + void RotateTowards(const Quaternion& target, float maxAngle) noexcept; + void __cdecl RotateTowards(const Quaternion& target, float maxAngle, Quaternion& result) const noexcept; + + // Computes rotation about y-axis (y), then x-axis (x), then z-axis (z) + Vector3 ToEuler() const noexcept; + + // Static functions + static Quaternion CreateFromAxisAngle(const Vector3& axis, float angle) noexcept; + + // Rotates about y-axis (yaw), then x-axis (pitch), then z-axis (roll) + static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll) noexcept; + + // Rotates about y-axis (angles.y), then x-axis (angles.x), then z-axis (angles.z) + static Quaternion CreateFromYawPitchRoll(const Vector3& angles) noexcept; + + static Quaternion CreateFromRotationMatrix(const Matrix& M) noexcept; + + static void Lerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion& result) noexcept; + static Quaternion Lerp(const Quaternion& q1, const Quaternion& q2, float t) noexcept; + + static void Slerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion& result) noexcept; + static Quaternion Slerp(const Quaternion& q1, const Quaternion& q2, float t) noexcept; + + static void Concatenate(const Quaternion& q1, const Quaternion& q2, Quaternion& result) noexcept; + static Quaternion Concatenate(const Quaternion& q1, const Quaternion& q2) noexcept; + + static void __cdecl FromToRotation(const Vector3& fromDir, const Vector3& toDir, Quaternion& result) noexcept; + static Quaternion FromToRotation(const Vector3& fromDir, const Vector3& toDir) noexcept; + + static void __cdecl LookRotation(const Vector3& forward, const Vector3& up, Quaternion& result) noexcept; + static Quaternion LookRotation(const Vector3& forward, const Vector3& up) noexcept; + + static float Angle(const Quaternion& q1, const Quaternion& q2) noexcept; + + // Constants + static const Quaternion Identity; + }; + + // Binary operators + Quaternion operator+ (const Quaternion& Q1, const Quaternion& Q2) noexcept; + Quaternion operator- (const Quaternion& Q1, const Quaternion& Q2) noexcept; + Quaternion operator* (const Quaternion& Q1, const Quaternion& Q2) noexcept; + Quaternion operator* (const Quaternion& Q, float S) noexcept; + Quaternion operator/ (const Quaternion& Q1, const Quaternion& Q2) noexcept; + Quaternion operator* (float S, const Quaternion& Q) noexcept; + + //------------------------------------------------------------------------------ + // Color + struct Color : public XMFLOAT4 + { + Color() noexcept : XMFLOAT4(0, 0, 0, 1.f) {} + constexpr Color(float _r, float _g, float _b) noexcept : XMFLOAT4(_r, _g, _b, 1.f) {} + constexpr Color(float _r, float _g, float _b, float _a) noexcept : XMFLOAT4(_r, _g, _b, _a) {} + explicit Color(const Vector3& clr) noexcept : XMFLOAT4(clr.x, clr.y, clr.z, 1.f) {} + explicit Color(const Vector4& clr) noexcept : XMFLOAT4(clr.x, clr.y, clr.z, clr.w) {} + explicit Color(_In_reads_(4) const float *pArray) noexcept : XMFLOAT4(pArray) {} + Color(FXMVECTOR V) noexcept { XMStoreFloat4(this, V); } + Color(const XMFLOAT4& c) noexcept { this->x = c.x; this->y = c.y; this->z = c.z; this->w = c.w; } + explicit Color(const XMVECTORF32& F) noexcept { this->x = F.f[0]; this->y = F.f[1]; this->z = F.f[2]; this->w = F.f[3]; } + + // BGRA Direct3D 9 D3DCOLOR packed color + explicit Color(const DirectX::PackedVector::XMCOLOR& Packed) noexcept; + + // RGBA XNA Game Studio packed color + explicit Color(const DirectX::PackedVector::XMUBYTEN4& Packed) noexcept; + + Color(const Color&) = default; + Color& operator=(const Color&) = default; + + Color(Color&&) = default; + Color& operator=(Color&&) = default; + + operator XMVECTOR() const noexcept { return XMLoadFloat4(this); } + operator const float*() const noexcept { return reinterpret_cast(this); } + + // Comparison operators + bool operator == (const Color& c) const noexcept; + bool operator != (const Color& c) const noexcept; + + // Assignment operators + Color& operator= (const XMVECTORF32& F) noexcept { x = F.f[0]; y = F.f[1]; z = F.f[2]; w = F.f[3]; return *this; } + Color& operator= (const DirectX::PackedVector::XMCOLOR& Packed) noexcept; + Color& operator= (const DirectX::PackedVector::XMUBYTEN4& Packed) noexcept; + Color& operator+= (const Color& c) noexcept; + Color& operator-= (const Color& c) noexcept; + Color& operator*= (const Color& c) noexcept; + Color& operator*= (float S) noexcept; + Color& operator/= (const Color& c) noexcept; + + // Unary operators + Color operator+ () const noexcept { return *this; } + Color operator- () const noexcept; + + // Properties + float R() const noexcept { return x; } + void R(float r) noexcept { x = r; } + + float G() const noexcept { return y; } + void G(float g) noexcept { y = g; } + + float B() const noexcept { return z; } + void B(float b) noexcept { z = b; } + + float A() const noexcept { return w; } + void A(float a) noexcept { w = a; } + + // Color operations + DirectX::PackedVector::XMCOLOR BGRA() const noexcept; + DirectX::PackedVector::XMUBYTEN4 RGBA() const noexcept; + + Vector3 ToVector3() const noexcept; + Vector4 ToVector4() const noexcept; + + void Negate() noexcept; + void Negate(Color& result) const noexcept; + + void Saturate() noexcept; + void Saturate(Color& result) const noexcept; + + void Premultiply() noexcept; + void Premultiply(Color& result) const noexcept; + + void AdjustSaturation(float sat) noexcept; + void AdjustSaturation(float sat, Color& result) const noexcept; + + void AdjustContrast(float contrast) noexcept; + void AdjustContrast(float contrast, Color& result) const noexcept; + + // Static functions + static void Modulate(const Color& c1, const Color& c2, Color& result) noexcept; + static Color Modulate(const Color& c1, const Color& c2) noexcept; + + static void Lerp(const Color& c1, const Color& c2, float t, Color& result) noexcept; + static Color Lerp(const Color& c1, const Color& c2, float t) noexcept; + }; + + // Binary operators + Color operator+ (const Color& C1, const Color& C2) noexcept; + Color operator- (const Color& C1, const Color& C2) noexcept; + Color operator* (const Color& C1, const Color& C2) noexcept; + Color operator* (const Color& C, float S) noexcept; + Color operator/ (const Color& C1, const Color& C2) noexcept; + Color operator* (float S, const Color& C) noexcept; + + //------------------------------------------------------------------------------ + // Ray + class Ray + { + public: + Vector3 position; + Vector3 direction; + + Ray() noexcept : position(0, 0, 0), direction(0, 0, 1) {} + Ray(const Vector3& pos, const Vector3& dir) noexcept : position(pos), direction(dir) {} + + Ray(const Ray&) = default; + Ray& operator=(const Ray&) = default; + + Ray(Ray&&) = default; + Ray& operator=(Ray&&) = default; + + // Comparison operators + bool operator == (const Ray& r) const noexcept; + bool operator != (const Ray& r) const noexcept; + + // Ray operations + bool Intersects(const BoundingSphere& sphere, _Out_ float& Dist) const noexcept; + bool Intersects(const BoundingBox& box, _Out_ float& Dist) const noexcept; + bool Intersects(const Vector3& tri0, const Vector3& tri1, const Vector3& tri2, _Out_ float& Dist) const noexcept; + bool Intersects(const Plane& plane, _Out_ float& Dist) const noexcept; + }; + + //------------------------------------------------------------------------------ + // Viewport + class Viewport + { + public: + float x; + float y; + float width; + float height; + float minDepth; + float maxDepth; + + Viewport() noexcept : + x(0.f), y(0.f), width(0.f), height(0.f), minDepth(0.f), maxDepth(1.f) + { + } + constexpr Viewport(float ix, float iy, float iw, float ih, float iminz = 0.f, float imaxz = 1.f) noexcept : + x(ix), y(iy), width(iw), height(ih), minDepth(iminz), maxDepth(imaxz) + { + } + explicit Viewport(const RECT& rct) noexcept : + x(float(rct.left)), y(float(rct.top)), + width(float(rct.right - rct.left)), + height(float(rct.bottom - rct.top)), + minDepth(0.f), maxDepth(1.f) + { + } + + #if defined(__d3d11_h__) || defined(__d3d11_x_h__) + // Direct3D 11 interop + explicit Viewport(const D3D11_VIEWPORT& vp) noexcept : + x(vp.TopLeftX), y(vp.TopLeftY), + width(vp.Width), height(vp.Height), + minDepth(vp.MinDepth), maxDepth(vp.MaxDepth) + { + } + + operator D3D11_VIEWPORT() noexcept { return *reinterpret_cast(this); } + const D3D11_VIEWPORT* Get11() const noexcept { return reinterpret_cast(this); } + Viewport& operator= (const D3D11_VIEWPORT& vp) noexcept; + #endif + + #if defined(__d3d12_h__) || defined(__d3d12_x_h__) || defined(__XBOX_D3D12_X__) + // Direct3D 12 interop + explicit Viewport(const D3D12_VIEWPORT& vp) noexcept : + x(vp.TopLeftX), y(vp.TopLeftY), + width(vp.Width), height(vp.Height), + minDepth(vp.MinDepth), maxDepth(vp.MaxDepth) + { + } + + operator D3D12_VIEWPORT() noexcept { return *reinterpret_cast(this); } + const D3D12_VIEWPORT* Get12() const noexcept { return reinterpret_cast(this); } + Viewport& operator= (const D3D12_VIEWPORT& vp) noexcept; + #endif + + Viewport(const Viewport&) = default; + Viewport& operator=(const Viewport&) = default; + + Viewport(Viewport&&) = default; + Viewport& operator=(Viewport&&) = default; + + // Comparison operators + #if (__cplusplus >= 202002L) + bool operator == (const Viewport&) const = default; + auto operator <=> (const Viewport&) const = default; + #else + bool operator == (const Viewport& vp) const noexcept; + bool operator != (const Viewport& vp) const noexcept; + #endif + + // Assignment operators + Viewport& operator= (const RECT& rct) noexcept; + + // Viewport operations + float AspectRatio() const noexcept; + + Vector3 Project(const Vector3& p, const Matrix& proj, const Matrix& view, const Matrix& world) const noexcept; + void Project(const Vector3& p, const Matrix& proj, const Matrix& view, const Matrix& world, Vector3& result) const noexcept; + + Vector3 Unproject(const Vector3& p, const Matrix& proj, const Matrix& view, const Matrix& world) const noexcept; + void Unproject(const Vector3& p, const Matrix& proj, const Matrix& view, const Matrix& world, Vector3& result) const noexcept; + + // Static methods + #if defined(__dxgi1_2_h__) || defined(__d3d11_x_h__) || defined(__d3d12_x_h__) || defined(__XBOX_D3D12_X__) + static RECT __cdecl ComputeDisplayArea(DXGI_SCALING scaling, UINT backBufferWidth, UINT backBufferHeight, int outputWidth, int outputHeight) noexcept; + #endif + static RECT __cdecl ComputeTitleSafeArea(UINT backBufferWidth, UINT backBufferHeight) noexcept; + }; + + #include "SimpleMath.inl" + + } // namespace SimpleMath + +} // namespace DirectX + +//------------------------------------------------------------------------------ +// Support for SimpleMath and Standard C++ Library containers +namespace std +{ + + template<> struct less + { + bool operator()(const DirectX::SimpleMath::Rectangle& r1, const DirectX::SimpleMath::Rectangle& r2) const noexcept + { + return ((r1.x < r2.x) + || ((r1.x == r2.x) && (r1.y < r2.y)) + || ((r1.x == r2.x) && (r1.y == r2.y) && (r1.width < r2.width)) + || ((r1.x == r2.x) && (r1.y == r2.y) && (r1.width == r2.width) && (r1.height < r2.height))); + } + }; + + template<> struct less + { + bool operator()(const DirectX::SimpleMath::Vector2& V1, const DirectX::SimpleMath::Vector2& V2) const noexcept + { + return ((V1.x < V2.x) || ((V1.x == V2.x) && (V1.y < V2.y))); + } + }; + + template<> struct less + { + bool operator()(const DirectX::SimpleMath::Vector3& V1, const DirectX::SimpleMath::Vector3& V2) const noexcept + { + return ((V1.x < V2.x) + || ((V1.x == V2.x) && (V1.y < V2.y)) + || ((V1.x == V2.x) && (V1.y == V2.y) && (V1.z < V2.z))); + } + }; + + template<> struct less + { + bool operator()(const DirectX::SimpleMath::Vector4& V1, const DirectX::SimpleMath::Vector4& V2) const noexcept + { + return ((V1.x < V2.x) + || ((V1.x == V2.x) && (V1.y < V2.y)) + || ((V1.x == V2.x) && (V1.y == V2.y) && (V1.z < V2.z)) + || ((V1.x == V2.x) && (V1.y == V2.y) && (V1.z == V2.z) && (V1.w < V2.w))); + } + }; + + template<> struct less + { + bool operator()(const DirectX::SimpleMath::Matrix& M1, const DirectX::SimpleMath::Matrix& M2) const noexcept + { + if (M1._11 != M2._11) return M1._11 < M2._11; + if (M1._12 != M2._12) return M1._12 < M2._12; + if (M1._13 != M2._13) return M1._13 < M2._13; + if (M1._14 != M2._14) return M1._14 < M2._14; + if (M1._21 != M2._21) return M1._21 < M2._21; + if (M1._22 != M2._22) return M1._22 < M2._22; + if (M1._23 != M2._23) return M1._23 < M2._23; + if (M1._24 != M2._24) return M1._24 < M2._24; + if (M1._31 != M2._31) return M1._31 < M2._31; + if (M1._32 != M2._32) return M1._32 < M2._32; + if (M1._33 != M2._33) return M1._33 < M2._33; + if (M1._34 != M2._34) return M1._34 < M2._34; + if (M1._41 != M2._41) return M1._41 < M2._41; + if (M1._42 != M2._42) return M1._42 < M2._42; + if (M1._43 != M2._43) return M1._43 < M2._43; + if (M1._44 != M2._44) return M1._44 < M2._44; + + return false; + } + }; + + template<> struct less + { + bool operator()(const DirectX::SimpleMath::Plane& P1, const DirectX::SimpleMath::Plane& P2) const noexcept + { + return ((P1.x < P2.x) + || ((P1.x == P2.x) && (P1.y < P2.y)) + || ((P1.x == P2.x) && (P1.y == P2.y) && (P1.z < P2.z)) + || ((P1.x == P2.x) && (P1.y == P2.y) && (P1.z == P2.z) && (P1.w < P2.w))); + } + }; + + template<> struct less + { + bool operator()(const DirectX::SimpleMath::Quaternion& Q1, const DirectX::SimpleMath::Quaternion& Q2) const noexcept + { + return ((Q1.x < Q2.x) + || ((Q1.x == Q2.x) && (Q1.y < Q2.y)) + || ((Q1.x == Q2.x) && (Q1.y == Q2.y) && (Q1.z < Q2.z)) + || ((Q1.x == Q2.x) && (Q1.y == Q2.y) && (Q1.z == Q2.z) && (Q1.w < Q2.w))); + } + }; + + template<> struct less + { + bool operator()(const DirectX::SimpleMath::Color& C1, const DirectX::SimpleMath::Color& C2) const noexcept + { + return ((C1.x < C2.x) + || ((C1.x == C2.x) && (C1.y < C2.y)) + || ((C1.x == C2.x) && (C1.y == C2.y) && (C1.z < C2.z)) + || ((C1.x == C2.x) && (C1.y == C2.y) && (C1.z == C2.z) && (C1.w < C2.w))); + } + }; + + template<> struct less + { + bool operator()(const DirectX::SimpleMath::Ray& R1, const DirectX::SimpleMath::Ray& R2) const noexcept + { + if (R1.position.x != R2.position.x) return R1.position.x < R2.position.x; + if (R1.position.y != R2.position.y) return R1.position.y < R2.position.y; + if (R1.position.z != R2.position.z) return R1.position.z < R2.position.z; + + if (R1.direction.x != R2.direction.x) return R1.direction.x < R2.direction.x; + if (R1.direction.y != R2.direction.y) return R1.direction.y < R2.direction.y; + if (R1.direction.z != R2.direction.z) return R1.direction.z < R2.direction.z; + + return false; + } + }; + + template<> struct less + { + bool operator()(const DirectX::SimpleMath::Viewport& vp1, const DirectX::SimpleMath::Viewport& vp2) const noexcept + { + if (vp1.x != vp2.x) return (vp1.x < vp2.x); + if (vp1.y != vp2.y) return (vp1.y < vp2.y); + + if (vp1.width != vp2.width) return (vp1.width < vp2.width); + if (vp1.height != vp2.height) return (vp1.height < vp2.height); + + if (vp1.minDepth != vp2.minDepth) return (vp1.minDepth < vp2.minDepth); + if (vp1.maxDepth != vp2.maxDepth) return (vp1.maxDepth < vp2.maxDepth); + + return false; + } + }; + +} // namespace std + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif diff --git a/enginecustom/include/Inc/SimpleMath.inl b/enginecustom/include/Inc/SimpleMath.inl new file mode 100644 index 0000000..2cd32dc --- /dev/null +++ b/enginecustom/include/Inc/SimpleMath.inl @@ -0,0 +1,3826 @@ +//------------------------------------------------------------------------------------- +// SimpleMath.inl -- Simplified C++ Math wrapper for DirectXMath +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +// http://go.microsoft.com/fwlink/?LinkID=615561 +//------------------------------------------------------------------------------------- + +#pragma once + +/**************************************************************************** +* +* Rectangle +* +****************************************************************************/ + +//------------------------------------------------------------------------------ +// Rectangle operations +//------------------------------------------------------------------------------ +inline Vector2 Rectangle::Location() const noexcept +{ + return Vector2(float(x), float(y)); +} + +inline Vector2 Rectangle::Center() const noexcept +{ + return Vector2(float(x) + (float(width) / 2.f), float(y) + (float(height) / 2.f)); +} + +inline bool Rectangle::Contains(const Vector2& point) const noexcept +{ + return (float(x) <= point.x) && (point.x < float(x + width)) && (float(y) <= point.y) && (point.y < float(y + height)); +} + +inline void Rectangle::Inflate(long horizAmount, long vertAmount) noexcept +{ + x -= horizAmount; + y -= vertAmount; + width += horizAmount; + height += vertAmount; +} + +//------------------------------------------------------------------------------ +// Static functions +//------------------------------------------------------------------------------ + +inline Rectangle Rectangle::Intersect(const Rectangle& ra, const Rectangle& rb) noexcept +{ + const long righta = ra.x + ra.width; + const long rightb = rb.x + rb.width; + + const long bottoma = ra.y + ra.height; + const long bottomb = rb.y + rb.height; + + const long maxX = ra.x > rb.x ? ra.x : rb.x; + const long maxY = ra.y > rb.y ? ra.y : rb.y; + + const long minRight = righta < rightb ? righta : rightb; + const long minBottom = bottoma < bottomb ? bottoma : bottomb; + + Rectangle result; + + if ((minRight > maxX) && (minBottom > maxY)) + { + result.x = maxX; + result.y = maxY; + result.width = minRight - maxX; + result.height = minBottom - maxY; + } + else + { + result.x = 0; + result.y = 0; + result.width = 0; + result.height = 0; + } + + return result; +} + +inline RECT Rectangle::Intersect(const RECT& rcta, const RECT& rctb) noexcept +{ + const long maxX = rcta.left > rctb.left ? rcta.left : rctb.left; + const long maxY = rcta.top > rctb.top ? rcta.top : rctb.top; + + const long minRight = rcta.right < rctb.right ? rcta.right : rctb.right; + const long minBottom = rcta.bottom < rctb.bottom ? rcta.bottom : rctb.bottom; + + RECT result; + + if ((minRight > maxX) && (minBottom > maxY)) + { + result.left = maxX; + result.top = maxY; + result.right = minRight; + result.bottom = minBottom; + } + else + { + result.left = 0; + result.top = 0; + result.right = 0; + result.bottom = 0; + } + + return result; +} + +inline Rectangle Rectangle::Union(const Rectangle& ra, const Rectangle& rb) noexcept +{ + const long righta = ra.x + ra.width; + const long rightb = rb.x + rb.width; + + const long bottoma = ra.y + ra.height; + const long bottomb = rb.y + rb.height; + + const int minX = ra.x < rb.x ? ra.x : rb.x; + const int minY = ra.y < rb.y ? ra.y : rb.y; + + const int maxRight = righta > rightb ? righta : rightb; + const int maxBottom = bottoma > bottomb ? bottoma : bottomb; + + Rectangle result; + result.x = minX; + result.y = minY; + result.width = maxRight - minX; + result.height = maxBottom - minY; + return result; +} + +inline RECT Rectangle::Union(const RECT& rcta, const RECT& rctb) noexcept +{ + RECT result; + result.left = rcta.left < rctb.left ? rcta.left : rctb.left; + result.top = rcta.top < rctb.top ? rcta.top : rctb.top; + result.right = rcta.right > rctb.right ? rcta.right : rctb.right; + result.bottom = rcta.bottom > rctb.bottom ? rcta.bottom : rctb.bottom; + return result; +} + + +/**************************************************************************** + * + * Vector2 + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ +// Comparision operators +//------------------------------------------------------------------------------ + +inline bool Vector2::operator == (const Vector2& V) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR v2 = XMLoadFloat2(&V); + return XMVector2Equal(v1, v2); +} + +inline bool Vector2::operator != (const Vector2& V) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR v2 = XMLoadFloat2(&V); + return XMVector2NotEqual(v1, v2); +} + +//------------------------------------------------------------------------------ +// Assignment operators +//------------------------------------------------------------------------------ + +inline Vector2& Vector2::operator+= (const Vector2& V) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR v2 = XMLoadFloat2(&V); + const XMVECTOR X = XMVectorAdd(v1, v2); + XMStoreFloat2(this, X); + return *this; +} + +inline Vector2& Vector2::operator-= (const Vector2& V) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR v2 = XMLoadFloat2(&V); + const XMVECTOR X = XMVectorSubtract(v1, v2); + XMStoreFloat2(this, X); + return *this; +} + +inline Vector2& Vector2::operator*= (const Vector2& V) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR v2 = XMLoadFloat2(&V); + const XMVECTOR X = XMVectorMultiply(v1, v2); + XMStoreFloat2(this, X); + return *this; +} + +inline Vector2& Vector2::operator*= (float S) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR X = XMVectorScale(v1, S); + XMStoreFloat2(this, X); + return *this; +} + +inline Vector2& Vector2::operator/= (float S) noexcept +{ + using namespace DirectX; + assert(S != 0.0f); + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR X = XMVectorScale(v1, 1.f / S); + XMStoreFloat2(this, X); + return *this; +} + +//------------------------------------------------------------------------------ +// Binary operators +//------------------------------------------------------------------------------ + +inline Vector2 operator+ (const Vector2& V1, const Vector2& V2) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&V1); + const XMVECTOR v2 = XMLoadFloat2(&V2); + const XMVECTOR X = XMVectorAdd(v1, v2); + Vector2 R; + XMStoreFloat2(&R, X); + return R; +} + +inline Vector2 operator- (const Vector2& V1, const Vector2& V2) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&V1); + const XMVECTOR v2 = XMLoadFloat2(&V2); + const XMVECTOR X = XMVectorSubtract(v1, v2); + Vector2 R; + XMStoreFloat2(&R, X); + return R; +} + +inline Vector2 operator* (const Vector2& V1, const Vector2& V2) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&V1); + const XMVECTOR v2 = XMLoadFloat2(&V2); + const XMVECTOR X = XMVectorMultiply(v1, v2); + Vector2 R; + XMStoreFloat2(&R, X); + return R; +} + +inline Vector2 operator* (const Vector2& V, float S) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&V); + const XMVECTOR X = XMVectorScale(v1, S); + Vector2 R; + XMStoreFloat2(&R, X); + return R; +} + +inline Vector2 operator/ (const Vector2& V1, const Vector2& V2) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&V1); + const XMVECTOR v2 = XMLoadFloat2(&V2); + const XMVECTOR X = XMVectorDivide(v1, v2); + Vector2 R; + XMStoreFloat2(&R, X); + return R; +} + +inline Vector2 operator/ (const Vector2& V, float S) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&V); + const XMVECTOR X = XMVectorScale(v1, 1.f / S); + Vector2 R; + XMStoreFloat2(&R, X); + return R; +} + +inline Vector2 operator* (float S, const Vector2& V) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&V); + const XMVECTOR X = XMVectorScale(v1, S); + Vector2 R; + XMStoreFloat2(&R, X); + return R; +} + +//------------------------------------------------------------------------------ +// Vector operations +//------------------------------------------------------------------------------ + +inline bool Vector2::InBounds(const Vector2& Bounds) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR v2 = XMLoadFloat2(&Bounds); + return XMVector2InBounds(v1, v2); +} + +inline float Vector2::Length() const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR X = XMVector2Length(v1); + return XMVectorGetX(X); +} + +inline float Vector2::LengthSquared() const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR X = XMVector2LengthSq(v1); + return XMVectorGetX(X); +} + +inline float Vector2::Dot(const Vector2& V) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR v2 = XMLoadFloat2(&V); + const XMVECTOR X = XMVector2Dot(v1, v2); + return XMVectorGetX(X); +} + +inline void Vector2::Cross(const Vector2& V, Vector2& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR v2 = XMLoadFloat2(&V); + const XMVECTOR R = XMVector2Cross(v1, v2); + XMStoreFloat2(&result, R); +} + +inline Vector2 Vector2::Cross(const Vector2& V) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR v2 = XMLoadFloat2(&V); + const XMVECTOR R = XMVector2Cross(v1, v2); + + Vector2 result; + XMStoreFloat2(&result, R); + return result; +} + +inline void Vector2::Normalize() noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR X = XMVector2Normalize(v1); + XMStoreFloat2(this, X); +} + +inline void Vector2::Normalize(Vector2& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR X = XMVector2Normalize(v1); + XMStoreFloat2(&result, X); +} + +inline void Vector2::Clamp(const Vector2& vmin, const Vector2& vmax) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR v2 = XMLoadFloat2(&vmin); + const XMVECTOR v3 = XMLoadFloat2(&vmax); + const XMVECTOR X = XMVectorClamp(v1, v2, v3); + XMStoreFloat2(this, X); +} + +inline void Vector2::Clamp(const Vector2& vmin, const Vector2& vmax, Vector2& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(this); + const XMVECTOR v2 = XMLoadFloat2(&vmin); + const XMVECTOR v3 = XMLoadFloat2(&vmax); + const XMVECTOR X = XMVectorClamp(v1, v2, v3); + XMStoreFloat2(&result, X); +} + +//------------------------------------------------------------------------------ +// Static functions +//------------------------------------------------------------------------------ + +inline float Vector2::Distance(const Vector2& v1, const Vector2& v2) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&v2); + const XMVECTOR V = XMVectorSubtract(x2, x1); + const XMVECTOR X = XMVector2Length(V); + return XMVectorGetX(X); +} + +inline float Vector2::DistanceSquared(const Vector2& v1, const Vector2& v2) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&v2); + const XMVECTOR V = XMVectorSubtract(x2, x1); + const XMVECTOR X = XMVector2LengthSq(V); + return XMVectorGetX(X); +} + +inline void Vector2::Min(const Vector2& v1, const Vector2& v2, Vector2& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&v2); + const XMVECTOR X = XMVectorMin(x1, x2); + XMStoreFloat2(&result, X); +} + +inline Vector2 Vector2::Min(const Vector2& v1, const Vector2& v2) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&v2); + const XMVECTOR X = XMVectorMin(x1, x2); + + Vector2 result; + XMStoreFloat2(&result, X); + return result; +} + +inline void Vector2::Max(const Vector2& v1, const Vector2& v2, Vector2& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&v2); + const XMVECTOR X = XMVectorMax(x1, x2); + XMStoreFloat2(&result, X); +} + +inline Vector2 Vector2::Max(const Vector2& v1, const Vector2& v2) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&v2); + const XMVECTOR X = XMVectorMax(x1, x2); + + Vector2 result; + XMStoreFloat2(&result, X); + return result; +} + +inline void Vector2::Lerp(const Vector2& v1, const Vector2& v2, float t, Vector2& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&v2); + const XMVECTOR X = XMVectorLerp(x1, x2, t); + XMStoreFloat2(&result, X); +} + +inline Vector2 Vector2::Lerp(const Vector2& v1, const Vector2& v2, float t) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&v2); + const XMVECTOR X = XMVectorLerp(x1, x2, t); + + Vector2 result; + XMStoreFloat2(&result, X); + return result; +} + +inline void Vector2::SmoothStep(const Vector2& v1, const Vector2& v2, float t, Vector2& result) noexcept +{ + using namespace DirectX; + t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t); // Clamp value to 0 to 1 + t = t * t*(3.f - 2.f*t); + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&v2); + const XMVECTOR X = XMVectorLerp(x1, x2, t); + XMStoreFloat2(&result, X); +} + +inline Vector2 Vector2::SmoothStep(const Vector2& v1, const Vector2& v2, float t) noexcept +{ + using namespace DirectX; + t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t); // Clamp value to 0 to 1 + t = t * t*(3.f - 2.f*t); + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&v2); + const XMVECTOR X = XMVectorLerp(x1, x2, t); + + Vector2 result; + XMStoreFloat2(&result, X); + return result; +} + +inline void Vector2::Barycentric(const Vector2& v1, const Vector2& v2, const Vector2& v3, float f, float g, Vector2& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&v2); + const XMVECTOR x3 = XMLoadFloat2(&v3); + const XMVECTOR X = XMVectorBaryCentric(x1, x2, x3, f, g); + XMStoreFloat2(&result, X); +} + +inline Vector2 Vector2::Barycentric(const Vector2& v1, const Vector2& v2, const Vector2& v3, float f, float g) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&v2); + const XMVECTOR x3 = XMLoadFloat2(&v3); + const XMVECTOR X = XMVectorBaryCentric(x1, x2, x3, f, g); + + Vector2 result; + XMStoreFloat2(&result, X); + return result; +} + +inline void Vector2::CatmullRom(const Vector2& v1, const Vector2& v2, const Vector2& v3, const Vector2& v4, float t, Vector2& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&v2); + const XMVECTOR x3 = XMLoadFloat2(&v3); + const XMVECTOR x4 = XMLoadFloat2(&v4); + const XMVECTOR X = XMVectorCatmullRom(x1, x2, x3, x4, t); + XMStoreFloat2(&result, X); +} + +inline Vector2 Vector2::CatmullRom(const Vector2& v1, const Vector2& v2, const Vector2& v3, const Vector2& v4, float t) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&v2); + const XMVECTOR x3 = XMLoadFloat2(&v3); + const XMVECTOR x4 = XMLoadFloat2(&v4); + const XMVECTOR X = XMVectorCatmullRom(x1, x2, x3, x4, t); + + Vector2 result; + XMStoreFloat2(&result, X); + return result; +} + +inline void Vector2::Hermite(const Vector2& v1, const Vector2& t1, const Vector2& v2, const Vector2& t2, float t, Vector2& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&t1); + const XMVECTOR x3 = XMLoadFloat2(&v2); + const XMVECTOR x4 = XMLoadFloat2(&t2); + const XMVECTOR X = XMVectorHermite(x1, x2, x3, x4, t); + XMStoreFloat2(&result, X); +} + +inline Vector2 Vector2::Hermite(const Vector2& v1, const Vector2& t1, const Vector2& v2, const Vector2& t2, float t) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat2(&v1); + const XMVECTOR x2 = XMLoadFloat2(&t1); + const XMVECTOR x3 = XMLoadFloat2(&v2); + const XMVECTOR x4 = XMLoadFloat2(&t2); + const XMVECTOR X = XMVectorHermite(x1, x2, x3, x4, t); + + Vector2 result; + XMStoreFloat2(&result, X); + return result; +} + +inline void Vector2::Reflect(const Vector2& ivec, const Vector2& nvec, Vector2& result) noexcept +{ + using namespace DirectX; + const XMVECTOR i = XMLoadFloat2(&ivec); + const XMVECTOR n = XMLoadFloat2(&nvec); + const XMVECTOR X = XMVector2Reflect(i, n); + XMStoreFloat2(&result, X); +} + +inline Vector2 Vector2::Reflect(const Vector2& ivec, const Vector2& nvec) noexcept +{ + using namespace DirectX; + const XMVECTOR i = XMLoadFloat2(&ivec); + const XMVECTOR n = XMLoadFloat2(&nvec); + const XMVECTOR X = XMVector2Reflect(i, n); + + Vector2 result; + XMStoreFloat2(&result, X); + return result; +} + +inline void Vector2::Refract(const Vector2& ivec, const Vector2& nvec, float refractionIndex, Vector2& result) noexcept +{ + using namespace DirectX; + const XMVECTOR i = XMLoadFloat2(&ivec); + const XMVECTOR n = XMLoadFloat2(&nvec); + const XMVECTOR X = XMVector2Refract(i, n, refractionIndex); + XMStoreFloat2(&result, X); +} + +inline Vector2 Vector2::Refract(const Vector2& ivec, const Vector2& nvec, float refractionIndex) noexcept +{ + using namespace DirectX; + const XMVECTOR i = XMLoadFloat2(&ivec); + const XMVECTOR n = XMLoadFloat2(&nvec); + const XMVECTOR X = XMVector2Refract(i, n, refractionIndex); + + Vector2 result; + XMStoreFloat2(&result, X); + return result; +} + +inline void Vector2::Transform(const Vector2& v, const Quaternion& quat, Vector2& result) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&v); + const XMVECTOR q = XMLoadFloat4(&quat); + const XMVECTOR X = XMVector3Rotate(v1, q); + XMStoreFloat2(&result, X); +} + +inline Vector2 Vector2::Transform(const Vector2& v, const Quaternion& quat) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&v); + const XMVECTOR q = XMLoadFloat4(&quat); + const XMVECTOR X = XMVector3Rotate(v1, q); + + Vector2 result; + XMStoreFloat2(&result, X); + return result; +} + +inline void Vector2::Transform(const Vector2& v, const Matrix& m, Vector2& result) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&v); + const XMMATRIX M = XMLoadFloat4x4(&m); + const XMVECTOR X = XMVector2TransformCoord(v1, M); + XMStoreFloat2(&result, X); +} + +inline Vector2 Vector2::Transform(const Vector2& v, const Matrix& m) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&v); + const XMMATRIX M = XMLoadFloat4x4(&m); + const XMVECTOR X = XMVector2TransformCoord(v1, M); + + Vector2 result; + XMStoreFloat2(&result, X); + return result; +} + +_Use_decl_annotations_ +inline void Vector2::Transform(const Vector2* varray, size_t count, const Matrix& m, Vector2* resultArray) noexcept +{ + using namespace DirectX; + const XMMATRIX M = XMLoadFloat4x4(&m); + XMVector2TransformCoordStream(resultArray, sizeof(XMFLOAT2), varray, sizeof(XMFLOAT2), count, M); +} + +inline void Vector2::Transform(const Vector2& v, const Matrix& m, Vector4& result) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&v); + const XMMATRIX M = XMLoadFloat4x4(&m); + const XMVECTOR X = XMVector2Transform(v1, M); + XMStoreFloat4(&result, X); +} + +_Use_decl_annotations_ +inline void Vector2::Transform(const Vector2* varray, size_t count, const Matrix& m, Vector4* resultArray) noexcept +{ + using namespace DirectX; + const XMMATRIX M = XMLoadFloat4x4(&m); + XMVector2TransformStream(resultArray, sizeof(XMFLOAT4), varray, sizeof(XMFLOAT2), count, M); +} + +inline void Vector2::TransformNormal(const Vector2& v, const Matrix& m, Vector2& result) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&v); + const XMMATRIX M = XMLoadFloat4x4(&m); + const XMVECTOR X = XMVector2TransformNormal(v1, M); + XMStoreFloat2(&result, X); +} + +inline Vector2 Vector2::TransformNormal(const Vector2& v, const Matrix& m) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&v); + const XMMATRIX M = XMLoadFloat4x4(&m); + const XMVECTOR X = XMVector2TransformNormal(v1, M); + + Vector2 result; + XMStoreFloat2(&result, X); + return result; +} + +_Use_decl_annotations_ +inline void Vector2::TransformNormal(const Vector2* varray, size_t count, const Matrix& m, Vector2* resultArray) noexcept +{ + using namespace DirectX; + const XMMATRIX M = XMLoadFloat4x4(&m); + XMVector2TransformNormalStream(resultArray, sizeof(XMFLOAT2), varray, sizeof(XMFLOAT2), count, M); +} + + +/**************************************************************************** + * + * Vector3 + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ +// Comparision operators +//------------------------------------------------------------------------------ + +inline bool Vector3::operator == (const Vector3& V) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR v2 = XMLoadFloat3(&V); + return XMVector3Equal(v1, v2); +} + +inline bool Vector3::operator != (const Vector3& V) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR v2 = XMLoadFloat3(&V); + return XMVector3NotEqual(v1, v2); +} + +//------------------------------------------------------------------------------ +// Assignment operators +//------------------------------------------------------------------------------ + +inline Vector3& Vector3::operator+= (const Vector3& V) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR v2 = XMLoadFloat3(&V); + const XMVECTOR X = XMVectorAdd(v1, v2); + XMStoreFloat3(this, X); + return *this; +} + +inline Vector3& Vector3::operator-= (const Vector3& V) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR v2 = XMLoadFloat3(&V); + const XMVECTOR X = XMVectorSubtract(v1, v2); + XMStoreFloat3(this, X); + return *this; +} + +inline Vector3& Vector3::operator*= (const Vector3& V) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR v2 = XMLoadFloat3(&V); + const XMVECTOR X = XMVectorMultiply(v1, v2); + XMStoreFloat3(this, X); + return *this; +} + +inline Vector3& Vector3::operator*= (float S) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR X = XMVectorScale(v1, S); + XMStoreFloat3(this, X); + return *this; +} + +inline Vector3& Vector3::operator/= (float S) noexcept +{ + using namespace DirectX; + assert(S != 0.0f); + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR X = XMVectorScale(v1, 1.f / S); + XMStoreFloat3(this, X); + return *this; +} + +//------------------------------------------------------------------------------ +// Urnary operators +//------------------------------------------------------------------------------ + +inline Vector3 Vector3::operator- () const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR X = XMVectorNegate(v1); + Vector3 R; + XMStoreFloat3(&R, X); + return R; +} + +//------------------------------------------------------------------------------ +// Binary operators +//------------------------------------------------------------------------------ + +inline Vector3 operator+ (const Vector3& V1, const Vector3& V2) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&V1); + const XMVECTOR v2 = XMLoadFloat3(&V2); + const XMVECTOR X = XMVectorAdd(v1, v2); + Vector3 R; + XMStoreFloat3(&R, X); + return R; +} + +inline Vector3 operator- (const Vector3& V1, const Vector3& V2) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&V1); + const XMVECTOR v2 = XMLoadFloat3(&V2); + const XMVECTOR X = XMVectorSubtract(v1, v2); + Vector3 R; + XMStoreFloat3(&R, X); + return R; +} + +inline Vector3 operator* (const Vector3& V1, const Vector3& V2) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&V1); + const XMVECTOR v2 = XMLoadFloat3(&V2); + const XMVECTOR X = XMVectorMultiply(v1, v2); + Vector3 R; + XMStoreFloat3(&R, X); + return R; +} + +inline Vector3 operator* (const Vector3& V, float S) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&V); + const XMVECTOR X = XMVectorScale(v1, S); + Vector3 R; + XMStoreFloat3(&R, X); + return R; +} + +inline Vector3 operator/ (const Vector3& V1, const Vector3& V2) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&V1); + const XMVECTOR v2 = XMLoadFloat3(&V2); + const XMVECTOR X = XMVectorDivide(v1, v2); + Vector3 R; + XMStoreFloat3(&R, X); + return R; +} + +inline Vector3 operator/ (const Vector3& V, float S) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&V); + const XMVECTOR X = XMVectorScale(v1, 1.f / S); + Vector3 R; + XMStoreFloat3(&R, X); + return R; +} + +inline Vector3 operator* (float S, const Vector3& V) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&V); + const XMVECTOR X = XMVectorScale(v1, S); + Vector3 R; + XMStoreFloat3(&R, X); + return R; +} + +//------------------------------------------------------------------------------ +// Vector operations +//------------------------------------------------------------------------------ + +inline bool Vector3::InBounds(const Vector3& Bounds) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR v2 = XMLoadFloat3(&Bounds); + return XMVector3InBounds(v1, v2); +} + +inline float Vector3::Length() const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR X = XMVector3Length(v1); + return XMVectorGetX(X); +} + +inline float Vector3::LengthSquared() const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR X = XMVector3LengthSq(v1); + return XMVectorGetX(X); +} + +inline float Vector3::Dot(const Vector3& V) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR v2 = XMLoadFloat3(&V); + const XMVECTOR X = XMVector3Dot(v1, v2); + return XMVectorGetX(X); +} + +inline void Vector3::Cross(const Vector3& V, Vector3& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR v2 = XMLoadFloat3(&V); + const XMVECTOR R = XMVector3Cross(v1, v2); + XMStoreFloat3(&result, R); +} + +inline Vector3 Vector3::Cross(const Vector3& V) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR v2 = XMLoadFloat3(&V); + const XMVECTOR R = XMVector3Cross(v1, v2); + + Vector3 result; + XMStoreFloat3(&result, R); + return result; +} + +inline void Vector3::Normalize() noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR X = XMVector3Normalize(v1); + XMStoreFloat3(this, X); +} + +inline void Vector3::Normalize(Vector3& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR X = XMVector3Normalize(v1); + XMStoreFloat3(&result, X); +} + +inline void Vector3::Clamp(const Vector3& vmin, const Vector3& vmax) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR v2 = XMLoadFloat3(&vmin); + const XMVECTOR v3 = XMLoadFloat3(&vmax); + const XMVECTOR X = XMVectorClamp(v1, v2, v3); + XMStoreFloat3(this, X); +} + +inline void Vector3::Clamp(const Vector3& vmin, const Vector3& vmax, Vector3& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(this); + const XMVECTOR v2 = XMLoadFloat3(&vmin); + const XMVECTOR v3 = XMLoadFloat3(&vmax); + const XMVECTOR X = XMVectorClamp(v1, v2, v3); + XMStoreFloat3(&result, X); +} + +//------------------------------------------------------------------------------ +// Static functions +//------------------------------------------------------------------------------ + +inline float Vector3::Distance(const Vector3& v1, const Vector3& v2) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&v2); + const XMVECTOR V = XMVectorSubtract(x2, x1); + const XMVECTOR X = XMVector3Length(V); + return XMVectorGetX(X); +} + +inline float Vector3::DistanceSquared(const Vector3& v1, const Vector3& v2) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&v2); + const XMVECTOR V = XMVectorSubtract(x2, x1); + const XMVECTOR X = XMVector3LengthSq(V); + return XMVectorGetX(X); +} + +inline void Vector3::Min(const Vector3& v1, const Vector3& v2, Vector3& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&v2); + const XMVECTOR X = XMVectorMin(x1, x2); + XMStoreFloat3(&result, X); +} + +inline Vector3 Vector3::Min(const Vector3& v1, const Vector3& v2) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&v2); + const XMVECTOR X = XMVectorMin(x1, x2); + + Vector3 result; + XMStoreFloat3(&result, X); + return result; +} + +inline void Vector3::Max(const Vector3& v1, const Vector3& v2, Vector3& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&v2); + const XMVECTOR X = XMVectorMax(x1, x2); + XMStoreFloat3(&result, X); +} + +inline Vector3 Vector3::Max(const Vector3& v1, const Vector3& v2) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&v2); + const XMVECTOR X = XMVectorMax(x1, x2); + + Vector3 result; + XMStoreFloat3(&result, X); + return result; +} + +inline void Vector3::Lerp(const Vector3& v1, const Vector3& v2, float t, Vector3& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&v2); + const XMVECTOR X = XMVectorLerp(x1, x2, t); + XMStoreFloat3(&result, X); +} + +inline Vector3 Vector3::Lerp(const Vector3& v1, const Vector3& v2, float t) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&v2); + const XMVECTOR X = XMVectorLerp(x1, x2, t); + + Vector3 result; + XMStoreFloat3(&result, X); + return result; +} + +inline void Vector3::SmoothStep(const Vector3& v1, const Vector3& v2, float t, Vector3& result) noexcept +{ + using namespace DirectX; + t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t); // Clamp value to 0 to 1 + t = t * t*(3.f - 2.f*t); + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&v2); + const XMVECTOR X = XMVectorLerp(x1, x2, t); + XMStoreFloat3(&result, X); +} + +inline Vector3 Vector3::SmoothStep(const Vector3& v1, const Vector3& v2, float t) noexcept +{ + using namespace DirectX; + t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t); // Clamp value to 0 to 1 + t = t * t*(3.f - 2.f*t); + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&v2); + const XMVECTOR X = XMVectorLerp(x1, x2, t); + + Vector3 result; + XMStoreFloat3(&result, X); + return result; +} + +inline void Vector3::Barycentric(const Vector3& v1, const Vector3& v2, const Vector3& v3, float f, float g, Vector3& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&v2); + const XMVECTOR x3 = XMLoadFloat3(&v3); + const XMVECTOR X = XMVectorBaryCentric(x1, x2, x3, f, g); + XMStoreFloat3(&result, X); +} + +inline Vector3 Vector3::Barycentric(const Vector3& v1, const Vector3& v2, const Vector3& v3, float f, float g) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&v2); + const XMVECTOR x3 = XMLoadFloat3(&v3); + const XMVECTOR X = XMVectorBaryCentric(x1, x2, x3, f, g); + + Vector3 result; + XMStoreFloat3(&result, X); + return result; +} + +inline void Vector3::CatmullRom(const Vector3& v1, const Vector3& v2, const Vector3& v3, const Vector3& v4, float t, Vector3& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&v2); + const XMVECTOR x3 = XMLoadFloat3(&v3); + const XMVECTOR x4 = XMLoadFloat3(&v4); + const XMVECTOR X = XMVectorCatmullRom(x1, x2, x3, x4, t); + XMStoreFloat3(&result, X); +} + +inline Vector3 Vector3::CatmullRom(const Vector3& v1, const Vector3& v2, const Vector3& v3, const Vector3& v4, float t) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&v2); + const XMVECTOR x3 = XMLoadFloat3(&v3); + const XMVECTOR x4 = XMLoadFloat3(&v4); + const XMVECTOR X = XMVectorCatmullRom(x1, x2, x3, x4, t); + + Vector3 result; + XMStoreFloat3(&result, X); + return result; +} + +inline void Vector3::Hermite(const Vector3& v1, const Vector3& t1, const Vector3& v2, const Vector3& t2, float t, Vector3& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&t1); + const XMVECTOR x3 = XMLoadFloat3(&v2); + const XMVECTOR x4 = XMLoadFloat3(&t2); + const XMVECTOR X = XMVectorHermite(x1, x2, x3, x4, t); + XMStoreFloat3(&result, X); +} + +inline Vector3 Vector3::Hermite(const Vector3& v1, const Vector3& t1, const Vector3& v2, const Vector3& t2, float t) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat3(&v1); + const XMVECTOR x2 = XMLoadFloat3(&t1); + const XMVECTOR x3 = XMLoadFloat3(&v2); + const XMVECTOR x4 = XMLoadFloat3(&t2); + const XMVECTOR X = XMVectorHermite(x1, x2, x3, x4, t); + + Vector3 result; + XMStoreFloat3(&result, X); + return result; +} + +inline void Vector3::Reflect(const Vector3& ivec, const Vector3& nvec, Vector3& result) noexcept +{ + using namespace DirectX; + const XMVECTOR i = XMLoadFloat3(&ivec); + const XMVECTOR n = XMLoadFloat3(&nvec); + const XMVECTOR X = XMVector3Reflect(i, n); + XMStoreFloat3(&result, X); +} + +inline Vector3 Vector3::Reflect(const Vector3& ivec, const Vector3& nvec) noexcept +{ + using namespace DirectX; + const XMVECTOR i = XMLoadFloat3(&ivec); + const XMVECTOR n = XMLoadFloat3(&nvec); + const XMVECTOR X = XMVector3Reflect(i, n); + + Vector3 result; + XMStoreFloat3(&result, X); + return result; +} + +inline void Vector3::Refract(const Vector3& ivec, const Vector3& nvec, float refractionIndex, Vector3& result) noexcept +{ + using namespace DirectX; + const XMVECTOR i = XMLoadFloat3(&ivec); + const XMVECTOR n = XMLoadFloat3(&nvec); + const XMVECTOR X = XMVector3Refract(i, n, refractionIndex); + XMStoreFloat3(&result, X); +} + +inline Vector3 Vector3::Refract(const Vector3& ivec, const Vector3& nvec, float refractionIndex) noexcept +{ + using namespace DirectX; + const XMVECTOR i = XMLoadFloat3(&ivec); + const XMVECTOR n = XMLoadFloat3(&nvec); + const XMVECTOR X = XMVector3Refract(i, n, refractionIndex); + + Vector3 result; + XMStoreFloat3(&result, X); + return result; +} + +inline void Vector3::Transform(const Vector3& v, const Quaternion& quat, Vector3& result) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&v); + const XMVECTOR q = XMLoadFloat4(&quat); + const XMVECTOR X = XMVector3Rotate(v1, q); + XMStoreFloat3(&result, X); +} + +inline Vector3 Vector3::Transform(const Vector3& v, const Quaternion& quat) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&v); + const XMVECTOR q = XMLoadFloat4(&quat); + const XMVECTOR X = XMVector3Rotate(v1, q); + + Vector3 result; + XMStoreFloat3(&result, X); + return result; +} + +inline void Vector3::Transform(const Vector3& v, const Matrix& m, Vector3& result) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&v); + const XMMATRIX M = XMLoadFloat4x4(&m); + const XMVECTOR X = XMVector3TransformCoord(v1, M); + XMStoreFloat3(&result, X); +} + +inline Vector3 Vector3::Transform(const Vector3& v, const Matrix& m) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&v); + const XMMATRIX M = XMLoadFloat4x4(&m); + const XMVECTOR X = XMVector3TransformCoord(v1, M); + + Vector3 result; + XMStoreFloat3(&result, X); + return result; +} + +_Use_decl_annotations_ +inline void Vector3::Transform(const Vector3* varray, size_t count, const Matrix& m, Vector3* resultArray) noexcept +{ + using namespace DirectX; + const XMMATRIX M = XMLoadFloat4x4(&m); + XMVector3TransformCoordStream(resultArray, sizeof(XMFLOAT3), varray, sizeof(XMFLOAT3), count, M); +} + +inline void Vector3::Transform(const Vector3& v, const Matrix& m, Vector4& result) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&v); + const XMMATRIX M = XMLoadFloat4x4(&m); + const XMVECTOR X = XMVector3Transform(v1, M); + XMStoreFloat4(&result, X); +} + +_Use_decl_annotations_ +inline void Vector3::Transform(const Vector3* varray, size_t count, const Matrix& m, Vector4* resultArray) noexcept +{ + using namespace DirectX; + const XMMATRIX M = XMLoadFloat4x4(&m); + XMVector3TransformStream(resultArray, sizeof(XMFLOAT4), varray, sizeof(XMFLOAT3), count, M); +} + +inline void Vector3::TransformNormal(const Vector3& v, const Matrix& m, Vector3& result) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&v); + const XMMATRIX M = XMLoadFloat4x4(&m); + const XMVECTOR X = XMVector3TransformNormal(v1, M); + XMStoreFloat3(&result, X); +} + +inline Vector3 Vector3::TransformNormal(const Vector3& v, const Matrix& m) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&v); + const XMMATRIX M = XMLoadFloat4x4(&m); + const XMVECTOR X = XMVector3TransformNormal(v1, M); + + Vector3 result; + XMStoreFloat3(&result, X); + return result; +} + +_Use_decl_annotations_ +inline void Vector3::TransformNormal(const Vector3* varray, size_t count, const Matrix& m, Vector3* resultArray) noexcept +{ + using namespace DirectX; + const XMMATRIX M = XMLoadFloat4x4(&m); + XMVector3TransformNormalStream(resultArray, sizeof(XMFLOAT3), varray, sizeof(XMFLOAT3), count, M); +} + + +/**************************************************************************** + * + * Vector4 + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ +// Comparision operators +//------------------------------------------------------------------------------ + +inline bool Vector4::operator == (const Vector4& V) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR v2 = XMLoadFloat4(&V); + return XMVector4Equal(v1, v2); +} + +inline bool Vector4::operator != (const Vector4& V) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR v2 = XMLoadFloat4(&V); + return XMVector4NotEqual(v1, v2); +} + +//------------------------------------------------------------------------------ +// Assignment operators +//------------------------------------------------------------------------------ + +inline Vector4& Vector4::operator+= (const Vector4& V) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR v2 = XMLoadFloat4(&V); + const XMVECTOR X = XMVectorAdd(v1, v2); + XMStoreFloat4(this, X); + return *this; +} + +inline Vector4& Vector4::operator-= (const Vector4& V) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR v2 = XMLoadFloat4(&V); + const XMVECTOR X = XMVectorSubtract(v1, v2); + XMStoreFloat4(this, X); + return *this; +} + +inline Vector4& Vector4::operator*= (const Vector4& V) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR v2 = XMLoadFloat4(&V); + const XMVECTOR X = XMVectorMultiply(v1, v2); + XMStoreFloat4(this, X); + return *this; +} + +inline Vector4& Vector4::operator*= (float S) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR X = XMVectorScale(v1, S); + XMStoreFloat4(this, X); + return *this; +} + +inline Vector4& Vector4::operator/= (float S) noexcept +{ + using namespace DirectX; + assert(S != 0.0f); + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR X = XMVectorScale(v1, 1.f / S); + XMStoreFloat4(this, X); + return *this; +} + +//------------------------------------------------------------------------------ +// Urnary operators +//------------------------------------------------------------------------------ + +inline Vector4 Vector4::operator- () const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR X = XMVectorNegate(v1); + Vector4 R; + XMStoreFloat4(&R, X); + return R; +} + +//------------------------------------------------------------------------------ +// Binary operators +//------------------------------------------------------------------------------ + +inline Vector4 operator+ (const Vector4& V1, const Vector4& V2) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(&V1); + const XMVECTOR v2 = XMLoadFloat4(&V2); + const XMVECTOR X = XMVectorAdd(v1, v2); + Vector4 R; + XMStoreFloat4(&R, X); + return R; +} + +inline Vector4 operator- (const Vector4& V1, const Vector4& V2) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(&V1); + const XMVECTOR v2 = XMLoadFloat4(&V2); + const XMVECTOR X = XMVectorSubtract(v1, v2); + Vector4 R; + XMStoreFloat4(&R, X); + return R; +} + +inline Vector4 operator* (const Vector4& V1, const Vector4& V2) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(&V1); + const XMVECTOR v2 = XMLoadFloat4(&V2); + const XMVECTOR X = XMVectorMultiply(v1, v2); + Vector4 R; + XMStoreFloat4(&R, X); + return R; +} + +inline Vector4 operator* (const Vector4& V, float S) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(&V); + const XMVECTOR X = XMVectorScale(v1, S); + Vector4 R; + XMStoreFloat4(&R, X); + return R; +} + +inline Vector4 operator/ (const Vector4& V1, const Vector4& V2) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(&V1); + const XMVECTOR v2 = XMLoadFloat4(&V2); + const XMVECTOR X = XMVectorDivide(v1, v2); + Vector4 R; + XMStoreFloat4(&R, X); + return R; +} + +inline Vector4 operator/ (const Vector4& V, float S) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(&V); + const XMVECTOR X = XMVectorScale(v1, 1.f / S); + Vector4 R; + XMStoreFloat4(&R, X); + return R; +} + +inline Vector4 operator* (float S, const Vector4& V) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(&V); + const XMVECTOR X = XMVectorScale(v1, S); + Vector4 R; + XMStoreFloat4(&R, X); + return R; +} + +//------------------------------------------------------------------------------ +// Vector operations +//------------------------------------------------------------------------------ + +inline bool Vector4::InBounds(const Vector4& Bounds) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR v2 = XMLoadFloat4(&Bounds); + return XMVector4InBounds(v1, v2); +} + +inline float Vector4::Length() const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR X = XMVector4Length(v1); + return XMVectorGetX(X); +} + +inline float Vector4::LengthSquared() const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR X = XMVector4LengthSq(v1); + return XMVectorGetX(X); +} + +inline float Vector4::Dot(const Vector4& V) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR v2 = XMLoadFloat4(&V); + const XMVECTOR X = XMVector4Dot(v1, v2); + return XMVectorGetX(X); +} + +inline void Vector4::Cross(const Vector4& v1, const Vector4& v2, Vector4& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(this); + const XMVECTOR x2 = XMLoadFloat4(&v1); + const XMVECTOR x3 = XMLoadFloat4(&v2); + const XMVECTOR R = XMVector4Cross(x1, x2, x3); + XMStoreFloat4(&result, R); +} + +inline Vector4 Vector4::Cross(const Vector4& v1, const Vector4& v2) const noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(this); + const XMVECTOR x2 = XMLoadFloat4(&v1); + const XMVECTOR x3 = XMLoadFloat4(&v2); + const XMVECTOR R = XMVector4Cross(x1, x2, x3); + + Vector4 result; + XMStoreFloat4(&result, R); + return result; +} + +inline void Vector4::Normalize() noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR X = XMVector4Normalize(v1); + XMStoreFloat4(this, X); +} + +inline void Vector4::Normalize(Vector4& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR X = XMVector4Normalize(v1); + XMStoreFloat4(&result, X); +} + +inline void Vector4::Clamp(const Vector4& vmin, const Vector4& vmax) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR v2 = XMLoadFloat4(&vmin); + const XMVECTOR v3 = XMLoadFloat4(&vmax); + const XMVECTOR X = XMVectorClamp(v1, v2, v3); + XMStoreFloat4(this, X); +} + +inline void Vector4::Clamp(const Vector4& vmin, const Vector4& vmax, Vector4& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(this); + const XMVECTOR v2 = XMLoadFloat4(&vmin); + const XMVECTOR v3 = XMLoadFloat4(&vmax); + const XMVECTOR X = XMVectorClamp(v1, v2, v3); + XMStoreFloat4(&result, X); +} + +//------------------------------------------------------------------------------ +// Static functions +//------------------------------------------------------------------------------ + +inline float Vector4::Distance(const Vector4& v1, const Vector4& v2) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&v2); + const XMVECTOR V = XMVectorSubtract(x2, x1); + const XMVECTOR X = XMVector4Length(V); + return XMVectorGetX(X); +} + +inline float Vector4::DistanceSquared(const Vector4& v1, const Vector4& v2) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&v2); + const XMVECTOR V = XMVectorSubtract(x2, x1); + const XMVECTOR X = XMVector4LengthSq(V); + return XMVectorGetX(X); +} + +inline void Vector4::Min(const Vector4& v1, const Vector4& v2, Vector4& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&v2); + const XMVECTOR X = XMVectorMin(x1, x2); + XMStoreFloat4(&result, X); +} + +inline Vector4 Vector4::Min(const Vector4& v1, const Vector4& v2) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&v2); + const XMVECTOR X = XMVectorMin(x1, x2); + + Vector4 result; + XMStoreFloat4(&result, X); + return result; +} + +inline void Vector4::Max(const Vector4& v1, const Vector4& v2, Vector4& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&v2); + const XMVECTOR X = XMVectorMax(x1, x2); + XMStoreFloat4(&result, X); +} + +inline Vector4 Vector4::Max(const Vector4& v1, const Vector4& v2) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&v2); + const XMVECTOR X = XMVectorMax(x1, x2); + + Vector4 result; + XMStoreFloat4(&result, X); + return result; +} + +inline void Vector4::Lerp(const Vector4& v1, const Vector4& v2, float t, Vector4& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&v2); + const XMVECTOR X = XMVectorLerp(x1, x2, t); + XMStoreFloat4(&result, X); +} + +inline Vector4 Vector4::Lerp(const Vector4& v1, const Vector4& v2, float t) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&v2); + const XMVECTOR X = XMVectorLerp(x1, x2, t); + + Vector4 result; + XMStoreFloat4(&result, X); + return result; +} + +inline void Vector4::SmoothStep(const Vector4& v1, const Vector4& v2, float t, Vector4& result) noexcept +{ + using namespace DirectX; + t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t); // Clamp value to 0 to 1 + t = t * t*(3.f - 2.f*t); + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&v2); + const XMVECTOR X = XMVectorLerp(x1, x2, t); + XMStoreFloat4(&result, X); +} + +inline Vector4 Vector4::SmoothStep(const Vector4& v1, const Vector4& v2, float t) noexcept +{ + using namespace DirectX; + t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t); // Clamp value to 0 to 1 + t = t * t*(3.f - 2.f*t); + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&v2); + const XMVECTOR X = XMVectorLerp(x1, x2, t); + + Vector4 result; + XMStoreFloat4(&result, X); + return result; +} + +inline void Vector4::Barycentric(const Vector4& v1, const Vector4& v2, const Vector4& v3, float f, float g, Vector4& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&v2); + const XMVECTOR x3 = XMLoadFloat4(&v3); + const XMVECTOR X = XMVectorBaryCentric(x1, x2, x3, f, g); + XMStoreFloat4(&result, X); +} + +inline Vector4 Vector4::Barycentric(const Vector4& v1, const Vector4& v2, const Vector4& v3, float f, float g) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&v2); + const XMVECTOR x3 = XMLoadFloat4(&v3); + const XMVECTOR X = XMVectorBaryCentric(x1, x2, x3, f, g); + + Vector4 result; + XMStoreFloat4(&result, X); + return result; +} + +inline void Vector4::CatmullRom(const Vector4& v1, const Vector4& v2, const Vector4& v3, const Vector4& v4, float t, Vector4& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&v2); + const XMVECTOR x3 = XMLoadFloat4(&v3); + const XMVECTOR x4 = XMLoadFloat4(&v4); + const XMVECTOR X = XMVectorCatmullRom(x1, x2, x3, x4, t); + XMStoreFloat4(&result, X); +} + +inline Vector4 Vector4::CatmullRom(const Vector4& v1, const Vector4& v2, const Vector4& v3, const Vector4& v4, float t) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&v2); + const XMVECTOR x3 = XMLoadFloat4(&v3); + const XMVECTOR x4 = XMLoadFloat4(&v4); + const XMVECTOR X = XMVectorCatmullRom(x1, x2, x3, x4, t); + + Vector4 result; + XMStoreFloat4(&result, X); + return result; +} + +inline void Vector4::Hermite(const Vector4& v1, const Vector4& t1, const Vector4& v2, const Vector4& t2, float t, Vector4& result) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&t1); + const XMVECTOR x3 = XMLoadFloat4(&v2); + const XMVECTOR x4 = XMLoadFloat4(&t2); + const XMVECTOR X = XMVectorHermite(x1, x2, x3, x4, t); + XMStoreFloat4(&result, X); +} + +inline Vector4 Vector4::Hermite(const Vector4& v1, const Vector4& t1, const Vector4& v2, const Vector4& t2, float t) noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(&v1); + const XMVECTOR x2 = XMLoadFloat4(&t1); + const XMVECTOR x3 = XMLoadFloat4(&v2); + const XMVECTOR x4 = XMLoadFloat4(&t2); + const XMVECTOR X = XMVectorHermite(x1, x2, x3, x4, t); + + Vector4 result; + XMStoreFloat4(&result, X); + return result; +} + +inline void Vector4::Reflect(const Vector4& ivec, const Vector4& nvec, Vector4& result) noexcept +{ + using namespace DirectX; + const XMVECTOR i = XMLoadFloat4(&ivec); + const XMVECTOR n = XMLoadFloat4(&nvec); + const XMVECTOR X = XMVector4Reflect(i, n); + XMStoreFloat4(&result, X); +} + +inline Vector4 Vector4::Reflect(const Vector4& ivec, const Vector4& nvec) noexcept +{ + using namespace DirectX; + const XMVECTOR i = XMLoadFloat4(&ivec); + const XMVECTOR n = XMLoadFloat4(&nvec); + const XMVECTOR X = XMVector4Reflect(i, n); + + Vector4 result; + XMStoreFloat4(&result, X); + return result; +} + +inline void Vector4::Refract(const Vector4& ivec, const Vector4& nvec, float refractionIndex, Vector4& result) noexcept +{ + using namespace DirectX; + const XMVECTOR i = XMLoadFloat4(&ivec); + const XMVECTOR n = XMLoadFloat4(&nvec); + const XMVECTOR X = XMVector4Refract(i, n, refractionIndex); + XMStoreFloat4(&result, X); +} + +inline Vector4 Vector4::Refract(const Vector4& ivec, const Vector4& nvec, float refractionIndex) noexcept +{ + using namespace DirectX; + const XMVECTOR i = XMLoadFloat4(&ivec); + const XMVECTOR n = XMLoadFloat4(&nvec); + const XMVECTOR X = XMVector4Refract(i, n, refractionIndex); + + Vector4 result; + XMStoreFloat4(&result, X); + return result; +} + +inline void Vector4::Transform(const Vector2& v, const Quaternion& quat, Vector4& result) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&v); + const XMVECTOR q = XMLoadFloat4(&quat); + XMVECTOR X = XMVector3Rotate(v1, q); + X = XMVectorSelect(g_XMIdentityR3, X, g_XMSelect1110); // result.w = 1.f + XMStoreFloat4(&result, X); +} + +inline Vector4 Vector4::Transform(const Vector2& v, const Quaternion& quat) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat2(&v); + const XMVECTOR q = XMLoadFloat4(&quat); + XMVECTOR X = XMVector3Rotate(v1, q); + X = XMVectorSelect(g_XMIdentityR3, X, g_XMSelect1110); // result.w = 1.f + + Vector4 result; + XMStoreFloat4(&result, X); + return result; +} + +inline void Vector4::Transform(const Vector3& v, const Quaternion& quat, Vector4& result) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&v); + const XMVECTOR q = XMLoadFloat4(&quat); + XMVECTOR X = XMVector3Rotate(v1, q); + X = XMVectorSelect(g_XMIdentityR3, X, g_XMSelect1110); // result.w = 1.f + XMStoreFloat4(&result, X); +} + +inline Vector4 Vector4::Transform(const Vector3& v, const Quaternion& quat) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat3(&v); + const XMVECTOR q = XMLoadFloat4(&quat); + XMVECTOR X = XMVector3Rotate(v1, q); + X = XMVectorSelect(g_XMIdentityR3, X, g_XMSelect1110); // result.w = 1.f + + Vector4 result; + XMStoreFloat4(&result, X); + return result; +} + +inline void Vector4::Transform(const Vector4& v, const Quaternion& quat, Vector4& result) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(&v); + const XMVECTOR q = XMLoadFloat4(&quat); + XMVECTOR X = XMVector3Rotate(v1, q); + X = XMVectorSelect(v1, X, g_XMSelect1110); // result.w = v.w + XMStoreFloat4(&result, X); +} + +inline Vector4 Vector4::Transform(const Vector4& v, const Quaternion& quat) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(&v); + const XMVECTOR q = XMLoadFloat4(&quat); + XMVECTOR X = XMVector3Rotate(v1, q); + X = XMVectorSelect(v1, X, g_XMSelect1110); // result.w = v.w + + Vector4 result; + XMStoreFloat4(&result, X); + return result; +} + +inline void Vector4::Transform(const Vector4& v, const Matrix& m, Vector4& result) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(&v); + const XMMATRIX M = XMLoadFloat4x4(&m); + const XMVECTOR X = XMVector4Transform(v1, M); + XMStoreFloat4(&result, X); +} + +inline Vector4 Vector4::Transform(const Vector4& v, const Matrix& m) noexcept +{ + using namespace DirectX; + const XMVECTOR v1 = XMLoadFloat4(&v); + const XMMATRIX M = XMLoadFloat4x4(&m); + const XMVECTOR X = XMVector4Transform(v1, M); + + Vector4 result; + XMStoreFloat4(&result, X); + return result; +} + +_Use_decl_annotations_ +inline void Vector4::Transform(const Vector4* varray, size_t count, const Matrix& m, Vector4* resultArray) noexcept +{ + using namespace DirectX; + const XMMATRIX M = XMLoadFloat4x4(&m); + XMVector4TransformStream(resultArray, sizeof(XMFLOAT4), varray, sizeof(XMFLOAT4), count, M); +} + + +/**************************************************************************** + * + * Matrix + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ +// Comparision operators +//------------------------------------------------------------------------------ + +inline bool Matrix::operator == (const Matrix& M) const noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&_11)); + const XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&_21)); + const XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&_31)); + const XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&_41)); + + const XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M._11)); + const XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M._21)); + const XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M._31)); + const XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M._41)); + + return (XMVector4Equal(x1, y1) + && XMVector4Equal(x2, y2) + && XMVector4Equal(x3, y3) + && XMVector4Equal(x4, y4)) != 0; +} + +inline bool Matrix::operator != (const Matrix& M) const noexcept +{ + using namespace DirectX; + const XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&_11)); + const XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&_21)); + const XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&_31)); + const XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&_41)); + + const XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M._11)); + const XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M._21)); + const XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M._31)); + const XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M._41)); + + return (XMVector4NotEqual(x1, y1) + || XMVector4NotEqual(x2, y2) + || XMVector4NotEqual(x3, y3) + || XMVector4NotEqual(x4, y4)) != 0; +} + +//------------------------------------------------------------------------------ +// Assignment operators +//------------------------------------------------------------------------------ + +inline Matrix::Matrix(const XMFLOAT3X3& M) noexcept +{ + _11 = M._11; _12 = M._12; _13 = M._13; _14 = 0.f; + _21 = M._21; _22 = M._22; _23 = M._23; _24 = 0.f; + _31 = M._31; _32 = M._32; _33 = M._33; _34 = 0.f; + _41 = 0.f; _42 = 0.f; _43 = 0.f; _44 = 1.f; +} + +inline Matrix::Matrix(const XMFLOAT4X3& M) noexcept +{ + _11 = M._11; _12 = M._12; _13 = M._13; _14 = 0.f; + _21 = M._21; _22 = M._22; _23 = M._23; _24 = 0.f; + _31 = M._31; _32 = M._32; _33 = M._33; _34 = 0.f; + _41 = M._41; _42 = M._42; _43 = M._43; _44 = 1.f; +} + +inline Matrix& Matrix::operator= (const XMFLOAT3X3& M) noexcept +{ + _11 = M._11; _12 = M._12; _13 = M._13; _14 = 0.f; + _21 = M._21; _22 = M._22; _23 = M._23; _24 = 0.f; + _31 = M._31; _32 = M._32; _33 = M._33; _34 = 0.f; + _41 = 0.f; _42 = 0.f; _43 = 0.f; _44 = 1.f; + return *this; +} + +inline Matrix& Matrix::operator= (const XMFLOAT4X3& M) noexcept +{ + _11 = M._11; _12 = M._12; _13 = M._13; _14 = 0.f; + _21 = M._21; _22 = M._22; _23 = M._23; _24 = 0.f; + _31 = M._31; _32 = M._32; _33 = M._33; _34 = 0.f; + _41 = M._41; _42 = M._42; _43 = M._43; _44 = 1.f; + return *this; +} + +inline Matrix& Matrix::operator+= (const Matrix& M) noexcept +{ + using namespace DirectX; + XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&_11)); + XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&_21)); + XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&_31)); + XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&_41)); + + const XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M._11)); + const XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M._21)); + const XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M._31)); + const XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M._41)); + + x1 = XMVectorAdd(x1, y1); + x2 = XMVectorAdd(x2, y2); + x3 = XMVectorAdd(x3, y3); + x4 = XMVectorAdd(x4, y4); + + XMStoreFloat4(reinterpret_cast(&_11), x1); + XMStoreFloat4(reinterpret_cast(&_21), x2); + XMStoreFloat4(reinterpret_cast(&_31), x3); + XMStoreFloat4(reinterpret_cast(&_41), x4); + return *this; +} + +inline Matrix& Matrix::operator-= (const Matrix& M) noexcept +{ + using namespace DirectX; + XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&_11)); + XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&_21)); + XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&_31)); + XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&_41)); + + const XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M._11)); + const XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M._21)); + const XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M._31)); + const XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M._41)); + + x1 = XMVectorSubtract(x1, y1); + x2 = XMVectorSubtract(x2, y2); + x3 = XMVectorSubtract(x3, y3); + x4 = XMVectorSubtract(x4, y4); + + XMStoreFloat4(reinterpret_cast(&_11), x1); + XMStoreFloat4(reinterpret_cast(&_21), x2); + XMStoreFloat4(reinterpret_cast(&_31), x3); + XMStoreFloat4(reinterpret_cast(&_41), x4); + return *this; +} + +inline Matrix& Matrix::operator*= (const Matrix& M) noexcept +{ + using namespace DirectX; + const XMMATRIX M1 = XMLoadFloat4x4(this); + const XMMATRIX M2 = XMLoadFloat4x4(&M); + const XMMATRIX X = XMMatrixMultiply(M1, M2); + XMStoreFloat4x4(this, X); + return *this; +} + +inline Matrix& Matrix::operator*= (float S) noexcept +{ + using namespace DirectX; + XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&_11)); + XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&_21)); + XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&_31)); + XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&_41)); + + x1 = XMVectorScale(x1, S); + x2 = XMVectorScale(x2, S); + x3 = XMVectorScale(x3, S); + x4 = XMVectorScale(x4, S); + + XMStoreFloat4(reinterpret_cast(&_11), x1); + XMStoreFloat4(reinterpret_cast(&_21), x2); + XMStoreFloat4(reinterpret_cast(&_31), x3); + XMStoreFloat4(reinterpret_cast(&_41), x4); + return *this; +} + +inline Matrix& Matrix::operator/= (float S) noexcept +{ + using namespace DirectX; + assert(S != 0.f); + XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&_11)); + XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&_21)); + XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&_31)); + XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&_41)); + + const float rs = 1.f / S; + + x1 = XMVectorScale(x1, rs); + x2 = XMVectorScale(x2, rs); + x3 = XMVectorScale(x3, rs); + x4 = XMVectorScale(x4, rs); + + XMStoreFloat4(reinterpret_cast(&_11), x1); + XMStoreFloat4(reinterpret_cast(&_21), x2); + XMStoreFloat4(reinterpret_cast(&_31), x3); + XMStoreFloat4(reinterpret_cast(&_41), x4); + return *this; +} + +inline Matrix& Matrix::operator/= (const Matrix& M) noexcept +{ + using namespace DirectX; + XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&_11)); + XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&_21)); + XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&_31)); + XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&_41)); + + const XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M._11)); + const XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M._21)); + const XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M._31)); + const XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M._41)); + + x1 = XMVectorDivide(x1, y1); + x2 = XMVectorDivide(x2, y2); + x3 = XMVectorDivide(x3, y3); + x4 = XMVectorDivide(x4, y4); + + XMStoreFloat4(reinterpret_cast(&_11), x1); + XMStoreFloat4(reinterpret_cast(&_21), x2); + XMStoreFloat4(reinterpret_cast(&_31), x3); + XMStoreFloat4(reinterpret_cast(&_41), x4); + return *this; +} + +//------------------------------------------------------------------------------ +// Urnary operators +//------------------------------------------------------------------------------ + +inline Matrix Matrix::operator- () const noexcept +{ + using namespace DirectX; + XMVECTOR v1 = XMLoadFloat4(reinterpret_cast(&_11)); + XMVECTOR v2 = XMLoadFloat4(reinterpret_cast(&_21)); + XMVECTOR v3 = XMLoadFloat4(reinterpret_cast(&_31)); + XMVECTOR v4 = XMLoadFloat4(reinterpret_cast(&_41)); + + v1 = XMVectorNegate(v1); + v2 = XMVectorNegate(v2); + v3 = XMVectorNegate(v3); + v4 = XMVectorNegate(v4); + + Matrix R; + XMStoreFloat4(reinterpret_cast(&R._11), v1); + XMStoreFloat4(reinterpret_cast(&R._21), v2); + XMStoreFloat4(reinterpret_cast(&R._31), v3); + XMStoreFloat4(reinterpret_cast(&R._41), v4); + return R; +} + +//------------------------------------------------------------------------------ +// Binary operators +//------------------------------------------------------------------------------ + +inline Matrix operator+ (const Matrix& M1, const Matrix& M2) noexcept +{ + using namespace DirectX; + XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M1._11)); + XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M1._21)); + XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M1._31)); + XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M1._41)); + + const XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M2._11)); + const XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M2._21)); + const XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M2._31)); + const XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M2._41)); + + x1 = XMVectorAdd(x1, y1); + x2 = XMVectorAdd(x2, y2); + x3 = XMVectorAdd(x3, y3); + x4 = XMVectorAdd(x4, y4); + + Matrix R; + XMStoreFloat4(reinterpret_cast(&R._11), x1); + XMStoreFloat4(reinterpret_cast(&R._21), x2); + XMStoreFloat4(reinterpret_cast(&R._31), x3); + XMStoreFloat4(reinterpret_cast(&R._41), x4); + return R; +} + +inline Matrix operator- (const Matrix& M1, const Matrix& M2) noexcept +{ + using namespace DirectX; + XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M1._11)); + XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M1._21)); + XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M1._31)); + XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M1._41)); + + const XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M2._11)); + const XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M2._21)); + const XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M2._31)); + const XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M2._41)); + + x1 = XMVectorSubtract(x1, y1); + x2 = XMVectorSubtract(x2, y2); + x3 = XMVectorSubtract(x3, y3); + x4 = XMVectorSubtract(x4, y4); + + Matrix R; + XMStoreFloat4(reinterpret_cast(&R._11), x1); + XMStoreFloat4(reinterpret_cast(&R._21), x2); + XMStoreFloat4(reinterpret_cast(&R._31), x3); + XMStoreFloat4(reinterpret_cast(&R._41), x4); + return R; +} + +inline Matrix operator* (const Matrix& M1, const Matrix& M2) noexcept +{ + using namespace DirectX; + const XMMATRIX m1 = XMLoadFloat4x4(&M1); + const XMMATRIX m2 = XMLoadFloat4x4(&M2); + const XMMATRIX X = XMMatrixMultiply(m1, m2); + + Matrix R; + XMStoreFloat4x4(&R, X); + return R; +} + +inline Matrix operator* (const Matrix& M, float S) noexcept +{ + using namespace DirectX; + XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M._11)); + XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M._21)); + XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M._31)); + XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M._41)); + + x1 = XMVectorScale(x1, S); + x2 = XMVectorScale(x2, S); + x3 = XMVectorScale(x3, S); + x4 = XMVectorScale(x4, S); + + Matrix R; + XMStoreFloat4(reinterpret_cast(&R._11), x1); + XMStoreFloat4(reinterpret_cast(&R._21), x2); + XMStoreFloat4(reinterpret_cast(&R._31), x3); + XMStoreFloat4(reinterpret_cast(&R._41), x4); + return R; +} + +inline Matrix operator/ (const Matrix& M, float S) noexcept +{ + using namespace DirectX; + assert(S != 0.f); + + XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M._11)); + XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M._21)); + XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M._31)); + XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M._41)); + + const float rs = 1.f / S; + + x1 = XMVectorScale(x1, rs); + x2 = XMVectorScale(x2, rs); + x3 = XMVectorScale(x3, rs); + x4 = XMVectorScale(x4, rs); + + Matrix R; + XMStoreFloat4(reinterpret_cast(&R._11), x1); + XMStoreFloat4(reinterpret_cast(&R._21), x2); + XMStoreFloat4(reinterpret_cast(&R._31), x3); + XMStoreFloat4(reinterpret_cast(&R._41), x4); + return R; +} + +inline Matrix operator/ (const Matrix& M1, const Matrix& M2) noexcept +{ + using namespace DirectX; + XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M1._11)); + XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M1._21)); + XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M1._31)); + XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M1._41)); + + const XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M2._11)); + const XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M2._21)); + const XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M2._31)); + const XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M2._41)); + + x1 = XMVectorDivide(x1, y1); + x2 = XMVectorDivide(x2, y2); + x3 = XMVectorDivide(x3, y3); + x4 = XMVectorDivide(x4, y4); + + Matrix R; + XMStoreFloat4(reinterpret_cast(&R._11), x1); + XMStoreFloat4(reinterpret_cast(&R._21), x2); + XMStoreFloat4(reinterpret_cast(&R._31), x3); + XMStoreFloat4(reinterpret_cast(&R._41), x4); + return R; +} + +inline Matrix operator* (float S, const Matrix& M) noexcept +{ + using namespace DirectX; + + XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M._11)); + XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M._21)); + XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M._31)); + XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M._41)); + + x1 = XMVectorScale(x1, S); + x2 = XMVectorScale(x2, S); + x3 = XMVectorScale(x3, S); + x4 = XMVectorScale(x4, S); + + Matrix R; + XMStoreFloat4(reinterpret_cast(&R._11), x1); + XMStoreFloat4(reinterpret_cast(&R._21), x2); + XMStoreFloat4(reinterpret_cast(&R._31), x3); + XMStoreFloat4(reinterpret_cast(&R._41), x4); + return R; +} + +//------------------------------------------------------------------------------ +// Matrix operations +//------------------------------------------------------------------------------ + +inline bool Matrix::Decompose(Vector3& scale, Quaternion& rotation, Vector3& translation) noexcept +{ + using namespace DirectX; + + XMVECTOR s, r, t; + + if (!XMMatrixDecompose(&s, &r, &t, *this)) + return false; + + XMStoreFloat3(&scale, s); + XMStoreFloat4(&rotation, r); + XMStoreFloat3(&translation, t); + + return true; +} + +inline Matrix Matrix::Transpose() const noexcept +{ + using namespace DirectX; + const XMMATRIX M = XMLoadFloat4x4(this); + Matrix R; + XMStoreFloat4x4(&R, XMMatrixTranspose(M)); + return R; +} + +inline void Matrix::Transpose(Matrix& result) const noexcept +{ + using namespace DirectX; + const XMMATRIX M = XMLoadFloat4x4(this); + XMStoreFloat4x4(&result, XMMatrixTranspose(M)); +} + +inline Matrix Matrix::Invert() const noexcept +{ + using namespace DirectX; + const XMMATRIX M = XMLoadFloat4x4(this); + Matrix R; + XMVECTOR det; + XMStoreFloat4x4(&R, XMMatrixInverse(&det, M)); + return R; +} + +inline void Matrix::Invert(Matrix& result) const noexcept +{ + using namespace DirectX; + const XMMATRIX M = XMLoadFloat4x4(this); + XMVECTOR det; + XMStoreFloat4x4(&result, XMMatrixInverse(&det, M)); +} + +inline float Matrix::Determinant() const noexcept +{ + using namespace DirectX; + const XMMATRIX M = XMLoadFloat4x4(this); + return XMVectorGetX(XMMatrixDeterminant(M)); +} + +inline Vector3 Matrix::ToEuler() const noexcept +{ + const float cy = sqrtf(_33 * _33 + _31 * _31); + const float cx = atan2f(-_32, cy); + if (cy > 16.f * FLT_EPSILON) + { + return Vector3(cx, atan2f(_31, _33), atan2f(_12, _22)); + } + else + { + return Vector3(cx, 0.f, atan2f(-_21, _11)); + } +} + +//------------------------------------------------------------------------------ +// Static functions +//------------------------------------------------------------------------------ + +_Use_decl_annotations_ +inline Matrix Matrix::CreateBillboard( + const Vector3& object, + const Vector3& cameraPosition, + const Vector3& cameraUp, + const Vector3* cameraForward) noexcept +{ + using namespace DirectX; + const XMVECTOR O = XMLoadFloat3(&object); + const XMVECTOR C = XMLoadFloat3(&cameraPosition); + XMVECTOR Z = XMVectorSubtract(O, C); + + const XMVECTOR N = XMVector3LengthSq(Z); + if (XMVector3Less(N, g_XMEpsilon)) + { + if (cameraForward) + { + const XMVECTOR F = XMLoadFloat3(cameraForward); + Z = XMVectorNegate(F); + } + else + Z = g_XMNegIdentityR2; + } + else + { + Z = XMVector3Normalize(Z); + } + + const XMVECTOR up = XMLoadFloat3(&cameraUp); + XMVECTOR X = XMVector3Cross(up, Z); + X = XMVector3Normalize(X); + + const XMVECTOR Y = XMVector3Cross(Z, X); + + XMMATRIX M; + M.r[0] = X; + M.r[1] = Y; + M.r[2] = Z; + M.r[3] = XMVectorSetW(O, 1.f); + + Matrix R; + XMStoreFloat4x4(&R, M); + return R; +} + +_Use_decl_annotations_ +inline Matrix Matrix::CreateConstrainedBillboard( + const Vector3& object, + const Vector3& cameraPosition, + const Vector3& rotateAxis, + const Vector3* cameraForward, + const Vector3* objectForward) noexcept +{ + using namespace DirectX; + + static const XMVECTORF32 s_minAngle = { { { 0.99825467075f, 0.99825467075f, 0.99825467075f, 0.99825467075f } } }; // 1.0 - XMConvertToRadians( 0.1f ); + + const XMVECTOR O = XMLoadFloat3(&object); + const XMVECTOR C = XMLoadFloat3(&cameraPosition); + XMVECTOR faceDir = XMVectorSubtract(O, C); + + const XMVECTOR N = XMVector3LengthSq(faceDir); + if (XMVector3Less(N, g_XMEpsilon)) + { + if (cameraForward) + { + const XMVECTOR F = XMLoadFloat3(cameraForward); + faceDir = XMVectorNegate(F); + } + else + faceDir = g_XMNegIdentityR2; + } + else + { + faceDir = XMVector3Normalize(faceDir); + } + + const XMVECTOR Y = XMLoadFloat3(&rotateAxis); + XMVECTOR X, Z; + + XMVECTOR dot = XMVectorAbs(XMVector3Dot(Y, faceDir)); + if (XMVector3Greater(dot, s_minAngle)) + { + if (objectForward) + { + Z = XMLoadFloat3(objectForward); + dot = XMVectorAbs(XMVector3Dot(Y, Z)); + if (XMVector3Greater(dot, s_minAngle)) + { + dot = XMVectorAbs(XMVector3Dot(Y, g_XMNegIdentityR2)); + Z = (XMVector3Greater(dot, s_minAngle)) ? g_XMIdentityR0 : g_XMNegIdentityR2; + } + } + else + { + dot = XMVectorAbs(XMVector3Dot(Y, g_XMNegIdentityR2)); + Z = (XMVector3Greater(dot, s_minAngle)) ? g_XMIdentityR0 : g_XMNegIdentityR2; + } + + X = XMVector3Cross(Y, Z); + X = XMVector3Normalize(X); + + Z = XMVector3Cross(X, Y); + Z = XMVector3Normalize(Z); + } + else + { + X = XMVector3Cross(Y, faceDir); + X = XMVector3Normalize(X); + + Z = XMVector3Cross(X, Y); + Z = XMVector3Normalize(Z); + } + + XMMATRIX M; + M.r[0] = X; + M.r[1] = Y; + M.r[2] = Z; + M.r[3] = XMVectorSetW(O, 1.f); + + Matrix R; + XMStoreFloat4x4(&R, M); + return R; +} + +inline Matrix Matrix::CreateTranslation(const Vector3& position) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixTranslation(position.x, position.y, position.z)); + return R; +} + +inline Matrix Matrix::CreateTranslation(float x, float y, float z) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixTranslation(x, y, z)); + return R; +} + +inline Matrix Matrix::CreateScale(const Vector3& scales) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixScaling(scales.x, scales.y, scales.z)); + return R; +} + +inline Matrix Matrix::CreateScale(float xs, float ys, float zs) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixScaling(xs, ys, zs)); + return R; +} + +inline Matrix Matrix::CreateScale(float scale) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixScaling(scale, scale, scale)); + return R; +} + +inline Matrix Matrix::CreateRotationX(float radians) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixRotationX(radians)); + return R; +} + +inline Matrix Matrix::CreateRotationY(float radians) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixRotationY(radians)); + return R; +} + +inline Matrix Matrix::CreateRotationZ(float radians) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixRotationZ(radians)); + return R; +} + +inline Matrix Matrix::CreateFromAxisAngle(const Vector3& axis, float angle) noexcept +{ + using namespace DirectX; + Matrix R; + const XMVECTOR a = XMLoadFloat3(&axis); + XMStoreFloat4x4(&R, XMMatrixRotationAxis(a, angle)); + return R; +} + +inline Matrix Matrix::CreatePerspectiveFieldOfView(float fov, float aspectRatio, float nearPlane, float farPlane) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixPerspectiveFovRH(fov, aspectRatio, nearPlane, farPlane)); + return R; +} + +inline Matrix Matrix::CreatePerspective(float width, float height, float nearPlane, float farPlane) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixPerspectiveRH(width, height, nearPlane, farPlane)); + return R; +} + +inline Matrix Matrix::CreatePerspectiveOffCenter(float left, float right, float bottom, float top, float nearPlane, float farPlane) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixPerspectiveOffCenterRH(left, right, bottom, top, nearPlane, farPlane)); + return R; +} + +inline Matrix Matrix::CreateOrthographic(float width, float height, float zNearPlane, float zFarPlane) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixOrthographicRH(width, height, zNearPlane, zFarPlane)); + return R; +} + +inline Matrix Matrix::CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNearPlane, float zFarPlane) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixOrthographicOffCenterRH(left, right, bottom, top, zNearPlane, zFarPlane)); + return R; +} + +inline Matrix Matrix::CreateLookAt(const Vector3& eye, const Vector3& target, const Vector3& up) noexcept +{ + using namespace DirectX; + Matrix R; + const XMVECTOR eyev = XMLoadFloat3(&eye); + const XMVECTOR targetv = XMLoadFloat3(&target); + const XMVECTOR upv = XMLoadFloat3(&up); + XMStoreFloat4x4(&R, XMMatrixLookAtRH(eyev, targetv, upv)); + return R; +} + +inline Matrix Matrix::CreateWorld(const Vector3& position, const Vector3& forward, const Vector3& up) noexcept +{ + using namespace DirectX; + const XMVECTOR zaxis = XMVector3Normalize(XMVectorNegate(XMLoadFloat3(&forward))); + XMVECTOR yaxis = XMLoadFloat3(&up); + const XMVECTOR xaxis = XMVector3Normalize(XMVector3Cross(yaxis, zaxis)); + yaxis = XMVector3Cross(zaxis, xaxis); + + Matrix R; + XMStoreFloat3(reinterpret_cast(&R._11), xaxis); + XMStoreFloat3(reinterpret_cast(&R._21), yaxis); + XMStoreFloat3(reinterpret_cast(&R._31), zaxis); + R._14 = R._24 = R._34 = 0.f; + R._41 = position.x; R._42 = position.y; R._43 = position.z; + R._44 = 1.f; + return R; +} + +inline Matrix Matrix::CreateFromQuaternion(const Quaternion& rotation) noexcept +{ + using namespace DirectX; + const XMVECTOR quatv = XMLoadFloat4(&rotation); + Matrix R; + XMStoreFloat4x4(&R, XMMatrixRotationQuaternion(quatv)); + return R; +} + +inline Matrix Matrix::CreateFromYawPitchRoll(float yaw, float pitch, float roll) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixRotationRollPitchYaw(pitch, yaw, roll)); + return R; +} + +inline Matrix Matrix::CreateFromYawPitchRoll(const Vector3& angles) noexcept +{ + using namespace DirectX; + Matrix R; + XMStoreFloat4x4(&R, XMMatrixRotationRollPitchYawFromVector(angles)); + return R; +} + +inline Matrix Matrix::CreateShadow(const Vector3& lightDir, const Plane& plane) noexcept +{ + using namespace DirectX; + const XMVECTOR light = XMLoadFloat3(&lightDir); + const XMVECTOR planev = XMLoadFloat4(&plane); + Matrix R; + XMStoreFloat4x4(&R, XMMatrixShadow(planev, light)); + return R; +} + +inline Matrix Matrix::CreateReflection(const Plane& plane) noexcept +{ + using namespace DirectX; + const XMVECTOR planev = XMLoadFloat4(&plane); + Matrix R; + XMStoreFloat4x4(&R, XMMatrixReflect(planev)); + return R; +} + +inline void Matrix::Lerp(const Matrix& M1, const Matrix& M2, float t, Matrix& result) noexcept +{ + using namespace DirectX; + XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M1._11)); + XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M1._21)); + XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M1._31)); + XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M1._41)); + + const XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M2._11)); + const XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M2._21)); + const XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M2._31)); + const XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M2._41)); + + x1 = XMVectorLerp(x1, y1, t); + x2 = XMVectorLerp(x2, y2, t); + x3 = XMVectorLerp(x3, y3, t); + x4 = XMVectorLerp(x4, y4, t); + + XMStoreFloat4(reinterpret_cast(&result._11), x1); + XMStoreFloat4(reinterpret_cast(&result._21), x2); + XMStoreFloat4(reinterpret_cast(&result._31), x3); + XMStoreFloat4(reinterpret_cast(&result._41), x4); +} + +inline Matrix Matrix::Lerp(const Matrix& M1, const Matrix& M2, float t) noexcept +{ + using namespace DirectX; + XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M1._11)); + XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M1._21)); + XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M1._31)); + XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M1._41)); + + const XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M2._11)); + const XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M2._21)); + const XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M2._31)); + const XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M2._41)); + + x1 = XMVectorLerp(x1, y1, t); + x2 = XMVectorLerp(x2, y2, t); + x3 = XMVectorLerp(x3, y3, t); + x4 = XMVectorLerp(x4, y4, t); + + Matrix result; + XMStoreFloat4(reinterpret_cast(&result._11), x1); + XMStoreFloat4(reinterpret_cast(&result._21), x2); + XMStoreFloat4(reinterpret_cast(&result._31), x3); + XMStoreFloat4(reinterpret_cast(&result._41), x4); + return result; +} + +inline void Matrix::Transform(const Matrix& M, const Quaternion& rotation, Matrix& result) noexcept +{ + using namespace DirectX; + const XMVECTOR quatv = XMLoadFloat4(&rotation); + + const XMMATRIX M0 = XMLoadFloat4x4(&M); + const XMMATRIX M1 = XMMatrixRotationQuaternion(quatv); + + XMStoreFloat4x4(&result, XMMatrixMultiply(M0, M1)); +} + +inline Matrix Matrix::Transform(const Matrix& M, const Quaternion& rotation) noexcept +{ + using namespace DirectX; + const XMVECTOR quatv = XMLoadFloat4(&rotation); + + const XMMATRIX M0 = XMLoadFloat4x4(&M); + const XMMATRIX M1 = XMMatrixRotationQuaternion(quatv); + + Matrix result; + XMStoreFloat4x4(&result, XMMatrixMultiply(M0, M1)); + return result; +} + + +/**************************************************************************** + * + * Plane + * + ****************************************************************************/ + +inline Plane::Plane(const Vector3& point1, const Vector3& point2, const Vector3& point3) noexcept +{ + using namespace DirectX; + const XMVECTOR P0 = XMLoadFloat3(&point1); + const XMVECTOR P1 = XMLoadFloat3(&point2); + const XMVECTOR P2 = XMLoadFloat3(&point3); + XMStoreFloat4(this, XMPlaneFromPoints(P0, P1, P2)); +} + +inline Plane::Plane(const Vector3& point, const Vector3& normal) noexcept +{ + using namespace DirectX; + const XMVECTOR P = XMLoadFloat3(&point); + const XMVECTOR N = XMLoadFloat3(&normal); + XMStoreFloat4(this, XMPlaneFromPointNormal(P, N)); +} + +//------------------------------------------------------------------------------ +// Comparision operators +//------------------------------------------------------------------------------ + +inline bool Plane::operator == (const Plane& p) const noexcept +{ + using namespace DirectX; + const XMVECTOR p1 = XMLoadFloat4(this); + const XMVECTOR p2 = XMLoadFloat4(&p); + return XMPlaneEqual(p1, p2); +} + +inline bool Plane::operator != (const Plane& p) const noexcept +{ + using namespace DirectX; + const XMVECTOR p1 = XMLoadFloat4(this); + const XMVECTOR p2 = XMLoadFloat4(&p); + return XMPlaneNotEqual(p1, p2); +} + +//------------------------------------------------------------------------------ +// Plane operations +//------------------------------------------------------------------------------ + +inline void Plane::Normalize() noexcept +{ + using namespace DirectX; + const XMVECTOR p = XMLoadFloat4(this); + XMStoreFloat4(this, XMPlaneNormalize(p)); +} + +inline void Plane::Normalize(Plane& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR p = XMLoadFloat4(this); + XMStoreFloat4(&result, XMPlaneNormalize(p)); +} + +inline float Plane::Dot(const Vector4& v) const noexcept +{ + using namespace DirectX; + const XMVECTOR p = XMLoadFloat4(this); + const XMVECTOR v0 = XMLoadFloat4(&v); + return XMVectorGetX(XMPlaneDot(p, v0)); +} + +inline float Plane::DotCoordinate(const Vector3& position) const noexcept +{ + using namespace DirectX; + const XMVECTOR p = XMLoadFloat4(this); + const XMVECTOR v0 = XMLoadFloat3(&position); + return XMVectorGetX(XMPlaneDotCoord(p, v0)); +} + +inline float Plane::DotNormal(const Vector3& normal) const noexcept +{ + using namespace DirectX; + const XMVECTOR p = XMLoadFloat4(this); + const XMVECTOR n0 = XMLoadFloat3(&normal); + return XMVectorGetX(XMPlaneDotNormal(p, n0)); +} + +//------------------------------------------------------------------------------ +// Static functions +//------------------------------------------------------------------------------ + +inline void Plane::Transform(const Plane& plane, const Matrix& M, Plane& result) noexcept +{ + using namespace DirectX; + const XMVECTOR p = XMLoadFloat4(&plane); + const XMMATRIX m0 = XMLoadFloat4x4(&M); + XMStoreFloat4(&result, XMPlaneTransform(p, m0)); +} + +inline Plane Plane::Transform(const Plane& plane, const Matrix& M) noexcept +{ + using namespace DirectX; + const XMVECTOR p = XMLoadFloat4(&plane); + const XMMATRIX m0 = XMLoadFloat4x4(&M); + + Plane result; + XMStoreFloat4(&result, XMPlaneTransform(p, m0)); + return result; +} + +inline void Plane::Transform(const Plane& plane, const Quaternion& rotation, Plane& result) noexcept +{ + using namespace DirectX; + const XMVECTOR p = XMLoadFloat4(&plane); + const XMVECTOR q = XMLoadFloat4(&rotation); + XMVECTOR X = XMVector3Rotate(p, q); + X = XMVectorSelect(p, X, g_XMSelect1110); // result.d = plane.d + XMStoreFloat4(&result, X); +} + +inline Plane Plane::Transform(const Plane& plane, const Quaternion& rotation) noexcept +{ + using namespace DirectX; + const XMVECTOR p = XMLoadFloat4(&plane); + const XMVECTOR q = XMLoadFloat4(&rotation); + XMVECTOR X = XMVector3Rotate(p, q); + X = XMVectorSelect(p, X, g_XMSelect1110); // result.d = plane.d + + Plane result; + XMStoreFloat4(&result, X); + return result; +} + + +/**************************************************************************** + * + * Quaternion + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ +// Comparision operators +//------------------------------------------------------------------------------ + +inline bool Quaternion::operator == (const Quaternion& q) const noexcept +{ + using namespace DirectX; + const XMVECTOR q1 = XMLoadFloat4(this); + const XMVECTOR q2 = XMLoadFloat4(&q); + return XMQuaternionEqual(q1, q2); +} + +inline bool Quaternion::operator != (const Quaternion& q) const noexcept +{ + using namespace DirectX; + const XMVECTOR q1 = XMLoadFloat4(this); + const XMVECTOR q2 = XMLoadFloat4(&q); + return XMQuaternionNotEqual(q1, q2); +} + +//------------------------------------------------------------------------------ +// Assignment operators +//------------------------------------------------------------------------------ + +inline Quaternion& Quaternion::operator+= (const Quaternion& q) noexcept +{ + using namespace DirectX; + const XMVECTOR q1 = XMLoadFloat4(this); + const XMVECTOR q2 = XMLoadFloat4(&q); + XMStoreFloat4(this, XMVectorAdd(q1, q2)); + return *this; +} + +inline Quaternion& Quaternion::operator-= (const Quaternion& q) noexcept +{ + using namespace DirectX; + const XMVECTOR q1 = XMLoadFloat4(this); + const XMVECTOR q2 = XMLoadFloat4(&q); + XMStoreFloat4(this, XMVectorSubtract(q1, q2)); + return *this; +} + +inline Quaternion& Quaternion::operator*= (const Quaternion& q) noexcept +{ + using namespace DirectX; + const XMVECTOR q1 = XMLoadFloat4(this); + const XMVECTOR q2 = XMLoadFloat4(&q); + XMStoreFloat4(this, XMQuaternionMultiply(q1, q2)); + return *this; +} + +inline Quaternion& Quaternion::operator*= (float S) noexcept +{ + using namespace DirectX; + const XMVECTOR q = XMLoadFloat4(this); + XMStoreFloat4(this, XMVectorScale(q, S)); + return *this; +} + +inline Quaternion& Quaternion::operator/= (const Quaternion& q) noexcept +{ + using namespace DirectX; + const XMVECTOR q1 = XMLoadFloat4(this); + XMVECTOR q2 = XMLoadFloat4(&q); + q2 = XMQuaternionInverse(q2); + XMStoreFloat4(this, XMQuaternionMultiply(q1, q2)); + return *this; +} + +//------------------------------------------------------------------------------ +// Urnary operators +//------------------------------------------------------------------------------ + +inline Quaternion Quaternion::operator- () const noexcept +{ + using namespace DirectX; + const XMVECTOR q = XMLoadFloat4(this); + + Quaternion R; + XMStoreFloat4(&R, XMVectorNegate(q)); + return R; +} + +//------------------------------------------------------------------------------ +// Binary operators +//------------------------------------------------------------------------------ + +inline Quaternion operator+ (const Quaternion& Q1, const Quaternion& Q2) noexcept +{ + using namespace DirectX; + const XMVECTOR q1 = XMLoadFloat4(&Q1); + const XMVECTOR q2 = XMLoadFloat4(&Q2); + + Quaternion R; + XMStoreFloat4(&R, XMVectorAdd(q1, q2)); + return R; +} + +inline Quaternion operator- (const Quaternion& Q1, const Quaternion& Q2) noexcept +{ + using namespace DirectX; + const XMVECTOR q1 = XMLoadFloat4(&Q1); + const XMVECTOR q2 = XMLoadFloat4(&Q2); + + Quaternion R; + XMStoreFloat4(&R, XMVectorSubtract(q1, q2)); + return R; +} + +inline Quaternion operator* (const Quaternion& Q1, const Quaternion& Q2) noexcept +{ + using namespace DirectX; + const XMVECTOR q1 = XMLoadFloat4(&Q1); + const XMVECTOR q2 = XMLoadFloat4(&Q2); + + Quaternion R; + XMStoreFloat4(&R, XMQuaternionMultiply(q1, q2)); + return R; +} + +inline Quaternion operator* (const Quaternion& Q, float S) noexcept +{ + using namespace DirectX; + const XMVECTOR q = XMLoadFloat4(&Q); + + Quaternion R; + XMStoreFloat4(&R, XMVectorScale(q, S)); + return R; +} + +inline Quaternion operator/ (const Quaternion& Q1, const Quaternion& Q2) noexcept +{ + using namespace DirectX; + const XMVECTOR q1 = XMLoadFloat4(&Q1); + XMVECTOR q2 = XMLoadFloat4(&Q2); + q2 = XMQuaternionInverse(q2); + + Quaternion R; + XMStoreFloat4(&R, XMQuaternionMultiply(q1, q2)); + return R; +} + +inline Quaternion operator* (float S, const Quaternion& Q) noexcept +{ + using namespace DirectX; + const XMVECTOR q1 = XMLoadFloat4(&Q); + + Quaternion R; + XMStoreFloat4(&R, XMVectorScale(q1, S)); + return R; +} + +//------------------------------------------------------------------------------ +// Quaternion operations +//------------------------------------------------------------------------------ + +inline float Quaternion::Length() const noexcept +{ + using namespace DirectX; + const XMVECTOR q = XMLoadFloat4(this); + return XMVectorGetX(XMQuaternionLength(q)); +} + +inline float Quaternion::LengthSquared() const noexcept +{ + using namespace DirectX; + const XMVECTOR q = XMLoadFloat4(this); + return XMVectorGetX(XMQuaternionLengthSq(q)); +} + +inline void Quaternion::Normalize() noexcept +{ + using namespace DirectX; + const XMVECTOR q = XMLoadFloat4(this); + XMStoreFloat4(this, XMQuaternionNormalize(q)); +} + +inline void Quaternion::Normalize(Quaternion& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR q = XMLoadFloat4(this); + XMStoreFloat4(&result, XMQuaternionNormalize(q)); +} + +inline void Quaternion::Conjugate() noexcept +{ + using namespace DirectX; + const XMVECTOR q = XMLoadFloat4(this); + XMStoreFloat4(this, XMQuaternionConjugate(q)); +} + +inline void Quaternion::Conjugate(Quaternion& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR q = XMLoadFloat4(this); + XMStoreFloat4(&result, XMQuaternionConjugate(q)); +} + +inline void Quaternion::Inverse(Quaternion& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR q = XMLoadFloat4(this); + XMStoreFloat4(&result, XMQuaternionInverse(q)); +} + +inline float Quaternion::Dot(const Quaternion& q) const noexcept +{ + using namespace DirectX; + const XMVECTOR q1 = XMLoadFloat4(this); + const XMVECTOR q2 = XMLoadFloat4(&q); + return XMVectorGetX(XMQuaternionDot(q1, q2)); +} + +inline void Quaternion::RotateTowards(const Quaternion& target, float maxAngle) noexcept +{ + RotateTowards(target, maxAngle, *this); +} + +inline Vector3 Quaternion::ToEuler() const noexcept +{ + const float xx = x * x; + const float yy = y * y; + const float zz = z * z; + + const float m31 = 2.f * x * z + 2.f * y * w; + const float m32 = 2.f * y * z - 2.f * x * w; + const float m33 = 1.f - 2.f * xx - 2.f * yy; + + const float cy = sqrtf(m33 * m33 + m31 * m31); + const float cx = atan2f(-m32, cy); + if (cy > 16.f * FLT_EPSILON) + { + const float m12 = 2.f * x * y + 2.f * z * w; + const float m22 = 1.f - 2.f * xx - 2.f * zz; + + return Vector3(cx, atan2f(m31, m33), atan2f(m12, m22)); + } + else + { + const float m11 = 1.f - 2.f * yy - 2.f * zz; + const float m21 = 2.f * x * y - 2.f * z * w; + + return Vector3(cx, 0.f, atan2f(-m21, m11)); + } +} + +//------------------------------------------------------------------------------ +// Static functions +//------------------------------------------------------------------------------ + +inline Quaternion Quaternion::CreateFromAxisAngle(const Vector3& axis, float angle) noexcept +{ + using namespace DirectX; + const XMVECTOR a = XMLoadFloat3(&axis); + + Quaternion R; + XMStoreFloat4(&R, XMQuaternionRotationAxis(a, angle)); + return R; +} + +inline Quaternion Quaternion::CreateFromYawPitchRoll(float yaw, float pitch, float roll) noexcept +{ + using namespace DirectX; + Quaternion R; + XMStoreFloat4(&R, XMQuaternionRotationRollPitchYaw(pitch, yaw, roll)); + return R; +} + +inline Quaternion Quaternion::CreateFromYawPitchRoll(const Vector3& angles) noexcept +{ + using namespace DirectX; + Quaternion R; + XMStoreFloat4(&R, XMQuaternionRotationRollPitchYawFromVector(angles)); + return R; +} + +inline Quaternion Quaternion::CreateFromRotationMatrix(const Matrix& M) noexcept +{ + using namespace DirectX; + const XMMATRIX M0 = XMLoadFloat4x4(&M); + + Quaternion R; + XMStoreFloat4(&R, XMQuaternionRotationMatrix(M0)); + return R; +} + +inline void Quaternion::Lerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion& result) noexcept +{ + using namespace DirectX; + const XMVECTOR Q0 = XMLoadFloat4(&q1); + const XMVECTOR Q1 = XMLoadFloat4(&q2); + + const XMVECTOR dot = XMVector4Dot(Q0, Q1); + + XMVECTOR R; + if (XMVector4GreaterOrEqual(dot, XMVectorZero())) + { + R = XMVectorLerp(Q0, Q1, t); + } + else + { + const XMVECTOR tv = XMVectorReplicate(t); + const XMVECTOR t1v = XMVectorReplicate(1.f - t); + const XMVECTOR X0 = XMVectorMultiply(Q0, t1v); + const XMVECTOR X1 = XMVectorMultiply(Q1, tv); + R = XMVectorSubtract(X0, X1); + } + + XMStoreFloat4(&result, XMQuaternionNormalize(R)); +} + +inline Quaternion Quaternion::Lerp(const Quaternion& q1, const Quaternion& q2, float t) noexcept +{ + using namespace DirectX; + const XMVECTOR Q0 = XMLoadFloat4(&q1); + const XMVECTOR Q1 = XMLoadFloat4(&q2); + + const XMVECTOR dot = XMVector4Dot(Q0, Q1); + + XMVECTOR R; + if (XMVector4GreaterOrEqual(dot, XMVectorZero())) + { + R = XMVectorLerp(Q0, Q1, t); + } + else + { + const XMVECTOR tv = XMVectorReplicate(t); + const XMVECTOR t1v = XMVectorReplicate(1.f - t); + const XMVECTOR X0 = XMVectorMultiply(Q0, t1v); + const XMVECTOR X1 = XMVectorMultiply(Q1, tv); + R = XMVectorSubtract(X0, X1); + } + + Quaternion result; + XMStoreFloat4(&result, XMQuaternionNormalize(R)); + return result; +} + +inline void Quaternion::Slerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion& result) noexcept +{ + using namespace DirectX; + const XMVECTOR Q0 = XMLoadFloat4(&q1); + const XMVECTOR Q1 = XMLoadFloat4(&q2); + XMStoreFloat4(&result, XMQuaternionSlerp(Q0, Q1, t)); +} + +inline Quaternion Quaternion::Slerp(const Quaternion& q1, const Quaternion& q2, float t) noexcept +{ + using namespace DirectX; + const XMVECTOR Q0 = XMLoadFloat4(&q1); + const XMVECTOR Q1 = XMLoadFloat4(&q2); + + Quaternion result; + XMStoreFloat4(&result, XMQuaternionSlerp(Q0, Q1, t)); + return result; +} + +inline void Quaternion::Concatenate(const Quaternion& q1, const Quaternion& q2, Quaternion& result) noexcept +{ + using namespace DirectX; + const XMVECTOR Q0 = XMLoadFloat4(&q1); + const XMVECTOR Q1 = XMLoadFloat4(&q2); + XMStoreFloat4(&result, XMQuaternionMultiply(Q1, Q0)); +} + +inline Quaternion Quaternion::Concatenate(const Quaternion& q1, const Quaternion& q2) noexcept +{ + using namespace DirectX; + const XMVECTOR Q0 = XMLoadFloat4(&q1); + const XMVECTOR Q1 = XMLoadFloat4(&q2); + + Quaternion result; + XMStoreFloat4(&result, XMQuaternionMultiply(Q1, Q0)); + return result; +} + +inline Quaternion Quaternion::FromToRotation(const Vector3& fromDir, const Vector3& toDir) noexcept +{ + Quaternion result; + FromToRotation(fromDir, toDir, result); + return result; +} + +inline Quaternion Quaternion::LookRotation(const Vector3& forward, const Vector3& up) noexcept +{ + Quaternion result; + LookRotation(forward, up, result); + return result; +} + +inline float Quaternion::Angle(const Quaternion& q1, const Quaternion& q2) noexcept +{ + using namespace DirectX; + const XMVECTOR Q0 = XMLoadFloat4(&q1); + const XMVECTOR Q1 = XMLoadFloat4(&q2); + + // We can use the conjugate here instead of inverse assuming q1 & q2 are normalized. + XMVECTOR R = XMQuaternionMultiply(XMQuaternionConjugate(Q0), Q1); + + const float rs = XMVectorGetW(R); + R = XMVector3Length(R); + return 2.f * atan2f(XMVectorGetX(R), rs); +} + + +/**************************************************************************** + * + * Color + * + ****************************************************************************/ + +inline Color::Color(const DirectX::PackedVector::XMCOLOR& Packed) noexcept +{ + using namespace DirectX; + XMStoreFloat4(this, PackedVector::XMLoadColor(&Packed)); +} + +inline Color::Color(const DirectX::PackedVector::XMUBYTEN4& Packed) noexcept +{ + using namespace DirectX; + XMStoreFloat4(this, PackedVector::XMLoadUByteN4(&Packed)); +} + +//------------------------------------------------------------------------------ +// Comparision operators +//------------------------------------------------------------------------------ +inline bool Color::operator == (const Color& c) const noexcept +{ + using namespace DirectX; + const XMVECTOR c1 = XMLoadFloat4(this); + const XMVECTOR c2 = XMLoadFloat4(&c); + return XMColorEqual(c1, c2); +} + +inline bool Color::operator != (const Color& c) const noexcept +{ + using namespace DirectX; + const XMVECTOR c1 = XMLoadFloat4(this); + const XMVECTOR c2 = XMLoadFloat4(&c); + return XMColorNotEqual(c1, c2); +} + +//------------------------------------------------------------------------------ +// Assignment operators +//------------------------------------------------------------------------------ + +inline Color& Color::operator= (const DirectX::PackedVector::XMCOLOR& Packed) noexcept +{ + using namespace DirectX; + XMStoreFloat4(this, PackedVector::XMLoadColor(&Packed)); + return *this; +} + +inline Color& Color::operator= (const DirectX::PackedVector::XMUBYTEN4& Packed) noexcept +{ + using namespace DirectX; + XMStoreFloat4(this, PackedVector::XMLoadUByteN4(&Packed)); + return *this; +} + +inline Color& Color::operator+= (const Color& c) noexcept +{ + using namespace DirectX; + const XMVECTOR c1 = XMLoadFloat4(this); + const XMVECTOR c2 = XMLoadFloat4(&c); + XMStoreFloat4(this, XMVectorAdd(c1, c2)); + return *this; +} + +inline Color& Color::operator-= (const Color& c) noexcept +{ + using namespace DirectX; + const XMVECTOR c1 = XMLoadFloat4(this); + const XMVECTOR c2 = XMLoadFloat4(&c); + XMStoreFloat4(this, XMVectorSubtract(c1, c2)); + return *this; +} + +inline Color& Color::operator*= (const Color& c) noexcept +{ + using namespace DirectX; + const XMVECTOR c1 = XMLoadFloat4(this); + const XMVECTOR c2 = XMLoadFloat4(&c); + XMStoreFloat4(this, XMVectorMultiply(c1, c2)); + return *this; +} + +inline Color& Color::operator*= (float S) noexcept +{ + using namespace DirectX; + const XMVECTOR c = XMLoadFloat4(this); + XMStoreFloat4(this, XMVectorScale(c, S)); + return *this; +} + +inline Color& Color::operator/= (const Color& c) noexcept +{ + using namespace DirectX; + const XMVECTOR c1 = XMLoadFloat4(this); + const XMVECTOR c2 = XMLoadFloat4(&c); + XMStoreFloat4(this, XMVectorDivide(c1, c2)); + return *this; +} + +//------------------------------------------------------------------------------ +// Urnary operators +//------------------------------------------------------------------------------ + +inline Color Color::operator- () const noexcept +{ + using namespace DirectX; + const XMVECTOR c = XMLoadFloat4(this); + Color R; + XMStoreFloat4(&R, XMVectorNegate(c)); + return R; +} + +//------------------------------------------------------------------------------ +// Binary operators +//------------------------------------------------------------------------------ + +inline Color operator+ (const Color& C1, const Color& C2) noexcept +{ + using namespace DirectX; + const XMVECTOR c1 = XMLoadFloat4(&C1); + const XMVECTOR c2 = XMLoadFloat4(&C2); + Color R; + XMStoreFloat4(&R, XMVectorAdd(c1, c2)); + return R; +} + +inline Color operator- (const Color& C1, const Color& C2) noexcept +{ + using namespace DirectX; + const XMVECTOR c1 = XMLoadFloat4(&C1); + const XMVECTOR c2 = XMLoadFloat4(&C2); + Color R; + XMStoreFloat4(&R, XMVectorSubtract(c1, c2)); + return R; +} + +inline Color operator* (const Color& C1, const Color& C2) noexcept +{ + using namespace DirectX; + const XMVECTOR c1 = XMLoadFloat4(&C1); + const XMVECTOR c2 = XMLoadFloat4(&C2); + Color R; + XMStoreFloat4(&R, XMVectorMultiply(c1, c2)); + return R; +} + +inline Color operator* (const Color& C, float S) noexcept +{ + using namespace DirectX; + const XMVECTOR c = XMLoadFloat4(&C); + Color R; + XMStoreFloat4(&R, XMVectorScale(c, S)); + return R; +} + +inline Color operator/ (const Color& C1, const Color& C2) noexcept +{ + using namespace DirectX; + const XMVECTOR c1 = XMLoadFloat4(&C1); + const XMVECTOR c2 = XMLoadFloat4(&C2); + Color R; + XMStoreFloat4(&R, XMVectorDivide(c1, c2)); + return R; +} + +inline Color operator* (float S, const Color& C) noexcept +{ + using namespace DirectX; + const XMVECTOR c1 = XMLoadFloat4(&C); + Color R; + XMStoreFloat4(&R, XMVectorScale(c1, S)); + return R; +} + +//------------------------------------------------------------------------------ +// Color operations +//------------------------------------------------------------------------------ + +inline DirectX::PackedVector::XMCOLOR Color::BGRA() const noexcept +{ + using namespace DirectX; + const XMVECTOR clr = XMLoadFloat4(this); + PackedVector::XMCOLOR Packed; + PackedVector::XMStoreColor(&Packed, clr); + return Packed; +} + +inline DirectX::PackedVector::XMUBYTEN4 Color::RGBA() const noexcept +{ + using namespace DirectX; + const XMVECTOR clr = XMLoadFloat4(this); + PackedVector::XMUBYTEN4 Packed; + PackedVector::XMStoreUByteN4(&Packed, clr); + return Packed; +} + +inline Vector3 Color::ToVector3() const noexcept +{ + return Vector3(x, y, z); +} + +inline Vector4 Color::ToVector4() const noexcept +{ + return Vector4(x, y, z, w); +} + +inline void Color::Negate() noexcept +{ + using namespace DirectX; + const XMVECTOR c = XMLoadFloat4(this); + XMStoreFloat4(this, XMColorNegative(c)); +} + +inline void Color::Negate(Color& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR c = XMLoadFloat4(this); + XMStoreFloat4(&result, XMColorNegative(c)); +} + +inline void Color::Saturate() noexcept +{ + using namespace DirectX; + const XMVECTOR c = XMLoadFloat4(this); + XMStoreFloat4(this, XMVectorSaturate(c)); +} + +inline void Color::Saturate(Color& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR c = XMLoadFloat4(this); + XMStoreFloat4(&result, XMVectorSaturate(c)); +} + +inline void Color::Premultiply() noexcept +{ + using namespace DirectX; + const XMVECTOR c = XMLoadFloat4(this); + XMVECTOR a = XMVectorSplatW(c); + a = XMVectorSelect(g_XMIdentityR3, a, g_XMSelect1110); + XMStoreFloat4(this, XMVectorMultiply(c, a)); +} + +inline void Color::Premultiply(Color& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR c = XMLoadFloat4(this); + XMVECTOR a = XMVectorSplatW(c); + a = XMVectorSelect(g_XMIdentityR3, a, g_XMSelect1110); + XMStoreFloat4(&result, XMVectorMultiply(c, a)); +} + +inline void Color::AdjustSaturation(float sat) noexcept +{ + using namespace DirectX; + const XMVECTOR c = XMLoadFloat4(this); + XMStoreFloat4(this, XMColorAdjustSaturation(c, sat)); +} + +inline void Color::AdjustSaturation(float sat, Color& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR c = XMLoadFloat4(this); + XMStoreFloat4(&result, XMColorAdjustSaturation(c, sat)); +} + +inline void Color::AdjustContrast(float contrast) noexcept +{ + using namespace DirectX; + const XMVECTOR c = XMLoadFloat4(this); + XMStoreFloat4(this, XMColorAdjustContrast(c, contrast)); +} + +inline void Color::AdjustContrast(float contrast, Color& result) const noexcept +{ + using namespace DirectX; + const XMVECTOR c = XMLoadFloat4(this); + XMStoreFloat4(&result, XMColorAdjustContrast(c, contrast)); +} + +//------------------------------------------------------------------------------ +// Static functions +//------------------------------------------------------------------------------ + +inline void Color::Modulate(const Color& c1, const Color& c2, Color& result) noexcept +{ + using namespace DirectX; + const XMVECTOR C0 = XMLoadFloat4(&c1); + const XMVECTOR C1 = XMLoadFloat4(&c2); + XMStoreFloat4(&result, XMColorModulate(C0, C1)); +} + +inline Color Color::Modulate(const Color& c1, const Color& c2) noexcept +{ + using namespace DirectX; + const XMVECTOR C0 = XMLoadFloat4(&c1); + const XMVECTOR C1 = XMLoadFloat4(&c2); + + Color result; + XMStoreFloat4(&result, XMColorModulate(C0, C1)); + return result; +} + +inline void Color::Lerp(const Color& c1, const Color& c2, float t, Color& result) noexcept +{ + using namespace DirectX; + const XMVECTOR C0 = XMLoadFloat4(&c1); + const XMVECTOR C1 = XMLoadFloat4(&c2); + XMStoreFloat4(&result, XMVectorLerp(C0, C1, t)); +} + +inline Color Color::Lerp(const Color& c1, const Color& c2, float t) noexcept +{ + using namespace DirectX; + const XMVECTOR C0 = XMLoadFloat4(&c1); + const XMVECTOR C1 = XMLoadFloat4(&c2); + + Color result; + XMStoreFloat4(&result, XMVectorLerp(C0, C1, t)); + return result; +} + + +/**************************************************************************** + * + * Ray + * + ****************************************************************************/ + +//----------------------------------------------------------------------------- +// Comparision operators +//------------------------------------------------------------------------------ +inline bool Ray::operator == (const Ray& r) const noexcept +{ + using namespace DirectX; + const XMVECTOR r1p = XMLoadFloat3(&position); + const XMVECTOR r2p = XMLoadFloat3(&r.position); + const XMVECTOR r1d = XMLoadFloat3(&direction); + const XMVECTOR r2d = XMLoadFloat3(&r.direction); + return XMVector3Equal(r1p, r2p) && XMVector3Equal(r1d, r2d); +} + +inline bool Ray::operator != (const Ray& r) const noexcept +{ + using namespace DirectX; + const XMVECTOR r1p = XMLoadFloat3(&position); + const XMVECTOR r2p = XMLoadFloat3(&r.position); + const XMVECTOR r1d = XMLoadFloat3(&direction); + const XMVECTOR r2d = XMLoadFloat3(&r.direction); + return XMVector3NotEqual(r1p, r2p) && XMVector3NotEqual(r1d, r2d); +} + +//----------------------------------------------------------------------------- +// Ray operators +//------------------------------------------------------------------------------ + +inline bool Ray::Intersects(const BoundingSphere& sphere, _Out_ float& Dist) const noexcept +{ + return sphere.Intersects(position, direction, Dist); +} + +inline bool Ray::Intersects(const BoundingBox& box, _Out_ float& Dist) const noexcept +{ + return box.Intersects(position, direction, Dist); +} + +inline bool Ray::Intersects(const Vector3& tri0, const Vector3& tri1, const Vector3& tri2, _Out_ float& Dist) const noexcept +{ + return DirectX::TriangleTests::Intersects(position, direction, tri0, tri1, tri2, Dist); +} + +inline bool Ray::Intersects(const Plane& plane, _Out_ float& Dist) const noexcept +{ + using namespace DirectX; + + const XMVECTOR p = XMLoadFloat4(&plane); + const XMVECTOR dir = XMLoadFloat3(&direction); + + const XMVECTOR nd = XMPlaneDotNormal(p, dir); + + if (XMVector3LessOrEqual(XMVectorAbs(nd), g_RayEpsilon)) + { + Dist = 0.f; + return false; + } + else + { + // t = -(dot(n,origin) + D) / dot(n,dir) + const XMVECTOR pos = XMLoadFloat3(&position); + XMVECTOR v = XMPlaneDotNormal(p, pos); + v = XMVectorAdd(v, XMVectorSplatW(p)); + v = XMVectorDivide(v, nd); + float dist = -XMVectorGetX(v); + if (dist < 0) + { + Dist = 0.f; + return false; + } + else + { + Dist = dist; + return true; + } + } +} + + +/**************************************************************************** + * + * Viewport + * + ****************************************************************************/ + +//------------------------------------------------------------------------------ +// Comparision operators +//------------------------------------------------------------------------------ + +#if (__cplusplus < 202002L) +inline bool Viewport::operator == (const Viewport& vp) const noexcept +{ + return (x == vp.x && y == vp.y + && width == vp.width && height == vp.height + && minDepth == vp.minDepth && maxDepth == vp.maxDepth); +} + +inline bool Viewport::operator != (const Viewport& vp) const noexcept +{ + return (x != vp.x || y != vp.y + || width != vp.width || height != vp.height + || minDepth != vp.minDepth || maxDepth != vp.maxDepth); +} +#endif + +//------------------------------------------------------------------------------ +// Assignment operators +//------------------------------------------------------------------------------ + +inline Viewport& Viewport::operator= (const RECT& rct) noexcept +{ + x = float(rct.left); y = float(rct.top); + width = float(rct.right - rct.left); + height = float(rct.bottom - rct.top); + minDepth = 0.f; maxDepth = 1.f; + return *this; +} + +#if defined(__d3d11_h__) || defined(__d3d11_x_h__) +inline Viewport& Viewport::operator= (const D3D11_VIEWPORT& vp) noexcept +{ + x = vp.TopLeftX; y = vp.TopLeftY; + width = vp.Width; height = vp.Height; + minDepth = vp.MinDepth; maxDepth = vp.MaxDepth; + return *this; +} +#endif + +#if defined(__d3d12_h__) || defined(__d3d12_x_h__) || defined(__XBOX_D3D12_X__) +inline Viewport& Viewport::operator= (const D3D12_VIEWPORT& vp) noexcept +{ + x = vp.TopLeftX; y = vp.TopLeftY; + width = vp.Width; height = vp.Height; + minDepth = vp.MinDepth; maxDepth = vp.MaxDepth; + return *this; +} +#endif + +//------------------------------------------------------------------------------ +// Viewport operations +//------------------------------------------------------------------------------ + +inline float Viewport::AspectRatio() const noexcept +{ + if (width == 0.f || height == 0.f) + return 0.f; + + return (width / height); +} + +inline Vector3 Viewport::Project(const Vector3& p, const Matrix& proj, const Matrix& view, const Matrix& world) const noexcept +{ + using namespace DirectX; + XMVECTOR v = XMLoadFloat3(&p); + const XMMATRIX projection = XMLoadFloat4x4(&proj); + v = XMVector3Project(v, x, y, width, height, minDepth, maxDepth, projection, view, world); + Vector3 result; + XMStoreFloat3(&result, v); + return result; +} + +inline void Viewport::Project(const Vector3& p, const Matrix& proj, const Matrix& view, const Matrix& world, Vector3& result) const noexcept +{ + using namespace DirectX; + XMVECTOR v = XMLoadFloat3(&p); + const XMMATRIX projection = XMLoadFloat4x4(&proj); + v = XMVector3Project(v, x, y, width, height, minDepth, maxDepth, projection, view, world); + XMStoreFloat3(&result, v); +} + +inline Vector3 Viewport::Unproject(const Vector3& p, const Matrix& proj, const Matrix& view, const Matrix& world) const noexcept +{ + using namespace DirectX; + XMVECTOR v = XMLoadFloat3(&p); + const XMMATRIX projection = XMLoadFloat4x4(&proj); + v = XMVector3Unproject(v, x, y, width, height, minDepth, maxDepth, projection, view, world); + Vector3 result; + XMStoreFloat3(&result, v); + return result; +} + +inline void Viewport::Unproject(const Vector3& p, const Matrix& proj, const Matrix& view, const Matrix& world, Vector3& result) const noexcept +{ + using namespace DirectX; + XMVECTOR v = XMLoadFloat3(&p); + const XMMATRIX projection = XMLoadFloat4x4(&proj); + v = XMVector3Unproject(v, x, y, width, height, minDepth, maxDepth, projection, view, world); + XMStoreFloat3(&result, v); +} diff --git a/enginecustom/include/Inc/SpriteBatch.h b/enginecustom/include/Inc/SpriteBatch.h new file mode 100644 index 0000000..ca274ec --- /dev/null +++ b/enginecustom/include/Inc/SpriteBatch.h @@ -0,0 +1,102 @@ +//-------------------------------------------------------------------------------------- +// File: SpriteBatch.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#include +#endif + +#include +#include +#include + +#include +#include + + +namespace DirectX +{ + inline namespace DX11 + { + enum SpriteSortMode + { + SpriteSortMode_Deferred, + SpriteSortMode_Immediate, + SpriteSortMode_Texture, + SpriteSortMode_BackToFront, + SpriteSortMode_FrontToBack, + }; + + enum SpriteEffects : uint32_t + { + SpriteEffects_None = 0, + SpriteEffects_FlipHorizontally = 1, + SpriteEffects_FlipVertically = 2, + SpriteEffects_FlipBoth = SpriteEffects_FlipHorizontally | SpriteEffects_FlipVertically, + }; + + class SpriteBatch + { + public: + explicit SpriteBatch(_In_ ID3D11DeviceContext* deviceContext); + + SpriteBatch(SpriteBatch&&) noexcept; + SpriteBatch& operator= (SpriteBatch&&) noexcept; + + SpriteBatch(SpriteBatch const&) = delete; + SpriteBatch& operator= (SpriteBatch const&) = delete; + + virtual ~SpriteBatch(); + + // Begin/End a batch of sprite drawing operations. + void XM_CALLCONV Begin(SpriteSortMode sortMode = SpriteSortMode_Deferred, + _In_opt_ ID3D11BlendState* blendState = nullptr, + _In_opt_ ID3D11SamplerState* samplerState = nullptr, + _In_opt_ ID3D11DepthStencilState* depthStencilState = nullptr, + _In_opt_ ID3D11RasterizerState* rasterizerState = nullptr, + _In_ std::function setCustomShaders = nullptr, + FXMMATRIX transformMatrix = MatrixIdentity); + void __cdecl End(); + + // Draw overloads specifying position, origin and scale as XMFLOAT2. + void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, XMFLOAT2 const& position, FXMVECTOR color = Colors::White); + void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, XMFLOAT2 const& position, _In_opt_ RECT const* sourceRectangle, FXMVECTOR color = Colors::White, float rotation = 0, XMFLOAT2 const& origin = Float2Zero, float scale = 1, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0); + void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, XMFLOAT2 const& position, _In_opt_ RECT const* sourceRectangle, FXMVECTOR color, float rotation, XMFLOAT2 const& origin, XMFLOAT2 const& scale, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0); + + // Draw overloads specifying position, origin and scale via the first two components of an XMVECTOR. + void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, FXMVECTOR position, FXMVECTOR color = Colors::White); + void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, FXMVECTOR position, _In_opt_ RECT const* sourceRectangle, FXMVECTOR color = Colors::White, float rotation = 0, FXMVECTOR origin = g_XMZero, float scale = 1, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0); + void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, FXMVECTOR position, _In_opt_ RECT const* sourceRectangle, FXMVECTOR color, float rotation, FXMVECTOR origin, GXMVECTOR scale, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0); + + // Draw overloads specifying position as a RECT. + void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, RECT const& destinationRectangle, FXMVECTOR color = Colors::White); + void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, RECT const& destinationRectangle, _In_opt_ RECT const* sourceRectangle, FXMVECTOR color = Colors::White, float rotation = 0, XMFLOAT2 const& origin = Float2Zero, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0); + + // Rotation mode to be applied to the sprite transformation + void __cdecl SetRotation(DXGI_MODE_ROTATION mode); + DXGI_MODE_ROTATION __cdecl GetRotation() const noexcept; + + // Set viewport for sprite transformation + void __cdecl SetViewport(const D3D11_VIEWPORT& viewPort); + + private: + // Private implementation. + struct Impl; + + std::unique_ptr pImpl; + + static const XMMATRIX MatrixIdentity; + static const XMFLOAT2 Float2Zero; + }; + } +} diff --git a/enginecustom/include/Inc/SpriteFont.h b/enginecustom/include/Inc/SpriteFont.h new file mode 100644 index 0000000..d5b6ddf --- /dev/null +++ b/enginecustom/include/Inc/SpriteFont.h @@ -0,0 +1,116 @@ +//-------------------------------------------------------------------------------------- +// File: SpriteFont.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#include "SpriteBatch.h" + +#include +#include +#include + + +namespace DirectX +{ + inline namespace DX11 + { + class SpriteFont + { + public: + struct Glyph; + + SpriteFont(_In_ ID3D11Device* device, _In_z_ wchar_t const* fileName, bool forceSRGB = false); + SpriteFont(_In_ ID3D11Device* device, _In_reads_bytes_(dataSize) uint8_t const* dataBlob, _In_ size_t dataSize, bool forceSRGB = false); + SpriteFont(_In_ ID3D11ShaderResourceView* texture, _In_reads_(glyphCount) Glyph const* glyphs, _In_ size_t glyphCount, _In_ float lineSpacing); + + SpriteFont(SpriteFont&&) noexcept; + SpriteFont& operator= (SpriteFont&&) noexcept; + + SpriteFont(SpriteFont const&) = delete; + SpriteFont& operator= (SpriteFont const&) = delete; + + virtual ~SpriteFont(); + + // Wide-character / UTF-16LE + void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ wchar_t const* text, XMFLOAT2 const& position, FXMVECTOR color = Colors::White, float rotation = 0, XMFLOAT2 const& origin = Float2Zero, float scale = 1, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; + void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ wchar_t const* text, XMFLOAT2 const& position, FXMVECTOR color, float rotation, XMFLOAT2 const& origin, XMFLOAT2 const& scale, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; + void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ wchar_t const* text, FXMVECTOR position, FXMVECTOR color = Colors::White, float rotation = 0, FXMVECTOR origin = g_XMZero, float scale = 1, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; + void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ wchar_t const* text, FXMVECTOR position, FXMVECTOR color, float rotation, FXMVECTOR origin, GXMVECTOR scale, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; + + XMVECTOR XM_CALLCONV MeasureString(_In_z_ wchar_t const* text, bool ignoreWhitespace = true) const; + + RECT __cdecl MeasureDrawBounds(_In_z_ wchar_t const* text, XMFLOAT2 const& position, bool ignoreWhitespace = true) const; + RECT XM_CALLCONV MeasureDrawBounds(_In_z_ wchar_t const* text, FXMVECTOR position, bool ignoreWhitespace = true) const; + + // UTF-8 + void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ char const* text, XMFLOAT2 const& position, FXMVECTOR color = Colors::White, float rotation = 0, XMFLOAT2 const& origin = Float2Zero, float scale = 1, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; + void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ char const* text, XMFLOAT2 const& position, FXMVECTOR color, float rotation, XMFLOAT2 const& origin, XMFLOAT2 const& scale, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; + void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ char const* text, FXMVECTOR position, FXMVECTOR color = Colors::White, float rotation = 0, FXMVECTOR origin = g_XMZero, float scale = 1, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; + void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ char const* text, FXMVECTOR position, FXMVECTOR color, float rotation, FXMVECTOR origin, GXMVECTOR scale, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; + + XMVECTOR XM_CALLCONV MeasureString(_In_z_ char const* text, bool ignoreWhitespace = true) const; + + RECT __cdecl MeasureDrawBounds(_In_z_ char const* text, XMFLOAT2 const& position, bool ignoreWhitespace = true) const; + RECT XM_CALLCONV MeasureDrawBounds(_In_z_ char const* text, FXMVECTOR position, bool ignoreWhitespace = true) const; + + // Spacing properties + float __cdecl GetLineSpacing() const noexcept; + void __cdecl SetLineSpacing(float spacing); + + // Font properties + wchar_t __cdecl GetDefaultCharacter() const noexcept; + void __cdecl SetDefaultCharacter(wchar_t character); + + bool __cdecl ContainsCharacter(wchar_t character) const; + + // Custom layout/rendering + Glyph const* __cdecl FindGlyph(wchar_t character) const; + void __cdecl GetSpriteSheet(ID3D11ShaderResourceView** texture) const; + + // Describes a single character glyph. + struct Glyph + { + uint32_t Character; + RECT Subrect; + float XOffset; + float YOffset; + float XAdvance; + }; + +#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED) + SpriteFont(_In_ ID3D11Device* device, _In_z_ __wchar_t const* fileName, bool forceSRGB = false); + + void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ __wchar_t const* text, XMFLOAT2 const& position, FXMVECTOR color = Colors::White, float rotation = 0, XMFLOAT2 const& origin = Float2Zero, float scale = 1, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; + + void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ __wchar_t const* text, XMFLOAT2 const& position, FXMVECTOR color, float rotation, XMFLOAT2 const& origin, XMFLOAT2 const& scale, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; + void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ __wchar_t const* text, FXMVECTOR position, FXMVECTOR color = Colors::White, float rotation = 0, FXMVECTOR origin = g_XMZero, float scale = 1, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; + void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ __wchar_t const* text, FXMVECTOR position, FXMVECTOR color, float rotation, FXMVECTOR origin, GXMVECTOR scale, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; + + XMVECTOR XM_CALLCONV MeasureString(_In_z_ __wchar_t const* text, bool ignoreWhitespace = true) const; + + RECT __cdecl MeasureDrawBounds(_In_z_ __wchar_t const* text, XMFLOAT2 const& position, bool ignoreWhitespace = true) const; + RECT XM_CALLCONV MeasureDrawBounds(_In_z_ __wchar_t const* text, FXMVECTOR position, bool ignoreWhitespace = true) const; + + void __cdecl SetDefaultCharacter(__wchar_t character); + + bool __cdecl ContainsCharacter(__wchar_t character) const; + + Glyph const* __cdecl FindGlyph(__wchar_t character) const; +#endif // !_NATIVE_WCHAR_T_DEFINED + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + + static const XMFLOAT2 Float2Zero; + }; + } +} diff --git a/enginecustom/include/Inc/VertexTypes.h b/enginecustom/include/Inc/VertexTypes.h new file mode 100644 index 0000000..3ea910d --- /dev/null +++ b/enginecustom/include/Inc/VertexTypes.h @@ -0,0 +1,504 @@ +//-------------------------------------------------------------------------------------- +// File: VertexTypes.h +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +#include + +#include + + +namespace DirectX +{ + inline namespace DX11 + { + // Vertex struct holding position information. + struct VertexPosition + { + VertexPosition() = default; + + VertexPosition(const VertexPosition&) = default; + VertexPosition& operator=(const VertexPosition&) = default; + + VertexPosition(VertexPosition&&) = default; + VertexPosition& operator=(VertexPosition&&) = default; + + VertexPosition(XMFLOAT3 const& iposition) noexcept + : position(iposition) + { + } + + VertexPosition(FXMVECTOR iposition) noexcept + { + XMStoreFloat3(&this->position, iposition); + } + + XMFLOAT3 position; + + static constexpr unsigned int InputElementCount = 1; + static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; + }; + + + // Vertex struct holding position and color information. + struct VertexPositionColor + { + VertexPositionColor() = default; + + VertexPositionColor(const VertexPositionColor&) = default; + VertexPositionColor& operator=(const VertexPositionColor&) = default; + + VertexPositionColor(VertexPositionColor&&) = default; + VertexPositionColor& operator=(VertexPositionColor&&) = default; + + VertexPositionColor(XMFLOAT3 const& iposition, XMFLOAT4 const& icolor) noexcept + : position(iposition), + color(icolor) + { + } + + VertexPositionColor(FXMVECTOR iposition, FXMVECTOR icolor) noexcept + { + XMStoreFloat3(&this->position, iposition); + XMStoreFloat4(&this->color, icolor); + } + + XMFLOAT3 position; + XMFLOAT4 color; + + static constexpr unsigned int InputElementCount = 2; + static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; + }; + + + // Vertex struct holding position and texture mapping information. + struct VertexPositionTexture + { + VertexPositionTexture() = default; + + VertexPositionTexture(const VertexPositionTexture&) = default; + VertexPositionTexture& operator=(const VertexPositionTexture&) = default; + + VertexPositionTexture(VertexPositionTexture&&) = default; + VertexPositionTexture& operator=(VertexPositionTexture&&) = default; + + VertexPositionTexture(XMFLOAT3 const& iposition, XMFLOAT2 const& itextureCoordinate) noexcept + : position(iposition), + textureCoordinate(itextureCoordinate) + { + } + + VertexPositionTexture(FXMVECTOR iposition, FXMVECTOR itextureCoordinate) noexcept + { + XMStoreFloat3(&this->position, iposition); + XMStoreFloat2(&this->textureCoordinate, itextureCoordinate); + } + + XMFLOAT3 position; + XMFLOAT2 textureCoordinate; + + static constexpr unsigned int InputElementCount = 2; + static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; + }; + + + // Vertex struct holding position and dual texture mapping information. + struct VertexPositionDualTexture + { + VertexPositionDualTexture() = default; + + VertexPositionDualTexture(const VertexPositionDualTexture&) = default; + VertexPositionDualTexture& operator=(const VertexPositionDualTexture&) = default; + + VertexPositionDualTexture(VertexPositionDualTexture&&) = default; + VertexPositionDualTexture& operator=(VertexPositionDualTexture&&) = default; + + VertexPositionDualTexture( + XMFLOAT3 const& iposition, + XMFLOAT2 const& itextureCoordinate0, + XMFLOAT2 const& itextureCoordinate1) noexcept + : position(iposition), + textureCoordinate0(itextureCoordinate0), + textureCoordinate1(itextureCoordinate1) + { + } + + VertexPositionDualTexture( + FXMVECTOR iposition, + FXMVECTOR itextureCoordinate0, + FXMVECTOR itextureCoordinate1) noexcept + { + XMStoreFloat3(&this->position, iposition); + XMStoreFloat2(&this->textureCoordinate0, itextureCoordinate0); + XMStoreFloat2(&this->textureCoordinate1, itextureCoordinate1); + } + + XMFLOAT3 position; + XMFLOAT2 textureCoordinate0; + XMFLOAT2 textureCoordinate1; + + static constexpr unsigned int InputElementCount = 3; + static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; + }; + + + // Vertex struct holding position and normal vector. + struct VertexPositionNormal + { + VertexPositionNormal() = default; + + VertexPositionNormal(const VertexPositionNormal&) = default; + VertexPositionNormal& operator=(const VertexPositionNormal&) = default; + + VertexPositionNormal(VertexPositionNormal&&) = default; + VertexPositionNormal& operator=(VertexPositionNormal&&) = default; + + VertexPositionNormal(XMFLOAT3 const& iposition, XMFLOAT3 const& inormal) noexcept + : position(iposition), + normal(inormal) + { + } + + VertexPositionNormal(FXMVECTOR iposition, FXMVECTOR inormal) noexcept + { + XMStoreFloat3(&this->position, iposition); + XMStoreFloat3(&this->normal, inormal); + } + + XMFLOAT3 position; + XMFLOAT3 normal; + + static constexpr unsigned int InputElementCount = 2; + static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; + }; + + + // Vertex struct holding position, color, and texture mapping information. + struct VertexPositionColorTexture + { + VertexPositionColorTexture() = default; + + VertexPositionColorTexture(const VertexPositionColorTexture&) = default; + VertexPositionColorTexture& operator=(const VertexPositionColorTexture&) = default; + + VertexPositionColorTexture(VertexPositionColorTexture&&) = default; + VertexPositionColorTexture& operator=(VertexPositionColorTexture&&) = default; + + VertexPositionColorTexture(XMFLOAT3 const& iposition, XMFLOAT4 const& icolor, XMFLOAT2 const& itextureCoordinate) noexcept + : position(iposition), + color(icolor), + textureCoordinate(itextureCoordinate) + { + } + + VertexPositionColorTexture(FXMVECTOR iposition, FXMVECTOR icolor, FXMVECTOR itextureCoordinate) noexcept + { + XMStoreFloat3(&this->position, iposition); + XMStoreFloat4(&this->color, icolor); + XMStoreFloat2(&this->textureCoordinate, itextureCoordinate); + } + + XMFLOAT3 position; + XMFLOAT4 color; + XMFLOAT2 textureCoordinate; + + static constexpr unsigned int InputElementCount = 3; + static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; + }; + + + // Vertex struct holding position, normal vector, and color information. + struct VertexPositionNormalColor + { + VertexPositionNormalColor() = default; + + VertexPositionNormalColor(const VertexPositionNormalColor&) = default; + VertexPositionNormalColor& operator=(const VertexPositionNormalColor&) = default; + + VertexPositionNormalColor(VertexPositionNormalColor&&) = default; + VertexPositionNormalColor& operator=(VertexPositionNormalColor&&) = default; + + VertexPositionNormalColor(XMFLOAT3 const& iposition, XMFLOAT3 const& inormal, XMFLOAT4 const& icolor) noexcept + : position(iposition), + normal(inormal), + color(icolor) + { + } + + VertexPositionNormalColor(FXMVECTOR iposition, FXMVECTOR inormal, FXMVECTOR icolor) noexcept + { + XMStoreFloat3(&this->position, iposition); + XMStoreFloat3(&this->normal, inormal); + XMStoreFloat4(&this->color, icolor); + } + + XMFLOAT3 position; + XMFLOAT3 normal; + XMFLOAT4 color; + + static constexpr unsigned int InputElementCount = 3; + static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; + }; + + + // Vertex struct holding position, normal vector, and texture mapping information. + struct VertexPositionNormalTexture + { + VertexPositionNormalTexture() = default; + + VertexPositionNormalTexture(const VertexPositionNormalTexture&) = default; + VertexPositionNormalTexture& operator=(const VertexPositionNormalTexture&) = default; + + VertexPositionNormalTexture(VertexPositionNormalTexture&&) = default; + VertexPositionNormalTexture& operator=(VertexPositionNormalTexture&&) = default; + + VertexPositionNormalTexture(XMFLOAT3 const& iposition, XMFLOAT3 const& inormal, XMFLOAT2 const& itextureCoordinate) noexcept + : position(iposition), + normal(inormal), + textureCoordinate(itextureCoordinate) + { + } + + VertexPositionNormalTexture(FXMVECTOR iposition, FXMVECTOR inormal, FXMVECTOR itextureCoordinate) noexcept + { + XMStoreFloat3(&this->position, iposition); + XMStoreFloat3(&this->normal, inormal); + XMStoreFloat2(&this->textureCoordinate, itextureCoordinate); + } + + XMFLOAT3 position; + XMFLOAT3 normal; + XMFLOAT2 textureCoordinate; + + static constexpr unsigned int InputElementCount = 3; + static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; + }; + + + // Vertex struct holding position, normal vector, color, and texture mapping information. + struct VertexPositionNormalColorTexture + { + VertexPositionNormalColorTexture() = default; + + VertexPositionNormalColorTexture(const VertexPositionNormalColorTexture&) = default; + VertexPositionNormalColorTexture& operator=(const VertexPositionNormalColorTexture&) = default; + + VertexPositionNormalColorTexture(VertexPositionNormalColorTexture&&) = default; + VertexPositionNormalColorTexture& operator=(VertexPositionNormalColorTexture&&) = default; + + VertexPositionNormalColorTexture( + XMFLOAT3 const& iposition, + XMFLOAT3 const& inormal, + XMFLOAT4 const& icolor, + XMFLOAT2 const& itextureCoordinate) noexcept + : position(iposition), + normal(inormal), + color(icolor), + textureCoordinate(itextureCoordinate) + { + } + + VertexPositionNormalColorTexture(FXMVECTOR iposition, FXMVECTOR inormal, FXMVECTOR icolor, CXMVECTOR itextureCoordinate) noexcept + { + XMStoreFloat3(&this->position, iposition); + XMStoreFloat3(&this->normal, inormal); + XMStoreFloat4(&this->color, icolor); + XMStoreFloat2(&this->textureCoordinate, itextureCoordinate); + } + + XMFLOAT3 position; + XMFLOAT3 normal; + XMFLOAT4 color; + XMFLOAT2 textureCoordinate; + + static constexpr unsigned int InputElementCount = 4; + static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; + }; + + + // Vertex struct for Visual Studio Shader Designer (DGSL) holding position, normal, + // tangent, color (RGBA), and texture mapping information + struct VertexPositionNormalTangentColorTexture + { + VertexPositionNormalTangentColorTexture() = default; + + VertexPositionNormalTangentColorTexture(const VertexPositionNormalTangentColorTexture&) = default; + VertexPositionNormalTangentColorTexture& operator=(const VertexPositionNormalTangentColorTexture&) = default; + + VertexPositionNormalTangentColorTexture(VertexPositionNormalTangentColorTexture&&) = default; + VertexPositionNormalTangentColorTexture& operator=(VertexPositionNormalTangentColorTexture&&) = default; + + XMFLOAT3 position; + XMFLOAT3 normal; + XMFLOAT4 tangent; + uint32_t color; + XMFLOAT2 textureCoordinate; + + VertexPositionNormalTangentColorTexture( + XMFLOAT3 const& iposition, + XMFLOAT3 const& inormal, + XMFLOAT4 const& itangent, + uint32_t irgba, + XMFLOAT2 const& itextureCoordinate) noexcept + : position(iposition), + normal(inormal), + tangent(itangent), + color(irgba), + textureCoordinate(itextureCoordinate) + { + } + + VertexPositionNormalTangentColorTexture( + FXMVECTOR iposition, + FXMVECTOR inormal, + FXMVECTOR itangent, + uint32_t irgba, + CXMVECTOR itextureCoordinate) noexcept + : color(irgba) + { + XMStoreFloat3(&this->position, iposition); + XMStoreFloat3(&this->normal, inormal); + XMStoreFloat4(&this->tangent, itangent); + XMStoreFloat2(&this->textureCoordinate, itextureCoordinate); + } + + VertexPositionNormalTangentColorTexture( + XMFLOAT3 const& iposition, + XMFLOAT3 const& inormal, + XMFLOAT4 const& itangent, + XMFLOAT4 const& icolor, + XMFLOAT2 const& itextureCoordinate) noexcept + : position(iposition), + normal(inormal), + tangent(itangent), + color{}, + textureCoordinate(itextureCoordinate) + { + SetColor(icolor); + } + + VertexPositionNormalTangentColorTexture( + FXMVECTOR iposition, + FXMVECTOR inormal, + FXMVECTOR itangent, + CXMVECTOR icolor, + CXMVECTOR itextureCoordinate) noexcept + : color{} + { + XMStoreFloat3(&this->position, iposition); + XMStoreFloat3(&this->normal, inormal); + XMStoreFloat4(&this->tangent, itangent); + XMStoreFloat2(&this->textureCoordinate, itextureCoordinate); + + SetColor(icolor); + } + + void __cdecl SetColor(XMFLOAT4 const& icolor) noexcept { SetColor(XMLoadFloat4(&icolor)); } + void XM_CALLCONV SetColor(FXMVECTOR icolor) noexcept; + + static constexpr unsigned int InputElementCount = 5; + static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; + }; + + + // Vertex struct for Visual Studio Shader Designer (DGSL) holding position, normal, + // tangent, color (RGBA), texture mapping information, and skinning weights + struct VertexPositionNormalTangentColorTextureSkinning : public VertexPositionNormalTangentColorTexture + { + VertexPositionNormalTangentColorTextureSkinning() = default; + + VertexPositionNormalTangentColorTextureSkinning(const VertexPositionNormalTangentColorTextureSkinning&) = default; + VertexPositionNormalTangentColorTextureSkinning& operator=(const VertexPositionNormalTangentColorTextureSkinning&) = default; + + VertexPositionNormalTangentColorTextureSkinning(VertexPositionNormalTangentColorTextureSkinning&&) = default; + VertexPositionNormalTangentColorTextureSkinning& operator=(VertexPositionNormalTangentColorTextureSkinning&&) = default; + + uint32_t indices; + uint32_t weights; + + VertexPositionNormalTangentColorTextureSkinning( + XMFLOAT3 const& iposition, + XMFLOAT3 const& inormal, + XMFLOAT4 const& itangent, + uint32_t irgba, + XMFLOAT2 const& itextureCoordinate, + XMUINT4 const& iindices, + XMFLOAT4 const& iweights) noexcept + : VertexPositionNormalTangentColorTexture(iposition, inormal, itangent, irgba, itextureCoordinate), + indices{}, + weights{} + { + SetBlendIndices(iindices); + SetBlendWeights(iweights); + } + + VertexPositionNormalTangentColorTextureSkinning( + FXMVECTOR iposition, + FXMVECTOR inormal, + FXMVECTOR itangent, + uint32_t irgba, + CXMVECTOR itextureCoordinate, + XMUINT4 const& iindices, + CXMVECTOR iweights) noexcept + : VertexPositionNormalTangentColorTexture(iposition, inormal, itangent, irgba, itextureCoordinate), + indices{}, + weights{} + { + SetBlendIndices(iindices); + SetBlendWeights(iweights); + } + + VertexPositionNormalTangentColorTextureSkinning( + XMFLOAT3 const& iposition, + XMFLOAT3 const& inormal, + XMFLOAT4 const& itangent, + XMFLOAT4 const& icolor, + XMFLOAT2 const& itextureCoordinate, + XMUINT4 const& iindices, + XMFLOAT4 const& iweights) noexcept + : VertexPositionNormalTangentColorTexture(iposition, inormal, itangent, icolor, itextureCoordinate), + indices{}, + weights{} + { + SetBlendIndices(iindices); + SetBlendWeights(iweights); + } + + VertexPositionNormalTangentColorTextureSkinning( + FXMVECTOR iposition, + FXMVECTOR inormal, + FXMVECTOR itangent, + CXMVECTOR icolor, + CXMVECTOR itextureCoordinate, + XMUINT4 const& iindices, + CXMVECTOR iweights) noexcept + : VertexPositionNormalTangentColorTexture(iposition, inormal, itangent, icolor, itextureCoordinate), + indices{}, + weights{} + { + SetBlendIndices(iindices); + SetBlendWeights(iweights); + } + + void __cdecl SetBlendIndices(XMUINT4 const& iindices) noexcept; + + void __cdecl SetBlendWeights(XMFLOAT4 const& iweights) noexcept { SetBlendWeights(XMLoadFloat4(&iweights)); } + void XM_CALLCONV SetBlendWeights(FXMVECTOR iweights) noexcept; + + static constexpr unsigned int InputElementCount = 7; + static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; + }; + } +} diff --git a/enginecustom/include/Inc/WICTextureLoader.h b/enginecustom/include/Inc/WICTextureLoader.h new file mode 100644 index 0000000..82eeeae --- /dev/null +++ b/enginecustom/include/Inc/WICTextureLoader.h @@ -0,0 +1,177 @@ +//-------------------------------------------------------------------------------------- +// File: WICTextureLoader.h +// +// Function for loading a WIC image and creating a Direct3D runtime texture for it +// (auto-generating mipmaps if possible) +// +// Note: Assumes application has already called CoInitializeEx +// +// Warning: CreateWICTexture* functions are not thread-safe if given a d3dContext instance for +// auto-gen mipmap support. +// +// Note these functions are useful for images created as simple 2D textures. For +// more complex resources, DDSTextureLoader is an excellent light-weight runtime loader. +// For a full-featured DDS file reader, writer, and texture processing pipeline see +// the 'Texconv' sample and the 'DirectXTex' library. +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248926 +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +#include +#include + +#ifdef _MSC_VER +#pragma comment(lib,"uuid.lib") +#endif + + +namespace DirectX +{ + inline namespace DX11 + { + enum WIC_LOADER_FLAGS : uint32_t + { + WIC_LOADER_DEFAULT = 0, + WIC_LOADER_FORCE_SRGB = 0x1, + WIC_LOADER_IGNORE_SRGB = 0x2, + WIC_LOADER_SRGB_DEFAULT = 0x4, + WIC_LOADER_FIT_POW2 = 0x20, + WIC_LOADER_MAKE_SQUARE = 0x40, + WIC_LOADER_FORCE_RGBA32 = 0x80, + }; + } + + // Standard version + HRESULT __cdecl CreateWICTextureFromMemory( + _In_ ID3D11Device* d3dDevice, + _In_reads_bytes_(wicDataSize) const uint8_t* wicData, + _In_ size_t wicDataSize, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0) noexcept; + + HRESULT __cdecl CreateWICTextureFromFile( + _In_ ID3D11Device* d3dDevice, + _In_z_ const wchar_t* szFileName, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0) noexcept; + + // Standard version with optional auto-gen mipmap support + HRESULT __cdecl CreateWICTextureFromMemory( + #if defined(_XBOX_ONE) && defined(_TITLE) + _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_reads_bytes_(wicDataSize) const uint8_t* wicData, + _In_ size_t wicDataSize, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0) noexcept; + + HRESULT __cdecl CreateWICTextureFromFile( + #if defined(_XBOX_ONE) && defined(_TITLE) + _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_z_ const wchar_t* szFileName, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _In_ size_t maxsize = 0) noexcept; + + // Extended version + HRESULT __cdecl CreateWICTextureFromMemoryEx( + _In_ ID3D11Device* d3dDevice, + _In_reads_bytes_(wicDataSize) const uint8_t* wicData, + _In_ size_t wicDataSize, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ WIC_LOADER_FLAGS loadFlags, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView) noexcept; + + HRESULT __cdecl CreateWICTextureFromFileEx( + _In_ ID3D11Device* d3dDevice, + _In_z_ const wchar_t* szFileName, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ WIC_LOADER_FLAGS loadFlags, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView) noexcept; + + // Extended version with optional auto-gen mipmap support + HRESULT __cdecl CreateWICTextureFromMemoryEx( + #if defined(_XBOX_ONE) && defined(_TITLE) + _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_reads_bytes_(wicDataSize) const uint8_t* wicData, + _In_ size_t wicDataSize, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ WIC_LOADER_FLAGS loadFlags, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView) noexcept; + + HRESULT __cdecl CreateWICTextureFromFileEx( + #if defined(_XBOX_ONE) && defined(_TITLE) + _In_ ID3D11DeviceX* d3dDevice, + _In_opt_ ID3D11DeviceContextX* d3dContext, + #else + _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + #endif + _In_z_ const wchar_t* szFileName, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ WIC_LOADER_FLAGS loadFlags, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView) noexcept; + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-dynamic-exception-spec" +#endif + + inline namespace DX11 + { + DEFINE_ENUM_FLAG_OPERATORS(WIC_LOADER_FLAGS); + } + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +} diff --git a/enginecustom/include/Inc/XboxDDSTextureLoader.h b/enginecustom/include/Inc/XboxDDSTextureLoader.h new file mode 100644 index 0000000..1d8bb2f --- /dev/null +++ b/enginecustom/include/Inc/XboxDDSTextureLoader.h @@ -0,0 +1,67 @@ +//-------------------------------------------------------------------------------------- +// File: XboxDDSTextureLoader.h +// +// Functions for loading a DDS texture using the XBOX extended header and creating a +// Direct3D11.X runtime resource for it via the CreatePlacement APIs +// +// Note these functions will not load standard DDS files. Use the DDSTextureLoader +// module in the DirectXTex package or as part of the DirectXTK library to load +// these files which use standard Direct3D resource creation APIs. +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkId=248926 +// http://go.microsoft.com/fwlink/?LinkId=248929 +//-------------------------------------------------------------------------------------- + +#pragma once + +#if !defined(_XBOX_ONE) || !defined(_TITLE) +#error This module only supports Xbox One exclusive apps +#endif + +#include + +#include +#include + +#ifndef DDS_ALPHA_MODE_DEFINED +#define DDS_ALPHA_MODE_DEFINED +namespace DirectX +{ + enum DDS_ALPHA_MODE : uint32_t + { + DDS_ALPHA_MODE_UNKNOWN = 0, + DDS_ALPHA_MODE_STRAIGHT = 1, + DDS_ALPHA_MODE_PREMULTIPLIED = 2, + DDS_ALPHA_MODE_OPAQUE = 3, + DDS_ALPHA_MODE_CUSTOM = 4, + }; +} +#endif + +namespace Xbox +{ + using DirectX::DDS_ALPHA_MODE; + + HRESULT __cdecl CreateDDSTextureFromMemory( + _In_ ID3D11DeviceX* d3dDevice, + _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, + _In_ size_t ddsDataSize, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _Outptr_ void** grfxMemory, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr, + _In_ bool forceSRGB = false) noexcept; + + HRESULT __cdecl CreateDDSTextureFromFile( _In_ ID3D11DeviceX* d3dDevice, + _In_z_ const wchar_t* szFileName, + _Outptr_opt_ ID3D11Resource** texture, + _Outptr_opt_ ID3D11ShaderResourceView** textureView, + _Outptr_ void** grfxMemory, + _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr, + _In_ bool forceSRGB = false) noexcept; + + void FreeDDSTextureMemory( _In_opt_ void* grfxMemory ) noexcept; +} diff --git a/enginecustom/modelclass.cpp b/enginecustom/modelclass.cpp index 55ace1b..1d00fb0 100644 --- a/enginecustom/modelclass.cpp +++ b/enginecustom/modelclass.cpp @@ -5,7 +5,6 @@ ModelClass::ModelClass() { m_vertexBuffer = 0; m_indexBuffer = 0; - m_Textures = 0; m_model = 0; } @@ -19,16 +18,14 @@ ModelClass::~ModelClass() { } -bool ModelClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* modelFilename, vector filename) -{ - Logger::Get().Log("Initializing model class", __FILE__, __LINE__, Logger::LogLevel::Initialize); +bool ModelClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* modelFilename, std::vector textures) { + Logger::Get().Log("Initializing model class with preloaded textures", __FILE__, __LINE__, Logger::LogLevel::Initialize); bool result; // Load in the model data. result = LoadModel(modelFilename); - if (!result) - { + if (!result) { Logger::Get().Log("Failed to load model data", __FILE__, __LINE__, Logger::LogLevel::Error); return false; } @@ -38,20 +35,14 @@ bool ModelClass::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceCon // Initialize the vertex and index buffers. result = InitializeBuffers(device); - if (!result) - { + if (!result) { Logger::Get().Log("Failed to initialize buffers", __FILE__, __LINE__, Logger::LogLevel::Error); return false; } - // Load the textures for this model. - result = LoadTextures(device, deviceContext, filename); - if (!result) - { - Logger::Get().Log("Failed to load textures", __FILE__, __LINE__, Logger::LogLevel::Error); - return false; - } - Logger::Get().Log("Model class initialized", __FILE__, __LINE__, Logger::LogLevel::Initialize); + m_Textures = textures; + + Logger::Get().Log("Model class initialized with preloaded textures", __FILE__, __LINE__, Logger::LogLevel::Initialize); return true; } @@ -88,7 +79,7 @@ int ModelClass::GetIndexCount() ID3D11ShaderResourceView* ModelClass::GetTexture(int index) { - return m_Textures[index].GetTexture(); + return m_Textures[index]; } @@ -221,52 +212,23 @@ void ModelClass::RenderBuffers(ID3D11DeviceContext* deviceContext) return; } - -bool ModelClass::LoadTextures(ID3D11Device* device, ID3D11DeviceContext* deviceContext, vector textureFile) -{ - Logger::Get().Log("Loading textures", __FILE__, __LINE__); - - bool result; - - // Create and initialize the texture object array. - m_Textures = new TextureClass[textureFile.size()]; - - for (int i = 0; i < textureFile.size(); i++) - { - result = m_Textures[i].Initialize(device, deviceContext, textureFile[i]); - if (!result) - { - Logger::Get().Log("Failed to initialize texture", __FILE__, __LINE__, Logger::LogLevel::Error); - return false; - } - } - - Logger::Get().Log("Textures loaded", __FILE__, __LINE__); - - return true; -} - void ModelClass::ReleaseTextures() { Logger::Get().Log("Releasing textures", __FILE__, __LINE__); // Release the texture object array. - if (m_Textures) + for (auto& texture : m_Textures) { - m_Textures[0].Shutdown(); - m_Textures[1].Shutdown(); - m_Textures[2].Shutdown(); - m_Textures[3].Shutdown(); - m_Textures[4].Shutdown(); - m_Textures[5].Shutdown(); - - delete[] m_Textures; - m_Textures = 0; + if (texture) + { + texture->Release(); + texture = nullptr; + } } - Logger::Get().Log("Textures released", __FILE__, __LINE__); + m_Textures.clear(); - return; + Logger::Get().Log("Textures released", __FILE__, __LINE__); } bool ModelClass::LoadModel(char* filename) @@ -590,23 +552,39 @@ void ModelClass::ReleaseModel() bool ModelClass::ChangeTexture(ID3D11Device* device, ID3D11DeviceContext* deviceContext, std::wstring filename, int index) { - bool result; + Logger::Get().Log("Changing texture", __FILE__, __LINE__, Logger::LogLevel::Initialize); - // convert wstring to string - std::string str(filename.begin(), filename.end()); + HRESULT result; + ID3D11ShaderResourceView* newTexture = nullptr; - // Release the old texture object. - m_Textures[index].Shutdown(); - - // Initialize the new texture object. - result = m_Textures[index].Initialize(device, deviceContext, str); - if (!result) + // Load the new texture using WICTextureLoader. + result = DirectX::CreateWICTextureFromFile(device, deviceContext, filename.c_str(), nullptr, &newTexture); + if (FAILED(result)) { - Logger::Get().Log("Failed to initialize texture", __FILE__, __LINE__, Logger::LogLevel::Error); + Logger::Get().Log("Failed to load new texture", __FILE__, __LINE__, Logger::LogLevel::Error); return false; } - Logger::Get().Log("Texture changed", __FILE__, __LINE__, Logger::LogLevel::Debug); + // Release the old texture if it exists. + if (index >= 0 && index < m_Textures.size() && m_Textures[index]) + { + m_Textures[index]->Release(); + m_Textures[index] = nullptr; + } + // Assign the new texture to the specified index. + if (index >= 0 && index < m_Textures.size()) + { + m_Textures[index] = newTexture; + } + else + { + // If the index is out of range, log an error and release the new texture. + Logger::Get().Log("Texture index out of range", __FILE__, __LINE__, Logger::LogLevel::Error); + newTexture->Release(); + return false; + } + + Logger::Get().Log("Texture changed successfully", __FILE__, __LINE__, Logger::LogLevel::Initialize); return true; } \ No newline at end of file diff --git a/enginecustom/modelclass.h b/enginecustom/modelclass.h index d55f5a2..24376ed 100644 --- a/enginecustom/modelclass.h +++ b/enginecustom/modelclass.h @@ -13,6 +13,7 @@ #include #include #include +#include using namespace DirectX; using namespace std; @@ -82,7 +83,8 @@ public: ModelClass(const ModelClass&); ~ModelClass(); - bool Initialize(ID3D11Device*, ID3D11DeviceContext*, char*, vector); + bool Initialize(ID3D11Device*, ID3D11DeviceContext*, char*, std::vector); + void Shutdown(); void Render(ID3D11DeviceContext*); @@ -108,7 +110,7 @@ private: private: ID3D11Buffer* m_vertexBuffer, * m_indexBuffer; int m_vertexCount, m_indexCount; - TextureClass* m_Textures; + std::vector m_Textures; ModelType* m_model; }; diff --git a/enginecustom/object.cpp b/enginecustom/object.cpp index 335e3bb..c07198e 100644 --- a/enginecustom/object.cpp +++ b/enginecustom/object.cpp @@ -17,6 +17,23 @@ Object::Object() : ModelClass() Object::~Object() { + if (m_Texture) { + m_Texture->Release(); + m_Texture = nullptr; + } +} + +bool Object::LoadTexture(ID3D11Device* device, ID3D11DeviceContext* deviceContext, const std::wstring& filename) { + HRESULT result = DirectX::CreateWICTextureFromFile(device, deviceContext, filename.c_str(), nullptr, &m_Texture); + if (FAILED(result)) { + return false; + } + return true; +} + +ID3D11ShaderResourceView* Object::GetTexture() const +{ + return m_Texture; } void Object::SetScaleMatrix(XMMATRIX scaleMatrix) diff --git a/enginecustom/object.h b/enginecustom/object.h index 86ea467..fd22899 100644 --- a/enginecustom/object.h +++ b/enginecustom/object.h @@ -1,5 +1,7 @@ #pragma once #include "modelclass.h" +#include +#include class Object : public ModelClass { @@ -50,6 +52,10 @@ public: int SetId(int id); int GetId() const; + bool LoadTexture(ID3D11Device* device, ID3D11DeviceContext* deviceContext, const std::wstring& filename); + + ID3D11ShaderResourceView* GetTexture() const; + public : bool m_demoSpinning = false; XMVECTOR m_previousPosition; @@ -68,5 +74,5 @@ private: bool m_isGrounded; std::string m_name; - + ID3D11ShaderResourceView* m_Texture; };