Terrain ecs is taking a lot

This commit is contained in:
Carlos Sanchez 2024-09-14 01:00:20 -04:00
parent dd68a9115e
commit a17ef2d379
4 changed files with 191 additions and 95 deletions

3
ecs2.h
View File

@ -90,7 +90,8 @@ typedef int ecs_eid;
// Define the CIDs necessary to access a component (each component MUST // Define the CIDs necessary to access a component (each component MUST
// have a unique id and I can't do that inside a macro without requiring // have a unique id and I can't do that inside a macro without requiring
// extensions) // extensions). Note: can't use enum, because we need the flag value too.
// (unless you have a compiler that supports iterating over macro varargs)
#define ECS_CID(type, id) \ #define ECS_CID(type, id) \
const int type##_id = id; \ const int type##_id = id; \
const ecs_cid type##_fl = (1ULL << id); const ecs_cid type##_fl = (1ULL << id);

15
junk.txt Normal file
View File

@ -0,0 +1,15 @@
// haloo3d_print(&pt, "Thi sis a gaint string. I am disylax, I acn'at type, really \n"
// "And this string will just keep going because i need it to take up tons of\n"
// "your time today. fuck you, eat a cock, thank you. just kidding, i love you\n"
// "please have a nice day, but eat a cock if you like that kind of thing. \n"
// "slurp slurp yummy yummy give me treats. i like fat bellies");
// haloo3d_print(&pt, "Thi sis a gaint string. I am disylax, I acn'at type, really \n"
// "And this string will just keep going because i need it to take up tons of\n"
// "your time today. fuck you, eat a cock, thank you. just kidding, i love you\n"
// "please have a nice day, but eat a cock if you like that kind of thing. \n"
// "slurp slurp yummy yummy give me treats. i like fat bellies");
// haloo3d_print(&pt, "Thi sis a gaint string. I am disylax, I acn'at type, really \n"
// "And this string will just keep going because i need it to take up tons of\n"
// "your time today. fuck you, eat a cock, thank you. just kidding, i love you\n"
// "please have a nice day, but eat a cock if you like that kind of thing. \n"
// "slurp slurp yummy yummy give me treats. i like fat bellies");

115
terrain.c
View File

@ -22,6 +22,11 @@
#define AVGWEIGHT 0.85 #define AVGWEIGHT 0.85
#define DEFAULTUP \ #define DEFAULTUP \
{ .x = 0, .y = 1, .z = 0 } { .x = 0, .y = 1, .z = 0 }
// Lookvec for objects which all face forward along with the player
#define DEFAULTLOOK \
{ .x = 0, .y = 0, .z = -1 }
#define CHUNKSCALE \
{ .x = 1.0, .y = 1.0, .z = 1.0 }
// These are initial values but there may be ways to change it // These are initial values but there may be ways to change it
#define CAM_INITPITCH MPI_2 #define CAM_INITPITCH MPI_2
@ -30,6 +35,9 @@
#define INIT_FOV 90.0 #define INIT_FOV 90.0
#define INIT_DITHERSTART 10000 #define INIT_DITHERSTART 10000
#define INIT_DITHEREND 10000 #define INIT_DITHEREND 10000
#define INIT_LIGHTPITCH -MPI / 4.0
#define INIT_LIGHTYAW 0
#define INIT_MINLIGHT 0.2
#define INIT_PLAYERSPEED \ #define INIT_PLAYERSPEED \
{ .x = 0, .y = 0, .z = -0.5 } { .x = 0, .y = 0, .z = -0.5 }
@ -37,6 +45,8 @@
// Some globals you can mess around with potentially // Some globals you can mess around with potentially
int fps = 30; int fps = 30;
#define PALETTEKEY "palette"
// --------------------------------------------------- // ---------------------------------------------------
// The terrain ecs systems // The terrain ecs systems
// --------------------------------------------------- // ---------------------------------------------------
@ -91,14 +101,17 @@ void sys_renderobject(ecs_placement *p, ecs_object *o, tecs **ecs) {
// Apply scale such that it looks like it was applied first (this prevents // Apply scale such that it looks like it was applied first (this prevents
// scaling applying skew to a rotated object) // scaling applying skew to a rotated object)
haloo3d_mat4_prescalev(modelm, o->scale.v); haloo3d_mat4_prescalev(modelm, o->scale.v);
mat4_multiply(finalmatrix, o->context->precalc_screen, modelm); // We might be rendering into multiple contexts in a multiplayer game (or
// just different angles or something)
for (int ctx = 0; ctx < o->contextcount; ctx++) {
mat4_multiply(finalmatrix, o->context[ctx]->precalc_screen, modelm);
haloo3d_precalc_verts(o->model, finalmatrix, precalc_verts); haloo3d_precalc_verts(o->model, finalmatrix, precalc_verts);
// --**-- Next, setup some rendering invariants --**-- // --**-- Next, setup some rendering invariants --**--
struct vec3 lighting; struct vec3 lighting;
// The compiler is complaining about lighting being used unitialized, even // The compiler is complaining about lighting being used unitialized, even
// though it's not. Just shut it up // though it's not. Just shut it up
vec3(lighting.v, 0, 0, 0); vec3(lighting.v, 0, 0, 0);
o->context->rendersettings.texture = o->texture; o->context[ctx]->rendersettings.texture = o->texture;
if (o->lighting) { if (o->lighting) {
if (o->lighting->autolightfix) { if (o->lighting->autolightfix) {
// Lighting doesn't rotate with the model unless you do it yourself. // Lighting doesn't rotate with the model unless you do it yourself.
@ -106,8 +119,8 @@ void sys_renderobject(ecs_placement *p, ecs_object *o, tecs **ecs) {
struct vec4 ltmp, lout; struct vec4 ltmp, lout;
// Lighting is centered at 0 // Lighting is centered at 0
vec4(ltmp.v, 0, 0, 0, 1); vec4(ltmp.v, 0, 0, 0, 1);
// Calc the same lookat just without translation. THis should be the same // Calc the same lookat just without translation. THis should be the
// rotation matrix used on the model // same rotation matrix used on the model
haloo3d_my_lookat(modelm, ltmp.v, p->lookvec.v, p->up.v); haloo3d_my_lookat(modelm, ltmp.v, p->lookvec.v, p->up.v);
// We actually want the inverse. Apparently to speed things up, the // We actually want the inverse. Apparently to speed things up, the
// transpose works for rotation matrices(?) but I don't trust that this // transpose works for rotation matrices(?) but I don't trust that this
@ -118,8 +131,8 @@ void sys_renderobject(ecs_placement *p, ecs_object *o, tecs **ecs) {
vec4(ltmp.v, o->lighting->dir.x, o->lighting->dir.y, o->lighting->dir.z, vec4(ltmp.v, o->lighting->dir.x, o->lighting->dir.y, o->lighting->dir.z,
1); 1);
haloo3d_vec4_multmat_into(&ltmp, modelm, &lout); haloo3d_vec4_multmat_into(&ltmp, modelm, &lout);
// No need to fix W, should all be good (no perspective divide). But we DO // No need to fix W, should all be good (no perspective divide). But we
// need to pull out that result // DO need to pull out that result
vec3(lighting.v, lout.x, lout.y, lout.z); vec3(lighting.v, lout.x, lout.y, lout.z);
vec3_normalize(lighting.v, lighting.v); vec3_normalize(lighting.v, lighting.v);
} else { } else {
@ -135,13 +148,13 @@ void sys_renderobject(ecs_placement *p, ecs_object *o, tecs **ecs) {
o->model->vtexture, face); o->model->vtexture, face);
int tris = haloo3d_facef_clip(face, outfaces); int tris = haloo3d_facef_clip(face, outfaces);
if (tris > 0) { if (tris > 0) {
uint8_t oflags = o->context->rendersettings.flags; uint8_t oflags = o->context[ctx]->rendersettings.flags;
if (o->lighting) { if (o->lighting) {
haloo3d_obj_facef(o->model, o->model->faces[facei], baseface); haloo3d_obj_facef(o->model, o->model->faces[facei], baseface);
o->context->rendersettings.intensity = o->context[ctx]->rendersettings.intensity =
haloo3d_calc_light(lighting.v, o->lighting->minlight, baseface); haloo3d_calc_light(lighting.v, o->lighting->minlight, baseface);
} else { } else {
o->context->rendersettings.intensity = H3DVF(1.0); o->context[ctx]->rendersettings.intensity = H3DVF(1.0);
} }
// if ((r->_objstate[object - r->objects] & H3D_EASYOBJSTATE_NOTRANS)) { // if ((r->_objstate[object - r->objects] & H3D_EASYOBJSTATE_NOTRANS)) {
// r->rendersettings.flags &= ~H3DR_TRANSPARENCY; // r->rendersettings.flags &= ~H3DR_TRANSPARENCY;
@ -154,12 +167,13 @@ void sys_renderobject(ecs_placement *p, ecs_object *o, tecs **ecs) {
(*ecs)->totaldrawn++; (*ecs)->totaldrawn++;
// We still have to convert the points into the view // We still have to convert the points into the view
haloo3d_facef_viewport_into_fast(outfaces[ti], haloo3d_facef_viewport_into_fast(outfaces[ti],
o->context->precalc_halfwidth, o->context[ctx]->precalc_halfwidth,
o->context->precalc_halfheight); o->context[ctx]->precalc_halfheight);
haloo3d_triangle(&o->context->window, &o->context->rendersettings, haloo3d_triangle(&o->context[ctx]->window,
outfaces[ti]); &o->context[ctx]->rendersettings, outfaces[ti]);
}
o->context[ctx]->rendersettings.flags = oflags;
} }
o->context->rendersettings.flags = oflags;
} }
} }
} }
@ -186,6 +200,51 @@ void sys_playerinput(ecs_input *in) {
} while (event.type != unigi_enum_event_none); } while (event.type != unigi_enum_event_none);
} }
void sys_playergarbage(ecs_playergarbage *pg, ecs_object *ob, tecs **ecs) {
ecs_eid id = tecs_eid(ecs);
if (ob->contextcount <= 0) {
eprintf("Deleting object %d\n", id);
if (pg->dynmodel[0]) {
haloo3d_easystore_deleteobj(&(*ecs)->storage, pg->dynmodel,
haloo3d_obj_free);
}
tecs_deleteentity(*ecs, id);
}
}
void gen_chunk(render_context *ctx, tecs *ecs, struct vec2i pos) {
eprintf("Generating chunk %d,%d\n", pos.x, pos.y);
// TODO: don't make the system generate components? Let someone else set
// ourselves up, then we just generate the model or... whatever... or is
// that bad? Maybe that's bad, since we'll suddenly be renderable without a
// model, ugh.
// haloo3d_gen_paletteuv(haloo3d_fb *fb, uint16_t col, struct vec2 *uvout);
ecs_eid id = tecs_newentity(ecs, 0);
ecs_playergarbage garbage;
sprintf(garbage.dynmodel, "e%d", id);
haloo3d_obj *model =
haloo3d_easystore_addobj(&ecs->storage, garbage.dynmodel);
ECS_SETCOMPONENT(ecs, id, ecs_playergarbage) garbage;
ECS_SETCOMPONENT(ecs, id,
ecs_placement){.up = DEFAULTUP,
.lookvec = DEFAULTLOOK,
.pos = {.x = pos.x, .y = 0, .z = pos.y}};
// TODO: an easy place for optimization (if it's even needed)
ECS_SETCOMPONENT(ecs, id, ecs_object){
.texture = haloo3d_easystore_gettex(&ecs->storage, PALETTEKEY),
.scale = CHUNKSCALE,
.lighting = &ecs->chunklight,
.model = model,
.cullbackface = 1,
.context = {ctx},
.contextcount = 1};
}
// void sys_chunk(ecs_chunk *ch, ecs_object *o, tecs **ecs) {
// // Is it really ok to have this check every single time? Seems kinda
// wasteful if (ch->generation == 1) {
// }
// }
// --------------------------------------------------- // ---------------------------------------------------
// MAIN FUNCTION // MAIN FUNCTION
// --------------------------------------------------- // ---------------------------------------------------
@ -204,19 +263,13 @@ int main() { // int argc, char **argv) {
eprintf("Initialized unigi system\n"); 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");
haloo3d_fb screen; haloo3d_fb screen;
haloo3d_fb_init(&screen, SWIDTH, SHEIGHT); haloo3d_fb_init(&screen, SWIDTH, SHEIGHT);
haloo3d_print_tracker pt; haloo3d_print_tracker pt;
char printbuf[8192]; char printbuf[8192];
haloo3d_print_initdefault(&pt, printbuf, sizeof(printbuf)); haloo3d_print_initdefault(&pt, printbuf, sizeof(printbuf));
pt.fb = &screen; pt.fb = &screen;
pt.scale = 1;
haloo3d_easytimer frametimer, drawtimer, sdltimer; haloo3d_easytimer frametimer, drawtimer, sdltimer;
haloo3d_easytimer_init(&frametimer, AVGWEIGHT); haloo3d_easytimer_init(&frametimer, AVGWEIGHT);
@ -236,6 +289,17 @@ int main() { // int argc, char **argv) {
ecs.delta_s = 0; ecs.delta_s = 0;
tecs_init(&ecs); tecs_init(&ecs);
int tecs_size = sizeof(tecs); int tecs_size = sizeof(tecs);
YAWP2VEC(INIT_LIGHTYAW, INIT_LIGHTPITCH, ecs.globallighting.v);
// An issue? Not a pointer? Eeehhh....
ecs.chunklight.dir = ecs.globallighting;
ecs.chunklight.minlight = INIT_MINLIGHT;
ecs.chunklight.autolightfix = 0;
haloo3d_easystore_init(&ecs.storage);
haloo3d_fb *palettetex = haloo3d_easystore_addtex(&ecs.storage, PALETTEKEY);
haloo3d_gen_palettetex(palettetex);
eprintf("Setup ECS system + obj/tex storage (%d bytes)\n", tecs_size);
ecs_eid playerid = tecs_newentity(&ecs, 0); ecs_eid playerid = tecs_newentity(&ecs, 0);
ECS_SETCOMPONENT(&ecs, playerid, ecs_placement){ ECS_SETCOMPONENT(&ecs, playerid, ecs_placement){
@ -247,7 +311,7 @@ int main() { // int argc, char **argv) {
ECS_SETCOMPONENT(&ecs, playerid, ecs_input){}; ECS_SETCOMPONENT(&ecs, playerid, ecs_input){};
ecs_placement *playerpos = &ECS_GETCOMPONENT(&ecs, playerid, ecs_placement); ecs_placement *playerpos = &ECS_GETCOMPONENT(&ecs, playerid, ecs_placement);
eprintf("Setup ECS system (%d bytes)\n", tecs_size); eprintf("Setup player\n");
// MAIN LOOP // MAIN LOOP
while (1) { while (1) {
@ -261,6 +325,9 @@ int main() { // int argc, char **argv) {
ECS_RUNSYSTEM2(&ecs, sys_rotation, ecs_placement, ecs_rotation); ECS_RUNSYSTEM2(&ecs, sys_rotation, ecs_placement, ecs_rotation);
ECS_RUNSYSTEM3(&ecs, sys_movement, ecs_placement, ecs_movement, tecs); ECS_RUNSYSTEM3(&ecs, sys_movement, ecs_placement, ecs_movement, tecs);
ECS_RUNSYSTEM2(&ecs, sys_rendercontext, ecs_rendercontext, ecs_placement); ECS_RUNSYSTEM2(&ecs, sys_rendercontext, ecs_rendercontext, ecs_placement);
// ECS_RUNSYSTEM3(&ecs, sys_chunk, ecs_chunk, ecs_object, tecs);
ECS_RUNSYSTEM3(&ecs, sys_playergarbage, ecs_playergarbage, ecs_object,
tecs);
haloo3d_easytimer_start(&drawtimer); haloo3d_easytimer_start(&drawtimer);
ECS_RUNSYSTEM3(&ecs, sys_renderobject, ecs_placement, ecs_object, tecs); ECS_RUNSYSTEM3(&ecs, sys_renderobject, ecs_placement, ecs_object, tecs);
haloo3d_easytimer_end(&drawtimer); haloo3d_easytimer_end(&drawtimer);
@ -302,6 +369,6 @@ int main() { // int argc, char **argv) {
haloo3d_fb_free(&screen); haloo3d_fb_free(&screen);
haloo3d_fb_free(&context.window); haloo3d_fb_free(&context.window);
haloo3d_easystore_deleteallobj(&storage, haloo3d_obj_free); haloo3d_easystore_deleteallobj(&ecs.storage, haloo3d_obj_free);
haloo3d_easystore_deletealltex(&storage, haloo3d_fb_free); haloo3d_easystore_deletealltex(&ecs.storage, haloo3d_fb_free);
} }

View File

@ -3,16 +3,14 @@
#include "ecs2.h" #include "ecs2.h"
#include "haloo3d/haloo3d.h" #include "haloo3d/haloo3d.h"
// #include "haloo3d/haloo3dex_easy.h" #include "haloo3d/haloo3dex_easy.h"
#define TERRAIN_MAXPLAYERS 4
// Baseline render context. When a pointer to this is attached as a component, // Baseline render context. When a pointer to this is attached as a component,
// it becomes a render target, and that entity will perform the precalcs // it becomes a render target, and that entity will perform the precalcs
// necessary for later object rendering. // necessary for later object rendering.
typedef struct { typedef struct {
// struct vec4 precalcs[H3D_OBJ_MAXVERTICES];
// haloo3d_facef outfaces[H3D_FACEF_MAXCLIP];
// haloo3d_perspective(render.perspective, fov, ASPECT, NEARCLIP, FARCLIP);
// mfloat_t precalc_perspective[MAT4_SIZE];
mfloat_t precalc_screen[MAT4_SIZE]; mfloat_t precalc_screen[MAT4_SIZE];
mfloat_t precalc_halfwidth; // Optimization for reducing calcs per tri mfloat_t precalc_halfwidth; // Optimization for reducing calcs per tri
mfloat_t precalc_halfheight; // Optimization for reducing calcs per tri mfloat_t precalc_halfheight; // Optimization for reducing calcs per tri
@ -46,12 +44,13 @@ typedef struct {
// All values which allow rendering of a 3d object // All values which allow rendering of a 3d object
typedef struct { typedef struct {
// haloo3d_trirender rendersettings; // baseline settings for THIS object. // haloo3d_trirender rendersettings; // baseline settings for THIS object.
render_context *context[TERRAIN_MAXPLAYERS]; // What to render into
struct vec3 scale; // how big the thing should be in world struct vec3 scale; // how big the thing should be in world
object_lighting *lighting; // a pointer to lighting, null for none object_lighting *lighting; // a pointer to lighting, null for none
render_context *context; // What to render into
haloo3d_obj *model; haloo3d_obj *model;
haloo3d_fb *texture; haloo3d_fb *texture;
uint8_t cullbackface; // Whether to cull backfaces (you probably should) uint8_t cullbackface; // Whether to cull backfaces (you probably should)
uint8_t contextcount; // How many contexts we render into
} ecs_object; } ecs_object;
// Some placement within the world. Doesn't imply anything other than a // Some placement within the world. Doesn't imply anything other than a
@ -81,8 +80,21 @@ typedef struct {
int numevents; int numevents;
} ecs_input; } ecs_input;
// typedef haloo3d_camera *ecs_camera; // Simple component for some entity that should clean itself up
// typedef haloo3d_obj_instance *ecs_object; // when there are no more "references" to it. Whatever that means...
// some fields are for special cleanup
typedef struct {
char dynmodel[8]; // A model we may have to cleanup
} ecs_playergarbage;
// Represents the singular object that is the entire stationary
// object of terrain. The position is the "chunk position", which
// should be integer aligned. Not necessarily 1:1 with world
// coordinates?
typedef struct {
struct vec2i pos;
// uint8_t generation; // The type(?) of generation (idk honestly)
} ecs_chunk;
// // A billboard for OUR system, which does not look up or down at the target. // // A billboard for OUR system, which does not look up or down at the target.
// As // As
@ -94,29 +106,28 @@ typedef struct {
// struct vec3 *lookat; // struct vec3 *lookat;
// } ecs_billboard; // } ecs_billboard;
// // A component which allows an object instance to die
// // when the maze is initiailized.
// typedef struct {
// haloo3d_obj_instance *obj;
// haloo3d_easyrender *render;
// worldstate *ws;
// void (*diefunc)(haloo3d_obj_instance *);
// } ecs_dieoninit;
// Setup ECS system for our game // Setup ECS system for our game
ECS_START(tecs) ECS_START(tecs)
float delta_s; // Store delta time in ecs float delta_s; // Store delta time in ecs
int totaldrawn; // A place to store total drawn tris int totaldrawn; // A place to store total drawn tris
struct vec3 globallighting; // the global lighting to apply to terrain
object_lighting chunklight; // lighting to assign to a chunk
// Everyone needs to be able to get and set obj/texture
haloo3d_easystore storage;
ECS_COMPONENT(ecs_rendercontext); ECS_COMPONENT(ecs_rendercontext);
ECS_COMPONENT(ecs_object); ECS_COMPONENT(ecs_object);
ECS_COMPONENT(ecs_placement); ECS_COMPONENT(ecs_placement);
ECS_COMPONENT(ecs_rotation); ECS_COMPONENT(ecs_rotation);
ECS_COMPONENT(ecs_movement); ECS_COMPONENT(ecs_movement);
ECS_COMPONENT(ecs_input); ECS_COMPONENT(ecs_input);
ECS_COMPONENT(ecs_playergarbage);
ECS_COMPONENT(ecs_chunk);
ECS_END(tecs) ECS_END(tecs)
ECS_FN_INIT(tecs) ECS_FN_INIT(tecs)
ECS_FN_NEWENTITY(tecs) ECS_FN_NEWENTITY(tecs)
ECS_FN_DELETEENTITY(tecs)
ECS_FN_EID(tecs)
// And then a copy of the components here... that sucksssss // And then a copy of the components here... that sucksssss
ECS_CID(ecs_rendercontext, 0); ECS_CID(ecs_rendercontext, 0);
@ -125,5 +136,7 @@ ECS_CID(ecs_placement, 2);
ECS_CID(ecs_rotation, 3); ECS_CID(ecs_rotation, 3);
ECS_CID(ecs_movement, 4); ECS_CID(ecs_movement, 4);
ECS_CID(ecs_input, 5); ECS_CID(ecs_input, 5);
ECS_CID(ecs_playergarbage, 6);
ECS_CID(ecs_chunk, 7);
#endif #endif