diff --git a/TODO b/TODO index d7c9132..4ff3ed0 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ -[ ] write a monolithic header file +[x] write a monolithic header file [x] refactor example code using composition [x] remove draw class entirely [x] create shader classes with polymorphism diff --git a/example b/example index 5fd8bb3..56272d3 100755 Binary files a/example and b/example differ diff --git a/example.cpp b/example.cpp index 7137591..407950b 100644 --- a/example.cpp +++ b/example.cpp @@ -7,21 +7,22 @@ #include #include -#include "datatypes.cpp" -#include "helpers.cpp" -#include "buffer.cpp" -#include "surface.cpp" -#include "primatives/line.cpp" -#include "primatives/point.cpp" -#include "primatives/rectangle.cpp" -#include "primatives/trapezoid.cpp" -#include "primatives/triangle.cpp" -#include "shader.cpp" +// #include "datatypes.cpp" +// #include "helpers.cpp" +// #include "buffer.cpp" +// #include "surface.cpp" +// #include "primatives/line.cpp" +// #include "primatives/point.cpp" +// #include "primatives/rectangle.cpp" +// #include "primatives/trapezoid.cpp" +// #include "primatives/triangle.cpp" +// #include "shader.cpp" +#include "uwugl.h" #include - #include "font.cpp" + static void onKey(void *user, uint32_t keycode, uint32_t state) { if (keycode == 1) { exit(1); @@ -34,113 +35,56 @@ 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::V, 100, 300, UwU::Color(0xb00b69ff), UwU::Color(0x00000000)); - UwU::Shader red = UwU::Shader(UwU::Direction::V, 69, 420, UwU::Color(0xff0000ff), UwU::Color(0x00000000)); - UwU::Shader bisexual = UwU::Shader(UwU::Direction::H, 0, 799, UwU::Color(0xff0000ff), UwU::Color(0x0000ffff)); - UwU::Shader aqua = UwU::Shader(UwU::Direction::V, 2, 349, UwU::Color(0x00ff00ff), UwU::Color(0x0000ffff)); - UwU::Shader warmup = UwU::Shader(UwU::Color(0xb00b69ff)); - UwU::Shader green = UwU::Shader(UwU::Color(0x00ff00ff)); - UwU::Color blue = UwU::Color(0x0000ff80); - // UwU::Color alpha = UwU::Color(0x00000000); UwU::Surface surface = UwU::Surface(w, h, onKey); - UwU::Buffer buffer = UwU::Buffer(800, 480); - UwU::Shader gradientBuffer = UwU::Shader(69, 69, buffer); - + + UwU::ColorShader fuchsia = UwU::ColorShader(UwU::Color(0xb00b69ff)); + UwU::Rectangle rectangle = UwU::Rectangle(69, 69, 420, 420); - UwU::Rectangle bgRectangle = UwU::Rectangle(2, 2, 797, 477); - 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); - // Window Header - UwU::Trapezoid trap0 = UwU::Trapezoid(0, 7, 7, 0, 792, 799); - UwU::Rectangle rect1 = UwU::Rectangle(0, 8, 799, 23); - UwU::Trapezoid trap2 = UwU::Trapezoid(24, 31, 0, 0, 71, 63); - UwU::Trapezoid trap3 = UwU::Trapezoid(24, 31, 727, 736, 799, 799); - // trap0.draw(surface.buffer, bisexual); - // rect1.draw(surface.buffer, bisexual); - // trap2.draw(surface.buffer, bisexual); - // trap3.draw(surface.buffer, bisexual); - - // Window Body - UwU::Shader sU1 = UwU::Shader(8, 8, font()); - UwU::Shader sw1 = UwU::Shader(10, 8, font()); - UwU::Shader sU2 = UwU::Shader(28, 8, font()); - UwU::Shader sG1 = UwU::Shader(20, 8, font()); - UwU::Shader sL1 = UwU::Shader(22, 8, font()); - UwU::Rectangle rU1 = UwU::Rectangle(8, 8, 13, 16); - UwU::Rectangle rw1 = UwU::Rectangle(16, 8, 25, 16); - UwU::Rectangle rU2 = UwU::Rectangle(28, 8, 33, 16); - UwU::Rectangle rG1 = UwU::Rectangle(36, 8, 41, 16); - UwU::Rectangle rL1 = UwU::Rectangle(44, 8, 48, 16); - rU1.draw(surface.buffer, sU1); - rw1.draw(surface.buffer, sw1); - rU2.draw(surface.buffer, sU2); - rG1.draw(surface.buffer, sG1); - rL1.draw(surface.buffer, sL1); - - // Window Footer - UwU::Trapezoid trap5 = UwU::Trapezoid(440, 471, 712, 689, 799, 799); - UwU::Trapezoid trap6 = UwU::Trapezoid(472, 479, 0, 7, 799, 792); - trap5.draw(surface.buffer, bisexual); - trap6.draw(surface.buffer, bisexual); - - // Window Buttons - UwU::Trapezoid trap7 = UwU::Trapezoid(448, 455, 728, 720, 791, 791); - UwU::Rectangle rect8 = UwU::Rectangle(720, 456, 791, 463); - UwU::Trapezoid trap9 = UwU::Trapezoid(464, 471, 720, 720, 791, 783); - trap7.draw(surface.buffer, fuchsia); - rect8.draw(surface.buffer, fuchsia); - trap9.draw(surface.buffer, fuchsia); - - bgRectangle.draw(buffer, aqua); + rectangle.draw(surface.buffer, fuchsia); - // Benchmarking - struct timespec start, end; - const int WARMUP = 100; - const int BATCH = 1000; - const int SAMPLES = 10; + // // Benchmarking + // struct timespec start, end; + // const int WARMUP = 100; + // const int BATCH = 1000; + // const int SAMPLES = 10; - for (int i = 0; i < WARMUP; i++) { - rectangle.draw(surface.buffer, gradientBuffer); - } - 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, gradientBuffer); - } - clock_gettime(CLOCK_MONOTONIC, &end); - times[s] = (end.tv_sec - start.tv_sec) * 1000000000L + (end.tv_nsec - start.tv_nsec); - } - long timeAvg = 0; - for (int i = 0; i < SAMPLES; i++) { - timeAvg += times[i]; - } - timeAvg /= SAMPLES; - timeAvg /= BATCH; - printf("Elapsed: %ld ns\n", timeAvg); + // for (int i = 0; i < WARMUP; i++) { + // rectangle.draw(surface.buffer, gradientBuffer); + // } + // 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, gradientBuffer); + // } + // clock_gettime(CLOCK_MONOTONIC, &end); + // times[s] = (end.tv_sec - start.tv_sec) * 1000000000L + (end.tv_nsec - start.tv_nsec); + // } + // long timeAvg = 0; + // for (int i = 0; i < SAMPLES; i++) { + // timeAvg += times[i]; + // } + // timeAvg /= SAMPLES; + // timeAvg /= BATCH; + // printf("Elapsed: %ld ns\n", timeAvg); - triangle.draw(surface.buffer, fuchsia); - trapezoid.draw(surface.buffer, red); - point.draw(surface.buffer, green); - - UwU::Line lines[8] { - UwU::Line(300, 100, 250, 469), - UwU::Line(250, 100, 300, 469), - UwU::Line(300, 100, 469, 250), - UwU::Line(469, 100, 300, 250), - UwU::Line(100, 300, 250, 469), - UwU::Line(250, 300, 100, 469), - UwU::Line(100, 300, 469, 250), - UwU::Line(469, 300, 100, 250) - }; + // UwU::Line lines[8] { + // UwU::Line(300, 100, 250, 469), + // UwU::Line(250, 100, 300, 469), + // UwU::Line(300, 100, 469, 250), + // UwU::Line(469, 100, 300, 250), + // UwU::Line(100, 300, 250, 469), + // UwU::Line(250, 300, 100, 469), + // UwU::Line(100, 300, 469, 250), + // UwU::Line(469, 300, 100, 250) + // }; - for (uint16_t i = 0; i < 8; i++) { - lines[i].draw(surface.buffer, bisexual); - } + // for (uint16_t i = 0; i < 8; i++) { + // lines[i].draw(surface.buffer, bisexual); + // } surface.present(); diff --git a/primatives/rectangle.cpp b/primatives/rectangle.cpp index a6d15e0..5fb6471 100644 --- a/primatives/rectangle.cpp +++ b/primatives/rectangle.cpp @@ -5,7 +5,8 @@ #include "../datatypes.cpp" #include "../helpers.cpp" #include "../buffer.cpp" -#include "../shader.cpp" +#include "../shaders/shaderbase.cpp" +#include "../shaders/colorshader.cpp" namespace UwU { // rectangle @@ -24,47 +25,13 @@ namespace UwU { uint16_t y1; // Draw a rectangle - void draw (Buffer buffer, Shader shader) { + template + void draw (Buffer buffer, ShaderBase& shader) { if (x0 > buffer.width || y0 > buffer.height || x1 > buffer.width || y1 > buffer.height) {return;}; - if (shader.shaderType == COLOR) { - for (uint16_t y = y0; y <= y1; y++) { - for (uint16_t x = x0; x <= x1; x++) { - buffer.drawPixel(x, y, shader.c0); - } - } - return; - - } else if (shader.shaderType == HGRADIENT) { - - // Precompute gradient LUT - Color cols[x1 - x0]; + for (uint16_t y = y0; y <= y1; y++) { for (uint16_t x = x0; x <= x1; x++) { - cols[x - x0] = ShaderMethods::gradient(shader.u0, shader.scale, shader.c0, shader.c1, x); + buffer.drawPixel(x, y, shader.shade(x, y)); } - - for (uint16_t y = y0; y <= y1; y++) { - for (uint16_t x = x0; x <= x1; x++) { - buffer.drawPixel(x, y, cols[x - x0]); - } - } - return; - - } else if (shader.shaderType == VGRADIENT) { - 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(x, y, c); - } - } - return; - - } else if (shader.shaderType == BUFFER) { - for (uint16_t y = y0; y <= y1; y++) { - for (uint16_t x = x0; x <= x1; x++) { - buffer.drawPixel(x, y, ShaderMethods::buffer(shader.u0, shader.v0, shader.buffer, x, y)); - } - } - return; } return; } diff --git a/shaders/colorshader.cpp b/shaders/colorshader.cpp index ad0ccc1..927410e 100644 --- a/shaders/colorshader.cpp +++ b/shaders/colorshader.cpp @@ -16,6 +16,8 @@ namespace UwU { Color c; Color shade(uint16_t x, uint16_t y) { + (void)x; + (void)y; return c; } }; diff --git a/shaders/hgradientshader.cpp b/shaders/hgradientshader.cpp new file mode 100644 index 0000000..f6bb993 --- /dev/null +++ b/shaders/hgradientshader.cpp @@ -0,0 +1,29 @@ +#pragma once + +#include + +#include "../datatypes.cpp" +#include "../helpers.cpp" +#include "../buffer.cpp" +#include "shaderbase.cpp" + +namespace UwU { + class HGradienthader : public ShaderBase { + public: + HGradientShader(uint16_t u0, uint16_t u1, Color c0, Color c1) { + this->u0; + this->uScale = 0xffffffff / (1 + (uint32_t)u1 - (uint32_t)u0); + this->c0 = c0; + this->c1 = c1; + } + uint16_t u0; + uint16_t uScale; + Color c0; + Color c1; + + Color shade(uint16_t u, uint16_t u) { + uint32_t t = (((uint32_t)u - (uint32_t)u0) * uScale) / 0x01000000; + return Helpers::lerpColor(c0, c1, (uint8_t)t); + } + }; +} \ No newline at end of file diff --git a/shaders/shaderbase.cpp b/shaders/shaderbase.cpp index fcccfbc..96aa1a5 100644 --- a/shaders/shaderbase.cpp +++ b/shaders/shaderbase.cpp @@ -7,11 +7,11 @@ #include "../buffer.cpp" namespace UwU { - template + template class ShaderBase { public: Color shade(uint16_t x, uint16_t y) { - return static_cast(this)->shade(x, y); + return static_cast(this)->shade(x, y); } }; } \ No newline at end of file diff --git a/shaders/vgradientshader.cpp b/shaders/vgradientshader.cpp new file mode 100644 index 0000000..29c664f --- /dev/null +++ b/shaders/vgradientshader.cpp @@ -0,0 +1,29 @@ +#pragma once + +#include + +#include "../datatypes.cpp" +#include "../helpers.cpp" +#include "../buffer.cpp" +#include "shaderbase.cpp" + +namespace UwU { + class VGradienthader : public ShaderBase { + public: + VGradientShader(uint16_t v0, uint16_t v1, Color c0, Color c1) { + this->v0; + this->vScale = 0xffffffff / (1 + (uint32_t)v1 - (uint32_t)v0); + this->c0 = c0; + this->c1 = c1; + } + uint16_t v0; + uint16_t vScale; + Color c0; + Color c1; + + Color shade(uint16_t u, uint16_t u) { + uint32_t t = (((uint32_t)v - (uint32_t)v0) * vScale) / 0x01000000; + return Helpers::lerpColor(c0, c1, (uint8_t)t); + } + }; +} \ No newline at end of file diff --git a/uwugl.h b/uwugl.h new file mode 100644 index 0000000..04f1ef9 --- /dev/null +++ b/uwugl.h @@ -0,0 +1,10 @@ +#include "datatypes.cpp" +#include "helpers.cpp" +#include "buffer.cpp" +#include "surface.cpp" +#include "primatives/line.cpp" +#include "primatives/point.cpp" +#include "primatives/rectangle.cpp" +#include "primatives/trapezoid.cpp" +#include "primatives/triangle.cpp" +#include "shader.cpp" \ No newline at end of file