Compare commits
12 Commits
0f0e352fca
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 3acd7de9a7 | |||
| 1c2579148e | |||
| e6ce80ce13 | |||
| 5298e75fdb | |||
| eddbb85256 | |||
| 78ec985f7a | |||
| a89ef52247 | |||
| c7cdfd402e | |||
| ee2c66f97b | |||
| 8a00e42f75 | |||
| 90df991e7e | |||
| 3588a41657 |
+19
@@ -0,0 +1,19 @@
|
|||||||
|
shapes:
|
||||||
|
triangles:
|
||||||
|
point
|
||||||
|
line
|
||||||
|
solid
|
||||||
|
gradient
|
||||||
|
rectangle
|
||||||
|
solid
|
||||||
|
gradient
|
||||||
|
blitter (tilemaps)
|
||||||
|
triangle
|
||||||
|
solid
|
||||||
|
gradient
|
||||||
|
perspective mapping (3D!!!)
|
||||||
|
quad
|
||||||
|
solid
|
||||||
|
gradient (charts)
|
||||||
|
blitter (isometric)
|
||||||
|
affine mapping (sprite rotation and scaling)
|
||||||
+127
@@ -0,0 +1,127 @@
|
|||||||
|
# UwUGL Styleguide
|
||||||
|
|
||||||
|
This document describes the coding conventions used in UwUGL, inferred from the existing codebase. It prioritizes readability and simplicity for a small graphics library.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. File Organization
|
||||||
|
|
||||||
|
- **Single monolithic header**: `uwugl.h` is the public entry point and includes all implementation files.
|
||||||
|
- **Header-like `.cpp` files**: Every implementation file begins with `#pragma once` and is designed to be `#include`d directly by `uwugl.h` (or by other `.cpp` files). There are no traditional separate `.h`/`.cpp` pairs.
|
||||||
|
- **No separate headers for internal modules**: Classes and structs are declared and defined directly in `.cpp` files.
|
||||||
|
- **Exception**: `shaders/shaders.h` is a small aggregator file that includes the shader `.cpp` files.
|
||||||
|
- **Directory layout**:
|
||||||
|
- `primatives/` — shape classes (`Line`, `Point`, `Rectangle`, `Trapezoid`, `Triangle`)
|
||||||
|
- `shaders/` — shader classes and base
|
||||||
|
- `waymini/` — external Wayland helper library (C)
|
||||||
|
|
||||||
|
## 2. Naming Conventions
|
||||||
|
|
||||||
|
- **Namespace**: All library code lives in `namespace UwU`.
|
||||||
|
- **Classes / structs**: PascalCase (`Buffer`, `ColorShader`, `Rectangle`, `Helpers`).
|
||||||
|
- **Functions / methods**: camelCase (`drawPixel`, `lerpColor`, `bresenham`, `shouldClose`).
|
||||||
|
- **Member variables**: lowercase with no prefix (`pixels`, `width`, `x0`, `c`).
|
||||||
|
- **Template parameters**: PascalCase ending in `T` (`ShaderT`).
|
||||||
|
- **Enums**: PascalCase type name; UPPER_SNAKE_CASE values (`ShaderType`, `COLOR`, `HGRADIENT`, `VGRADIENT`).
|
||||||
|
- **Constants in code**: prefer lowercase; UPPER_SNAKE_CASE may be used for local compile-time-ish constants in comments or test code.
|
||||||
|
- **Filenames**: lowercase and descriptive (`buffer.cpp`, `colorshader.cpp`, `line.cpp`).
|
||||||
|
|
||||||
|
## 3. Formatting
|
||||||
|
|
||||||
|
- **Indentation**: 2 spaces.
|
||||||
|
- **Brace style**: K&R — opening brace on the same line as the class/function/control statement.
|
||||||
|
- **Pointer/reference syntax**: attach `*` and `&` to the variable name:
|
||||||
|
- `uint8_t* pixels`
|
||||||
|
- `ShaderBase<ShaderT>& shader`
|
||||||
|
- **Empty parameter lists**: use `()` for default constructors, e.g., `Color() {}`.
|
||||||
|
- **Spacing around operators**: use spaces around binary operators for readability (`x + y` instead of `x+y`).
|
||||||
|
- **Explicit `return;` at end of void functions**: Acceptable, but not required.
|
||||||
|
- **Comments**: use `//` for both inline and block-style comments. Keep them informal and focused on intent or known issues.
|
||||||
|
|
||||||
|
## 4. Includes
|
||||||
|
|
||||||
|
Include order within a file:
|
||||||
|
|
||||||
|
1. `#pragma once`
|
||||||
|
2. C/C++ standard headers (`<stdint.h>`, `<stdio.h>`, `<algorithm>`)
|
||||||
|
3. Project implementation files via relative paths (`"../datatypes.cpp"`, `"../buffer.cpp"`)
|
||||||
|
|
||||||
|
External C library headers (e.g., `"waymini/waymini.h"`) are included where needed.
|
||||||
|
|
||||||
|
## 5. Code Patterns
|
||||||
|
|
||||||
|
- **Composition over inheritance**: primitives hold data; shaders are passed into `draw()`.
|
||||||
|
- **CRTP for shaders**: `ShaderBase<ShaderT>` uses the Curiously Recurring Template Pattern for static polymorphism.
|
||||||
|
- **Template `draw` methods**: every primitive's `draw()` is templated on `ShaderT` and takes `(Buffer buffer, ShaderBase<ShaderT>& shader)`.
|
||||||
|
- **Manual memory management**: `new uint8_t[...]` in `Buffer`; no smart pointers.
|
||||||
|
- **C-style casts**: `(uint16_t)x`, `(uint8_t*)ptr`.
|
||||||
|
- **Bounds checks**: primitives guard `draw()` with `if (x > buffer.width || y > buffer.height) {return;};`.
|
||||||
|
- **Unused parameter suppression**: use `(void)param;` to silence warnings.
|
||||||
|
|
||||||
|
## 6. C++ Feature Usage
|
||||||
|
|
||||||
|
### Used
|
||||||
|
|
||||||
|
- Classes and structs
|
||||||
|
- Namespaces
|
||||||
|
- Templates (`template <class ShaderT>`)
|
||||||
|
- CRTP (Curiously Recurring Template Pattern)
|
||||||
|
- Function overloading (constructors)
|
||||||
|
- References
|
||||||
|
- C-style casts
|
||||||
|
- `new` / `new[]` for dynamic allocation
|
||||||
|
- Raw pointers
|
||||||
|
- Stack-allocated arrays
|
||||||
|
- C standard headers (`<stdint.h>`, `<stdio.h>`, `<stdlib.h>`, `<string.h>`, `<time.h>`, `<algorithm>`)
|
||||||
|
|
||||||
|
### Not Used but Allowed
|
||||||
|
- Smart pointers (`std::unique_ptr`, `std::shared_ptr`)
|
||||||
|
- Standard containers (`std::vector`, `std::array`, etc.)
|
||||||
|
- `enum class`
|
||||||
|
- Exceptions
|
||||||
|
- `std::string`
|
||||||
|
- `std::chrono`
|
||||||
|
- `std::function`
|
||||||
|
|
||||||
|
### Not Used
|
||||||
|
|
||||||
|
The following features are intentionally not used. This keeps the codebase small, predictable, and easy to reason about.
|
||||||
|
|
||||||
|
- `auto`
|
||||||
|
- Range-based `for` loops
|
||||||
|
- `nullptr`
|
||||||
|
- Lambda expressions
|
||||||
|
- `constexpr` / `consteval`
|
||||||
|
- `using` type aliases
|
||||||
|
- Move semantics / rvalue references
|
||||||
|
- Default member initializers
|
||||||
|
- Delegating constructors
|
||||||
|
- `override` / `final`
|
||||||
|
- Named casts (`static_cast`, `reinterpret_cast`, etc.)
|
||||||
|
- Structured bindings
|
||||||
|
- Concepts / `requires` (C++20)
|
||||||
|
- Virtual functions / runtime polymorphism / abstract base classes
|
||||||
|
- Operator overloading
|
||||||
|
- RTTI / `dynamic_cast` / `typeid`
|
||||||
|
- `<iostream>` (use C-style `printf`/`fflush`)
|
||||||
|
|
||||||
|
## 7. Build System
|
||||||
|
|
||||||
|
- **Makefile-based**.
|
||||||
|
- C library (`waymini`) compiled with `gcc`.
|
||||||
|
- Main example compiled with `g++`.
|
||||||
|
- Flags: `-Wall -Wextra -O3`, plus Wayland client flags from `pkg-config`.
|
||||||
|
|
||||||
|
## 8. Known Inconsistencies and Recommendations
|
||||||
|
|
||||||
|
The codebase currently has a few inconsistencies. The following recommendations aim to improve readability without adding complexity:
|
||||||
|
|
||||||
|
- **Indentation consistency**: some blocks are not aligned (e.g., `line.cpp` inner loop). Keep all indentation strictly at 2 spaces per level.
|
||||||
|
- **Spacing consistency**: standardize on spaces around binary operators and after commas.
|
||||||
|
- **Include consistency**: some primitives include `../shaders/shaders.h` while `rectangle.cpp` also includes `../shaders/shaderbase.cpp` directly. Prefer the aggregator `shaders.h` everywhere.
|
||||||
|
- **`return;` at end of void functions**: acceptable, but can be omitted when it adds no clarity.
|
||||||
|
- **Bounds check style**: the pattern `if (...) {return;};` has a redundant semicolon. Prefer `if (...) { return; }`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This guide should evolve with the project. When in doubt, favor simplicity and consistency with the existing code.
|
||||||
+9
-9
@@ -26,15 +26,15 @@ namespace UwU {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Coord2 datatype for xy coordinates, from top-left of surface
|
// Coord2 datatype for xy coordinates, from top-left of surface
|
||||||
// struct Coord2 {
|
struct Coord2 {
|
||||||
// Coord2(uint16_t x, uint16_t y) {
|
Coord2(uint16_t x, uint16_t y) {
|
||||||
// this->x = x;
|
this->x = x;
|
||||||
// this->y = y;
|
this->y = y;
|
||||||
// }
|
}
|
||||||
// Coord2() {}
|
Coord2() {}
|
||||||
// uint16_t x;
|
uint16_t x;
|
||||||
// uint16_t y;
|
uint16_t y;
|
||||||
// };
|
};
|
||||||
|
|
||||||
// Vec2 datatype for signed x, y coordinates
|
// Vec2 datatype for signed x, y coordinates
|
||||||
// struct Vec2 {
|
// struct Vec2 {
|
||||||
|
|||||||
+42
-29
@@ -7,17 +7,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
// #include "datatypes.cpp"
|
|
||||||
// #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 "shader.cpp"
|
|
||||||
|
|
||||||
#include "uwugl.h"
|
#include "uwugl.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "font.cpp"
|
#include "font.cpp"
|
||||||
@@ -38,13 +27,37 @@ int main(void) {
|
|||||||
|
|
||||||
UwU::Surface surface = UwU::Surface(w, h, onKey);
|
UwU::Surface surface = UwU::Surface(w, h, onKey);
|
||||||
|
|
||||||
UwU::ColorShader fuchsia = UwU::ColorShader(UwU::Color(0xb00b69ff));
|
// UwU::Color fuchsia = UwU::Color(0xb00b69ff);
|
||||||
UwU::Rectangle rectangle = UwU::Rectangle(69, 69, 420, 420);
|
UwU::Color red = UwU::Color(0xff0000ff);
|
||||||
rectangle.draw(surface.buffer, fuchsia);
|
UwU::Color green = UwU::Color(0x00ff00ff);
|
||||||
|
UwU::Color blue = UwU::Color(0x0000ffff);
|
||||||
|
|
||||||
UwU::ColorShader green = UwU::ColorShader(UwU::Color(0x00ff00ff));
|
// 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::TilemapTexture textMap = UwU::TilemapTexture(myTilemap, fontBuffer);
|
||||||
|
UwU::Rectangle rectangle = UwU::Rectangle(69, 69, 420, 420);
|
||||||
|
rectangle.draw(surface.buffer, offsetMapper, textMap);
|
||||||
|
|
||||||
|
UwU::ColorTexture greenTexture = UwU::ColorTexture(green);
|
||||||
|
UwU::NullMapper nullMapper = UwU::NullMapper();
|
||||||
UwU::Point point = UwU::Point(187, 37);
|
UwU::Point point = UwU::Point(187, 37);
|
||||||
point.draw(surface.buffer, green);
|
point.draw(surface.buffer, nullMapper, greenTexture);
|
||||||
|
|
||||||
|
UwU::ColorTexture blueTexture = UwU::ColorTexture(blue);
|
||||||
|
UwU::Trapezoid trapezoid = UwU::Trapezoid(100, 300, 690, 320, 720, 780);
|
||||||
|
trapezoid.draw(surface.buffer, nullMapper, blueTexture);
|
||||||
|
|
||||||
|
UwU::ColorTexture redTexture = UwU::ColorTexture(red);
|
||||||
|
UwU::Triangle triangle = UwU::Triangle(140, 140, 60, 400, 240, 240);
|
||||||
|
triangle.draw(surface.buffer, offsetMapper, bisexual);
|
||||||
|
|
||||||
// // Benchmarking
|
// // Benchmarking
|
||||||
// struct timespec start, end;
|
// struct timespec start, end;
|
||||||
@@ -73,20 +86,20 @@ int main(void) {
|
|||||||
// printf("Elapsed: %ld ns\n", timeAvg);
|
// printf("Elapsed: %ld ns\n", timeAvg);
|
||||||
|
|
||||||
|
|
||||||
// UwU::Line lines[8] {
|
UwU::Line lines[8] {
|
||||||
// UwU::Line(300, 100, 250, 469),
|
UwU::Line(300, 100, 250, 469),
|
||||||
// UwU::Line(250, 100, 300, 469),
|
UwU::Line(250, 100, 300, 469),
|
||||||
// UwU::Line(300, 100, 469, 250),
|
UwU::Line(300, 100, 469, 250),
|
||||||
// UwU::Line(469, 100, 300, 250),
|
UwU::Line(469, 100, 300, 250),
|
||||||
// UwU::Line(100, 300, 250, 469),
|
UwU::Line(100, 300, 250, 469),
|
||||||
// UwU::Line(250, 300, 100, 469),
|
UwU::Line(250, 300, 100, 469),
|
||||||
// UwU::Line(100, 300, 469, 250),
|
UwU::Line(100, 300, 469, 250),
|
||||||
// UwU::Line(469, 300, 100, 250)
|
UwU::Line(469, 300, 100, 250)
|
||||||
// };
|
};
|
||||||
|
|
||||||
// for (uint16_t i = 0; i < 8; i++) {
|
for (uint16_t i = 0; i < 8; i++) {
|
||||||
// lines[i].draw(surface.buffer, bisexual);
|
lines[i].draw(surface.buffer, nullMapper, blueTexture);
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
|
||||||
surface.present();
|
surface.present();
|
||||||
|
|||||||
@@ -90,5 +90,9 @@ namespace UwU {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// plot a 90 degree arc
|
||||||
|
static void fastArc(uint16_t radius, uint16_t* LUT) {
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../datatypes.cpp"
|
||||||
|
#include "../helpers.cpp"
|
||||||
|
|
||||||
|
namespace UwU {
|
||||||
|
template <class MapperT>
|
||||||
|
class MapperBase {
|
||||||
|
public:
|
||||||
|
Coord2 map(uint16_t x0, uint16_t y0, uint16_t x, uint16_t y) {
|
||||||
|
return static_cast<MapperT*>(this)->map(x0, y0, x, y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#include "mapperbase.cpp"
|
||||||
|
#include "nullmapper.cpp"
|
||||||
|
#include "offsetmapper.cpp"
|
||||||
|
// #include "tilemapper.cpp"
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../datatypes.cpp"
|
||||||
|
#include "../helpers.cpp"
|
||||||
|
#include "mapperbase.cpp"
|
||||||
|
|
||||||
|
namespace UwU {
|
||||||
|
class NullMapper : public MapperBase<NullMapper> {
|
||||||
|
public:
|
||||||
|
NullMapper() {}
|
||||||
|
|
||||||
|
Coord2 map(uint16_t x0, uint16_t y0, uint16_t x, uint16_t y) {
|
||||||
|
(void)x0;
|
||||||
|
(void)y0;
|
||||||
|
return Coord2(x, y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../datatypes.cpp"
|
||||||
|
#include "../helpers.cpp"
|
||||||
|
#include "mapperbase.cpp"
|
||||||
|
|
||||||
|
namespace UwU {
|
||||||
|
class OffsetMapper : public MapperBase<OffsetMapper> {
|
||||||
|
public:
|
||||||
|
OffsetMapper() {}
|
||||||
|
|
||||||
|
Coord2 map(uint16_t x0, uint16_t y0, uint16_t x, uint16_t y) {
|
||||||
|
uint16_t u = x -x0;
|
||||||
|
uint16_t v = y -y0;
|
||||||
|
return Coord2(u, v);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
+27
-95
@@ -5,14 +5,16 @@
|
|||||||
#include "../datatypes.cpp"
|
#include "../datatypes.cpp"
|
||||||
#include "../helpers.cpp"
|
#include "../helpers.cpp"
|
||||||
#include "../buffer.cpp"
|
#include "../buffer.cpp"
|
||||||
#include "../shader.cpp"
|
#include "../mappers/mappers.h"
|
||||||
|
#include "../textures/textures.h"
|
||||||
|
|
||||||
namespace UwU {
|
namespace UwU {
|
||||||
// line
|
// line
|
||||||
class Line {
|
class Line {
|
||||||
private:
|
private:
|
||||||
// plot lines if m <= 1
|
// plot lines if m <= 1
|
||||||
void lineLow(int16_t ix0, int16_t iy0, int16_t ix1, int16_t iy1, Buffer buffer, Shader shader) {
|
template <class MapperT, class TextureT>
|
||||||
|
void lineLow(int16_t ix0, int16_t iy0, int16_t ix1, int16_t iy1, Buffer buffer, MapperBase<MapperT>& mapper, TextureBase<TextureT>& texture) {
|
||||||
int16_t dx = ix1 - ix0;
|
int16_t dx = ix1 - ix0;
|
||||||
int16_t dy = iy1 - iy0;
|
int16_t dy = iy1 - iy0;
|
||||||
int16_t yi = 1;
|
int16_t yi = 1;
|
||||||
@@ -23,59 +25,24 @@ namespace UwU {
|
|||||||
int16_t d = (2 * dy) - dx;
|
int16_t d = (2 * dy) - dx;
|
||||||
int16_t y = iy0;
|
int16_t y = iy0;
|
||||||
|
|
||||||
if (shader.shaderType == COLOR) {
|
Coord2 uv;
|
||||||
for (int16_t x = ix0; x < ix1; x++) {
|
|
||||||
buffer.drawPixel((uint16_t)x, (uint16_t)y, shader.c0);
|
|
||||||
if (d > 0) {
|
|
||||||
y += yi;
|
|
||||||
d += (2 * (dy - dx));
|
|
||||||
} else {
|
|
||||||
d += (2 * dy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else if (shader.shaderType == HGRADIENT) {
|
for (int16_t x = ix0; x < ix1; x++) {
|
||||||
for (int16_t x = ix0; x < ix1; x++) {
|
uv = mapper.map(ix0, iy0, x, y);
|
||||||
buffer.drawPixel((uint16_t)x, (uint16_t)y, ShaderMethods::gradient(shader.u0, shader.scale, shader.c0, shader.c1, x));
|
buffer.drawPixel((uint16_t)x, (uint16_t)y, texture.texel(uv.x, uv.y));
|
||||||
if (d > 0) {
|
if (d > 0) {
|
||||||
y += yi;
|
y += yi;
|
||||||
d += (2 * (dy - dx));
|
d += (2 * (dy - dx));
|
||||||
} else {
|
} else {
|
||||||
d += (2 * dy);
|
d += (2 * dy);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
|
|
||||||
} else if (shader.shaderType == VGRADIENT) {
|
|
||||||
for (int16_t x = ix0; x < ix1; x++) {
|
|
||||||
buffer.drawPixel((uint16_t)x, (uint16_t)y, ShaderMethods::gradient(shader.v0, shader.scale, shader.c0, shader.c1, y));
|
|
||||||
if (d > 0) {
|
|
||||||
y += yi;
|
|
||||||
d += (2 * (dy - dx));
|
|
||||||
} else {
|
|
||||||
d += (2 * dy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else if (shader.shaderType == BUFFER) {
|
|
||||||
for (int16_t x = ix0; x < ix1; x++) {
|
|
||||||
buffer.drawPixel((uint16_t)x, (uint16_t)y, ShaderMethods::buffer(shader.u0, shader.v0, shader.buffer, x, y));
|
|
||||||
if (d > 0) {
|
|
||||||
y += yi;
|
|
||||||
d += (2 * (dy - dx));
|
|
||||||
} else {
|
|
||||||
d += (2 * dy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// plot lines if m >1
|
// plot lines if m >1
|
||||||
void lineHigh(int16_t ix0, int16_t iy0, int16_t ix1, int16_t iy1, Buffer buffer, Shader shader) {
|
template <class MapperT, class TextureT>
|
||||||
|
void lineHigh(int16_t ix0, int16_t iy0, int16_t ix1, int16_t iy1, Buffer buffer, MapperBase<MapperT>& mapper, TextureBase<TextureT>& texture) {
|
||||||
int16_t dx = ix1 - ix0;
|
int16_t dx = ix1 - ix0;
|
||||||
int16_t dy = iy1 - iy0;
|
int16_t dy = iy1 - iy0;
|
||||||
int16_t xi = 1;
|
int16_t xi = 1;
|
||||||
@@ -86,55 +53,19 @@ namespace UwU {
|
|||||||
int16_t d = (2 * dx) - dy;
|
int16_t d = (2 * dx) - dy;
|
||||||
int16_t x = ix0;
|
int16_t x = ix0;
|
||||||
|
|
||||||
if (shader.shaderType == COLOR) {
|
Coord2 uv;
|
||||||
for (int16_t y = iy0; y < iy1; y++) {
|
|
||||||
buffer.drawPixel((uint16_t)x, (uint16_t)y, shader.c0);
|
|
||||||
if (d > 0) {
|
|
||||||
x += xi;
|
|
||||||
d += (2 * (dx - dy));
|
|
||||||
} else {
|
|
||||||
d += (2 * dx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else if (shader.shaderType == HGRADIENT) {
|
for (int16_t y = iy0; y < iy1; y++) {
|
||||||
for (int16_t y = iy0; y < iy1; y++) {
|
uv = mapper.map(ix0, iy0, x, y);
|
||||||
buffer.drawPixel((uint16_t)x, (uint16_t)y, ShaderMethods::gradient(shader.u0, shader.scale, shader.c0, shader.c1, x));
|
buffer.drawPixel((uint16_t)x, (uint16_t)y, texture.texel(uv.x, uv.y));
|
||||||
if (d > 0) {
|
if (d > 0) {
|
||||||
x += xi;
|
x += xi;
|
||||||
d += (2 * (dx - dy));
|
d += (2 * (dx - dy));
|
||||||
} else {
|
} else {
|
||||||
d += (2 * dx);
|
d += (2 * dx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
} else if (shader.shaderType == VGRADIENT) {
|
|
||||||
for (int16_t y = iy0; y < iy1; y++) {
|
|
||||||
buffer.drawPixel((uint16_t)x, (uint16_t)y, ShaderMethods::gradient(shader.v0, shader.scale, shader.c0, shader.c1, y));
|
|
||||||
if (d > 0) {
|
|
||||||
x += xi;
|
|
||||||
d += (2 * (dx - dy));
|
|
||||||
} else {
|
|
||||||
d += (2 * dx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else if (shader.shaderType == BUFFER) {
|
|
||||||
for (int16_t y = iy0; y < iy1; y++) {
|
|
||||||
buffer.drawPixel((uint16_t)x, (uint16_t)y, ShaderMethods::buffer(shader.u0, shader.v0, shader.buffer, x, y));
|
|
||||||
if (d > 0) {
|
|
||||||
x += xi;
|
|
||||||
d += (2 * (dx - dy));
|
|
||||||
} else {
|
|
||||||
d += (2 * dx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -151,7 +82,8 @@ namespace UwU {
|
|||||||
uint16_t y1;
|
uint16_t y1;
|
||||||
|
|
||||||
// Uses Bresenham's line algorithm to draw line of any slope
|
// Uses Bresenham's line algorithm to draw line of any slope
|
||||||
void draw (Buffer buffer, Shader shader) {
|
template <class MapperT, class TextureT>
|
||||||
|
void draw (Buffer buffer, MapperBase<MapperT>& mapper, TextureBase<TextureT>& texture) {
|
||||||
if (x0 > buffer.width || y0 > buffer.height || x1 > buffer.width || y1 > buffer.height) {return;};
|
if (x0 > buffer.width || y0 > buffer.height || x1 > buffer.width || y1 > buffer.height) {return;};
|
||||||
int16_t ix0 = x0;
|
int16_t ix0 = x0;
|
||||||
int16_t iy0 = y0;
|
int16_t iy0 = y0;
|
||||||
@@ -159,15 +91,15 @@ namespace UwU {
|
|||||||
int16_t iy1 = y1;
|
int16_t iy1 = y1;
|
||||||
if (abs(iy1 - iy0) < abs(ix1 - ix0)) {
|
if (abs(iy1 - iy0) < abs(ix1 - ix0)) {
|
||||||
if (ix0 > ix1) {
|
if (ix0 > ix1) {
|
||||||
lineLow(ix1, iy1, ix0, iy0, buffer, shader);
|
lineLow(ix1, iy1, ix0, iy0, buffer, mapper, texture);
|
||||||
} else {
|
} else {
|
||||||
lineLow(ix0, iy0, ix1, iy1, buffer, shader);
|
lineLow(ix0, iy0, ix1, iy1, buffer, mapper, texture);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (iy0 > iy1) {
|
if (iy0 > iy1) {
|
||||||
lineHigh(ix1, iy1, ix0, iy0, buffer, shader);
|
lineHigh(ix1, iy1, ix0, iy0, buffer, mapper, texture);
|
||||||
} else {
|
} else {
|
||||||
lineHigh(ix0, iy0, ix1, iy1, buffer, shader);
|
lineHigh(ix0, iy0, ix1, iy1, buffer, mapper, texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
#include "../datatypes.cpp"
|
#include "../datatypes.cpp"
|
||||||
#include "../helpers.cpp"
|
#include "../helpers.cpp"
|
||||||
#include "../buffer.cpp"
|
#include "../buffer.cpp"
|
||||||
#include "../shaders/shaders.h"
|
#include "../mappers/mappers.h"
|
||||||
|
#include "../textures/textures.h"
|
||||||
|
|
||||||
namespace UwU {
|
namespace UwU {
|
||||||
// point
|
// point
|
||||||
@@ -20,10 +21,11 @@ namespace UwU {
|
|||||||
uint16_t y;
|
uint16_t y;
|
||||||
|
|
||||||
// Draw a point
|
// Draw a point
|
||||||
template <class ShaderT>
|
template <class MapperT, class TextureT>
|
||||||
void draw (Buffer buffer, ShaderBase<ShaderT>& shader) {
|
void draw (Buffer buffer, MapperBase<MapperT>& mapper, TextureBase<TextureT>& texture) {
|
||||||
if (x > buffer.width || y > buffer.height) {return;};
|
if (x > buffer.width || y > buffer.height) {return;};
|
||||||
buffer.drawPixel(x, y, shader.shade(x, y));
|
Coord2 uv = mapper.map(x, y, x, y);
|
||||||
|
buffer.drawPixel(x, y, texture.texel(uv.x, uv.y));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#include "point.cpp"
|
||||||
|
#include "line.cpp"
|
||||||
|
#include "rectangle.cpp"
|
||||||
|
#include "trapezoid.cpp"
|
||||||
|
#include "triangle.cpp"
|
||||||
@@ -5,8 +5,8 @@
|
|||||||
#include "../datatypes.cpp"
|
#include "../datatypes.cpp"
|
||||||
#include "../helpers.cpp"
|
#include "../helpers.cpp"
|
||||||
#include "../buffer.cpp"
|
#include "../buffer.cpp"
|
||||||
#include "../shaders/shaderbase.cpp"
|
#include "../mappers/mappers.h"
|
||||||
#include "../shaders/shaders.h"
|
#include "../textures/textures.h"
|
||||||
|
|
||||||
namespace UwU {
|
namespace UwU {
|
||||||
// rectangle
|
// rectangle
|
||||||
@@ -25,12 +25,13 @@ namespace UwU {
|
|||||||
uint16_t y1;
|
uint16_t y1;
|
||||||
|
|
||||||
// Draw a rectangle
|
// Draw a rectangle
|
||||||
template <class ShaderT>
|
template <class MapperT, class TextureT>
|
||||||
void draw (Buffer buffer, ShaderBase<ShaderT>& shader) {
|
void draw (Buffer buffer, MapperBase<MapperT>& mapper, TextureBase<TextureT>& texture) {
|
||||||
if (x0 > buffer.width || y0 > buffer.height || x1 > buffer.width || y1 > buffer.height) {return;};
|
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 y = y0; y <= y1; y++) {
|
||||||
for (uint16_t x = x0; x <= x1; x++) {
|
for (uint16_t x = x0; x <= x1; x++) {
|
||||||
buffer.drawPixel(x, y, shader.shade(x, y));
|
Coord2 uv = mapper.map(x0, y0, x, y);
|
||||||
|
buffer.drawPixel(x, y, texture.texel(uv.x, uv.y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
+10
-44
@@ -6,7 +6,8 @@
|
|||||||
#include "../datatypes.cpp"
|
#include "../datatypes.cpp"
|
||||||
#include "../helpers.cpp"
|
#include "../helpers.cpp"
|
||||||
#include "../buffer.cpp"
|
#include "../buffer.cpp"
|
||||||
#include "../shader.cpp"
|
#include "../mappers/mappers.h"
|
||||||
|
#include "../textures/textures.h"
|
||||||
|
|
||||||
namespace UwU {
|
namespace UwU {
|
||||||
// trapezoid (horizontally constrained)
|
// trapezoid (horizontally constrained)
|
||||||
@@ -30,57 +31,22 @@ namespace UwU {
|
|||||||
|
|
||||||
// Draw a horizontally bounded trapezoid
|
// Draw a horizontally bounded trapezoid
|
||||||
// y1 >= y0
|
// y1 >= y0
|
||||||
void draw (Buffer buffer, Shader shader) {
|
template <class MapperT, class TextureT>
|
||||||
|
void draw (Buffer buffer, MapperBase<MapperT>& mapper, TextureBase<TextureT>& texture) {
|
||||||
uint16_t height = 1 + y1 - y0;
|
uint16_t height = 1 + y1 - y0;
|
||||||
int16_t LeftBound[height];
|
int16_t LeftBound[height];
|
||||||
int16_t RightBound[height];
|
int16_t RightBound[height];
|
||||||
|
|
||||||
Helpers::bresenham(0, xl0, y1 - y0, xl1, LeftBound);
|
Helpers::bresenham(0, xl0, y1 - y0, xl1, LeftBound);
|
||||||
Helpers::bresenham(0, xr0, y1 - y0, xr1, RightBound);
|
Helpers::bresenham(0, xr0, y1 - y0, xr1, RightBound);
|
||||||
|
|
||||||
|
uint16_t x0 = std::min(xl0, xl1);
|
||||||
|
|
||||||
if (shader.shaderType == COLOR) {
|
for (uint16_t i = 0; i < height; i++) {
|
||||||
for (uint16_t i = 0; i < height; i++) {
|
for (uint16_t x = LeftBound[i]; x <= RightBound[i]; x++) {
|
||||||
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.c0);
|
buffer.drawPixel(x, i + y0, texture.texel(uv.x, uv.y));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
|
|
||||||
} else if (shader.shaderType == HGRADIENT) {
|
|
||||||
// find left-right boundaries
|
|
||||||
uint16_t leftmost = std::min(xl0, xl1);
|
|
||||||
uint16_t rightmost = std::max(xr0, xr1);
|
|
||||||
|
|
||||||
// precompute gradient LUT
|
|
||||||
Color cols[rightmost - leftmost];
|
|
||||||
for (uint16_t x = leftmost; x < rightmost; x++) {
|
|
||||||
cols[x - leftmost] = ShaderMethods::gradient(shader.u0, shader.scale, shader.c0, shader.c1, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint16_t i = 0; i < height; i++) {
|
|
||||||
for (uint16_t x = LeftBound[i]; x <= RightBound[i]; x++) {
|
|
||||||
buffer.drawPixel(x, i + y0, cols[x - leftmost]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else if (shader.shaderType == VGRADIENT) {
|
|
||||||
Color c;
|
|
||||||
for (uint16_t i = 0; i < height; i++) {
|
|
||||||
c = ShaderMethods::gradient(shader.v0, shader.scale, shader.c0, shader.c1, i + y0);
|
|
||||||
for (uint16_t x = LeftBound[i]; x <= RightBound[i]; x++) {
|
|
||||||
buffer.drawPixel(x, i + y0, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else if (shader.shaderType == BUFFER) {
|
|
||||||
for (uint16_t i = 0; i < height; i++) {
|
|
||||||
for (uint16_t x = LeftBound[i]; x <= RightBound[i]; x++) {
|
|
||||||
buffer.drawPixel(x, i + y0, ShaderMethods::buffer(shader.u0, shader.v0, shader.buffer, x, i + y0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-83
@@ -6,7 +6,8 @@
|
|||||||
#include "../datatypes.cpp"
|
#include "../datatypes.cpp"
|
||||||
#include "../helpers.cpp"
|
#include "../helpers.cpp"
|
||||||
#include "../buffer.cpp"
|
#include "../buffer.cpp"
|
||||||
#include "../shader.cpp"
|
#include "../mappers/mappers.h"
|
||||||
|
#include "../textures/textures.h"
|
||||||
|
|
||||||
namespace UwU {
|
namespace UwU {
|
||||||
class Triangle {
|
class Triangle {
|
||||||
@@ -30,7 +31,8 @@ namespace UwU {
|
|||||||
uint16_t y2;
|
uint16_t y2;
|
||||||
|
|
||||||
// Draw a triangle
|
// Draw a triangle
|
||||||
void draw (Buffer buffer, Shader shader) {
|
template <class MapperT, class TextureT>
|
||||||
|
void draw (Buffer buffer, MapperBase<MapperT>& mapper, TextureBase<TextureT>& texture) {
|
||||||
uint16_t topX, topY, midX, midY, btmX, btmY;
|
uint16_t topX, topY, midX, midY, btmX, btmY;
|
||||||
// Find top, middle and bottom points of triangle
|
// Find top, middle and bottom points of triangle
|
||||||
if (y0 <= y1 && y0 <= y2) {
|
if (y0 <= y1 && y0 <= y2) {
|
||||||
@@ -90,91 +92,25 @@ namespace UwU {
|
|||||||
Helpers::bresenham(0, topX, midY - topY, midX, splitBound);
|
Helpers::bresenham(0, topX, midY - topY, midX, splitBound);
|
||||||
Helpers::bresenham(midY - topY, midX, height - 1, btmX, splitBound);
|
Helpers::bresenham(midY - topY, midX, height - 1, btmX, splitBound);
|
||||||
|
|
||||||
if (shader.shaderType == COLOR) {
|
Coord2 uv;
|
||||||
// Left-handed triangle case (midpoint is left of triangle)
|
uint16_t leftX = std::min(topX, std::min(midX, btmX));
|
||||||
if ((int16_t)midX < longBound[midY - topY]) {
|
|
||||||
for (uint16_t i = 0; i < height; i++) {
|
// Left-handed triangle case (midpoint is left of triangle)
|
||||||
for (uint16_t x = (uint16_t)splitBound[i]; x <= (uint16_t)longBound[i]; x++) {
|
if ((int16_t)midX < longBound[midY - topY]) {
|
||||||
buffer.drawPixel(x, i + (uint16_t)topY, shader.c0);
|
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);
|
||||||
// Right-handed triangle case (midpoint is right of triangle)
|
buffer.drawPixel(x, i + (uint16_t)topY, texture.texel(uv.x, uv.y));
|
||||||
} else {
|
|
||||||
for (uint16_t i = 0; i < height; i++) {
|
|
||||||
for (uint16_t x = (uint16_t)longBound[i]; x <= (uint16_t)splitBound[i]; x++) {
|
|
||||||
buffer.drawPixel(x, i + (uint16_t)topY, shader.c0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
// Right-handed triangle case (midpoint is right of triangle)
|
||||||
|
} else {
|
||||||
} else if (shader.shaderType == HGRADIENT) {
|
for (uint16_t i = 0; i < height; i++) {
|
||||||
// find left and right bounds
|
for (uint16_t x = (uint16_t)longBound[i]; x <= (uint16_t)splitBound[i]; x++) {
|
||||||
uint16_t leftmost = std::min(x0, std::min(x1, x2));
|
uv = mapper.map(leftX, topY, x, i + (uint16_t)topY);
|
||||||
uint16_t rightmost = std::max(x0, std::max(x1, x2));
|
buffer.drawPixel(x, i + (uint16_t)topY, texture.texel(uv.x, uv.y));
|
||||||
|
|
||||||
// precompute gradient LUT
|
|
||||||
Color cols[rightmost - leftmost];
|
|
||||||
for (uint16_t x = leftmost; x < rightmost; x++) {
|
|
||||||
cols[x - leftmost] = ShaderMethods::gradient(shader.u0, shader.scale, shader.c0, shader.c1, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Left-handed triangle case (midpoint is left of triangle)
|
|
||||||
if ((int16_t)midX < longBound[midY - topY]) {
|
|
||||||
for (uint16_t i = 0; i < height; i++) {
|
|
||||||
for (uint16_t x = (uint16_t)splitBound[i]; x <= (uint16_t)longBound[i]; x++) {
|
|
||||||
buffer.drawPixel(x, i + (uint16_t)topY, cols[x - leftmost]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Right-handed triangle case (midpoint is right of triangle)
|
|
||||||
} else {
|
|
||||||
for (uint16_t i = 0; i < height; i++) {
|
|
||||||
for (uint16_t x = (uint16_t)longBound[i]; x <= (uint16_t)splitBound[i]; x++) {
|
|
||||||
buffer.drawPixel(x, i + (uint16_t)topY, cols[x - leftmost]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
|
|
||||||
} else if (shader.shaderType == VGRADIENT) {
|
|
||||||
Color c;
|
|
||||||
|
|
||||||
// Left-handed triangle case (midpoint is left of triangle)
|
|
||||||
if ((int16_t)midX < longBound[midY - topY]) {
|
|
||||||
for (uint16_t i = 0; i < height; i++) {
|
|
||||||
c = ShaderMethods::gradient(shader.v0, shader.scale, shader.c0, shader.c1, i + topY);
|
|
||||||
for (uint16_t x = (uint16_t)splitBound[i]; x <= (uint16_t)longBound[i]; x++) {
|
|
||||||
buffer.drawPixel(x, i + (uint16_t)topY, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Right-handed triangle case (midpoint is right of triangle)
|
|
||||||
} else {
|
|
||||||
for (uint16_t i = 0; i < height; i++) {
|
|
||||||
c = ShaderMethods::gradient(shader.v0, shader.scale, shader.c0, shader.c1, i + topY);
|
|
||||||
for (uint16_t x = (uint16_t)longBound[i]; x <= (uint16_t)splitBound[i]; x++) {
|
|
||||||
buffer.drawPixel(x, i + (uint16_t)topY, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else if (shader.shaderType == BUFFER) {
|
|
||||||
// Left-handed triangle case (midpoint is left of triangle)
|
|
||||||
if ((int16_t)midX < longBound[midY - topY]) {
|
|
||||||
for (uint16_t i = 0; i < height; i++) {
|
|
||||||
for (uint16_t x = (uint16_t)splitBound[i]; x <= (uint16_t)longBound[i]; x++) {
|
|
||||||
buffer.drawPixel(x, i + (uint16_t)topY, ShaderMethods::buffer(shader.u0, shader.v0, shader.buffer, x, i + topY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Right-handed triangle case (midpoint is right of triangle)
|
|
||||||
} else {
|
|
||||||
for (uint16_t i = 0; i < height; i++) {
|
|
||||||
for (uint16_t x = (uint16_t)longBound[i]; x <= (uint16_t)splitBound[i]; x++) {
|
|
||||||
buffer.drawPixel(x, i + (uint16_t)topY, ShaderMethods::buffer(shader.u0, shader.v0, shader.buffer, x, i + topY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
-70
@@ -1,70 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "datatypes.cpp"
|
|
||||||
#include "helpers.cpp"
|
|
||||||
#include "buffer.cpp"
|
|
||||||
|
|
||||||
namespace UwU {
|
|
||||||
// shader prototype
|
|
||||||
class Shader {
|
|
||||||
public:
|
|
||||||
//COLOR Shader
|
|
||||||
Shader(Color color) {
|
|
||||||
this->shaderType = COLOR;
|
|
||||||
this->c0 = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
//HGRADIENT or VGRADIENT shader
|
|
||||||
Shader(Direction direction, uint16_t uv0, uint16_t uv1, Color c0, Color c1) {
|
|
||||||
this->c0 = c0;
|
|
||||||
this->c1 = c1;
|
|
||||||
switch (direction) {
|
|
||||||
case H:
|
|
||||||
shaderType = HGRADIENT;
|
|
||||||
this->u0 = uv0;
|
|
||||||
this->scale = 0xffffffff / (1 + (uint32_t)uv1 - (uint32_t)uv0);
|
|
||||||
break;
|
|
||||||
case V:
|
|
||||||
shaderType = VGRADIENT;
|
|
||||||
this->v0 = uv0;
|
|
||||||
this->scale = 0xffffffff / (1 + (uint32_t)uv1 - (uint32_t)uv0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// BUFFER shader
|
|
||||||
Shader(uint16_t u, uint16_t v, Buffer buffer) {
|
|
||||||
this->shaderType = BUFFER;
|
|
||||||
this->u0 = u;
|
|
||||||
this->v0 = v;
|
|
||||||
this->buffer = buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShaderType shaderType;
|
|
||||||
uint16_t u0;
|
|
||||||
uint16_t v0;
|
|
||||||
Color c0;
|
|
||||||
Color c1;
|
|
||||||
uint32_t scale;
|
|
||||||
Buffer buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ShaderMethods {
|
|
||||||
public:
|
|
||||||
static Color gradient(uint16_t uv0, uint32_t scale, Color c0, Color c1, uint16_t xy) {
|
|
||||||
uint32_t t = (((uint32_t)xy - (uint32_t)uv0) * scale) / 0x01000000;
|
|
||||||
return Helpers::lerpColor(c0, c1, (uint8_t)t);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Color buffer(uint16_t u0, uint16_t v0, Buffer buffer, uint16_t x, uint16_t y) {
|
|
||||||
size_t i = ((size_t)y - (size_t)v0) * buffer.stride + ((size_t)x - (size_t)u0) * 4;
|
|
||||||
uint8_t b = buffer.pixels[i + 0];
|
|
||||||
uint8_t g = buffer.pixels[i + 1];
|
|
||||||
uint8_t r = buffer.pixels[i + 2];
|
|
||||||
uint8_t a = buffer.pixels[i + 3];
|
|
||||||
return Color(r, g, b, a);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "../datatypes.cpp"
|
|
||||||
#include "../helpers.cpp"
|
|
||||||
#include "../buffer.cpp"
|
|
||||||
#include "shaderbase.cpp"
|
|
||||||
|
|
||||||
namespace UwU {
|
|
||||||
class ColorShader : public ShaderBase<ColorShader> {
|
|
||||||
public:
|
|
||||||
ColorShader(Color c) {
|
|
||||||
this->c = c;
|
|
||||||
}
|
|
||||||
Color c;
|
|
||||||
|
|
||||||
Color shade(uint16_t x, uint16_t y) {
|
|
||||||
(void)x;
|
|
||||||
(void)y;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "../datatypes.cpp"
|
|
||||||
#include "../helpers.cpp"
|
|
||||||
#include "../buffer.cpp"
|
|
||||||
#include "shaderbase.cpp"
|
|
||||||
|
|
||||||
namespace UwU {
|
|
||||||
class HGradienthader : public ShaderBase<HGradientShader> {
|
|
||||||
public:
|
|
||||||
HGradientShader(uint16_t u0, uint16_t u1, Color c0, Color c1) {
|
|
||||||
this->u0;
|
|
||||||
this->uScale = 0xffffffff / (1 + (uint32_t)u1 - (uint32_t)u0);
|
|
||||||
this->c0 = c0;
|
|
||||||
this->c1 = c1;
|
|
||||||
}
|
|
||||||
uint16_t u0;
|
|
||||||
uint16_t uScale;
|
|
||||||
Color c0;
|
|
||||||
Color c1;
|
|
||||||
|
|
||||||
Color shade(uint16_t u, uint16_t u) {
|
|
||||||
uint32_t t = (((uint32_t)u - (uint32_t)u0) * uScale) / 0x01000000;
|
|
||||||
return Helpers::lerpColor(c0, c1, (uint8_t)t);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
+1
-4
@@ -1,4 +1 @@
|
|||||||
#include "shaderbase.cpp"
|
#include "shaderbase.cpp"
|
||||||
#include "colorshader.cpp"
|
|
||||||
// #include "hgradientshader.cpp"
|
|
||||||
// #include "vgradientshader.cpp"
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "../datatypes.cpp"
|
|
||||||
#include "../helpers.cpp"
|
|
||||||
#include "../buffer.cpp"
|
|
||||||
#include "shaderbase.cpp"
|
|
||||||
|
|
||||||
namespace UwU {
|
|
||||||
class VGradienthader : public ShaderBase<VGradientShader> {
|
|
||||||
public:
|
|
||||||
VGradientShader(uint16_t v0, uint16_t v1, Color c0, Color c1) {
|
|
||||||
this->v0;
|
|
||||||
this->vScale = 0xffffffff / (1 + (uint32_t)v1 - (uint32_t)v0);
|
|
||||||
this->c0 = c0;
|
|
||||||
this->c1 = c1;
|
|
||||||
}
|
|
||||||
uint16_t v0;
|
|
||||||
uint16_t vScale;
|
|
||||||
Color c0;
|
|
||||||
Color c1;
|
|
||||||
|
|
||||||
Color shade(uint16_t u, uint16_t u) {
|
|
||||||
uint32_t t = (((uint32_t)v - (uint32_t)v0) * vScale) / 0x01000000;
|
|
||||||
return Helpers::lerpColor(c0, c1, (uint8_t)t);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../datatypes.cpp"
|
||||||
|
#include "../helpers.cpp"
|
||||||
|
#include "../buffer.cpp"
|
||||||
|
#include "texturebase.cpp"
|
||||||
|
|
||||||
|
namespace UwU {
|
||||||
|
class BitmapTexture : public TextureBase<BitmapTexture> {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../datatypes.cpp"
|
||||||
|
#include "../helpers.cpp"
|
||||||
|
#include "../buffer.cpp"
|
||||||
|
#include "texturebase.cpp"
|
||||||
|
|
||||||
|
namespace UwU {
|
||||||
|
class ColorTexture : public TextureBase<ColorTexture> {
|
||||||
|
private:
|
||||||
|
Color color;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ColorTexture(Color color) {
|
||||||
|
this->color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color texel(uint16_t u, uint16_t v) {
|
||||||
|
(void)u;
|
||||||
|
(void)v;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../datatypes.cpp"
|
||||||
|
#include "../helpers.cpp"
|
||||||
|
#include "../buffer.cpp"
|
||||||
|
#include "texturebase.cpp"
|
||||||
|
|
||||||
|
namespace UwU {
|
||||||
|
class GradientTexture : public TextureBase<GradientTexture> {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../datatypes.cpp"
|
||||||
|
#include "../helpers.cpp"
|
||||||
|
#include "../buffer.cpp"
|
||||||
|
#include "texturebase.cpp"
|
||||||
|
|
||||||
|
namespace UwU {
|
||||||
|
class HGradientTexture : public TextureBase<HGradientTexture> {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../datatypes.cpp"
|
||||||
|
#include "../helpers.cpp"
|
||||||
|
#include "../buffer.cpp"
|
||||||
|
|
||||||
|
namespace UwU {
|
||||||
|
template <class TextureT>
|
||||||
|
class TextureBase {
|
||||||
|
public:
|
||||||
|
Color texel(uint16_t u, uint16_t v) {
|
||||||
|
return static_cast<TextureT*>(this)->texel(u, v);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../datatypes.cpp"
|
||||||
|
#include "../helpers.cpp"
|
||||||
|
#include "../buffer.cpp"
|
||||||
|
#include "texturebase.cpp"
|
||||||
|
#include "../tilemap.cpp"
|
||||||
|
|
||||||
|
namespace UwU {
|
||||||
|
class TilemapTexture : public TextureBase<TilemapTexture> {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../datatypes.cpp"
|
||||||
|
#include "../helpers.cpp"
|
||||||
|
#include "../buffer.cpp"
|
||||||
|
#include "texturebase.cpp"
|
||||||
|
|
||||||
|
namespace UwU {
|
||||||
|
class VGradientTexture : public TextureBase<VGradientTexture> {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -2,9 +2,8 @@
|
|||||||
#include "helpers.cpp"
|
#include "helpers.cpp"
|
||||||
#include "buffer.cpp"
|
#include "buffer.cpp"
|
||||||
#include "surface.cpp"
|
#include "surface.cpp"
|
||||||
#include "primatives/line.cpp"
|
#include "primatives/primatives.h"
|
||||||
#include "primatives/point.cpp"
|
#include "mappers/mappers.h"
|
||||||
#include "primatives/rectangle.cpp"
|
#include "textures/textures.h"
|
||||||
#include "primatives/trapezoid.cpp"
|
#include "tilemap.cpp"
|
||||||
#include "primatives/triangle.cpp"
|
// #include "shaders/shaders.h"
|
||||||
#include "shader.cpp"
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user