From 1c2579148e93c3220b6ff40705d02df561ac5cf9 Mon Sep 17 00:00:00 2001 From: Annika Date: Sat, 25 Jul 2026 23:47:54 -0700 Subject: [PATCH] moved textures into their own classes, better tilemapping --- example | Bin 37000 -> 37000 bytes example.cpp | 36 +++++++++++++++++----------------- mappers/mappers.h | 2 +- primatives/line.cpp | 26 ++++++++++++------------ primatives/point.cpp | 8 ++++---- primatives/primatives.h | 5 +++++ primatives/rectangle.cpp | 8 ++++---- primatives/trapezoid.cpp | 8 ++++---- primatives/triangle.cpp | 10 +++++----- textures/bitmaptexture.cpp | 26 ++++++++++++++++++++++++ textures/colortexture.cpp | 26 ++++++++++++++++++++++++ textures/gradienttexture.cpp | 28 ++++++++++++++++++++++++++ textures/hgradienttexture.cpp | 28 ++++++++++++++++++++++++++ textures/texturebase.cpp | 17 ++++++++++++++++ textures/textures.h | 7 +++++++ textures/tilemaptexture.cpp | 30 ++++++++++++++++++++++++++++ textures/vgradienttexture.cpp | 28 ++++++++++++++++++++++++++ tilemap.cpp | 28 ++++++++++++++++++++++++++ uwugl.h | 12 +++++------- 19 files changed, 277 insertions(+), 56 deletions(-) create mode 100644 primatives/primatives.h create mode 100644 textures/bitmaptexture.cpp create mode 100644 textures/colortexture.cpp create mode 100644 textures/gradienttexture.cpp create mode 100644 textures/hgradienttexture.cpp create mode 100644 textures/texturebase.cpp create mode 100644 textures/textures.h create mode 100644 textures/tilemaptexture.cpp create mode 100644 textures/vgradienttexture.cpp create mode 100644 tilemap.cpp diff --git a/example b/example index 0609a4640feca7a989a0d59b26133ca5ada9360f..9bda96933396b827f9dc7bc1cade43b838002c7c 100755 GIT binary patch delta 134 zcmeBJ$kefrX~PU=k4`e zT^V*T1DR=#ovs`&u5vK|g${Tee5J5C$@mc?|x^&0ssr|F0KFo delta 134 zcmV;10D1q2p#q4Z0K)3u(PZKk}o9a?Fs+@Nr}Kn z!RjDLxBvhV0RR9Z0!fKQ0Jt*)003q|iA4yrVl(0a0r;~;HPiwF!4_<@960>}1Hl$- olN>r;0nw9tI;{>wJpe?Dt#tqY|3r;660 @@ -43,31 +43,31 @@ int main(void) { UwU::Color green = UwU::Color(0x00ff00ff); UwU::Color blue = UwU::Color(0x0000ffff); - // UwU::ColorShader fuchsia = UwU::ColorShader(UwU::Color(0xb00b69ff)); - UwU::HGradientShader bisexual = UwU::HGradientShader(0, 179, red, blue); - UwU::TileMapper tileMapper = UwU::TileMapper(); + // UwU::ColorTexture fuchsia = UwU::ColorTexture(UwU::Color(0xb00b69ff)); + UwU::HGradientTexture bisexual = UwU::HGradientTexture(180, red, blue); + UwU::OffsetMapper offsetMapper = UwU::OffsetMapper(); + UwU::Tilemap myTilemap = UwU::Tilemap(); + myTilemap.tilemap[0] = 0x0000; + myTilemap.tilemap[1] = 0x0001; + myTilemap.tilemap[2] = 0x0000; + myTilemap.tilemap[3] = 0x0002; + myTilemap.tilemap[4] = 0x0003; UwU::Buffer fontBuffer = font(); - UwU::BufferShader textMap = UwU::BufferShader(fontBuffer); - tileMapper.tileMap[0] = 0x0000; - tileMapper.tileMap[1] = 0x0111; - tileMapper.tileMap[2] = 0x0000; - tileMapper.tileMap[3] = 0x0222; - tileMapper.tileMap[4] = 0x0333; + UwU::TilemapTexture textMap = UwU::TilemapTexture(myTilemap, fontBuffer); UwU::Rectangle rectangle = UwU::Rectangle(69, 69, 420, 420); - rectangle.draw(surface.buffer, tileMapper, textMap); + rectangle.draw(surface.buffer, offsetMapper, textMap); - UwU::ColorShader greenShader = UwU::ColorShader(green); + UwU::ColorTexture greenTexture = UwU::ColorTexture(green); UwU::NullMapper nullMapper = UwU::NullMapper(); UwU::Point point = UwU::Point(187, 37); - point.draw(surface.buffer, nullMapper, greenShader); + point.draw(surface.buffer, nullMapper, greenTexture); - UwU::ColorShader blueShader = UwU::ColorShader(blue); + UwU::ColorTexture blueTexture = UwU::ColorTexture(blue); UwU::Trapezoid trapezoid = UwU::Trapezoid(100, 300, 690, 320, 720, 780); - trapezoid.draw(surface.buffer, nullMapper, blueShader); + trapezoid.draw(surface.buffer, nullMapper, blueTexture); - UwU::ColorShader redShader = UwU::ColorShader(red); + UwU::ColorTexture redTexture = UwU::ColorTexture(red); UwU::Triangle triangle = UwU::Triangle(140, 140, 60, 400, 240, 240); - UwU::OffsetMapper offsetMapper = UwU::OffsetMapper(); triangle.draw(surface.buffer, offsetMapper, bisexual); // // Benchmarking @@ -109,7 +109,7 @@ int main(void) { }; for (uint16_t i = 0; i < 8; i++) { - lines[i].draw(surface.buffer, nullMapper, blueShader); + lines[i].draw(surface.buffer, nullMapper, blueTexture); } diff --git a/mappers/mappers.h b/mappers/mappers.h index 90c660d..0af3532 100644 --- a/mappers/mappers.h +++ b/mappers/mappers.h @@ -1,4 +1,4 @@ #include "mapperbase.cpp" #include "nullmapper.cpp" #include "offsetmapper.cpp" -#include "tilemapper.cpp" \ No newline at end of file +// #include "tilemapper.cpp" \ No newline at end of file diff --git a/primatives/line.cpp b/primatives/line.cpp index 69cfb61..553f008 100644 --- a/primatives/line.cpp +++ b/primatives/line.cpp @@ -5,16 +5,16 @@ #include "../datatypes.cpp" #include "../helpers.cpp" #include "../buffer.cpp" -#include "../shaders/shaders.h" #include "../mappers/mappers.h" +#include "../textures/textures.h" namespace UwU { // line class Line { private: // plot lines if m <= 1 - template - void lineLow(int16_t ix0, int16_t iy0, int16_t ix1, int16_t iy1, Buffer buffer, MapperBase& mapper, ShaderBase& shader) { + template + void lineLow(int16_t ix0, int16_t iy0, int16_t ix1, int16_t iy1, Buffer buffer, MapperBase& mapper, TextureBase& texture) { int16_t dx = ix1 - ix0; int16_t dy = iy1 - iy0; int16_t yi = 1; @@ -29,7 +29,7 @@ namespace UwU { for (int16_t x = ix0; x < ix1; x++) { uv = mapper.map(ix0, iy0, x, y); - buffer.drawPixel((uint16_t)x, (uint16_t)y, shader.shade(uv.x, uv.y)); + buffer.drawPixel((uint16_t)x, (uint16_t)y, texture.texel(uv.x, uv.y)); if (d > 0) { y += yi; d += (2 * (dy - dx)); @@ -41,8 +41,8 @@ namespace UwU { } // plot lines if m >1 - template - void lineHigh(int16_t ix0, int16_t iy0, int16_t ix1, int16_t iy1, Buffer buffer, MapperBase& mapper, ShaderBase& shader) { + template + void lineHigh(int16_t ix0, int16_t iy0, int16_t ix1, int16_t iy1, Buffer buffer, MapperBase& mapper, TextureBase& texture) { int16_t dx = ix1 - ix0; int16_t dy = iy1 - iy0; int16_t xi = 1; @@ -57,7 +57,7 @@ namespace UwU { for (int16_t y = iy0; y < iy1; y++) { uv = mapper.map(ix0, iy0, x, y); - buffer.drawPixel((uint16_t)x, (uint16_t)y, shader.shade(uv.x, uv.y)); + buffer.drawPixel((uint16_t)x, (uint16_t)y, texture.texel(uv.x, uv.y)); if (d > 0) { x += xi; d += (2 * (dx - dy)); @@ -82,8 +82,8 @@ namespace UwU { uint16_t y1; // Uses Bresenham's line algorithm to draw line of any slope - template - void draw (Buffer buffer, MapperBase& mapper, ShaderBase& shader) { + template + void draw (Buffer buffer, MapperBase& mapper, TextureBase& texture) { if (x0 > buffer.width || y0 > buffer.height || x1 > buffer.width || y1 > buffer.height) {return;}; int16_t ix0 = x0; int16_t iy0 = y0; @@ -91,15 +91,15 @@ namespace UwU { int16_t iy1 = y1; if (abs(iy1 - iy0) < abs(ix1 - ix0)) { if (ix0 > ix1) { - lineLow(ix1, iy1, ix0, iy0, buffer, mapper, shader); + lineLow(ix1, iy1, ix0, iy0, buffer, mapper, texture); } else { - lineLow(ix0, iy0, ix1, iy1, buffer, mapper, shader); + lineLow(ix0, iy0, ix1, iy1, buffer, mapper, texture); } } else { if (iy0 > iy1) { - lineHigh(ix1, iy1, ix0, iy0, buffer, mapper, shader); + lineHigh(ix1, iy1, ix0, iy0, buffer, mapper, texture); } else { - lineHigh(ix0, iy0, ix1, iy1, buffer, mapper, shader); + lineHigh(ix0, iy0, ix1, iy1, buffer, mapper, texture); } } return; diff --git a/primatives/point.cpp b/primatives/point.cpp index 54fbc0b..13ee1cf 100644 --- a/primatives/point.cpp +++ b/primatives/point.cpp @@ -5,8 +5,8 @@ #include "../datatypes.cpp" #include "../helpers.cpp" #include "../buffer.cpp" -#include "../shaders/shaders.h" #include "../mappers/mappers.h" +#include "../textures/textures.h" namespace UwU { // point @@ -21,11 +21,11 @@ namespace UwU { uint16_t y; // Draw a point - template - void draw (Buffer buffer, MapperBase& mapper, ShaderBase& shader) { + template + void draw (Buffer buffer, MapperBase& mapper, TextureBase& texture) { if (x > buffer.width || y > buffer.height) {return;}; Coord2 uv = mapper.map(x, y, x, y); - buffer.drawPixel(x, y, shader.shade(uv.x, uv.y)); + buffer.drawPixel(x, y, texture.texel(uv.x, uv.y)); return; } }; diff --git a/primatives/primatives.h b/primatives/primatives.h new file mode 100644 index 0000000..0727129 --- /dev/null +++ b/primatives/primatives.h @@ -0,0 +1,5 @@ +#include "point.cpp" +#include "line.cpp" +#include "rectangle.cpp" +#include "trapezoid.cpp" +#include "triangle.cpp" \ No newline at end of file diff --git a/primatives/rectangle.cpp b/primatives/rectangle.cpp index e7d5c66..9d1025c 100644 --- a/primatives/rectangle.cpp +++ b/primatives/rectangle.cpp @@ -5,8 +5,8 @@ #include "../datatypes.cpp" #include "../helpers.cpp" #include "../buffer.cpp" -#include "../shaders/shaders.h" #include "../mappers/mappers.h" +#include "../textures/textures.h" namespace UwU { // rectangle @@ -25,13 +25,13 @@ namespace UwU { uint16_t y1; // Draw a rectangle - template - void draw (Buffer buffer, MapperBase& mapper, ShaderBase& shader) { + template + void draw (Buffer buffer, MapperBase& mapper, TextureBase& texture) { if (x0 > buffer.width || y0 > buffer.height || x1 > buffer.width || y1 > buffer.height) {return;}; for (uint16_t y = y0; y <= y1; y++) { for (uint16_t x = x0; x <= x1; x++) { Coord2 uv = mapper.map(x0, y0, x, y); - buffer.drawPixel(x, y, shader.shade(uv.x, uv.y)); + buffer.drawPixel(x, y, texture.texel(uv.x, uv.y)); } } return; diff --git a/primatives/trapezoid.cpp b/primatives/trapezoid.cpp index ab268bb..337a2f5 100644 --- a/primatives/trapezoid.cpp +++ b/primatives/trapezoid.cpp @@ -6,8 +6,8 @@ #include "../datatypes.cpp" #include "../helpers.cpp" #include "../buffer.cpp" -#include "../shaders/shaders.h" #include "../mappers/mappers.h" +#include "../textures/textures.h" namespace UwU { // trapezoid (horizontally constrained) @@ -31,8 +31,8 @@ namespace UwU { // Draw a horizontally bounded trapezoid // y1 >= y0 - template - void draw (Buffer buffer, MapperBase& mapper, ShaderBase& shader) { + template + void draw (Buffer buffer, MapperBase& mapper, TextureBase& texture) { uint16_t height = 1 + y1 - y0; int16_t LeftBound[height]; int16_t RightBound[height]; @@ -45,7 +45,7 @@ namespace UwU { for (uint16_t i = 0; i < height; i++) { for (uint16_t x = LeftBound[i]; x <= RightBound[i]; x++) { Coord2 uv = mapper.map(x0, y0, x, i + y0); - buffer.drawPixel(x, i + y0, shader.shade(uv.x, uv.y)); + buffer.drawPixel(x, i + y0, texture.texel(uv.x, uv.y)); } } return; diff --git a/primatives/triangle.cpp b/primatives/triangle.cpp index 6d2c07f..7d948d8 100644 --- a/primatives/triangle.cpp +++ b/primatives/triangle.cpp @@ -6,8 +6,8 @@ #include "../datatypes.cpp" #include "../helpers.cpp" #include "../buffer.cpp" -#include "../shaders/shaders.h" #include "../mappers/mappers.h" +#include "../textures/textures.h" namespace UwU { class Triangle { @@ -31,8 +31,8 @@ namespace UwU { uint16_t y2; // Draw a triangle - template - void draw (Buffer buffer, MapperBase& mapper, ShaderBase& shader) { + template + void draw (Buffer buffer, MapperBase& mapper, TextureBase& texture) { uint16_t topX, topY, midX, midY, btmX, btmY; // Find top, middle and bottom points of triangle if (y0 <= y1 && y0 <= y2) { @@ -100,7 +100,7 @@ namespace UwU { for (uint16_t i = 0; i < height; i++) { for (uint16_t x = (uint16_t)splitBound[i]; x <= (uint16_t)longBound[i]; x++) { uv = mapper.map(leftX, topY, x, i + (uint16_t)topY); - buffer.drawPixel(x, i + (uint16_t)topY, shader.shade(uv.x, uv.y)); + buffer.drawPixel(x, i + (uint16_t)topY, texture.texel(uv.x, uv.y)); } } // Right-handed triangle case (midpoint is right of triangle) @@ -108,7 +108,7 @@ namespace UwU { for (uint16_t i = 0; i < height; i++) { for (uint16_t x = (uint16_t)longBound[i]; x <= (uint16_t)splitBound[i]; x++) { uv = mapper.map(leftX, topY, x, i + (uint16_t)topY); - buffer.drawPixel(x, i + (uint16_t)topY, shader.shade(uv.x, uv.y)); + buffer.drawPixel(x, i + (uint16_t)topY, texture.texel(uv.x, uv.y)); } } } diff --git a/textures/bitmaptexture.cpp b/textures/bitmaptexture.cpp new file mode 100644 index 0000000..9e8eea2 --- /dev/null +++ b/textures/bitmaptexture.cpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include "../datatypes.cpp" +#include "../helpers.cpp" +#include "../buffer.cpp" +#include "texturebase.cpp" + +namespace UwU { + class BitmapTexture : public TextureBase { + private: + Buffer buffer; + + public: + BitmapTexture(Buffer buffer) { + this->buffer = buffer; + } + + Color texel(uint16_t u, uint16_t v) { + uint32_t index = (v * buffer.stride) + (u * 4); + Color c = Color(buffer.pixels[index + 2], buffer.pixels[index + 1], buffer.pixels[index], buffer.pixels[index + 3]); + return c; + } + }; +} \ No newline at end of file diff --git a/textures/colortexture.cpp b/textures/colortexture.cpp new file mode 100644 index 0000000..12c4d43 --- /dev/null +++ b/textures/colortexture.cpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include "../datatypes.cpp" +#include "../helpers.cpp" +#include "../buffer.cpp" +#include "texturebase.cpp" + +namespace UwU { + class ColorTexture : public TextureBase { + private: + Color color; + + public: + ColorTexture(Color color) { + this->color = color; + } + + Color texel(uint16_t u, uint16_t v) { + (void)u; + (void)v; + return color; + } + }; +} \ No newline at end of file diff --git a/textures/gradienttexture.cpp b/textures/gradienttexture.cpp new file mode 100644 index 0000000..462689b --- /dev/null +++ b/textures/gradienttexture.cpp @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include "../datatypes.cpp" +#include "../helpers.cpp" +#include "../buffer.cpp" +#include "texturebase.cpp" + +namespace UwU { + class GradientTexture : public TextureBase { + public: + GradientTexture(uint16_t width, Color c0, Color c1) { + this->uScale = 0xffffffff / (1 + (uint32_t)width); + this->c0 = c0; + this->c1 = c1; + } + uint32_t uScale; + Color c0; + Color c1; + + Color texel(uint16_t u, uint16_t v) { + (void)v; + uint32_t t = (((uint32_t)u) * uScale) / 0x01000000; + return Helpers::lerpColor(c0, c1, (uint8_t)t); + } + }; +} \ No newline at end of file diff --git a/textures/hgradienttexture.cpp b/textures/hgradienttexture.cpp new file mode 100644 index 0000000..3e1ba52 --- /dev/null +++ b/textures/hgradienttexture.cpp @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include "../datatypes.cpp" +#include "../helpers.cpp" +#include "../buffer.cpp" +#include "texturebase.cpp" + +namespace UwU { + class HGradientTexture : public TextureBase { + public: + HGradientTexture(uint16_t width, Color c0, Color c1) { + this->uScale = 0xffffffff / (1 + (uint32_t)width); + this->c0 = c0; + this->c1 = c1; + } + uint32_t uScale; + Color c0; + Color c1; + + Color texel(uint16_t u, uint16_t v) { + (void)v; + uint32_t t = (((uint32_t)u) * uScale) / 0x01000000; + return Helpers::lerpColor(c0, c1, (uint8_t)t); + } + }; +} \ No newline at end of file diff --git a/textures/texturebase.cpp b/textures/texturebase.cpp new file mode 100644 index 0000000..d0f4563 --- /dev/null +++ b/textures/texturebase.cpp @@ -0,0 +1,17 @@ +#pragma once + +#include + +#include "../datatypes.cpp" +#include "../helpers.cpp" +#include "../buffer.cpp" + +namespace UwU { + template + class TextureBase { + public: + Color texel(uint16_t u, uint16_t v) { + return static_cast(this)->texel(u, v); + } + }; +} \ No newline at end of file diff --git a/textures/textures.h b/textures/textures.h new file mode 100644 index 0000000..c3e9f84 --- /dev/null +++ b/textures/textures.h @@ -0,0 +1,7 @@ +#include "texturebase.cpp" +#include "colortexture.cpp" +#include "bitmaptexture.cpp" +#include "tilemaptexture.cpp" +#include "hgradienttexture.cpp" +#include "vgradienttexture.cpp" +// #include "gradienttexture.cpp" \ No newline at end of file diff --git a/textures/tilemaptexture.cpp b/textures/tilemaptexture.cpp new file mode 100644 index 0000000..71aa076 --- /dev/null +++ b/textures/tilemaptexture.cpp @@ -0,0 +1,30 @@ +#pragma once + +#include + +#include "../datatypes.cpp" +#include "../helpers.cpp" +#include "../buffer.cpp" +#include "texturebase.cpp" +#include "../tilemap.cpp" + +namespace UwU { + class TilemapTexture : public TextureBase { + private: + Buffer buffer; + Tilemap tilemap; + + public: + TilemapTexture(Tilemap tilemap, Buffer buffer) { + this->buffer = buffer; + this->tilemap = tilemap; + } + + Color texel(uint16_t u, uint16_t v) { + Coord2 bitmapUV = tilemap.map(u, v); + uint32_t index = (bitmapUV.y * buffer.stride) + (bitmapUV.x * 4); + Color c = Color(buffer.pixels[index + 2], buffer.pixels[index + 1], buffer.pixels[index], buffer.pixels[index + 3]); + return c; + } + }; +} \ No newline at end of file diff --git a/textures/vgradienttexture.cpp b/textures/vgradienttexture.cpp new file mode 100644 index 0000000..2697e75 --- /dev/null +++ b/textures/vgradienttexture.cpp @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include "../datatypes.cpp" +#include "../helpers.cpp" +#include "../buffer.cpp" +#include "texturebase.cpp" + +namespace UwU { + class VGradientTexture : public TextureBase { + public: + VGradientTexture(uint16_t height, Color c0, Color c1) { + this->vScale = 0xffffffff / (1 + (uint32_t)height); + this->c0 = c0; + this->c1 = c1; + } + uint32_t vScale; + Color c0; + Color c1; + + Color texel(uint16_t u, uint16_t v) { + (void)u; + uint32_t t = (((uint32_t)v) * vScale) / 0x01000000; + return Helpers::lerpColor(c0, c1, (uint8_t)t); + } + }; +} \ No newline at end of file diff --git a/tilemap.cpp b/tilemap.cpp new file mode 100644 index 0000000..ac08305 --- /dev/null +++ b/tilemap.cpp @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include "datatypes.cpp" +#include "helpers.cpp" + +namespace UwU { + class Tilemap { + public: + Tilemap() { + this->tilemap = new uint16_t[16384]; // the map of tile positions 128x128 8x8 tiles from a 512x512 bitmap space + } + uint16_t* tilemap; + + Coord2 map(uint16_t u, uint16_t v) { + // returns uv coordinates that point to a specific pixel of a specific tile on a tilesheet buffer + uint16_t mapX = (u & 0x03f8) >> 3; + uint16_t mapY = (v & 0x03f8) << 4; + uint16_t tileIndex = tilemap[mapY + mapX]; + uint16_t u1 = (tileIndex & 0x003f) << 3; + u1 += (u & 0x0007); + uint16_t v1 = (tileIndex & 0x0fc0) >> 3; + v1 += (v & 0x0007); + return Coord2(u1, v1); + } + }; +} \ No newline at end of file diff --git a/uwugl.h b/uwugl.h index 381c56d..e2717a2 100644 --- a/uwugl.h +++ b/uwugl.h @@ -2,10 +2,8 @@ #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 "shaders/shaders.h" -#include "mappers/mappers.h" \ No newline at end of file +#include "primatives/primatives.h" +#include "mappers/mappers.h" +#include "textures/textures.h" +#include "tilemap.cpp" +// #include "shaders/shaders.h" \ No newline at end of file