179 lines
5.5 KiB
C
179 lines
5.5 KiB
C
#include "triangle.h"
|
|
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
#include "display.h"
|
|
|
|
// TODO: Create implementation for triangle.h functions
|
|
int compare_vec2_t(const void* a, const void* b) {
|
|
const int_vec2_t* arg1 = (const int_vec2_t*)a;
|
|
const int_vec2_t* arg2 = (const int_vec2_t*)b;
|
|
if (arg1->y < arg2->y) return -1;
|
|
if (arg1->y > arg2->y) return 1;
|
|
return 0;
|
|
}
|
|
|
|
#define FUNC (int)ceilf
|
|
#define FUNC2 (int)floorf
|
|
|
|
uint32_t invert_rgb(uint32_t color) {
|
|
uint32_t a = color & 0xFF000000; // Alpha channel
|
|
uint32_t rgb = color & 0x00FFFFFF; // RGB channels
|
|
rgb = ~rgb & 0x00FFFFFF; // Invert RGB only
|
|
return a | rgb;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Draw a filled a triangle with a flat bottom
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// (x0,y0)
|
|
// / \
|
|
// / \
|
|
// / \
|
|
// / \
|
|
// / \
|
|
// (x1,y1)------(x2,y2)
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void fill_flat_bottom_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t color) {
|
|
// Find the two slopes (two triangle legs)
|
|
float inv_slope_1 = (float)(x1 - x0) / (y1 - y0);
|
|
float inv_slope_2 = (float)(x2 - x0) / (y2 - y0);
|
|
|
|
// Start x_start and x_end from the top vertex (x0,y0)
|
|
float x_start = x0;
|
|
float x_end = x0;
|
|
|
|
// Loop all the scanlines from top to bottom
|
|
for (int y = y0; y <= y2; y++) {
|
|
draw_line(x_start, y, x_end, y, color);
|
|
x_start += inv_slope_1;
|
|
x_end += inv_slope_2;
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Draw a filled a triangle with a flat top
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// (x0,y0)------(x1,y1)
|
|
// \ /
|
|
// \ /
|
|
// \ /
|
|
// \ /
|
|
// \ /
|
|
// (x2,y2)
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void fill_flat_top_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t color) {
|
|
// Find the two slopes (two triangle legs)
|
|
float inv_slope_1 = (float)(x2 - x0) / (y2 - y0);
|
|
float inv_slope_2 = (float)(x2 - x1) / (y2 - y1);
|
|
|
|
// Start x_start and x_end from the bottom vertex (x2,y2)
|
|
float x_start = x2;
|
|
float x_end = x2;
|
|
|
|
// Loop all the scanlines from bottom to top
|
|
for (int y = y2; y >= y0; y--) {
|
|
draw_line(x_start, y, x_end, y, color);
|
|
x_start -= inv_slope_1;
|
|
x_end -= inv_slope_2;
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Draw a filled triangle with the flat-top/flat-bottom method
|
|
// We split the original triangle in two, half flat-bottom and half flat-top
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// (x0,y0)
|
|
// / \
|
|
// / \
|
|
// / \
|
|
// / \
|
|
// / \
|
|
// (x1,y1)------(Mx,My)
|
|
// \_ \
|
|
// \_ \
|
|
// \_ \
|
|
// \_ \
|
|
// \ \
|
|
// \_ \
|
|
// \_\
|
|
// \
|
|
// (x2,y2)
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void draw_filled_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t color) {
|
|
// We need to sort the vertices by y-coordinate ascending (y0 < y1 < y2)
|
|
if (y0 > y1) {
|
|
int_swap(&y0, &y1);
|
|
int_swap(&x0, &x1);
|
|
}
|
|
if (y1 > y2) {
|
|
int_swap(&y1, &y2);
|
|
int_swap(&x1, &x2);
|
|
}
|
|
if (y0 > y1) {
|
|
int_swap(&y0, &y1);
|
|
int_swap(&x0, &x1);
|
|
}
|
|
|
|
if (y1 == y2) {
|
|
// Draw flat-bottom triangle
|
|
fill_flat_bottom_triangle(x0, y0, x1, y1, x2, y2, color);
|
|
} else if (y0 == y1) {
|
|
// Draw flat-top triangle
|
|
fill_flat_top_triangle(x0, y0, x1, y1, x2, y2, color);
|
|
} else {
|
|
// Calculate the new vertex (Mx,My) using triangle similarity
|
|
int My = y1;
|
|
int Mx = (((x2 - x0) * (y1 - y0)) / (y2 - y0)) + x0;
|
|
|
|
// Draw flat-bottom triangle
|
|
fill_flat_bottom_triangle(x0, y0, x1, y1, Mx, My, color);
|
|
|
|
// Draw flat-top triangle
|
|
fill_flat_top_triangle(x1, y1, Mx, My, x2, y2, color);
|
|
}
|
|
}
|
|
|
|
void draw_textured_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t* texture) {
|
|
// sort by y
|
|
int temp = 0, min_idx = 0, mid_idx = 1, max_idx = 2;
|
|
|
|
// We need to sort the vertices by y-coordinate ascending (y0 < y1 < y2)
|
|
if (y0 > y1) {
|
|
int_swap(&y0, &y1);
|
|
int_swap(&x0, &x1);
|
|
}
|
|
if (y1 > y2) {
|
|
int_swap(&y1, &y2);
|
|
int_swap(&x1, &x2);
|
|
}
|
|
if (y0 > y1) {
|
|
int_swap(&y0, &y1);
|
|
int_swap(&x0, &x1);
|
|
}
|
|
|
|
float inv_slope_1 = 0;
|
|
float inv_slope_2 = 0;
|
|
|
|
/*if (triangle.points[mid_idx].y - triangle.points[min_idx].y != 0) {
|
|
inv_slope_1 = (float)(triangle.points[mid_idx].x - triangle.points[min_idx].x) / fabsf(triangle.points[mid_idx].y - triangle.points[min_idx].y);
|
|
}
|
|
|
|
if (triangle.points[max_idx].y - triangle.points[min_idx].y != 0) {
|
|
inv_slope_2 = (float)(triangle.points[max_idx].x - triangle.points[min_idx].x) / fabsf(triangle.points[max_idx].y - triangle.points[min_idx].y);
|
|
}
|
|
|
|
for (int y = triangle.points[min_idx].y; y <= triangle.points[mid_idx].y; y++) {
|
|
//float x_start = triangle
|
|
}
|
|
*/
|
|
|
|
|
|
} |