Add shading
This commit is contained in:
parent
9f9cc2308d
commit
c3c0dd732e
@ -37,8 +37,9 @@ int main(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clear_image(&img, bg);
|
clear_image(&img, bg);
|
||||||
render_model(&model, &img, teal, RENDER_TYPE_FILLED, COLOUR_TYPE_RANDOM);
|
render_model(&model, &img, teal, RENDER_TYPE_SHADED, COLOUR_TYPE_FIXED);
|
||||||
render_model(&model, &img, orange, RENDER_TYPE_WIREFRAME, COLOUR_TYPE_FIXED);
|
// render_model(&model, &img, orange, RENDER_TYPE_WIREFRAME,
|
||||||
|
// COLOUR_TYPE_FIXED);
|
||||||
save_image(&img, "result.pam");
|
save_image(&img, "result.pam");
|
||||||
|
|
||||||
wapp_mem_arena_destroy(&arena);
|
wapp_mem_arena_destroy(&arena);
|
||||||
|
46
src/obj.c
46
src/obj.c
@ -5,15 +5,33 @@
|
|||||||
#include "typed_list.h"
|
#include "typed_list.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define TRIANGLE_VERTICES 3
|
#define TRIANGLE_VERTICES 3
|
||||||
|
|
||||||
|
#define V2(T, ELEM_T, X0, Y0, X1, Y1) \
|
||||||
|
((T){(ELEM_T)X1 - (ELEM_T)X0, (ELEM_T)Y1 - (ELEM_T)Y0})
|
||||||
|
#define V3(T, ELEM_T, X0, Y0, Z0, X1, Y1, Z1) \
|
||||||
|
((T){(ELEM_T)X1 - (ELEM_T)X0, (ELEM_T)Y1 - (ELEM_T)Y0, \
|
||||||
|
(ELEM_T)Z1 - (ELEM_T)Z0})
|
||||||
#define dot_v2(V1, V2) ((f32)V1.x * (f32)V2.x + (f32)V1.y * (f32)V2.y)
|
#define dot_v2(V1, V2) ((f32)V1.x * (f32)V2.x + (f32)V1.y * (f32)V2.y)
|
||||||
#define dot_v3(V1, V2) \
|
#define dot_v3(V1, V2) \
|
||||||
((f32)V1.x * (f32)V2.x + (f32)V1.y * (f32)V2.y + (f32)V1.z * (f32)V2.z)
|
((f32)V1.x * (f32)V2.x + (f32)V1.y * (f32)V2.y + (f32)V1.z * (f32)V2.z)
|
||||||
#define V2(T, ELEM_T, X0, Y0, X1, Y1) \
|
#define normalise_v3(V) \
|
||||||
((T){(ELEM_T)X1 - (ELEM_T)X0, (ELEM_T)Y1 - (ELEM_T)Y0})
|
do { \
|
||||||
|
f32 magnitude = sqrtf(dot_v3(V, V)); \
|
||||||
|
V.x /= magnitude; \
|
||||||
|
V.y /= magnitude; \
|
||||||
|
V.z /= magnitude; \
|
||||||
|
} while (0);
|
||||||
|
#define cross_product(V1, V2) \
|
||||||
|
((V3f){ \
|
||||||
|
.x = V1.y * V2.z - V1.z * V2.y, \
|
||||||
|
.y = V1.z * V2.x - V1.x * V2.z, \
|
||||||
|
.z = V1.x * V2.y - V1.y * V2.x, \
|
||||||
|
})
|
||||||
|
|
||||||
typedef struct triangle_bbox TriangleBBox;
|
typedef struct triangle_bbox TriangleBBox;
|
||||||
struct triangle_bbox {
|
struct triangle_bbox {
|
||||||
@ -63,6 +81,8 @@ internal void get_image_coordinates(const Vertex *vertex, const Image *img,
|
|||||||
u64 *x, u64 *y);
|
u64 *x, u64 *y);
|
||||||
internal u64 ndc_to_image_coordinate(f32 value, u64 max);
|
internal u64 ndc_to_image_coordinate(f32 value, u64 max);
|
||||||
|
|
||||||
|
V3f g_light_dir = {0.0f, 0.0f, -1.0f};
|
||||||
|
|
||||||
Model load_obj_file(Arena *arena, const char *filename) {
|
Model load_obj_file(Arena *arena, const char *filename) {
|
||||||
if (!arena) {
|
if (!arena) {
|
||||||
return NULL_MODEL;
|
return NULL_MODEL;
|
||||||
@ -148,9 +168,29 @@ internal void render_triangle(const Triangle *triangle, const Model *model,
|
|||||||
|
|
||||||
draw_line(img, x0, y0, x1, y1, colour);
|
draw_line(img, x0, y0, x1, y1, colour);
|
||||||
}
|
}
|
||||||
} else if (type == RENDER_TYPE_FILLED) {
|
} else if (type == RENDER_TYPE_FILLED || type == RENDER_TYPE_SHADED) {
|
||||||
|
f32 intensity = 1.0f;
|
||||||
|
|
||||||
|
if (type == RENDER_TYPE_SHADED) {
|
||||||
|
V3f ab = V3(V3f, f32, vertices[0].x, vertices[0].y, vertices[0].z,
|
||||||
|
vertices[1].x, vertices[1].y, vertices[1].z);
|
||||||
|
V3f ac = V3(V3f, f32, vertices[0].x, vertices[0].y, vertices[0].z,
|
||||||
|
vertices[2].x, vertices[2].y, vertices[2].z);
|
||||||
|
|
||||||
|
V3f normal = cross_product(ac, ab);
|
||||||
|
normalise_v3(normal);
|
||||||
|
|
||||||
|
intensity = dot_v3(normal, g_light_dir);
|
||||||
|
|
||||||
|
colour.r *= intensity;
|
||||||
|
colour.g *= intensity;
|
||||||
|
colour.b *= intensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intensity > 0.0f) {
|
||||||
fill_triangle(img, vertices, colour);
|
fill_triangle(img, vertices, colour);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void fill_triangle(Image *img, Vertex vertices[TRIANGLE_VERTICES],
|
internal void fill_triangle(Image *img, Vertex vertices[TRIANGLE_VERTICES],
|
||||||
|
Loading…
Reference in New Issue
Block a user