Compare commits

...

2 Commits

Author SHA1 Message Date
ba88c5b27c Make face region higher poly 2024-08-10 17:38:39 +01:00
1ad2ca1a47 Fix checking barycentric coordinates 2024-08-10 17:38:13 +01:00
4 changed files with 70105 additions and 20322 deletions

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,7 @@ u8 *_get_pixel(Buffer *buffer, u64 x, u64 y, u64 base_size) {
void _set_pixel(Buffer *buffer, u64 x, u64 y, void *value, u64 base_size) { void _set_pixel(Buffer *buffer, u64 x, u64 y, void *value, u64 base_size) {
u64 idx = calculate_pixel_index(buffer, x, y, base_size); u64 idx = calculate_pixel_index(buffer, x, y, base_size);
memcpy(((u8 *)(buffer->buf)) + idx, value, base_size); memcpy(((u8 *)(buffer->buf)) + idx, value, base_size);
return;
} }
void _clear_buffer(Buffer *buffer, void *value, u64 base_size) { void _clear_buffer(Buffer *buffer, void *value, u64 base_size) {

View File

@ -7,6 +7,9 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#define SIZE 1200
#define RESOURCE(NAME) "resources/" NAME
enum { enum {
TINY_EXIT_SUCCESS, TINY_EXIT_SUCCESS,
TINY_EXIT_ARENA_INIT_FAILED, TINY_EXIT_ARENA_INIT_FAILED,
@ -27,12 +30,12 @@ int main(void) {
Colour teal = {.r = 14, .g = 156, .b = 208, .a = 255}; Colour teal = {.r = 14, .g = 156, .b = 208, .a = 255};
Colour orange = {.r = 242, .g = 100, .b = 48, .a = 255}; Colour orange = {.r = 242, .g = 100, .b = 48, .a = 255};
Render render; Render render;
if (!init_render(arena, &render, 1200, 1200)) { if (!init_render(arena, &render, SIZE, SIZE)) {
return TINY_EXIT_RENDER_INIT_FAILED; return TINY_EXIT_RENDER_INIT_FAILED;
} }
Model model = Model model =
load_obj_file(arena, "resources/head.obj", "resources/head.pnm"); load_obj_file(arena, RESOURCE("head.obj"), RESOURCE("head.pnm"));
if (INVALID_MODEL(model)) { if (INVALID_MODEL(model)) {
return TINY_EXIT_MODEL_LOAD_FAILED; return TINY_EXIT_MODEL_LOAD_FAILED;
} }

View File

@ -49,6 +49,12 @@ struct i64x2 {
i64 y; i64 y;
}; };
typedef struct u64x2 V2u;
struct u64x2 {
u64 x;
u64 y;
};
typedef struct f32x3 V3f; typedef struct f32x3 V3f;
struct f32x3 { struct f32x3 {
f32 x; f32 x;
@ -75,6 +81,8 @@ internal void render_triangle(const Triangle *triangle, const Model *model,
internal void fill_triangle(Render *render, Vertex vertices[TRIANGLE_VERTICES], internal void fill_triangle(Render *render, Vertex vertices[TRIANGLE_VERTICES],
TexCoord coordinates[TRIANGLE_VERTICES], TexCoord coordinates[TRIANGLE_VERTICES],
Colour colour, f32 intensity, Image *texture); Colour colour, f32 intensity, Image *texture);
internal void reorder_points(V2u vertices[TRIANGLE_VERTICES],
TexCoord coordinates[TRIANGLE_VERTICES]);
internal TriangleBBox get_triangle_bbox(const Image *img, internal TriangleBBox get_triangle_bbox(const Image *img,
Vertex vertices[TRIANGLE_VERTICES]); Vertex vertices[TRIANGLE_VERTICES]);
internal V3f get_barycentric_coords(f32 d00, f32 d01, f32 d11, f32 denom, internal V3f get_barycentric_coords(f32 d00, f32 d01, f32 d11, f32 denom,
@ -162,7 +170,7 @@ bool init_render(Arena *arena, Render *render, u64 width, u64 height) {
return false; return false;
} }
f32 inf = -1.0f * INFINITY; f32 inf = -INFINITY;
clear_buffer(&(render->depth), &inf); clear_buffer(&(render->depth), &inf);
return true; return true;
@ -239,17 +247,17 @@ internal void fill_triangle(Render *render, Vertex vertices[TRIANGLE_VERTICES],
Depth *depth = &(render->depth); Depth *depth = &(render->depth);
TriangleBBox bbox = get_triangle_bbox(img, vertices); TriangleBBox bbox = get_triangle_bbox(img, vertices);
u64 v0x, v0y, v1x, v1y, v2x, v2y; V2u v0, v1, v2;
get_image_coordinates(vertices[0].x, vertices[0].y, img, &v0x, &v0y); get_image_coordinates(vertices[0].x, vertices[0].y, img, &(v0.x), &(v0.y));
get_image_coordinates(vertices[1].x, vertices[1].y, img, &v1x, &v1y); get_image_coordinates(vertices[1].x, vertices[1].y, img, &(v1.x), &(v1.y));
get_image_coordinates(vertices[2].x, vertices[2].y, img, &v2x, &v2y); get_image_coordinates(vertices[2].x, vertices[2].y, img, &(v2.x), &(v2.y));
V2i ab = V2(V2i, i64, v0x, v0y, v1x, v1y); V2i ab = V2(V2i, i64, v0.x, v0.y, v1.x, v1.y);
V2i ac = V2(V2i, i64, v0x, v0y, v2x, v2y); V2i ac = V2(V2i, i64, v0.x, v0.y, v2.x, v2.y);
f32 d00 = dot_v2(ab, ab); f32 d00 = dot_v2(ab, ab);
f32 d01 = dot_v2(ab, ac); f32 d01 = dot_v2(ab, ac);
f32 d11 = dot_v2(ac, ac); f32 d11 = dot_v2(ac, ac);
f32 denom = (f32)d00 * (f32)d11 - (f32)d01 * (f32)d01; f32 denom = d00 * d11 - d01 * d01;
V2i ap; V2i ap;
V3f coords; V3f coords;
f32 z; f32 z;
@ -263,11 +271,11 @@ internal void fill_triangle(Render *render, Vertex vertices[TRIANGLE_VERTICES],
colour.b *= intensity; colour.b *= intensity;
} }
for (u64 y = bbox.y0; y < bbox.y1; ++y) { for (u64 y = bbox.y0; y <= bbox.y1; ++y) {
for (u64 x = bbox.x0; x < bbox.x1; ++x) { for (u64 x = bbox.x0; x <= bbox.x1; ++x) {
ap = V2(V2i, i64, v0x, v0y, x, y); ap = V2(V2i, i64, v0.x, v0.y, x, y);
coords = get_barycentric_coords(d00, d01, d11, denom, &ab, &ac, &ap); coords = get_barycentric_coords(d00, d01, d11, denom, &ab, &ac, &ap);
if (coords.x < 0.0f || coords.y < 0.0f || coords.z < 0.0f) { if (coords.x < 0.0f || coords.y < 0.0f || coords.x + coords.y > 1.0f) {
continue; continue;
} }
@ -317,6 +325,10 @@ internal TriangleBBox get_triangle_bbox(const Image *img,
internal V3f get_barycentric_coords(f32 d00, f32 d01, f32 d11, f32 denom, internal V3f get_barycentric_coords(f32 d00, f32 d01, f32 d11, f32 denom,
const V2i *ab, const V2i *ac, const V2i *ab, const V2i *ac,
const V2i *ap) { const V2i *ap) {
if (denom == 0.0f) {
return (V3f){-INFINITY, -INFINITY, -INFINITY};
}
f32 d20 = dot_v2((*ap), (*ab)); f32 d20 = dot_v2((*ap), (*ab));
f32 d21 = dot_v2((*ap), (*ac)); f32 d21 = dot_v2((*ap), (*ac));
@ -331,6 +343,13 @@ internal void get_image_coordinates(f32 norm_x, f32 norm_y, const Image *img,
u64 *x, u64 *y) { u64 *x, u64 *y) {
*x = ndc_to_image_coordinate(norm_x, img->width); *x = ndc_to_image_coordinate(norm_x, img->width);
*y = ndc_to_image_coordinate(0.0f - norm_y, img->height); *y = ndc_to_image_coordinate(0.0f - norm_y, img->height);
if (*x >= img->width) {
*x = img->width - 1;
}
if (*y >= img->height) {
*y = img->height - 1;
}
} }
internal u64 ndc_to_image_coordinate(f32 value, u64 max) { internal u64 ndc_to_image_coordinate(f32 value, u64 max) {