commit a921fb27b132437da5e1d6c5b71dc4d6e1f5680b Author: Amy Retzerau Date: Tue Nov 4 11:23:39 2025 +0100 init: first commit - rendering triangle diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ab24f7a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.15) + +project(SDFVisual VERSION 0.1 + DESCRIPTION "CPU SDF Renderer" + LANGUAGES CXX) +set (CMAKE_CXX_STANDARD 20) +add_executable(one main.cpp) + +target_link_libraries(one m) diff --git a/fastmath.hpp b/fastmath.hpp new file mode 100644 index 0000000..3dca49c --- /dev/null +++ b/fastmath.hpp @@ -0,0 +1,140 @@ +#ifndef FASTMATH_H +#define FASTMATH_H + +#include +#include +#include +#include +#define SHIFT_AMOUNT 16 +#define HALF_SHIFT (SHIFT_AMOUNT / 2) + +#define SHIFT_MASK ((1 << SHIFT_AMOUNT) - 1) +#define TO_FLOAT(x) \ + (((float)(x >> SHIFT_AMOUNT)) + \ + ((double)(x & SHIFT_MASK) / (1 << SHIFT_AMOUNT))) +#define TO_INT(x) ((int32_t)(x * (1 << SHIFT_AMOUNT))) +#define MUL_F(a, b) (((a) >> HALF_SHIFT) * ((b) >> HALF_SHIFT)) +#define DIV_F(a, b) ((((a) << HALF_SHIFT) / (b)) << HALF_SHIFT) + +struct decimal { + + const int32_t i; + + decimal(float i) : i(TO_INT(i)) {} + decimal(double i) : i(TO_INT(i)) {} + decimal(int32_t i) : i(i) {} + + friend std::ostream &operator<<(std::ostream &os, const decimal &d) { + return (os << TO_FLOAT(d.i)); + } + + friend decimal operator+(const decimal &d1, const decimal &d2) { + return {d1.i + d2.i}; + } + decimal &operator+=(const decimal &d) { return (*this) = {i + d.i}; } + + friend decimal operator-(const decimal &d1, const decimal &d2) { + return {d1.i - d2.i}; + } + friend decimal operator-(const decimal &d) { return {-d.i}; } + + friend decimal operator*(const decimal &d1, const decimal &d2) { + return {MUL_F(d1.i, d2.i)}; + } + + friend decimal operator/(const decimal &d1, const decimal &d2) { + return {DIV_F(d1.i, d2.i)}; + } + + friend bool operator<(const decimal &d1, const decimal &d2) { + return d1.i < d2.i; + } + + friend bool operator>(const decimal &d1, const decimal &d2) { + return d1.i > d2.i; + } + + friend bool operator==(const decimal &d1, const decimal &d2) { + return d1.i == d2.i; + } + + decimal &operator=(decimal const &in) { + if (this != &in) { + std::destroy_at(this); + std::construct_at(this, in); + } + return *this; + } + + decimal sqrt() { return {((int32_t)sqrtf(i)) << HALF_SHIFT}; } + + float to_float() { return TO_FLOAT(i); } +}; + +struct vec3 { + const decimal x; + const decimal y; + const decimal z; + + vec3(float x, float y, float z) + : x(decimal(x)), y(decimal(y)), z(decimal(z)) {} + + vec3(double x, double y, double z) + : x(decimal(x)), y(decimal(y)), z(decimal(z)) {} + + vec3(int32_t x, int32_t y, int32_t z) + : x(decimal(x)), y(decimal(y)), z(decimal(z)) {} + vec3(decimal x, decimal y, decimal z) : x(x), y(y), z(z) {} + + friend vec3 operator+(const vec3 &v1, const vec3 &v2) { + return vec3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); + } + + friend vec3 operator-(const vec3 &v1, const vec3 &v2) { + return vec3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); + } + + vec3 operator-() { return vec3(-x, -y, -z); } + + friend vec3 operator*(const vec3 &v, const decimal &n) { + int32_t f = n.i >> HALF_SHIFT; + return vec3({(v.x.i >> HALF_SHIFT) * f}, {(v.y.i >> HALF_SHIFT) * f}, + {(v.z.i >> HALF_SHIFT) * f}); + } + friend vec3 operator*(const decimal &n, const vec3 &v) { return v * n; } + + decimal operator*(const vec3 &v) { return v.x * x + v.y * y + v.z * z; } + + friend bool operator==(const vec3 &v1, const vec3 &v2) { + return (v1.x == v2.x) & (v1.y == v2.y) & (v1.z == v2.z); + } + + vec3 &operator=(vec3 const &in) { + if (this != &in) { + std::destroy_at(this); + std::construct_at(this, in); + } + return *this; + } + + friend std::ostream &operator<<(std::ostream &os, const vec3 &v) { + return (os << "(" << v.x << ", " << v.y << ", " << v.z << ")" + << std::endl); + } + + vec3 cross(const vec3 &v) { + return vec3((y * v.z) - (z * v.y), (z * v.x) - (x * v.z), + (x * v.y) - (y * v.x)); + } + + decimal len_sq() { return *this * *this; } + + decimal len() { return this->len_sq().sqrt(); } + + vec3 normalize() { + decimal f = decimal(1.0) / this->len(); + return (*this * f); + } +}; + +#endif diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..186dfe6 --- /dev/null +++ b/main.cpp @@ -0,0 +1,79 @@ +#include "fastmath.hpp" +#include "polygon.hpp" +#include +#include +#include +#include +#include +#include + +#define HIGHT 64 +#define WIDTH 64 + +#define FAA_FAC 2 +#define RHIGHT ((int)(HIGHT * FAA_FAC)) +#define RWIDTH ((int)(WIDTH * FAA_FAC)) + +char *drawToString(unsigned short *img) { + char *textImg = (char *)malloc(200000 * sizeof(char)); + // strcat(textImg,"\e[1;1H\e[2J"); --clear + for (int y = 0; y < HIGHT; y++) { + for (int x = 0; x < WIDTH; x++) { + // printf("%d,%d\n",x,y); + char buff[20]; + unsigned short val = 0; + int my = y * FAA_FAC; + int mx = x * FAA_FAC; + val += img[my * RWIDTH + mx]; + val += img[my * RWIDTH + mx + 1]; + val += img[(my + 1) * RWIDTH + mx]; + val += img[(my + 1) * RWIDTH + mx + 1]; + sprintf(buff, "\033[38;5;%dm██\033[0m", 232 + val / 4); + strcat(textImg, buff); + } + strcat(textImg, "\n"); + } + return textImg; +} + +void drawImage(unsigned short *img) { + decimal heightPerPix = decimal(1.0) / decimal((float)(HIGHT * FAA_FAC)); + decimal widthPerPix = decimal(1.0) / decimal((float)(WIDTH * FAA_FAC)); + + polygon poly = polygon(vec3(0.9, 0.9, 0.0) * decimal(128.0), + vec3(0.5, 0.1, 0.0) * decimal(128.0), + vec3(0.1, 0.9, 0.0) * decimal(128.0)); + + // printf("\n hpp: %f, wpp: %f + // \n",TO_FLOAT(heightPerPix),TO_FLOAT(widthPerPix)); calcViewPos(t); + for (decimal y = 0; y < decimal((float)(RHIGHT)); y += decimal(1.0)) { + for (decimal x = 0; x < decimal((float)(RWIDTH)); x += decimal(1.0)) { + + vec3 p = vec3(x, y, 0.0); + + if (poly.contains(p)) { + + img[(y.i >> SHIFT_AMOUNT) * RWIDTH + (x.i >> SHIFT_AMOUNT)] = + (unsigned short)23; // (((-normal[1]+(1 << + // SHIFT_AMOUNT))*14)>>SHIFT_AMOUNT); + } else { + img[(y.i >> SHIFT_AMOUNT) * RWIDTH + (x.i >> SHIFT_AMOUNT)] = + (unsigned short)0; + } + } + } + printf("done writing %d \n", *(img + sizeof(unsigned short) * 32 * 32)); +} + +int main() { + unsigned short *img = + (unsigned short *)malloc(128 * 128 * sizeof(unsigned short)); + while (true) { + drawImage(img); + printf("%s", drawToString(img)); + return 0; + // sleep(0.001); + } + // printf("%s", test); + return 0; +} diff --git a/polygon.hpp b/polygon.hpp new file mode 100644 index 0000000..c683986 --- /dev/null +++ b/polygon.hpp @@ -0,0 +1,29 @@ +#ifndef POLYGON_H +#define POLYGON_H + +#include "fastmath.hpp" + +struct polygon { + + const vec3 points[3]; + + polygon(const vec3 &v1, const vec3 &v2, const vec3 &v3) + : points{v1, v2, v3} {} + + bool contains(const vec3 &p) { + for (int i = 0; i < 3; i++) { + int n = (i + 1) % 3; + + vec3 d = points[n] - points[i]; + d = vec3(d.y, -d.x, d.z); + + vec3 s = p - points[n]; + + if (s * d < decimal(0.0)) + return false; + } + return true; + } +}; + +#endif