Pass model as a CLI arg
This commit is contained in:
parent
351b7e9d42
commit
1223e55db1
72
src/main.c
72
src/main.c
@ -4,30 +4,82 @@
|
||||
#include "obj.h"
|
||||
#include "render.h"
|
||||
#include "shaders.h"
|
||||
#include "str.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
||||
#define IMAGE_DIMENSION 1200
|
||||
#define RESOURCE(NAME) "resources/" NAME
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
int tinyrenderer(void);
|
||||
typedef struct tiny_args TinyArgs;
|
||||
struct tiny_args {
|
||||
Str8 obj;
|
||||
Str8 diffuse;
|
||||
Str8 nm_tangent;
|
||||
};
|
||||
|
||||
int main(void) { return tinyrenderer(); }
|
||||
internal TinyArgs parse_args(Arena *arena, int argc, char *argv[]);
|
||||
internal i32 tinyrenderer(Arena *arena, TinyArgs args);
|
||||
internal bool file_exists(const Str8 *path);
|
||||
|
||||
int tinyrenderer(void) {
|
||||
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);
|
||||
}
|
||||
|
||||
const Str8 basename = str8_substr(&args.obj, 0, args.obj.length - 4);
|
||||
|
||||
args.diffuse = str8_copy(arena, &basename);
|
||||
str8_concat(arena, &args.diffuse, "_diffuse.pnm");
|
||||
if (!file_exists(&args.diffuse)) {
|
||||
args.diffuse = (Str8){0};
|
||||
}
|
||||
|
||||
args.nm_tangent = str8_copy(arena, &basename);
|
||||
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;
|
||||
@ -35,8 +87,9 @@ int tinyrenderer(void) {
|
||||
return TINY_EXIT_RENDER_INIT_FAILED;
|
||||
}
|
||||
|
||||
Model obj = load_obj_file(arena, RESOURCE("head.obj"), RESOURCE("head.pnm"),
|
||||
RESOURCE("head_nm_tangent.pnm"));
|
||||
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;
|
||||
}
|
||||
@ -48,7 +101,10 @@ int tinyrenderer(void) {
|
||||
main_colour);
|
||||
save_image(&(render.img), "result.pam");
|
||||
|
||||
wapp_mem_arena_destroy(&arena);
|
||||
|
||||
return TINY_EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
internal bool file_exists(const Str8 *path) {
|
||||
struct stat st;
|
||||
return stat(path->str, &st) == 0;
|
||||
}
|
||||
|
98
src/str/str.c
Normal file
98
src/str/str.c
Normal file
@ -0,0 +1,98 @@
|
||||
#include "str.h"
|
||||
#include "aliases.h"
|
||||
#include "mem_arena.h"
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CAPACITY_SCALAR 8
|
||||
|
||||
internal Arena *get_temp_arena(void);
|
||||
internal void destroy_temp_arena(Arena *arena);
|
||||
|
||||
Str8 str8(Arena *arena, char *str) {
|
||||
if (!str) {
|
||||
return (Str8){0};
|
||||
}
|
||||
|
||||
u64 length = strlen(str);
|
||||
Str8 output = {
|
||||
.str = str,
|
||||
.length = length,
|
||||
.capacity = length,
|
||||
};
|
||||
|
||||
if (arena) {
|
||||
output.capacity *= CAPACITY_SCALAR;
|
||||
|
||||
output.str = wapp_mem_arena_alloc(arena, output.capacity);
|
||||
if (!output.str) {
|
||||
return (Str8){0};
|
||||
}
|
||||
|
||||
strncpy(output.str, str, output.length);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
Str8 str8_copy(Arena *arena, const Str8 *str) {
|
||||
if (!arena) {
|
||||
return str8_lit(str->str);
|
||||
}
|
||||
|
||||
char *tmp = wapp_mem_arena_alloc(arena, str->capacity);
|
||||
if (!tmp) {
|
||||
return str8_lit(str->str);
|
||||
}
|
||||
|
||||
strncpy(tmp, str->str, str->length);
|
||||
|
||||
return (Str8){
|
||||
.str = tmp,
|
||||
.length = str->length,
|
||||
.capacity = str->capacity,
|
||||
};
|
||||
}
|
||||
|
||||
i32 str8_concat(Arena *arena, Str8 *dst, char *src) {
|
||||
if (!src || !dst) {
|
||||
return STR_OP_FAILED;
|
||||
}
|
||||
|
||||
u64 src_length = strlen(src);
|
||||
if (src_length + dst->length > dst->capacity) {
|
||||
if (!arena) {
|
||||
return STR_OP_FAILED;
|
||||
}
|
||||
|
||||
u64 capacity = dst->capacity * CAPACITY_SCALAR + src_length;
|
||||
char *str = wapp_mem_arena_alloc(arena, capacity);
|
||||
if (!str) {
|
||||
return STR_OP_FAILED;
|
||||
}
|
||||
|
||||
strncpy(str, dst->str, dst->length);
|
||||
strncpy(str + dst->length, src, src_length);
|
||||
|
||||
dst->str = str;
|
||||
dst->length = dst->length + src_length;
|
||||
dst->capacity = capacity;
|
||||
|
||||
return STR_OP_SUCEEDED;
|
||||
}
|
||||
|
||||
strncpy(dst->str + dst->length, src, src_length);
|
||||
return STR_OP_SUCEEDED;
|
||||
}
|
||||
|
||||
const Str8 str8_substr(const Str8 *str, u64 start, u64 count) {
|
||||
if (start > str->length || start + count > str->length) {
|
||||
return (Str8){0};
|
||||
}
|
||||
|
||||
return (Str8){
|
||||
.str = str->str + start,
|
||||
.length = count,
|
||||
.capacity = count,
|
||||
};
|
||||
}
|
26
src/str/str.h
Normal file
26
src/str/str.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef STR_H
|
||||
#define STR_H
|
||||
|
||||
#include "aliases.h"
|
||||
#include "mem_arena.h"
|
||||
|
||||
enum {
|
||||
STR_OP_SUCEEDED,
|
||||
STR_OP_FAILED,
|
||||
};
|
||||
|
||||
typedef struct str8 Str8;
|
||||
struct str8 {
|
||||
char *str;
|
||||
u64 length;
|
||||
u64 capacity;
|
||||
};
|
||||
|
||||
#define str8_lit(STR) (str8(NULL, STR))
|
||||
|
||||
Str8 str8(Arena *arena, char *str);
|
||||
Str8 str8_copy(Arena *arena, const Str8 *str);
|
||||
i32 str8_concat(Arena *arena, Str8 *dst, char *src);
|
||||
const Str8 str8_substr(const Str8 *str, u64 start, u64 count);
|
||||
|
||||
#endif // !STR_H
|
Loading…
Reference in New Issue
Block a user