fix camera, back face culling, simple lighting

This commit is contained in:
opfez 2021-11-13 18:42:30 +01:00
parent 5b8e38a7f4
commit 651cfe8c07
3 changed files with 64 additions and 29 deletions

View File

@ -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

69
main.c
View File

@ -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);

View File

@ -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)
{