Refactor renderer and input handling; add OBJ loader and math utilities
- Updated renderer.h to replace Vec3 and Vec2 structs with Math namespace equivalents. - Introduced Texture struct to manage texture properties. - Modified Triangle struct to use Texture instead of GLuint for texture handling. - Removed deprecated matrix functions and replaced them with Math namespace methods. - Implemented InputManager class for better input handling, including key and mouse state tracking. - Added ObjLoader class to load OBJ files and associated textures, with MTL file parsing. - Created math utilities for fixed-point arithmetic and vector/matrix operations. - Added time management class for frame timing and delta time calculations.
This commit is contained in:
3
Engine/math/math.h
Normal file
3
Engine/math/math.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#include <vec3.h>
|
||||
#include <vec2.h>
|
||||
#include <matrix4.h>
|
||||
147
Engine/math/matrix4.h
Normal file
147
Engine/math/matrix4.h
Normal file
@@ -0,0 +1,147 @@
|
||||
#pragma once
|
||||
|
||||
#include "vec3.h"
|
||||
#include <cmath>
|
||||
|
||||
#ifndef FIXED_POINT_PRECISION
|
||||
#define FIXED_POINT_PRECISION 4096
|
||||
#endif
|
||||
|
||||
inline int fixed_sin(int angle)
|
||||
{
|
||||
return std::sin(angle / static_cast<float>(FIXED_POINT_PRECISION)) * FIXED_POINT_PRECISION;
|
||||
}
|
||||
|
||||
inline int fixed_cos(int angle)
|
||||
{
|
||||
return std::cos(angle / static_cast<float>(FIXED_POINT_PRECISION)) * FIXED_POINT_PRECISION;
|
||||
}
|
||||
|
||||
namespace Math {
|
||||
|
||||
struct Matrix4
|
||||
{
|
||||
int m[16];
|
||||
|
||||
inline Matrix4()
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
m[i] = (i % 5 == 0) ? FIXED_POINT_PRECISION : 0;
|
||||
}
|
||||
|
||||
inline static Matrix4 identity()
|
||||
{
|
||||
return Matrix4();
|
||||
}
|
||||
|
||||
inline static Matrix4 multiply(const Matrix4 &a, const Matrix4 &b)
|
||||
{
|
||||
Matrix4 result;
|
||||
for (int row = 0; row < 4; ++row)
|
||||
{
|
||||
for (int col = 0; col < 4; ++col)
|
||||
{
|
||||
int sum = 0;
|
||||
for (int k = 0; k < 4; ++k)
|
||||
{
|
||||
sum += (a.m[row * 4 + k] * b.m[k * 4 + col]) / FIXED_POINT_PRECISION;
|
||||
}
|
||||
result.m[row * 4 + col] = sum;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline static Vec3 multiply(const Matrix4 &mat, const Vec3 &v)
|
||||
{
|
||||
int x = (mat.m[0] * v.x + mat.m[1] * v.y + mat.m[2] * v.z + mat.m[3]) / FIXED_POINT_PRECISION;
|
||||
int y = (mat.m[4] * v.x + mat.m[5] * v.y + mat.m[6] * v.z + mat.m[7]) / FIXED_POINT_PRECISION;
|
||||
int z = (mat.m[8] * v.x + mat.m[9] * v.y + mat.m[10] * v.z + mat.m[11]) / FIXED_POINT_PRECISION;
|
||||
return Vec3(x, y, z);
|
||||
}
|
||||
|
||||
inline static Matrix4 translation(int tx, int ty, int tz)
|
||||
{
|
||||
Matrix4 result = identity();
|
||||
result.m[12] = tx * FIXED_POINT_PRECISION;
|
||||
result.m[13] = ty * FIXED_POINT_PRECISION;
|
||||
result.m[14] = tz * FIXED_POINT_PRECISION;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline static Matrix4 scale(int sx, int sy, int sz)
|
||||
{
|
||||
Matrix4 result;
|
||||
result.m[0] = sx * FIXED_POINT_PRECISION;
|
||||
result.m[5] = sy * FIXED_POINT_PRECISION;
|
||||
result.m[10] = sz * FIXED_POINT_PRECISION;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline static Matrix4 rotateX(int angle)
|
||||
{
|
||||
Matrix4 mat = identity();
|
||||
float rad = angle / static_cast<float>(FIXED_POINT_PRECISION);
|
||||
int cos_val = static_cast<int>(std::cos(rad) * FIXED_POINT_PRECISION);
|
||||
int sin_val = static_cast<int>(std::sin(rad) * FIXED_POINT_PRECISION);
|
||||
mat.m[5] = cos_val;
|
||||
mat.m[6] = -sin_val;
|
||||
mat.m[9] = sin_val;
|
||||
mat.m[10] = cos_val;
|
||||
return mat;
|
||||
}
|
||||
|
||||
inline static Matrix4 rotateY(int angle)
|
||||
{
|
||||
Matrix4 mat = identity();
|
||||
float rad = angle / static_cast<float>(FIXED_POINT_PRECISION);
|
||||
int cos_val = static_cast<int>(std::cos(rad) * FIXED_POINT_PRECISION);
|
||||
int sin_val = static_cast<int>(std::sin(rad) * FIXED_POINT_PRECISION);
|
||||
mat.m[0] = cos_val;
|
||||
mat.m[2] = sin_val;
|
||||
mat.m[8] = -sin_val;
|
||||
mat.m[10] = cos_val;
|
||||
return mat;
|
||||
}
|
||||
|
||||
inline static Matrix4 rotateZ(int angle)
|
||||
{
|
||||
Matrix4 mat = identity();
|
||||
float rad = angle / static_cast<float>(FIXED_POINT_PRECISION);
|
||||
int cos_val = static_cast<int>(std::cos(rad) * FIXED_POINT_PRECISION);
|
||||
int sin_val = static_cast<int>(std::sin(rad) * FIXED_POINT_PRECISION);
|
||||
mat.m[0] = cos_val;
|
||||
mat.m[1] = -sin_val;
|
||||
mat.m[4] = sin_val;
|
||||
mat.m[5] = cos_val;
|
||||
return mat;
|
||||
}
|
||||
|
||||
inline static Matrix4 perspective(float fov_rad, float aspect, float near, float far)
|
||||
{
|
||||
Matrix4 result = {};
|
||||
float tanHalfFov = std::tan(fov_rad / 2.0f);
|
||||
result.m[0] = static_cast<int>((1.0f / (aspect * tanHalfFov)) * FIXED_POINT_PRECISION);
|
||||
result.m[5] = static_cast<int>((1.0f / tanHalfFov) * FIXED_POINT_PRECISION);
|
||||
result.m[10] = static_cast<int>(((far + near) / (near - far)) * FIXED_POINT_PRECISION);
|
||||
result.m[11] = static_cast<int>(((2.0f * far * near) / (near - far)) * FIXED_POINT_PRECISION);
|
||||
result.m[14] = -FIXED_POINT_PRECISION;
|
||||
result.m[15] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline static Matrix4 orthographic(float left, float right, float bottom, float top, float near, float far)
|
||||
{
|
||||
Matrix4 result = {};
|
||||
result.m[0] = static_cast<int>((2.0f / (right - left)) * FIXED_POINT_PRECISION);
|
||||
result.m[5] = static_cast<int>((2.0f / (top - bottom)) * FIXED_POINT_PRECISION);
|
||||
result.m[10] = static_cast<int>((-2.0f / (far - near)) * FIXED_POINT_PRECISION);
|
||||
result.m[12] = static_cast<int>((-(right + left) / (right - left)) * FIXED_POINT_PRECISION);
|
||||
result.m[13] = static_cast<int>((-(top + bottom) / (top - bottom)) * FIXED_POINT_PRECISION);
|
||||
result.m[14] = static_cast<int>((-(far + near) / (far - near)) * FIXED_POINT_PRECISION);
|
||||
result.m[15] = FIXED_POINT_PRECISION;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
96
Engine/math/vec2.h
Normal file
96
Engine/math/vec2.h
Normal file
@@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
|
||||
#ifndef FIXED_POINT_PRECISION
|
||||
#define FIXED_POINT_PRECISION 4096
|
||||
#endif
|
||||
|
||||
namespace Math {
|
||||
struct Vec2
|
||||
{
|
||||
int x, y;
|
||||
|
||||
inline Vec2(int x_ = 0, int y_ = 0) : x(x_), y(y_) {}
|
||||
|
||||
inline Vec2 operator+(const Vec2 &other) const
|
||||
{
|
||||
return Vec2(x + other.x, y + other.y);
|
||||
}
|
||||
|
||||
inline Vec2 operator-(const Vec2 &other) const
|
||||
{
|
||||
return Vec2(x - other.x, y - other.y);
|
||||
}
|
||||
|
||||
inline Vec2 operator*(int scalar_fixed) const
|
||||
{
|
||||
return Vec2((x * scalar_fixed) / FIXED_POINT_PRECISION,
|
||||
(y * scalar_fixed) / FIXED_POINT_PRECISION);
|
||||
}
|
||||
|
||||
inline Vec2 operator/(int scalar_fixed) const
|
||||
{
|
||||
return Vec2((x * FIXED_POINT_PRECISION) / scalar_fixed,
|
||||
(y * FIXED_POINT_PRECISION) / scalar_fixed);
|
||||
}
|
||||
|
||||
inline Vec2 &operator+=(const Vec2 &other)
|
||||
{
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vec2 &operator-=(const Vec2 &other)
|
||||
{
|
||||
x -= other.x;
|
||||
y -= other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline static int dot(const Vec2 &a, const Vec2 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
|
||||
inline static int cross(const Vec2 &a, const Vec2 &b)
|
||||
{
|
||||
return a.x * b.y - a.y * b.x;
|
||||
}
|
||||
|
||||
inline int length_squared() const
|
||||
{
|
||||
return x * x + y * y;
|
||||
}
|
||||
|
||||
inline int length() const
|
||||
{
|
||||
return static_cast<int>(std::sqrt(static_cast<float>(length_squared())));
|
||||
}
|
||||
|
||||
inline Vec2 normalized() const
|
||||
{
|
||||
int len = length();
|
||||
if (len == 0) return *this;
|
||||
return Vec2((x * FIXED_POINT_PRECISION) / len,
|
||||
(y * FIXED_POINT_PRECISION) / len);
|
||||
}
|
||||
|
||||
inline int distance_squared(const Vec2 &other) const
|
||||
{
|
||||
int dx = x - other.x;
|
||||
int dy = y - other.y;
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
inline int distance(const Vec2 &other) const
|
||||
{
|
||||
return static_cast<int>(std::sqrt(static_cast<float>(distance_squared(other))));
|
||||
}
|
||||
|
||||
inline static Vec2 zero() { return Vec2(0, 0); }
|
||||
};
|
||||
|
||||
}
|
||||
198
Engine/math/vec3.h
Normal file
198
Engine/math/vec3.h
Normal file
@@ -0,0 +1,198 @@
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
using std::sqrt;
|
||||
|
||||
#ifndef FIXED_POINT_PRECISION
|
||||
#define FIXED_POINT_PRECISION 4096
|
||||
#endif
|
||||
|
||||
namespace Math {
|
||||
struct Vec3
|
||||
{
|
||||
int x, y, z;
|
||||
|
||||
inline Vec3(int x_ = 0, int y_ = 0, int z_ = 0) : x(x_), y(y_), z(z_) {}
|
||||
|
||||
inline Vec3 operator+(const Vec3 &other) const
|
||||
{
|
||||
return Vec3(x + other.x, y + other.y, z + other.z);
|
||||
}
|
||||
|
||||
inline Vec3 operator-(const Vec3 &other) const
|
||||
{
|
||||
return Vec3(x - other.x, y - other.y, z - other.z);
|
||||
}
|
||||
|
||||
inline Vec3 operator*(int scalar) const
|
||||
{
|
||||
return Vec3(x * scalar, y * scalar, z * scalar);
|
||||
}
|
||||
|
||||
inline Vec3 operator/(int scalar) const
|
||||
{
|
||||
return Vec3(x / scalar, y / scalar, z / scalar);
|
||||
}
|
||||
|
||||
inline Vec3 &operator+=(const Vec3 &other)
|
||||
{
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
z += other.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vec3 &operator-=(const Vec3 &other)
|
||||
{
|
||||
x -= other.x;
|
||||
y -= other.y;
|
||||
z -= other.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline static int dot(const Vec3 &a, const Vec3 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
|
||||
inline static Vec3 cross(const Vec3 &a, const Vec3 &b)
|
||||
{
|
||||
return Vec3(
|
||||
a.y * b.z - a.z * b.y,
|
||||
a.z * b.x - a.x * b.z,
|
||||
a.x * b.y - a.y * b.x);
|
||||
}
|
||||
|
||||
inline float length() const
|
||||
{
|
||||
return std::sqrt(static_cast<float>(x * x + y * y + z * z));
|
||||
}
|
||||
|
||||
inline Vec3 normalized() const
|
||||
{
|
||||
float len = length();
|
||||
return len == 0.0f ? *this : Vec3(static_cast<int>(x / len), static_cast<int>(y / len), static_cast<int>(z / len));
|
||||
}
|
||||
|
||||
inline float distance(const Vec3 &other) const
|
||||
{
|
||||
return std::sqrt(static_cast<float>((x - other.x) * (x - other.x) + (y - other.y) * (y - other.y) + (z - other.z) * (z - other.z)));
|
||||
}
|
||||
|
||||
inline float angle(const Vec3 &other) const
|
||||
{
|
||||
float dotProduct = dot(*this, other);
|
||||
float lengths = length() * other.length();
|
||||
return std::acos(dotProduct / lengths);
|
||||
}
|
||||
|
||||
inline Vec3 reflect(const Vec3 &normal) const
|
||||
{
|
||||
int dotProduct = dot(*this, normal);
|
||||
return *this - normal * (dotProduct * 2);
|
||||
}
|
||||
|
||||
inline Vec3 refract(const Vec3 &normal, float ior) const
|
||||
{
|
||||
float cosi = -dot(*this, normal);
|
||||
float eta = 1.0f / ior;
|
||||
float k = 1.0f - eta * eta * (1.0f - cosi * cosi);struct Vec2
|
||||
{
|
||||
int x, y;
|
||||
|
||||
inline Vec2(int x_ = 0, int y_ = 0) : x(x_), y(y_) {}
|
||||
|
||||
inline Vec2 operator+(const Vec2 &other) const
|
||||
{
|
||||
return Vec2(x + other.x, y + other.y);
|
||||
}
|
||||
|
||||
inline Vec2 operator-(const Vec2 &other) const
|
||||
{
|
||||
return Vec2(x - other.x, y - other.y);
|
||||
}
|
||||
|
||||
inline Vec2 operator*(int scalar_fixed) const
|
||||
{
|
||||
return Vec2((x * scalar_fixed) / FIXED_POINT_PRECISION,
|
||||
(y * scalar_fixed) / FIXED_POINT_PRECISION);
|
||||
}
|
||||
|
||||
inline Vec2 operator/(int scalar_fixed) const
|
||||
{
|
||||
return Vec2((x * FIXED_POINT_PRECISION) / scalar_fixed,
|
||||
(y * FIXED_POINT_PRECISION) / scalar_fixed);
|
||||
}
|
||||
|
||||
inline Vec2 &operator+=(const Vec2 &other)
|
||||
{
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vec2 &operator-=(const Vec2 &other)
|
||||
{
|
||||
x -= other.x;
|
||||
y -= other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline static int dot(const Vec2 &a, const Vec2 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
|
||||
inline static int cross(const Vec2 &a, const Vec2 &b)
|
||||
{
|
||||
return a.x * b.y - a.y * b.x;
|
||||
}
|
||||
|
||||
inline int length_squared() const
|
||||
{
|
||||
return x * x + y * y;
|
||||
}
|
||||
|
||||
inline int length() const
|
||||
{
|
||||
return static_cast<int>(std::sqrt(static_cast<float>(length_squared())));
|
||||
}
|
||||
|
||||
inline Vec2 normalized() const
|
||||
{
|
||||
int len = length();
|
||||
if (len == 0) return *this;
|
||||
return Vec2((x * FIXED_POINT_PRECISION) / len,
|
||||
(y * FIXED_POINT_PRECISION) / len);
|
||||
}
|
||||
|
||||
inline int distance_squared(const Vec2 &other) const
|
||||
{
|
||||
int dx = x - other.x;
|
||||
int dy = y - other.y;
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
inline int distance(const Vec2 &other) const
|
||||
{
|
||||
return static_cast<int>(std::sqrt(static_cast<float>(distance_squared(other))));
|
||||
}
|
||||
|
||||
inline static Vec2 zero() { return Vec2(0, 0); }
|
||||
};
|
||||
|
||||
if (k < 0.0f)
|
||||
return Vec3(0, 0, 0);
|
||||
return *this * eta + normal * (eta * cosi - std::sqrt(k));
|
||||
}
|
||||
|
||||
inline Vec3 project(const Vec3 &other) const
|
||||
{
|
||||
float dotProduct = dot(*this, other);
|
||||
float lenSquared = other.x * other.x + other.y * other.y + other.z * other.z;
|
||||
return other * (dotProduct / lenSquared);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user