diff --git a/cube.obj b/cube.obj index 6023c90..6e515c0 100644 --- a/cube.obj +++ b/cube.obj @@ -2,14 +2,14 @@ # www.blender.org mtllib cube.mtl o Cube_Cube.002 -v -100.000000 -100.000000 100.000000 -v -100.000000 100.000000 100.000000 -v -100.000000 -100.000000 -100.000000 -v -100.000000 100.000000 -100.000000 -v 100.000000 -100.000000 100.000000 -v 100.000000 100.000000 100.000000 -v 100.000000 -100.000000 -100.000000 -v 100.000000 100.000000 -100.000000 +v -50.000000 -50.000000 50.000000 +v -50.000000 50.000000 50.000000 +v -50.000000 -50.000000 -50.000000 +v -50.000000 50.000000 -50.000000 +v 50.000000 -50.000000 50.000000 +v 50.000000 50.000000 50.000000 +v 50.000000 -50.000000 -50.000000 +v 50.000000 50.000000 -50.000000 vt 0.625000 0.000000 vt 0.375000 0.250000 vt 0.375000 0.000000 diff --git a/main.c b/main.c index 6f00ea7..8cf1181 100644 --- a/main.c +++ b/main.c @@ -68,7 +68,7 @@ vec3_matrix3x3_multiply(vec3 v, matrix3x3 r) } camera -new_camera(double range, vec3 pos, vec3 target, vec3 up) +new_camera(double znear, vec3 pos, vec3 target, vec3 up) { if (pos.x == target.x && pos.y == target.y && @@ -76,7 +76,7 @@ new_camera(double range, vec3 pos, vec3 target, vec3 up) die("cannot create camera with same target and position"); camera ret = { - .range = range, + .znear = znear, .pos = pos, .target = target, .up = up, @@ -505,8 +505,10 @@ midpoint(vec2 a, vec2 b) vec2 project(camera c, vec3 v) { - double r = 200 / (v.z + c.range); - return (vec2){W / 2 + r * v.x, H / 2 + r * v.y}; + vec3 u = vec3_sub(v, c.pos); + // TODO rotation + double r = c.znear / u.z; + return (vec2){W / 2 + r * u.x, H / 2 + r * u.y}; } triangle2 @@ -542,18 +544,44 @@ void draw_mesh(rgb canvas[], rgb col, camera c, mesh mesh) { for (uint32_t i = 0; i < mesh.tri_num; i++) { - if (wireframe) - draw_triangle(canvas, col, project_triangle(c, (triangle3) { - mesh.vertices[mesh.indices[3*i ]], - mesh.vertices[mesh.indices[3*i+1]], - mesh.vertices[mesh.indices[3*i+2]], - })); - else - fill_triangle(canvas, col, project_triangle(c, (triangle3) { - mesh.vertices[mesh.indices[3*i ]], - mesh.vertices[mesh.indices[3*i+1]], - mesh.vertices[mesh.indices[3*i+2]], - })); + vec3 v0 = mesh.vertices[mesh.indices[3*i ]], + v1 = mesh.vertices[mesh.indices[3*i+1]], + v2 = mesh.vertices[mesh.indices[3*i+2]]; + + vec3 norm = vec3_normalize(vec3_cross(vec3_sub(v1, v0), vec3_sub(v2, v0))); + double x = vec3_dot(vec3_sub(v0, c.pos), norm); + + if (wireframe) { + if (x < 0) + draw_triangle(canvas, col, project_triangle(c, (triangle3) { + v0, v1, v2 + })); + /* else */ + /* draw_triangle(canvas, */ + /* (rgb) { */ + /* .r = col.r * 0.2, */ + /* .g = col.g * 0.2, */ + /* .b = col.b * 0.2, */ + /* .a = col.a */ + /* }, */ + /* project_triangle(c, (triangle3) { */ + /* v0, v1, v2 */ + /* })); */ + } + else { + if (x < 0) { + double col_mod = clamp(vec3_dot(norm, (vec3){200, 200, 200}) * 0.8, 0.0, 255.0); + fill_triangle(canvas, + (rgb) { + .r = col_mod, + .g = col_mod, + .b = col_mod + }, + project_triangle(c, (triangle3) { + v0, v1, v2 + })); + } + } } } @@ -623,7 +651,7 @@ int main(void) { sdl_state state = init_sdl(); - camera cam = new_camera(180, (vec3){0, 0, 3}, (vec3){0, 0, 0}, UP); + camera cam = new_camera(180, (vec3){0, 0, 200}, (vec3){0, 0, 0}, UP); /* print_camera(cam); */ SDL_Event event; @@ -633,14 +661,15 @@ main(void) uint64_t t = 0; + double rot_speed = 0.5; for (;;) { double elapsed, start = SDL_GetPerformanceCounter(); matrix3x3 rotation = matrix3x3_multiply( matrix3x3_multiply( - z_rotation(1.2 * t), - y_rotation(1.1 * t)), - x_rotation(1.0 * t)); + z_rotation(1.2 * t * rot_speed), + y_rotation(1.1 * t * rot_speed)), + x_rotation(1.0 * t * rot_speed)); int x, y; uint32_t buttons = SDL_GetMouseState(&x, &y); diff --git a/types.h b/types.h index 6e8aa49..690fff8 100644 --- a/types.h +++ b/types.h @@ -44,7 +44,7 @@ STRUCT(matrix4x4) END_STRUCT STRUCT(camera) - FIELD(range, double) + FIELD(znear, double) FIELD(pos, vec3) FIELD(target, vec3) FIELD(up, vec3) @@ -130,6 +130,12 @@ vec3_cross(vec3 u, vec3 v) }; } +double +vec3_dot(vec3 u, vec3 v) +{ + return u.x * v.x + u.y * v.y + u.z * v.z; +} + vec3 vec3_normalize(vec3 u) {