diff options
Diffstat (limited to 'samples')
| -rw-r--r-- | samples/AnselSDKDelayLoader/source/DelayLoader.cpp | 500 | ||||
| -rw-r--r-- | samples/AnselSDKDelayLoader/source/DelayLoader.h | 6 |
2 files changed, 276 insertions, 230 deletions
diff --git a/samples/AnselSDKDelayLoader/source/DelayLoader.cpp b/samples/AnselSDKDelayLoader/source/DelayLoader.cpp index 6b837fb..0756764 100644 --- a/samples/AnselSDKDelayLoader/source/DelayLoader.cpp +++ b/samples/AnselSDKDelayLoader/source/DelayLoader.cpp @@ -31,6 +31,7 @@ #include <ansel/Camera.h> #include <ansel/Hints.h> #include <ansel/Configuration.h> +#include <ansel/UserControls.h> #include <cmath> #include <Windows.h> #include <stdio.h> @@ -39,243 +40,288 @@ namespace { - HMODULE anselSDK = NULL; + HMODULE anselSDK = NULL; } namespace ansel { - namespace - { - typedef SetConfigurationStatus(__cdecl *PFNSETCONFIGURATION)(const Configuration& cfg); - typedef void(__cdecl *PFNUPDATECAMERA)(Camera& camera); - typedef void(__cdecl *PFNSESSIONFUNC)(); - typedef bool(__cdecl *PFNISANSELAVAILABLE)(); - typedef void(__cdecl *PFNMARKHDRBUFFERBIND)(HintType, uint64_t); - typedef void(__cdecl *PFNMARKHDRBUFFERFINISHED)(uint64_t); - PFNMARKHDRBUFFERFINISHED markHdrBufferFinishedFunc = nullptr; - PFNMARKHDRBUFFERBIND markHdrBufferBindFunc = nullptr; - PFNSESSIONFUNC stopSessionFunc = nullptr; - PFNSESSIONFUNC startSessionFunc = nullptr; - PFNUPDATECAMERA updateCameraFunc = nullptr; - PFNSETCONFIGURATION setConfigurationFunc = nullptr; - - DelayLoadStatus resolveFunctionPointers() - { - if (anselSDK == NULL) - return kDelayLoadDllNotFound; - - setConfigurationFunc = reinterpret_cast<PFNSETCONFIGURATION>(GetProcAddress(anselSDK, "setConfiguration")); - stopSessionFunc = reinterpret_cast<PFNSESSIONFUNC>(GetProcAddress(anselSDK, "stopSession")); - startSessionFunc = reinterpret_cast<PFNSESSIONFUNC>(GetProcAddress(anselSDK, "startSession")); - updateCameraFunc = reinterpret_cast<PFNUPDATECAMERA>(GetProcAddress(anselSDK, "updateCamera")); - markHdrBufferBindFunc = reinterpret_cast<PFNMARKHDRBUFFERBIND>(GetProcAddress(anselSDK, "markHdrBufferBind")); - markHdrBufferFinishedFunc = reinterpret_cast<PFNMARKHDRBUFFERFINISHED>(GetProcAddress(anselSDK, "markHdrBufferFinished")); - - if (setConfigurationFunc == nullptr || - stopSessionFunc == nullptr || - startSessionFunc == nullptr || - updateCameraFunc == nullptr || - markHdrBufferBindFunc == nullptr || - markHdrBufferFinishedFunc == nullptr) - return kDelayLoadIncompatibleVersion; - - return kDelayLoadOk; - } - - void makeQuaternionFromRotationMatrix(nv::Quat& q, const float r[3][3]) - { - float trace = r[0][0] + r[1][1] + r[2][2]; - - if (trace > 0.0f) { - // |w| > 1/2, may as well choose w > 1/2 - float s = sqrtf(trace + 1.0f); // 2w - - q.w = s * 0.5f; - s = 0.5f / s; // 1/(4w) - - q.x = (r[2][1] - r[1][2]) * s; - q.y = (r[0][2] - r[2][0]) * s; - q.z = (r[1][0] - r[0][1]) * s; - } - else { - // |w| <= 1/2 - int i = 0; - if (r[1][1] > r[0][0]) i = 1; - if (r[2][2] > r[i][i]) i = 2; - - int j = (1 << i) & 3; // i + 1 modulo 3. - int k = (1 << j) & 3; - - float s = sqrtf(r[i][i] - r[j][j] - r[k][k] + 1.0f); - - float* component = &q.x; - component[i] = s * 0.5f; - s = 0.5f / s; - component[j] = (r[i][j] + r[j][i]) * s; - component[k] = (r[k][i] + r[i][k]) * s; - q.w = (r[k][j] - r[j][k]) * s; - } - } - - void makeRotationMatrixFromQuaternion(float rot[3][3], const nv::Quat& q) - { - float s = 2.0f; - - float xs = q.x * s; - float ys = q.y * s; - float zs = q.z * s; - - float wx = q.w * xs; - float wy = q.w * ys; - float wz = q.w * zs; - - float xx = q.x * xs; - float xy = q.x * ys; - float xz = q.x * zs; - - float yy = q.y * ys; - float yz = q.y * zs; - float zz = q.z * zs; - - rot[0][0] = 1.0f - (yy + zz); - rot[0][1] = xy - wz; - rot[0][2] = xz + wy; - - rot[1][0] = xy + wz; - rot[1][1] = 1.0f - (xx + zz); - rot[1][2] = yz - wx; - - rot[2][0] = xz - wy; - rot[2][1] = yz + wx; - rot[2][2] = 1.0f - (xx + yy); - } - - // This may seem like a funky construct so allow me to explain. This code serves only - // one purpose: to create a signaling object that Ansel (when loaded from driver shim) - // can use to detect that a game has integrated the SDK. Note that this same object - // will also be created by the SDK DLL when loaded but this is safe since creating - // the same mutex again just provides a handle to the already existing mutex. - class SdkMutex - { - public: - SdkMutex() - { - DWORD id = GetCurrentProcessId(); - char name[MAX_PATH]; - sprintf_s(name, "NVIDIA/Ansel/%d", id); - CreateMutexA(NULL, false, name); - } - }; - - SdkMutex s_mySdkMutex; - } - - - SetConfigurationStatus setConfiguration(const Configuration& config) - { - if (setConfigurationFunc) - return setConfigurationFunc(config); - else - return kSetConfigurationSdkNotLoaded; - } - - void updateCamera(ansel::Camera& cam) - { - if (updateCameraFunc) - updateCameraFunc(cam); - } - - void stopSession() - { - if (stopSessionFunc) - stopSessionFunc(); - } - - void startSession() - { - if (startSessionFunc) - startSessionFunc(); - } - - bool isAnselAvailable() - { - // search for NvCamera32/64 DLL in the process - const char* moduleName = + namespace + { + typedef SetConfigurationStatus(__cdecl *PFNSETCONFIGURATION)(const Configuration& cfg); + typedef void(__cdecl *PFNUPDATECAMERA)(Camera& camera); + typedef void(__cdecl *PFNSESSIONFUNC)(); + typedef bool(__cdecl *PFNISANSELAVAILABLE)(); + typedef void(__cdecl *PFNMARKHDRBUFFERBIND)(HintType, uint64_t); + typedef void(__cdecl *PFNMARKHDRBUFFERFINISHED)(uint64_t); + typedef UserControlStatus(__cdecl *PFNADDUSERCONTROL)(const UserControlDesc&); + typedef UserControlStatus(__cdecl *PFNSETUSERCONTROLLABELLOCALIZATION)(uint32_t, const char*, const char*); + typedef UserControlStatus(__cdecl *PFNREMOVEUSERCONTROL)(uint32_t); + typedef UserControlStatus(__cdecl *PFNGETUSERCONTROLVALUE)(uint32_t, void*); + + PFNMARKHDRBUFFERFINISHED markHdrBufferFinishedFunc = nullptr; + PFNMARKHDRBUFFERBIND markHdrBufferBindFunc = nullptr; + PFNSESSIONFUNC stopSessionFunc = nullptr; + PFNSESSIONFUNC startSessionFunc = nullptr; + PFNUPDATECAMERA updateCameraFunc = nullptr; + PFNSETCONFIGURATION setConfigurationFunc = nullptr; + PFNADDUSERCONTROL addUserControlFunc = nullptr; + PFNSETUSERCONTROLLABELLOCALIZATION setUserControlLabelLocalizationFunc = nullptr; + PFNREMOVEUSERCONTROL removeUserControlFunc = nullptr; + PFNGETUSERCONTROLVALUE getUserControlValueFunc = nullptr; + + DelayLoadStatus resolveFunctionPointers() + { + if (anselSDK == NULL) + return kDelayLoadDllNotFound; + + setConfigurationFunc = reinterpret_cast<PFNSETCONFIGURATION>(GetProcAddress(anselSDK, "setConfiguration")); + stopSessionFunc = reinterpret_cast<PFNSESSIONFUNC>(GetProcAddress(anselSDK, "stopSession")); + startSessionFunc = reinterpret_cast<PFNSESSIONFUNC>(GetProcAddress(anselSDK, "startSession")); + updateCameraFunc = reinterpret_cast<PFNUPDATECAMERA>(GetProcAddress(anselSDK, "updateCamera")); + markHdrBufferBindFunc = reinterpret_cast<PFNMARKHDRBUFFERBIND>(GetProcAddress(anselSDK, "markHdrBufferBind")); + markHdrBufferFinishedFunc = reinterpret_cast<PFNMARKHDRBUFFERFINISHED>(GetProcAddress(anselSDK, "markHdrBufferFinished")); + addUserControlFunc = reinterpret_cast<PFNADDUSERCONTROL>(GetProcAddress(anselSDK, "addUserControl")); + setUserControlLabelLocalizationFunc = reinterpret_cast<PFNSETUSERCONTROLLABELLOCALIZATION>(GetProcAddress(anselSDK, "setUserControlLabelLocalization")); + removeUserControlFunc = reinterpret_cast<PFNREMOVEUSERCONTROL>(GetProcAddress(anselSDK, "removeUserControl")); + getUserControlValueFunc = reinterpret_cast<PFNGETUSERCONTROLVALUE>(GetProcAddress(anselSDK, "getUserControlValue")); + + if (setConfigurationFunc == nullptr || + stopSessionFunc == nullptr || + startSessionFunc == nullptr || + updateCameraFunc == nullptr || + markHdrBufferBindFunc == nullptr || + markHdrBufferFinishedFunc == nullptr || + addUserControlFunc == nullptr || + setUserControlLabelLocalizationFunc == nullptr || + removeUserControlFunc == nullptr || + getUserControlValueFunc == nullptr) + return kDelayLoadIncompatibleVersion; + + return kDelayLoadOk; + } + + void makeQuaternionFromRotationMatrix(nv::Quat& q, const float r[3][3]) + { + float trace = r[0][0] + r[1][1] + r[2][2]; + + if (trace > 0.0f) { + // |w| > 1/2, may as well choose w > 1/2 + float s = sqrtf(trace + 1.0f); // 2w + + q.w = s * 0.5f; + s = 0.5f / s; // 1/(4w) + + q.x = (r[2][1] - r[1][2]) * s; + q.y = (r[0][2] - r[2][0]) * s; + q.z = (r[1][0] - r[0][1]) * s; + } + else { + // |w| <= 1/2 + int i = 0; + if (r[1][1] > r[0][0]) i = 1; + if (r[2][2] > r[i][i]) i = 2; + + int j = (1 << i) & 3; // i + 1 modulo 3. + int k = (1 << j) & 3; + + float s = sqrtf(r[i][i] - r[j][j] - r[k][k] + 1.0f); + + float* component = &q.x; + component[i] = s * 0.5f; + s = 0.5f / s; + component[j] = (r[i][j] + r[j][i]) * s; + component[k] = (r[k][i] + r[i][k]) * s; + q.w = (r[k][j] - r[j][k]) * s; + } + } + + void makeRotationMatrixFromQuaternion(float rot[3][3], const nv::Quat& q) + { + float s = 2.0f; + + float xs = q.x * s; + float ys = q.y * s; + float zs = q.z * s; + + float wx = q.w * xs; + float wy = q.w * ys; + float wz = q.w * zs; + + float xx = q.x * xs; + float xy = q.x * ys; + float xz = q.x * zs; + + float yy = q.y * ys; + float yz = q.y * zs; + float zz = q.z * zs; + + rot[0][0] = 1.0f - (yy + zz); + rot[0][1] = xy - wz; + rot[0][2] = xz + wy; + + rot[1][0] = xy + wz; + rot[1][1] = 1.0f - (xx + zz); + rot[1][2] = yz - wx; + + rot[2][0] = xz - wy; + rot[2][1] = yz + wx; + rot[2][2] = 1.0f - (xx + yy); + } + + // This may seem like a funky construct so allow me to explain. This code serves only + // one purpose: to create a signaling object that Ansel (when loaded from driver shim) + // can use to detect that a game has integrated the SDK. Note that this same object + // will also be created by the SDK DLL when loaded but this is safe since creating + // the same mutex again just provides a handle to the already existing mutex. + class SdkMutex + { + public: + SdkMutex() + { + DWORD id = GetCurrentProcessId(); + char name[MAX_PATH]; + sprintf_s(name, "NVIDIA/Ansel/%d", id); + CreateMutexA(NULL, false, name); + } + }; + + SdkMutex s_mySdkMutex; + } + + + SetConfigurationStatus setConfiguration(const Configuration& config) + { + if (setConfigurationFunc) + return setConfigurationFunc(config); + else + return kSetConfigurationSdkNotLoaded; + } + + void updateCamera(ansel::Camera& cam) + { + if (updateCameraFunc) + updateCameraFunc(cam); + } + + void stopSession() + { + if (stopSessionFunc) + stopSessionFunc(); + } + + void startSession() + { + if (startSessionFunc) + startSessionFunc(); + } + + bool isAnselAvailable() + { + // search for NvCamera32/64 DLL in the process + const char* moduleName = #if _M_AMD64 - "NvCamera64.dll"; + "NvCamera64.dll"; #else - "NvCamera32.dll"; + "NvCamera32.dll"; #endif - return GetModuleHandleA(moduleName) != nullptr; - } - - void markHdrBufferBind(HintType hintType, uint64_t threadId) - { - if (markHdrBufferBindFunc) - markHdrBufferBindFunc(hintType, threadId); - } - - void markHdrBufferFinished(uint64_t threadId) - { - if (markHdrBufferFinishedFunc) - markHdrBufferFinishedFunc(threadId); - } - - void quaternionToRotationMatrixVectors(const nv::Quat& q, nv::Vec3& right, nv::Vec3& up, nv::Vec3& forward) - { - float rot[3][3]; - makeRotationMatrixFromQuaternion(rot, q); - right = { rot[0][0], rot[1][0], rot[2][0] }; - up = { rot[0][1], rot[1][1], rot[2][1] }; - forward = { rot[0][2], rot[1][2], rot[2][2] }; - } - - void rotationMatrixVectorsToQuaternion(const nv::Vec3& right, const nv::Vec3& up, const nv::Vec3& forward, nv::Quat& q) - { - const float rot[3][3] = { - { right.x, up.x, forward.x }, - { right.y, up.y, forward.y }, - { right.z, up.z, forward.z } - }; - makeQuaternionFromRotationMatrix(q, rot); - } + return GetModuleHandleA(moduleName) != nullptr; + } + + void markHdrBufferBind(HintType hintType, uint64_t threadId) + { + if (markHdrBufferBindFunc) + markHdrBufferBindFunc(hintType, threadId); + } + + void markHdrBufferFinished(uint64_t threadId) + { + if (markHdrBufferFinishedFunc) + markHdrBufferFinishedFunc(threadId); + } + + void quaternionToRotationMatrixVectors(const nv::Quat& q, nv::Vec3& right, nv::Vec3& up, nv::Vec3& forward) + { + float rot[3][3]; + makeRotationMatrixFromQuaternion(rot, q); + right = { rot[0][0], rot[1][0], rot[2][0] }; + up = { rot[0][1], rot[1][1], rot[2][1] }; + forward = { rot[0][2], rot[1][2], rot[2][2] }; + } + + void rotationMatrixVectorsToQuaternion(const nv::Vec3& right, const nv::Vec3& up, const nv::Vec3& forward, nv::Quat& q) + { + const float rot[3][3] = { + { right.x, up.x, forward.x }, + { right.y, up.y, forward.y }, + { right.z, up.z, forward.z } + }; + makeQuaternionFromRotationMatrix(q, rot); + } + + UserControlStatus addUserControl(const UserControlDesc& desc) + { + if (addUserControlFunc) + return addUserControlFunc(desc); + return UserControlStatus::kUserControlInvalidCallback; + } + + UserControlStatus setUserControlLabelLocalization(uint32_t userControlId, const char* lang, const char* labelUtf8) + { + if (setUserControlLabelLocalizationFunc) + return setUserControlLabelLocalizationFunc(userControlId, lang, labelUtf8); + return UserControlStatus::kUserControlInvalidCallback; + } + + UserControlStatus removeUserControl(uint32_t userControlId) + { + if (removeUserControlFunc) + return removeUserControlFunc(userControlId); + return UserControlStatus::kUserControlInvalidCallback; + } + + UserControlStatus getUserControlValue(uint32_t userControlId, void* value) + { + if (getUserControlValueFunc) + return getUserControlValueFunc(userControlId, value); + return UserControlStatus::kUserControlInvalidCallback; + } } DelayLoadStatus loadAnselSDKLibrary(const char* pathToLibraryUtf8) { - if (anselSDK == NULL) - { - if (pathToLibraryUtf8) - { - // convert from utf8 to wchar_t: - std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; - std::wstring pathWstring = converter.from_bytes(pathToLibraryUtf8); - anselSDK = LoadLibraryW(pathWstring.c_str()); - } - else - { - #if defined(_M_IX86) - #define ANSEL_BITNESS "32" - #elif defined(_M_AMD64) - #define ANSEL_BITNESS "64" - #endif - - #if defined(_DEBUG) - #define ANSEL_RUNTIME_FLAVOR "d" - #else - #define ANSEL_RUNTIME_FLAVOR "" - #endif - - const char* libName = "AnselSDK" ANSEL_BITNESS ANSEL_RUNTIME_FLAVOR ".dll"; - anselSDK = LoadLibraryA(libName); - } - - if (anselSDK == NULL) - return kDelayLoadDllNotFound; - else - return ansel::resolveFunctionPointers(); - } - - return kDelayLoadOk; + if (anselSDK == NULL) + { + if (pathToLibraryUtf8) + { + // convert from utf8 to wchar_t: + std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; + std::wstring pathWstring = converter.from_bytes(pathToLibraryUtf8); + anselSDK = LoadLibraryW(pathWstring.c_str()); + } + else + { + #if defined(_M_IX86) + #define ANSEL_BITNESS "32" + #elif defined(_M_AMD64) + #define ANSEL_BITNESS "64" + #endif + + #if defined(_DEBUG) + #define ANSEL_RUNTIME_FLAVOR "d" + #else + #define ANSEL_RUNTIME_FLAVOR "" + #endif + + const char* libName = "AnselSDK" ANSEL_BITNESS ANSEL_RUNTIME_FLAVOR ".dll"; + anselSDK = LoadLibraryA(libName); + } + + if (anselSDK == NULL) + return kDelayLoadDllNotFound; + else + return ansel::resolveFunctionPointers(); + } + + return kDelayLoadOk; } diff --git a/samples/AnselSDKDelayLoader/source/DelayLoader.h b/samples/AnselSDKDelayLoader/source/DelayLoader.h index 216261b..86192e1 100644 --- a/samples/AnselSDKDelayLoader/source/DelayLoader.h +++ b/samples/AnselSDKDelayLoader/source/DelayLoader.h @@ -29,9 +29,9 @@ enum DelayLoadStatus { - kDelayLoadOk = 0, - kDelayLoadDllNotFound = -1, - kDelayLoadIncompatibleVersion = -2, + kDelayLoadOk = 0, + kDelayLoadDllNotFound = -1, + kDelayLoadIncompatibleVersion = -2, }; // In order to use delay loading instead of regular linking to a dynamic library // define ANSEL_SDK_DELAYLOAD for the project and use this function to explicitly |