Shaders adapted for Legacy GL
Some checks failed
Build Dusk / run-tests (pull_request) Failing after 24s
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 15s
Build Dusk / build-wii (pull_request) Failing after 16s

This commit is contained in:
2026-03-22 10:44:28 -05:00
parent ca0e9fc3b2
commit 5ac21db997
9 changed files with 184 additions and 61 deletions

View File

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

View File

@@ -23,7 +23,7 @@ errorret_t shaderBind(shader_t *shader) {
errorret_t shaderSetMatrix( errorret_t shaderSetMatrix(
shader_t *shader, shader_t *shader,
const char_t *name, const char_t *name,
const mat4 matrix mat4 matrix
) { ) {
assertNotNull(shader, "Shader cannot be null"); assertNotNull(shader, "Shader cannot be null");
assertStrLenMin(name, 1, "Uniform name cannot be empty"); assertStrLenMin(name, 1, "Uniform name cannot be empty");

View File

@@ -54,7 +54,7 @@ errorret_t shaderBind(shader_t *shader);
errorret_t shaderSetMatrix( errorret_t shaderSetMatrix(
shader_t *shader, shader_t *shader,
const char_t *name, const char_t *name,
const mat4 matrix mat4 matrix
); );
/** /**

View File

@@ -8,8 +8,6 @@
#include "displaygl.h" #include "displaygl.h"
errorret_t displayOpenGLInit(void) { errorret_t displayOpenGLInit(void) {
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
// glDisable(GL_LIGHTING);// PSP defaults this on? // glDisable(GL_LIGHTING);// PSP defaults this on?
// glShadeModel(GL_SMOOTH); // Fixes color on PSP? // glShadeModel(GL_SMOOTH); // Fixes color on PSP?
@@ -26,10 +24,5 @@ errorret_t displayOpenGLInit(void) {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
errorChain(errorGLCheck()); errorChain(errorGLCheck());
// glEnableClientState(GL_COLOR_ARRAY);// To confirm: every frame on PSP?
// glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// glEnableClientState(GL_VERTEX_ARRAY);
// errorChain(errorGLCheck());
errorOk(); errorOk();
} }

View File

@@ -8,6 +8,7 @@
#include "display/mesh/mesh.h" #include "display/mesh/mesh.h"
#include "assert/assertgl.h" #include "assert/assertgl.h"
#include "error/errorgl.h" #include "error/errorgl.h"
#include "display/shader/shadergl.h"
errorret_t meshInitGL( errorret_t meshInitGL(
meshgl_t *mesh, meshgl_t *mesh,
@@ -25,6 +26,10 @@ errorret_t meshInitGL(
#ifdef DUSK_OPENGL_LEGACY #ifdef DUSK_OPENGL_LEGACY
// Nothing needed. // Nothing needed.
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
errorChain(errorGLCheck());
#else #else
// Generate Vertex Buffer Object // Generate Vertex Buffer Object
glGenBuffers(1, &mesh->vboId); glGenBuffers(1, &mesh->vboId);
@@ -143,6 +148,11 @@ errorret_t meshDrawGL(
(const GLvoid*)&mesh->vertices[offset].pos (const GLvoid*)&mesh->vertices[offset].pos
); );
// Shader may have model matrix here
#ifdef DUSK_OPENGL_LEGACY
errorChain(shaderLegacyMatrixUpdate());
#endif
glDrawArrays(mesh->primitiveType, offset, count); glDrawArrays(mesh->primitiveType, offset, count);
errorChain(errorGLCheck()); errorChain(errorGLCheck());
#else #else

View File

@@ -7,7 +7,13 @@
#include "shadergl.h" #include "shadergl.h"
#include "util/memory.h" #include "util/memory.h"
#include "util/string.h"
#include "assert/assertgl.h" #include "assert/assertgl.h"
#include "display/shader/shaderunlit.h"
#ifdef DUSK_OPENGL_LEGACY
shaderlegacygl_t SHADER_LEGACY = { 0 };
#endif
errorret_t shaderInitGL(shadergl_t *shader, const shaderdefinitiongl_t *def) { errorret_t shaderInitGL(shadergl_t *shader, const shaderdefinitiongl_t *def) {
assertNotNull(shader, "Shader cannot be null"); assertNotNull(shader, "Shader cannot be null");
@@ -15,7 +21,11 @@ errorret_t shaderInitGL(shadergl_t *shader, const shaderdefinitiongl_t *def) {
memoryZero(shader, sizeof(shadergl_t)); memoryZero(shader, sizeof(shadergl_t));
#ifdef DUSK_OPENGL_LEGACY #ifdef DUSK_OPENGL_LEGACY
// No initialization needed for legacy shader glm_mat4_identity(shader->view);
glm_mat4_identity(shader->proj);
glm_mat4_identity(shader->model);
SHADER_LEGACY.boundShader = NULL;
errorOk(); errorOk();
#else #else
// Create vertex shader // Create vertex shader
@@ -139,12 +149,16 @@ errorret_t shaderParamGetLocationGL(
assertStrLenMin(name, 1, "Uniform name cannot be empty"); assertStrLenMin(name, 1, "Uniform name cannot be empty");
assertNotNull(location, "Location cannot be null"); assertNotNull(location, "Location cannot be null");
shadergl_t *shaderGL = (shadergl_t *)shader; #ifdef DUSK_OPENGL_LEGACY
*location = glGetUniformLocation(shaderGL->shaderProgramId, name); assertUnreachable("Cannot get uniform locations on legacy opengl.");
errorret_t err = errorGLCheck(); #else
if(err.code != ERROR_OK) { shadergl_t *shaderGL = (shadergl_t *)shader;
errorChain(err); *location = glGetUniformLocation(shaderGL->shaderProgramId, name);
} errorret_t err = errorGLCheck();
if(err.code != ERROR_OK) {
errorChain(err);
}
#endif
errorOk(); errorOk();
} }
@@ -152,27 +166,58 @@ errorret_t shaderParamGetLocationGL(
errorret_t shaderSetMatrixGL( errorret_t shaderSetMatrixGL(
shadergl_t *shader, shadergl_t *shader,
const char_t *name, const char_t *name,
const mat4 mat mat4 mat
) { ) {
assertNotNull(shader, "Shader cannot be null"); assertNotNull(shader, "Shader cannot be null");
assertNotNull(mat, "Matrix data cannot be null"); assertNotNull(mat, "Matrix data cannot be null");
assertStrLenMin(name, 1, "Uniform name cannot be empty"); assertStrLenMin(name, 1, "Uniform name cannot be empty");
GLint location; #ifdef DUSK_OPENGL_LEGACY
errorChain(shaderParamGetLocationGL(shader, name, &location)); assertTrue(
SHADER_LEGACY.boundShader == shader,
"Shader must be bound to set legacy matrices."
);
if(stringCompare(name, SHADER_UNLIT_PROJECTION) == 0) {
SHADER_LEGACY.dirty |= SHADER_LEGACY_DIRTY_PROJ;
glm_mat4_copy(mat, shader->proj);
glUniformMatrix4fv(location, 1, GL_FALSE, (const GLfloat *)mat); } else if(stringCompare(name, SHADER_UNLIT_VIEW) == 0) {
errorChain(errorGLCheck()); SHADER_LEGACY.dirty |= SHADER_LEGACY_DIRTY_VIEW;
glm_mat4_copy(mat, shader->view);
} else if(stringCompare(name, SHADER_UNLIT_MODEL) == 0) {
SHADER_LEGACY.dirty |= SHADER_LEGACY_DIRTY_MODEL;
glm_mat4_copy(mat, shader->model);
} else {
assertUnreachable("Cannot use a custom matrix on legacy opengl.");
}
#else
GLint location;
errorChain(shaderParamGetLocationGL(shader, name, &location));
glUniformMatrix4fv(location, 1, GL_FALSE, (const GLfloat *)mat);
errorChain(errorGLCheck());
#endif
errorOk(); errorOk();
} }
errorret_t shaderBindGL(shadergl_t *shader) { errorret_t shaderBindGL(shadergl_t *shader) {
assertNotNull(shader, "Shader cannot be null"); #ifdef DUSK_OPENGL_LEGACY
assertNotNull(shader, "Cannot bind a null shader.");
glUseProgram(shader->shaderProgramId); SHADER_LEGACY.boundShader = shader;
errorChain(errorGLCheck()); SHADER_LEGACY.dirty = (
SHADER_LEGACY_DIRTY_MODEL |
SHADER_LEGACY_DIRTY_PROJ |
SHADER_LEGACY_DIRTY_VIEW
);
#else
assertNotNull(shader, "Shader cannot be null");
glUseProgram(shader->shaderProgramId);
errorChain(errorGLCheck());
#endif
errorOk(); errorOk();
} }
@@ -180,22 +225,58 @@ errorret_t shaderBindGL(shadergl_t *shader) {
errorret_t shaderDisposeGL(shadergl_t *shader) { errorret_t shaderDisposeGL(shadergl_t *shader) {
assertNotNull(shader, "Shader cannot be null"); assertNotNull(shader, "Shader cannot be null");
if(shader->shaderProgramId != 0) { #ifdef DUSK_OPENGL_LEGACY
glDeleteProgram(shader->shaderProgramId); SHADER_LEGACY.boundShader = NULL;
errorChain(errorGLCheck()); #else
} if(shader->shaderProgramId != 0) {
glDeleteProgram(shader->shaderProgramId);
if(shader->vertexShaderId != 0) { }
glDeleteShader(shader->vertexShaderId);
errorChain(errorGLCheck()); if(shader->vertexShaderId != 0) {
} glDeleteShader(shader->vertexShaderId);
}
if(shader->fragmentShaderId != 0) { if(shader->fragmentShaderId != 0) {
glDeleteShader(shader->fragmentShaderId); glDeleteShader(shader->fragmentShaderId);
errorChain(errorGLCheck()); }
}
assertNoGLError("Failed disposing shader");
#endif
assertNoGLError("Failed disposing shader");
memoryZero(shader, sizeof(shadergl_t)); memoryZero(shader, sizeof(shadergl_t));
errorOk(); errorOk();
} }
#ifdef DUSK_OPENGL_LEGACY
errorret_t shaderLegacyMatrixUpdate() {
assertNotNull(SHADER_LEGACY.boundShader, "No shader is currently bound.");
if((SHADER_LEGACY.dirty & SHADER_LEGACY_DIRTY_PROJ) != 0) {
glMatrixMode(GL_PROJECTION);
errorChain(errorGLCheck());
glLoadIdentity();
errorChain(errorGLCheck());
glMultMatrixf((const GLfloat *)SHADER_LEGACY.boundShader->proj);
errorChain(errorGLCheck());
}
if((SHADER_LEGACY.dirty & SHADER_LEGACY_DIRTY_VIEW) != 0) {
glMatrixMode(GL_MODELVIEW);
errorChain(errorGLCheck());
glLoadIdentity();
errorChain(errorGLCheck());
glMultMatrixf((const GLfloat *)SHADER_LEGACY.boundShader->view);
errorChain(errorGLCheck());
}
if((SHADER_LEGACY.dirty & SHADER_LEGACY_DIRTY_MODEL) != 0) {
glMatrixMode(GL_MODELVIEW);
errorChain(errorGLCheck());
glMultMatrixf((const GLfloat *)SHADER_LEGACY.boundShader->model);
errorChain(errorGLCheck());
}
SHADER_LEGACY.dirty = 0;
errorOk();
}
#endif

View File

@@ -16,6 +16,12 @@ typedef struct {
GLuint vertexShaderId; GLuint vertexShaderId;
GLuint fragmentShaderId; GLuint fragmentShaderId;
#endif #endif
#if DUSK_OPENGL_LEGACY
mat4 view;
mat4 proj;
mat4 model;
#endif
} shadergl_t; } shadergl_t;
typedef struct { typedef struct {
@@ -27,6 +33,19 @@ typedef struct {
#endif #endif
} shaderdefinitiongl_t; } shaderdefinitiongl_t;
#if DUSK_OPENGL_LEGACY
typedef struct {
shadergl_t *boundShader;
uint_fast8_t dirty;
} shaderlegacygl_t;
extern shaderlegacygl_t SHADER_LEGACY;
#define SHADER_LEGACY_DIRTY_PROJ (1 << 0)
#define SHADER_LEGACY_DIRTY_VIEW (1 << 1)
#define SHADER_LEGACY_DIRTY_MODEL (1 << 2)
#endif
/** /**
* Initializes a shader. * Initializes a shader.
* *
@@ -69,7 +88,7 @@ errorret_t shaderParamGetLocationGL(
errorret_t shaderSetMatrixGL( errorret_t shaderSetMatrixGL(
shadergl_t *shader, shadergl_t *shader,
const char_t *name, const char_t *name,
const mat4 matrix mat4 matrix
); );
/** /**
@@ -77,4 +96,14 @@ errorret_t shaderSetMatrixGL(
* *
* @param shader The shader to dispose. * @param shader The shader to dispose.
*/ */
errorret_t shaderDisposeGL(shadergl_t *shader); errorret_t shaderDisposeGL(shadergl_t *shader);
#ifdef DUSK_OPENGL_LEGACY
/**
* During mesh rendering, this is requesting the legacy system to push all
* shaders necessary to render the currently bound shader's matrices.
*
* @return Any error state.
*/
errorret_t shaderLegacyMatrixUpdate();
#endif

View File

@@ -7,21 +7,25 @@
#include "display/shader/shaderunlit.h" #include "display/shader/shaderunlit.h"
shaderdefinition_t SHADER_UNLIT_DEFINITION = { #ifdef DUSK_OPENGL_LEGACY
.vert = shaderdefinition_t SHADER_UNLIT_DEFINITION = { 0 };
"#version 330 core\n" #else
"layout(location = 0) in vec3 aPos;\n" shaderdefinition_t SHADER_UNLIT_DEFINITION = {
"uniform mat4 u_Proj;\n" .vert =
"uniform mat4 u_View;\n" "#version 330 core\n"
"uniform mat4 u_Model;\n" "layout(location = 0) in vec3 aPos;\n"
"void main() {\n" "uniform mat4 u_Proj;\n"
" gl_Position = u_Proj * u_View * u_Model * vec4(aPos, 1.0);\n" "uniform mat4 u_View;\n"
"}\n", "uniform mat4 u_Model;\n"
"void main() {\n"
" gl_Position = u_Proj * u_View * u_Model * vec4(aPos, 1.0);\n"
"}\n",
.frag = .frag =
"#version 330 core\n" "#version 330 core\n"
"out vec4 FragColor;\n" "out vec4 FragColor;\n"
"void main() {\n" "void main() {\n"
" FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" " FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n" "}\n"
}; };
#endif

View File

@@ -23,9 +23,14 @@ errorret_t displaySDL2Init(void) {
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
// SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); // SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
// SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); // SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); #ifdef DUSK_OPENGL_LEGACY
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
#else
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
#endif
// Create window with OpenGL flag. // Create window with OpenGL flag.
DISPLAY.window = SDL_CreateWindow( DISPLAY.window = SDL_CreateWindow(