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 70af5f6..89f3eaf 100755 Binary files a/example and b/example differ 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