From bb30e2df0be22794cfab3b25be6f8bc19400cab1 Mon Sep 17 00:00:00 2001 From: Annika Date: Wed, 8 Jul 2026 19:44:37 -0700 Subject: [PATCH] brute forced text support, fixed an off-by one, lots to fix --- TODO | 9 ++++--- buffer.cpp | 3 +-- example | Bin 41192 -> 45552 bytes example.cpp | 49 ++++++++++++++++++++++++++++++++++++--- font.cpp | 44 +++++++++++++++++++++++++++++++++++ primatives/rectangle.cpp | 18 +++++++------- 6 files changed, 106 insertions(+), 17 deletions(-) create mode 100644 font.cpp diff --git a/TODO b/TODO index 69620c9..ce0fb89 100644 --- a/TODO +++ b/TODO @@ -3,6 +3,9 @@ [x] remove draw class entirely [x] create shader classes with polymorphism [x] optimize shader/primative performance (repeat myself!) -[ ] finish implementing gradient shaders to primatives -[ ] implement buffer shader -[ ] implement more primatives \ No newline at end of file +[x] finish implementing gradient shaders to primatives +[x] implement buffer shader +[ ] implement more primatives +[ ] fix off by one with buffer shader (and probably certain primatives) +[ ] fix memory leak and arrays in stack issue +[ ] fix shader offset limitations and headache \ No newline at end of file diff --git a/buffer.cpp b/buffer.cpp index ddbe894..d9c7016 100644 --- a/buffer.cpp +++ b/buffer.cpp @@ -11,8 +11,7 @@ namespace UwU { class Buffer { public: Buffer(uint16_t width, uint16_t height) { - uint8_t pixels[width * height * 4]; - this->pixels = pixels; + this->pixels = new uint8_t[width * height * 4]; this->width = width; this->height = height; this->stride = width * 4; diff --git a/example b/example index 106f820f8b890e1b57f3933cbd0e9e8499ac3bb8..5fd8bb351b4fa728e24e9e6bd19f654cdcf53ef5 100755 GIT binary patch literal 45552 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 QF-kkzIW^uSU?P?O1yDRpC;$Ke literal 41192 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 +#include "font.cpp" + static void onKey(void *user, uint32_t keycode, uint32_t state) { if (keycode == 1) { exit(1); @@ -34,10 +36,10 @@ 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, 100, 469, UwU::Color(0xff0000ff), UwU::Color(0x0000ffff)); - UwU::Shader aqua = UwU::Shader(UwU::Direction::V, 4, 475, UwU::Color(0x00ff00ff), UwU::Color(0x0000ffff)); + 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::Color green = UwU::Color(0x00ff00ff); + UwU::Shader green = UwU::Shader(UwU::Color(0x00ff00ff)); UwU::Color blue = UwU::Color(0x0000ff80); // UwU::Color alpha = UwU::Color(0x00000000); @@ -51,6 +53,47 @@ int main(void) { 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); // Benchmarking diff --git a/font.cpp b/font.cpp new file mode 100644 index 0000000..58b8128 --- /dev/null +++ b/font.cpp @@ -0,0 +1,44 @@ +#pragma once + +#include + +#include "buffer.cpp" + + + +UwU::Buffer font() { + const uint32_t fontInt[9] = { + 0xcc003f00, + 0xcc004300, + 0xcf33c300, + 0xcf33c300, + 0xcf33df00, + 0xcf33cf00, + 0xcf33cf00, + 0xcf33cf00, + 0x7ffeffe0 + }; + + UwU::Buffer font = UwU::Buffer(32, 9); + uint32_t t; + uint32_t b; + for (uint16_t y = 0; y < 9; y++) { + t = fontInt[y]; + for (uint16_t x = 0; x < 32; x++) { + b = t & 0x80000000; + if (b == 0x80000000) { + font.pixels[(y * 128) + (x * 4) + 0] = 0xff; + font.pixels[(y * 128) + (x * 4) + 1] = 0xff; + font.pixels[(y * 128) + (x * 4) + 2] = 0xff; + font.pixels[(y * 128) + (x * 4) + 3] = 0xff; + } else { + font.pixels[(y * 128) + (x * 4) + 0] = 0x00; + font.pixels[(y * 128) + (x * 4) + 1] = 0x00; + font.pixels[(y * 128) + (x * 4) + 2] = 0x00; + font.pixels[(y * 128) + (x * 4) + 3] = 0x00; + } + t = t << 1; + } + } + return font; +} \ No newline at end of file diff --git a/primatives/rectangle.cpp b/primatives/rectangle.cpp index 1f26ac3..a6d15e0 100644 --- a/primatives/rectangle.cpp +++ b/primatives/rectangle.cpp @@ -27,8 +27,8 @@ namespace UwU { void draw (Buffer buffer, Shader 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++) { + for (uint16_t y = y0; y <= y1; y++) { + for (uint16_t x = x0; x <= x1; x++) { buffer.drawPixel(x, y, shader.c0); } } @@ -38,29 +38,29 @@ namespace UwU { // Precompute gradient LUT Color cols[x1 - x0]; - for (uint16_t x = x0; x < x1; x++) { + 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++) { + 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++) { + 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++) { + 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++) { + 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)); } }