From 85cfdaab49947b44213e7173e1c654552a2e633c Mon Sep 17 00:00:00 2001 From: Annika Date: Tue, 7 Jul 2026 17:57:25 -0700 Subject: [PATCH] added shaders, but ran into performance issues. will need refactor --- Makefile | 2 +- TODO | 3 +- buffer.cpp | 54 +++++++++++++++++++----------------- example | Bin 37424 -> 37032 bytes example.cpp | 39 ++++++++++++++++++-------- mapper.cpp | 2 +- primatives/rectangle.cpp | 16 +++++++---- shaders/colorshader.cpp | 4 +-- shaders/gradientshader.cpp | 29 ------------------- shaders/hgradientshader.cpp | 33 ++++++++++++++++++++++ shaders/shader.cpp | 2 +- shaders/vgradientshader.cpp | 33 ++++++++++++++++++++++ 12 files changed, 139 insertions(+), 78 deletions(-) delete mode 100644 shaders/gradientshader.cpp create mode 100644 shaders/hgradientshader.cpp create mode 100644 shaders/vgradientshader.cpp diff --git a/Makefile b/Makefile index 38e1f19..968b17b 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC ?= gcc -CFLAGS := -Wall -Wextra -O2 $(shell pkg-config --cflags wayland-client 2>/dev/null) +CFLAGS := -Wall -Wextra -O3 $(shell pkg-config --cflags wayland-client 2>/dev/null) LDFLAGS := $(shell pkg-config --libs wayland-client 2>/dev/null) # Fallback if pkg-config is unavailable or returns nothing. diff --git a/TODO b/TODO index 67a30e5..056bbac 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,5 @@ [ ] write a monolithic header file [x] refactor example code using composition [x] remove draw class entirely -[ ] create shader classes with polymorphism \ No newline at end of file +[x] create shader classes with polymorphism +[ ] optimize shader/primative performance (repeat myself!) \ No newline at end of file diff --git a/buffer.cpp b/buffer.cpp index 2384b87..c873c55 100644 --- a/buffer.cpp +++ b/buffer.cpp @@ -6,7 +6,9 @@ #include "helpers.cpp" #include "shaders/shader.cpp" #include "shaders/colorshader.cpp" -#include "shaders/gradientshader.cpp" +// #include "shaders/gradientshader.cpp" +#include "shaders/hgradientshader.cpp" +#include "shaders/vgradientshader.cpp" namespace UwU { // Buffer object - can be a wayland surface or a virtual buffer @@ -32,34 +34,36 @@ namespace UwU { uint16_t stride; void drawPixel(Coord2 coord, Color color) { + if (color.a == 0) {return;} size_t i = (size_t)coord.y * stride + (size_t)coord.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, color.b, color.a); - uint8_t g = Helpers::lerp8(g0, color.g, color.a); - uint8_t r = Helpers::lerp8(r0, color.r, color.a); - pixels[i + 0] = b; // B - pixels[i + 1] = g; // G - pixels[i + 2] = r; // R + // uint8_t b0 = pixels[i + 0]; + // uint8_t g0 = pixels[i + 1]; + // uint8_t r0 = pixels[i + 2]; + // uint8_t b = Helpers::lerp8(b0, color.b, color.a); + // uint8_t g = Helpers::lerp8(g0, color.g, color.a); + // uint8_t r = Helpers::lerp8(r0, color.r, color.a); + pixels[i + 0] = color.b; // B + pixels[i + 1] = color.g; // G + pixels[i + 2] = color.r; // R pixels[i + 3] = 0xff; // A return; } - void drawPixelShader(uint16_t x, uint16_t y, uint16_t u, uint16_t v, Shader& shader) { - 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]; - Color newColor = shader.color(u, v); - 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] = b; // B - pixels[i + 1] = g; // G - pixels[i + 2] = r; // R - 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 70af5f66db091e0bf3120513fbd57d61a9922b21..89f3eaf521779d3d778735f4f832845b2b55719b 100755 GIT binary patch literal 37032 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 literal 37424 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≶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 W#%L`$U3LaR2U(K2P)ne(#=ijq_Vo?` diff --git a/example.cpp b/example.cpp index eb24798..4de2243 100644 --- a/example.cpp +++ b/example.cpp @@ -19,8 +19,12 @@ // #include "draw.cpp" #include "shaders/shader.cpp" #include "shaders/colorshader.cpp" -#include "shaders/gradientshader.cpp" -#include "mapper.cpp" +// #include "shaders/gradientshader.cpp" +#include "shaders/hgradientshader.cpp" +#include "shaders/vgradientshader.cpp" +// #include "mapper.cpp" + +#include static void onKey(void *user, uint32_t keycode, uint32_t state) { if (keycode == 1) { @@ -34,26 +38,36 @@ static void onKey(void *user, uint32_t keycode, uint32_t state) { int main(void) { uint16_t w = 800, h = 480; - UwU::GradientShader fuchsia = UwU::GradientShader(UwU::Color(0xb00b69ff), UwU::Color(0xb00b6940)); + // UwU::GradientShader fuchsia = UwU::GradientShader(UwU::Color(0xb00b69ff), UwU::Color(0xb00b6940)); + // UwU::ColorShader fuchsia = UwU::ColorShader(UwU::Color(0xb00b69ff)); + UwU::VGradientShader fuchsia = UwU::VGradientShader(69, UwU::Color(0xb00b69ff), 420, UwU::Color(0x00000000)); int32_t rectScale = (255 * 65536) / 351; - UwU::Mapper rectMapper = UwU::Mapper(UwU::Vec2(-69, 0), UwU::Vec2(69, 0), UwU::Matrix4(rectScale, 0, 0, 1)); + // rectScale = 41233; //-23806 + // UwU::Mapper rectMapper = UwU::Mapper(UwU::Vec2(0, 0), UwU::Vec2(0, 0), UwU::Matrix4(0, 0, 0, 0)); UwU::Color red = UwU::Color(0xff000080); UwU::Color green = UwU::Color(0x00ff00ff); UwU::Color blue = UwU::Color(0x0000ff80); // UwU::Color alpha = UwU::Color(0x00000000); - + UwU::Surface surface = UwU::Surface(w, h, onKey); - - // draw.rainbow(); - + // UwU::Buffer buffer = UwU::Buffer(surface.getWidth(), surface.getHeight()); + UwU::Rectangle rectangle = UwU::Rectangle(69, 69, 420, 420); - rectangle.draw(surface.buffer, rectMapper, fuchsia); - + // draw.rainbow(); + + // draw.rectangleGradient(UwU::Coord2(200, 200), UwU::Coord2(600, 400), red, blue, alpha, red); - + + struct timespec start, end; + clock_gettime(CLOCK_MONOTONIC, &start); + rectangle.draw(surface.buffer, fuchsia); + clock_gettime(CLOCK_MONOTONIC, &end); + long elapsed_ns = (end.tv_sec - start.tv_sec) * 1000000000L + + (end.tv_nsec - start.tv_nsec); + printf("Elapsed: %ld ns\n", elapsed_ns); + 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); @@ -75,6 +89,7 @@ int main(void) { lines[i].draw(surface.buffer, green); } + surface.present(); while (!surface.shouldClose()) {} diff --git a/mapper.cpp b/mapper.cpp index 4b8a26c..eb81534 100644 --- a/mapper.cpp +++ b/mapper.cpp @@ -31,7 +31,7 @@ namespace UwU { y1 = y1 / 65536; y1 += origin.y; y1 += offset.y; - return Coord2((uint16_t)x1, (uint16_t)y1); + return Coord2((uint16_t)x1, (uint16_t)0); } }; } \ No newline at end of file diff --git a/primatives/rectangle.cpp b/primatives/rectangle.cpp index 64598e4..5a3daf5 100644 --- a/primatives/rectangle.cpp +++ b/primatives/rectangle.cpp @@ -7,8 +7,10 @@ #include "../buffer.cpp" #include "../shaders/shader.cpp" #include "../shaders/colorshader.cpp" -#include "../shaders/gradientshader.cpp" -#include "../mapper.cpp" +// #include "../shaders/gradientshader.cpp" +#include "../shaders/hgradientshader.cpp" +#include "../shaders/vgradientshader.cpp" +// #include "../mapper.cpp" namespace UwU { // rectangle @@ -27,14 +29,16 @@ namespace UwU { uint16_t y1; // Draw a rectangle - void draw (Buffer buffer, Mapper mapper, Shader& shader) { + template + void draw (Buffer buffer, ShaderType& shader) { // printf("color: %u, %u, %u, %u", shader.color().r, shader.color().g, shader.color().b, shader.color().a); if (x0 > buffer.width || y0 > buffer.height || x1 > buffer.width || y1 > buffer.height) {return;}; - Coord2 uv = Coord2(); + // Coord2 uv = Coord2(); for (uint16_t y = y0; y < y1; y++) { for (uint16_t x = x0; x < x1; x++) { - uv = mapper.map(Coord2(x, y)); - buffer.drawPixelShader(x, y, uv.x, uv.y, shader); + // uv = mapper.map(Coord2(x, y)); + Color c = shader.color(x, y); + buffer.drawPixel(Coord2(x, y), c); } } return; diff --git a/shaders/colorshader.cpp b/shaders/colorshader.cpp index baea2fb..eef2bde 100644 --- a/shaders/colorshader.cpp +++ b/shaders/colorshader.cpp @@ -8,7 +8,7 @@ #include "shader.cpp" namespace UwU { - class ColorShader : public Shader { + class ColorShader { public: ColorShader(Color color) { this->shaderColor = color; @@ -16,7 +16,7 @@ namespace UwU { Color shaderColor; - Color color(uint16_t u, uint16_t v) override { + Color color(uint16_t u, uint16_t v) { (void)u; (void)v; return shaderColor; diff --git a/shaders/gradientshader.cpp b/shaders/gradientshader.cpp deleted file mode 100644 index 267ce20..0000000 --- a/shaders/gradientshader.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -#include "../datatypes.cpp" -#include "../helpers.cpp" -#include "../buffer.cpp" -#include "shader.cpp" - -namespace UwU { - class GradientShader : public Shader { - public: - GradientShader(Color color0, Color color1) { - // this->x0 = x0; - this->shaderColor0 = color0; - // this->x1 = x1; - this->shaderColor1 = color1; - } - // uint16_t x0; - Color shaderColor0; - // uint16_t x1; - Color shaderColor1; - - Color color(uint16_t u, uint16_t v) override { - (void)v; - return Helpers::lerpColor(shaderColor0, shaderColor1, u); - } - }; -} \ No newline at end of file diff --git a/shaders/hgradientshader.cpp b/shaders/hgradientshader.cpp new file mode 100644 index 0000000..85e15ab --- /dev/null +++ b/shaders/hgradientshader.cpp @@ -0,0 +1,33 @@ +#pragma once + +#include + +#include "../datatypes.cpp" +#include "../helpers.cpp" +#include "../buffer.cpp" +#include "shader.cpp" + +namespace UwU { + class HGradientShader{ + public: + HGradientShader(uint16_t x0, Color color0, uint16_t x1, Color color1) { + this->x0 = x0; + this->shaderColor0 = color0; + this->scale = 0xffffffff / (1 + (uint32_t)x1 - (uint32_t)x0); + this->shaderColor1 = color1; + } + uint16_t x0; + Color shaderColor0; + uint32_t scale; + Color shaderColor1; + + Color color(uint16_t u, uint16_t v) { + (void)v; + uint32_t t = (((uint32_t)u - (uint32_t)x0) * scale) / 0x01000000; + // if (v == 42) { + // printf("(%u, %u)\n", u, t); + // } + return Helpers::lerpColor(shaderColor0, shaderColor1, (uint8_t)t); + } + }; +} \ No newline at end of file diff --git a/shaders/shader.cpp b/shaders/shader.cpp index 8f776cb..dabab4a 100644 --- a/shaders/shader.cpp +++ b/shaders/shader.cpp @@ -12,7 +12,7 @@ namespace UwU { public: Shader() {} - virtual Color color(uint16_t u, uint16_t v) { + Color color(uint16_t u, uint16_t v) { (void)u; (void)v; return Color(); diff --git a/shaders/vgradientshader.cpp b/shaders/vgradientshader.cpp new file mode 100644 index 0000000..04553de --- /dev/null +++ b/shaders/vgradientshader.cpp @@ -0,0 +1,33 @@ +#pragma once + +#include + +#include "../datatypes.cpp" +#include "../helpers.cpp" +#include "../buffer.cpp" +#include "shader.cpp" + +namespace UwU { + class VGradientShader { + public: + VGradientShader(uint16_t y0, Color color0, uint16_t y1, Color color1) { + this->y0 = y0; + this->shaderColor0 = color0; + this->scale = 0xffffffff / (1 + (uint32_t)y1 - (uint32_t)y0); + this->shaderColor1 = color1; + } + uint16_t y0; + Color shaderColor0; + uint32_t scale; + Color shaderColor1; + + Color color(uint16_t u, uint16_t v) { + (void)u; + uint32_t t = (((uint32_t)v - (uint32_t)y0) * scale) / 0x01000000; + // if (v == 42) { + // printf("(%u, %u)\n", u, t); + // } + return Helpers::lerpColor(shaderColor0, shaderColor1, (uint8_t)t); + } + }; +} \ No newline at end of file