diff --git a/example.cpp b/example.cpp index 0e4d4cd..1fb0291 100644 --- a/example.cpp +++ b/example.cpp @@ -49,6 +49,10 @@ int main(void) { UwU::ColorShader blue = UwU::ColorShader(UwU::Color(0x0000ffff)); UwU::Trapezoid trapezoid = UwU::Trapezoid(100, 300, 690, 320, 720, 780); trapezoid.draw(surface.buffer, blue); + + UwU::ColorShader red = UwU::ColorShader(UwU::Color(0xff0000ff)); + UwU::Triangle triangle = UwU::Triangle(140, 140, 60, 400, 240, 240); + triangle.draw(surface.buffer, red); // // Benchmarking // struct timespec start, end; diff --git a/primatives/triangle.cpp b/primatives/triangle.cpp index 6fc7a08..6c22b71 100644 --- a/primatives/triangle.cpp +++ b/primatives/triangle.cpp @@ -6,7 +6,7 @@ #include "../datatypes.cpp" #include "../helpers.cpp" #include "../buffer.cpp" -#include "../shader.cpp" +#include "../shaders/shaders.h" namespace UwU { class Triangle { @@ -30,7 +30,8 @@ namespace UwU { uint16_t y2; // Draw a triangle - void draw (Buffer buffer, Shader shader) { + template + void draw (Buffer buffer, ShaderBase& shader) { uint16_t topX, topY, midX, midY, btmX, btmY; // Find top, middle and bottom points of triangle if (y0 <= y1 && y0 <= y2) { @@ -90,91 +91,20 @@ namespace UwU { Helpers::bresenham(0, topX, midY - topY, midX, splitBound); Helpers::bresenham(midY - topY, midX, height - 1, btmX, splitBound); - if (shader.shaderType == COLOR) { - // 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, shader.c0); - } - } - // 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, shader.c0); - } + // 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, shader.shade(x, i + (uint16_t)topY)); } } - return; - - } else if (shader.shaderType == HGRADIENT) { - // find left and right bounds - uint16_t leftmost = std::min(x0, std::min(x1, x2)); - uint16_t rightmost = std::max(x0, std::max(x1, x2)); - - // 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]); - } + // 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, shader.shade(x, i + (uint16_t)topY)); } } - 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; }