diff --git a/test b/test index 4f0a237..eefd6f0 100755 Binary files a/test and b/test differ diff --git a/test.cpp b/test.cpp index db3e5ab..d5775a3 100644 --- a/test.cpp +++ b/test.cpp @@ -22,11 +22,12 @@ namespace UwU { // Color datatype returns individual channel values from rgba hexcode struct Color { Color(uint32_t hex) { - this->a = hex & 0x000000ff; + 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; @@ -49,6 +50,16 @@ namespace UwU { uint8_t lerp8(uint8_t a, uint8_t b, uint8_t t) { uint16_t product = (a * (255 - t)) + (b * t); return product / 255; + // return b; + } + + Color lerpColor(Color a, Color b, uint8_t t) { + Color mixed = Color(); + mixed.r = this->lerp8(a.r, b.r, t); + mixed.g = this->lerp8(a.g, b.g, t); + mixed.b = this->lerp8(a.b, b.b, t); + mixed.a = this->lerp8(a.a, b.a, t); + return mixed; } void putPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b, uint8_t a = 0xff) { @@ -110,6 +121,44 @@ namespace UwU { } return; } + + // plot gradients' lerp t value if m <= 1 + void gradLow(int32_t x1, uint8_t* gradLut) { + int32_t dx = x1; + int32_t dy = 256; + int32_t d = (2 * dy) - dx; + int32_t y = 0; + for (int32_t x = 0; x < x1; x++) { + gradLut[x] = (uint8_t)y; + // gradLut[x] = 240; + if (d > 0) { + y++; + d += (2 * (dy -dx)); + } else { + d += (2 * dy); + } + } + return; + } + + // plot gradients' lerp t value if m >1 + void gradHigh(int32_t x1, uint8_t* gradLut) { + int32_t dx = x1; + int32_t dy = 256; + int32_t d = (2 * dx) - dy; + int32_t x = 0; + for (int32_t y = 0; y < 256; y++) { + gradLut[x] = (uint8_t)y; + // gradLut[x] = 69; + if (d > 0) { + x++; + d += (2 * (dx -dy)); + } else { + d += (2 * dx); + } + } + return; + } public: struct waymini* wm; @@ -144,6 +193,73 @@ namespace UwU { } return; } + + // Draws a rectangle with a 4-point color gradient + void rectangleGradient(Coord2 point0, Coord2 point1, Color colorUL, Color colorUR, Color colorLL, Color colorLR) { + // void rectangleGradient(Coord2 point0, Coord2 point1) { + // convert to int32_t and ensure x1>x0 && y1>y0 + int32_t x0, y0, x1, y1; + if (point0.x > point1.x) { + x0 = (int32_t)point1.x; + x1 = (int32_t)point0.x; + } else { + x0 = (int32_t)point0.x; + x1 = (int32_t)point1.x; + } + if (point0.y > point1.y) { + y0 = (int32_t)point1.y; + y1 = (int32_t)point0.y; + } else { + y0 = (int32_t)point0.y; + y1 = (int32_t)point1.y; + } + + // setup gradient coefficient arrays + int32_t w = x1 - x0; + int32_t h = y1 - y0; + uint8_t xGrad[w]; + uint8_t yGrad[h]; + + // determine m and calculate horizontal gradient coefficient + if (w < 256) { + this->gradHigh(w, xGrad); + } else { + this->gradLow(w, xGrad); + } + + printf("horizontal LUT\n"); + for (uint16_t i = 0; i < w; i++) { + printf("(%u, %u)\n", i, xGrad[i]); + } + + // determine m and calculate vertical gradient coefficient + if (h < 256) { + this->gradHigh(h, yGrad); + } else { + this->gradLow(h, yGrad); + } + + printf("vertical LUT\n"); + for (uint16_t i = 0; i < h; i++) { + printf("(%u, %u)\n", i, yGrad[i]); + } + + // for each point calculate, alpha blend and print color + Color Lmix = Color(); + Color Rmix = Color(); + Color Xmix = Color(); + for (int32_t y = y0; y < y1; y++) { + Lmix = this->lerpColor(colorUL, colorLL, yGrad[y - y0]); + Rmix = this->lerpColor(colorUR, colorLR, yGrad[y - y0]); + for (int32_t x = x0; x < x1; x++) { + Xmix = this->lerpColor(Lmix, Rmix, xGrad[x - x0]); + putPixel(x, y, Xmix.r, Xmix.g, Xmix.b, Xmix.a); + } + } + + + return; + } // Fill a simple gradient. Each row is stride bytes. void rainbow() { @@ -190,8 +306,11 @@ namespace UwU { int main(void) { uint32_t w = 800, h = 480; - UwU::Color fuchsia = UwU::Color(0xb00b6980); - UwU::Color green = UwU::Color(0x00ff0060); + UwU::Color fuchsia = UwU::Color(0xb00b6940); + UwU::Color red = UwU::Color(0xff0000ff); + UwU::Color green = UwU::Color(0x00ff00ff); + UwU::Color blue = UwU::Color(0x0000ffff); + UwU::Color alpha = UwU::Color(0xffffff00); printf("r: %u, g:%u, b:%u, a:%u\n", fuchsia.r, fuchsia.g, fuchsia.b, fuchsia.a); // struct waymini *wm = waymini_create(w, h, on_key, NULL); @@ -199,8 +318,13 @@ int main(void) { draw.rainbow(); - waymini_present(draw.wm); + draw.rectangle(UwU::Coord2(69, 69), UwU::Coord2(420, 420), fuchsia); + draw.rectangleGradient(UwU::Coord2(200, 200), UwU::Coord2(600, 400), alpha, blue, green, red); + + + + draw.point(UwU::Coord2(387, 43), green); draw.line(UwU::Coord2(300, 100), UwU::Coord2(250, 469), green); draw.line(UwU::Coord2(250, 100), UwU::Coord2(300, 469), green); @@ -210,6 +334,7 @@ int main(void) { draw.line(UwU::Coord2(250, 300), UwU::Coord2(100, 469), green); draw.line(UwU::Coord2(100, 300), UwU::Coord2(469, 250), green); draw.line(UwU::Coord2(469, 300), UwU::Coord2(100, 250), green); + waymini_present(draw.wm); while (!waymini_should_close(draw.wm)) { if (waymini_dispatch(draw.wm) < 0) break;