diff --git a/src/ragar/ragar_main.c b/src/ragar/ragar_main.c index 3c8ef64..c4fc325 100644 --- a/src/ragar/ragar_main.c +++ b/src/ragar/ragar_main.c @@ -9,9 +9,64 @@ #include "base/base_inc.c" #include "renderer/display.c" -#define POINTS (9 * 9 * 9) -Vec3F32 cube_points[POINTS]; -Vec2F32 g_projected_points[POINTS]; +// NOTE(tijani): Vertices are points; +// Faces are the surfaces formed by connecting those points. + +#define MESH_VERTICES 8 +#define MESH_FACES (6 * 2) // 6 cube faces, 2 triangles per face + +typedef struct Triangle2F32 Triangle2F32; +struct Triangle2F32 { + Vec2F32 points[3]; +}; + +typedef struct Face3S32 Face3S32; +struct Face3S32 { + s32 a; + s32 b; + s32 c; +}; + +// clang-format off +Vec3F32 mesh_vertices[MESH_VERTICES] = { + { .x = -1, .y = -1, .z = -1}, + { .x = -1, .y = 1, .z = -1}, + { .x = 1, .y = 1, .z = -1}, + { .x = 1, .y = -1, .z = -1}, + { .x = 1, .y = 1, .z = 1}, + { .x = 1, .y = -1, .z = 1}, + { .x = -1, .y = 1, .z = 1}, + { .x = -1, .y = -1, .z = 1}, +}; +// clang-format on + +Face3S32 mesh_faces[MESH_FACES] = { + // front + {.a = 1, .b = 2, .c = 3}, + {.a = 1, .b = 3, .c = 4}, + + // right + {.a = 4, .b = 3, .c = 5}, + {.a = 4, .b = 5, .c = 6}, + + // back + {.a = 6, .b = 5, .c = 7}, + {.a = 6, .b = 7, .c = 8}, + + // left + {.a = 8, .b = 7, .c = 2}, + {.a = 8, .b = 2, .c = 1}, + + // top + {.a = 2, .b = 7, .c = 5}, + {.a = 2, .b = 5, .c = 3}, + + // bottom + {.a = 6, .b = 8, .c = 1}, + {.a = 6, .b = 1, .c = 4}, +}; + +Triangle2F32 g_triangles_to_render[MESH_FACES]; Vec3F32 camera_position = {.x = 0, .y = 0, .z = -5}; Vec3F32 cube_rotation = {.x = 0, .y = 0, .z = 0}; @@ -38,17 +93,6 @@ void setup(void) { colour_buffer = (u32 *)malloc(sizeof(u32) * window_width * window_height); colour_buffer_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, window_width, window_height); - - int point_count = 0; - // Load array of vectors, from -1 to 1 in the 9*9*9 cube - for (f32 x = -1; x <= 1; x += 0.25) { - for (f32 y = -1; y <= 1; y += 0.25) { - for (f32 z = -1; z <= 1; z += 0.25) { - Vec3F32 new_points = {.x = x, .y = y, .z = z}; - cube_points[point_count++] = new_points; - } - } - } } void process_input(void) { @@ -81,32 +125,52 @@ void update(void) { cube_rotation.y += 0.01; cube_rotation.z += 0.01; - for (s32 i = 0; i < POINTS; i++) { - Vec3F32 point = cube_points[i]; + // Loop through all triangle faces of the mesh + for (s32 i = 0; i < MESH_FACES; i++) { + Face3S32 current_mesh_face = mesh_faces[i]; + + Vec3F32 face_vertices[3]; + face_vertices[0] = mesh_vertices[current_mesh_face.a - 1]; + face_vertices[1] = mesh_vertices[current_mesh_face.b - 1]; + face_vertices[2] = mesh_vertices[current_mesh_face.c - 1]; - // Transform points - Vec3F32 transformed_points = vec3f32_rotate_x(point, cube_rotation.x); - transformed_points = vec3f32_rotate_y(transformed_points, cube_rotation.y); - transformed_points = vec3f32_rotate_z(transformed_points, cube_rotation.z); + Triangle2F32 projected_triangle; - // Translate points away from the camera - transformed_points.z -= camera_position.z; + // Loop throug all three vertices of the current face and apply transformations + for (s32 j = 0; j < 3; j++) { + Vec3F32 transformed_vertex = face_vertices[j]; - // Project the transformed point - Vec2F32 projected_point = perspective_projection(transformed_points); + transformed_vertex = vec3f32_rotate_x(transformed_vertex, cube_rotation.x); + transformed_vertex = vec3f32_rotate_y(transformed_vertex, cube_rotation.y); + transformed_vertex = vec3f32_rotate_z(transformed_vertex, cube_rotation.z); - // Save the projected 2D vector in the global array of projected points - g_projected_points[i] = projected_point; + // Translate the vertex away from the camera + transformed_vertex.z -= camera_position.z; + + // Project the current vertex + Vec2F32 projected_point = perspective_projection(transformed_vertex); + + // Scale and translate the projected points to the middle of the screen. + projected_point.x += (window_width / 2); + projected_point.y += (window_height / 2); + + projected_triangle.points[j] = projected_point; + } + + // Save the projected triangle in the array of triangles to render + g_triangles_to_render[i] = projected_triangle; } } void render(void) { - draw_grid(0xFF000000); + draw_grid(0xFF444444); // Loop through all projected points and render them - for (u32 i = 0; i < POINTS; i++) { - Vec2F32 projected_point = g_projected_points[i]; - draw_rect(projected_point.x + (window_width / 2), projected_point.y + (window_height / 2), 4, 4, 0xFF659F00); + for (u32 i = 0; i < MESH_FACES; i++) { + Triangle2F32 triangle = g_triangles_to_render[i]; + 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); } render_colour_buffer(); diff --git a/src/renderer/display.c b/src/renderer/display.c index 1f6da68..14e6e17 100644 --- a/src/renderer/display.c +++ b/src/renderer/display.c @@ -58,8 +58,8 @@ void draw_dots(u32 colour) { } void draw_grid(u32 colour) { - for (s32 column = 0; column < window_height; column++) { - for (s32 row = 0; row < window_width; row++) { + for (s32 column = 0; column < window_height; column += 10) { + for (s32 row = 0; row < window_width; row += 10) { colour_buffer[(window_width * column) + row] = colour; } }