Fixed errors
This commit is contained in:
@@ -7,16 +7,16 @@
|
|||||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
display.c
|
display.c
|
||||||
text.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Subdirectories
|
# Subdirectories
|
||||||
add_subdirectory(camera)
|
add_subdirectory(camera)
|
||||||
add_subdirectory(framebuffer)
|
add_subdirectory(framebuffer)
|
||||||
add_subdirectory(mesh)
|
add_subdirectory(mesh)
|
||||||
add_subdirectory(texture)
|
|
||||||
add_subdirectory(spritebatch)
|
|
||||||
add_subdirectory(screen)
|
add_subdirectory(screen)
|
||||||
|
add_subdirectory(spritebatch)
|
||||||
|
add_subdirectory(text)
|
||||||
|
add_subdirectory(texture)
|
||||||
|
|
||||||
# Color definitions
|
# Color definitions
|
||||||
dusk_run_python(
|
dusk_run_python(
|
||||||
|
|||||||
@@ -46,222 +46,12 @@ void cameraInitOrthographic(camera_t *camera) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cameraPushMatrix(camera_t *camera) {
|
void cameraPushMatrix(camera_t *camera) {
|
||||||
assertNotNull(camera, "Not a camera component");
|
assertNotNull(camera, "Invalid camera");
|
||||||
|
cameraPushMatrixPlatform(camera);
|
||||||
#if 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);
|
|
||||||
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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_copy(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");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DISPLAY_SDL2
|
|
||||||
// mat4 pv;
|
|
||||||
// glm_mat4_mul(projection, camera->transform, pv);
|
|
||||||
|
|
||||||
glPushMatrix();
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glLoadIdentity();
|
|
||||||
glLoadMatrixf((const GLfloat*)projection);
|
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glLoadIdentity();
|
|
||||||
glLoadMatrixf((const GLfloat*)view);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cameraPopMatrix(void) {
|
void cameraPopMatrix(void) {
|
||||||
#if DISPLAY_SDL2
|
#ifdef cameraPopMatrixPlatform
|
||||||
glPopMatrix();
|
cameraPopMatrixPlatform();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "dusk.h"
|
#include "dusk.h"
|
||||||
#include "display/color.h"
|
#include "display/color.h"
|
||||||
|
#include "display/camera/cameraplatform.h"
|
||||||
|
|
||||||
|
#ifndef cameraPushMatrixPlatform
|
||||||
|
#error "cameraPushMatrixPlatform must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CAMERA_PROJECTION_TYPE_PERSPECTIVE,
|
CAMERA_PROJECTION_TYPE_PERSPECTIVE,
|
||||||
@@ -22,8 +27,7 @@ typedef enum {
|
|||||||
CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT
|
CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT
|
||||||
} cameraviewtype_t;
|
} cameraviewtype_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct camera_s {
|
||||||
|
|
||||||
union {
|
union {
|
||||||
mat4 view;
|
mat4 view;
|
||||||
|
|
||||||
@@ -86,7 +90,7 @@ void cameraInitOrthographic(camera_t *camera);
|
|||||||
*
|
*
|
||||||
* @param id The ID of the camera entity to use.
|
* @param id The ID of the camera entity to use.
|
||||||
*/
|
*/
|
||||||
void cameraPushMatrix(camera_t* camera);
|
void cameraPushMatrix(camera_t *camera);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pops the camera's view matrix off the matrix stack.
|
* Pops the camera's view matrix off the matrix stack.
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "display/display.h"
|
#include "display/display.h"
|
||||||
#include "engine/engine.h"
|
|
||||||
#include "display/framebuffer/framebuffer.h"
|
#include "display/framebuffer/framebuffer.h"
|
||||||
#include "scene/scene.h"
|
#include "scene/scene.h"
|
||||||
#include "display/spritebatch/spritebatch.h"
|
#include "display/spritebatch/spritebatch.h"
|
||||||
@@ -14,7 +13,7 @@
|
|||||||
#include "display/screen/screen.h"
|
#include "display/screen/screen.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
#include "debug/debug.h"
|
#include "debug/debug.h"
|
||||||
#include "display/text.h"
|
#include "display/text/text.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
@@ -33,8 +32,7 @@ errorret_t displayInit(void) {
|
|||||||
errorChain(frameBufferInitBackBuffer());
|
errorChain(frameBufferInitBackBuffer());
|
||||||
errorChain(spriteBatchInit());
|
errorChain(spriteBatchInit());
|
||||||
errorChain(textInit());
|
errorChain(textInit());
|
||||||
// errorChain(assetLoad("main_palette.dpf", &PALETTES[0]));
|
errorChain(screenInit());
|
||||||
screenInit();
|
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
@@ -72,9 +70,9 @@ errorret_t displayUpdate(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errorret_t displayDispose(void) {
|
errorret_t displayDispose(void) {
|
||||||
spriteBatchDispose();
|
errorChain(spriteBatchDispose());
|
||||||
screenDispose();
|
screenDispose();
|
||||||
textDispose();
|
errorChain(textDispose());
|
||||||
|
|
||||||
#ifdef displayPlatformDispose
|
#ifdef displayPlatformDispose
|
||||||
displayPlatformDispose();
|
displayPlatformDispose();
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ uint32_t frameBufferGetHeight(const framebuffer_t *framebuffer) {
|
|||||||
return frameBufferPlatformGetHeight(framebuffer);
|
return frameBufferPlatformGetHeight(framebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void frameBufferClear(const uint8_t flags, const color_t color) {
|
||||||
|
frameBufferPlatformClear(flags, color);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||||
errorret_t frameBufferInit(
|
errorret_t frameBufferInit(
|
||||||
framebuffer_t *fb,
|
framebuffer_t *fb,
|
||||||
|
|||||||
@@ -23,6 +23,9 @@
|
|||||||
#ifndef frameBufferPlatformGetHeight
|
#ifndef frameBufferPlatformGetHeight
|
||||||
#error "frameBufferPlatformGetHeight not defined for this platform"
|
#error "frameBufferPlatformGetHeight not defined for this platform"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef frameBufferPlatformClear
|
||||||
|
#error "frameBufferPlatformClear not defined for this platform"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define FRAMEBUFFER_CLEAR_COLOR (1 << 0)
|
#define FRAMEBUFFER_CLEAR_COLOR (1 << 0)
|
||||||
#define FRAMEBUFFER_CLEAR_DEPTH (1 << 1)
|
#define FRAMEBUFFER_CLEAR_DEPTH (1 << 1)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
screen_t SCREEN;
|
screen_t SCREEN;
|
||||||
|
|
||||||
void screenInit() {
|
errorret_t screenInit() {
|
||||||
memoryZero(&SCREEN, sizeof(screen_t));
|
memoryZero(&SCREEN, sizeof(screen_t));
|
||||||
|
|
||||||
SCREEN.background = COLOR_CORNFLOWER_BLUE;
|
SCREEN.background = COLOR_CORNFLOWER_BLUE;
|
||||||
@@ -27,24 +27,25 @@ void screenInit() {
|
|||||||
SCREEN.framebufferCamera._2d.position[1] = 0;
|
SCREEN.framebufferCamera._2d.position[1] = 0;
|
||||||
SCREEN.framebufferCamera._2d.zoom = 1.0f;
|
SCREEN.framebufferCamera._2d.zoom = 1.0f;
|
||||||
|
|
||||||
quadBuffer(
|
errorChain(quadBuffer(
|
||||||
SCREEN.frameBufferMeshVertices,
|
SCREEN.frameBufferMeshVertices,
|
||||||
0.0f, 0.0f,
|
0.0f, 0.0f,
|
||||||
1.0f, 1.0f,
|
1.0f, 1.0f,
|
||||||
COLOR_WHITE,
|
COLOR_WHITE,
|
||||||
0.0f, 0.0f,
|
0.0f, 0.0f,
|
||||||
1.0f, 1.0f
|
1.0f, 1.0f
|
||||||
);
|
));
|
||||||
meshInit(
|
errorChain(meshInit(
|
||||||
&SCREEN.frameBufferMesh,
|
&SCREEN.frameBufferMesh,
|
||||||
QUAD_PRIMITIVE_TYPE,
|
QUAD_PRIMITIVE_TYPE,
|
||||||
QUAD_VERTEX_COUNT,
|
QUAD_VERTEX_COUNT,
|
||||||
SCREEN.frameBufferMeshVertices
|
SCREEN.frameBufferMeshVertices
|
||||||
);
|
));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Init screen to backbuffer mode by default
|
// Init screen to backbuffer mode by default
|
||||||
screenBind();
|
screenBind();
|
||||||
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void screenBind() {
|
void screenBind() {
|
||||||
|
|||||||
@@ -83,8 +83,10 @@ extern screen_t SCREEN;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the screen system.
|
* Initializes the screen system.
|
||||||
|
*
|
||||||
|
* @return Error code and state, if error occurs.
|
||||||
*/
|
*/
|
||||||
void screenInit();
|
errorret_t screenInit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binds the screen, this is done before rendering game content.
|
* Binds the screen, this is done before rendering game content.
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ errorret_t spriteBatchFlush() {
|
|||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
textureBind(SPRITEBATCH.currentTexture);
|
errorChain(textureBind(SPRITEBATCH.currentTexture));
|
||||||
errorChain(meshDraw(
|
errorChain(meshDraw(
|
||||||
&SPRITEBATCH.mesh, 0, QUAD_VERTEX_COUNT * SPRITEBATCH.spriteCount
|
&SPRITEBATCH.mesh, 0, QUAD_VERTEX_COUNT * SPRITEBATCH.spriteCount
|
||||||
));
|
));
|
||||||
@@ -91,6 +91,7 @@ errorret_t spriteBatchFlush() {
|
|||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void spriteBatchDispose() {
|
errorret_t spriteBatchDispose() {
|
||||||
meshDispose(&SPRITEBATCH.mesh);
|
errorChain(meshDispose(&SPRITEBATCH.mesh));
|
||||||
|
errorOk();
|
||||||
}
|
}
|
||||||
@@ -103,5 +103,7 @@ errorret_t spriteBatchFlush();
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Disposes of the sprite batch, freeing any allocated resources.
|
* Disposes of the sprite batch, freeing any allocated resources.
|
||||||
|
*
|
||||||
|
* @return An error code indicating success or failure.
|
||||||
*/
|
*/
|
||||||
void spriteBatchDispose();
|
errorret_t spriteBatchDispose();
|
||||||
10
src/dusk/display/text/CMakeLists.txt
Normal file
10
src/dusk/display/text/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# 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
|
||||||
|
text.c
|
||||||
|
)
|
||||||
@@ -20,11 +20,12 @@ errorret_t textInit(void) {
|
|||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void textDispose(void) {
|
errorret_t textDispose(void) {
|
||||||
textureDispose(&DEFAULT_FONT_TEXTURE);
|
// errorChain(textureDispose(&DEFAULT_FONT_TEXTURE));
|
||||||
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void textDrawChar(
|
errorret_t textDrawChar(
|
||||||
const float_t x,
|
const float_t x,
|
||||||
const float_t y,
|
const float_t y,
|
||||||
const char_t c,
|
const char_t c,
|
||||||
@@ -44,18 +45,19 @@ void textDrawChar(
|
|||||||
vec4 uv;
|
vec4 uv;
|
||||||
tilesetTileGetUV(tileset, tileIndex, uv);
|
tilesetTileGetUV(tileset, tileIndex, uv);
|
||||||
|
|
||||||
spriteBatchPush(
|
errorChain(spriteBatchPush(
|
||||||
texture,
|
texture,
|
||||||
x, y,
|
x, y,
|
||||||
x + tileset->tileWidth,
|
x + tileset->tileWidth,
|
||||||
y + tileset->tileHeight,
|
y + tileset->tileHeight,
|
||||||
color,
|
color,
|
||||||
uv[0], uv[1], uv[2], uv[3]
|
uv[0], uv[1], uv[2], uv[3]
|
||||||
);
|
));
|
||||||
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void textDraw(
|
errorret_t textDraw(
|
||||||
const float_t x,
|
const float_t x,
|
||||||
const float_t y,
|
const float_t y,
|
||||||
const char_t *text,
|
const char_t *text,
|
||||||
@@ -82,9 +84,10 @@ void textDraw(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
textDrawChar(posX, posY, c, color, tileset, texture);
|
errorChain(textDrawChar(posX, posY, c, color, tileset, texture));
|
||||||
posX += tileset->tileWidth;
|
posX += tileset->tileWidth;
|
||||||
}
|
}
|
||||||
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void textMeasure(
|
void textMeasure(
|
||||||
@@ -17,13 +17,17 @@ extern tileset_t DEFAULT_FONT_TILESET;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the text system.
|
* Initializes the text system.
|
||||||
|
*
|
||||||
|
* @return Either an error or success result.
|
||||||
*/
|
*/
|
||||||
errorret_t textInit(void);
|
errorret_t textInit(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disposes of the text system.
|
* Disposes of the text system.
|
||||||
|
*
|
||||||
|
* @return Either an error or success result.
|
||||||
*/
|
*/
|
||||||
void textDispose(void);
|
errorret_t textDispose(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a single character at the specified position.
|
* Draws a single character at the specified position.
|
||||||
@@ -34,8 +38,9 @@ void textDispose(void);
|
|||||||
* @param color The color to draw the character in.
|
* @param color The color to draw the character in.
|
||||||
* @param tileset Font tileset to use for rendering.
|
* @param tileset Font tileset to use for rendering.
|
||||||
* @param texture Texture containing the font tileset image.
|
* @param texture Texture containing the font tileset image.
|
||||||
|
* @return Either an error or success result.
|
||||||
*/
|
*/
|
||||||
void textDrawChar(
|
errorret_t textDrawChar(
|
||||||
const float_t x,
|
const float_t x,
|
||||||
const float_t y,
|
const float_t y,
|
||||||
const char_t c,
|
const char_t c,
|
||||||
@@ -53,8 +58,9 @@ void textDrawChar(
|
|||||||
* @param color The color to draw the text in.
|
* @param color The color to draw the text in.
|
||||||
* @param tileset Font tileset to use for rendering.
|
* @param tileset Font tileset to use for rendering.
|
||||||
* @param texture Texture containing the font tileset image.
|
* @param texture Texture containing the font tileset image.
|
||||||
|
* @return Either an error or success result.
|
||||||
*/
|
*/
|
||||||
void textDraw(
|
errorret_t textDraw(
|
||||||
const float_t x,
|
const float_t x,
|
||||||
const float_t y,
|
const float_t y,
|
||||||
const char_t *text,
|
const char_t *text,
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "moduletext.h"
|
#include "moduletext.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "display/text.h"
|
#include "display/text/text.h"
|
||||||
#include "display/spritebatch/spritebatch.h"
|
#include "display/spritebatch/spritebatch.h"
|
||||||
|
|
||||||
void moduleText(scriptcontext_t *context) {
|
void moduleText(scriptcontext_t *context) {
|
||||||
@@ -48,7 +48,7 @@ int moduleTextDraw(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For now, use the default font tileset and texture.
|
// For now, use the default font tileset and texture.
|
||||||
textDraw(
|
errorret_t ret = textDraw(
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
text,
|
text,
|
||||||
@@ -56,7 +56,16 @@ int moduleTextDraw(lua_State *L) {
|
|||||||
&DEFAULT_FONT_TILESET,
|
&DEFAULT_FONT_TILESET,
|
||||||
&DEFAULT_FONT_TEXTURE
|
&DEFAULT_FONT_TEXTURE
|
||||||
);
|
);
|
||||||
spriteBatchFlush();
|
if(ret.code != ERROR_OK) {
|
||||||
|
errorCatch(errorPrint(ret));
|
||||||
|
luaL_error(L, "Failed to draw text");
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = spriteBatchFlush();
|
||||||
|
if(ret.code != ERROR_OK) {
|
||||||
|
errorCatch(errorPrint(ret));
|
||||||
|
luaL_error(L, "Failed to flush sprite batch after drawing text");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int moduleTextMeasure(lua_State *L) {
|
int moduleTextMeasure(lua_State *L) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ 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)
|
||||||
10
src/duskgl/display/camera/CMakeLists.txt
Normal file
10
src/duskgl/display/camera/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# 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
|
||||||
|
)
|
||||||
132
src/duskgl/display/camera/cameragl.c
Normal file
132
src/duskgl/display/camera/cameragl.c
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
/**
|
||||||
|
* 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/assert.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_copy(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);
|
||||||
|
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
glLoadMatrixf((const GLfloat*)view);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cameraPopMatrixGL(void) {
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
22
src/duskgl/display/camera/cameragl.h
Normal file
22
src/duskgl/display/camera/cameragl.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* 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);
|
||||||
12
src/duskgl/display/camera/cameraplatform.h
Normal file
12
src/duskgl/display/camera/cameraplatform.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* 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
|
||||||
@@ -75,7 +75,7 @@ errorret_t frameBufferGLBind(framebuffer_t *framebuffer) {
|
|||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void frameBufferClear(const uint8_t flags, const color_t color) {
|
void frameBufferGLClear(const uint8_t flags, const color_t color) {
|
||||||
GLbitfield glFlags = 0;
|
GLbitfield glFlags = 0;
|
||||||
|
|
||||||
if(flags & FRAMEBUFFER_CLEAR_COLOR) {
|
if(flags & FRAMEBUFFER_CLEAR_COLOR) {
|
||||||
|
|||||||
@@ -45,6 +45,14 @@ uint32_t frameBufferGLGetHeight(const framebuffergl_t *framebuffer);
|
|||||||
*/
|
*/
|
||||||
errorret_t frameBufferGLBind(framebuffergl_t *framebuffer);
|
errorret_t frameBufferGLBind(framebuffergl_t *framebuffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the framebuffer with the specified flags and color.
|
||||||
|
*
|
||||||
|
* @param flags The clear flags.
|
||||||
|
* @param color The clear color.
|
||||||
|
*/
|
||||||
|
void frameBufferGLClear(const uint8_t flags, const color_t color);
|
||||||
|
|
||||||
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||||
/**
|
/**
|
||||||
* Initializes an OpenGL style framebuffer.
|
* Initializes an OpenGL style framebuffer.
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ typedef framebuffergl_t framebufferplatform_t;
|
|||||||
#define frameBufferPlatformGetWidth frameBufferGLGetWidth
|
#define frameBufferPlatformGetWidth frameBufferGLGetWidth
|
||||||
#define frameBufferPlatformGetHeight frameBufferGLGetHeight
|
#define frameBufferPlatformGetHeight frameBufferGLGetHeight
|
||||||
#define frameBufferPlatformBind frameBufferGLBind
|
#define frameBufferPlatformBind frameBufferGLBind
|
||||||
|
#define frameBufferPlatformClear frameBufferGLClear
|
||||||
|
|
||||||
#if DUSK_DISPLAY_SIZE_DYNAMIC
|
#if DUSK_DISPLAY_SIZE_DYNAMIC
|
||||||
#define frameBufferPlatformInit frameBufferGLInit
|
#define frameBufferPlatformInit frameBufferGLInit
|
||||||
|
|||||||
Reference in New Issue
Block a user