diff --git a/buffer.cpp b/buffer.cpp index d80d15e..f3fbac4 100644 --- a/buffer.cpp +++ b/buffer.cpp @@ -29,9 +29,9 @@ namespace UwU { uint16_t height; uint16_t stride; - void drawPixel(Coord2 coord, Color color) { + void drawPixel(uint16_t x, uint16_t y, Color color) { // if (color.a == 0) {return;} - size_t i = (size_t)coord.y * stride + (size_t)coord.x * 4; + size_t i = (size_t)y * stride + (size_t)x * 4; // uint8_t b0 = pixels[i + 0]; // uint8_t g0 = pixels[i + 1]; // uint8_t r0 = pixels[i + 2]; @@ -41,25 +41,8 @@ namespace UwU { pixels[i + 0] = color.b; // B pixels[i + 1] = color.g; // G pixels[i + 2] = color.r; // R - pixels[i + 3] = 0xff; // A + pixels[i + 3] = 0xff; // A return; } - - // void drawPixelShader(uint16_t x, uint16_t y, Shader& shader) { - // Color newColor = shader.color(x, y); - // if (newColor.a == 0) {return;} - // size_t i = (size_t)y * stride + (size_t)x * 4; - // // uint8_t b0 = pixels[i + 0]; - // // uint8_t g0 = pixels[i + 1]; - // // uint8_t r0 = pixels[i + 2]; - // // uint8_t b = Helpers::lerp8(b0, newColor.b, newColor.a); - // // uint8_t g = Helpers::lerp8(g0, newColor.g, newColor.a); - // // uint8_t r = Helpers::lerp8(r0, newColor.r, newColor.a); - // pixels[i + 0] = newColor.b; // B - // pixels[i + 1] = newColor.g; // G - // pixels[i + 2] = newColor.r; // R - // pixels[i + 3] = 0xff; // A - // return; - // } }; } \ No newline at end of file diff --git a/example b/example index 55e4408..2fceecc 100755 Binary files a/example and b/example differ diff --git a/example.cpp b/example.cpp index 54e9d52..89c41c2 100644 --- a/example.cpp +++ b/example.cpp @@ -32,9 +32,9 @@ static void onKey(void *user, uint32_t keycode, uint32_t state) { int main(void) { uint16_t w = 800, h = 480; - UwU::Shader fuchsia = UwU::Shader(UwU::Direction::H, 69, 420, UwU::Color(0xb00b69ff), UwU::Color(0x00000000)); + UwU::Shader fuchsia = UwU::Shader(UwU::Direction::H, 360, 600, UwU::Color(0xb00b69ff), UwU::Color(0x00000000)); + UwU::Shader red = UwU::Shader(UwU::Direction::V, 69, 420, UwU::Color(0xff0000ff), UwU::Color(0x00000000)); UwU::Shader warmup = UwU::Shader(UwU::Color(0xb00b69ff)); - UwU::Color red = UwU::Color(0xff000080); UwU::Color green = UwU::Color(0x00ff00ff); UwU::Color blue = UwU::Color(0x0000ff80); // UwU::Color alpha = UwU::Color(0x00000000); @@ -43,7 +43,11 @@ int main(void) { // UwU::Buffer buffer = UwU::Buffer(surface.getWidth(), surface.getHeight()); UwU::Rectangle rectangle = UwU::Rectangle(69, 69, 420, 420); + UwU::Trapezoid trapezoid = UwU::Trapezoid(300, 400, 360, 380, 600, 480); + UwU::Triangle triangle = UwU::Triangle(280, 100, 240, 290, 320, 300); + UwU::Point point = UwU::Point(387, 43); + rectangle.draw(surface.buffer, red); // Benchmarking struct timespec start, end; @@ -52,13 +56,13 @@ int main(void) { const int SAMPLES = 10; for (int i = 0; i < WARMUP; i++) { - rectangle.draw(surface.buffer, fuchsia); + trapezoid.draw(surface.buffer, fuchsia); } long times[SAMPLES]; for (int s = 0; s < SAMPLES; s++) { clock_gettime(CLOCK_MONOTONIC, &start); for (int i = 0; i < BATCH; i++) { - rectangle.draw(surface.buffer, fuchsia); + trapezoid.draw(surface.buffer, fuchsia); } clock_gettime(CLOCK_MONOTONIC, &end); times[s] = (end.tv_sec - start.tv_sec) * 1000000000L + (end.tv_nsec - start.tv_nsec); @@ -71,14 +75,10 @@ int main(void) { timeAvg /= BATCH; printf("Elapsed: %ld ns\n", timeAvg); - UwU::Trapezoid trapezoid = UwU::Trapezoid(300, 400, 360, 380, 600, 480); - trapezoid.draw(surface.buffer, red); - UwU::Triangle triangle = UwU::Triangle(280, 100, 240, 290, 320, 300); triangle.draw(surface.buffer, blue); - - UwU::Point point = UwU::Point(387, 43); + point.draw(surface.buffer, green); - + UwU::Line lines[8] { UwU::Line(300, 100, 250, 469), UwU::Line(250, 100, 300, 469), diff --git a/primatives/line.cpp b/primatives/line.cpp index 09d1a74..830e9ea 100644 --- a/primatives/line.cpp +++ b/primatives/line.cpp @@ -22,7 +22,7 @@ namespace UwU { int16_t d = (2 * dy) - dx; int16_t y = iy0; for (int16_t x = ix0; x < ix1; x++) { - buffer.drawPixel(Coord2((uint16_t)x, (uint16_t)y), color); + buffer.drawPixel((uint16_t)x, (uint16_t)y, color); if (d > 0) { y += yi; d += (2 * (dy - dx)); @@ -45,7 +45,7 @@ namespace UwU { int16_t d = (2 * dx) - dy; int16_t x = ix0; for (int16_t y = iy0; y < iy1; y++) { - buffer.drawPixel(Coord2((uint16_t)x, (uint16_t)y), color); + buffer.drawPixel((uint16_t)x, (uint16_t)y, color); if (d > 0) { x += xi; d += (2 * (dx - dy)); diff --git a/primatives/point.cpp b/primatives/point.cpp index f043228..c82255d 100644 --- a/primatives/point.cpp +++ b/primatives/point.cpp @@ -21,7 +21,7 @@ namespace UwU { // Draw a rectangle void draw (Buffer buffer, Color color) { if (x > buffer.width || y > buffer.height) {return;}; - buffer.drawPixel(Coord2(x, y), color); + buffer.drawPixel(x, y, color); return; } }; diff --git a/primatives/rectangle.cpp b/primatives/rectangle.cpp index f80bab9..b072550 100644 --- a/primatives/rectangle.cpp +++ b/primatives/rectangle.cpp @@ -29,20 +29,23 @@ namespace UwU { if (x0 > buffer.width || y0 > buffer.height || x1 > buffer.width || y1 > buffer.height) {return;}; for (uint16_t y = y0; y < y1; y++) { for (uint16_t x = x0; x < x1; x++) { - buffer.drawPixel(Coord2(x, y), shader.c0); + buffer.drawPixel(x, y, shader.c0); } } return; } else if (shader.shaderType == HGRADIENT) { if (x0 > buffer.width || y0 > buffer.height || x1 > buffer.width || y1 > buffer.height) {return;}; + + // Precompute gradient LUT Color cols[x1 - x0]; for (uint16_t x = x0; x < x1; x++) { cols[x - x0] = ShaderMethods::gradient(shader.u0, shader.scale, shader.c0, shader.c1, x); } + for (uint16_t y = y0; y < y1; y++) { for (uint16_t x = x0; x < x1; x++) { - buffer.drawPixel(Coord2(x, y), cols[x - x0]); + buffer.drawPixel(x, y, cols[x - x0]); } } return; @@ -52,7 +55,7 @@ namespace UwU { for (uint16_t y = y0; y < y1; y++) { Color c = ShaderMethods::gradient(shader.v0, shader.scale, shader.c0, shader.c1, y); for (uint16_t x = x0; x < x1; x++) { - buffer.drawPixel(Coord2(x, y), c); + buffer.drawPixel(x, y, c); } } return; diff --git a/primatives/trapezoid.cpp b/primatives/trapezoid.cpp index ec58236..9724d45 100644 --- a/primatives/trapezoid.cpp +++ b/primatives/trapezoid.cpp @@ -5,6 +5,7 @@ #include "../datatypes.cpp" #include "../helpers.cpp" #include "../buffer.cpp" +#include "../shader.cpp" namespace UwU { // trapezoid (horizontally constrained) @@ -28,9 +29,7 @@ namespace UwU { // Draw a horizontally bounded trapezoid // y1 >= y0 - // todo move to private and add public checks - void draw (Buffer buffer, Color color) { - // printf("(%u, %u, %u, %u, %u, %u)", coords.y0, coords.y1, coords.xl0, coords.xl1, coords.xr0, coords.xr1); + void draw (Buffer buffer, Shader shader) { uint16_t height = 1 + y1 - y0; int16_t LeftBound[height]; int16_t RightBound[height]; @@ -38,20 +37,51 @@ namespace UwU { Helpers::bresenham(0, xl0, y1 - y0, xl1, LeftBound); Helpers::bresenham(0, xr0, y1 - y0, xr1, RightBound); - // printf("leftbound\n"); - for (uint16_t i = 0; i < height; i++) { - // printf("(%u, %u)\n", i, LeftBound[i]); - } - // printf("rightbound\n"); - for (uint16_t i = 0; i < height; i++) { - // printf("(%u, %u)\n", i, RightBound[i]); - } - - for (uint16_t i = 0; i < height; i++) { - for (uint16_t x = LeftBound[i]; x <= RightBound[i]; x++) { - // printf("(%u, %u)", x, i + coords.y0); - buffer.drawPixel(Coord2(x, i + y0), color); + if (shader.shaderType == COLOR) { + for (uint16_t i = 0; i < height; i++) { + for (uint16_t x = LeftBound[i]; x <= RightBound[i]; x++) { + buffer.drawPixel(x, i + y0, shader.c0); + } } + return; + + } else if (shader.shaderType == HGRADIENT) { + // find left-right boundaries + uint16_t leftmost, rightmost; + if (xl0 < xl1) { + leftmost = xl0; + } else { + leftmost = xl1; + } + if (xr0 > xr1) { + rightmost = xr0; + } else { + rightmost = xr1; + } + + // precompute gradient LUT + Color cols[rightmost - leftmost]; + for (uint16_t x = leftmost; x < rightmost; x++) { + cols[x - leftmost] = ShaderMethods::gradient(shader.u0, shader.scale, shader.c0, shader.c1, x); + } + + for (uint16_t i = 0; i < height; i++) { + for (uint16_t x = LeftBound[i]; x <= RightBound[i]; x++) { + buffer.drawPixel(x, i + y0, cols[x - leftmost]); + } + } + return; + + } else if (shader.shaderType == VGRADIENT) { + Color c; + for (uint16_t i = 0; i < height; i++) { + c = ShaderMethods::gradient(shader.v0, shader.scale, shader.c0, shader.c1, i + y0); + for (uint16_t x = LeftBound[i]; x <= RightBound[i]; x++) { + buffer.drawPixel(x, i + y0, c); + } + } + return; + } return; } diff --git a/primatives/triangle.cpp b/primatives/triangle.cpp index 73152ce..e0400f1 100644 --- a/primatives/triangle.cpp +++ b/primatives/triangle.cpp @@ -101,7 +101,7 @@ namespace UwU { for (uint16_t i = 0; i < height; i++) { for (uint16_t x = (uint16_t)splitBound[i]; x <= (uint16_t)longBound[i]; x++) { // Helpers::putPixel(buffer, x, i + (uint32_t)top.y, color.r, color.g, color.b, color.a); - buffer.drawPixel(Coord2(x, i + (uint16_t)top.y), color); + buffer.drawPixel(x, i + (uint16_t)top.y, color); } } } else { @@ -115,7 +115,7 @@ namespace UwU { for (uint16_t i = 0; i < height; i++) { for (uint16_t x = (uint16_t)longBound[i]; x <= (uint16_t)splitBound[i]; x++) { // Helpers::putPixel(buffer, x, i + (uint32_t)top.y, color.r, color.g, color.b, color.a); - buffer.drawPixel(Coord2(x, i + (uint16_t)top.y), color); + buffer.drawPixel(x, i + (uint16_t)top.y, color); } } }