#include "img.h" #include "mem_arena.h" #include "misc_utils.h" #include "obj.h" #include "render.h" #include "shaders.h" #include "str.h" #include #include #include #include #include #include #define IMAGE_DIMENSION 1200 enum { TINY_EXIT_SUCCESS, TINY_EXIT_MISSING_ARGS, TINY_EXIT_OBJ_NOT_EXIST, TINY_EXIT_ARENA_INIT_FAILED, TINY_EXIT_RENDER_INIT_FAILED, TINY_EXIT_MODEL_LOAD_FAILED, }; typedef struct tiny_args TinyArgs; struct tiny_args { Str8 obj; Str8 diffuse; Str8 nm_tangent; }; internal TinyArgs parse_args(Arena *arena, int argc, char *argv[]); internal i32 tinyrenderer(Arena *arena, TinyArgs args); internal bool file_exists(const Str8 *path); i32 main(int argc, char *argv[]) { Arena *arena = NULL; if (!wapp_mem_arena_init(&arena, GB(10))) { return TINY_EXIT_ARENA_INIT_FAILED; } TinyArgs args = parse_args(arena, argc, argv); i32 output = tinyrenderer(arena, args); wapp_mem_arena_destroy(&arena); return output; } internal TinyArgs parse_args(Arena *arena, int argc, char *argv[]) { if (argc < 2) { exit(TINY_EXIT_MISSING_ARGS); } TinyArgs args = { .obj = str8_lit(argv[1]), }; if (!file_exists(&args.obj)) { exit(TINY_EXIT_OBJ_NOT_EXIST); } u64 substr_end = args.obj.length - 4; args.diffuse = str8_substr(arena, &args.obj, 0, substr_end); str8_concat(arena, &args.diffuse, "_diffuse.pnm"); if (!file_exists(&args.diffuse)) { args.diffuse = (Str8){0}; } args.nm_tangent = str8_substr(arena, &args.obj, 0, substr_end); str8_concat(arena, &args.nm_tangent, "_nm_tangent.pnm"); if (!file_exists(&args.nm_tangent)) { args.nm_tangent = (Str8){0}; } return args; } internal i32 tinyrenderer(Arena *arena, TinyArgs args) { Colour bg = {.r = 42, .g = 45, .b = 52, .a = 255}; Colour main_colour = {.r = 14, .g = 156, .b = 208, .a = 255}; Render render; if (!init_render(arena, &render, IMAGE_DIMENSION, IMAGE_DIMENSION)) { return TINY_EXIT_RENDER_INIT_FAILED; } Model obj = load_obj_file( arena, args.obj.str, args.diffuse.length > 0 ? args.diffuse.str : NULL, args.nm_tangent.length > 0 ? args.nm_tangent.str : NULL); if (IS_INVALID_MODEL(obj)) { return TINY_EXIT_MODEL_LOAD_FAILED; } load_shaders(); clear_buffer(&(render.img), &bg); render_model(&obj, &render, perspective_diffuse, RENDER_TYPE_SHADED, main_colour); save_image(&(render.img), "result.pam"); return TINY_EXIT_SUCCESS; } internal bool file_exists(const Str8 *path) { struct stat st; return stat(path->str, &st) == 0; }