Scene rendering native.

This commit is contained in:
2026-05-20 23:45:27 -05:00
parent 510a94b42c
commit a9e6f2b2a5
7 changed files with 153 additions and 141 deletions
+3 -1
View File
@@ -26,6 +26,8 @@
#include "item/backpack.h"
#include "save/save.h"
#include "scene/initial/initialscene.h"
engine_t ENGINE;
errorret_t engineInit(const int32_t argc, const char_t **argv) {
@@ -55,7 +57,7 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
/* Run the init script. */
consolePrint("Engine initialized");
// errorChain(scriptManagerExecFile("init.js", NULL));
sceneSet(SCENE_TYPE_INITIAL);
errorOk();
}
+18 -1
View File
@@ -5,4 +5,21 @@
* https://opensource.org/licenses/MIT
*/
#include "initialscene.h"
#include "initialscene.h"
#include "console/console.h"
void initialSceneInit(void) {
consolePrint("Initial scene initialized");
}
errorret_t initialSceneUpdate(void) {
errorOk();
}
errorret_t initialSceneDraw(void) {
errorOk();
}
void initialSceneDispose(void) {
}
+26 -10
View File
@@ -6,16 +6,32 @@
*/
#pragma once
#include "scene/scene.h"
#include "error/error.h"
typedef struct {
void *nothing;
} initialscene_t;
/**
* Initial scene initializer.
*/
void initialSceneInit(void);
errorret_t initialSceneUpdate(void);
errorret_t initialSceneDraw(void);
void initialSceneDispose(void);
static const scene_t INITIAL_SCENE = {
.init = initialSceneInit,
.update = initialSceneUpdate,
.draw = initialSceneDraw,
.dispose = initialSceneDispose
};
/**
* Initial scene updater.
*
* @return Any error state that happened.
*/
errorret_t initialSceneUpdate(void);
/**
* Initial scene drawer.
*
* @return Any error state that happened.
*/
errorret_t initialSceneDraw(void);
/**
* Initial scene disposer.
*/
void initialSceneDispose(void);
+63 -122
View File
@@ -18,15 +18,18 @@
#include "util/string.h"
#include "ui/ui.h"
scene_t SCENE_CURRENT;
scene_t SCENE_NEXT;
bool_t SCENE_NEXT_SET;
scenefuncs_t SCENE_FUNCTIONS[SCENE_TYPE_COUNT] = {
{ 0 },
#define X(structName, varName, varNameUpper, initFunc, updateFunc, renderFunc, disposeFunc) \
{ initFunc, updateFunc, renderFunc, disposeFunc },
#include "scene/scenelist.h"
#undef X
};
scene_t SCENE;
errorret_t sceneInit(void) {
memoryZero(&SCENE_CURRENT, sizeof(scene_t));
memoryZero(&SCENE_NEXT, sizeof(scene_t));
SCENE_NEXT_SET = false;
memoryZero(&SCENE, sizeof(scene_t));
errorOk();
}
@@ -37,14 +40,22 @@ errorret_t sceneUpdate(void) {
}
#endif
if(SCENE_NEXT_SET) {
if(SCENE_CURRENT.dispose) SCENE_CURRENT.dispose();
SCENE_CURRENT = SCENE_NEXT;
SCENE_NEXT_SET = false;
if(SCENE_CURRENT.init) SCENE_CURRENT.init();
// Dispose current scene.
if(SCENE.type != SCENE_TYPE_NULL) {
if(SCENE_FUNCTIONS[SCENE.type].dispose) {
SCENE_FUNCTIONS[SCENE.type].dispose();
}
}
if(SCENE_CURRENT.update != NULL) errorChain(SCENE_CURRENT.update());
// Init new scene
SCENE.type = SCENE.nextType;
SCENE.nextType = SCENE_TYPE_NULL;
if(SCENE.type != SCENE_TYPE_NULL) {
if(SCENE_FUNCTIONS[SCENE.type].init) {
SCENE_FUNCTIONS[SCENE.type].init();
}
}
errorOk();
}
@@ -52,131 +63,61 @@ errorret_t sceneUpdate(void) {
dusktimeepoch_t LAST;
errorret_t sceneRender(void) {
entityid_t camEnts[ENTITY_COUNT_MAX];
componentid_t camComps[ENTITY_COUNT_MAX];
entityid_t camCount = componentGetEntitiesWithComponent(
COMPONENT_TYPE_CAMERA, camEnts, camComps
);
shader_t *shaderCurrent = NULL;
mat4 view, proj, model;
errorChain(displaySetState((displaystate_t){
// .flags = DISPLAY_STATE_FLAG_CULL | DISPLAY_STATE_FLAG_DEPTH_TEST
.flags = 0
}));
// For each camera
for(entityid_t camIndex = 0; camIndex < camCount; camIndex++) {
entityid_t camEnt = camEnts[camIndex];
componentid_t camComp = camComps[camIndex];
componentid_t camPos = entityGetComponent(camEnt, COMPONENT_TYPE_POSITION);
if(camPos == COMPONENT_ID_INVALID) {
logError("Camera entity without entity position found\n");
continue;
}
entityCameraGetProjection(camEnt, camComp, proj);
entityPositionGetTransform(camEnt, camPos, view);
for(entityid_t entityId = 0; entityId < ENTITY_COUNT_MAX; entityId++) {
componentid_t renderComp = entityGetComponent(
entityId, COMPONENT_TYPE_RENDERABLE
);
if(renderComp == COMPONENT_ID_INVALID) continue;
entityrenderable_t *r = componentGetData(
entityId, renderComp, COMPONENT_TYPE_RENDERABLE
);
componentid_t posComp = entityGetComponent(
entityId, COMPONENT_TYPE_POSITION
);
if(posComp == COMPONENT_ID_INVALID) {
glm_mat4_identity(model);
} else {
entityPositionGetTransform(entityId, posComp, model);
}
switch(r->type) {
case ENTITY_RENDERABLE_TYPE_CALLBACK: {
if(!r->callback) break;
errorChain(r->callback(
entityId, renderComp, view, proj, model, r->user
));
break;
}
case ENTITY_RENDERABLE_TYPE_MATERIAL: {
shader_t *shader = r->shader;
if(!shader) break;
if(!r->mesh) break;
if(shaderCurrent != shader) {
shaderCurrent = shader;
errorChain(shaderBind(shaderCurrent));
errorChain(shaderSetMatrix(shader, SHADER_UNLIT_PROJECTION, proj));
errorChain(shaderSetMatrix(shader, SHADER_UNLIT_VIEW, view));
}
errorChain(shaderSetMatrix(shader, SHADER_UNLIT_MODEL, model));
errorChain(shaderSetMaterial(shader, &r->material));
errorChain(meshDraw(r->mesh, 0, -1));
break;
}
case ENTITY_RENDERABLE_TYPE_SPRITEBATCH: {
if(r->spritebatch.spriteCount == 0) break;
shader_t *shader = r->shader;
if(!shader) break;
if(shaderCurrent != shader) {
shaderCurrent = shader;
errorChain(shaderBind(shaderCurrent));
errorChain(shaderSetMatrix(shader, SHADER_UNLIT_PROJECTION, proj));
errorChain(shaderSetMatrix(shader, SHADER_UNLIT_VIEW, view));
}
errorChain(shaderSetMatrix(shader, SHADER_UNLIT_MODEL, model));
for(uint16_t si = 0; si < r->spritebatch.spriteCount; si++) {
errorChain(spriteBatchBufferSprite(&r->spritebatch.sprites[si]));
}
errorChain(spriteBatchFlush());
break;
}
}
}
}
// UI Rendering
mat4 view, proj;
glm_ortho(
0.0f, SCREEN.width,
SCREEN.height, 0.0f,
0.1f, 100.0f,
proj
);
glm_lookat(
(vec3){ 0.0f, 0.0f, 1.0f },
(vec3){ 0.0f, 0.0f, 0.0f },
(vec3){ 0.0f, 1.0f, 0.0f },
view
);
glm_mat4_identity(model);
errorChain(shaderBind(&SHADER_UNLIT));
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj));
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view));
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model));
errorChain(displaySetState((displaystate_t){
.flags = DISPLAY_STATE_FLAG_BLEND
}));
errorChain(uiRender());
if(SCENE.type != SCENE_TYPE_NULL && SCENE_FUNCTIONS[SCENE.type].render) {
glm_mat4_identity(view);
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view));
errorChain(SCENE_FUNCTIONS[SCENE.type].render());
}
// UI Rendering
{
glm_lookat(
(vec3){ 0.0f, 0.0f, 1.0f },
(vec3){ 0.0f, 0.0f, 0.0f },
(vec3){ 0.0f, 1.0f, 0.0f },
view
);
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view));
mat4 model;
glm_mat4_identity(model);
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model));
errorChain(displaySetState((displaystate_t){
.flags = DISPLAY_STATE_FLAG_BLEND
}));
errorChain(uiRender());
}
errorOk();
}
void sceneSet(const scene_t scene) {
SCENE_NEXT = scene;
SCENE_NEXT_SET = true;
void sceneSet(const scenetype_t type) {
assertTrue(
type > SCENE_TYPE_NULL && type < SCENE_TYPE_COUNT,
"Invalid scene type"
);
SCENE.nextType = type;
}
errorret_t sceneDispose(void) {
if(SCENE.type != SCENE_TYPE_NULL) {
if(SCENE_FUNCTIONS[SCENE.type].dispose) {
SCENE_FUNCTIONS[SCENE.type].dispose();
}
}
SCENE.type = SCENE_TYPE_NULL;
SCENE.nextType = SCENE_TYPE_NULL;
errorOk();
}
+28 -5
View File
@@ -7,18 +7,41 @@
#pragma once
#include "asset/assetfile.h"
#include "scene/initial/initialscene.h"
#define SCENE_EVENT_UPDATE_MAX 16
typedef enum {
SCENE_TYPE_NULL,
#define X(structName, varName, varNameUpper, initFunc, updateFunc, renderFunc, disposeFunc) \
SCENE_TYPE_##varNameUpper,
#include "scene/scenelist.h"
#undef X
SCENE_TYPE_COUNT
} scenetype_t;
typedef union {
#define X(structName, varName, varNameUpper, initFunc, updateFunc, renderFunc, disposeFunc) \
structName varName;
#include "scene/scenelist.h"
#undef X
} scenedata_t;
typedef struct {
void (*init)(void);
errorret_t (*update)(void);
errorret_t (*render)(void);
void (*dispose)(void);
} scenefuncs_t;
typedef struct {
scenedata_t data;
scenetype_t type;
scenetype_t nextType;
} scene_t;
extern scene_t SCENE_CURRENT;
extern scene_t SCENE_NEXT;
extern bool_t SCENE_NEXT_SET;
extern scenefuncs_t SCENE_FUNCTIONS[SCENE_TYPE_COUNT];
extern scene_t SCENE;
/**
* Initializes the scene manager.
@@ -44,9 +67,9 @@ errorret_t sceneRender(void);
/**
* Requests a scene change on the next safe opportunity.
*
* @param scene Which scene to set.
* @param type The type of scene to change to.
*/
void sceneSet(const scene_t scene);
void sceneSet(const scenetype_t type);
/**
* Disposes of the current scene.
+13
View File
@@ -0,0 +1,13 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#ifndef X
#define X(structName, varName, varNameUpper, initFunc, updateFunc, renderFunc, disposeFunc) \
((void))
#endif
X(initialscene_t, initial, INITIAL, initialSceneInit, initialSceneUpdate, initialSceneDraw, initialSceneDispose)
+2 -2
View File
@@ -207,6 +207,8 @@ void uiTextboxNextPage(void) {
}
errorret_t uiTextboxDraw(void) {
if(UI_TEXTBOX.lineCount == 0 || UI_TEXTBOX.text[0] == '\0') errorOk();
errorChain(uiFrameDraw(
&UI_TEXTBOX.frame,
UI_TEXTBOX.x, UI_TEXTBOX.y,
@@ -214,8 +216,6 @@ errorret_t uiTextboxDraw(void) {
));
errorChain(spriteBatchFlush());
if(UI_TEXTBOX.lineCount == 0 || UI_TEXTBOX.text[0] == '\0') errorOk();
errorChain(shaderSetTexture(
&SHADER_UNLIT, SHADER_UNLIT_TEXTURE, &UI_TEXTBOX.font->texture
));