mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Feat] (MG_State/TextureState): Implement TextureState.
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
#pragma once
|
||||
|
||||
#include <Includes.h>
|
||||
|
||||
namespace MobileGL {
|
||||
|
||||
template <typename Derived, typename T, SizeT N>
|
||||
struct VecBase {
|
||||
Array<T, N> data;
|
||||
|
||||
VecBase() { std::fill(data.begin(), data.end(), T(0)); }
|
||||
|
||||
VecBase(std::initializer_list<T> init) {
|
||||
std::copy_n(init.begin(), std::min(N, init.size()), data.begin());
|
||||
if (init.size() < N) {
|
||||
std::fill(data.begin() + init.size(), data.end(), T(0));
|
||||
}
|
||||
}
|
||||
|
||||
explicit VecBase(T scalar) { std::fill(data.begin(), data.end(), scalar); }
|
||||
|
||||
T& operator[](SizeT index) {
|
||||
if (index >= N) throw std::out_of_range("Vector index out of range");
|
||||
return data[index];
|
||||
}
|
||||
|
||||
const T& operator[](SizeT index) const {
|
||||
if (index >= N) throw std::out_of_range("Vector index out of range");
|
||||
return data[index];
|
||||
}
|
||||
|
||||
bool operator==(const VecBase& rhs) const { return data == rhs.data; }
|
||||
bool operator!=(const VecBase& rhs) const { return !(*this == rhs); }
|
||||
|
||||
Derived operator+(const VecBase& rhs) const {
|
||||
Derived result;
|
||||
for (SizeT i = 0; i < N; ++i)
|
||||
result[i] = data[i] + rhs[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
Derived operator-(const VecBase& rhs) const {
|
||||
Derived result;
|
||||
for (SizeT i = 0; i < N; ++i)
|
||||
result[i] = data[i] - rhs[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
Derived operator*(T scalar) const {
|
||||
Derived result;
|
||||
for (SizeT i = 0; i < N; ++i)
|
||||
result[i] = data[i] * scalar;
|
||||
return result;
|
||||
}
|
||||
|
||||
Derived operator/(T scalar) const {
|
||||
if (scalar == 0) throw std::domain_error("Division by zero");
|
||||
T inv = T(1) / scalar;
|
||||
return *this * inv;
|
||||
}
|
||||
|
||||
T Dot(const VecBase& rhs) const {
|
||||
T result = T(0);
|
||||
for (SizeT i = 0; i < N; ++i)
|
||||
result += data[i] * rhs[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
T Length() const { return std::sqrt(Dot(*this)); }
|
||||
|
||||
Derived Normalized() const {
|
||||
T len = Length();
|
||||
if (len > 0) {
|
||||
return *this * (T(1) / len);
|
||||
}
|
||||
return static_cast<const Derived&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Vec2 : public VecBase<Vec2<T>, T, 2> {
|
||||
using Base = VecBase<Vec2<T>, T, 2>;
|
||||
using Base::Base;
|
||||
|
||||
Vec2(T x, T y) : Base{x, y} {}
|
||||
|
||||
T& x() { return (*this)[0]; }
|
||||
T& y() { return (*this)[1]; }
|
||||
const T& x() const { return (*this)[0]; }
|
||||
const T& y() const { return (*this)[1]; }
|
||||
|
||||
T Cross(const Vec2& rhs) const { return x() * rhs.y() - y() * rhs.x(); }
|
||||
|
||||
Vec2 Rotated(T angle) const {
|
||||
T cosA = std::cos(angle);
|
||||
T sinA = std::sin(angle);
|
||||
return {x() * cosA - y() * sinA, x() * sinA + y() * cosA};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Vec3 : public VecBase<Vec3<T>, T, 3> {
|
||||
using Base = VecBase<Vec3<T>, T, 3>;
|
||||
using Base::Base;
|
||||
|
||||
Vec3(T x, T y, T z) : Base{x, y, z} {}
|
||||
explicit Vec3(const Vec2<T>& v2, T z = T(0)) : Base{v2.x(), v2.y(), z} {}
|
||||
|
||||
T& x() { return (*this)[0]; }
|
||||
T& y() { return (*this)[1]; }
|
||||
T& z() { return (*this)[2]; }
|
||||
const T& x() const { return (*this)[0]; }
|
||||
const T& y() const { return (*this)[1]; }
|
||||
const T& z() const { return (*this)[2]; }
|
||||
|
||||
Vec2<T> xy() const { return {x(), y()}; }
|
||||
Vec2<T> xz() const { return {x(), z()}; }
|
||||
Vec2<T> yz() const { return {y(), z()}; }
|
||||
|
||||
Vec3 Cross(const Vec3& rhs) const {
|
||||
return {y() * rhs.z() - z() * rhs.y(), z() * rhs.x() - x() * rhs.z(), x() * rhs.y() - y() * rhs.x()};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Vec4 : public VecBase<Vec4<T>, T, 4> {
|
||||
using Base = VecBase<Vec4<T>, T, 4>;
|
||||
using Base::Base;
|
||||
|
||||
Vec4(T x, T y, T z, T w) : Base{x, y, z, w} {}
|
||||
explicit Vec4(const Vec3<T>& v3, T w = T(1)) : Base{v3.x(), v3.y(), v3.z(), w} {}
|
||||
|
||||
T& x() { return (*this)[0]; }
|
||||
T& y() { return (*this)[1]; }
|
||||
T& z() { return (*this)[2]; }
|
||||
T& w() { return (*this)[3]; }
|
||||
const T& x() const { return (*this)[0]; }
|
||||
const T& y() const { return (*this)[1]; }
|
||||
const T& z() const { return (*this)[2]; }
|
||||
const T& w() const { return (*this)[3]; }
|
||||
|
||||
Vec3<T> xyz() const { return {x(), y(), z()}; }
|
||||
Vec3<T> Homogenized() const { return (w() != 0) ? xyz() / w() : xyz(); }
|
||||
};
|
||||
|
||||
using IntVec2 = Vec2<Int32>;
|
||||
using IntVec3 = Vec3<Int32>;
|
||||
using IntVec4 = Vec4<Int32>;
|
||||
using UintVec2 = Vec2<Uint32>;
|
||||
using UintVec3 = Vec3<Uint32>;
|
||||
using UintVec4 = Vec4<Uint32>;
|
||||
using FloatVec2 = Vec2<Float>;
|
||||
using FloatVec3 = Vec3<Float>;
|
||||
using FloatVec4 = Vec4<Float>;
|
||||
|
||||
using Size2D = IntVec2;
|
||||
using Size3D = IntVec3;
|
||||
using TextureSize = IntVec3;
|
||||
|
||||
using ColorRGB = FloatVec3;
|
||||
using ColorRGBA = FloatVec4;
|
||||
using ColorRGB8 = UintVec3;
|
||||
using ColorRGBA8 = UintVec4;
|
||||
|
||||
namespace MG_Util {
|
||||
template <typename Derived, typename T, SizeT N>
|
||||
Derived Lerp(const VecBase<Derived, T, N>& a, const VecBase<Derived, T, N>& b, Float t) {
|
||||
Derived result;
|
||||
for (SizeT i = 0; i < N; ++i)
|
||||
result[i] = a[i] + (b[i] - a[i]) * t;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Derived, typename T, SizeT N>
|
||||
Derived MultiplyComponents(const VecBase<Derived, T, N>& a, const VecBase<Derived, T, N>& b) {
|
||||
Derived result;
|
||||
for (SizeT i = 0; i < N; ++i)
|
||||
result[i] = a[i] * b[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Derived, typename T, SizeT N>
|
||||
T Distance(const VecBase<Derived, T, N>& a, const VecBase<Derived, T, N>& b) {
|
||||
return (a - b).Length();
|
||||
}
|
||||
|
||||
inline FloatVec3 Reflect(const FloatVec3& incident, const FloatVec3& normal) {
|
||||
return incident - normal * (2.0f * incident.Dot(normal));
|
||||
}
|
||||
} // namespace MG_Util
|
||||
} // namespace MobileGL
|
||||
Reference in New Issue
Block a user