diff --git a/TODO b/TODO index 137a585..67a30e5 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ [ ] write a monolithic header file [x] refactor example code using composition -[ ] remove draw class entirely +[x] remove draw class entirely [ ] create shader classes with polymorphism \ No newline at end of file diff --git a/buffer.cpp b/buffer.cpp index 419d0eb..2384b87 100644 --- a/buffer.cpp +++ b/buffer.cpp @@ -5,6 +5,8 @@ #include "datatypes.cpp" #include "helpers.cpp" #include "shaders/shader.cpp" +#include "shaders/colorshader.cpp" +#include "shaders/gradientshader.cpp" namespace UwU { // Buffer object - can be a wayland surface or a virtual buffer @@ -44,12 +46,12 @@ namespace UwU { return; } - void drawPixelShader(Coord2 coord, Shader shader) { - size_t i = (size_t)coord.y * stride + (size_t)coord.x * 4; + 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(); + 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); diff --git a/datatypes.cpp b/datatypes.cpp index 7ff0edd..ecbd130 100644 --- a/datatypes.cpp +++ b/datatypes.cpp @@ -36,22 +36,38 @@ namespace UwU { uint16_t y; }; - // // trapezoid datatype (horizontally constrained) - // struct Trapezoid { - // Trapezoid(uint16_t y0, uint16_t y1, uint16_t xl0, uint16_t xl1, uint16_t xr0, uint16_t xr1) { - // this->y0 = y0; - // this->y1 = y1; - // this->xl0 = xl0; - // this->xl1 = xl1; - // this->xr0 = xr0; - // this->xr1 = xr1; + // Vec2 datatype for signed x, y coordinates + struct Vec2 { + Vec2(int16_t x, int16_t y) { + this->x = x; + this->y = y; + } + Vec2() {} + int16_t x; + int16_t y; + }; + + // 2x2 matrix, Q15.16 signed fixed point + struct Matrix4 { + Matrix4(int32_t xx, int32_t xy, int32_t yx, int32_t yy) { + this->xx = xx; + this->xy = xy; + this->yx = yx; + this->yy = yy; + } + Matrix4() {} + int32_t xx; // x' = x*xx + y*xy + int32_t xy; + int32_t yx; // y' = x*yx + y*yy + int32_t yy; + }; + + // class Mapper { + // public: + // Mapper() { + // } - // Trapezoid() {} - // uint16_t y0; - // uint16_t y1; - // uint16_t xl0; - // uint16_t xl1; - // uint16_t xr0; - // uint16_t xr1; + // uint16_t *xxMap; + // }; } \ No newline at end of file diff --git a/example b/example index b09f128..70af5f6 100755 Binary files a/example and b/example differ diff --git a/example.cpp b/example.cpp index 2b12bf6..eb24798 100644 --- a/example.cpp +++ b/example.cpp @@ -18,6 +18,9 @@ #include "primatives/triangle.cpp" // #include "draw.cpp" #include "shaders/shader.cpp" +#include "shaders/colorshader.cpp" +#include "shaders/gradientshader.cpp" +#include "mapper.cpp" static void onKey(void *user, uint32_t keycode, uint32_t state) { if (keycode == 1) { @@ -31,18 +34,20 @@ 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::GradientShader fuchsia = UwU::GradientShader(UwU::Color(0xb00b69ff), UwU::Color(0xb00b6940)); + 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)); 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::Color alpha = UwU::Color(0x00000000); UwU::Surface surface = UwU::Surface(w, h, onKey); // draw.rainbow(); UwU::Rectangle rectangle = UwU::Rectangle(69, 69, 420, 420); - rectangle.draw(surface.buffer, fuchsia); + rectangle.draw(surface.buffer, rectMapper, fuchsia); // draw.rectangleGradient(UwU::Coord2(200, 200), UwU::Coord2(600, 400), red, blue, alpha, red); diff --git a/mapper.cpp b/mapper.cpp new file mode 100644 index 0000000..4b8a26c --- /dev/null +++ b/mapper.cpp @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include +#include + +#include "datatypes.cpp" +#include "helpers.cpp" + +namespace UwU { + class Mapper { + public: + Mapper(Vec2 offset, Vec2 origin, Matrix4 transformation) { + this->offset = offset; + this->origin = origin; + this->transformation = transformation; + } + Vec2 offset; // offset (translation) + Vec2 origin; // origin (for rotation, etc) + Matrix4 transformation; // transformation matrix (for rotation, translation, etc) + + Coord2 map(Coord2 input) { + int64_t x1 = (int64_t)transformation.xx * ((int64_t)input.x - (int64_t)origin.x); + x1 += (int64_t)transformation.xy * ((int64_t)input.y - (int64_t)origin.y); + x1 = x1 / 65536; + x1 += origin.x; + x1 += offset.x; + int64_t y1 = (int64_t)transformation.yx * ((int64_t)input.x - (int64_t)origin.x); + y1 += (int64_t)transformation.yy * ((int64_t)input.y - (int64_t)origin.y); + y1 = y1 / 65536; + y1 += origin.y; + y1 += offset.y; + return Coord2((uint16_t)x1, (uint16_t)y1); + } + }; +} \ No newline at end of file diff --git a/primatives/rectangle.cpp b/primatives/rectangle.cpp index b038055..64598e4 100644 --- a/primatives/rectangle.cpp +++ b/primatives/rectangle.cpp @@ -6,6 +6,9 @@ #include "../helpers.cpp" #include "../buffer.cpp" #include "../shaders/shader.cpp" +#include "../shaders/colorshader.cpp" +#include "../shaders/gradientshader.cpp" +#include "../mapper.cpp" namespace UwU { // rectangle @@ -24,11 +27,14 @@ namespace UwU { uint16_t y1; // Draw a rectangle - void draw (Buffer buffer, Shader shader) { + void draw (Buffer buffer, Mapper mapper, Shader& 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(); for (uint16_t y = y0; y < y1; y++) { for (uint16_t x = x0; x < x1; x++) { - buffer.drawPixelShader(Coord2(x, y), shader); + uv = mapper.map(Coord2(x, y)); + buffer.drawPixelShader(x, y, uv.x, uv.y, shader); } } return; diff --git a/shaders/colorshader.cpp b/shaders/colorshader.cpp new file mode 100644 index 0000000..baea2fb --- /dev/null +++ b/shaders/colorshader.cpp @@ -0,0 +1,25 @@ +#pragma once + +#include + +#include "../datatypes.cpp" +#include "../helpers.cpp" +#include "../buffer.cpp" +#include "shader.cpp" + +namespace UwU { + class ColorShader : public Shader { + public: + ColorShader(Color color) { + this->shaderColor = color; + } + + Color shaderColor; + + Color color(uint16_t u, uint16_t v) override { + (void)u; + (void)v; + return shaderColor; + } + }; +} \ No newline at end of file diff --git a/shaders/gradientshader.cpp b/shaders/gradientshader.cpp new file mode 100644 index 0000000..267ce20 --- /dev/null +++ b/shaders/gradientshader.cpp @@ -0,0 +1,29 @@ +#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/shader.cpp b/shaders/shader.cpp index a9e6cf2..8f776cb 100644 --- a/shaders/shader.cpp +++ b/shaders/shader.cpp @@ -12,8 +12,10 @@ namespace UwU { public: Shader() {} - Color color() { - return Color(0xb00b69ff); + virtual Color color(uint16_t u, uint16_t v) { + (void)u; + (void)v; + return Color(); } }; } \ No newline at end of file