2024-09-08 22:42:50 +00:00
|
|
|
#include "haloo3d/haloo3d.h"
|
|
|
|
#include "haloo3d/haloo3dex_easy.h"
|
|
|
|
#include "haloo3d/haloo3dex_gen.h"
|
|
|
|
#include "haloo3d/haloo3dex_obj.h"
|
|
|
|
|
2024-09-09 03:04:57 +00:00
|
|
|
#include "haloo3d/lib/mathc.h"
|
2024-09-08 22:42:50 +00:00
|
|
|
#include "unigi/unigi.headers/src/main.h"
|
|
|
|
#include "unigi/unigi.platform.sdl1/src/main.c"
|
|
|
|
|
|
|
|
#include "ecs2.h"
|
2024-09-09 03:04:57 +00:00
|
|
|
// #include "keys.h"
|
2024-09-08 22:42:50 +00:00
|
|
|
#include "terrain_ecstypes.h"
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#define WIDTH 480
|
|
|
|
#define HEIGHT 300
|
|
|
|
#define SCREENSCALE 2
|
|
|
|
#define SWIDTH (WIDTH * SCREENSCALE)
|
|
|
|
#define SHEIGHT (HEIGHT * SCREENSCALE)
|
|
|
|
#define AVGWEIGHT 0.85
|
|
|
|
|
2024-09-09 03:04:57 +00:00
|
|
|
// These are initial values but there may be ways to change it
|
2024-09-08 22:42:50 +00:00
|
|
|
#define CAM_INITPITCH MPI_2
|
2024-09-09 03:04:57 +00:00
|
|
|
#define INIT_NEARCLIP 0.01
|
|
|
|
#define INIT_FARCLIP 100.0
|
|
|
|
#define INIT_DITHERSTART 10000
|
|
|
|
#define INIT_DITHEREND 10000
|
2024-09-08 22:42:50 +00:00
|
|
|
|
2024-09-09 03:04:57 +00:00
|
|
|
// Some globals you can mess around with potentially
|
|
|
|
int fps = 30;
|
|
|
|
|
|
|
|
// The terrain ecs systems
|
|
|
|
|
|
|
|
// All initialization for a specific render context
|
|
|
|
void sys_rendercontext(ecs_rendercontext *erc, ecs_placement *p) {
|
|
|
|
render_context *rc = *erc;
|
|
|
|
rc->precalc_halfwidth = rc->window.width * H3DVF(0.5);
|
|
|
|
rc->precalc_halfheight = rc->window.height * H3DVF(0.5);
|
|
|
|
haloo3d_perspective(rc->precalc_perspective, rc->fov,
|
|
|
|
(mfloat_t)rc->window.width / rc->window.height,
|
|
|
|
rc->nearclip, rc->farclip);
|
|
|
|
haloo3d_fb_cleardepth(&rc->window);
|
|
|
|
if (rc->windowclear & 0xF000) {
|
|
|
|
haloo3d_fb_clear(&rc->window, rc->windowclear);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Apply rotation to lookvec of placement
|
|
|
|
void sys_rotation(ecs_placement *p, ecs_rotation *r) {
|
|
|
|
YAWP2VEC(r->yaw, r->pitch, p->lookvec.v);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sys_movement(ecs_placement *p, ecs_movement *m) {
|
|
|
|
vec3_add(p->lookvec.v, p->lookvec.v, m->lookvec.v);
|
|
|
|
vec3_add(p->up.v, p->up.v, m->up.v);
|
|
|
|
vec3_add(p->pos.v, p->pos.v, m->pos.v);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Perform the entire rendering of an object
|
|
|
|
void sys_renderobject(ecs_placement *p, ecs_object *o) {
|
|
|
|
struct vec3 lighting;
|
|
|
|
struct vec4 precalc_verts[H3D_OBJ_MAXVERTICES];
|
|
|
|
// First, precalc all the vertices in the object
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
mfloat_t tmp[VEC4_SIZE];
|
|
|
|
mfloat_t modelm[MAT4_SIZE];
|
|
|
|
mfloat_t finalmatrix[MAT4_SIZE];
|
|
|
|
vec3_add(tmp, p->pos.v, p->lookvec.v);
|
|
|
|
haloo3d_my_lookat(modelm, p->pos.v, tmp, p->up.v);
|
|
|
|
// Apply scale such that it looks like it was applied first (this prevents
|
|
|
|
// scaling applying skew to a rotated object)
|
|
|
|
haloo3d_mat4_prescalev(modelm, o->scale.v);
|
|
|
|
mat4_multiply(finalmatrix, o->context->precalc_screen, modelm);
|
|
|
|
haloo3d_precalc_verts(o->model, finalmatrix, precalc_verts);
|
|
|
|
// Next, setup some rendering invariants
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
o->context->rendersettings.texture = o->texture;
|
|
|
|
if (o->lighting) {
|
|
|
|
if (o->lighting->autolightfix) {
|
|
|
|
// Lighting doesn't rotate with the model unless you do it yourself.
|
|
|
|
// In the easy system, you can request the renderer to do it for you
|
|
|
|
struct vec4 ltmp, lout;
|
|
|
|
// Lighting is centered at 0
|
|
|
|
vec4(ltmp.v, 0, 0, 0, 1);
|
|
|
|
// Calc the same lookat just without translation. THis should be the same
|
|
|
|
// rotation matrix used on the model
|
|
|
|
haloo3d_my_lookat(modelm, ltmp.v, p->lookvec.v, p->up.v);
|
|
|
|
// We actually want the inverse. Apparently to speed things up, the
|
|
|
|
// transpose works for rotation matrices(?) but I don't trust that this
|
|
|
|
// lookat does that
|
|
|
|
// mat4_inverse(modelm, modelm);
|
|
|
|
mat4_transpose(modelm, modelm);
|
|
|
|
// We HAVE to have a vec4 (oof)
|
|
|
|
vec4(ltmp.v, o->lighting->dir.x, o->lighting->dir.y, o->lighting->dir.z,
|
|
|
|
1);
|
|
|
|
haloo3d_vec4_multmat_into(<mp, modelm, &lout);
|
|
|
|
// No need to fix W, should all be good (no perspective divide). But we DO
|
|
|
|
// need to pull out that result
|
|
|
|
vec3(lighting.v, lout.x, lout.y, lout.z);
|
|
|
|
vec3_normalize(lighting.v, lighting.v);
|
|
|
|
} else {
|
|
|
|
vec3_assign(lighting.v, o->lighting->dir.v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Finally, actually render faces
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
int totaldrawn = 0;
|
|
|
|
haloo3d_facef face, baseface;
|
|
|
|
haloo3d_facef outfaces[H3D_FACEF_MAXCLIP];
|
|
|
|
for (int facei = 0; facei < o->model->numfaces; facei++) {
|
|
|
|
// Copy face values out of precalc array and clip them
|
|
|
|
haloo3d_make_facef(o->model->faces[facei], precalc_verts,
|
|
|
|
o->model->vtexture, face);
|
|
|
|
int tris = haloo3d_facef_clip(face, outfaces);
|
|
|
|
if (tris > 0) {
|
|
|
|
uint8_t oflags = o->context->rendersettings.flags;
|
|
|
|
if (o->lighting) {
|
|
|
|
haloo3d_obj_facef(o->model, o->model->faces[facei], baseface);
|
|
|
|
o->context->rendersettings.intensity =
|
|
|
|
haloo3d_calc_light(lighting.v, o->lighting->minlight, baseface);
|
|
|
|
} else {
|
|
|
|
o->context->rendersettings.intensity = H3DVF(1.0);
|
|
|
|
}
|
|
|
|
// if ((r->_objstate[object - r->objects] & H3D_EASYOBJSTATE_NOTRANS)) {
|
|
|
|
// r->rendersettings.flags &= ~H3DR_TRANSPARENCY;
|
|
|
|
// }
|
|
|
|
for (int ti = 0; ti < tris; ti++) {
|
|
|
|
int backface = !haloo3d_facef_finalize(outfaces[ti]);
|
|
|
|
if (o->cullbackface && backface) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
totaldrawn++;
|
|
|
|
// We still have to convert the points into the view
|
|
|
|
haloo3d_facef_viewport_into_fast(outfaces[ti],
|
|
|
|
o->context->precalc_halfwidth,
|
|
|
|
o->context->precalc_halfheight);
|
|
|
|
haloo3d_triangle(&o->context->window, &o->context->rendersettings,
|
|
|
|
outfaces[ti]);
|
|
|
|
}
|
|
|
|
o->context->rendersettings.flags = oflags;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// return totaldrawn;
|
|
|
|
}
|
2024-09-08 22:42:50 +00:00
|
|
|
|
|
|
|
int main() { // int argc, char **argv) {
|
|
|
|
srand(clock());
|
|
|
|
|
|
|
|
// Init unigi system. Can use anything here that can render to screen
|
|
|
|
unigi_type_event event;
|
|
|
|
unigi_type_resolution res;
|
|
|
|
res.width = SWIDTH;
|
|
|
|
res.height = SHEIGHT;
|
|
|
|
res.depth = 0;
|
|
|
|
|
|
|
|
unigi_graphics_init();
|
|
|
|
unigi_window_create(res, "terrain.exe"); // render.printbuf);
|
|
|
|
|
|
|
|
eprintf("Initialized unigi system\n");
|
|
|
|
|
|
|
|
haloo3d_easystore storage;
|
|
|
|
haloo3d_easystore_init(&storage);
|
|
|
|
haloo3d_fb *palettetex = haloo3d_easystore_addtex(&storage, "palette");
|
|
|
|
haloo3d_gen_palettetex(palettetex);
|
|
|
|
|
|
|
|
eprintf("Initialized storage and default textures/etc\n");
|
|
|
|
|
2024-09-09 03:04:57 +00:00
|
|
|
haloo3d_fb screen3d;
|
|
|
|
haloo3d_fb_init(&screen3d, WIDTH, HEIGHT);
|
2024-09-08 22:42:50 +00:00
|
|
|
haloo3d_fb screen;
|
|
|
|
haloo3d_fb_init(&screen, SWIDTH, SHEIGHT);
|
|
|
|
|
|
|
|
haloo3d_easytimer frametimer, drawtimer, sdltimer, filltimer, logictimer;
|
|
|
|
haloo3d_easytimer_init(&frametimer, AVGWEIGHT);
|
|
|
|
haloo3d_easytimer_init(&drawtimer, AVGWEIGHT);
|
|
|
|
haloo3d_easytimer_init(&sdltimer, AVGWEIGHT);
|
|
|
|
haloo3d_easytimer_init(&filltimer, AVGWEIGHT);
|
|
|
|
haloo3d_easytimer_init(&logictimer, AVGWEIGHT);
|
|
|
|
|
2024-09-09 03:04:57 +00:00
|
|
|
eprintf("Initialized screen buffers and timers\n");
|
|
|
|
|
|
|
|
tecs ecs;
|
|
|
|
tecs_init(&ecs);
|
|
|
|
|
|
|
|
// MAIN LOOP
|
|
|
|
while (1) {
|
|
|
|
haloo3d_easytimer_start(&frametimer);
|
|
|
|
|
|
|
|
do {
|
|
|
|
unigi_event_get(&event);
|
|
|
|
switch (event.type) {
|
|
|
|
case unigi_enum_event_input_keyboard:
|
|
|
|
if (event.data.input_keyboard.down) {
|
|
|
|
switch (event.data.input_keyboard.button) {
|
|
|
|
// case KEY_SPACE:
|
|
|
|
// haloo3d_debugconsole_beginprompt(&dc);
|
|
|
|
// break;
|
|
|
|
default:
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (event.type != unigi_enum_event_none);
|
|
|
|
|
|
|
|
// ECS logic (which includes rendering)
|
|
|
|
ECS_RUNSYSTEM2(&ecs, sys_rotation, ecs_placement, ecs_rotation);
|
|
|
|
ECS_RUNSYSTEM2(&ecs, sys_movement, ecs_placement, ecs_movement);
|
|
|
|
ECS_RUNSYSTEM2(&ecs, sys_rendercontext, ecs_rendercontext, ecs_placement);
|
|
|
|
ECS_RUNSYSTEM2(&ecs, sys_renderobject, ecs_placement, ecs_object);
|
|
|
|
|
|
|
|
// Scale 3D into final buffer
|
|
|
|
haloo3d_easytimer_start(&filltimer);
|
|
|
|
haloo3d_fb_fill(&screen, &screen3d);
|
|
|
|
haloo3d_easytimer_end(&filltimer);
|
|
|
|
|
|
|
|
/*
|
|
|
|
haloo3d_print(&render.tprint,
|
|
|
|
"Pframe: %05.2f (%05.2f)\nPSDLFl: %05.2f "
|
|
|
|
"(%05.2f)\nFill: %05.2f "
|
|
|
|
"(%05.2f)\nLogic: %05.2f (%05.2f)\nTris: %d / %d\nVerts: "
|
|
|
|
"%d\nWState: %d",
|
|
|
|
frametimer.last * 1000, frametimer.sum * 1000,
|
|
|
|
sdltimer.last * 1000, sdltimer.sum * 1000,
|
|
|
|
filltimer.last * 1000, filltimer.sum * 1000,
|
|
|
|
logictimer.last * 1000, logictimer.sum * 1000, totaldrawn,
|
|
|
|
render.totalfaces, render.totalverts, wstate.state);
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Finally, actually put buffer onto screen
|
|
|
|
haloo3d_easytimer_start(&sdltimer);
|
|
|
|
unigi_graphics_blit(0, (unigi_type_color *)screen.buffer,
|
|
|
|
res.width * res.height);
|
|
|
|
unigi_graphics_flush();
|
|
|
|
haloo3d_easytimer_end(&sdltimer);
|
|
|
|
|
|
|
|
haloo3d_easytimer_end(&frametimer);
|
|
|
|
|
|
|
|
// Wait for next frame based on fps
|
|
|
|
float waittime = (1.0 / fps) - frametimer.last;
|
|
|
|
if (waittime > 0) {
|
|
|
|
unigi_time_sleep(waittime * unigi_time_clocks_per_s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
haloo3d_fb_free(&screen);
|
|
|
|
haloo3d_fb_free(&screen3d);
|
2024-09-08 22:42:50 +00:00
|
|
|
haloo3d_easystore_deleteallobj(&storage, haloo3d_obj_free);
|
|
|
|
haloo3d_easystore_deletealltex(&storage, haloo3d_fb_free);
|
|
|
|
}
|