Dolphin shaders
Some checks failed
Build Dusk / run-tests (pull_request) Failing after 13s
Build Dusk / build-linux (pull_request) Failing after 18s
Build Dusk / build-psp (pull_request) Failing after 18s
Build Dusk / build-gamecube (pull_request) Failing after 16s
Build Dusk / build-wii (pull_request) Failing after 13s
Some checks failed
Build Dusk / run-tests (pull_request) Failing after 13s
Build Dusk / build-linux (pull_request) Failing after 18s
Build Dusk / build-psp (pull_request) Failing after 18s
Build Dusk / build-gamecube (pull_request) Failing after 16s
Build Dusk / build-wii (pull_request) Failing after 13s
This commit is contained in:
@@ -5,7 +5,159 @@
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "shadergl.h"
|
||||
#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];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user