depth sorting
This commit is contained in:
parent
57699deea9
commit
38ea89c4a6
267979
assets/tank.obj
Normal file
267979
assets/tank.obj
Normal file
File diff suppressed because it is too large
Load Diff
@ -36,6 +36,7 @@ bool is_running = false;
|
|||||||
|
|
||||||
int cull_method = CULL_BACKFACE;
|
int cull_method = CULL_BACKFACE;
|
||||||
int render_method = RENDER_WIRE_VERTEX;
|
int render_method = RENDER_WIRE_VERTEX;
|
||||||
|
bool sort_faces = true;
|
||||||
|
|
||||||
uint32_t previous_frame_time = 0;
|
uint32_t previous_frame_time = 0;
|
||||||
|
|
||||||
@ -53,7 +54,8 @@ void setup(void) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// load cube mesh data
|
// 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;
|
cull_method = !cull_method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key == SDLK_s) {
|
||||||
|
sort_faces = !sort_faces;
|
||||||
|
}
|
||||||
|
|
||||||
if (key == SDLK_1) {
|
if (key == SDLK_1) {
|
||||||
render_method = RENDER_WIRE_VERTEX;
|
render_method = RENDER_WIRE_VERTEX;
|
||||||
}
|
}
|
||||||
@ -196,6 +202,10 @@ void update(void) {
|
|||||||
projected_triangle.points[j] = projected_point;
|
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);
|
//vec2_t midpoint = triangle_midpoint(projected_triangle);
|
||||||
//draw_rect(midpoint.x, midpoint.y, 10, 10, 0xFFFF0000);
|
//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) {
|
void render(void) {
|
||||||
draw_grid();
|
draw_grid();
|
||||||
//uint32_t colors[] = { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFF757500, 0xFF007575, 0xFF750075 };
|
//uint32_t colors[] = { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFF757500, 0xFF007575, 0xFF750075 };
|
||||||
// Loop all projected points and render them
|
// 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];
|
triangle_t triangle = triangles_to_render[i];
|
||||||
|
|
||||||
switch (render_method) {
|
switch (render_method) {
|
||||||
@ -220,16 +243,16 @@ void render(void) {
|
|||||||
draw_triangle(triangle, 0x0000ff);
|
draw_triangle(triangle, 0x0000ff);
|
||||||
break;
|
break;
|
||||||
case RENDER_WIRE_VERTEX:
|
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[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[1].x, triangle.points[1].y, 3, 3, 0xFFFFFF00);
|
||||||
draw_rect(triangle.points[2].x, triangle.points[2].y, 3, 3, 0xFFFFFF00);
|
draw_rect(triangle.points[2].x, triangle.points[2].y, 3, 3, 0xFFFFFF00);
|
||||||
break;
|
break;
|
||||||
case RENDER_FILL_TRIANGLE:
|
case RENDER_FILL_TRIANGLE:
|
||||||
draw_filled_triangle(triangle, 0x0000ff);
|
draw_filled_triangle(triangle);
|
||||||
break;
|
break;
|
||||||
case RENDER_FILL_TRIANGLE_LINE:
|
case RENDER_FILL_TRIANGLE_LINE:
|
||||||
draw_filled_triangle(triangle, 0xff00);
|
draw_filled_triangle(triangle);
|
||||||
draw_triangle(triangle, 0x0000ff);
|
draw_triangle(triangle, 0x0000ff);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -27,23 +27,23 @@ vec3_t cube_vertices[N_CUBE_VERTICES] = {
|
|||||||
|
|
||||||
face_t cube_faces[N_CUBE_FACES] = {
|
face_t cube_faces[N_CUBE_FACES] = {
|
||||||
// front
|
// front
|
||||||
{ .a = 1, .b = 2, .c = 3 },
|
{ .a = 1, .b = 2, .c = 3 , .color = COLOR_ORANGE},
|
||||||
{ .a = 1, .b = 3, .c = 4 },
|
{ .a = 1, .b = 3, .c = 4, .color = COLOR_ORANGE},
|
||||||
// right
|
// right
|
||||||
{ .a = 4, .b = 3, .c = 5 },
|
{ .a = 4, .b = 3, .c = 5, .color = COLOR_TEAL_GREEN },
|
||||||
{ .a = 4, .b = 5, .c = 6 },
|
{ .a = 4, .b = 5, .c = 6, .color = COLOR_TEAL_GREEN},
|
||||||
// back
|
// back
|
||||||
{ .a = 6, .b = 5, .c = 7 },
|
{ .a = 6, .b = 5, .c = 7, .color = COLOR_RED },
|
||||||
{ .a = 6, .b = 7, .c = 8 },
|
{ .a = 6, .b = 7, .c = 8, .color = COLOR_RED },
|
||||||
// left
|
// left
|
||||||
{ .a = 8, .b = 7, .c = 2 },
|
{ .a = 8, .b = 7, .c = 2, .color = COLOR_PURPLE },
|
||||||
{ .a = 8, .b = 2, .c = 1 },
|
{ .a = 8, .b = 2, .c = 1, .color = COLOR_PURPLE },
|
||||||
// top
|
// top
|
||||||
{ .a = 2, .b = 7, .c = 5 },
|
{ .a = 2, .b = 7, .c = 5, .color = COLOR_GREY },
|
||||||
{ .a = 2, .b = 5, .c = 3 },
|
{ .a = 2, .b = 5, .c = 3, .color = COLOR_GREY },
|
||||||
// bottom
|
// bottom
|
||||||
{ .a = 6, .b = 8, .c = 1 },
|
{ .a = 6, .b = 8, .c = 1, .color = COLOR_LIGHT_GREEN_BLUE },
|
||||||
{ .a = 6, .b = 1, .c = 4 }
|
{ .a = 6, .b = 1, .c = 4, .color = COLOR_LIGHT_GREEN_BLUE }
|
||||||
};
|
};
|
||||||
|
|
||||||
void load_cube_mesh_data(void) {
|
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;
|
face->c = token ? atoi(token) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_file(void) {
|
void load_file(const char* filename) {
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
char* tok;
|
char* tok;
|
||||||
|
|
||||||
fp = fopen("..\\assets\\f22.obj", "r");
|
fp = fopen(filename, "r");
|
||||||
|
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|||||||
@ -12,6 +12,21 @@
|
|||||||
extern vec3_t cube_vertices[N_CUBE_VERTICES];
|
extern vec3_t cube_vertices[N_CUBE_VERTICES];
|
||||||
extern face_t cube_faces[N_CUBE_FACES];
|
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;
|
typedef struct mesh_t mesh_t;
|
||||||
struct mesh_t {
|
struct mesh_t {
|
||||||
vec3_t* vertices;
|
vec3_t* vertices;
|
||||||
@ -24,6 +39,6 @@ extern mesh_t mesh;
|
|||||||
void parse_face(const char* buffer, face_t* face);
|
void parse_face(const char* buffer, face_t* face);
|
||||||
|
|
||||||
void load_cube_mesh_data(void);
|
void load_cube_mesh_data(void);
|
||||||
void load_file(void);
|
void load_file(const char* filename);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -23,7 +23,7 @@ uint32_t invert_rgb(uint32_t color) {
|
|||||||
return a | rgb;
|
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_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);;
|
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_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);;
|
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
|
// sort by y
|
||||||
int temp = 0, min_idx = 0, mid_idx = 1, max_idx = 2;
|
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;
|
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) {
|
if (triangle.points[mid_idx].y == triangle.points[max_idx].y) {
|
||||||
fill_flat_bottom_triangle(&triangle, color);
|
fill_flat_bottom_triangle(&triangle, color);
|
||||||
} else if (triangle.points[min_idx].y == triangle.points[mid_idx].y) {
|
} else if (triangle.points[min_idx].y == triangle.points[mid_idx].y) {
|
||||||
|
|||||||
@ -4,10 +4,13 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
|
|
||||||
|
typedef uint32_t color_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int a;
|
int a;
|
||||||
int b;
|
int b;
|
||||||
int c;
|
int c;
|
||||||
|
color_t color;
|
||||||
} face_t;
|
} face_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -17,8 +20,10 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
vec2_t points[3];
|
vec2_t points[3];
|
||||||
|
color_t color;
|
||||||
|
float average_depth;
|
||||||
} triangle_t;
|
} triangle_t;
|
||||||
|
|
||||||
void draw_filled_triangle(triangle_t triangle, uint32_t color);
|
void draw_filled_triangle(triangle_t triangle);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user