This commit is contained in:
jb 2025-07-11 23:56:41 -07:00
parent 38ea89c4a6
commit 6be5527b37
8 changed files with 196 additions and 19 deletions

View File

@ -7,6 +7,7 @@ set(CMAKE_C_STANDARD 11)
add_executable(${PROJECT_NAME} scripts/main.c
scripts/array.c
scripts/vector.c
scripts/matrix.c
scripts/mesh.c
scripts/triangle.c
scripts/display.c)

View File

@ -8,6 +8,7 @@
#include "mesh.h"
#include "vector.h"
#include "array.h"
#include "matrix.h"
#define STEP 0.075
@ -113,8 +114,8 @@ void process_input(void) {
////////////////////////////////////////////////////////////////////////////////
vec2_t project(vec3_t point) {
vec2_t projected_point = {
.x = round((fov_factor * point.x) / point.z),
.y = round((fov_factor * point.y) / point.z),
.x = roundf((fov_factor * point.x) / point.z),
.y = roundf((fov_factor * point.y) / point.z),
};
return projected_point;
}
@ -131,9 +132,27 @@ void update(void) {
previous_frame_time = SDL_GetTicks();
mesh.rotation.y += 0.01;
mesh.rotation.x -= 0.01;
mesh.rotation.z += 0.01;
mesh.rotation.y += 0.01f;
mesh.rotation.x -= 0.01f;
mesh.rotation.z += 0.01f;
mesh.translation.x += 0.004f;
mesh.translation.z = 5.0f;
//mesh.scale.x += 0.002f;
//mesh.scale.y += 0.002f;
// create scale matrix that will be used
mat4_t scale_matrix = mat4_make_scale(mesh.scale.x, mesh.scale.y, mesh.scale.z);
// create translation matrix
mat4_t translation_matrix = mat4_make_translation(mesh.translation.x, mesh.translation.y, mesh.translation.z);
// create rotation matrices
mat4_t rotation_matrix_x = mat4_make_rotation_x(mesh.rotation.x);
mat4_t rotation_matrix_y = mat4_make_rotation_y(mesh.rotation.y);
mat4_t rotation_matrix_z = mat4_make_rotation_z(mesh.rotation.z);
triangles_to_render = NULL;
@ -146,17 +165,21 @@ void update(void) {
face_vertices[1] = mesh.vertices[mesh_face.b - 1];
face_vertices[2] = mesh.vertices[mesh_face.c - 1];
vec3_t transformed_vertices[3];
vec4_t transformed_vertices[3];
for (int j = 0; j < 3; j++) {
vec3_t transformed_vertex = face_vertices[j];
vec4_t transformed_vertex = vec4_from_vec3(face_vertices[j]);
transformed_vertex = vec3_rotate_x(transformed_vertex, mesh.rotation.x);
transformed_vertex = vec3_rotate_y(transformed_vertex, mesh.rotation.y);
transformed_vertex = vec3_rotate_z(transformed_vertex, mesh.rotation.z);
// use matrix to scale original matrix
transformed_vertex = mat4_multiply_vec4(scale_matrix, transformed_vertex);
// translate away from camera in z
transformed_vertex.z += 5;
// use matrices to rotate
transformed_vertex = mat4_multiply_vec4(rotation_matrix_x, transformed_vertex);
transformed_vertex = mat4_multiply_vec4(rotation_matrix_y, transformed_vertex);
transformed_vertex = mat4_multiply_vec4(rotation_matrix_z, transformed_vertex);
// use matrix to translate
transformed_vertex = mat4_multiply_vec4(translation_matrix, transformed_vertex);
// save translated vertex in the array of transformed vertices
transformed_vertices[j] = transformed_vertex;
@ -164,9 +187,9 @@ void update(void) {
if (cull_method == CULL_BACKFACE) {
// check backface culling
vec3_t vector_a = transformed_vertices[0]; /* A */
vec3_t vector_b = transformed_vertices[1]; /* / \ */
vec3_t vector_c = transformed_vertices[2]; /* C---B */
vec3_t vector_a = vec3_from_vec4(transformed_vertices[0]); /* A */
vec3_t vector_b = vec3_from_vec4(transformed_vertices[1]); /* / \ */
vec3_t vector_c = vec3_from_vec4(transformed_vertices[2]); /* C---B */
// get the vector subtraction of B-A and C-A
vec3_t vector_ab = vec3_subtract(vector_b, vector_a);
@ -193,7 +216,7 @@ void update(void) {
for (int j = 0; j < 3; j++) {
// project the current vertex
vec2_t projected_point = project(transformed_vertices[j]);
vec2_t projected_point = project(vec3_from_vec4(transformed_vertices[j]));
// scale and translate the projected points to the center of the screen
projected_point.x += (window_width / 2);
@ -221,8 +244,8 @@ 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;
if (arg_a.average_depth > arg_b.average_depth) return -1;
if (arg_a.average_depth < arg_b.average_depth) return 1;
return 0;
}

103
scripts/matrix.c Normal file
View File

@ -0,0 +1,103 @@
#include "matrix.h"
mat4_t mat4_identity(void) {
mat4_t m = {{
{ 1, 0, 0, 0},
{ 0, 1, 0, 0},
{ 0, 0, 1, 0},
{ 0, 0, 0, 1},
}};
return m;
}
mat4_t mat4_make_scale(float sx, float sy, float sz) {
mat4_t m = mat4_identity();
m.m[0][0] *= sx;
m.m[1][1] *= sy;
m.m[2][2] *= sz;
return m;
}
mat4_t mat4_make_translation(float tx, float ty, float tz) {
/*
* 1 0 0 tx
* 0 1 0 ty
* 0 0 1 tz
* 0 0 0 1
*/
mat4_t m = mat4_identity();
m.m[0][3] = tx;
m.m[1][3] = ty;
m.m[2][3] = tz;
return m;
}
mat4_t mat4_make_rotation_y(float ra) {
/*
* cos 0 -sin 0
* 0 1 0 0
* sin 0 cos 0
* 0 0 0 1
*/
const float cosine = cosf(ra);
const float sine = sinf(ra);
mat4_t m = mat4_identity();
m.m[0][0] = cosine;
m.m[0][2] = -sine;
m.m[2][0] = sine;
m.m[2][2] = cosine;
return m;
}
mat4_t mat4_make_rotation_x(float ra) {
/*
* 1 0 0 0
* 0 cos sin 0
* 0 -sin cos 0
* 0 0 0 1
*/
const float cosine = cosf(ra);
const float sine = sinf(ra);
mat4_t m = mat4_identity();
m.m[1][1] = cosine;
m.m[1][2] = sine;
m.m[2][1] = -sine;
m.m[2][2] = cosine;
return m;
}
mat4_t mat4_make_rotation_z(float ra) {
/*
* cos sin 0 0
* -sin cos 0 0
* 0 0 1 0
* 0 0 0 1
*/
const float cosine = cosf(ra);
const float sine = sinf(ra);
mat4_t m = mat4_identity();
m.m[0][0] = cosine;
m.m[0][1] = sine;
m.m[1][0] = -sine;
m.m[1][1] = cosine;
return m;
}
vec4_t mat4_multiply_vec4(mat4_t m, vec4_t v) {
vec4_t ret = {};
ret.x = m.m[0][0] * v.x + m.m[0][1] * v.y + m.m[0][2] * v.z + m.m[0][3] * v.w;
ret.y = m.m[1][0] * v.x + m.m[1][1] * v.y + m.m[1][2] * v.z + m.m[1][3] * v.w;
ret.z = m.m[2][0] * v.x + m.m[2][1] * v.y + m.m[2][2] * v.z + m.m[2][3] * v.w;
ret.w = m.m[3][0] * v.x + m.m[3][1] * v.y + m.m[3][2] * v.z + m.m[3][3] * v.w;
return ret;
}

21
scripts/matrix.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef MATRIX_H
#define MATRIX_H
#include <math.h>
#include "vector.h"
typedef struct mat4_t mat4_t;
struct mat4_t {
float m[4][4];
};
mat4_t mat4_identity(void);
mat4_t mat4_make_scale(float sx, float sy, float sz);
mat4_t mat4_make_translation(float tx, float ty, float tz);
mat4_t mat4_make_rotation_x(float ra);
mat4_t mat4_make_rotation_y(float ra);
mat4_t mat4_make_rotation_z(float ra);
vec4_t mat4_multiply_vec4(mat4_t m, vec4_t v);
#endif

View File

@ -11,7 +11,9 @@
mesh_t mesh = {
.vertices = NULL,
.faces = NULL,
.rotation = { 0, 0, 0 }
.rotation = { 0, 0, 0 },
.scale = { 1.0, 1.0, 1.0 },
.translation = { 0, 0, 0 },
};
vec3_t cube_vertices[N_CUBE_VERTICES] = {

View File

@ -32,6 +32,8 @@ struct mesh_t {
vec3_t* vertices;
face_t* faces;
vec3_t rotation;
vec3_t scale;
vec3_t translation;
};
extern mesh_t mesh;

View File

@ -122,4 +122,22 @@ void vec3_normalize(vec3_t* vertex) {
vertex->x /= length;
vertex->y /= length;
vertex->z /= length;
}
vec4_t vec4_from_vec3(vec3_t vertex) {
vec4_t ret;
ret.x = vertex.x;
ret.y = vertex.y;
ret.z = vertex.z;
ret.w = 1;
return ret;
}
vec3_t vec3_from_vec4(vec4_t v) {
return (vec3_t) {
.x = v.x,
.y = v.y,
.z = v.z,
};
}

View File

@ -12,6 +12,10 @@ typedef struct {
float z;
} vec3_t;
typedef struct {
float x, y, z, w;
} vec4_t;
// TODO: Add functions to manipulate vectors 2D and 3D
// ...
@ -36,4 +40,7 @@ float vec3_length(const vec3_t vector);
float vec3_dot(const vec3_t a, const vec3_t b);
void vec3_normalize(vec3_t* vertex);
vec4_t vec4_from_vec3(vec3_t vertex);
vec3_t vec3_from_vec4(vec4_t v);
#endif