3dtoys/scene.c

279 lines
9.1 KiB
C
Raw Normal View History

2024-08-13 01:21:18 +00:00
#include "haloo3d/haloo3d.h"
2024-09-21 04:38:46 +00:00
// #include "haloo3d/haloo3dex_easy.h"
2024-08-13 01:21:18 +00:00
#include "haloo3d/haloo3dex_gen.h"
#include "haloo3d/haloo3dex_img.h"
#include "haloo3d/haloo3dex_obj.h"
#include "haloo3d/haloo3dex_print.h"
2024-09-21 04:38:46 +00:00
#include "unigi/main.h"
2024-08-13 01:47:01 +00:00
// #include "unigi/unigi.ext/src/main.c"
#include "camera.h"
2024-08-13 01:21:18 +00:00
#include "resources/flower.h"
#include <stdlib.h>
#include <time.h>
#define DOLIGHTING
2024-09-21 04:38:46 +00:00
// #define FASTTRIS
2024-08-13 01:21:18 +00:00
2024-08-13 04:40:03 +00:00
// IDK you probably have to change this based on your display.
// Maybe there's a way to fix this?
2024-08-26 05:28:02 +00:00
#define UNIGIBITDEPTH 0
2024-08-13 04:40:03 +00:00
#define TARGETFPS 60
2024-08-15 06:28:37 +00:00
#define DITHERSTART 100
#define DITHEREND 101
2024-09-21 04:38:46 +00:00
#define PCTSTART 100
2024-08-15 06:28:37 +00:00
2024-08-13 01:21:18 +00:00
#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 SKYSCALE 30
#define AVGWEIGHT 0.85
// this is the number of DYNAMIC objects..
#define NUMOBJECTS 4
#define NUMFLOWERS 300
#define PLANESIZE 61
#define FLOWERIND (NUMOBJECTS - 1)
#define NUMINSTANCES (NUMOBJECTS - 1 + NUMFLOWERS)
#define MAXCAM 1200
2024-09-21 04:38:46 +00:00
// #ifdef FASTTRIS
// #define WBUFCLEAR FARCLIP
// #define TRIFUNC haloo3d_texturedtriangle_fast
// #else
// #define WBUFCLEAR 0
// #define TRIFUNC haloo3d_texturedtriangle
// #endif
2024-08-13 01:21:18 +00:00
#define CALCTIME(thistime, start, end, sum) \
2024-08-13 02:17:14 +00:00
thistime = 1000.0 * (float)(end - start) / CLOCKS_PER_SEC; \
2024-08-13 01:21:18 +00:00
if (sum == 0) \
sum = thistime; \
sum = AVGWEIGHT * sum + (1 - AVGWEIGHT) * thistime;
uint16_t redflower[64] = H3D_FLOWER(0xFE55, 0xF6C4, 0xFFE0, 0xFD44, 0xF492);
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");
}
// Load the junk + generate stuff
haloo3d_obj models[NUMOBJECTS];
haloo3d_fb textures[NUMOBJECTS];
haloo3d_obj_loadfile(models, argv[1]);
haloo3d_img_loadppmfile(textures, argv[2]);
2024-08-16 03:45:30 +00:00
haloo3d_fb_init_tex(textures + 1, 32, 32);
haloo3d_apply_vgradient(textures + 1, 0xF001, 0xF44F);
2024-08-13 01:21:18 +00:00
haloo3d_gen_skybox(models + 1);
uint16_t checkcols[2] = {0xF0A0, 0xF270};
2024-08-16 03:45:30 +00:00
haloo3d_fb_init_tex(textures + 2, 32, 32);
haloo3d_apply_alternating(textures + 2, checkcols, 2);
2024-08-13 01:21:18 +00:00
haloo3d_gen_sloped(models + 2, PLANESIZE, 1.0, 1.25);
haloo3d_fb_init_tex(textures + 3, 8, 8);
memcpy(textures[3].buffer, redflower, sizeof(uint16_t) * 64);
2024-08-26 05:28:02 +00:00
haloo3d_gen_crossquad(models + 3, textures + 3,
(struct vec3){.x = 0, .y = 0, .z = 0});
eprintf("Initialized models + textures");
2024-08-13 01:21:18 +00:00
camset cams[MAXCAM];
int numcams = readcam(cams, MAXCAM, argv[3]);
// Create the camera matrix, which DOES change. In this one,
// we move the camera instead of the model
haloo3d_camera camera;
haloo3d_camera_init(&camera);
// Create the perspective matrix, which doesn't change
mfloat_t perspective[MAT4_SIZE];
haloo3d_perspective(perspective, FOV, ASPECT, NEARCLIP, FARCLIP);
// 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 objects[NUMINSTANCES];
for (int i = 0; i < NUMINSTANCES; i++) {
if (i < FLOWERIND) {
haloo3d_objin_init(objects + i, models + i, textures + i);
} else { // Setup the flowers
haloo3d_objin_init(objects + i, models + FLOWERIND, textures + FLOWERIND);
objects[i].cullbackface = 0;
2024-08-16 03:45:30 +00:00
vec3(objects[i].scale.v, 0.5, 0.5, 0.5);
2024-08-13 01:21:18 +00:00
int rvi = rand() % models[2].numvertices;
vec3_assign(objects[i].pos.v, models[2].vertices[rvi].v);
objects[i].pos.y += 0.5;
}
totalfaces += objects[i].model->numfaces;
totalverts += objects[i].model->numvertices;
}
#ifdef DOLIGHTING
objects[0].lighting = &light;
objects[2].lighting = &light;
#endif
objects[0].pos.y = 1;
2024-08-16 03:45:30 +00:00
vec3(objects[1].scale.v, SKYSCALE, SKYSCALE, SKYSCALE);
2024-08-26 05:28:02 +00:00
eprintf("Initialized object instances\n");
2024-08-13 01:21:18 +00:00
// Now we create a framebuffer to draw the triangle into
haloo3d_fb fb;
haloo3d_fb_init(&fb, WIDTH, HEIGHT);
2024-08-13 01:47:01 +00:00
unigi_type_event event;
unigi_type_resolution res;
res.width = WIDTH;
res.height = HEIGHT;
2024-08-13 04:40:03 +00:00
res.depth = UNIGIBITDEPTH;
2024-08-13 01:47:01 +00:00
2024-08-13 01:21:18 +00:00
// Printing to screen needs tracking
haloo3d_print_tracker t;
char printbuf[8192];
haloo3d_print_initdefault(&t, printbuf, sizeof(printbuf));
t.fb = &fb;
2024-08-13 01:47:01 +00:00
// t.logprints = 1;
2024-08-13 01:21:18 +00:00
// Storage stuff
mfloat_t matrix3d[MAT4_SIZE], matrixcam[MAT4_SIZE], matrixscreen[MAT4_SIZE],
matrixmodel[MAT4_SIZE];
haloo3d_facef outfaces[H3D_FACEF_MAXCLIP];
struct vec3 tmp1;
haloo3d_facef face, baseface;
struct vec4 *vert_precalc;
mallocordie(vert_precalc, sizeof(struct vec4) * H3D_OBJ_MAXVERTICES);
clock_t begin, end;
2024-08-13 04:40:03 +00:00
// Measured in milliseconds
2024-08-13 02:17:14 +00:00
float sumframe = 0, lastframe = 0;
2024-08-13 04:40:03 +00:00
float msperframe = 1000.0 / TARGETFPS;
2024-08-13 01:21:18 +00:00
int totaldrawn = 0;
2024-08-15 06:28:37 +00:00
// Setup render config with defaults. We won't necessarily use all features
// present in this
haloo3d_trirender rendersettings;
haloo3d_trirender_init(&rendersettings);
2024-09-21 04:38:46 +00:00
rendersettings.ditherfar = DITHEREND;
rendersettings.ditherclose = DITHERSTART;
rendersettings.pctminsize = PCTSTART;
2024-08-15 06:28:37 +00:00
2024-08-13 01:21:18 +00:00
eprintf("Scene has %d tris, %d verts\n", totalfaces, totalverts);
2024-08-13 01:47:01 +00:00
// Init unigi system
sprintf(printbuf, "scene.exe - %s %s %s", argv[1], argv[2], argv[3]);
unigi_graphics_init();
unigi_window_create(res, printbuf);
2024-08-13 01:21:18 +00:00
// -----------------------------------
// Actual rendering
// -----------------------------------
2024-08-13 01:47:01 +00:00
int cami = 0;
while (1) {
2024-08-13 02:17:14 +00:00
begin = clock();
2024-08-13 01:47:01 +00:00
unigi_event_get(&event);
if (event.type == unigi_enum_event_input_keyboard) {
exit(0);
}
2024-08-13 01:21:18 +00:00
totaldrawn = 0;
haloo3d_print_refresh(&t);
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;
// REMEMBER TO CLEAR DEPTH BUFFER
2024-09-21 04:38:46 +00:00
haloo3d_fb_cleardepth(&fb);
2024-08-13 01:21:18 +00:00
// Screen matrix calc. We multiply the modelview matrix with this later
haloo3d_camera_calclook(&camera, matrixcam);
mat4_inverse(matrixcam, matrixcam);
mat4_multiply(matrixscreen, perspective, matrixcam);
2024-08-26 05:28:02 +00:00
// eprintf("BEGIN ITERATE OBJECTS\n");
2024-08-13 01:21:18 +00:00
// Iterate over objects
for (int i = 0; i < NUMINSTANCES; i++) {
// Setup final model matrix and the precalced vertices
vec3_add(tmp1.v, objects[i].pos.v, objects[i].lookvec.v);
haloo3d_my_lookat(matrixmodel, objects[i].pos.v, tmp1.v, camera.up.v);
2024-08-16 03:45:30 +00:00
haloo3d_mat4_scalev(matrixmodel, objects[i].scale.v);
2024-08-13 01:21:18 +00:00
mat4_multiply(matrix3d, matrixscreen, matrixmodel);
haloo3d_precalc_verts(objects[i].model, matrix3d, vert_precalc);
2024-08-15 06:28:37 +00:00
rendersettings.texture = objects[i].texture;
2024-08-13 01:21:18 +00:00
// Iterate over object faces
for (int fi = 0; fi < objects[i].model->numfaces; fi++) {
// Copy face values out of precalc array and clip them
haloo3d_make_facef(objects[i].model->faces[fi], vert_precalc,
objects[i].model->vtexture, face);
int tris = haloo3d_facef_clip(face, outfaces);
2024-08-15 06:28:37 +00:00
if (tris > 0) {
2024-09-21 04:38:46 +00:00
// haloo3d_getdither4x4(float dither, uint8_t *buf)
// haloo3d_easy_calcdither4x4(&rendersettings, face, DITHERSTART,
// DITHEREND);
2024-08-15 06:28:37 +00:00
rendersettings.intensity = 1.0;
if (objects[i].lighting) {
haloo3d_obj_facef(objects[i].model, objects[i].model->faces[fi],
baseface);
rendersettings.intensity =
haloo3d_calc_light(objects[i].lighting->v, MINLIGHT, baseface);
}
}
2024-08-13 01:21:18 +00:00
for (int ti = 0; ti < tris; ti++) {
int backface = !haloo3d_facef_finalize(outfaces[ti]);
if (objects[i].cullbackface && backface) {
continue;
}
totaldrawn++;
// We still have to convert the points into the view
haloo3d_facef_viewport_into(outfaces[ti], WIDTH, HEIGHT);
2024-08-26 05:28:02 +00:00
// eprintf("RENDER TRI\n");
2024-09-21 04:38:46 +00:00
haloo3d_triangle(&fb, &rendersettings, outfaces[ti]);
2024-08-13 01:21:18 +00:00
}
}
}
2024-08-26 05:28:02 +00:00
// eprintf("OBJECTS COMPLETE\n");
2024-08-13 01:21:18 +00:00
2024-08-13 02:17:14 +00:00
haloo3d_print(&t, "Last frame: %05.2f (%05.2f)\nTris: %d / %d\nVerts: %d\n",
lastframe, sumframe, totaldrawn, totalfaces, totalverts);
2024-08-13 01:21:18 +00:00
2024-08-13 01:47:01 +00:00
unigi_graphics_blit(0, (unigi_type_color *)fb.buffer,
res.width * res.height);
unigi_graphics_flush();
cami = (cami + 1) % numcams;
2024-08-13 02:17:14 +00:00
end = clock();
CALCTIME(lastframe, begin, end, sumframe);
2024-08-13 04:40:03 +00:00
float waittime = msperframe - lastframe;
if (waittime > 0) {
unigi_time_sleep(waittime * unigi_time_clocks_per_s / 1000);
}
2024-08-13 01:21:18 +00:00
}
2024-08-13 04:40:03 +00:00
// Free after loop
2024-08-13 01:21:18 +00:00
for (int i = 0; i < NUMOBJECTS; i++) {
haloo3d_obj_free(models + i);
haloo3d_fb_free(textures + i);
}
}