/* * 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/Math.hpp" #include namespace OpenVulkano::Math { class RGBA5551 { static uint16_t Make5(uint8_t val) { return static_cast(val * 31.0f / 255.0f); } static uint8_t Unmake5(uint16_t val) { return static_cast(val * 255.0f / 31.0f); } static float Unmake5ToFloat(uint16_t val) { return std::clamp(val / 31.0f, 0.0f, 1.0f); } static uint16_t Make5FromFloat(float val) { return (uint16_t) std::clamp(val * 31.0f, 0.0f, 31.f); } public: union { uint16_t value; struct { uint16_t b : 5; uint16_t g : 5; uint16_t r : 5; uint16_t a : 1; }; }; RGBA5551() : b(0), g(0), r(0), a(1) {} template, bool> = true> RGBA5551(const Math::Vector3& color) : b(Make5(color.b)), g(Make5(color.g)), r(Make5(color.r)), a(1) { } template, bool> = true> RGBA5551(const Math::Vector4& color) : b(Make5(color.b)), g(Make5(color.g)), r(Make5(color.r)), a(color.a > 128) { } template, bool> = true> RGBA5551(const Math::Vector3& color) : b(Make5FromFloat(color.b)), g(Make5FromFloat(color.g)), r(Make5FromFloat(color.r)), a(1) { } template, bool> = true> RGBA5551(const Math::Vector4& color) : b(Make5FromFloat(color.b)), g(Make5FromFloat(color.g)), r(Make5FromFloat(color.r)), a(color.a > 0.5f) { } uint8_t GetR() const { return Unmake5(r); } uint8_t GetG() const { return Unmake5(g); } uint8_t GetB() const { return Unmake5(b); } uint8_t GetA() const { return a ? 255 : 0; } float GetR_Normalized() const { return Unmake5ToFloat(r); } float GetG_Normalized() const { return Unmake5ToFloat(g); } float GetB_Normalized() const { return Unmake5ToFloat(b); } float GetA_Normalized() const { return a; } void SetR(uint8_t red) { r = Make5(red); } void SetG(uint8_t green) { g = Make5(green); } void SetB(uint8_t blue) { b = Make5(blue); } void SetA(uint8_t alpha) { a = (alpha > 128); } void SetR_Normalized(float red) { r = Make5FromFloat(red); } void SetG_Normalized(float green) { g = Make5FromFloat(green); } void SetB_Normalized(float blue) { b = Make5FromFloat(blue); } void SetA_Normalized(float alpha) { a = (alpha > 0.5f); } template, bool> = true> Math::Vector3 Get3() const { return { GetR(), GetG(), GetB() }; } template, bool> = true> Math::Vector4 Get4() const { return { GetR(), GetG(), GetB(), GetA() }; } template, bool> = true> Math::Vector4 Get4Normalized() const { return { GetR_Normalized(), GetG_Normalized(), GetB_Normalized(), GetA_Normalized() }; } template, bool> = true> Math::Vector3 Get3Normalized() const { return { GetR_Normalized(), GetG_Normalized(), GetB_Normalized() }; } RGBA5551& operator=(const RGBA5551& other) { value = other.value; return *this; } bool operator==(const RGBA5551& other) const { return value == other.value; } bool operator!=(const RGBA5551& other) const { return value != other.value; } template, bool> = true> RGBA5551& operator=(const Math::Vector3& color) { SetR_Normalized(color.r); SetG_Normalized(color.g); SetB_Normalized(color.b); SetA_Normalized(1); return *this; } template, bool> = true> RGBA5551& operator=(const Math::Vector4& color) { SetR_Normalized(color.r); SetG_Normalized(color.g); SetB_Normalized(color.b); SetA_Normalized(color.a); return *this; } template, bool> = true> RGBA5551& operator=(const Math::Vector3& color) { SetR(color.r); SetG(color.g); SetB(color.b); SetA(255); return *this; } template, bool> = true> RGBA5551& operator=(const Math::Vector4& color) { SetR(color.r); SetG(color.g); SetB(color.b); SetA(color.a); return *this; } template, bool> = true> operator Math::Vector3() const { return Get3(); } template, bool> = true> operator Math::Vector3() const { return Get3Normalized(); } template, bool> = true> operator Math::Vector4() const { return Get4(); } template, bool> = true> operator Math::Vector4() const { return Get4Normalized(); } }; static_assert(sizeof(RGBA5551) == 2); }