diff --git a/bresenham.cpp b/bresenham.cpp new file mode 100644 index 0000000..259a67a --- /dev/null +++ b/bresenham.cpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +namespace UwU { + + class Bresenham { + private: + int16_t x0; + int16_t y0; + int16_t x1; + int16_t y1; + int16_t d; + int16_t + + public: + Bresenham(int16_t x0, int16_t y0, int16_t x1, int16_t y1) { + this->x0 = x0; + this->y0 = y0; + this->x1 = x1; + this->y1 = y1; + + if (abs(y1 - y0) < abs(x1 - x0)) { + if (x0 > x1) { + + } + } + } + }; +} \ No newline at end of file diff --git a/datatypes.cpp b/datatypes.cpp new file mode 100644 index 0000000..14fdf67 --- /dev/null +++ b/datatypes.cpp @@ -0,0 +1,69 @@ +#pragma once + +#include + +namespace UwU { + + // Color datatype returns individual channel values from rgba hexcode + struct Color { + Color(uint32_t hex) { + this->a = hex & 0x000000ff; + this->b = (hex & 0x0000ff00) >> 8; + this->g = (hex & 0x00ff0000) >> 16; + this->r = (hex & 0xff000000) >> 24; + } + Color() {} + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; + }; + + // Coord2 datatype for xy coordinates, from top-left of surface + struct Coord2 { + Coord2(uint32_t x, uint32_t y) { + this->x = x; + this->y = y; + } + Coord2() {} + uint32_t x; + uint32_t y; + }; + + // trapezoid datatype (horizontally constrained) + struct Trapezoid { + Trapezoid(uint16_t y0, uint16_t y1, uint16_t xl0, uint16_t xl1, uint16_t xr0, uint16_t xr1) { + this->y0 = y0; + this->y1 = y1; + this->xl0 = xl0; + this->xl1 = xl1; + this->xr0 = xr0; + this->xr1 = xr1; + } + Trapezoid() {} + uint16_t y0; + uint16_t y1; + uint16_t xl0; + uint16_t xl1; + uint16_t xr0; + uint16_t xr1; + }; + + struct Triangle { + Triangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { + this->x0 = x0; + this->y0 = y0; + this->x1 = x1; + this->y1 = y1; + this->x2 = x2; + this->y2 = y2; + } + Triangle() {} + uint16_t x0; + uint16_t y0; + uint16_t x1; + uint16_t y1; + uint16_t x2; + uint16_t y2; + }; +} \ No newline at end of file diff --git a/datatypes.h b/datatypes.h new file mode 100644 index 0000000..fd19294 --- /dev/null +++ b/datatypes.h @@ -0,0 +1,31 @@ +#include + +namespace UwU { + + struct Color { + Color(uint32_t hex); + Color(); + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; + }; + + struct Coord2 { + Coord2(uint32_t x, uint32_t y); + Coord2(); + uint32_t x; + uint32_t y; + }; + + struct Trapezoid { + Trapezoid(uint16_t y0, uint16_t y1, uint16_t xl0, uint16_t xl1, uint16_t xr0, uint16_t xr1); + Trapezoid(); + uint16_t y0; + uint16_t y1; + uint16_t xl0; + uint16_t xl1; + uint16_t xr0; + uint16_t xr1; + }; +} \ No newline at end of file diff --git a/helpers.cpp b/helpers.cpp new file mode 100644 index 0000000..4f829b9 --- /dev/null +++ b/helpers.cpp @@ -0,0 +1,94 @@ +#pragma once + +#include +#include "datatypes.cpp" + +namespace UwU { + + class Helpers { + public: + static uint8_t lerp8(uint8_t a, uint8_t b, uint8_t t) { + uint16_t product = (a * (255 - t)) + (b * t); + return product / 255; + } + + static Color lerpColor(Color a, Color b, uint8_t t) { + Color mixed = Color(); + mixed.r = lerp8(a.r, b.r, t); + mixed.g = lerp8(a.g, b.g, t); + mixed.b = lerp8(a.b, b.b, t); + mixed.a = lerp8(a.a, b.a, t); // maybe the alpha channel should be handled differently? + return mixed; + } + + static void bresenhamLow(uint16_t x0, int16_t y0, uint16_t x1, int16_t y1, int16_t* LUT) { + int16_t dx = int16_t(x1) - int16_t(x0); + int16_t dy = y1 - y0; + int16_t yi = 1; + if (dy < 0) { + yi = -1; + dy = -dy; + } + int16_t d = (2 * dy) - dx; + int16_t y = y0; + for (uint16_t x = x0; x <= x1; x++) { + LUT[x] = y; + if (d > 0) { + y += yi; + d += (2 * (dy - dx)); + } else { + d += (2 * dy); + } + } + return; + } + + static void bresenhamHigh(uint16_t x0, int16_t y0, uint16_t x1, int16_t y1, int16_t* LUT) { + int16_t dx = (int16_t)x1 - (int16_t)x0; + int16_t dy = y1 - y0; + int16_t xi = 1; + if (dx < 0) { + xi = -1; + dx = -dx; + } + int16_t d = (2 * dx) - dy; + int16_t x = (int16_t)x0; + for (int16_t y = y0; y <= y1; y++) { + LUT[x] = y; + if (d > 0) { + x += xi; + d += (2 * (dx - dy)); + } else { + d += (2 * dx); + } + } + return; + } + + // x1 must >= x0 && LUT must be size x1 + 1 + static void bresenham(uint16_t x0, int16_t y0, uint16_t x1, int16_t y1, int16_t* LUT) { + if (x0 == x1) { + // catch vline condition + LUT[x0] = y1; + return; + } + if (y0 == y1) { + // catch hline condition + for (uint16_t i = x0; i <= x1; i++) { + LUT[i] = y1; + } + return; + } + if (abs(y1 - y0) <= x1) { + bresenhamLow(x0, y0, x1, y1, LUT); + } else { + if (y0 > y1) { + bresenhamHigh(x1, y1, x0, y0, LUT); + } else { + bresenhamHigh(x0, y0, x1, y1, LUT); + } + } + return; + } + }; +} \ No newline at end of file diff --git a/triangle.cpp b/triangle.cpp new file mode 100644 index 0000000..8885334 --- /dev/null +++ b/triangle.cpp @@ -0,0 +1,27 @@ +#pragma once + +#include + +#include "datatypes.cpp" +#include "helpers.cpp" + +namespace UwU { + class Triangle { + public: + Triangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { + this->x0 = x0; + this->y0 = y0; + this->x1 = x1; + this->y1 = y1; + this->x2 = x2; + this->y2 = y2; + } + Triangle() {} + uint16_t x0; + uint16_t y0; + uint16_t x1; + uint16_t y1; + uint16_t x2; + uint16_t y2; + }; +} \ No newline at end of file