textures rendering, but not quite working
This commit is contained in:
parent
7a91b72708
commit
6991731160
@ -71,17 +71,7 @@ void draw_rect(int x, int y, int width, int height, uint32_t color) {
|
||||
}
|
||||
}
|
||||
|
||||
void draw_triangle_old(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t color) {
|
||||
draw_line(x0, y0, x1, y1, color);
|
||||
draw_line(x1, y1, x2, y2, color);
|
||||
draw_line(x2, y2, x0, y0, color);
|
||||
}
|
||||
|
||||
void draw_triangle(triangle_t triangle, uint32_t color) {
|
||||
draw_line(triangle.points[0].x, triangle.points[0].y, triangle.points[1].x, triangle.points[1].y, color);
|
||||
draw_line(triangle.points[1].x, triangle.points[1].y, triangle.points[2].x, triangle.points[2].y, color);
|
||||
draw_line(triangle.points[2].x, triangle.points[2].y, triangle.points[0].x, triangle.points[0].y, color);
|
||||
}
|
||||
|
||||
void draw_line(int x0, int y0, int x1, int y1, uint32_t color) {
|
||||
int delta_x = (x1 - x0);
|
||||
|
||||
@ -38,8 +38,6 @@ void draw_grid(void);
|
||||
void draw_pixel(int x, int y, uint32_t color);
|
||||
void draw_line(int x0, int y0, int x1, int y1, uint32_t color);
|
||||
void draw_rect(int x, int y, int width, int height, uint32_t color);
|
||||
void draw_triangle(triangle_t triangle, uint32_t color);
|
||||
void draw_triangle_old(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t color);
|
||||
void render_color_buffer(void);
|
||||
void clear_color_buffer(uint32_t color);
|
||||
void destroy_window(void);
|
||||
|
||||
@ -38,7 +38,7 @@ light_t light = { .direction = { .x = 0, .y = 0, .z = 1 }};
|
||||
bool is_running = false;
|
||||
|
||||
int cull_method = CULL_BACKFACE;
|
||||
int render_method = RENDER_FILL_TRIANGLE;
|
||||
int render_method = RENDER_TEXTURED;
|
||||
bool sort_faces = true;
|
||||
|
||||
uint32_t previous_frame_time = 0;
|
||||
@ -68,8 +68,8 @@ void setup(void) {
|
||||
texture_width = 64;
|
||||
|
||||
// load cube mesh data
|
||||
load_file("..\\assets\\f22.obj");
|
||||
//load_cube_mesh_data();
|
||||
//load_file("..\\assets\\f22.obj");
|
||||
load_cube_mesh_data();
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
@ -334,10 +334,20 @@ void render(void) {
|
||||
draw_triangle(triangle, 0xff0000ff);
|
||||
break;
|
||||
case RENDER_TEXTURED:
|
||||
//draw_textured_triangle(triangle, mesh_texture);
|
||||
draw_textured_triangle(
|
||||
triangle.points[0].x, triangle.points[0].y, triangle.texcoords[0].u, triangle.texcoords[0].v, // vertex A
|
||||
triangle.points[1].x, triangle.points[1].y, triangle.texcoords[1].u, triangle.texcoords[1].v, // vertex B
|
||||
triangle.points[2].x, triangle.points[2].y, triangle.texcoords[2].u, triangle.texcoords[2].v, // vertex C
|
||||
mesh_texture
|
||||
);
|
||||
break;
|
||||
case RENDER_TEXTURED_LINE:
|
||||
//draw_textured_triangle(triangle, mesh_texture);
|
||||
draw_textured_triangle(
|
||||
triangle.points[0].x, triangle.points[0].y, triangle.texcoords[0].u, triangle.texcoords[0].v, // vertex A
|
||||
triangle.points[1].x, triangle.points[1].y, triangle.texcoords[1].u, triangle.texcoords[1].v, // vertex B
|
||||
triangle.points[2].x, triangle.points[2].y, triangle.texcoords[2].u, triangle.texcoords[2].v, // vertex C
|
||||
mesh_texture
|
||||
);
|
||||
draw_triangle(triangle, 0xff0000ff);
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -29,23 +29,23 @@ vec3_t cube_vertices[N_CUBE_VERTICES] = {
|
||||
|
||||
face_t cube_faces[N_CUBE_FACES] = {
|
||||
// front
|
||||
{ .a = 1, .b = 2, .c = 3, .a_uv = { 0, 0 }, .b_uv = { 0, 1 }, .c_uv = { 1, 1 }, .color = COLOR_ORANGE},
|
||||
{ .a = 1, .b = 3, .c = 4, .a_uv = { 0, 0 }, .b_uv = { 1, 1 }, .c_uv = { 1, 0 }, .color = COLOR_ORANGE},
|
||||
{ .a = 1, .b = 2, .c = 3, .a_uv = { 0, 0 }, .b_uv = { 0, 1 }, .c_uv = { 1, 1 }, .color = 0xFFFFFFFF },
|
||||
{ .a = 1, .b = 3, .c = 4, .a_uv = { 0, 0 }, .b_uv = { 1, 1 }, .c_uv = { 1, 0 }, .color = 0xFFFFFFFF },
|
||||
// right
|
||||
{ .a = 4, .b = 3, .c = 5, .a_uv = { 0, 0 }, .b_uv = { 0, 1 }, .c_uv = { 1, 1 }, .color = COLOR_TEAL_GREEN },
|
||||
{ .a = 4, .b = 5, .c = 6, .a_uv = { 0, 0 }, .b_uv = { 1, 1 }, .c_uv = { 1, 0 }, .color = COLOR_TEAL_GREEN},
|
||||
{ .a = 4, .b = 3, .c = 5, .a_uv = { 0, 0 }, .b_uv = { 0, 1 }, .c_uv = { 1, 1 }, .color = 0xFFFFFFFF },
|
||||
{ .a = 4, .b = 5, .c = 6, .a_uv = { 0, 0 }, .b_uv = { 1, 1 }, .c_uv = { 1, 0 }, .color = 0xFFFFFFFF },
|
||||
// back
|
||||
{ .a = 6, .b = 5, .c = 7, .a_uv = { 0, 0 }, .b_uv = { 0, 1 }, .c_uv = { 1, 1 }, .color = COLOR_RED },
|
||||
{ .a = 6, .b = 7, .c = 8, .a_uv = { 0, 0 }, .b_uv = { 1, 1 }, .c_uv = { 1, 0 }, .color = COLOR_RED },
|
||||
{ .a = 6, .b = 5, .c = 7, .a_uv = { 0, 0 }, .b_uv = { 0, 1 }, .c_uv = { 1, 1 }, .color = 0xFFFFFFFF },
|
||||
{ .a = 6, .b = 7, .c = 8, .a_uv = { 0, 0 }, .b_uv = { 1, 1 }, .c_uv = { 1, 0 }, .color = 0xFFFFFFFF },
|
||||
// left
|
||||
{ .a = 8, .b = 7, .c = 2, .a_uv = { 0, 0 }, .b_uv = { 0, 1 }, .c_uv = { 1, 1 }, .color = COLOR_PURPLE },
|
||||
{ .a = 8, .b = 2, .c = 1, .a_uv = { 0, 0 }, .b_uv = { 1, 1 }, .c_uv = { 1, 0 }, .color = COLOR_PURPLE },
|
||||
{ .a = 8, .b = 7, .c = 2, .a_uv = { 0, 0 }, .b_uv = { 0, 1 }, .c_uv = { 1, 1 }, .color = 0xFFFFFFFF },
|
||||
{ .a = 8, .b = 2, .c = 1, .a_uv = { 0, 0 }, .b_uv = { 1, 1 }, .c_uv = { 1, 0 }, .color = 0xFFFFFFFF },
|
||||
// top
|
||||
{ .a = 2, .b = 7, .c = 5, .a_uv = { 0, 0 }, .b_uv = { 0, 1 }, .c_uv = { 1, 1 }, .color = COLOR_GREY },
|
||||
{ .a = 2, .b = 5, .c = 3, .a_uv = { 0, 0 }, .b_uv = { 1, 1 }, .c_uv = { 1, 0 }, .color = COLOR_GREY },
|
||||
{ .a = 2, .b = 7, .c = 5, .a_uv = { 0, 0 }, .b_uv = { 0, 1 }, .c_uv = { 1, 1 }, .color = 0xFFFFFFFF },
|
||||
{ .a = 2, .b = 5, .c = 3, .a_uv = { 0, 0 }, .b_uv = { 1, 1 }, .c_uv = { 1, 0 }, .color = 0xFFFFFFFF },
|
||||
// bottom
|
||||
{ .a = 6, .b = 8, .c = 1, .a_uv = { 0, 0 }, .b_uv = { 0, 1 }, .c_uv = { 1, 1 }, .color = COLOR_LIGHT_GREEN_BLUE },
|
||||
{ .a = 6, .b = 1, .c = 4, .a_uv = { 0, 0 }, .b_uv = { 1, 1 }, .c_uv = { 1, 0 }, .color = COLOR_LIGHT_GREEN_BLUE }
|
||||
{ .a = 6, .b = 8, .c = 1, .a_uv = { 0, 0 }, .b_uv = { 0, 1 }, .c_uv = { 1, 1 }, .color = 0xFFFFFFFF },
|
||||
{ .a = 6, .b = 1, .c = 4, .a_uv = { 0, 0 }, .b_uv = { 1, 1 }, .c_uv = { 1, 0 }, .color = 0xFFFFFFFF }
|
||||
};
|
||||
|
||||
void load_cube_mesh_data(void) {
|
||||
|
||||
@ -24,6 +24,12 @@ uint32_t invert_rgb(uint32_t color) {
|
||||
return a | rgb;
|
||||
}
|
||||
|
||||
void draw_triangle(triangle_t triangle, uint32_t color) {
|
||||
draw_line(triangle.points[0].x, triangle.points[0].y, triangle.points[1].x, triangle.points[1].y, color);
|
||||
draw_line(triangle.points[1].x, triangle.points[1].y, triangle.points[2].x, triangle.points[2].y, color);
|
||||
draw_line(triangle.points[2].x, triangle.points[2].y, triangle.points[0].x, triangle.points[0].y, color);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Draw a filled a triangle with a flat bottom
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -141,7 +147,60 @@ void draw_filled_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint32
|
||||
}
|
||||
}
|
||||
|
||||
void draw_textured_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t* texture) {
|
||||
vec3_t barycentric_weights(vec2_t a, vec2_t b, vec2_t c, vec2_t p) {
|
||||
// Find the vectors between the vertices ABC and point p
|
||||
vec2_t ac = vec2_subtract(c, a);
|
||||
vec2_t ab = vec2_subtract(b, a);
|
||||
vec2_t ap = vec2_subtract(p, a);
|
||||
vec2_t pc = vec2_subtract(c, p);
|
||||
vec2_t pb = vec2_subtract(b, p);
|
||||
|
||||
// Compute the area of the full parallegram/triangle ABC using 2D cross product
|
||||
float area_parallelogram_abc = (ac.x * ab.y - ac.y * ab.x); // || AC x AB ||
|
||||
|
||||
// Alpha is the area of the small parallelogram/triangle PBC divided by the area of the full parallelogram/triangle ABC
|
||||
float alpha = (pc.x * pb.y - pc.y * pb.x) / area_parallelogram_abc;
|
||||
|
||||
// Beta is the area of the small parallelogram/triangle APC divided by the area of the full parallelogram/triangle ABC
|
||||
float beta = (ac.x * ap.y - ac.y * ap.x) / area_parallelogram_abc;
|
||||
|
||||
// Weight gamma is easily found since barycentric coordinates always add up to 1.0
|
||||
float gamma = 1 - alpha - beta;
|
||||
|
||||
vec3_t weights = { alpha, beta, gamma };
|
||||
return weights;
|
||||
}
|
||||
////////////////////////////
|
||||
// Function to draw textue at x/y using interpolation
|
||||
void draw_texel(
|
||||
int x, int y, uint32_t* texture,
|
||||
vec2_t point_a, vec2_t point_b, vec2_t point_c,
|
||||
float u0, float v0, float u1, float v1, float u2, float v2) {
|
||||
vec2_t point_p = { x, y };
|
||||
vec3_t weights = barycentric_weights(point_a, point_b, point_c, point_p);
|
||||
|
||||
float alpha = weights.x;
|
||||
float beta = weights.y;
|
||||
float gamma = weights.z;
|
||||
|
||||
// Perform the interpolation of all U and V values using barycentric weights
|
||||
float interpolated_u = (u0) * alpha + (u1) * beta + (u2) * gamma;
|
||||
float interpolated_v = (v0) * alpha + (v1) * beta + (v2) * gamma;
|
||||
|
||||
// Map the UV coordinate to the full texture width and height
|
||||
int tex_x = abs((int)(interpolated_u * texture_width));
|
||||
int tex_y = abs((int)(interpolated_v * texture_height));
|
||||
|
||||
draw_pixel(x, y, texture[(texture_width * tex_y) + tex_x]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void draw_textured_triangle(
|
||||
int x0, int y0, float u0, float v0,
|
||||
int x1, int y1, float u1, float v1,
|
||||
int x2, int y2, float u2, float v2,
|
||||
uint32_t* texture) {
|
||||
// sort by y
|
||||
int temp = 0, min_idx = 0, mid_idx = 1, max_idx = 2;
|
||||
|
||||
@ -159,21 +218,62 @@ void draw_textured_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint
|
||||
int_swap(&x0, &x1);
|
||||
}
|
||||
|
||||
// create vector points after sorting vertices
|
||||
vec2_t point_a = { x0, y0 };
|
||||
vec2_t point_b = { x1, y1 };
|
||||
vec2_t point_c = { x2, y2 };
|
||||
|
||||
|
||||
// FLAT BOTTOM
|
||||
|
||||
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 (y1 - y0 != 0) inv_slope_1 = (float)(x1 - x0) / abs(y1 - y0);
|
||||
if (y2 - y0 != 0) inv_slope_2 = (float)(x2 - x0) / abs(y2 - y0);
|
||||
|
||||
if (y1 - y0 != 0) {
|
||||
for (int y = y0; y <= y1; y++) {
|
||||
int x_start = x1 + (y - y1) * inv_slope_1;
|
||||
int x_end = x0 + (y - y0) * inv_slope_2;
|
||||
|
||||
if (x_end < x_start) {
|
||||
int_swap(&x_start, &x_end);
|
||||
}
|
||||
|
||||
for (int x = x_start; x < x_end; x++) {
|
||||
// draw pixel with color from texture
|
||||
//draw_pixel(x, y, (x % 2 == 0 && y % 2 == 0) ? 0xFF00FF00 : 0xFF000000);
|
||||
draw_texel(x, y, texture, point_a, point_b, point_c, u0, v0, u1, v1, u2, v2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
// FLAT TOP
|
||||
inv_slope_1 = 0;
|
||||
inv_slope_2 = 0;
|
||||
|
||||
if (y2 - y1 != 0) inv_slope_1 = (float)(x2 - x1) / abs(y2 - y1);
|
||||
if (y2 - y0 != 0) inv_slope_2 = (float)(x2 - x0) / abs(y2 - y0);
|
||||
|
||||
if (y2 - y1 != 0) {
|
||||
for (int y = y1; y <= y2; y++) {
|
||||
int x_start = x1 + (y - y1) * inv_slope_1;
|
||||
int x_end = x0 + (y - y0) * inv_slope_2;
|
||||
|
||||
if (x_end < x_start) {
|
||||
int_swap(&x_start, &x_end);
|
||||
}
|
||||
|
||||
for (int x = x_start; x < x_end; x++) {
|
||||
// draw pixel with color from texture
|
||||
//draw_pixel(x, y, (x % 2 == 0 && y % 2 == 0) ? 0xFF00FF00 : 0xFF000000);
|
||||
draw_texel(x, y, texture, point_a, point_b, point_c, u0, v0, u1, v1, u2, v2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = triangle.points[min_idx].y; y <= triangle.points[mid_idx].y; y++) {
|
||||
//float x_start = triangle
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -32,8 +32,16 @@ typedef struct {
|
||||
float average_depth;
|
||||
} triangle_t;
|
||||
|
||||
void draw_triangle(triangle_t triangle, uint32_t color);
|
||||
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);
|
||||
|
||||
void draw_textured_triangle(
|
||||
int x0, int y0, float u0, float v0,
|
||||
int x1, int y1, float u1, float v1,
|
||||
int x2, int y2, float u2, float v2,
|
||||
uint32_t* texture);
|
||||
void draw_texel(
|
||||
int x, int y, uint32_t* texture,
|
||||
vec2_t point_a, vec2_t point_b, vec2_t point_c,
|
||||
float u0, float v0, float u1, float v1, float u2, float v2);
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user