shader #2

Merged
YourWishes merged 2 commits from shader into main 2026-03-23 04:33:20 +00:00
10 changed files with 320 additions and 9 deletions

View File

@@ -29,7 +29,6 @@ target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC
DUSK_SDL2
DUSK_OPENGL
DUSK_LINUX
DUSK_OPENGL_LEGACY
DUSK_DISPLAY_SIZE_DYNAMIC
DUSK_DISPLAY_WIDTH_DEFAULT=640
DUSK_DISPLAY_HEIGHT_DEFAULT=480

View File

@@ -56,7 +56,7 @@ void cameraGetProjectionMatrix(camera_t *camera, mat4 dest) {
glm_mat4_identity(dest);
glm_perspective(
camera->perspective.fov,
SCREEN.aspect,
(640.0f / 480.0f),
camera->nearClip,
camera->farClip,
dest

View File

@@ -58,11 +58,15 @@ errorret_t displayUpdate(void) {
errorChain(shaderBind(&SHADER_UNLIT));
camera_t camera;
cameraInitOrthographic(&camera);
camera.orthographic.left = 0.0f;
camera.orthographic.right = SCREEN.width;
camera.orthographic.top = SCREEN.height;
camera.orthographic.bottom = 0.0f;
// cameraInitOrthographic(&camera);
// camera.orthographic.left = 0.0f;
// camera.orthographic.right = SCREEN.width;
// camera.orthographic.top = SCREEN.height;
// camera.orthographic.bottom = 0.0f;
cameraInitPerspective(&camera);
camera.lookat.position[0] = 10.0f;
camera.lookat.position[1] = 10.0f;
camera.lookat.position[2] = 10.0f;
mat4 proj, view, model;
cameraGetProjectionMatrix(&camera, proj);
@@ -75,7 +79,7 @@ errorret_t displayUpdate(void) {
errorChain(spriteBatchPush(
NULL,
TIME.time * 2.0f, TIME.time * 3.0f, 100, 100, COLOR_WHITE, 0, 0, 1, 1
0.0f, 0.0f, 100, 100, COLOR_WHITE, 0, 0, 1, 1
));
errorChain(spriteBatchFlush());

View File

@@ -14,4 +14,5 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
add_subdirectory(camera)
add_subdirectory(framebuffer)
add_subdirectory(mesh)
add_subdirectory(texture)
add_subdirectory(texture)
add_subdirectory(shader)

View File

@@ -8,6 +8,7 @@
#include "display/mesh/mesh.h"
#include "display/texture/texture.h"
#include "assert/assert.h"
#include "display/shader/shader.h"
errorret_t meshInitDolphin(
meshdolphin_t *mesh,
@@ -53,6 +54,9 @@ errorret_t meshDrawDolphin(
sizeof(meshvertex_t) * vertexCount
);
// Update matrix.
errorChain(shaderUpdateMVPDolphin());
const uint8_t stride = (uint8_t)sizeof(meshvertex_t);
GX_SetArray(GX_VA_POS, (void*)&mesh->vertices[vertexOffset].pos[0], stride);
GX_SetArray(GX_VA_CLR0, (void*)&mesh->vertices[vertexOffset].color.r, stride);

View File

@@ -0,0 +1,11 @@
# 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
shaderdolphin.c
shaderunlitdolphin.c
)

View File

@@ -0,0 +1,163 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "util/memory.h"
#include "util/string.h"
#include "display/shader/shaderunlit.h"
#include "assert/assert.h"
#include "log/log.h"
shaderdolphin_t *SHADER_BOUND;
errorret_t shaderInitDolphin(
shaderdolphin_t *shader,
const shaderdefinitiondolphin_t *def
) {
assertNotNull(shader, "Shader must not be null");
assertNotNull(def, "Shader definition must not be null");
memoryZero(shader, sizeof(shaderdolphin_t));
glm_mat4_identity(shader->view);
glm_mat4_identity(shader->proj);
glm_mat4_identity(shader->model);
shader->dirtyMatrix = (
SHADER_DOLPHIN_DIRTY_MODEL |
SHADER_DOLPHIN_DIRTY_PROJ |
SHADER_DOLPHIN_DIRTY_VIEW
);
errorOk();
}
errorret_t shaderBindDolphin(shaderdolphin_t *shader) {
assertNotNull(shader, "Shader must not be null");
SHADER_BOUND = shader;
GX_LoadProjectionMtx(
shader->matrixProjection,
shader->isProjectionPerspective ? GX_PERSPECTIVE : GX_ORTHOGRAPHIC
);
GX_LoadPosMtxImm(shader->matrixModelView, GX_PNMTX0);
errorOk();
}
errorret_t shaderSetMatrixDolphin(
shaderdolphin_t *shader,
const char_t *name,
mat4 mat
) {
assertNotNull(shader, "Shader must not be null");
assertNotNull(name, "Uniform name must not be null");
assertStrLenMin(name, 1, "Uniform name cannot be empty");
if(stringCompare(name, SHADER_UNLIT_PROJECTION) == 0) {
shader->dirtyMatrix |= SHADER_DOLPHIN_DIRTY_PROJ;
glm_mat4_copy(mat, shader->proj);
} else if(stringCompare(name, SHADER_UNLIT_VIEW) == 0) {
shader->dirtyMatrix |= SHADER_DOLPHIN_DIRTY_VIEW;
glm_mat4_copy(mat, shader->view);
} else if(stringCompare(name, SHADER_UNLIT_MODEL) == 0) {
shader->dirtyMatrix |= SHADER_DOLPHIN_DIRTY_MODEL;
glm_mat4_copy(mat, shader->model);
} else {
assertUnreachable("Cannot use a custom matrix on dolphin.");
}
errorOk();
}
errorret_t shaderDisposeDolphin(shaderdolphin_t *shader) {
assertNotNull(shader, "Shader must not be null");
SHADER_BOUND = NULL;
errorOk();
}
errorret_t shaderUpdateMVPDolphin() {
assertNotNull(SHADER_BOUND, "Shader must not be null");
// Any changes?
if(SHADER_BOUND->dirtyMatrix == 0) errorOk();
// Need to update projection?
if((SHADER_BOUND->dirtyMatrix & SHADER_DOLPHIN_DIRTY_PROJ) != 0) {
shaderMat4ToMtx44(SHADER_BOUND->proj, SHADER_BOUND->matrixProjection);
// Fix projection Z mapping between GLM and GX.
float A = SHADER_BOUND->matrixProjection[2][2];
float B = SHADER_BOUND->matrixProjection[2][3];
SHADER_BOUND->matrixProjection[2][2] = 0.5f * (A + 1.0f);
SHADER_BOUND->matrixProjection[2][3] = 0.5f * B;
// Is this perspective or ortho originally? Dolphin cares for some reason.
const float_t epsilon = 0.0001f;
SHADER_BOUND->isProjectionPerspective = (
fabsf(SHADER_BOUND->proj[3][2]) > epsilon &&
fabsf(SHADER_BOUND->proj[3][3]) < epsilon
);
GX_LoadProjectionMtx(
SHADER_BOUND->matrixProjection,
SHADER_BOUND->isProjectionPerspective ? GX_PERSPECTIVE : GX_ORTHOGRAPHIC
);
}
// Need to update view or model?
bool_t mvDirt = false;
if((SHADER_BOUND->dirtyMatrix & SHADER_DOLPHIN_DIRTY_VIEW) != 0) {
shaderMat4ToMtx(SHADER_BOUND->view, SHADER_BOUND->matrixView);
mvDirt = true;
}
if((SHADER_BOUND->dirtyMatrix & SHADER_DOLPHIN_DIRTY_MODEL) != 0) {
shaderMat4ToMtx(SHADER_BOUND->model, SHADER_BOUND->matrixModel);
mvDirt = true;
}
// Set Model/View Matrix
if(mvDirt) {
guMtxConcat(
SHADER_BOUND->matrixView,
SHADER_BOUND->matrixModel,
SHADER_BOUND->matrixModelView
);
GX_LoadPosMtxImm(SHADER_BOUND->matrixModelView, GX_PNMTX0);
}
SHADER_BOUND->dirtyMatrix = 0;
errorOk();
}
void shaderMat4ToMtx44(const mat4 inGlmMatrix, Mtx44 outGXMatrix) {
assertNotNull(inGlmMatrix, "Input matrix cannot be null");
assertNotNull(outGXMatrix, "Output matrix cannot be null");
for(int row = 0; row < 4; ++row) {
for(int col = 0; col < 4; ++col) {
outGXMatrix[row][col] = inGlmMatrix[col][row];
}
}
}
void shaderMat4ToMtx(const mat4 inGlmMatrix, Mtx outGXMatrix) {
assertNotNull(inGlmMatrix, "Input matrix cannot be null");
assertNotNull(outGXMatrix, "Output matrix cannot be null");
for(int row = 0; row < 3; ++row) {
for(int col = 0; col < 4; ++col) {
outGXMatrix[row][col] = inGlmMatrix[col][row];
}
}
}

View File

@@ -0,0 +1,99 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
typedef struct {
mat4 view;
mat4 proj;
mat4 model;
bool_t isProjectionPerspective;
Mtx44 matrixProjection;
Mtx matrixView;
Mtx matrixModel;
Mtx matrixModelView;
uint_fast8_t dirtyMatrix;
} shaderdolphin_t;
typedef struct {
void *empty;
} shaderdefinitiondolphin_t;
#define SHADER_DOLPHIN_DIRTY_MODEL (1 << 0)
#define SHADER_DOLPHIN_DIRTY_PROJ (1 << 1)
#define SHADER_DOLPHIN_DIRTY_VIEW (1 << 2)
extern shaderdolphin_t *SHADER_BOUND;
/**
* Initializes a dolphin shader. Basically a render parameter pipeline.
*
* @param shader Shader to initialize.
* @param def Definition of the shader to initialize with.
* @return Error code if failure.
*/
errorret_t shaderInitDolphin(
shaderdolphin_t *shader,
const shaderdefinitiondolphin_t *def
);
/**
* Binds a dolphin shader. Basically sets the render parameters for rendering.
*
* @param shader Shader to bind.
* @return Error code if failure.
*/
errorret_t shaderBindDolphin(shaderdolphin_t *shader);
/**
* Sets a matrix uniform in the dolphin shader. Basically does nothing.
*
* @param shader Shader to set the matrix in.
* @param name Name of the uniform to set.
* @param matrix Matrix to set.
* @return Error code if failure.
*/
errorret_t shaderSetMatrixDolphin(
shaderdolphin_t *shader,
const char_t *name,
mat4 matrix
);
/**
* Disposes a dolphin shader. Basically does nothing.
*
* @param shader Shader to dispose.
* @return Error code if failure.
*/
errorret_t shaderDisposeDolphin(shaderdolphin_t *shader);
/**
* Internal Dolphin method, called right before a draw call to perform a matrix
* update and recalc.
*
* @return Error code if failure.
*/
errorret_t shaderUpdateMVPDolphin();
/**
* Converts a glm style column major mat4 to a GX compatible row major Mtx44.
*
* @param in Matrix to convert.
* @param out Output converted matrix.
*/
void shaderMat4ToMtx44(const mat4 in, Mtx44 out);
/**
* Converts a glm style column major mat4 to a GX compatible row major Mtx.
*
* @param inGlmMatrix Matrix to convert.
* @param outGXMatrix Output converted matrix.
*/
void shaderMat4ToMtx(const mat4 inGlmMatrix, Mtx outGXMatrix);

View File

@@ -0,0 +1,18 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "shaderdolphin.h"
typedef shaderdolphin_t shaderplatform_t;
typedef shaderdefinitiondolphin_t shaderdefinitionplatform_t;
#define shaderInitPlatform shaderInitDolphin
#define shaderBindPlatform shaderBindDolphin
#define shaderSetMatrixPlatform shaderSetMatrixDolphin
// #define shaderSetTexturePlatform shaderSetTextureDolphin
#define shaderDisposePlatform shaderDisposeDolphin

View File

@@ -0,0 +1,12 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "display/shader/shaderunlit.h"
shaderdefinition_t SHADER_UNLIT_DEFINITION = {
0
};