/* * 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 OpenVulkano::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>> void Set(Vector3 vec3) { vec3 &= VALUE_BITMASK; SetUnchecked(vec3); } template>> void Set(Vector3_SIMD vec3) { vec3 &= VALUE_BITMASK; SetUnchecked(vec3); } template>> 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>> void const SetUnchecked(Vector3& vec3) { value = vec3.r | vec3.g << 10 | vec3.b << 20 | MAX_ALPHA_VALUE << 30; } template>> void SetUnchecked(const Vector3_SIMD& vec3) { value = vec3.r | vec3.g << 10 | vec3.b << 20 | MAX_ALPHA_VALUE << 30; } template>> 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(Vector3(vec4 * static_cast(MAX_VALUE)), vec4.a * static_cast(MAX_ALPHA_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 /= 85; } else { value.x *= 2; value.y *= 2; value.z *= 2; value.w /= 255; } 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 }; } operator Math::Vector4i() const { return { r, g, b, a }; } operator Math::Vector3i_SIMD() const { return { r, g, b }; } operator Math::Vector3i() const { return { r, g, b }; } 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; }