Compare commits
2 Commits
b111058f31
...
ba88c5b27c
Author | SHA1 | Date | |
---|---|---|---|
ba88c5b27c | |||
1ad2ca1a47 |
90376
resources/head.obj
90376
resources/head.obj
File diff suppressed because it is too large
Load Diff
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
43
src/obj.c
43
src/obj.c
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user