added gradients to rectangle

This commit is contained in:
2026-07-04 08:31:39 -07:00
parent a89a4dacb5
commit 12d03c73b4
2 changed files with 129 additions and 4 deletions
BIN
View File
Binary file not shown.
+129 -4
View File
@@ -22,11 +22,12 @@ namespace UwU {
// Color datatype returns individual channel values from rgba hexcode // Color datatype returns individual channel values from rgba hexcode
struct Color { struct Color {
Color(uint32_t hex) { Color(uint32_t hex) {
this->a = hex & 0x000000ff; this->a = hex & 0x000000ff;
this->b = (hex & 0x0000ff00) >> 8; this->b = (hex & 0x0000ff00) >> 8;
this->g = (hex & 0x00ff0000) >> 16; this->g = (hex & 0x00ff0000) >> 16;
this->r = (hex & 0xff000000) >> 24; this->r = (hex & 0xff000000) >> 24;
} }
Color() {}
uint8_t r; uint8_t r;
uint8_t g; uint8_t g;
uint8_t b; uint8_t b;
@@ -49,6 +50,16 @@ namespace UwU {
uint8_t lerp8(uint8_t a, uint8_t b, uint8_t t) { uint8_t lerp8(uint8_t a, uint8_t b, uint8_t t) {
uint16_t product = (a * (255 - t)) + (b * t); uint16_t product = (a * (255 - t)) + (b * t);
return product / 255; 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) { void putPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b, uint8_t a = 0xff) {
@@ -111,6 +122,44 @@ namespace UwU {
return; 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: public:
struct waymini* wm; struct waymini* wm;
uint32_t width; uint32_t width;
@@ -145,6 +194,73 @@ namespace UwU {
return; 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. // Fill a simple gradient. Each row is stride bytes.
void rainbow() { void rainbow() {
for (uint32_t y = 0; y < this->height; y++) { for (uint32_t y = 0; y < this->height; y++) {
@@ -190,8 +306,11 @@ namespace UwU {
int main(void) { int main(void) {
uint32_t w = 800, h = 480; uint32_t w = 800, h = 480;
UwU::Color fuchsia = UwU::Color(0xb00b6980); UwU::Color fuchsia = UwU::Color(0xb00b6940);
UwU::Color green = UwU::Color(0x00ff0060); 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); 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); // struct waymini *wm = waymini_create(w, h, on_key, NULL);
@@ -199,8 +318,13 @@ int main(void) {
draw.rainbow(); draw.rainbow();
waymini_present(draw.wm);
draw.rectangle(UwU::Coord2(69, 69), UwU::Coord2(420, 420), fuchsia); 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.point(UwU::Coord2(387, 43), green);
draw.line(UwU::Coord2(300, 100), UwU::Coord2(250, 469), green); draw.line(UwU::Coord2(300, 100), UwU::Coord2(250, 469), green);
draw.line(UwU::Coord2(250, 100), UwU::Coord2(300, 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(250, 300), UwU::Coord2(100, 469), green);
draw.line(UwU::Coord2(100, 300), UwU::Coord2(469, 250), green); draw.line(UwU::Coord2(100, 300), UwU::Coord2(469, 250), green);
draw.line(UwU::Coord2(469, 300), UwU::Coord2(100, 250), green); draw.line(UwU::Coord2(469, 300), UwU::Coord2(100, 250), green);
waymini_present(draw.wm);
while (!waymini_should_close(draw.wm)) { while (!waymini_should_close(draw.wm)) {
if (waymini_dispatch(draw.wm) < 0) break; if (waymini_dispatch(draw.wm) < 0) break;