From 66ebcb1608ebfd96d902a10eac96b79eb82cc818 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Tue, 17 Mar 2026 17:05:39 -0500 Subject: [PATCH] shader prog --- cmake/targets/linux.cmake | 1 - cmake/targets/psp.cmake | 1 + src/dusk/display/display.c | 70 +++++++- src/dusk/display/shader/shaderunlit.h | 3 +- src/duskgl/display/displaygl.c | 4 +- src/duskgl/display/displaygl.h | 3 - src/duskgl/display/mesh/meshgl.c | 132 ++++++++++++--- src/duskgl/display/mesh/meshgl.h | 8 +- src/duskgl/display/shader/shadergl.c | 196 +++++++++++----------- src/duskgl/display/shader/shadergl.h | 18 +- src/duskgl/display/shader/shaderunlitgl.c | 7 +- 11 files changed, 303 insertions(+), 140 deletions(-) diff --git a/cmake/targets/linux.cmake b/cmake/targets/linux.cmake index 3bc994a..f83d136 100644 --- a/cmake/targets/linux.cmake +++ b/cmake/targets/linux.cmake @@ -30,7 +30,6 @@ target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC DUSK_OPENGL DUSK_LINUX DUSK_DISPLAY_SIZE_DYNAMIC - DUSK_OPENGL_SHADER DUSK_DISPLAY_WIDTH_DEFAULT=640 DUSK_DISPLAY_HEIGHT_DEFAULT=480 DUSK_DISPLAY_SCREEN_HEIGHT=240 diff --git a/cmake/targets/psp.cmake b/cmake/targets/psp.cmake index e58dd80..4f3a6b0 100644 --- a/cmake/targets/psp.cmake +++ b/cmake/targets/psp.cmake @@ -36,6 +36,7 @@ target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC DUSK_PSP DUSK_INPUT_GAMEPAD DUSK_PLATFORM_ENDIAN_LITTLE + DUSK_OPENGL_LEGACY DUSK_DISPLAY_WIDTH=480 DUSK_DISPLAY_HEIGHT=272 ) diff --git a/src/dusk/display/display.c b/src/dusk/display/display.c index 50860ff..e72cae2 100644 --- a/src/dusk/display/display.c +++ b/src/dusk/display/display.c @@ -17,6 +17,8 @@ #include "util/memory.h" #include "util/string.h" #include "asset/asset.h" +#include "display/shader/shaderunlit.h" +#include "time/time.h" display_t DISPLAY = { 0 }; @@ -27,6 +29,7 @@ errorret_t displayInit(void) { errorChain(displayPlatformInit()); #endif + errorChain(shaderInit(&SHADER_UNLIT, &SHADER_UNLIT_DEFINITION)); errorChain(quadInit()); errorChain(frameBufferInitBackBuffer()); errorChain(spriteBatchInit()); @@ -52,7 +55,71 @@ errorret_t displayUpdate(void) { SCREEN.background ); - errorCatch(errorPrint(sceneRender())); + errorChain(shaderBind(&SHADER_UNLIT)); + + mat4 proj; + glm_mat4_identity(proj); + glm_ortho(0.0f, (float_t)SCREEN.width, (float_t)SCREEN.height, 0.0f, -1.0f, 1.0f, proj); + + mat4 view; + glm_mat4_identity(view); + + mat4 model; + glm_mat4_identity(model); + glm_translate(model, (vec3){ + sinf(TIME.time * 10.0f) * 30.0f + 100.0f, + cosf(TIME.time * 10.0f) * 50.0f + 100.0f, + 0.0f + }); + + 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 verts[6] = { + { + .pos = { 0.0f, 0.0f, 0.0f }, + .uv = { 0.0f, 0.0f }, + .color = COLOR_WHITE + }, + + { + .pos = { 100.0f, 0.0f, 0.0f }, + .uv = { 1.0f, 0.0f }, + .color = COLOR_WHITE + }, + + { + .pos = { 100.0f, 100.0f, 0.0f }, + .uv = { 1.0f, 1.0f }, + .color = COLOR_WHITE + }, + + { + .pos = { 100.0f, 100.0f, 0.0f }, + .uv = { 1.0f, 1.0f }, + .color = COLOR_WHITE + }, + + { + .pos = { 0.0f, 100.0f, 0.0f }, + .uv = { 0.0f, 1.0f }, + .color = COLOR_WHITE + }, + + { + .pos = { 0.0f, 0.0f, 0.0f }, + .uv = { 0.0f, 0.0f }, + .color = COLOR_WHITE + } + }; + + mesh_t mesh; + meshInit(&mesh, MESH_PRIMITIVE_TYPE_TRIANGLES, 6, verts); + meshDraw(&mesh, 0, -1); + meshDispose(&mesh); + + // errorCatch(errorPrint(sceneRender())); // Render UI // uiRender(); @@ -69,6 +136,7 @@ errorret_t displayUpdate(void) { } errorret_t displayDispose(void) { + errorChain(shaderDispose(&SHADER_UNLIT)); errorChain(spriteBatchDispose()); screenDispose(); errorChain(textDispose()); diff --git a/src/dusk/display/shader/shaderunlit.h b/src/dusk/display/shader/shaderunlit.h index 15b4f42..881a695 100644 --- a/src/dusk/display/shader/shaderunlit.h +++ b/src/dusk/display/shader/shaderunlit.h @@ -12,4 +12,5 @@ #define SHADER_UNLIT_VIEW "u_View" #define SHADER_UNLIT_MODEL "u_Model" -extern shaderdefinition_t SHADER_UNLIT_DEFINITION; \ No newline at end of file +extern shaderdefinition_t SHADER_UNLIT_DEFINITION; +static shader_t SHADER_UNLIT; \ No newline at end of file diff --git a/src/duskgl/display/displaygl.c b/src/duskgl/display/displaygl.c index 212a571..0affce3 100644 --- a/src/duskgl/display/displaygl.c +++ b/src/duskgl/display/displaygl.c @@ -8,6 +8,8 @@ #include "displaygl.h" errorret_t displayOpenGLInit(void) { + + glDisable(GL_CULL_FACE); // glDisable(GL_LIGHTING);// PSP defaults this on? // glShadeModel(GL_SMOOTH); // Fixes color on PSP? @@ -29,7 +31,5 @@ errorret_t displayOpenGLInit(void) { // glEnableClientState(GL_VERTEX_ARRAY); // errorChain(errorGLCheck()); - errorChain(shaderInit(&testShader, &SHADER_UNLIT_DEFINITION)); - errorOk(); } \ No newline at end of file diff --git a/src/duskgl/display/displaygl.h b/src/duskgl/display/displaygl.h index da3a118..2944f22 100644 --- a/src/duskgl/display/displaygl.h +++ b/src/duskgl/display/displaygl.h @@ -7,9 +7,6 @@ #pragma once #include "error/errorgl.h" -#include "display/shader/shaderunlit.h" - -static shadergl_t testShader; /** * Initializes the OpenGL specific contexts for rendering. diff --git a/src/duskgl/display/mesh/meshgl.c b/src/duskgl/display/mesh/meshgl.c index e7f6257..233bb59 100644 --- a/src/duskgl/display/mesh/meshgl.c +++ b/src/duskgl/display/mesh/meshgl.c @@ -21,7 +21,74 @@ errorret_t meshInitGL( mesh->primitiveType = primitiveType; mesh->vertexCount = vertexCount; - mesh->vertices = vertices; + + #ifdef DUSK_OPENGL_LEGACY + mesh->vertices = vertices; + #else + // Generate Vertex Buffer Object + glGenBuffers(1, &mesh->vboId); + errorChain(errorGLCheck()); + glBindBuffer(GL_ARRAY_BUFFER, mesh->vboId); + errorChain(errorGLCheck()); + glBufferData( + GL_ARRAY_BUFFER, + vertexCount * sizeof(meshvertex_t), + vertices, + GL_STATIC_DRAW + ); + errorChain(errorGLCheck()); + + // Generate Vertex Array Object + glGenVertexArrays(1, &mesh->vaoId); + errorChain(errorGLCheck()); + glBindVertexArray(mesh->vaoId); + errorChain(errorGLCheck()); + glBindBuffer(GL_ARRAY_BUFFER, mesh->vboId); + errorChain(errorGLCheck()); + + // Set up vertex attribute pointers + glVertexAttribPointer( + 0, + MESH_VERTEX_POS_SIZE, + GL_FLOAT, + GL_FALSE, + sizeof(meshvertex_t), + (const GLvoid*)offsetof(meshvertex_t, pos) + ); + errorChain(errorGLCheck()); + glEnableVertexAttribArray(0); + errorChain(errorGLCheck()); + + glVertexAttribPointer( + 1, + MESH_VERTEX_UV_SIZE, + GL_FLOAT, + GL_FALSE, + sizeof(meshvertex_t), + (const GLvoid*)offsetof(meshvertex_t, uv) + ); + errorChain(errorGLCheck()); + glEnableVertexAttribArray(1); + errorChain(errorGLCheck()); + + glVertexAttribPointer( + 2, + sizeof(color_t) / sizeof(GLubyte), + GL_UNSIGNED_BYTE, + GL_TRUE, + sizeof(meshvertex_t), + (const GLvoid*)offsetof(meshvertex_t, color) + ); + errorChain(errorGLCheck()); + glEnableVertexAttribArray(2); + errorChain(errorGLCheck()); + + // Unbind VAO and VBO to prevent accidental modification + glBindBuffer(GL_ARRAY_BUFFER, 0); + errorChain(errorGLCheck()); + glBindVertexArray(0); + errorChain(errorGLCheck()); + #endif errorOk(); } @@ -31,30 +98,40 @@ errorret_t meshDrawGL( const int32_t offset, const int32_t count ) { - // PSP style pointer legacy OpenGL - const GLsizei stride = sizeof(meshvertex_t); + #ifdef DUSK_OPENGL_LEGACY + // Legacy pointer style rendering + const GLsizei stride = sizeof(meshvertex_t); - // glColorPointer( - // sizeof(color4b_t), - // GL_UNSIGNED_BYTE, - // stride, - // (const GLvoid*)&mesh->vertices[offset].color - // ); - // glTexCoordPointer( - // MESH_VERTEX_UV_SIZE, - // GL_FLOAT, - // stride, - // (const GLvoid*)&mesh->vertices[offset].uv - // ); - // glVertexPointer( - // MESH_VERTEX_POS_SIZE, - // GL_FLOAT, - // stride, - // (const GLvoid*)&mesh->vertices[offset].pos - // ); + glColorPointer( + sizeof(color4b_t), + GL_UNSIGNED_BYTE, + stride, + (const GLvoid*)&mesh->vertices[offset].color + ); + glTexCoordPointer( + MESH_VERTEX_UV_SIZE, + GL_FLOAT, + stride, + (const GLvoid*)&mesh->vertices[offset].uv + ); + glVertexPointer( + MESH_VERTEX_POS_SIZE, + GL_FLOAT, + stride, + (const GLvoid*)&mesh->vertices[offset].pos + ); - // glDrawArrays(mesh->primitiveType, offset, count); - // errorChain(errorGLCheck()); + glDrawArrays(mesh->primitiveType, offset, count); + errorChain(errorGLCheck()); + #else + // Modern VAO/VBO rendering + glBindVertexArray(mesh->vaoId); + errorChain(errorGLCheck()); + glDrawArrays(mesh->primitiveType, offset, count); + errorChain(errorGLCheck()); + glBindVertexArray(0); + errorChain(errorGLCheck()); + #endif errorOk(); } @@ -64,6 +141,13 @@ int32_t meshGetVertexCountGL(const meshgl_t *mesh) { } errorret_t meshDisposeGL(meshgl_t *mesh) { - // No dynamic resources to free for this mesh implementation + #ifdef DUSK_OPENGL_LEGACY + // No dynamic resources to free for this mesh implementation + #else + glDeleteBuffers(1, &mesh->vboId); + errorChain(errorGLCheck()); + glDeleteVertexArrays(1, &mesh->vaoId); + errorChain(errorGLCheck()); + #endif errorOk(); } \ No newline at end of file diff --git a/src/duskgl/display/mesh/meshgl.h b/src/duskgl/display/mesh/meshgl.h index 8acc6c3..208a3ab 100644 --- a/src/duskgl/display/mesh/meshgl.h +++ b/src/duskgl/display/mesh/meshgl.h @@ -16,9 +16,15 @@ typedef enum { } meshprimitivetypegl_t; typedef struct { - const meshvertex_t *vertices; int32_t vertexCount; meshprimitivetypegl_t primitiveType; + + #ifdef DUSK_OPENGL_LEGACY + const meshvertex_t *vertices; + #else + GLuint vaoId; + GLuint vboId; + #endif } meshgl_t; /** diff --git a/src/duskgl/display/shader/shadergl.c b/src/duskgl/display/shader/shadergl.c index 6f7726f..2c82aa3 100644 --- a/src/duskgl/display/shader/shadergl.c +++ b/src/duskgl/display/shader/shadergl.c @@ -12,116 +12,120 @@ errorret_t shaderInitGL(shadergl_t *shader, const shaderdefinitiongl_t *def) { assertNotNull(shader, "Shader cannot be null"); assertNotNull(def, "Shader definition cannot be null"); - memoryZero(shader, sizeof(shadergl_t)); - // Create vertex shader - shader->vertexShaderId = glCreateShader(GL_VERTEX_SHADER); - errorret_t err = errorGLCheck(); - errorChain(err); - - glShaderSource(shader->vertexShaderId, 1, &def->vert, NULL); - err = errorGLCheck(); - if(err.code != ERROR_OK) { - glDeleteShader(shader->vertexShaderId); + #ifdef DUSK_OPENGL_LEGACY + // No initialization needed for legacy shader + errorOk(); + #else + // Create vertex shader + shader->vertexShaderId = glCreateShader(GL_VERTEX_SHADER); + errorret_t err = errorGLCheck(); errorChain(err); - } - glCompileShader(shader->vertexShaderId); - err = errorGLCheck(); - if(err.code != ERROR_OK) { - glDeleteShader(shader->vertexShaderId); - errorChain(err); - } + glShaderSource(shader->vertexShaderId, 1, &def->vert, NULL); + err = errorGLCheck(); + if(err.code != ERROR_OK) { + glDeleteShader(shader->vertexShaderId); + errorChain(err); + } - GLint ok = 0; - glGetShaderiv(shader->vertexShaderId, GL_COMPILE_STATUS, &ok); - if(!ok) { - GLchar log[1024]; - glGetShaderInfoLog(shader->vertexShaderId, sizeof(log), NULL, log); - glDeleteShader(shader->vertexShaderId); - errorThrow("Vertex shader compilation failed: %s", log); - } + glCompileShader(shader->vertexShaderId); + err = errorGLCheck(); + if(err.code != ERROR_OK) { + glDeleteShader(shader->vertexShaderId); + errorChain(err); + } - // Create fragment shader - shader->fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); - err = errorGLCheck(); - if(err.code != ERROR_OK) { - glDeleteShader(shader->vertexShaderId); - errorChain(err); - } + GLint ok = 0; + glGetShaderiv(shader->vertexShaderId, GL_COMPILE_STATUS, &ok); + if(!ok) { + GLchar log[1024]; + glGetShaderInfoLog(shader->vertexShaderId, sizeof(log), NULL, log); + glDeleteShader(shader->vertexShaderId); + errorThrow("Vertex shader compilation failed: %s", log); + } - glShaderSource(shader->fragmentShaderId, 1, &def->frag, NULL); - err = errorGLCheck(); - if(err.code != ERROR_OK) { - glDeleteShader(shader->vertexShaderId); - glDeleteShader(shader->fragmentShaderId); - errorChain(err); - } + // Create fragment shader + shader->fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); + err = errorGLCheck(); + if(err.code != ERROR_OK) { + glDeleteShader(shader->vertexShaderId); + errorChain(err); + } - glCompileShader(shader->fragmentShaderId); - err = errorGLCheck(); - if(err.code != ERROR_OK) { - glDeleteShader(shader->vertexShaderId); - glDeleteShader(shader->fragmentShaderId); - errorChain(err); - } + glShaderSource(shader->fragmentShaderId, 1, &def->frag, NULL); + err = errorGLCheck(); + if(err.code != ERROR_OK) { + glDeleteShader(shader->vertexShaderId); + glDeleteShader(shader->fragmentShaderId); + errorChain(err); + } - glGetShaderiv(shader->fragmentShaderId, GL_COMPILE_STATUS, &ok); - if(!ok) { - GLchar log[1024]; - glGetShaderInfoLog(shader->fragmentShaderId, sizeof(log), NULL, log); - glDeleteShader(shader->vertexShaderId); - glDeleteShader(shader->fragmentShaderId); - errorThrow("Fragment shader compilation failed: %s", log); - } + glCompileShader(shader->fragmentShaderId); + err = errorGLCheck(); + if(err.code != ERROR_OK) { + glDeleteShader(shader->vertexShaderId); + glDeleteShader(shader->fragmentShaderId); + errorChain(err); + } - // Create shader program - shader->shaderProgramId = glCreateProgram(); - err = errorGLCheck(); - if(err.code != ERROR_OK) { - glDeleteShader(shader->vertexShaderId); - glDeleteShader(shader->fragmentShaderId); - errorChain(err); - } + glGetShaderiv(shader->fragmentShaderId, GL_COMPILE_STATUS, &ok); + if(!ok) { + GLchar log[1024]; + glGetShaderInfoLog(shader->fragmentShaderId, sizeof(log), NULL, log); + glDeleteShader(shader->vertexShaderId); + glDeleteShader(shader->fragmentShaderId); + errorThrow("Fragment shader compilation failed: %s", log); + } - glAttachShader(shader->shaderProgramId, shader->vertexShaderId); - err = errorGLCheck(); - if(err.code != ERROR_OK) { - glDeleteProgram(shader->shaderProgramId); - glDeleteShader(shader->vertexShaderId); - glDeleteShader(shader->fragmentShaderId); - errorChain(err); - } + // Create shader program + shader->shaderProgramId = glCreateProgram(); + err = errorGLCheck(); + if(err.code != ERROR_OK) { + glDeleteShader(shader->vertexShaderId); + glDeleteShader(shader->fragmentShaderId); + errorChain(err); + } - glAttachShader(shader->shaderProgramId, shader->fragmentShaderId); - err = errorGLCheck(); - if(err.code != ERROR_OK) { - glDeleteProgram(shader->shaderProgramId); - glDeleteShader(shader->vertexShaderId); - glDeleteShader(shader->fragmentShaderId); - errorChain(err); - } + glAttachShader(shader->shaderProgramId, shader->vertexShaderId); + err = errorGLCheck(); + if(err.code != ERROR_OK) { + glDeleteProgram(shader->shaderProgramId); + glDeleteShader(shader->vertexShaderId); + glDeleteShader(shader->fragmentShaderId); + errorChain(err); + } - glLinkProgram(shader->shaderProgramId); - err = errorGLCheck(); - if(err.code != ERROR_OK) { - glDeleteProgram(shader->shaderProgramId); - glDeleteShader(shader->vertexShaderId); - glDeleteShader(shader->fragmentShaderId); - errorChain(err); - } + glAttachShader(shader->shaderProgramId, shader->fragmentShaderId); + err = errorGLCheck(); + if(err.code != ERROR_OK) { + glDeleteProgram(shader->shaderProgramId); + glDeleteShader(shader->vertexShaderId); + glDeleteShader(shader->fragmentShaderId); + errorChain(err); + } - ok = 0; - glGetProgramiv(shader->shaderProgramId, GL_LINK_STATUS, &ok); - if(!ok) { - GLchar log[1024]; - glGetProgramInfoLog(shader->shaderProgramId, sizeof(log), NULL, log); - glDeleteProgram(shader->shaderProgramId); - glDeleteShader(shader->vertexShaderId); - glDeleteShader(shader->fragmentShaderId); - errorThrow("Shader program linking failed: %s", log); - } + glLinkProgram(shader->shaderProgramId); + err = errorGLCheck(); + if(err.code != ERROR_OK) { + glDeleteProgram(shader->shaderProgramId); + glDeleteShader(shader->vertexShaderId); + glDeleteShader(shader->fragmentShaderId); + errorChain(err); + } + + ok = 0; + glGetProgramiv(shader->shaderProgramId, GL_LINK_STATUS, &ok); + if(!ok) { + GLchar log[1024]; + glGetProgramInfoLog(shader->shaderProgramId, sizeof(log), NULL, log); + glDeleteProgram(shader->shaderProgramId); + glDeleteShader(shader->vertexShaderId); + glDeleteShader(shader->fragmentShaderId); + errorThrow("Shader program linking failed: %s", log); + } + #endif errorOk(); } diff --git a/src/duskgl/display/shader/shadergl.h b/src/duskgl/display/shader/shadergl.h index 91bb5de..56d50cf 100644 --- a/src/duskgl/display/shader/shadergl.h +++ b/src/duskgl/display/shader/shadergl.h @@ -9,14 +9,22 @@ #include "error/errorgl.h" typedef struct { - GLuint shaderProgramId; - GLuint vertexShaderId; - GLuint fragmentShaderId; + #ifdef DUSK_OPENGL_LEGACY + void *nothing; + #else + GLuint shaderProgramId; + GLuint vertexShaderId; + GLuint fragmentShaderId; + #endif } shadergl_t; typedef struct { - const char_t *vert; - const char_t *frag; + #ifdef DUSK_OPENGL_LEGACY + void *nothing; + #else + const char_t *vert; + const char_t *frag; + #endif } shaderdefinitiongl_t; /** diff --git a/src/duskgl/display/shader/shaderunlitgl.c b/src/duskgl/display/shader/shaderunlitgl.c index 8ac2cd0..9a653d1 100644 --- a/src/duskgl/display/shader/shaderunlitgl.c +++ b/src/duskgl/display/shader/shaderunlitgl.c @@ -11,22 +11,17 @@ shaderdefinition_t SHADER_UNLIT_DEFINITION = { .vert = "#version 330 core\n" "layout(location = 0) in vec3 aPos;\n" - "layout(location = 1) in vec2 aTexCoord;\n" "uniform mat4 u_Proj;\n" "uniform mat4 u_View;\n" "uniform mat4 u_Model;\n" - "out vec2 v_TexCoord;\n" "void main() {\n" " gl_Position = u_Proj * u_View * u_Model * vec4(aPos, 1.0);\n" - " v_TexCoord = aTexCoord;\n" "}\n", .frag = "#version 330 core\n" - "in vec2 v_TexCoord;\n" "out vec4 FragColor;\n" - "uniform sampler2D u_Texture;\n" "void main() {\n" - " FragColor = texture(u_Texture, v_TexCoord);\n" + " FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" "}\n" }; \ No newline at end of file