From 5cd6abdd48d56118c9540d02b0a3d0060673f3ea Mon Sep 17 00:00:00 2001 From: velimir Date: Thu, 12 Feb 2026 19:55:21 +0100 Subject: [PATCH] initial commit --- .gitignore | 70 +++++++++++++++++++++++++++++ include/entity.hpp | 17 ++++++++ include/globals.hpp | 8 ++++ include/math.hpp | 35 +++++++++++++++ include/renderer/calls.hpp | 10 +++++ include/renderer/camera.hpp | 16 +++++++ make.sh | 5 +++ src/main.cpp | 64 +++++++++++++++++++++++++++ src/math.cpp | 87 +++++++++++++++++++++++++++++++++++++ src/renderer/calls.cpp | 24 ++++++++++ src/renderer/camera.cpp | 53 ++++++++++++++++++++++ 11 files changed, 389 insertions(+) create mode 100644 .gitignore create mode 100644 include/entity.hpp create mode 100644 include/globals.hpp create mode 100644 include/math.hpp create mode 100644 include/renderer/calls.hpp create mode 100644 include/renderer/camera.hpp create mode 100644 make.sh create mode 100644 src/main.cpp create mode 100644 src/math.cpp create mode 100644 src/renderer/calls.cpp create mode 100644 src/renderer/camera.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7445429 --- /dev/null +++ b/.gitignore @@ -0,0 +1,70 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Linker files +*.ilk + +# Debugger Files +*.pdb + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll +*.so.* + + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# Build directories +build/ +Build/ +build-*/ + +# CMake generated files +CMakeFiles/ +CMakeCache.txt +cmake_install.cmake +Makefile +install_manifest.txt +compile_commands.json + +# Temporary files +*.tmp +*.log +*.bak +*.swp + +# vcpkg +vcpkg_installed/ + +# debug information files +*.dwo + +# test output & cache +Testing/ +.cache/ +.vscode/ \ No newline at end of file diff --git a/include/entity.hpp b/include/entity.hpp new file mode 100644 index 0000000..6e1fe7f --- /dev/null +++ b/include/entity.hpp @@ -0,0 +1,17 @@ +#ifndef DELTA_ENTITY +#define DELTA_ENTITY + +#include "renderer/camera.hpp" +#include "math.hpp" + +class DeltaEntity { + public: + DeltaVector3 pos; + DeltaVector2 angle; + + DeltaEntity(float x, float y, float z); + void draw(DeltaCamera camera); + void update(float deltaTime); +}; + +#endif \ No newline at end of file diff --git a/include/globals.hpp b/include/globals.hpp new file mode 100644 index 0000000..7d3888c --- /dev/null +++ b/include/globals.hpp @@ -0,0 +1,8 @@ +#ifndef DELTA_GLOBALS +#define DELTA_GLOBALS + +const int SIMULATED_WIDTH = 1200; +const int SIMULATED_HEIGHT = 800; +const int FOCAL = 200; + +#endif \ No newline at end of file diff --git a/include/math.hpp b/include/math.hpp new file mode 100644 index 0000000..05f3ea3 --- /dev/null +++ b/include/math.hpp @@ -0,0 +1,35 @@ +#ifndef DELTA_MATH +#define DELTA_MATH + +class DeltaVector2 { + public: + float x, y; + DeltaVector2(float xval, float yval); + DeltaVector2(); + DeltaVector2 operator+(const DeltaVector2& other) const; + DeltaVector2 operator-(const DeltaVector2& other) const; + DeltaVector2 operator*(float a) const; + DeltaVector2& operator+=(const DeltaVector2& other); + DeltaVector2& operator-=(const DeltaVector2& other); + float distanceToVector(const DeltaVector2& vec) const; + float distanceToPos(float x, float y) const; + float dotProduct(const DeltaVector2& vec) const; + float angleTo(const DeltaVector2& vec) const; + float length() const; +}; + +class DeltaVector3 { + public: + float x, y, z; + DeltaVector3(float xval, float yval, float zval); + DeltaVector3(); + float distanceToVector(const DeltaVector3 &vec) const; + float distanceToPos(float x, float y) const; + float dotProduct(const DeltaVector3 &vec) const; + float angleTo(const DeltaVector3 &vec) const; + float length() const; +}; + +float getDeterminant(const DeltaVector2 &pointA, const DeltaVector2 &pointB, const DeltaVector2 &candidate); + +#endif \ No newline at end of file diff --git a/include/renderer/calls.hpp b/include/renderer/calls.hpp new file mode 100644 index 0000000..a478525 --- /dev/null +++ b/include/renderer/calls.hpp @@ -0,0 +1,10 @@ +#ifndef DELTA_RENDERCALLS +#define DELTA_RENDERCALLS + +#include + +#include "math.hpp" + +void rasterizeTriangle(SDL_Renderer *renderer, const DeltaVector2 &a, const DeltaVector2 &b, const DeltaVector2 &c); + +#endif \ No newline at end of file diff --git a/include/renderer/camera.hpp b/include/renderer/camera.hpp new file mode 100644 index 0000000..26643f4 --- /dev/null +++ b/include/renderer/camera.hpp @@ -0,0 +1,16 @@ +#ifndef DELTA_CAMERA +#define DELTA_CAMERA + +#include "math.hpp" + +class DeltaCamera { + public: + DeltaVector3 pos; + DeltaVector2 angle; + + DeltaCamera(float x, float y, float z); + DeltaVector2 projectPointVec(const DeltaVector3 &worldPos); + DeltaVector2 projectPoint(float worldX, float worldY, float worldZ); +}; + +#endif \ No newline at end of file diff --git a/make.sh b/make.sh new file mode 100644 index 0000000..b1c0c88 --- /dev/null +++ b/make.sh @@ -0,0 +1,5 @@ +clang++ -c src/*.cpp -I/opt/homebrew/include -Iinclude/ +clang++ -c src/**/*.cpp -I/opt/homebrew/include -Iinclude/ +clang++ *.o -L/opt/homebrew/lib -Wl,-rpath,/opt/homebrew/lib -lSDL3 -o out/debug.bin +rm ./*.o +./out/debug.bin \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..2399d88 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,64 @@ +#define SDL_MAIN_USE_CALLBACKS 1 + +#include +#include +#include +#include + +#include "globals.hpp" +#include "math.hpp" +#include "renderer/camera.hpp" +#include "renderer/calls.hpp" + +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; + +DeltaVector2 temp1(125, 150), temp2(150, 120), temp3(100, 100); +DeltaVector2 topleft, bottomright, p; + +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + SDL_SetAppMetadata("delta engine game", "0.0", "com.miletici.game"); + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("game", SIMULATED_WIDTH, SIMULATED_HEIGHT, 0, &window, &renderer)) { + SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); + return SDL_APP_FAILURE; + } + SDL_SetRenderLogicalPresentation(renderer, 640, 480, SDL_LOGICAL_PRESENTATION_LETTERBOX); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; + } + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppIterate(void *appstate) +{ + const double now = ((double)SDL_GetTicks()) / 1000.0; + + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE_FLOAT); + SDL_RenderClear(renderer); + + SDL_SetRenderDrawColor(renderer, 255, 0, 255, SDL_ALPHA_OPAQUE); + rasterizeTriangle(renderer, temp1, temp2, temp3); + + SDL_RenderPresent(renderer); + + return SDL_APP_CONTINUE; +} + +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ + +} + diff --git a/src/math.cpp b/src/math.cpp new file mode 100644 index 0000000..5d3441c --- /dev/null +++ b/src/math.cpp @@ -0,0 +1,87 @@ +#include +#include +#include + +#include "math.hpp" + +// DeltaVector2 + +DeltaVector2::DeltaVector2(float xval, float yval) { + x = xval; + y = yval; +} + +float DeltaVector2::length() const { + return std::sqrt(x * x + y * y); +} + +float DeltaVector2::dotProduct(const DeltaVector2& vec) const { + return x * vec.x + y * vec.y; +} + +float DeltaVector2::angleTo(const DeltaVector2& vec) const { + return std::acos(dotProduct(vec)) / (length() * vec.length()); +} + +DeltaVector2::DeltaVector2() { + x = 0; + y = 0; +} + +DeltaVector2 DeltaVector2::operator+(const DeltaVector2& other) const { + return DeltaVector2(x + other.x, y + other.y); +} + +DeltaVector2 DeltaVector2::operator-(const DeltaVector2& other) const { + return DeltaVector2(x - other.x, y - other.y); +} + +DeltaVector2 DeltaVector2::operator*(float a) const { + return DeltaVector2(x * a, y * a); +} + +DeltaVector2& DeltaVector2::operator+=(const DeltaVector2& other) { + x += other.x; + y += other.y; + + return *this; +} +DeltaVector2& DeltaVector2::operator-=(const DeltaVector2& other) { + x -= other.x; + y -= other.y; + + return *this; +} + +// DeltaVector3 + +DeltaVector3::DeltaVector3() { + x = 0; + y = 0; + z = 0; +} + +DeltaVector3::DeltaVector3(float xval, float yval, float zval) { + x = xval; + y = yval; + z = zval; +} + +float DeltaVector3::length() const { + return std::sqrt(x * x + y * y + z * z); +} + +float DeltaVector3::dotProduct(const DeltaVector3 &vec) const { + return x * vec.x + y * vec.y + z * vec.z; +} + +float DeltaVector3::angleTo(const DeltaVector3 &vec) const { + return std::acos(dotProduct(vec)) / (length() * vec.length()); +} + +float getDeterminant(const DeltaVector2 &pointA, const DeltaVector2 &pointB, const DeltaVector2 &candidate) { + DeltaVector2 ab = pointB - pointA; + DeltaVector2 ac = candidate - pointA; + + return (ab.y * ac.x) - (ab.x * ac.y); +} \ No newline at end of file diff --git a/src/renderer/calls.cpp b/src/renderer/calls.cpp new file mode 100644 index 0000000..23a4a1b --- /dev/null +++ b/src/renderer/calls.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include "renderer/calls.hpp" + +void rasterizeTriangle(SDL_Renderer *renderer, const DeltaVector2 &a, const DeltaVector2 &b, const DeltaVector2 &c) { + DeltaVector2 begin, end, p; + begin.x = std::min(a.x, std::min(b.x, c.x)); + begin.y = std::min(a.y, std::min(b.y, c.y)); + end.x = std::max(a.x, std::max(b.x, c.x)); + end.y = std::max(a.y, std::max(b.y, c.y)); + + for (int y = begin.y; y < end.y; y++) { + for (int x = begin.x; x < end.x; x++) { + p.x = x; p.y = y; + + if (getDeterminant(a, b, p) >= 0 && getDeterminant(b, c, p) >= 0 && getDeterminant(c, a, p) >= 0) { + SDL_RenderPoint(renderer, p.x, p.y); + } + + } + } +} \ No newline at end of file diff --git a/src/renderer/camera.cpp b/src/renderer/camera.cpp new file mode 100644 index 0000000..7bb50d3 --- /dev/null +++ b/src/renderer/camera.cpp @@ -0,0 +1,53 @@ +// please do not touch this code. +// it is a waste of time looking at this code. +// please, dont. if you do continue, edit the value below +// as a warning for future you. + +// hoursWasted = 2 + +#include +#include +#include + +#include "renderer/camera.hpp" +#include "globals.hpp" + +DeltaCamera::DeltaCamera(float x, float y, float z) { + pos = DeltaVector3(x, y, z); + angle = DeltaVector2(); +} + +DeltaVector2 DeltaCamera::projectPointVec(const DeltaVector3 &worldPos) { + DeltaVector3 calculatedPos; DeltaVector2 projected; + float sineX = std::sin(angle.x); + float cosineX = std::cos(angle.x); + + float sineY = std::sin(angle.y); + float cosineY = std::cos(angle.y); + + // yaw translate + + calculatedPos.x = (worldPos.x - pos.x) * cosineX - (worldPos.y - pos.y) * sineX; + calculatedPos.y = (worldPos.y - pos.y) * cosineX + (worldPos.x - pos.x) * sineX; + calculatedPos.z = (worldPos.z - pos.z); + + // pitch translate + + calculatedPos.y = calculatedPos.y * cosineY - calculatedPos.z * sineY; + calculatedPos.z = calculatedPos.y * sineY + calculatedPos.z * cosineY; + // dont touch calculatedPos.x + + projected.x = calculatedPos.x * FOCAL / calculatedPos.y + SIMULATED_WIDTH / 2; + projected.y = calculatedPos.y * FOCAL / calculatedPos.y + SIMULATED_HEIGHT / 2; + + // now gotta convert y to our y + projected.y = SIMULATED_HEIGHT - projected.y; + + // we are done =D + return projected; +} + +DeltaVector2 DeltaCamera::projectPoint(float worldX, float worldY, float worldZ) { + // simple conversion, dont iterate further + return projectPointVec({ worldX, worldY, worldZ }); +} \ No newline at end of file