refactor(core): 重构代码组织结构,将类型定义移至types目录
将核心类型定义从core目录迁移至新创建的types目录,包括: - 基础类型别名(type_alias.h) - 数学相关类型(type_math.h) - 颜色类型(type_color.h) - 窗口配置合并至application.h 删除不再使用的平台配置和旧类型文件 优化头文件包含关系,减少编译依赖
This commit is contained in:
@@ -1,12 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <fostbite2D/core/window.h>
|
||||
#include <fostbite2D/module/module.h>
|
||||
#include <fostbite2D/config/app_config.h>
|
||||
#include <fostbite2D/platform/window.h>
|
||||
#include <fostbite2D/types/type_alias.h>
|
||||
#include <string>
|
||||
|
||||
namespace frostbite2D {
|
||||
|
||||
/**
|
||||
* @brief 应用配置结构体
|
||||
* 仅包含应用级别的配置项,模块配置由各模块自行管理
|
||||
*/
|
||||
struct AppConfig {
|
||||
std::string appName = "frostbite2D App";
|
||||
std::string appVersion = "1.0.0";
|
||||
std::string organization = "frostbite";
|
||||
|
||||
WindowConfig windowConfig;
|
||||
PlatformType targetPlatform = PlatformType::Auto;
|
||||
|
||||
/**
|
||||
* @brief 创建默认配置
|
||||
* @return 默认的应用配置实例
|
||||
*/
|
||||
static AppConfig createDefault() {
|
||||
AppConfig config;
|
||||
config.appName = "Frostbite2D App";
|
||||
config.appVersion = "1.0.0";
|
||||
config.organization = "frostbite";
|
||||
config.targetPlatform = PlatformType::Auto;
|
||||
config.windowConfig = WindowConfig();
|
||||
return config;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 应用程序类
|
||||
*/
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <fostbite2D/core/types.h>
|
||||
#include <algorithm>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
namespace frostbite2D {
|
||||
|
||||
/// RGB 颜色(字节,每通道 0-255)
|
||||
struct Color3B {
|
||||
uint8_t r = 255;
|
||||
uint8_t g = 255;
|
||||
uint8_t b = 255;
|
||||
|
||||
constexpr Color3B() = default;
|
||||
constexpr Color3B(uint8_t r, uint8_t g, uint8_t b) : r(r), g(g), b(b) {}
|
||||
|
||||
constexpr bool operator==(const Color3B &other) const {
|
||||
return r == other.r && g == other.g && b == other.b;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const Color3B &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
Color3B operator+(const Color3B &other) const {
|
||||
return Color3B(
|
||||
static_cast<uint8_t>(std::min(255, static_cast<int>(r) + other.r)),
|
||||
static_cast<uint8_t>(std::min(255, static_cast<int>(g) + other.g)),
|
||||
static_cast<uint8_t>(std::min(255, static_cast<int>(b) + other.b)));
|
||||
}
|
||||
|
||||
Color3B operator-(const Color3B &other) const {
|
||||
return Color3B(
|
||||
static_cast<uint8_t>(std::max(0, static_cast<int>(r) - other.r)),
|
||||
static_cast<uint8_t>(std::max(0, static_cast<int>(g) - other.g)),
|
||||
static_cast<uint8_t>(std::max(0, static_cast<int>(b) - other.b)));
|
||||
}
|
||||
};
|
||||
|
||||
/// RGBA 颜色(浮点数,每通道 0.0 - 1.0)
|
||||
struct Color {
|
||||
float r = 0.0f;
|
||||
float g = 0.0f;
|
||||
float b = 0.0f;
|
||||
float a = 1.0f;
|
||||
|
||||
constexpr Color() = default;
|
||||
|
||||
constexpr Color(float r, float g, float b, float a = 1.0f)
|
||||
: r(r), g(g), b(b), a(a) {}
|
||||
|
||||
/// 从 0xRRGGBB 整数构造
|
||||
constexpr explicit Color(uint32_t rgb, float a = 1.0f)
|
||||
: r(static_cast<float>((rgb >> 16) & 0xFF) / 255.0f),
|
||||
g(static_cast<float>((rgb >> 8) & 0xFF) / 255.0f),
|
||||
b(static_cast<float>((rgb) & 0xFF) / 255.0f), a(a) {}
|
||||
|
||||
/// 从 0-255 整数构造
|
||||
static constexpr Color fromRGBA(uint8_t r, uint8_t g, uint8_t b,
|
||||
uint8_t a = 255) {
|
||||
return Color(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
|
||||
}
|
||||
|
||||
/// 转换为 glm::vec4
|
||||
glm::vec4 toVec4() const { return {r, g, b, a}; }
|
||||
|
||||
/// 线性插值
|
||||
static Color lerp(const Color &a, const Color &b, float t) {
|
||||
t = std::clamp(t, 0.0f, 1.0f);
|
||||
return Color(a.r + (b.r - a.r) * t, a.g + (b.g - a.g) * t,
|
||||
a.b + (b.b - a.b) * t, a.a + (b.a - a.a) * t);
|
||||
}
|
||||
|
||||
bool operator==(const Color &other) const {
|
||||
return r == other.r && g == other.g && b == other.b && a == other.a;
|
||||
}
|
||||
|
||||
bool operator!=(const Color &other) const { return !(*this == other); }
|
||||
|
||||
// 算术运算符
|
||||
Color operator+(const Color &other) const {
|
||||
return Color(r + other.r, g + other.g, b + other.b, a + other.a);
|
||||
}
|
||||
|
||||
Color operator-(const Color &other) const {
|
||||
return Color(r - other.r, g - other.g, b - other.b, a - other.a);
|
||||
}
|
||||
|
||||
Color operator*(float scalar) const {
|
||||
return Color(r * scalar, g * scalar, b * scalar, a * scalar);
|
||||
}
|
||||
|
||||
Color operator/(float scalar) const {
|
||||
return Color(r / scalar, g / scalar, b / scalar, a / scalar);
|
||||
}
|
||||
|
||||
Color &operator+=(const Color &other) {
|
||||
r += other.r;
|
||||
g += other.g;
|
||||
b += other.b;
|
||||
a += other.a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Color &operator-=(const Color &other) {
|
||||
r -= other.r;
|
||||
g -= other.g;
|
||||
b -= other.b;
|
||||
a -= other.a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Color &operator*=(float scalar) {
|
||||
r *= scalar;
|
||||
g *= scalar;
|
||||
b *= scalar;
|
||||
a *= scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Color &operator/=(float scalar) {
|
||||
r /= scalar;
|
||||
g /= scalar;
|
||||
b /= scalar;
|
||||
a /= scalar;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// 命名颜色常量
|
||||
namespace Colors {
|
||||
inline constexpr Color White{1.0f, 1.0f, 1.0f, 1.0f};
|
||||
inline constexpr Color Black{0.0f, 0.0f, 0.0f, 1.0f};
|
||||
inline constexpr Color Red{1.0f, 0.0f, 0.0f, 1.0f};
|
||||
inline constexpr Color Green{0.0f, 1.0f, 0.0f, 1.0f};
|
||||
inline constexpr Color Blue{0.0f, 0.0f, 1.0f, 1.0f};
|
||||
inline constexpr Color Yellow{1.0f, 1.0f, 0.0f, 1.0f};
|
||||
inline constexpr Color Cyan{0.0f, 1.0f, 1.0f, 1.0f};
|
||||
inline constexpr Color Magenta{1.0f, 0.0f, 1.0f, 1.0f};
|
||||
inline constexpr Color Orange{1.0f, 0.647f, 0.0f, 1.0f};
|
||||
inline constexpr Color Purple{0.502f, 0.0f, 0.502f, 1.0f};
|
||||
inline constexpr Color Pink{1.0f, 0.753f, 0.796f, 1.0f};
|
||||
inline constexpr Color Gray{0.502f, 0.502f, 0.502f, 1.0f};
|
||||
inline constexpr Color LightGray{0.827f, 0.827f, 0.827f, 1.0f};
|
||||
inline constexpr Color DarkGray{0.412f, 0.412f, 0.412f, 1.0f};
|
||||
inline constexpr Color Brown{0.647f, 0.165f, 0.165f, 1.0f};
|
||||
inline constexpr Color Gold{1.0f, 0.843f, 0.0f, 1.0f};
|
||||
inline constexpr Color Silver{0.753f, 0.753f, 0.753f, 1.0f};
|
||||
inline constexpr Color SkyBlue{0.529f, 0.808f, 0.922f, 1.0f};
|
||||
inline constexpr Color LimeGreen{0.196f, 0.804f, 0.196f, 1.0f};
|
||||
inline constexpr Color Coral{1.0f, 0.498f, 0.314f, 1.0f};
|
||||
inline constexpr Color Transparent{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
} // namespace Colors
|
||||
|
||||
} // namespace frostbite2D
|
||||
@@ -1,552 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <fostbite2D/core/types.h>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
namespace frostbite2D {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 常量
|
||||
// ---------------------------------------------------------------------------
|
||||
constexpr float PI_F = 3.14159265358979323846f;
|
||||
constexpr float DEG_TO_RAD = PI_F / 180.0f;
|
||||
constexpr float RAD_TO_DEG = 180.0f / PI_F;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 2D 向量
|
||||
// ---------------------------------------------------------------------------
|
||||
struct Vec2 {
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
|
||||
constexpr Vec2() = default;
|
||||
constexpr Vec2(float x, float y) : x(x), y(y) {}
|
||||
explicit Vec2(const glm::vec2 &v) : x(v.x), y(v.y) {}
|
||||
|
||||
glm::vec2 toGlm() const { return {x, y}; }
|
||||
static Vec2 fromGlm(const glm::vec2 &v) { return {v.x, v.y}; }
|
||||
|
||||
// 基础运算
|
||||
Vec2 operator+(const Vec2 &v) const { return {x + v.x, y + v.y}; }
|
||||
Vec2 operator-(const Vec2 &v) const { return {x - v.x, y - v.y}; }
|
||||
Vec2 operator*(float s) const { return {x * s, y * s}; }
|
||||
Vec2 operator/(float s) const { return {x / s, y / s}; }
|
||||
Vec2 operator-() const { return {-x, -y}; }
|
||||
|
||||
Vec2 &operator+=(const Vec2 &v) {
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
return *this;
|
||||
}
|
||||
Vec2 &operator-=(const Vec2 &v) {
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
return *this;
|
||||
}
|
||||
Vec2 &operator*=(float s) {
|
||||
x *= s;
|
||||
y *= s;
|
||||
return *this;
|
||||
}
|
||||
Vec2 &operator/=(float s) {
|
||||
x /= s;
|
||||
y /= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Vec2 &v) const { return x == v.x && y == v.y; }
|
||||
bool operator!=(const Vec2 &v) const { return !(*this == v); }
|
||||
|
||||
// 向量运算
|
||||
float length() const { return std::sqrt(x * x + y * y); }
|
||||
float lengthSquared() const { return x * x + y * y; }
|
||||
|
||||
Vec2 normalized() const {
|
||||
float len = length();
|
||||
if (len > 0.0f)
|
||||
return {x / len, y / len};
|
||||
return {0.0f, 0.0f};
|
||||
}
|
||||
|
||||
float dot(const Vec2 &v) const { return x * v.x + y * v.y; }
|
||||
float cross(const Vec2 &v) const { return x * v.y - y * v.x; }
|
||||
|
||||
float distance(const Vec2 &v) const { return (*this - v).length(); }
|
||||
float angle() const { return std::atan2(y, x) * RAD_TO_DEG; }
|
||||
|
||||
static Vec2 lerp(const Vec2 &a, const Vec2 &b, float t) {
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
static constexpr Vec2 Zero() { return {0.0f, 0.0f}; }
|
||||
static constexpr Vec2 One() { return {1.0f, 1.0f}; }
|
||||
static constexpr Vec2 UnitX() { return {1.0f, 0.0f}; }
|
||||
static constexpr Vec2 UnitY() { return {0.0f, 1.0f}; }
|
||||
};
|
||||
|
||||
inline Vec2 operator*(float s, const Vec2 &v) { return v * s; }
|
||||
|
||||
using Point = Vec2;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 3D 向量 (用于3D动作)
|
||||
// ---------------------------------------------------------------------------
|
||||
struct Vec3 {
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
|
||||
constexpr Vec3() = default;
|
||||
constexpr Vec3(float x, float y, float z) : x(x), y(y), z(z) {}
|
||||
explicit Vec3(const glm::vec3 &v) : x(v.x), y(v.y), z(v.z) {}
|
||||
|
||||
glm::vec3 toGlm() const { return {x, y, z}; }
|
||||
static Vec3 fromGlm(const glm::vec3 &v) { return {v.x, v.y, v.z}; }
|
||||
|
||||
Vec3 operator+(const Vec3 &v) const { return {x + v.x, y + v.y, z + v.z}; }
|
||||
Vec3 operator-(const Vec3 &v) const { return {x - v.x, y - v.y, z - v.z}; }
|
||||
Vec3 operator*(float s) const { return {x * s, y * s, z * s}; }
|
||||
Vec3 operator/(float s) const { return {x / s, y / s, z / s}; }
|
||||
Vec3 operator-() const { return {-x, -y, -z}; }
|
||||
|
||||
Vec3 &operator+=(const Vec3 &v) {
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
z += v.z;
|
||||
return *this;
|
||||
}
|
||||
Vec3 &operator-=(const Vec3 &v) {
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
z -= v.z;
|
||||
return *this;
|
||||
}
|
||||
Vec3 &operator*=(float s) {
|
||||
x *= s;
|
||||
y *= s;
|
||||
z *= s;
|
||||
return *this;
|
||||
}
|
||||
Vec3 &operator/=(float s) {
|
||||
x /= s;
|
||||
y /= s;
|
||||
z /= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Vec3 &v) const {
|
||||
return x == v.x && y == v.y && z == v.z;
|
||||
}
|
||||
bool operator!=(const Vec3 &v) const { return !(*this == v); }
|
||||
|
||||
float length() const { return std::sqrt(x * x + y * y + z * z); }
|
||||
float lengthSquared() const { return x * x + y * y + z * z; }
|
||||
|
||||
Vec3 normalized() const {
|
||||
float len = length();
|
||||
if (len > 0.0f)
|
||||
return {x / len, y / len, z / len};
|
||||
return {0.0f, 0.0f, 0.0f};
|
||||
}
|
||||
|
||||
float dot(const Vec3 &v) const { return x * v.x + y * v.y + z * v.z; }
|
||||
|
||||
static Vec3 lerp(const Vec3 &a, const Vec3 &b, float t) {
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
static constexpr Vec3 Zero() { return {0.0f, 0.0f, 0.0f}; }
|
||||
static constexpr Vec3 One() { return {1.0f, 1.0f, 1.0f}; }
|
||||
};
|
||||
|
||||
inline Vec3 operator*(float s, const Vec3 &v) { return v * s; }
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 2D 尺寸
|
||||
// ---------------------------------------------------------------------------
|
||||
struct Size {
|
||||
float width = 0.0f;
|
||||
float height = 0.0f;
|
||||
|
||||
constexpr Size() = default;
|
||||
constexpr Size(float w, float h) : width(w), height(h) {}
|
||||
|
||||
bool operator==(const Size &s) const {
|
||||
return width == s.width && height == s.height;
|
||||
}
|
||||
bool operator!=(const Size &s) const { return !(*this == s); }
|
||||
|
||||
float area() const { return width * height; }
|
||||
bool empty() const { return width <= 0.0f || height <= 0.0f; }
|
||||
|
||||
static constexpr Size Zero() { return {0.0f, 0.0f}; }
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 2D 矩形
|
||||
// ---------------------------------------------------------------------------
|
||||
struct Rect {
|
||||
Point origin;
|
||||
Size size;
|
||||
|
||||
constexpr Rect() = default;
|
||||
constexpr Rect(float x, float y, float w, float h)
|
||||
: origin(x, y), size(w, h) {}
|
||||
constexpr Rect(const Point &o, const Size &s) : origin(o), size(s) {}
|
||||
|
||||
float left() const { return origin.x; }
|
||||
float top() const { return origin.y; }
|
||||
float right() const { return origin.x + size.width; }
|
||||
float bottom() const { return origin.y + size.height; }
|
||||
float width() const { return size.width; }
|
||||
float height() const { return size.height; }
|
||||
Point center() const {
|
||||
return {origin.x + size.width * 0.5f, origin.y + size.height * 0.5f};
|
||||
}
|
||||
|
||||
bool empty() const { return size.empty(); }
|
||||
|
||||
bool containsPoint(const Point &p) const {
|
||||
return p.x >= left() && p.x <= right() && p.y >= top() && p.y <= bottom();
|
||||
}
|
||||
|
||||
bool contains(const Rect &r) const {
|
||||
return r.left() >= left() && r.right() <= right() && r.top() >= top() &&
|
||||
r.bottom() <= bottom();
|
||||
}
|
||||
|
||||
bool intersects(const Rect &r) const {
|
||||
return !(left() > r.right() || right() < r.left() || top() > r.bottom() ||
|
||||
bottom() < r.top());
|
||||
}
|
||||
|
||||
Rect intersection(const Rect &r) const {
|
||||
float l = std::max(left(), r.left());
|
||||
float t = std::max(top(), r.top());
|
||||
float ri = std::min(right(), r.right());
|
||||
float b = std::min(bottom(), r.bottom());
|
||||
if (l < ri && t < b)
|
||||
return {l, t, ri - l, b - t};
|
||||
return {};
|
||||
}
|
||||
|
||||
Rect unionWith(const Rect &r) const {
|
||||
if (empty())
|
||||
return r;
|
||||
if (r.empty())
|
||||
return *this;
|
||||
float l = std::min(left(), r.left());
|
||||
float t = std::min(top(), r.top());
|
||||
float ri = std::max(right(), r.right());
|
||||
float b = std::max(bottom(), r.bottom());
|
||||
return {l, t, ri - l, b - t};
|
||||
}
|
||||
|
||||
bool operator==(const Rect &r) const {
|
||||
return origin == r.origin && size == r.size;
|
||||
}
|
||||
bool operator!=(const Rect &r) const { return !(*this == r); }
|
||||
|
||||
static constexpr Rect Zero() { return {0, 0, 0, 0}; }
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 2D 变换矩阵(基于 glm::mat4,兼容 OpenGL)
|
||||
// ---------------------------------------------------------------------------
|
||||
struct Transform2D {
|
||||
glm::mat4 matrix{1.0f}; // 单位矩阵
|
||||
|
||||
Transform2D() = default;
|
||||
explicit Transform2D(const glm::mat4 &m) : matrix(m) {}
|
||||
|
||||
static Transform2D identity() { return Transform2D{}; }
|
||||
|
||||
static Transform2D translation(float x, float y) {
|
||||
Transform2D t;
|
||||
t.matrix = glm::translate(glm::mat4(1.0f), glm::vec3(x, y, 0.0f));
|
||||
return t;
|
||||
}
|
||||
|
||||
static Transform2D translation(const Vec2 &v) {
|
||||
return translation(v.x, v.y);
|
||||
}
|
||||
|
||||
static Transform2D rotation(float degrees) {
|
||||
Transform2D t;
|
||||
t.matrix = glm::rotate(glm::mat4(1.0f), degrees * DEG_TO_RAD,
|
||||
glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
return t;
|
||||
}
|
||||
|
||||
static Transform2D scaling(float sx, float sy) {
|
||||
Transform2D t;
|
||||
t.matrix = glm::scale(glm::mat4(1.0f), glm::vec3(sx, sy, 1.0f));
|
||||
return t;
|
||||
}
|
||||
|
||||
static Transform2D scaling(float s) { return scaling(s, s); }
|
||||
|
||||
static Transform2D skewing(float skewX, float skewY) {
|
||||
Transform2D t;
|
||||
t.matrix = glm::mat4(1.0f);
|
||||
t.matrix[1][0] = std::tan(skewX * DEG_TO_RAD);
|
||||
t.matrix[0][1] = std::tan(skewY * DEG_TO_RAD);
|
||||
return t;
|
||||
}
|
||||
|
||||
Transform2D operator*(const Transform2D &other) const {
|
||||
return Transform2D(matrix * other.matrix);
|
||||
}
|
||||
|
||||
Transform2D &operator*=(const Transform2D &other) {
|
||||
matrix *= other.matrix;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2 transformPoint(const Vec2 &p) const {
|
||||
glm::vec4 result = matrix * glm::vec4(p.x, p.y, 0.0f, 1.0f);
|
||||
return {result.x, result.y};
|
||||
}
|
||||
|
||||
Transform2D inverse() const { return Transform2D(glm::inverse(matrix)); }
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 数学工具函数
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace math {
|
||||
|
||||
inline float clamp(float value, float minVal, float maxVal) {
|
||||
return std::clamp(value, minVal, maxVal);
|
||||
}
|
||||
|
||||
inline float lerp(float a, float b, float t) { return a + (b - a) * t; }
|
||||
|
||||
inline float degrees(float radians) { return radians * RAD_TO_DEG; }
|
||||
|
||||
inline float radians(float degrees) { return degrees * DEG_TO_RAD; }
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 角度工具函数
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief 规范化角度到 [0, 360) 范围
|
||||
* @param degrees 输入角度(度数)
|
||||
* @return 规范化后的角度,范围 [0, 360)
|
||||
*/
|
||||
inline float normalizeAngle360(float degrees) {
|
||||
degrees = std::fmod(degrees, 360.0f);
|
||||
if (degrees < 0.0f) {
|
||||
degrees += 360.0f;
|
||||
}
|
||||
return degrees;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 规范化角度到 [-180, 180) 范围
|
||||
* @param degrees 输入角度(度数)
|
||||
* @return 规范化后的角度,范围 [-180, 180)
|
||||
*/
|
||||
inline float normalizeAngle180(float degrees) {
|
||||
degrees = std::fmod(degrees + 180.0f, 360.0f);
|
||||
if (degrees < 0.0f) {
|
||||
degrees += 360.0f;
|
||||
}
|
||||
return degrees - 180.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 计算两个角度之间的最短差值
|
||||
* @param from 起始角度(度数)
|
||||
* @param to 目标角度(度数)
|
||||
* @return 从 from 到 to 的最短角度差,范围 [-180, 180]
|
||||
*/
|
||||
inline float angleDifference(float from, float to) {
|
||||
float diff = normalizeAngle360(to - from);
|
||||
if (diff > 180.0f) {
|
||||
diff -= 360.0f;
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 线性插值角度
|
||||
* @param from 起始角度(度数)
|
||||
* @param to 目标角度(度数)
|
||||
* @param t 插值因子 [0, 1]
|
||||
* @return 插值后的角度
|
||||
*/
|
||||
inline float lerpAngle(float from, float to, float t) {
|
||||
return from + angleDifference(from, to) * t;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 向量工具函数
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief 计算方向向量(从 from 指向 to 的单位向量)
|
||||
* @param from 起始点
|
||||
* @param to 目标点
|
||||
* @return 归一化的方向向量
|
||||
*/
|
||||
inline Vec2 direction(const Vec2 &from, const Vec2 &to) {
|
||||
return (to - from).normalized();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 计算两点之间的角度
|
||||
* @param from 起始点
|
||||
* @param to 目标点
|
||||
* @return 角度(度数),范围 [-180, 180]
|
||||
*/
|
||||
inline float angleBetween(const Vec2 &from, const Vec2 &to) {
|
||||
Vec2 dir = to - from;
|
||||
return std::atan2(dir.y, dir.x) * RAD_TO_DEG;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据角度创建方向向量
|
||||
* @param degrees 角度(度数),0度指向右方,逆时针为正
|
||||
* @return 单位方向向量
|
||||
*/
|
||||
inline Vec2 angleToVector(float degrees) {
|
||||
float rad = degrees * DEG_TO_RAD;
|
||||
return {std::cos(rad), std::sin(rad)};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将向量旋转指定角度
|
||||
* @param v 原始向量
|
||||
* @param degrees 旋转角度(度数),正值为逆时针旋转
|
||||
* @return 旋转后的向量
|
||||
*/
|
||||
inline Vec2 rotateVector(const Vec2 &v, float degrees) {
|
||||
float rad = degrees * DEG_TO_RAD;
|
||||
float cosA = std::cos(rad);
|
||||
float sinA = std::sin(rad);
|
||||
return {v.x * cosA - v.y * sinA, v.x * sinA + v.y * cosA};
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 坐标系转换工具
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Y轴向上坐标转Y轴向下坐标
|
||||
* @param pos Y轴向上坐标系中的位置
|
||||
* @param height 画布/屏幕高度
|
||||
* @return Y轴向下坐标系中的位置
|
||||
*/
|
||||
inline Vec2 flipY(const Vec2 &pos, float height) {
|
||||
return {pos.x, height - pos.y};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Y轴向下坐标转Y轴向上坐标
|
||||
* @param pos Y轴向下坐标系中的位置
|
||||
* @param height 画布/屏幕高度
|
||||
* @return Y轴向上坐标系中的位置
|
||||
*/
|
||||
inline Vec2 unflipY(const Vec2 &pos, float height) {
|
||||
return {pos.x, height - pos.y};
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 矩阵工具函数
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief 从变换矩阵提取位置
|
||||
* @param matrix 4x4变换矩阵
|
||||
* @return 提取的位置向量
|
||||
*/
|
||||
inline Vec2 extractPosition(const glm::mat4 &matrix) {
|
||||
return {matrix[3][0], matrix[3][1]};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从变换矩阵提取缩放
|
||||
* @param matrix 4x4变换矩阵
|
||||
* @return 提取的缩放向量
|
||||
*/
|
||||
inline Vec2 extractScale(const glm::mat4 &matrix) {
|
||||
float scaleX =
|
||||
std::sqrt(matrix[0][0] * matrix[0][0] + matrix[0][1] * matrix[0][1]);
|
||||
float scaleY =
|
||||
std::sqrt(matrix[1][0] * matrix[1][0] + matrix[1][1] * matrix[1][1]);
|
||||
return {scaleX, scaleY};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从变换矩阵提取旋转角度
|
||||
* @param matrix 4x4变换矩阵
|
||||
* @return 提取的旋转角度(度数)
|
||||
*/
|
||||
inline float extractRotation(const glm::mat4 &matrix) {
|
||||
return std::atan2(matrix[0][1], matrix[0][0]) * RAD_TO_DEG;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 碰撞检测工具
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief 判断点是否在矩形内
|
||||
* @param point 要检测的点
|
||||
* @param rect 矩形区域
|
||||
* @return 如果点在矩形内返回 true,否则返回 false
|
||||
*/
|
||||
inline bool pointInRect(const Vec2 &point, const Rect &rect) {
|
||||
return point.x >= rect.left() && point.x <= rect.right() &&
|
||||
point.y >= rect.top() && point.y <= rect.bottom();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 判断点是否在圆内
|
||||
* @param point 要检测的点
|
||||
* @param center 圆心
|
||||
* @param radius 圆的半径
|
||||
* @return 如果点在圆内返回 true,否则返回 false
|
||||
*/
|
||||
inline bool pointInCircle(const Vec2 &point, const Vec2 ¢er, float radius) {
|
||||
float dx = point.x - center.x;
|
||||
float dy = point.y - center.y;
|
||||
return (dx * dx + dy * dy) <= (radius * radius);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 判断两个矩形是否相交
|
||||
* @param a 第一个矩形
|
||||
* @param b 第二个矩形
|
||||
* @return 如果矩形相交返回 true,否则返回 false
|
||||
*/
|
||||
inline bool rectsIntersect(const Rect &a, const Rect &b) {
|
||||
return a.intersects(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 判断两个圆是否相交
|
||||
* @param center1 第一个圆的圆心
|
||||
* @param radius1 第一个圆的半径
|
||||
* @param center2 第二个圆的圆心
|
||||
* @param radius2 第二个圆的半径
|
||||
* @return 如果圆相交返回 true,否则返回 false
|
||||
*/
|
||||
inline bool circlesIntersect(const Vec2 ¢er1, float radius1,
|
||||
const Vec2 ¢er2, float radius2) {
|
||||
float dx = center2.x - center1.x;
|
||||
float dy = center2.y - center1.y;
|
||||
float distSq = dx * dx + dy * dy;
|
||||
float radiusSum = radius1 + radius2;
|
||||
return distSq <= (radiusSum * radiusSum);
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace frostbite2D
|
||||
@@ -1,58 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace frostbite2D {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 宏定义
|
||||
// ---------------------------------------------------------------------------
|
||||
#define E2D_CONCAT_IMPL(a, b) a##b
|
||||
#define E2D_CONCAT(a, b) E2D_CONCAT_IMPL(a, b)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 智能指针别名
|
||||
// ---------------------------------------------------------------------------
|
||||
template <typename T> using Ptr = std::shared_ptr<T>;
|
||||
template <typename T> using SharedPtr = std::shared_ptr<T>;
|
||||
|
||||
template <typename T> using UniquePtr = std::unique_ptr<T>;
|
||||
|
||||
template <typename T> using WeakPtr = std::weak_ptr<T>;
|
||||
|
||||
/// 创建 shared_ptr 的便捷函数
|
||||
template <typename T, typename... Args> inline Ptr<T> makePtr(Args &&...args) {
|
||||
return std::make_shared<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
inline SharedPtr<T> makeShared(Args &&...args) {
|
||||
return std::make_shared<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/// 创建 unique_ptr 的便捷函数
|
||||
template <typename T, typename... Args>
|
||||
inline UniquePtr<T> makeUnique(Args &&...args) {
|
||||
return std::make_unique<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 函数别名
|
||||
// ---------------------------------------------------------------------------
|
||||
template <typename Sig> using Function = std::function<Sig>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 基础类型别名
|
||||
// ---------------------------------------------------------------------------
|
||||
using int8 = std::int8_t;
|
||||
using int16 = std::int16_t;
|
||||
using int32 = std::int32_t;
|
||||
using int64 = std::int64_t;
|
||||
using uint8 = std::uint8_t;
|
||||
using uint16 = std::uint16_t;
|
||||
using uint32 = std::uint32_t;
|
||||
using uint64 = std::uint64_t;
|
||||
|
||||
} // namespace frostbite2D
|
||||
272
Fostbite2D/include/fostbite2D/core/window.h
Normal file
272
Fostbite2D/include/fostbite2D/core/window.h
Normal file
@@ -0,0 +1,272 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <fostbite2D/types/type_alias.h>
|
||||
#include <fostbite2D/types/type_math.h>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace frostbite2D {
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 鼠标指针类型
|
||||
*/
|
||||
enum class CursorType {
|
||||
Arrow, ///< 指针
|
||||
TextInput, ///< 文本
|
||||
Hand, ///< 手
|
||||
SizeAll, ///< 指向四个方向的箭头
|
||||
SizeWE, ///< 指向左右方向的箭头
|
||||
SizeNS, ///< 指向上下方向的箭头
|
||||
SizeNESW, ///< 指向左下到右上方向的箭头
|
||||
SizeNWSE, ///< 指向左上到右下方向的箭头
|
||||
No, ///< 禁止
|
||||
};
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 分辨率
|
||||
*/
|
||||
struct Resolution {
|
||||
uint32_t width = 0; ///< 分辨率宽度
|
||||
uint32_t height = 0; ///< 分辨率高度
|
||||
uint32_t refresh_rate = 0; ///< 刷新率
|
||||
|
||||
Resolution() = default;
|
||||
|
||||
Resolution(uint32_t width, uint32_t height, uint32_t refresh_rate)
|
||||
: width(width), height(height), refresh_rate(refresh_rate) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 图标
|
||||
*/
|
||||
struct Icon {
|
||||
Icon() = default;
|
||||
|
||||
Icon(std::string file_path) : file_path(file_path) {}
|
||||
|
||||
std::string file_path; ///< 文件路径
|
||||
|
||||
#if defined(_WIN32)
|
||||
uint32_t resource_id = 0; ///< 资源ID,仅在windows上生效
|
||||
|
||||
Icon(uint32_t resource_id) : resource_id(resource_id) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 窗口设置
|
||||
*/
|
||||
struct WindowConfig {
|
||||
uint32_t width = 640; ///< 窗口宽度
|
||||
uint32_t height = 480; ///< 窗口高度
|
||||
std::string title = "fostbite2D Game"; ///< 窗口标题
|
||||
Icon icon; ///< 窗口图标
|
||||
bool resizable = false; ///< 窗口大小可调整
|
||||
bool fullscreen = false; ///< 窗口全屏
|
||||
bool borderless = false; ///< 无边框窗口
|
||||
bool decorated = true; ///< 窗口装饰
|
||||
int multisamples = 0; ///< 多重采样数
|
||||
bool centered = true; ///< 窗口是否居中
|
||||
bool vsync = true; ///< 是否启用垂直同步
|
||||
bool showCursor = true; ///< 是否显示光标
|
||||
};
|
||||
|
||||
class Window {
|
||||
public:
|
||||
Window() = default;
|
||||
virtual ~Window() = default;
|
||||
|
||||
/**
|
||||
* @brief 创建窗口
|
||||
* @param cfg 窗口配置
|
||||
* @return 创建是否成功
|
||||
*/
|
||||
virtual bool create(const WindowConfig &cfg);
|
||||
|
||||
/**
|
||||
* @brief 销毁窗口
|
||||
*/
|
||||
virtual void destroy();
|
||||
|
||||
/**
|
||||
* @brief 轮询事件
|
||||
*/
|
||||
virtual void poll();
|
||||
|
||||
/**
|
||||
* @brief 交换缓冲区
|
||||
*/
|
||||
virtual void swap();
|
||||
|
||||
/**
|
||||
* @brief 设置窗口关闭标志
|
||||
*/
|
||||
virtual void close();
|
||||
|
||||
/**
|
||||
* @brief 设置窗口标题
|
||||
*/
|
||||
virtual void setTitle(const std::string &title);
|
||||
|
||||
/**
|
||||
* @brief 设置窗口大小
|
||||
*/
|
||||
virtual void setSize(int w, int h);
|
||||
|
||||
/**
|
||||
* @brief 设置窗口位置
|
||||
*/
|
||||
virtual void setPos(int x, int y);
|
||||
|
||||
/**
|
||||
* @brief 设置全屏模式
|
||||
*/
|
||||
virtual void setFullscreen(bool fs);
|
||||
|
||||
/**
|
||||
* @brief 设置垂直同步
|
||||
*/
|
||||
virtual void setVSync(bool vsync);
|
||||
|
||||
/**
|
||||
* @brief 设置窗口可见性
|
||||
*/
|
||||
virtual void setVisible(bool visible);
|
||||
|
||||
/**
|
||||
* @brief 获取窗口宽度
|
||||
*/
|
||||
virtual int width() const;
|
||||
|
||||
/**
|
||||
* @brief 获取窗口高度
|
||||
*/
|
||||
virtual int height() const;
|
||||
|
||||
/**
|
||||
* @brief 获取窗口大小
|
||||
*/
|
||||
virtual Size size() const;
|
||||
|
||||
/**
|
||||
* @brief 获取窗口位置
|
||||
*/
|
||||
virtual Vec2 pos() const;
|
||||
|
||||
/**
|
||||
* @brief 是否全屏
|
||||
*/
|
||||
virtual bool fullscreen() const;
|
||||
|
||||
/**
|
||||
* @brief 是否启用垂直同步
|
||||
*/
|
||||
virtual bool vsync() const;
|
||||
|
||||
/**
|
||||
* @brief 窗口是否获得焦点
|
||||
*/
|
||||
virtual bool focused() const;
|
||||
|
||||
/**
|
||||
* @brief 窗口是否最小化
|
||||
*/
|
||||
virtual bool minimized() const;
|
||||
|
||||
/**
|
||||
* @brief 获取内容缩放X
|
||||
*/
|
||||
virtual float scaleX() const;
|
||||
|
||||
/**
|
||||
* @brief 获取内容缩放Y
|
||||
*/
|
||||
virtual float scaleY() const;
|
||||
|
||||
/**
|
||||
* @brief 设置光标形状
|
||||
*/
|
||||
virtual void setCursor(CursorType cursor);
|
||||
|
||||
/**
|
||||
* @brief 显示/隐藏光标
|
||||
*/
|
||||
virtual void showCursor(bool show);
|
||||
|
||||
/**
|
||||
* @brief 锁定/解锁光标
|
||||
*/
|
||||
virtual void lockCursor(bool lock);
|
||||
|
||||
/**
|
||||
* @brief 窗口大小改变回调
|
||||
*/
|
||||
using ResizeCb = std::function<void(int, int)>;
|
||||
|
||||
/**
|
||||
* @brief 窗口关闭回调
|
||||
*/
|
||||
using CloseCb = std::function<void()>;
|
||||
|
||||
/**
|
||||
* @brief 窗口焦点改变回调
|
||||
*/
|
||||
using FocusCb = std::function<void(bool)>;
|
||||
|
||||
/**
|
||||
* @brief 设置大小改变回调
|
||||
*/
|
||||
virtual void onResize(ResizeCb cb);
|
||||
|
||||
/**
|
||||
* @brief 设置关闭回调
|
||||
*/
|
||||
virtual void onClose(CloseCb cb);
|
||||
|
||||
/**
|
||||
* @brief 设置焦点改变回调
|
||||
*/
|
||||
virtual void onFocus(FocusCb cb);
|
||||
|
||||
/**
|
||||
* @brief 获取原生窗口句柄
|
||||
*/
|
||||
virtual void *native() const;
|
||||
|
||||
/**
|
||||
* @brief 获取 SDL 窗口句柄
|
||||
*/
|
||||
SDL_Window *sdlWindow() const { return sdlWindow_; }
|
||||
|
||||
/**
|
||||
* @brief 获取 OpenGL 上下文
|
||||
*/
|
||||
SDL_GLContext glContext() const { return glContext_; }
|
||||
|
||||
private:
|
||||
SDL_Window *sdlWindow_ = nullptr;
|
||||
SDL_GLContext glContext_ = nullptr;
|
||||
|
||||
int width_ = 1280;
|
||||
int height_ = 720;
|
||||
bool fullscreen_ = false;
|
||||
bool vsync_ = true;
|
||||
bool focused_ = true;
|
||||
bool minimized_ = false;
|
||||
bool shouldClose_ = false;
|
||||
float scaleX_ = 1.0f;
|
||||
float scaleY_ = 1.0f;
|
||||
bool cursorVisible_ = true;
|
||||
bool cursorLocked_ = false;
|
||||
|
||||
ResizeCb resizeCb_;
|
||||
CloseCb closeCb_;
|
||||
FocusCb focusCb_;
|
||||
};
|
||||
|
||||
} // namespace frostbite2D
|
||||
Reference in New Issue
Block a user