ECS POC
This commit is contained in:
@@ -14,11 +14,6 @@
|
|||||||
#error "cameraPushMatrixPlatform must be defined"
|
#error "cameraPushMatrixPlatform must be defined"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CAMERA_PROJECTION_TYPE_PERSPECTIVE,
|
|
||||||
CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED,
|
|
||||||
CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC
|
|
||||||
} cameraprojectiontype_t;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CAMERA_VIEW_TYPE_MATRIX,
|
CAMERA_VIEW_TYPE_MATRIX,
|
||||||
@@ -10,7 +10,6 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Subdirectories
|
# Subdirectories
|
||||||
add_subdirectory(camera)
|
|
||||||
add_subdirectory(framebuffer)
|
add_subdirectory(framebuffer)
|
||||||
add_subdirectory(mesh)
|
add_subdirectory(mesh)
|
||||||
add_subdirectory(screen)
|
add_subdirectory(screen)
|
||||||
|
|||||||
@@ -37,17 +37,29 @@ errorret_t displayInit(void) {
|
|||||||
errorChain(screenInit());
|
errorChain(screenInit());
|
||||||
|
|
||||||
// Setup initial shader with default values
|
// Setup initial shader with default values
|
||||||
|
mat4 view, proj, model;
|
||||||
|
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_perspective(
|
||||||
|
glm_rad(45.0f),
|
||||||
|
(float_t)SCREEN.width / (float_t)SCREEN.height,
|
||||||
|
0.1f,
|
||||||
|
100.0f,
|
||||||
|
proj
|
||||||
|
);
|
||||||
|
|
||||||
|
glm_mat4_identity(model);
|
||||||
|
|
||||||
errorChain(shaderInit(&SHADER_UNLIT, &SHADER_UNLIT_DEFINITION));
|
errorChain(shaderInit(&SHADER_UNLIT, &SHADER_UNLIT_DEFINITION));
|
||||||
camera_t cam;
|
|
||||||
cameraInit(&cam);
|
|
||||||
mat4 mat;
|
|
||||||
cameraGetProjectionMatrix(&cam, mat);
|
|
||||||
errorChain(shaderBind(&SHADER_UNLIT));
|
errorChain(shaderBind(&SHADER_UNLIT));
|
||||||
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, mat));
|
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj));
|
||||||
cameraGetViewMatrix(&cam, mat);
|
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view));
|
||||||
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, mat));
|
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model));
|
||||||
glm_mat4_identity(mat);
|
|
||||||
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, mat));
|
|
||||||
errorChain(shaderSetTexture(&SHADER_UNLIT, SHADER_UNLIT_TEXTURE, NULL));
|
errorChain(shaderSetTexture(&SHADER_UNLIT, SHADER_UNLIT_TEXTURE, NULL));
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "display/displayplatform.h"
|
#include "display/displayplatform.h"
|
||||||
#include "display/camera/camera.h"
|
|
||||||
|
|
||||||
// Expecting some definitions to be provided
|
// Expecting some definitions to be provided
|
||||||
#ifndef DUSK_DISPLAY_SIZE_DYNAMIC
|
#ifndef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||||
|
|||||||
@@ -22,12 +22,6 @@ errorret_t screenInit() {
|
|||||||
SCREEN.mode = SCREEN_MODE_FIXED_VIEWPORT_HEIGHT;
|
SCREEN.mode = SCREEN_MODE_FIXED_VIEWPORT_HEIGHT;
|
||||||
SCREEN.fixedHeight.height = DUSK_DISPLAY_SCREEN_HEIGHT;
|
SCREEN.fixedHeight.height = DUSK_DISPLAY_SCREEN_HEIGHT;
|
||||||
|
|
||||||
cameraInitOrthographic(&SCREEN.framebufferCamera);
|
|
||||||
SCREEN.framebufferCamera.viewType = CAMERA_VIEW_TYPE_2D;
|
|
||||||
SCREEN.framebufferCamera._2d.position[0] = 0;
|
|
||||||
SCREEN.framebufferCamera._2d.position[1] = 0;
|
|
||||||
SCREEN.framebufferCamera._2d.zoom = 1.0f;
|
|
||||||
|
|
||||||
quadBuffer(
|
quadBuffer(
|
||||||
SCREEN.frameBufferMeshVertices,
|
SCREEN.frameBufferMeshVertices,
|
||||||
0.0f, 0.0f,
|
0.0f, 0.0f,
|
||||||
@@ -352,13 +346,17 @@ errorret_t screenRender() {
|
|||||||
fbY = (bbHeight - fbHeight) * 0.5f;
|
fbY = (bbHeight - fbHeight) * 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine back buffer matricies
|
||||||
float_t centerX = bbWidth * 0.5f;
|
float_t centerX = bbWidth * 0.5f;
|
||||||
float_t centerY = bbHeight * 0.5f;
|
float_t centerY = bbHeight * 0.5f;
|
||||||
|
mat4 view, proj, model;
|
||||||
|
glm_ortho(
|
||||||
|
0.0f, bbWidth, bbHeight, 0.0f, 0.01f, 1.0f,
|
||||||
|
proj
|
||||||
|
);
|
||||||
|
glm_mat4_identity(view);
|
||||||
|
glm_mat4_identity(model);
|
||||||
|
|
||||||
SCREEN.framebufferCamera.orthographic.left = 0.0f;
|
|
||||||
SCREEN.framebufferCamera.orthographic.right = bbWidth;
|
|
||||||
SCREEN.framebufferCamera.orthographic.top = 0.0f;
|
|
||||||
SCREEN.framebufferCamera.orthographic.bottom = bbHeight;
|
|
||||||
quadBuffer(
|
quadBuffer(
|
||||||
SCREEN.frameBufferMeshVertices,
|
SCREEN.frameBufferMeshVertices,
|
||||||
centerX - fbWidth * 0.5f, centerY + fbHeight * 0.5f, // top-left
|
centerX - fbWidth * 0.5f, centerY + fbHeight * 0.5f, // top-left
|
||||||
@@ -374,10 +372,6 @@ errorret_t screenRender() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
shaderBind(&SHADER_UNLIT);
|
shaderBind(&SHADER_UNLIT);
|
||||||
mat4 proj, view, model;
|
|
||||||
cameraGetProjectionMatrix(&SCREEN.framebufferCamera, proj);
|
|
||||||
cameraGetViewMatrix(&SCREEN.framebufferCamera, view);
|
|
||||||
glm_mat4_identity(model);
|
|
||||||
shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj);
|
shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj);
|
||||||
shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view);
|
shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view);
|
||||||
shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model);
|
shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model);
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "dusk.h"
|
#include "dusk.h"
|
||||||
#include "display/framebuffer/framebuffer.h"
|
#include "display/framebuffer/framebuffer.h"
|
||||||
#include "display/camera/camera.h"
|
|
||||||
#include "display/mesh/quad.h"
|
#include "display/mesh/quad.h"
|
||||||
#include "display/color.h"
|
#include "display/color.h"
|
||||||
|
|
||||||
@@ -50,7 +49,7 @@ typedef struct {
|
|||||||
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||||
framebuffer_t framebuffer;
|
framebuffer_t framebuffer;
|
||||||
bool_t framebufferReady;
|
bool_t framebufferReady;
|
||||||
camera_t framebufferCamera;
|
// camera_t framebufferCamera;
|
||||||
mesh_t frameBufferMesh;
|
mesh_t frameBufferMesh;
|
||||||
meshvertex_t frameBufferMeshVertices[QUAD_VERTEX_COUNT];
|
meshvertex_t frameBufferMeshVertices[QUAD_VERTEX_COUNT];
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -68,26 +68,42 @@ componentindex_t componentGetIndex(
|
|||||||
|
|
||||||
entityid_t componentGetEntitiesWithComponent(
|
entityid_t componentGetEntitiesWithComponent(
|
||||||
const componenttype_t type,
|
const componenttype_t type,
|
||||||
entityid_t outEntities[ENTITY_COUNT_MAX]
|
entityid_t outEntities[ENTITY_COUNT_MAX],
|
||||||
|
componentid_t outComponents[ENTITY_COUNT_MAX]
|
||||||
) {
|
) {
|
||||||
assertTrue(type < COMPONENT_TYPE_COUNT, "Component type OOB");
|
assertTrue(type < COMPONENT_TYPE_COUNT, "Component type OOB");
|
||||||
assertTrue(type != COMPONENT_TYPE_NULL, "Cannot check NULL type");
|
assertTrue(type != COMPONENT_TYPE_NULL, "Cannot check NULL type");
|
||||||
assertNotNull(outEntities, "Output entities array cannot be null");
|
assertNotNull(outEntities, "Output entities array cannot be null");
|
||||||
|
assertNotNull(outComponents, "Output components array cannot be null");
|
||||||
|
|
||||||
entityid_t written = 0;
|
entityid_t written = 0;
|
||||||
for(entityid_t i = 0; i < ENTITY_COUNT_MAX; i++) {
|
for(entityid_t i = 0; i < ENTITY_COUNT_MAX; i++) {
|
||||||
entityid_t used = ENTITY_MANAGER.entitiesWithComponent[
|
componentid_t used = ENTITY_MANAGER.entitiesWithComponent[
|
||||||
type * ENTITY_COUNT_MAX + i
|
type * ENTITY_COUNT_MAX + i
|
||||||
];
|
];
|
||||||
if(used == 0xFF) continue;
|
if(used == 0xFF) continue;
|
||||||
outEntities[written++] = used;
|
|
||||||
assertTrue(
|
assertTrue(
|
||||||
used == i, "Entity ID mismatch in entitiesWithComponent lookup"
|
ENTITY_MANAGER.components[componentGetIndex(i, used)].type == type,
|
||||||
|
"Component type mismatch in entitiesWithComponent lookup"
|
||||||
);
|
);
|
||||||
assertTrue(
|
assertTrue(
|
||||||
(ENTITY_MANAGER.entities[used].state & ENTITY_STATE_ACTIVE) != 0,
|
(ENTITY_MANAGER.entities[i].state & ENTITY_STATE_ACTIVE) != 0,
|
||||||
"Inactive entity in entitiesWithComponent lookup"
|
"Inactive entity in entitiesWithComponent lookup"
|
||||||
);
|
);
|
||||||
|
assertTrue(
|
||||||
|
used < ENTITY_COMPONENT_COUNT_MAX,
|
||||||
|
"Component ID OOB in entitiesWithComponent lookup"
|
||||||
|
);
|
||||||
|
assertTrue(
|
||||||
|
componentGetIndex(i, used) < ENTITY_COUNT_MAX * ENTITY_COMPONENT_COUNT_MAX,
|
||||||
|
"Component index OOB in entitiesWithComponent lookup"
|
||||||
|
);
|
||||||
|
assertTrue(
|
||||||
|
ENTITY_MANAGER.components[componentGetIndex(i,used)].type == type,
|
||||||
|
"Component type mismatch in entitiesWithComponent lookup"
|
||||||
|
);
|
||||||
|
outComponents[written] = used;
|
||||||
|
outEntities[written++] = i;
|
||||||
}
|
}
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,11 +87,13 @@ componentindex_t componentGetIndex(
|
|||||||
* @param type The type of the component to get entities for.
|
* @param type The type of the component to get entities for.
|
||||||
* @param outEntities An array to write the entity IDs to, must be at least
|
* @param outEntities An array to write the entity IDs to, must be at least
|
||||||
* ENTITY_COUNT_MAX in size.
|
* ENTITY_COUNT_MAX in size.
|
||||||
|
* @param outComponents An array to write the component IDs to.
|
||||||
* @return The number of entity IDs written to outEntities.
|
* @return The number of entity IDs written to outEntities.
|
||||||
*/
|
*/
|
||||||
entityid_t componentGetEntitiesWithComponent(
|
entityid_t componentGetEntitiesWithComponent(
|
||||||
const componenttype_t type,
|
const componenttype_t type,
|
||||||
entityid_t outEntities[ENTITY_COUNT_MAX]
|
entityid_t outEntities[ENTITY_COUNT_MAX],
|
||||||
|
componentid_t outComponents[ENTITY_COUNT_MAX]
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ void entityCameraInit(const entityid_t ent, const componentid_t comp) {
|
|||||||
);
|
);
|
||||||
cam->nearClip = 0.1f;
|
cam->nearClip = 0.1f;
|
||||||
cam->farClip = 100.0f;
|
cam->farClip = 100.0f;
|
||||||
cam->projType = CAMERA_PROJECTION_TYPE_PERSPECTIVE;
|
cam->projType = ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE;
|
||||||
cam->perspective.fov = 60.0f;
|
cam->perspective.fov = glm_rad(45.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void entityCameraGetProjection(
|
void entityCameraGetProjection(
|
||||||
@@ -29,8 +29,8 @@ void entityCameraGetProjection(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if(
|
if(
|
||||||
cam->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE ||
|
cam->projType == ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE ||
|
||||||
cam->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED
|
cam->projType == ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED
|
||||||
) {
|
) {
|
||||||
glm_mat4_identity(out);
|
glm_mat4_identity(out);
|
||||||
glm_perspective(
|
glm_perspective(
|
||||||
@@ -41,10 +41,10 @@ void entityCameraGetProjection(
|
|||||||
out
|
out
|
||||||
);
|
);
|
||||||
|
|
||||||
if(cam->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED) {
|
if(cam->projType == ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED) {
|
||||||
out[1][1] *= -1.0f;
|
out[1][1] *= -1.0f;
|
||||||
}
|
}
|
||||||
} else if(cam->projType == CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) {
|
} else if(cam->projType == ENTITY_CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) {
|
||||||
glm_mat4_identity(out);
|
glm_mat4_identity(out);
|
||||||
glm_ortho(
|
glm_ortho(
|
||||||
cam->orthographic.left,
|
cam->orthographic.left,
|
||||||
|
|||||||
@@ -7,7 +7,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "entity/entitybase.h"
|
#include "entity/entitybase.h"
|
||||||
#include "display/camera/camera.h"
|
|
||||||
|
typedef enum {
|
||||||
|
ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE,
|
||||||
|
ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED,
|
||||||
|
ENTITY_CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC
|
||||||
|
} entitycameraprojectiontype_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
union {
|
union {
|
||||||
@@ -25,7 +30,7 @@ typedef struct {
|
|||||||
|
|
||||||
float_t nearClip;
|
float_t nearClip;
|
||||||
float_t farClip;
|
float_t farClip;
|
||||||
cameraprojectiontype_t projType;
|
entitycameraprojectiontype_t projType;
|
||||||
} entitycamera_t;
|
} entitycamera_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -30,3 +30,14 @@ void entityPositionLookAt(
|
|||||||
);
|
);
|
||||||
glm_lookat(eye, target, up, pos->transform);
|
glm_lookat(eye, target, up, pos->transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void entityPositionGetTransform(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componentid_t componentId,
|
||||||
|
mat4 dest
|
||||||
|
) {
|
||||||
|
entityposition_t *pos = componentGetData(
|
||||||
|
entityId, componentId, COMPONENT_TYPE_POSITION
|
||||||
|
);
|
||||||
|
glm_mat4_copy(pos->transform, dest);
|
||||||
|
}
|
||||||
@@ -39,3 +39,16 @@ void entityPositionLookAt(
|
|||||||
vec3 up,
|
vec3 up,
|
||||||
vec3 eye
|
vec3 eye
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the transform matrix of the entity position component.
|
||||||
|
*
|
||||||
|
* @param entityId The entity ID.
|
||||||
|
* @param componentId The component ID.
|
||||||
|
* @param dest The destination matrix to write the transform to.
|
||||||
|
*/
|
||||||
|
void entityPositionGetTransform(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componentid_t componentId,
|
||||||
|
mat4 dest
|
||||||
|
);
|
||||||
@@ -37,11 +37,17 @@ componentid_t entityAddComponent(
|
|||||||
|
|
||||||
for(componentid_t i = 0; i < ENTITY_COMPONENT_COUNT_MAX; i++) {
|
for(componentid_t i = 0; i < ENTITY_COMPONENT_COUNT_MAX; i++) {
|
||||||
compInd = componentGetIndex(entityId, i);
|
compInd = componentGetIndex(entityId, i);
|
||||||
if(ENTITY_MANAGER.components[compInd].type != COMPONENT_TYPE_NULL) continue;
|
if(ENTITY_MANAGER.components[compInd].type != COMPONENT_TYPE_NULL) {
|
||||||
|
assertTrue(
|
||||||
|
ENTITY_MANAGER.components[compInd].type != type,
|
||||||
|
"Entity already has component of this type"
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
componentInit(entityId, i, type);
|
componentInit(entityId, i, type);
|
||||||
ENTITY_MANAGER.entitiesWithComponent[
|
ENTITY_MANAGER.entitiesWithComponent[
|
||||||
type * ENTITY_COUNT_MAX + entityId
|
type * ENTITY_COUNT_MAX + entityId
|
||||||
] = entityId;
|
] = i;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,6 +55,21 @@ componentid_t entityAddComponent(
|
|||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentid_t entityGetComponent(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componenttype_t type
|
||||||
|
) {
|
||||||
|
componentid_t compId = ENTITY_MANAGER.entitiesWithComponent[
|
||||||
|
type * ENTITY_COUNT_MAX + entityId
|
||||||
|
];
|
||||||
|
if(compId == 0xFF) return compId;
|
||||||
|
assertTrue(
|
||||||
|
ENTITY_MANAGER.components[componentGetIndex(entityId, compId)].type == type,
|
||||||
|
"Component type mismatch"
|
||||||
|
);
|
||||||
|
return compId;
|
||||||
|
}
|
||||||
|
|
||||||
void entityDispose(const entityid_t entityId) {
|
void entityDispose(const entityid_t entityId) {
|
||||||
componentindex_t compInd;
|
componentindex_t compInd;
|
||||||
entity_t *ent = &ENTITY_MANAGER.entities[entityId];
|
entity_t *ent = &ENTITY_MANAGER.entities[entityId];
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ typedef struct {
|
|||||||
void entityInit(const entityid_t entityId);
|
void entityInit(const entityid_t entityId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a component of the given type to the entity with the given ID.
|
* Adds a component of the given type to the entity with the given ID.
|
||||||
*
|
*
|
||||||
* @param entityId The ID of the entity to add the component to.
|
* @param entityId The ID of the entity to add the component to.
|
||||||
* @param type The type of the component to add.
|
* @param type The type of the component to add.
|
||||||
@@ -33,6 +33,18 @@ componentid_t entityAddComponent(
|
|||||||
const componenttype_t type
|
const componenttype_t type
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ID of the component of the given type on the entity with the given ID.
|
||||||
|
*
|
||||||
|
* @param entityId The ID of the entity to get the component from.
|
||||||
|
* @param type The type of the component to get.
|
||||||
|
* @return The ID of the component.
|
||||||
|
*/
|
||||||
|
componentid_t entityGetComponent(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componenttype_t type
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disposes of an entity with the given ID.
|
* Disposes of an entity with the given ID.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
entity_t entities[ENTITY_COUNT_MAX];
|
entity_t entities[ENTITY_COUNT_MAX];
|
||||||
component_t components[ENTITY_COUNT_MAX * ENTITY_COMPONENT_COUNT_MAX];
|
component_t components[ENTITY_COUNT_MAX * ENTITY_COMPONENT_COUNT_MAX];
|
||||||
entityid_t entitiesWithComponent[COMPONENT_TYPE_COUNT * ENTITY_COUNT_MAX];
|
componentid_t entitiesWithComponent[COMPONENT_TYPE_COUNT * ENTITY_COUNT_MAX];
|
||||||
} entitymanager_t;
|
} entitymanager_t;
|
||||||
|
|
||||||
extern entitymanager_t ENTITY_MANAGER;
|
extern entitymanager_t ENTITY_MANAGER;
|
||||||
|
|||||||
+46
-1
@@ -8,8 +8,9 @@
|
|||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "log/log.h"
|
#include "log/log.h"
|
||||||
#include "time/time.h"
|
#include "time/time.h"
|
||||||
#include "display/camera/camera.h"
|
|
||||||
#include "display/screen/screen.h"
|
#include "display/screen/screen.h"
|
||||||
|
#include "entity/entitymanager.h"
|
||||||
|
#include "display/shader/shaderunlit.h"
|
||||||
|
|
||||||
scene_t SCENE;
|
scene_t SCENE;
|
||||||
|
|
||||||
@@ -31,7 +32,51 @@ errorret_t sceneUpdate(void) {
|
|||||||
|
|
||||||
errorret_t sceneRender(void) {
|
errorret_t sceneRender(void) {
|
||||||
// For each camera
|
// For each camera
|
||||||
|
entityid_t camEnts[ENTITY_COUNT_MAX];
|
||||||
|
componentid_t camComps[ENTITY_COUNT_MAX];
|
||||||
|
entityid_t camCount = componentGetEntitiesWithComponent(
|
||||||
|
COMPONENT_TYPE_CAMERA, camEnts, camComps
|
||||||
|
);
|
||||||
|
if(camCount == 0) errorOk();
|
||||||
|
|
||||||
|
// Matricies
|
||||||
|
mat4 view, proj, model;
|
||||||
|
|
||||||
|
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 == 0xFF) {
|
||||||
|
logError("Camera entity without entity position found\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
entityCameraGetProjection(camEnt, camComp, proj);
|
||||||
|
entityPositionGetTransform(camEnt, camPos, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm_mat4_identity(model);
|
||||||
|
|
||||||
|
// Shader
|
||||||
|
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));
|
||||||
|
|
||||||
|
meshvertex_t quadVerts[QUAD_VERTEX_COUNT];
|
||||||
|
quadBuffer(
|
||||||
|
quadVerts,
|
||||||
|
0.0f, 0.0f, 1.0f, 1.0f,
|
||||||
|
COLOR_WHITE,
|
||||||
|
0.0f, 0.0f, 1.0f, 1.0f
|
||||||
|
);
|
||||||
|
mesh_t mesh;
|
||||||
|
errorChain(meshInit(
|
||||||
|
&mesh, MESH_PRIMITIVE_TYPE_TRIANGLES,
|
||||||
|
QUAD_VERTEX_COUNT, quadVerts
|
||||||
|
));
|
||||||
|
errorChain(meshDraw(&mesh, 0, -1));
|
||||||
|
meshDispose(&mesh);
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
moduleglm.c
|
moduleglm.c
|
||||||
modulecamera.c
|
|
||||||
modulespritebatch.c
|
modulespritebatch.c
|
||||||
moduleglm.c
|
moduleglm.c
|
||||||
modulecolor.c
|
modulecolor.c
|
||||||
|
|||||||
@@ -1,333 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "modulecamera.h"
|
|
||||||
#include "assert/assert.h"
|
|
||||||
#include "display/camera/camera.h"
|
|
||||||
#include "util/memory.h"
|
|
||||||
#include "util/string.h"
|
|
||||||
|
|
||||||
void moduleCamera(scriptcontext_t *context) {
|
|
||||||
assertNotNull(context, "Context cannot be NULL.");
|
|
||||||
|
|
||||||
// Create metatable for camera structure.
|
|
||||||
if(luaL_newmetatable(context->luaState, "camera_mt")) {
|
|
||||||
// Metatable methods
|
|
||||||
lua_pushcfunction(context->luaState, moduleCameraIndex);
|
|
||||||
lua_setfield(context->luaState, -2, "__index");
|
|
||||||
lua_pushcfunction(context->luaState, moduleCameraNewIndex);
|
|
||||||
lua_setfield(context->luaState, -2, "__newindex");
|
|
||||||
lua_pop(context->luaState, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Definitions
|
|
||||||
#define MODULE_CAMERA_SCRIPT_LEN 64
|
|
||||||
char_t buffer[MODULE_CAMERA_SCRIPT_LEN];
|
|
||||||
#define MODULE_CAMERA_DEF(str, val) \
|
|
||||||
snprintf( \
|
|
||||||
buffer, \
|
|
||||||
MODULE_CAMERA_SCRIPT_LEN, \
|
|
||||||
"%s = %d", \
|
|
||||||
str, \
|
|
||||||
val \
|
|
||||||
); \
|
|
||||||
scriptContextExec(context, buffer);
|
|
||||||
|
|
||||||
MODULE_CAMERA_DEF(
|
|
||||||
"CAMERA_PROJECTION_TYPE_PERSPECTIVE",
|
|
||||||
CAMERA_PROJECTION_TYPE_PERSPECTIVE
|
|
||||||
);
|
|
||||||
MODULE_CAMERA_DEF(
|
|
||||||
"CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED",
|
|
||||||
CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED
|
|
||||||
);
|
|
||||||
MODULE_CAMERA_DEF(
|
|
||||||
"CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC",
|
|
||||||
CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC
|
|
||||||
);
|
|
||||||
|
|
||||||
MODULE_CAMERA_DEF(
|
|
||||||
"CAMERA_VIEW_TYPE_MATRIX",
|
|
||||||
CAMERA_VIEW_TYPE_MATRIX
|
|
||||||
);
|
|
||||||
MODULE_CAMERA_DEF(
|
|
||||||
"CAMERA_VIEW_TYPE_LOOKAT",
|
|
||||||
CAMERA_VIEW_TYPE_LOOKAT
|
|
||||||
);
|
|
||||||
MODULE_CAMERA_DEF(
|
|
||||||
"CAMERA_VIEW_TYPE_2D",
|
|
||||||
CAMERA_VIEW_TYPE_2D
|
|
||||||
);
|
|
||||||
MODULE_CAMERA_DEF(
|
|
||||||
"CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT",
|
|
||||||
CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT
|
|
||||||
);
|
|
||||||
|
|
||||||
// Methods
|
|
||||||
lua_register(context->luaState, "cameraCreate", moduleCameraCreate);
|
|
||||||
lua_register(
|
|
||||||
context->luaState,
|
|
||||||
"cameraGetProjectionMatrix",
|
|
||||||
moduleCameraGetProjectionMatrix
|
|
||||||
);
|
|
||||||
lua_register(
|
|
||||||
context->luaState,
|
|
||||||
"cameraGetViewMatrix",
|
|
||||||
moduleCameraGetViewMatrix
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleCameraCreate(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL.");
|
|
||||||
|
|
||||||
scriptcontext_t *context = *(scriptcontext_t **)lua_getextraspace(L);
|
|
||||||
assertNotNull(context, "Script context cannot be NULL.");
|
|
||||||
|
|
||||||
// If we are provided a projection type, use it.
|
|
||||||
cameraprojectiontype_t projType = CAMERA_PROJECTION_TYPE_PERSPECTIVE;
|
|
||||||
if(lua_gettop(L) >= 1) {
|
|
||||||
if(!lua_isnumber(L, 1)) {
|
|
||||||
luaL_error(L, "Camera projection type must be a number.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
projType = (cameraprojectiontype_t)lua_tonumber(L, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create camera that Lua will own
|
|
||||||
camera_t *cam = (camera_t *)lua_newuserdata(L, sizeof(camera_t));
|
|
||||||
memoryZero(cam, sizeof(camera_t));
|
|
||||||
|
|
||||||
// Set metatable
|
|
||||||
luaL_getmetatable(L, "camera_mt");
|
|
||||||
lua_setmetatable(L, -2);
|
|
||||||
|
|
||||||
// Init camera
|
|
||||||
switch(projType) {
|
|
||||||
case CAMERA_PROJECTION_TYPE_PERSPECTIVE:
|
|
||||||
case CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED:
|
|
||||||
cameraInitPerspective(cam);
|
|
||||||
cam->projType = projType;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC:
|
|
||||||
cameraInitOrthographic(cam);
|
|
||||||
cam->projType = projType;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
luaL_error(L, "Invalid camera projection type specified.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleCameraIndex(lua_State *l) {
|
|
||||||
assertNotNull(l, "Lua state cannot be NULL.");
|
|
||||||
|
|
||||||
const char_t *key = luaL_checkstring(l, 2);
|
|
||||||
assertStrLenMin(key, 1, "Key cannot be empty.");
|
|
||||||
|
|
||||||
camera_t *cam = (camera_t *)luaL_checkudata(l, 1, "camera_mt");
|
|
||||||
assertNotNull(cam, "Camera pointer cannot be NULL.");
|
|
||||||
|
|
||||||
if(stringCompare(key, "near") == 0) {
|
|
||||||
lua_pushnumber(l, cam->nearClip);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "far") == 0) {
|
|
||||||
lua_pushnumber(l, cam->farClip);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "nearClip") == 0) {
|
|
||||||
lua_pushnumber(l, cam->nearClip);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "farClip") == 0) {
|
|
||||||
lua_pushnumber(l, cam->farClip);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perspective relative values
|
|
||||||
if(cam->projType == CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) {
|
|
||||||
if(stringCompare(key, "left") == 0) {
|
|
||||||
lua_pushnumber(l, cam->orthographic.left);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "right") == 0) {
|
|
||||||
lua_pushnumber(l, cam->orthographic.right);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "top") == 0) {
|
|
||||||
lua_pushnumber(l, cam->orthographic.top);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "bottom") == 0) {
|
|
||||||
lua_pushnumber(l, cam->orthographic.bottom);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else if(
|
|
||||||
cam->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE ||
|
|
||||||
cam->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED
|
|
||||||
) {
|
|
||||||
if(stringCompare(key, "fov") == 0) {
|
|
||||||
lua_pushnumber(l, cam->perspective.fov);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// View type relative values.
|
|
||||||
if(cam->viewType == CAMERA_VIEW_TYPE_MATRIX) {
|
|
||||||
|
|
||||||
} else if(cam->viewType == CAMERA_VIEW_TYPE_LOOKAT) {
|
|
||||||
if(stringCompare(key, "position") == 0) {
|
|
||||||
vec3 *v = (vec3 *)lua_newuserdata(l, sizeof(vec3));
|
|
||||||
memoryCopy(v, &cam->lookat.position, sizeof(vec3));
|
|
||||||
luaL_getmetatable(l, "vec3_mt");
|
|
||||||
lua_setmetatable(l, -2);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "target") == 0) {
|
|
||||||
vec3 *v = (vec3 *)lua_newuserdata(l, sizeof(vec3));
|
|
||||||
memoryCopy(v, &cam->lookat.target, sizeof(vec3));
|
|
||||||
luaL_getmetatable(l, "vec3_mt");
|
|
||||||
lua_setmetatable(l, -2);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "up") == 0) {
|
|
||||||
vec3 *v = (vec3 *)lua_newuserdata(l, sizeof(vec3));
|
|
||||||
memoryCopy(v, &cam->lookat.up, sizeof(vec3));
|
|
||||||
luaL_getmetatable(l, "vec3_mt");
|
|
||||||
lua_setmetatable(l, -2);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else if(cam->viewType == CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT) {
|
|
||||||
|
|
||||||
} else if(cam->viewType == CAMERA_VIEW_TYPE_2D) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_pushnil(l);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleCameraNewIndex(lua_State *l) {
|
|
||||||
assertNotNull(l, "Lua state cannot be NULL.");
|
|
||||||
|
|
||||||
const char_t *key = luaL_checkstring(l, 2);
|
|
||||||
assertStrLenMin(key, 1, "Key cannot be empty.");
|
|
||||||
|
|
||||||
camera_t *cam = (camera_t *)luaL_checkudata(l, 1, "camera_mt");
|
|
||||||
assertNotNull(cam, "Camera pointer cannot be NULL.");
|
|
||||||
|
|
||||||
if(stringCompare(key, "near") == 0 || stringCompare(key, "nearClip") == 0) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Camera near clip must be a number.");
|
|
||||||
}
|
|
||||||
cam->nearClip = (float_t)lua_tonumber(l, 3);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stringCompare(key, "far") == 0 || stringCompare(key, "farClip") == 0) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Camera far clip must be a number.");
|
|
||||||
}
|
|
||||||
cam->farClip = (float_t)lua_tonumber(l, 3);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perspective relative values
|
|
||||||
if(cam->projType == CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) {
|
|
||||||
if(stringCompare(key, "left") == 0) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Camera orthographic left must be a number.");
|
|
||||||
}
|
|
||||||
cam->orthographic.left = (float_t)lua_tonumber(l, 3);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stringCompare(key, "right") == 0) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Camera orthographic right must be a number.");
|
|
||||||
}
|
|
||||||
cam->orthographic.right = (float_t)lua_tonumber(l, 3);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stringCompare(key, "top") == 0) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Camera orthographic top must be a number.");
|
|
||||||
}
|
|
||||||
cam->orthographic.top = (float_t)lua_tonumber(l, 3);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stringCompare(key, "bottom") == 0) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Camera orthographic bottom must be a number.");
|
|
||||||
}
|
|
||||||
cam->orthographic.bottom = (float_t)lua_tonumber(l, 3);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} else if(
|
|
||||||
cam->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE ||
|
|
||||||
cam->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED
|
|
||||||
) {
|
|
||||||
if(stringCompare(key, "fov") == 0) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Camera perspective FOV must be a number.");
|
|
||||||
}
|
|
||||||
cam->perspective.fov = (float_t)lua_tonumber(l, 3);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cam->viewType == CAMERA_VIEW_TYPE_LOOKAT) {
|
|
||||||
if(stringCompare(key, "position") == 0) {
|
|
||||||
vec3 *v = (vec3 *)luaL_checkudata(l, 3, "vec3_mt");
|
|
||||||
assertNotNull(v, "Vec3 pointer cannot be NULL.");
|
|
||||||
memoryCopy(&cam->lookat.position, v, sizeof(vec3));
|
|
||||||
return 0;
|
|
||||||
} else if(stringCompare(key, "target") == 0) {
|
|
||||||
vec3 *v = (vec3 *)luaL_checkudata(l, 3, "vec3_mt");
|
|
||||||
assertNotNull(v, "Vec3 pointer cannot be NULL.");
|
|
||||||
memoryCopy(&cam->lookat.target, v, sizeof(vec3));
|
|
||||||
return 0;
|
|
||||||
} else if(stringCompare(key, "up") == 0) {
|
|
||||||
vec3 *v = (vec3 *)luaL_checkudata(l, 3, "vec3_mt");
|
|
||||||
assertNotNull(v, "Vec3 pointer cannot be NULL.");
|
|
||||||
memoryCopy(&cam->lookat.up, v, sizeof(vec3));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleCameraGetProjectionMatrix(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL.");
|
|
||||||
|
|
||||||
camera_t *cam = (camera_t *)luaL_checkudata(L, 1, "camera_mt");
|
|
||||||
assertNotNull(cam, "Camera pointer cannot be NULL.");
|
|
||||||
|
|
||||||
// Create mat4
|
|
||||||
mat4 test;
|
|
||||||
cameraGetProjectionMatrix(cam, test);
|
|
||||||
|
|
||||||
// Lua needs to own this matrix now
|
|
||||||
mat4 *m = (mat4 *)lua_newuserdata(L, sizeof(mat4));
|
|
||||||
memoryCopy(m, test, sizeof(mat4));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleCameraGetViewMatrix(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL.");
|
|
||||||
|
|
||||||
camera_t *cam = (camera_t *)luaL_checkudata(L, 1, "camera_mt");
|
|
||||||
assertNotNull(cam, "Camera pointer cannot be NULL.");
|
|
||||||
|
|
||||||
// Create mat4
|
|
||||||
mat4 test;
|
|
||||||
cameraGetViewMatrix(cam, test);
|
|
||||||
|
|
||||||
// Lua needs to own this matrix now
|
|
||||||
mat4 *m = (mat4 *)lua_newuserdata(L, sizeof(mat4));
|
|
||||||
memoryCopy(m, test, sizeof(mat4));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "script/scriptcontext.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register camera functions to the given script context.
|
|
||||||
*
|
|
||||||
* @param context The script context to register camera functions to.
|
|
||||||
*/
|
|
||||||
void moduleCamera(scriptcontext_t *context);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Script binding for creating a new camera.
|
|
||||||
*
|
|
||||||
* @param L The Lua state.
|
|
||||||
* @return Number of return values on the Lua stack.
|
|
||||||
*/
|
|
||||||
int moduleCameraCreate(lua_State *L);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter for camera structure fields.
|
|
||||||
*
|
|
||||||
* @param l The Lua state.
|
|
||||||
*/
|
|
||||||
int moduleCameraIndex(lua_State *l);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setter for camera structure fields.
|
|
||||||
*
|
|
||||||
* @param l The Lua state.
|
|
||||||
*/
|
|
||||||
int moduleCameraNewIndex(lua_State *l);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Script binding for getting a camera's projection matrix.
|
|
||||||
*
|
|
||||||
* @param L The Lua state.
|
|
||||||
* @return Number of return values on the Lua stack.
|
|
||||||
*/
|
|
||||||
int moduleCameraGetProjectionMatrix(lua_State *L);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Script binding for getting a camera's view matrix.
|
|
||||||
*
|
|
||||||
* @param L The Lua state.
|
|
||||||
* @return Number of return values on the Lua stack.
|
|
||||||
*/
|
|
||||||
int moduleCameraGetViewMatrix(lua_State *L);
|
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "display/shader/shader.h"
|
#include "display/shader/shader.h"
|
||||||
#include "display/shader/shaderunlit.h"
|
#include "display/shader/shaderunlit.h"
|
||||||
#include "display/camera/camera.h"
|
|
||||||
|
|
||||||
void moduleShader(scriptcontext_t *context) {
|
void moduleShader(scriptcontext_t *context) {
|
||||||
assertNotNull(context, "Context cannot be NULL.");
|
assertNotNull(context, "Context cannot be NULL.");
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
#include "script/module/event/moduleevent.h"
|
#include "script/module/event/moduleevent.h"
|
||||||
#include "script/module/display/modulecolor.h"
|
#include "script/module/display/modulecolor.h"
|
||||||
#include "script/module/display/modulespritebatch.h"
|
#include "script/module/display/modulespritebatch.h"
|
||||||
#include "script/module/display/modulecamera.h"
|
|
||||||
#include "script/module/display/moduleglm.h"
|
#include "script/module/display/moduleglm.h"
|
||||||
#include "script/module/display/moduleshader.h"
|
#include "script/module/display/moduleshader.h"
|
||||||
#include "script/module/ui/moduleui.h"
|
#include "script/module/ui/moduleui.h"
|
||||||
@@ -36,7 +35,6 @@ const scriptmodule_t SCRIPT_MODULE_LIST[] = {
|
|||||||
{ .name = "time", .callback = moduleTime },
|
{ .name = "time", .callback = moduleTime },
|
||||||
{ .name = "event", .callback = moduleEvent },
|
{ .name = "event", .callback = moduleEvent },
|
||||||
{ .name = "spritebatch", .callback = moduleSpriteBatch },
|
{ .name = "spritebatch", .callback = moduleSpriteBatch },
|
||||||
{ .name = "camera", .callback = moduleCamera },
|
|
||||||
{ .name = "glm", .callback = moduleGLM },
|
{ .name = "glm", .callback = moduleGLM },
|
||||||
{ .name = "ui", .callback = moduleUi },
|
{ .name = "ui", .callback = moduleUi },
|
||||||
{ .name = "text", .callback = moduleText },
|
{ .name = "text", .callback = moduleText },
|
||||||
|
|||||||
+9
-9
@@ -16,9 +16,9 @@ ui_t UI;
|
|||||||
errorret_t uiInit(void) {
|
errorret_t uiInit(void) {
|
||||||
memoryZero(&UI, sizeof(ui_t));
|
memoryZero(&UI, sizeof(ui_t));
|
||||||
|
|
||||||
cameraInitOrthographic(&UI.camera);
|
// cameraInitOrthographic(&UI.camera);
|
||||||
UI.camera.orthographic.left = 0;
|
// UI.camera.orthographic.left = 0;
|
||||||
UI.camera.orthographic.bottom = 0;
|
// UI.camera.orthographic.bottom = 0;
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
@@ -27,14 +27,14 @@ void uiUpdate(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void uiRender(void) {
|
void uiRender(void) {
|
||||||
UI.camera.orthographic.right = SCREEN.width;
|
// UI.camera.orthographic.right = SCREEN.width;
|
||||||
UI.camera.orthographic.top = SCREEN.height;
|
// UI.camera.orthographic.top = SCREEN.height;
|
||||||
|
|
||||||
// cameraPushMatrix(&UI.camera);
|
// // cameraPushMatrix(&UI.camera);
|
||||||
spriteBatchClear();
|
// spriteBatchClear();
|
||||||
|
|
||||||
spriteBatchFlush();
|
// spriteBatchFlush();
|
||||||
// cameraPopMatrix();
|
// // cameraPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiDispose(void) {
|
void uiDispose(void) {
|
||||||
|
|||||||
+1
-2
@@ -6,11 +6,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "display/camera/camera.h"
|
|
||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
camera_t camera;
|
void *nothing;
|
||||||
} ui_t;
|
} ui_t;
|
||||||
|
|
||||||
extern ui_t UI;
|
extern ui_t UI;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Subdirs
|
# Subdirs
|
||||||
add_subdirectory(camera)
|
|
||||||
add_subdirectory(framebuffer)
|
add_subdirectory(framebuffer)
|
||||||
add_subdirectory(mesh)
|
add_subdirectory(mesh)
|
||||||
add_subdirectory(texture)
|
add_subdirectory(texture)
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
# Copyright (c) 2026 Dominic Masters
|
|
||||||
#
|
|
||||||
# This software is released under the MIT License.
|
|
||||||
# https://opensource.org/licenses/MIT
|
|
||||||
|
|
||||||
# Sources
|
|
||||||
|
|
||||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
|
||||||
PUBLIC
|
|
||||||
cameradolphin.c
|
|
||||||
)
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "display/camera/camera.h"
|
|
||||||
#include "display/framebuffer/framebuffer.h"
|
|
||||||
#include "assert/assert.h"
|
|
||||||
|
|
||||||
void cameraPushMatrixDolphin(camera_t *camera) {
|
|
||||||
assertNotNull(camera, "Camera cannot be null");
|
|
||||||
assertTrue(
|
|
||||||
camera->nearClip > 0.0f,
|
|
||||||
"Camera near clip must be greater than 0 for Dolphin"
|
|
||||||
);
|
|
||||||
|
|
||||||
Mtx44 guProjection;
|
|
||||||
Mtx guView;
|
|
||||||
Mtx modelView;
|
|
||||||
|
|
||||||
switch(camera->projType) {
|
|
||||||
case CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC:
|
|
||||||
guOrtho(
|
|
||||||
guProjection,
|
|
||||||
camera->orthographic.top,
|
|
||||||
camera->orthographic.bottom,
|
|
||||||
camera->orthographic.left,
|
|
||||||
camera->orthographic.right,
|
|
||||||
camera->nearClip,
|
|
||||||
camera->farClip
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CAMERA_PROJECTION_TYPE_PERSPECTIVE:
|
|
||||||
guPerspective(
|
|
||||||
guProjection,
|
|
||||||
// FOV is in degrees.
|
|
||||||
camera->perspective.fov * (180.0f / GLM_PIf),
|
|
||||||
(float_t)frameBufferGetWidth(FRAMEBUFFER_BOUND) /
|
|
||||||
(float_t)frameBufferGetHeight(FRAMEBUFFER_BOUND),
|
|
||||||
camera->nearClip,
|
|
||||||
camera->farClip
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED:
|
|
||||||
assertUnreachable("Flipped perspective not implemented on Dolphin");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assertUnreachable("Invalid camera projection type");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(camera->viewType) {
|
|
||||||
case CAMERA_VIEW_TYPE_LOOKAT:
|
|
||||||
guVector eye = {
|
|
||||||
camera->lookat.position[0],
|
|
||||||
camera->lookat.position[1],
|
|
||||||
camera->lookat.position[2]
|
|
||||||
};
|
|
||||||
guVector up = {
|
|
||||||
camera->lookat.up[0],
|
|
||||||
camera->lookat.up[1],
|
|
||||||
camera->lookat.up[2]
|
|
||||||
};
|
|
||||||
guVector look = {
|
|
||||||
camera->lookat.target[0],
|
|
||||||
camera->lookat.target[1],
|
|
||||||
camera->lookat.target[2]
|
|
||||||
};
|
|
||||||
guLookAt(guView, &eye, &up, &look);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CAMERA_VIEW_TYPE_MATRIX:
|
|
||||||
assertUnreachable("Matrix camera not implemented");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT:
|
|
||||||
assertUnreachable("Pixel perfect camera not implemented");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CAMERA_VIEW_TYPE_2D:
|
|
||||||
guMtxIdentity(guView);
|
|
||||||
guMtxTrans(guView, -camera->_2d.position[0], -camera->_2d.position[1], 0.0f);
|
|
||||||
guMtxScale(guView, camera->_2d.zoom, camera->_2d.zoom, 1.0f);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assertUnreachable("Invalid camera view type");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Projection Matrix
|
|
||||||
GX_LoadProjectionMtx(
|
|
||||||
guProjection,
|
|
||||||
camera->projType == CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC ?
|
|
||||||
GX_ORTHOGRAPHIC :
|
|
||||||
GX_PERSPECTIVE
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set view and model matrix. Dunno how I'll handle models but whatever.
|
|
||||||
guMtxIdentity(modelView);
|
|
||||||
guMtxTransApply(modelView, modelView, 0.0F, 0.0F, 0.0F);
|
|
||||||
guMtxConcat(guView,modelView,modelView);
|
|
||||||
GX_LoadPosMtxImm(modelView, GX_PNMTX0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cameraPopMatrixDolphin(void) {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "dusk.h"
|
|
||||||
|
|
||||||
typedef struct camera_s camera_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pushes the camera's transformation matrix onto the graphics stack.
|
|
||||||
*
|
|
||||||
* @param camera The camera to push the matrix of.
|
|
||||||
*/
|
|
||||||
void cameraPushMatrixDolphin(camera_t *camera);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pops the camera's transformation matrix from the graphics stack.
|
|
||||||
*/
|
|
||||||
void cameraPopMatrixDolphin(void);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "cameradolphin.h"
|
|
||||||
|
|
||||||
#define cameraPushMatrixPlatform cameraPushMatrixDolphin
|
|
||||||
#define cameraPopMatrixPlatform cameraPopMatrixDolphin
|
|
||||||
@@ -10,7 +10,6 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Subdirs
|
# Subdirs
|
||||||
add_subdirectory(camera)
|
|
||||||
add_subdirectory(framebuffer)
|
add_subdirectory(framebuffer)
|
||||||
add_subdirectory(texture)
|
add_subdirectory(texture)
|
||||||
add_subdirectory(mesh)
|
add_subdirectory(mesh)
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
# Copyright (c) 2026 Dominic Masters
|
|
||||||
#
|
|
||||||
# This software is released under the MIT License.
|
|
||||||
# https://opensource.org/licenses/MIT
|
|
||||||
|
|
||||||
# Sources
|
|
||||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
|
||||||
PUBLIC
|
|
||||||
cameragl.c
|
|
||||||
)
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "display/camera/camera.h"
|
|
||||||
#include "display/framebuffer/framebuffer.h"
|
|
||||||
#include "display/screen/screen.h"
|
|
||||||
#include "assert/assertgl.h"
|
|
||||||
|
|
||||||
void cameraPushMatrixGL(camera_t *camera) {
|
|
||||||
assertNotNull(camera, "Not a camera component");
|
|
||||||
|
|
||||||
mat4 projection;
|
|
||||||
mat4 view;
|
|
||||||
|
|
||||||
switch(camera->projType) {
|
|
||||||
case CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC: {
|
|
||||||
assertTrue(
|
|
||||||
camera->orthographic.right != camera->orthographic.left &&
|
|
||||||
camera->orthographic.top != camera->orthographic.bottom,
|
|
||||||
"Invalid orthographic projection parameters"
|
|
||||||
);
|
|
||||||
glm_ortho(
|
|
||||||
camera->orthographic.left,
|
|
||||||
camera->orthographic.right,
|
|
||||||
camera->orthographic.bottom,
|
|
||||||
camera->orthographic.top,
|
|
||||||
camera->nearClip,
|
|
||||||
camera->farClip,
|
|
||||||
projection
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED:
|
|
||||||
case CAMERA_PROJECTION_TYPE_PERSPECTIVE: {
|
|
||||||
const float_t aspect = (
|
|
||||||
(float_t)frameBufferGetWidth(FRAMEBUFFER_BOUND) /
|
|
||||||
(float_t)frameBufferGetHeight(FRAMEBUFFER_BOUND)
|
|
||||||
);
|
|
||||||
glm_perspective(
|
|
||||||
camera->perspective.fov,
|
|
||||||
aspect,
|
|
||||||
camera->nearClip,
|
|
||||||
camera->farClip,
|
|
||||||
projection
|
|
||||||
);
|
|
||||||
|
|
||||||
if(camera->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED) {
|
|
||||||
// Flip Y axis
|
|
||||||
projection[1][1] *= -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(camera->viewType) {
|
|
||||||
case CAMERA_VIEW_TYPE_MATRIX:
|
|
||||||
glm_mat4_ucopy(camera->view, view);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CAMERA_VIEW_TYPE_LOOKAT:
|
|
||||||
glm_lookat(
|
|
||||||
camera->lookat.position,
|
|
||||||
camera->lookat.target,
|
|
||||||
camera->lookat.up,
|
|
||||||
view
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT:
|
|
||||||
assertTrue(
|
|
||||||
camera->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE ||
|
|
||||||
camera->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED,
|
|
||||||
"Pixel perfect camera view requires perspective projection"
|
|
||||||
);
|
|
||||||
|
|
||||||
// const float_t viewportHeight = (
|
|
||||||
// (float_t)frameBufferGetHeight(FRAMEBUFFER_BOUND)
|
|
||||||
// );
|
|
||||||
const float_t viewportHeight = (float_t)SCREEN.height;
|
|
||||||
const float_t z = (viewportHeight / 2.0f) / (
|
|
||||||
camera->lookatPixelPerfect.pixelsPerUnit *
|
|
||||||
tanf(camera->perspective.fov / 2.0f)
|
|
||||||
);
|
|
||||||
|
|
||||||
vec3 position;
|
|
||||||
glm_vec3_copy(camera->lookatPixelPerfect.target, position);
|
|
||||||
glm_vec3_add(position, camera->lookatPixelPerfect.offset, position);
|
|
||||||
position[2] += z;
|
|
||||||
glm_lookat(
|
|
||||||
position,
|
|
||||||
camera->lookatPixelPerfect.target,
|
|
||||||
camera->lookatPixelPerfect.up,
|
|
||||||
view
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CAMERA_VIEW_TYPE_2D:
|
|
||||||
glm_mat4_identity(view);
|
|
||||||
glm_translate(view, (vec3){
|
|
||||||
-camera->_2d.position[0],
|
|
||||||
-camera->_2d.position[1],
|
|
||||||
0.0f
|
|
||||||
});
|
|
||||||
glm_scale(view, (vec3){
|
|
||||||
camera->_2d.zoom,
|
|
||||||
camera->_2d.zoom,
|
|
||||||
1.0f
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assertUnreachable("Invalid camera view type");
|
|
||||||
}
|
|
||||||
|
|
||||||
// glPushMatrix();
|
|
||||||
// glMatrixMode(GL_PROJECTION);
|
|
||||||
// glLoadIdentity();
|
|
||||||
// glLoadMatrixf((const GLfloat*)projection);
|
|
||||||
assertNoGLError("Failed to set projection matrix");
|
|
||||||
|
|
||||||
// glMatrixMode(GL_MODELVIEW);
|
|
||||||
// glLoadIdentity();
|
|
||||||
// glLoadMatrixf((const GLfloat*)view);
|
|
||||||
assertNoGLError("Failed to set view matrix");
|
|
||||||
}
|
|
||||||
|
|
||||||
void cameraPopMatrixGL(void) {
|
|
||||||
// glPopMatrix();
|
|
||||||
assertNoGLError("Failed to pop camera matrix");
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
typedef struct camera_s camera_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes a camera with default perspective parameters.
|
|
||||||
*
|
|
||||||
* @param camera The camera to initialize.
|
|
||||||
*/
|
|
||||||
void cameraPushMatrixGL(camera_t *camera);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the previously pushed camera matrix off the matrix stack.
|
|
||||||
*/
|
|
||||||
void cameraPopMatrixGL(void);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "cameragl.h"
|
|
||||||
|
|
||||||
#define cameraPushMatrixPlatform cameraPushMatrixGL
|
|
||||||
#define cameraPopMatrixPlatform cameraPopMatrixGL
|
|
||||||
Reference in New Issue
Block a user