depth sorting

This commit is contained in:
jb 2025-07-11 21:08:11 -07:00
parent 57699deea9
commit 38ea89c4a6
6 changed files with 268048 additions and 24 deletions

267979
assets/tank.obj Normal file

File diff suppressed because it is too large Load Diff

View File

@ -36,6 +36,7 @@ bool is_running = false;
int cull_method = CULL_BACKFACE;
int render_method = RENDER_WIRE_VERTEX;
bool sort_faces = true;
uint32_t previous_frame_time = 0;
@ -53,7 +54,8 @@ void setup(void) {
);
// load cube mesh data
load_file();
//load_file("..\\assets\\tank.obj");
load_cube_mesh_data();
}
@ -82,6 +84,10 @@ void process_input(void) {
cull_method = !cull_method;
}
if (key == SDLK_s) {
sort_faces = !sort_faces;
}
if (key == SDLK_1) {
render_method = RENDER_WIRE_VERTEX;
}
@ -196,6 +202,10 @@ void update(void) {
projected_triangle.points[j] = projected_point;
}
// calculate the average depth of the triangle
projected_triangle.average_depth = (transformed_vertices[0].z + transformed_vertices[1].z + transformed_vertices[2].z) / 3.0f;
projected_triangle.color = mesh_face.color;// | 0xFF00FF00;
//vec2_t midpoint = triangle_midpoint(projected_triangle);
//draw_rect(midpoint.x, midpoint.y, 10, 10, 0xFFFF0000);
@ -207,12 +217,25 @@ void update(void) {
}
}
int depth_comp(const void* a, const void* b) {
triangle_t arg_a = *(const triangle_t*)a;
triangle_t arg_b = *(const triangle_t*)b;
if (arg_a.average_depth < arg_b.average_depth) return -1;
if (arg_a.average_depth > arg_b.average_depth) return 1;
return 0;
}
void render(void) {
draw_grid();
//uint32_t colors[] = { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFF757500, 0xFF007575, 0xFF750075 };
// Loop all projected points and render them
size_t arr_length = array_length(triangles_to_render);
for (int i = 0; i < array_length(triangles_to_render); i++) {
// sort triangles
if (sort_faces) qsort(triangles_to_render, arr_length, sizeof(triangle_t), depth_comp);
for (int i = 0; i < arr_length; i++) {
triangle_t triangle = triangles_to_render[i];
switch (render_method) {
@ -220,16 +243,16 @@ void render(void) {
draw_triangle(triangle, 0x0000ff);
break;
case RENDER_WIRE_VERTEX:
draw_triangle(triangle, 0x000055);
draw_triangle(triangle, 0x0000ff);
draw_rect(triangle.points[0].x, triangle.points[0].y, 3, 3, 0xFFFFFF00);
draw_rect(triangle.points[1].x, triangle.points[1].y, 3, 3, 0xFFFFFF00);
draw_rect(triangle.points[2].x, triangle.points[2].y, 3, 3, 0xFFFFFF00);
break;
case RENDER_FILL_TRIANGLE:
draw_filled_triangle(triangle, 0x0000ff);
draw_filled_triangle(triangle);
break;
case RENDER_FILL_TRIANGLE_LINE:
draw_filled_triangle(triangle, 0xff00);
draw_filled_triangle(triangle);
draw_triangle(triangle, 0x0000ff);
break;
default:

View File

@ -27,23 +27,23 @@ vec3_t cube_vertices[N_CUBE_VERTICES] = {
face_t cube_faces[N_CUBE_FACES] = {
// front
{ .a = 1, .b = 2, .c = 3 },
{ .a = 1, .b = 3, .c = 4 },
{ .a = 1, .b = 2, .c = 3 , .color = COLOR_ORANGE},
{ .a = 1, .b = 3, .c = 4, .color = COLOR_ORANGE},
// right
{ .a = 4, .b = 3, .c = 5 },
{ .a = 4, .b = 5, .c = 6 },
{ .a = 4, .b = 3, .c = 5, .color = COLOR_TEAL_GREEN },
{ .a = 4, .b = 5, .c = 6, .color = COLOR_TEAL_GREEN},
// back
{ .a = 6, .b = 5, .c = 7 },
{ .a = 6, .b = 7, .c = 8 },
{ .a = 6, .b = 5, .c = 7, .color = COLOR_RED },
{ .a = 6, .b = 7, .c = 8, .color = COLOR_RED },
// left
{ .a = 8, .b = 7, .c = 2 },
{ .a = 8, .b = 2, .c = 1 },
{ .a = 8, .b = 7, .c = 2, .color = COLOR_PURPLE },
{ .a = 8, .b = 2, .c = 1, .color = COLOR_PURPLE },
// top
{ .a = 2, .b = 7, .c = 5 },
{ .a = 2, .b = 5, .c = 3 },
{ .a = 2, .b = 7, .c = 5, .color = COLOR_GREY },
{ .a = 2, .b = 5, .c = 3, .color = COLOR_GREY },
// bottom
{ .a = 6, .b = 8, .c = 1 },
{ .a = 6, .b = 1, .c = 4 }
{ .a = 6, .b = 8, .c = 1, .color = COLOR_LIGHT_GREEN_BLUE },
{ .a = 6, .b = 1, .c = 4, .color = COLOR_LIGHT_GREEN_BLUE }
};
void load_cube_mesh_data(void) {
@ -71,11 +71,11 @@ void parse_face(const char* buffer, face_t* face) {
face->c = token ? atoi(token) : -1;
}
void load_file(void) {
void load_file(const char* filename) {
FILE* fp;
char* tok;
fp = fopen("..\\assets\\f22.obj", "r");
fp = fopen(filename, "r");
if (fp == NULL) {
exit(EXIT_FAILURE);

View File

@ -12,6 +12,21 @@
extern vec3_t cube_vertices[N_CUBE_VERTICES];
extern face_t cube_faces[N_CUBE_FACES];
typedef enum {
COLOR_PURPLE = 0xFF6A2EFF,
COLOR_SAND_YELLOW = 0xFFE9C46A,
COLOR_TEAL_GREEN = 0xFF2A9D8F,
COLOR_ORANGE = 0xFFF4A261,
COLOR_DARK_BLUE_GREY = 0xFF264653,
COLOR_MAUVE = 0xFFB5838D,
COLOR_RED = 0xFFD7263D,
COLOR_TURQUOISE = 0xFF38A3A5,
COLOR_GREY = 0xFF757575,
COLOR_LIGHT_GREEN_BLUE = 0xFF70C1B3,
COLOR_YELLOW = 0xFFFFC300,
COLOR_DEEP_PURPLE = 0xFF5D2E8C
} color_enum_t;
typedef struct mesh_t mesh_t;
struct mesh_t {
vec3_t* vertices;
@ -24,6 +39,6 @@ extern mesh_t mesh;
void parse_face(const char* buffer, face_t* face);
void load_cube_mesh_data(void);
void load_file(void);
void load_file(const char* filename);
#endif

View File

@ -23,7 +23,7 @@ uint32_t invert_rgb(uint32_t color) {
return a | rgb;
}
void fill_flat_bottom_triangle(const triangle_t* triangle, uint32_t color) {
void fill_flat_bottom_triangle(const triangle_t* triangle, color_t color) {
float inv_slope_1 = (triangle->points[1].x - triangle->points[0].x) / (triangle->points[1].y - triangle->points[0].y);
float inv_slope_2 = (triangle->points[2].x - triangle->points[0].x) / (triangle->points[2].y - triangle->points[0].y);;
@ -37,7 +37,7 @@ void fill_flat_bottom_triangle(const triangle_t* triangle, uint32_t color) {
}
}
void fill_flat_top_triangle(const triangle_t* triangle, uint32_t color) {
void fill_flat_top_triangle(const triangle_t* triangle, color_t color) {
float inv_slope_1 = (triangle->points[2].x - triangle->points[0].x) / (triangle->points[2].y - triangle->points[0].y);
float inv_slope_2 = (triangle->points[2].x - triangle->points[1].x) / (triangle->points[2].y - triangle->points[1].y);;
@ -51,7 +51,7 @@ void fill_flat_top_triangle(const triangle_t* triangle, uint32_t color) {
}
}
void draw_filled_triangle(triangle_t triangle, uint32_t color) {
void draw_filled_triangle(triangle_t triangle) {
// sort by y
int temp = 0, min_idx = 0, mid_idx = 1, max_idx = 2;
@ -65,6 +65,8 @@ void draw_filled_triangle(triangle_t triangle, uint32_t color) {
temp = mid_idx; mid_idx = max_idx; max_idx = temp;
}
color_t color = triangle.color ? triangle.color : 0xFF00FF00; // Default to 0xFF00FF00 if not setr; // Default color if not set
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) {

View File

@ -4,10 +4,13 @@
#include <stdint.h>
#include "vector.h"
typedef uint32_t color_t;
typedef struct {
int a;
int b;
int c;
color_t color;
} face_t;
typedef struct {
@ -17,8 +20,10 @@ typedef struct {
typedef struct {
vec2_t points[3];
color_t color;
float average_depth;
} triangle_t;
void draw_filled_triangle(triangle_t triangle, uint32_t color);
void draw_filled_triangle(triangle_t triangle);
#endif