refactor to plain x/y
This commit is contained in:
parent
5b8347afaa
commit
7a91b72708
@ -12,6 +12,7 @@ add_executable(${PROJECT_NAME} scripts/main.c
|
||||
scripts/triangle.c
|
||||
scripts/light.c
|
||||
scripts/texture.c
|
||||
scripts/swap.c
|
||||
scripts/display.c)
|
||||
|
||||
# --- SDL2 SETUP ---
|
||||
|
||||
@ -152,9 +152,9 @@ void update(void) {
|
||||
|
||||
previous_frame_time = SDL_GetTicks();
|
||||
|
||||
//mesh.rotation.y += 0.01f;
|
||||
mesh.rotation.y += 0.01f;
|
||||
mesh.rotation.x -= 0.01f;
|
||||
//mesh.rotation.z += 0.01f;
|
||||
mesh.rotation.z += 0.01f;
|
||||
|
||||
//mesh.translation.x += 0.004f;
|
||||
mesh.translation.z = 5.0f;
|
||||
@ -317,17 +317,27 @@ void render(void) {
|
||||
draw_rect(triangle.points[2].x, triangle.points[2].y, 3, 3, 0xFFFFFF00);
|
||||
break;
|
||||
case RENDER_FILL_TRIANGLE:
|
||||
draw_filled_triangle(triangle);
|
||||
draw_filled_triangle(
|
||||
triangle.points[0].x, triangle.points[0].y, // vertex A
|
||||
triangle.points[1].x, triangle.points[1].y, // vertex B
|
||||
triangle.points[2].x, triangle.points[2].y,
|
||||
triangle.color
|
||||
);
|
||||
break;
|
||||
case RENDER_FILL_TRIANGLE_LINE:
|
||||
draw_filled_triangle(triangle);
|
||||
draw_filled_triangle(
|
||||
triangle.points[0].x, triangle.points[0].y, // vertex A
|
||||
triangle.points[1].x, triangle.points[1].y, // vertex B
|
||||
triangle.points[2].x, triangle.points[2].y, // vertex C
|
||||
triangle.color
|
||||
);
|
||||
draw_triangle(triangle, 0xff0000ff);
|
||||
break;
|
||||
case RENDER_TEXTURED:
|
||||
draw_textured_triangle(triangle, mesh_texture);
|
||||
//draw_textured_triangle(triangle, mesh_texture);
|
||||
break;
|
||||
case RENDER_TEXTURED_LINE:
|
||||
draw_textured_triangle(triangle, mesh_texture);
|
||||
//draw_textured_triangle(triangle, mesh_texture);
|
||||
draw_triangle(triangle, 0xff0000ff);
|
||||
default:
|
||||
break;
|
||||
|
||||
13
scripts/swap.c
Normal file
13
scripts/swap.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include "swap.h"
|
||||
|
||||
void int_swap(int* a, int* b) {
|
||||
int tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
void float_swap(float* a, float* b) {
|
||||
float tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
2
scripts/swap.h
Normal file
2
scripts/swap.h
Normal file
@ -0,0 +1,2 @@
|
||||
void int_swap(int* a, int* b);
|
||||
void float_swap(float* a, float* b);
|
||||
@ -1,5 +1,6 @@
|
||||
#include "triangle.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "display.h"
|
||||
@ -23,94 +24,145 @@ uint32_t invert_rgb(uint32_t color) {
|
||||
return a | rgb;
|
||||
}
|
||||
|
||||
void fill_flat_bottom_triangle(const triangle_t* triangle, color_t color) {
|
||||
float inv_slope_1 = (float)(triangle->points[1].x - triangle->points[0].x) / (float)(triangle->points[1].y - triangle->points[0].y);
|
||||
float inv_slope_2 = (float)(triangle->points[2].x - triangle->points[0].x) / (float)(triangle->points[2].y - triangle->points[0].y);;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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);
|
||||
|
||||
float x_start = (float)triangle->points[0].x, x_end = (float)triangle->points[0].x;
|
||||
// Start x_start and x_end from the top vertex (x0,y0)
|
||||
float x_start = x0;
|
||||
float x_end = x0;
|
||||
|
||||
for (int x = triangle->points[0].y; x <= triangle->points[2].y; x++) {
|
||||
//draw_rect((int)triangle->points[0].x, i, 1, 1, 0xFFFF0000);
|
||||
draw_line((int)x_start, x, (int)x_end, x, color);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
void fill_flat_top_triangle(const triangle_t* triangle, color_t color) {
|
||||
float inv_slope_1 = (float)(triangle->points[2].x - triangle->points[0].x) / (float)(triangle->points[2].y - triangle->points[0].y);
|
||||
float inv_slope_2 = (float)(triangle->points[2].x - triangle->points[1].x) / (float)(triangle->points[2].y - triangle->points[1].y);;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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);
|
||||
|
||||
float x_start = (float)triangle->points[2].x, x_end = (float)triangle->points[2].x;
|
||||
// Start x_start and x_end from the bottom vertex (x2,y2)
|
||||
float x_start = x2;
|
||||
float x_end = x2;
|
||||
|
||||
for (int y = triangle->points[2].y; y >= triangle->points[0].y; y--) {
|
||||
//draw_rect((int)triangle->points[0].x, i, 1, 1, 0xFFFF0000);
|
||||
draw_line((int)x_start, y, (int)x_end, y, color);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_filled_triangle(triangle_t triangle) {
|
||||
// sort by y
|
||||
int temp = 0, min_idx = 0, mid_idx = 1, max_idx = 2;
|
||||
|
||||
if (triangle.points[min_idx].y > triangle.points[mid_idx].y) {
|
||||
temp = min_idx; min_idx = mid_idx; mid_idx = temp;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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 (triangle.points[min_idx].y > triangle.points[max_idx].y) {
|
||||
temp = min_idx; min_idx = max_idx; max_idx = temp;
|
||||
if (y1 > y2) {
|
||||
int_swap(&y1, &y2);
|
||||
int_swap(&x1, &x2);
|
||||
}
|
||||
if (triangle.points[mid_idx].y > triangle.points[max_idx].y) {
|
||||
temp = mid_idx; mid_idx = max_idx; max_idx = temp;
|
||||
if (y0 > y1) {
|
||||
int_swap(&y0, &y1);
|
||||
int_swap(&x0, &x1);
|
||||
}
|
||||
|
||||
color_t color = triangle.color ? triangle.color : 0xFF00FF00; // Default to 0xFF00FF00 if not setr; // Default color if not set
|
||||
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;
|
||||
|
||||
if (triangle.points[mid_idx].y == triangle.points[max_idx].y) {
|
||||
fill_flat_bottom_triangle(&triangle, color);
|
||||
} else if (triangle.points[min_idx].y == triangle.points[mid_idx].y) {
|
||||
fill_flat_top_triangle(&triangle, color);
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
int_vec2_t midpoint;
|
||||
midpoint.y = triangle.points[mid_idx].y;
|
||||
midpoint.x = (((triangle.points[max_idx].x - triangle.points[min_idx].x) * (triangle.points[mid_idx].y - triangle.points[min_idx].y)) / (triangle.points[max_idx].y - triangle.points[min_idx].y)) + triangle.points[min_idx].x;
|
||||
|
||||
triangle_t flat_top, flat_bottom;
|
||||
|
||||
flat_bottom.points[0] = triangle.points[min_idx];
|
||||
flat_bottom.points[1] = triangle.points[mid_idx];
|
||||
flat_bottom.points[2] = midpoint;
|
||||
|
||||
flat_top.points[0] = triangle.points[mid_idx];
|
||||
flat_top.points[1] = midpoint;
|
||||
flat_top.points[2] = triangle.points[max_idx];
|
||||
|
||||
fill_flat_bottom_triangle(&flat_bottom, color);
|
||||
fill_flat_top_triangle(&flat_top, (color));
|
||||
|
||||
}
|
||||
|
||||
void draw_textured_triangle(triangle_t triangle, uint32_t* texture) {
|
||||
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;
|
||||
|
||||
if (triangle.points[min_idx].y > triangle.points[mid_idx].y) {
|
||||
temp = min_idx; min_idx = mid_idx; mid_idx = temp;
|
||||
// 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 (triangle.points[min_idx].y > triangle.points[max_idx].y) {
|
||||
temp = min_idx; min_idx = max_idx; max_idx = temp;
|
||||
if (y1 > y2) {
|
||||
int_swap(&y1, &y2);
|
||||
int_swap(&x1, &x2);
|
||||
}
|
||||
if (triangle.points[mid_idx].y > triangle.points[max_idx].y) {
|
||||
temp = mid_idx; mid_idx = max_idx; max_idx = temp;
|
||||
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) {
|
||||
/*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);
|
||||
}
|
||||
|
||||
@ -121,6 +173,7 @@ void draw_textured_triangle(triangle_t triangle, uint32_t* texture) {
|
||||
for (int y = triangle.points[min_idx].y; y <= triangle.points[mid_idx].y; y++) {
|
||||
//float x_start = triangle
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
@ -4,6 +4,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "texture.h"
|
||||
#include "swap.h"
|
||||
#include "vector.h"
|
||||
#include "texture.h"
|
||||
|
||||
@ -25,14 +26,14 @@ typedef struct {
|
||||
} int_vec2_t;
|
||||
|
||||
typedef struct {
|
||||
int_vec2_t points[3];
|
||||
vec2_t points[3];
|
||||
tex2_t texcoords[3];
|
||||
color_t color;
|
||||
float average_depth;
|
||||
} triangle_t;
|
||||
|
||||
void draw_filled_triangle(triangle_t triangle);
|
||||
void draw_textured_triangle(triangle_t triangle, uint32_t* texture);
|
||||
void draw_filled_triangle(int x0, int y0, int x1, int y1, int x2, int y2, color_t color);
|
||||
void draw_textured_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t* texture);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user