From 0f15c691e1e846f6c7e985ff0da89fe9b338f18d Mon Sep 17 00:00:00 2001 From: GeorgH93 Date: Tue, 25 May 2021 14:45:15 +0200 Subject: [PATCH] Add RGB10A2 type --- openVulkanoCpp/Math/RGB10A2.hpp | 205 ++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 openVulkanoCpp/Math/RGB10A2.hpp diff --git a/openVulkanoCpp/Math/RGB10A2.hpp b/openVulkanoCpp/Math/RGB10A2.hpp new file mode 100644 index 0000000..8f7a030 --- /dev/null +++ b/openVulkanoCpp/Math/RGB10A2.hpp @@ -0,0 +1,205 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "Math.hpp" + +namespace openVulkanoCpp::Math +{ + template + struct RGB10A2 + { + static constexpr TYPE VALUE_BITMASK = (1 << 10) - 1; + static constexpr TYPE MAX_VALUE = (1 << ((std::is_signed_v) ? 9 : 10)) - 1; + static constexpr TYPE MAX_ALPHA_VALUE = (std::is_signed_v) ? 1 : 3; + + union + { + TYPE value; + struct { + TYPE r:10; + TYPE g:10; + TYPE b:10; + TYPE a:2; + }; + }; + + RGB10A2(TYPE value = 0) : value(value) {} + + template || std::is_signed_v>> + void Set(Vector3 vec3) + { + vec3 &= VALUE_BITMASK; + SetUnchecked(vec3); + } + + template || std::is_signed_v>> + void Set(Vector3_SIMD vec3) + { + vec3 &= VALUE_BITMASK; + SetUnchecked(vec3); + } + + template || std::is_signed_v>> + void Set(Vector4 vec4) + { + vec4 &= VALUE_BITMASK; + SetUnchecked(vec4); + } + + template>> + void Set(const Vector3& vec3) + { + Set(Math::Vector3(vec3)); + } + + template>> + void Set(const Vector3_SIMD& vec3) + { + Set(Math::Vector3(vec3)); + } + + template>> + void Set(const Vector4& vec4) + { + Set(Math::Vector4(vec4)); + } + + template || std::is_signed_v>> + void const SetUnchecked(Vector3& vec3) + { + value = vec3.r | vec3.g << 10 | vec3.b << 20 | MAX_ALPHA_VALUE << 30; + } + + template || std::is_signed_v>> + void SetUnchecked(const Vector3_SIMD& vec3) + { + value = vec3.r | vec3.g << 10 | vec3.b << 20 | MAX_ALPHA_VALUE << 30; + } + + template || std::is_signed_v>> + void SetUnchecked(const Vector4& vec4) + { + value = vec4.r | vec4.g << 10 | vec4.b << 20 | vec4.a << 30; + } + + template>> + void SetNormalized(Vector3 vec3) + { + Set(Vector3(vec3 * static_cast(MAX_VALUE))); + } + + template>> + void SetNormalized(Vector3_SIMD vec3) + { + Set(Vector3_SIMD(vec3 * static_cast(MAX_VALUE))); + } + + template>> + void SetNormalized(Vector4 vec4) + { + Set(Vector4(vec4 * static_cast(MAX_VALUE))); + } + + void SetNormalized(const Vector3uc& vec3) + { + constexpr uint16_t factor = std::is_unsigned_v ? 4 : 2; + SetUnchecked(Math::Vector3us(vec3) * factor); + } + + void SetNormalized(const Vector3uc_SIMD& vec3) + { + constexpr uint16_t factor = std::is_unsigned_v ? 4 : 2; + SetUnchecked(Math::Vector3us(vec3) * factor); + } + + void SetNormalized(const Vector4uc& vec4) + { + Math::Vector4us value(vec4); + if constexpr(std::is_unsigned_v) + { + value.x *= 4; + value.y *= 4; + value.z *= 4; + value.w /= 255; + } + else + { + value.x *= 2; + value.y *= 2; + value.z *= 2; + value.w /= 85; + } + SetUnchecked(value); + } + + operator Math::Vector3f() const + { + float scale = 1.0f / MAX_VALUE; + return { r * scale, g * scale, b * scale }; + } + + operator Math::Vector3f_SIMD() const + { + float scale = 1.0f / MAX_VALUE; + return { r * scale, g * scale, b * scale }; + } + + operator Math::Vector4f() const + { + float scale = 1.0f / MAX_VALUE; + return { r * scale, g * scale, b * scale, a / static_cast(MAX_ALPHA_VALUE) }; + + } + + operator Math::Vector4uc() const + { + constexpr TYPE factor = std::is_unsigned_v ? 4 : 2; + return { r / factor, g / factor, b / factor, a * 255 / MAX_ALPHA_VALUE }; + } + + RGB10A2& operator =(const RGB10A2& rhs) + { + this->value = rhs.value; + return *this; + } + + template + RGB10A2& operator =(const Math::Vector3& rhs) + { + Set(rhs); + return *this; + } + + template + RGB10A2& operator =(const Math::Vector3_SIMD& rhs) + { + Set(rhs); + return *this; + } + + template + RGB10A2& operator =(const Math::Vector4& rhs) + { + Set(rhs); + return *this; + } + + bool operator==(const RGB10A2& rhs) + { + return value == rhs.value; + } + + bool operator!=(const RGB10A2& rhs) + { + return value != rhs.value; + } + }; + + typedef RGB10A2 RGB10A2U; + typedef RGB10A2 RGB10A2S; +}