#include "haloo3d/haloo3d.h" #include "haloo3d/haloo3dex_easy.h" #include "haloo3d/haloo3dex_gen.h" // #include "haloo3d/haloo3dex_img.h" #include "haloo3d/haloo3dex_obj.h" #include "haloo3d/haloo3dex_print.h" #include "unigi/unigi.headers/src/main.h" #include "unigi/unigi.platform.sdl1/src/main.c" #include // Performance options #define DOLIGHTING // #define FASTTRIS #define DITHERSTART 100 #define DITHEREND 101 #define TARGETFPS 60 #define SECPERFRAME 1.0 / TARGETFPS // IDK you probably have to change this based on your display. // Maybe there's a way to fix this? #define UNIGIBITDEPTH 32 #define WIDTH 640 #define HEIGHT 480 #define ASPECT ((float)WIDTH / HEIGHT) #define FOV 90.0 #define NEARCLIP 0.01 #define FARCLIP 100.0 #define LIGHTANG -MPI / 4.0 #define MINLIGHT 0.25 #define AVGWEIGHT 0.85 // Game options #define MAZESIZE 31 #ifdef FASTTRIS #define DBUFCLEARFUNC(fb) haloo3d_fb_cleardepth(fb, FARCLIP); #define TRIFUNC haloo3d_texturedtriangle_fast #else #define DBUFCLEARFUNC(fb) haloo3d_fb_cleardepth(fb, 0); #define TRIFUNC haloo3d_texturedtriangle #endif int main(int argc, char **argv) { if (argc != 4) { dieerr("You must pass in the following:\n- obj file .obj\n- texture file " ".ppm\n- camera file (xofs yofs zofs yawdeg pitchdeg)\n"); } haloo3d_easystore storage; haloo3d_easystore_init(&storage); haloo3d_easyrender render; haloo3d_easyrender_init(&render, WIDTH, HEIGHT); haloo3d_perspective(render.perspective, FOV, ASPECT, NEARCLIP, FARCLIP); // Setup render config with defaults. We won't necessarily use all features // present in this haloo3d_trirender rendersettings; haloo3d_trirender_init(&rendersettings); haloo3d_easytimer frametimer; haloo3d_easytimer_init(&frametimer); // Load the junk + generate stuff haloo3d_obj *flooro = haloo3d_easystore_addobj(&storage, "floor"); haloo3d_obj *ceilo = haloo3d_easystore_addobj(&storage, "ceiling"); haloo3d_fb *floort = haloo3d_easystore_addtex(&storage, "floor"); haloo3d_fb *ceilt = haloo3d_easystore_addtex(&storage, "ceiling"); haloo3d_gen_plane(flooro, MAZESIZE); haloo3d_gen_plane(ceilo, MAZESIZE); uint16_t cols[4] = {0xFD93, 0xFB83, 0xFEEE, 0xFDDD}; haloo3d_gen_checkerboard(floort, cols, 2, 32); haloo3d_gen_checkerboard(ceilt, cols + 2, 2, 32); // Lighting. Note that for performance, the lighting is always calculated // against the base model, and is thus not realistic if the object rotates in // the world. This can be fixed easily, since each object gets its own // lighting vector, which can easily be rotated in the opposite direction of // the model struct vec3 light; vec3(light.v, 0, -MCOS(LIGHTANG), MSIN(LIGHTANG)); int totalfaces = 0; int totalverts = 0; haloo3d_obj_instance *floori = haloo3d_easyrender_addinstance(&render, flooro, floort); haloo3d_obj_instance *ceili = haloo3d_easyrender_addinstance(&render, ceilo, ceilt); // totalfaces += objects[i].model->numfaces; // totalverts += objects[i].model->numvertices; // #ifdef DOLIGHTING // objects[0].lighting = &light; // objects[2].lighting = &light; // #endif unigi_type_event event; unigi_type_resolution res; res.width = WIDTH; res.height = HEIGHT; res.depth = UNIGIBITDEPTH; // Storage stuff haloo3d_facef face, baseface; int totaldrawn = 0; eprintf("Scene has %d tris, %d verts\n", totalfaces, totalverts); // Init unigi system sprintf(render.printbuf, "scene.exe - %s %s %s", argv[1], argv[2], argv[3]); unigi_graphics_init(); unigi_window_create(res, render.printbuf); // ----------------------------------- // Actual rendering // ----------------------------------- while (1) { haloo3d_easytimer_start(&frametimer); haloo3d_easyrender_beginframe(&render); unigi_event_get(&event); if (event.type == unigi_enum_event_input_keyboard) { exit(0); } totaldrawn = 0; // camera.pos.x = cams[cami].xofs; // camera.pos.y = cams[cami].yofs; // camera.pos.z = cams[cami].zofs; // camera.yaw = cams[cami].yaw; // camera.pitch = cams[cami].pitch + MPI_2; haloo3d_obj_instance *object = NULL; // Iterate over objects while ((object = haloo3d_easyrender_nextinstance(&render, object))) { // Setup final model matrix and the precalced vertices haloo3d_easyrender_beginmodel(&render, object); rendersettings.texture = object->texture; // Iterate over object faces for (int fi = 0; fi < object->model->numfaces; fi++) { // Copy face values out of precalc array and clip them haloo3d_make_facef(object->model->faces[fi], render.precalcs, object->model->vtexture, face); int tris = haloo3d_facef_clip(face, render.outfaces); if (tris > 0) { haloo3d_easy_calcdither4x4(&rendersettings, face, DITHERSTART, DITHEREND); rendersettings.intensity = 1.0; if (object->lighting) { haloo3d_obj_facef(object->model, object->model->faces[fi], baseface); rendersettings.intensity = haloo3d_calc_light(object->lighting->v, MINLIGHT, baseface); } } for (int ti = 0; ti < tris; ti++) { int backface = !haloo3d_facef_finalize(render.outfaces[ti]); if (object->cullbackface && backface) { continue; } totaldrawn++; // We still have to convert the points into the view haloo3d_facef_viewport_into(render.outfaces[ti], WIDTH, HEIGHT); TRIFUNC(&render.window, &rendersettings, render.outfaces[ti]); } } } haloo3d_print(&render.tprint, "Last frame: %05.2f (%05.2f)\nTris: %d / %d\nVerts: %d\n", frametimer.last * 1000, frametimer.sum * 1000, totaldrawn, totalfaces, totalverts); unigi_graphics_blit(0, (unigi_type_color *)&render.window, res.width * res.height); unigi_graphics_flush(); haloo3d_easytimer_end(&frametimer); float waittime = SECPERFRAME - frametimer.last; if (waittime > 0) { unigi_time_sleep(waittime * unigi_time_clocks_per_s); } } haloo3d_easystore_deleteallobj(&storage, haloo3d_obj_free); haloo3d_easystore_deletealltex(&storage, haloo3d_fb_free); }