adding gfx and ui stuff

This commit is contained in:
Daniel Ledda
2026-06-04 18:22:30 +02:00
parent d676c50961
commit 4dfac3f82f
48 changed files with 26734 additions and 3 deletions

26
gfx/world/camera.c Normal file
View File

@@ -0,0 +1,26 @@
#include "camera.h"
#include "../../vendor/raymath.h"
Camera createCamera(int32 width, int32 height) {
return (Camera){
.view = (Matrix){0},
.proj = MatrixPerspective(DEG2RAD * 45.0f, (real32)width/(real32)height, 0.1f, 100.0f),
.pos = (Vec3){0},
.up = (Vec3){0,1,0},
};
}
void cameraSetAspect(Camera *c, int32 width, int32 height) {
real32 aspectRatio = (real32)width/(real32)height;
c->proj = MatrixPerspective(DEG2RAD * 45.0f, aspectRatio, 0.1f, 100.0f);
}
void cameraLookAt(Camera *c, float x, float y, float z) {
c->target = (Vec3){x, y, z};
c->view = MatrixLookAt(c->pos, c->target, c->up);
}
void cameraSetUp(Camera *c, real32 up_x, real32 up_y, real32 up_z) {
c->up = (Vec3){up_x, up_y, up_z};
}

21
gfx/world/camera.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef DJSTDLIB_GFX_CAMERA_H
#define DJSTDLIB_GFX_CAMERA_H
#include "../../core.h"
#include "../../vendor/raymath.h"
typedef struct Camera Camera;
struct Camera {
Matrix view;
Matrix proj;
Vec3 pos;
Vec3 up;
Vec3 target;
};
Camera createCamera(int32 width, int32 height);
void cameraSetAspect(Camera *c, int32 width, int32 height);
void cameraLookAt(Camera *c, float x, float y, float z);
void cameraSetUp(Camera *c, real32 up_x, real32 up_y, real32 up_z);
#endif

196
gfx/world/scene.c Normal file
View File

@@ -0,0 +1,196 @@
#include "../../core.h"
#include "scene.h"
Entity *getEntity(Scene *s, int32 entityHandle) {
return &s->entities.data[entityHandle];
}
SceneGraphNode *getSceneGraphNode(Scene *s, int32 sceneGraphNodeHandle) {
return &s->graphNodes.data[sceneGraphNodeHandle];
}
SceneGraphNode *getSceneGraphNodeForEntity(Scene *s, int32 entityHandle) {
return getSceneGraphNode(s, getEntity(s, entityHandle)->graphNodeHandle);
}
int32 createSceneGraphNode(Scene *s) {
SceneGraphNode *newNode;
int32 newNodeHandle;
if (s->nextFreeNode) {
newNodeHandle = s->nextFreeNode;
newNode = getSceneGraphNode(s, newNodeHandle);
if (newNode->next) {
s->nextFreeNode = newNode->next;
} else {
s->nextFreeNode = 0;
}
newNode->next = 0;
} else {
ListAppend(s->graphNodes, (SceneGraphNode){0});
newNodeHandle = (int32)s->graphNodes.length - 1;
newNode = getSceneGraphNode(s, newNodeHandle);
newNode->nextSibling = 0;
}
initGraphNode(newNode);
return newNodeHandle;
}
int32 createEntity(Scene *s) {
Entity *newEntity;
int32 newEntityHandle;
if (s->nextFreeEntity) {
newEntityHandle = s->nextFreeEntity;
newEntity = getEntity(s, newEntityHandle);
if (newEntity->next) {
s->nextFreeEntity = newEntity->next;
} else {
s->nextFreeEntity = 0;
}
newEntity->next = 0;
} else {
ListAppend(s->entities, (Entity){0});
newEntityHandle = (int32)s->entities.length - 1;
newEntity = getEntity(s, newEntityHandle);
}
newEntity->graphNodeHandle = createSceneGraphNode(s);
getSceneGraphNodeForEntity(s, newEntityHandle)->entityHandle = newEntityHandle;
return newEntityHandle;
}
void initGraphNode(SceneGraphNode *n) {
n->scale = (Vec3){1.0f, 1.0f, 1.0f};
n->translation = (Vec3){0.0f, 0.0f, 0.0f};
n->rotation = (Quaternion){1.0f, 0.0f, 0.0f, 0.0f};
n->local = MatrixIdentity();
n->world = n->local;
}
Scene createScene(Arena *arena) {
Scene result = {
.entities = PushListZero(arena, EntityList, 100000),
.nextFreeEntity = 0,
.graphNodes = PushListZero(arena, SceneGraphNodeList, 100000),
.nextFreeNode = 0,
};
int32 handle = createEntity(&result); // Intialise the "zero" nodes
getEntity(&result, handle)->flags = EntityFlags_None | EntityFlags_Dead;
result.sceneRoot = createSceneGraphNode(&result);
return result;
}
void recalcSceneGraphNode(Scene *s, int32 parentHandle) {
if (!parentHandle) return;
SceneGraphNode *parentNode = getSceneGraphNode(s, parentHandle);
getEntity(s, parentNode->entityHandle)->flags |= EntityFlags_Render;
int32 nextChild = parentNode->firstChild;
while (nextChild) {
SceneGraphNode *childNode = getSceneGraphNode(s, nextChild);
childNode->parentHandle = parentHandle;
childNode->local = MatrixCompose(childNode->translation, childNode->rotation, childNode->scale);
childNode->world = MatrixMultiply(childNode->local, parentNode->world);
recalcSceneGraphNode(s, nextChild);
nextChild = childNode->nextSibling;
}
}
void recalcScene(Scene *s) {
recalcSceneGraphNode(s, s->sceneRoot);
}
static void removeSceneGraphNodeRecursive(Scene *s, int32 deletedNodeHandle, bool deletingParent) {
if (!deletedNodeHandle) return;
SceneGraphNode *deletedNode = getSceneGraphNode(s, deletedNodeHandle);
int32 nextChild = deletedNode->firstChild;
while (nextChild) {
int32 sibling = getSceneGraphNode(s, nextChild)->nextSibling;
removeSceneGraphNodeRecursive(s, nextChild, true);
nextChild = sibling;
}
if (deletedNode->entityHandle) {
Entity *entity = getEntity(s, deletedNode->entityHandle);
*entity = (Entity){0};
if (s->nextFreeEntity) {
entity->next = s->nextFreeEntity;
}
s->nextFreeEntity = deletedNode->entityHandle;
}
if (s->nextFreeNode) {
deletedNode->next = s->nextFreeNode;
}
s->nextFreeNode = deletedNodeHandle;
if (!deletingParent && deletedNode->parentHandle) {
SceneGraphNode *parentNode = getSceneGraphNode(s, deletedNode->parentHandle);
if (parentNode->firstChild == deletedNodeHandle) {
if (deletedNode->nextSibling) {
parentNode->firstChild = deletedNode->nextSibling;
} else {
parentNode->firstChild = 0;
}
} else {
int32 prevSibling = parentNode->firstChild;
int32 nextSibling = getSceneGraphNode(s, parentNode->firstChild)->nextSibling;
while (nextSibling) {
SceneGraphNode *siblingNode = getSceneGraphNode(s, nextSibling);
if (nextSibling == deletedNodeHandle) {
SceneGraphNode *prevSiblingNode = getSceneGraphNode(s, prevSibling);
prevSiblingNode->nextSibling = deletedNode->nextSibling;
break;
}
prevSibling = nextSibling;
nextSibling = siblingNode->nextSibling;
}
}
}
deletedNode->firstChild = 0;
deletedNode->parentHandle = 0;
deletedNode->entityHandle = 0;
deletedNode->nextSibling = 0;
}
void removeSceneGraphNode(Scene *s, int32 graphNodeHandle) {
removeSceneGraphNodeRecursive(s, graphNodeHandle, false);
}
void removeEntity(Scene *s, int32 entityHandle) {
if (!entityHandle) return;
removeSceneGraphNode(s, getEntity(s, entityHandle)->graphNodeHandle);
}
void sceneNodeAddNode(Scene *s, int32 parentHandle, int32 childHandle) {
SceneGraphNode *parentNode = getSceneGraphNode(s, parentHandle);
SceneGraphNode *childNode = getSceneGraphNode(s, childHandle);
childNode->nextSibling = parentNode->firstChild;
parentNode->firstChild = childHandle;
childNode->parentHandle = parentHandle;
}
void show(Scene *s, uint32 graphNodeHandle) {
SceneGraphNode *node = getSceneGraphNode(s, graphNodeHandle);
if (node->entityHandle) {
getEntity(s, node->entityHandle)->flags |= EntityFlags_Visible;
}
int32 next = node->firstChild;
while (next) {
show(s, next);
next = getSceneGraphNode(s, next)->nextSibling;
}
}
void hide(Scene *s, uint32 graphNodeHandle) {
SceneGraphNode *node = getSceneGraphNode(s, graphNodeHandle);
if (node->entityHandle) {
getEntity(s, node->entityHandle)->flags &= ~EntityFlags_Visible;
}
int32 next = node->firstChild;
while (next) {
hide(s, next);
next = getSceneGraphNode(s, next)->nextSibling;
}
}

75
gfx/world/scene.h Normal file
View File

@@ -0,0 +1,75 @@
#ifndef DJSTDLIB_GFX_SCENE_H
#define DJSTDLIB_GFX_SCENE_H
#include "../../core.h"
#include "../../vendor/raymath.h"
#include "../Mesh.h"
#include "../Texture.h"
DefineList(int32, Handle);
enum EntityFlags {
EntityFlags_None=0,
EntityFlags_Visible=1<<0,
EntityFlags_Dead=1<<1,
EntityFlags_Render=1<<2,
};
typedef struct Entity Entity;
struct Entity {
int32 graphNodeHandle;
uint64 flags;
Vec4 color;
Mesh *mesh;
Texture *tex;
// Free list
int32 next;
};
DefineList(Entity, Entity);
typedef struct SceneGraphNode SceneGraphNode;
struct SceneGraphNode {
Matrix local;
Matrix world;
Vec3 translation;
Quaternion rotation;
Vec3 scale;
int32 entityHandle;
int32 parentHandle;
/** Next free in the free list */
int32 next;
/** Next child in child list in scene hierarchy */
int32 nextSibling;
int32 firstChild;
};
DefineList(SceneGraphNode, SceneGraphNode);
typedef struct Scene Scene;
struct Scene {
int32 sceneRoot;
EntityList entities;
int32 nextFreeEntity;
/** @internal */
SceneGraphNodeList graphNodes;
int32 nextFreeNode;
};
int32 createEntity(Scene *s);
Entity *getEntity(Scene *s, int32 id);
SceneGraphNode *getSceneGraphNode(Scene *s, int32 id);
int32 createSceneGraphNode(Scene *s);
Scene createScene(Arena *arena);
void initGraphNode(SceneGraphNode *n);
void recalcSceneGraphNode(Scene *s, int32 parentHandle);
void recalcScene(Scene *s);
void removeEntity(Scene *s, int32 entityHandle);
void removeSceneGraphNode(Scene *s, int32 graphNodeHandle);
void sceneNodeAddNode(Scene *s, int32 recipientNodeHandle, int32 graphNodeHandle);
SceneGraphNode *getSceneGraphNodeForEntity(Scene *s, int32 entityHandle);
void show(Scene *s, uint32 graphNodeHandle);
void hide(Scene *s, uint32 graphNodeHandle);
#endif

2
gfx/world/world.c Normal file
View File

@@ -0,0 +1,2 @@
#include "scene.c"
#include "camera.c"

8
gfx/world/world.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef DJSTDLIB_GFX_WORLD_H
#define DJSTDLIB_GFX_WORLD_H
#include "scene.h"
#include "camera.h"
#endif