From 673d8e0a181ef4131cd7bf4b9d8b667dab2b4e57 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Fri, 10 Apr 2026 12:48:05 -0500 Subject: [PATCH] Shader material ECS example --- src/dusk/display/display.c | 1 + src/dusk/display/shader/shader.c | 33 +++++++--- src/dusk/display/shader/shader.h | 26 ++++++-- src/dusk/display/shader/shadermaterial.h | 13 ++++ src/dusk/display/shader/shaderunlit.c | 24 ++++++- src/dusk/display/shader/shaderunlit.h | 21 ++++++- src/dusk/engine/engine.c | 2 +- .../entity/component/display/CMakeLists.txt | 1 + .../entity/component/display/entitymaterial.c | 51 +++++++++++++++ .../entity/component/display/entitymaterial.h | 63 +++++++++++++++++++ src/dusk/entity/componentlist.h | 4 +- src/dusk/scene/scene.c | 28 +++++++-- .../display/shader/shaderdolphin.c | 14 +++++ .../display/shader/shaderdolphin.h | 16 ++++- .../display/shader/shaderplatform.h | 1 + .../display/shader/shaderunlitdolphin.c | 3 +- src/duskgl/display/shader/shadergl.c | 38 +++++++++-- src/duskgl/display/shader/shadergl.h | 38 ++++++----- src/duskgl/display/shader/shaderplatform.h | 2 +- src/duskgl/display/shader/shaderunlitgl.c | 34 ++++++---- 20 files changed, 349 insertions(+), 64 deletions(-) create mode 100644 src/dusk/display/shader/shadermaterial.h create mode 100644 src/dusk/entity/component/display/entitymaterial.c create mode 100644 src/dusk/entity/component/display/entitymaterial.h diff --git a/src/dusk/display/display.c b/src/dusk/display/display.c index 8a48924c..ea23d6a3 100644 --- a/src/dusk/display/display.c +++ b/src/dusk/display/display.c @@ -63,6 +63,7 @@ errorret_t displayInit(void) { errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view)); errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model)); errorChain(shaderSetTexture(&SHADER_UNLIT, SHADER_UNLIT_TEXTURE, NULL)); + errorChain(shaderSetColor(&SHADER_UNLIT, SHADER_UNLIT_COLOR, COLOR_WHITE)); errorOk(); } diff --git a/src/dusk/display/shader/shader.c b/src/dusk/display/shader/shader.c index 359e82f2..a4d0ae78 100644 --- a/src/dusk/display/shader/shader.c +++ b/src/dusk/display/shader/shader.c @@ -6,6 +6,7 @@ */ #include "shader.h" +#include "shadermaterial.h" #include "assert/assert.h" shader_t *bound = NULL; @@ -49,16 +50,28 @@ errorret_t shaderSetTexture( errorOk(); } -// errorret_t shaderSetColor( -// shader_t *shader, -// const char_t *name, -// color_t color -// ) { -// assertNotNull(shader, "Shader cannot be null"); -// assertStrLenMin(name, 1, "Uniform name cannot be empty"); -// errorChain(shaderSetColorPlatform(shader, name, color)); -// errorOk(); -// } +errorret_t shaderSetColor( + shader_t *shader, + const char_t *name, + color_t color +) { + assertNotNull(shader, "Shader cannot be null"); + assertStrLenMin(name, 1, "Uniform name cannot be empty"); + errorChain(shaderSetColorPlatform(shader, name, color)); + errorOk(); +} + +errorret_t shaderSetMaterial( + shader_t *shader, + const shadermaterial_t *material +) { + assertNotNull(shader, "Shader cannot be null"); + assertNotNull(material, "Material cannot be null"); + assertTrue(bound == shader, "Shader must be bound."); + assertNotNull(shader->definition, "Shader definition cannot be null"); + assertNotNull(shader->definition->setMaterial, "Def lacks setMaterial"); + return shader->definition->setMaterial(shader, material); +} errorret_t shaderDispose(shader_t *shader) { assertNotNull(shader, "Shader cannot be null"); diff --git a/src/dusk/display/shader/shader.h b/src/dusk/display/shader/shader.h index 7f2cf87d..bb94e3a1 100644 --- a/src/dusk/display/shader/shader.h +++ b/src/dusk/display/shader/shader.h @@ -23,6 +23,7 @@ #error "shaderDisposePlatform must be defined to use shader.h" #endif +typedef union shadermaterial_u shadermaterial_t; typedef shaderplatform_t shader_t; typedef shaderdefinitionplatform_t shaderdefinition_t; @@ -79,15 +80,28 @@ errorret_t shaderSetTexture( * @param color Color to set * @return Error if failure, otherwise errorOk */ -// errorret_t shaderSetColor( -// shader_t *shader, -// const char_t *name, -// color_t color -// ); +errorret_t shaderSetColor( + shader_t *shader, + const char_t *name, + color_t color +); + +/** + * Sets a material's properties in the shader. This is platform dependant. + * the definition's upload function pointer. + * + * @param shader The shader to upload material properties to. + * @param material The material data to upload. + * @return Error if failure, otherwise errorOk. + */ +errorret_t shaderSetMaterial( + shader_t *shader, + const shadermaterial_t *material +); /** * Disposes of a shader. This is platform dependant. - * + * * @param shader Shader to dispose * @return Error if failure, otherwise errorOk */ diff --git a/src/dusk/display/shader/shadermaterial.h b/src/dusk/display/shader/shadermaterial.h new file mode 100644 index 00000000..293d2bb3 --- /dev/null +++ b/src/dusk/display/shader/shadermaterial.h @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "display/shader/shaderunlit.h" + +typedef union shadermaterial_u { + shaderunlitmaterial_t unlit; +} shadermaterial_t; \ No newline at end of file diff --git a/src/dusk/display/shader/shaderunlit.c b/src/dusk/display/shader/shaderunlit.c index f6c0c643..a6d04649 100644 --- a/src/dusk/display/shader/shaderunlit.c +++ b/src/dusk/display/shader/shaderunlit.c @@ -6,5 +6,27 @@ */ #include "shaderunlit.h" +#include "display/shader/shadermaterial.h" -shader_t SHADER_UNLIT = { 0 }; \ No newline at end of file +shader_t SHADER_UNLIT = { + .definition = &SHADER_UNLIT_DEFINITION +}; + +errorret_t shaderUnlitSetMaterial( + shader_t *shader, + const shadermaterial_t *material +) { + errorChain(shaderSetTexture( + shader, + SHADER_UNLIT_TEXTURE, + material->unlit.texture + )); + + errorChain(shaderSetColor( + shader, + SHADER_UNLIT_COLOR, + material->unlit.color + )); + + errorOk(); +} \ No newline at end of file diff --git a/src/dusk/display/shader/shaderunlit.h b/src/dusk/display/shader/shaderunlit.h index 56dbf890..3a04d613 100644 --- a/src/dusk/display/shader/shaderunlit.h +++ b/src/dusk/display/shader/shaderunlit.h @@ -12,7 +12,24 @@ #define SHADER_UNLIT_VIEW "u_View" #define SHADER_UNLIT_MODEL "u_Model" #define SHADER_UNLIT_TEXTURE "u_Texture" -// #define SHADER_UNLIT_COLOR "u_Color" +#define SHADER_UNLIT_COLOR "u_Color" + +typedef struct { + color_t color; + texture_t *texture; +} shaderunlitmaterial_t; extern shaderdefinition_t SHADER_UNLIT_DEFINITION; -extern shader_t SHADER_UNLIT; \ No newline at end of file +extern shader_t SHADER_UNLIT; + +/** + * Uploads the unlit material properties to the shader. + * + * @param shader The shader to upload to. + * @param material The material data to upload. + * @return Error if failure, otherwise errorOk. + */ +errorret_t shaderUnlitSetMaterial( + shader_t *shader, + const shadermaterial_t *material +); \ No newline at end of file diff --git a/src/dusk/engine/engine.c b/src/dusk/engine/engine.c index b653f61c..c1e8f74a 100644 --- a/src/dusk/engine/engine.c +++ b/src/dusk/engine/engine.c @@ -56,6 +56,7 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) { entityid_t ent1 = entityManagerAdd(); componentid_t ent1Pos = entityAddComponent(ent1, COMPONENT_TYPE_POSITION); componentid_t ent1Mesh = entityAddComponent(ent1, COMPONENT_TYPE_MESH); + componentid_t ent1Mat = entityAddComponent(ent1, COMPONENT_TYPE_MATERIAL); mesh_t *mesh = entityMeshGetMesh(ent1, ent1Mesh); errorChain(meshInit( @@ -64,7 +65,6 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) { CUBE_VERTEX_COUNT, CUBE_MESH_SIMPLE_VERTICES )); - // EOF // Run the init script. diff --git a/src/dusk/entity/component/display/CMakeLists.txt b/src/dusk/entity/component/display/CMakeLists.txt index 193e309e..d0b84aa4 100644 --- a/src/dusk/entity/component/display/CMakeLists.txt +++ b/src/dusk/entity/component/display/CMakeLists.txt @@ -9,4 +9,5 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME} entityposition.c entitycamera.c entitymesh.c + entitymaterial.c ) \ No newline at end of file diff --git a/src/dusk/entity/component/display/entitymaterial.c b/src/dusk/entity/component/display/entitymaterial.c new file mode 100644 index 00000000..692b406d --- /dev/null +++ b/src/dusk/entity/component/display/entitymaterial.c @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "entity/entitymanager.h" +#include "display/shader/shaderunlit.h" + +void entityMaterialInit( + const entityid_t entityId, + const componentid_t componentId +) { + entitymaterial_t *mat = componentGetData( + entityId, componentId, COMPONENT_TYPE_MATERIAL + ); + mat->shader = &SHADER_UNLIT; + mat->material.unlit.color = COLOR_MAGENTA; +} + +shadermaterial_t * entityMaterialGetShaderMaterial( + const entityid_t entityId, + const componentid_t componentId +) { + entitymaterial_t *mat = componentGetData( + entityId, componentId, COMPONENT_TYPE_MATERIAL + ); + return &mat->material; +} + +shader_t * entityMaterialGetShader( + const entityid_t entityId, + const componentid_t componentId +) { + entitymaterial_t *mat = componentGetData( + entityId, componentId, COMPONENT_TYPE_MATERIAL + ); + return mat->shader; +} + +void entityMaterialSetShader( + const entityid_t entityId, + const componentid_t componentId, + shader_t *shader +) { + entitymaterial_t *mat = componentGetData( + entityId, componentId, COMPONENT_TYPE_MATERIAL + ); + mat->shader = shader; +} \ No newline at end of file diff --git a/src/dusk/entity/component/display/entitymaterial.h b/src/dusk/entity/component/display/entitymaterial.h new file mode 100644 index 00000000..c4bd1e4f --- /dev/null +++ b/src/dusk/entity/component/display/entitymaterial.h @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "entity/entitybase.h" +#include "display/shader/shadermaterial.h" + +typedef struct { + shader_t *shader; + shadermaterial_t material; +} entitymaterial_t; + +/** + * Initializes the entity material component, defaulting to the unlit shader. + * + * @param entityId The entity ID. + * @param componentId The component ID. + */ +void entityMaterialInit( + const entityid_t entityId, + const componentid_t componentId +); + +/** + * Gets the shader material for the given entity and component. + * + * @param entityId The entity ID. + * @param componentId The component ID. + * @return The shader material for the given entity and component. + */ +shadermaterial_t * entityMaterialGetShaderMaterial( + const entityid_t entityId, + const componentid_t componentId +); + +/** + * Gets the shader for the given entity and component. + * + * @param entityId The entity ID. + * @param componentId The component ID. + * @return The shader for the given entity and component. + */ +shader_t * entityMaterialGetShader( + const entityid_t entityId, + const componentid_t componentId +); + +/** + * Sets the shader for the given entity and component. + * + * @param entityId The entity ID. + * @param componentId The component ID. + * @param shader The shader to set. + */ +void entityMaterialSetShader( + const entityid_t entityId, + const componentid_t componentId, + shader_t *shader +); \ No newline at end of file diff --git a/src/dusk/entity/componentlist.h b/src/dusk/entity/componentlist.h index 5d3eaeb5..6333b9ec 100644 --- a/src/dusk/entity/componentlist.h +++ b/src/dusk/entity/componentlist.h @@ -8,7 +8,9 @@ #include "entity/component/display/entityposition.h" #include "entity/component/display/entitycamera.h" #include "entity/component/display/entitymesh.h" +#include "entity/component/display/entitymaterial.h" X(POSITION, entityposition_t, position, entityPositionInit, NULL) X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL) -X(MESH, entitymesh_t, mesh, entityMeshInit, entityMeshDispose) \ No newline at end of file +X(MESH, entitymesh_t, mesh, entityMeshInit, entityMeshDispose) +X(MATERIAL, entitymaterial_t, material, entityMaterialInit, NULL) \ No newline at end of file diff --git a/src/dusk/scene/scene.c b/src/dusk/scene/scene.c index 325552d2..501b2eab 100644 --- a/src/dusk/scene/scene.c +++ b/src/dusk/scene/scene.c @@ -64,8 +64,6 @@ errorret_t sceneRender(void) { entityCameraGetProjection(camEnt, camComp, proj); entityPositionGetTransform(camEnt, camPos, view); - errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj)); - errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view)); // For each mesh. for(entityid_t meshIndex = 0; meshIndex < meshCount; meshIndex++) { @@ -77,9 +75,31 @@ errorret_t sceneRender(void) { continue; } - entityPositionGetTransform(meshEnt, meshPos, model); - errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model)); + componentid_t meshMat = entityGetComponent( + meshEnt, COMPONENT_TYPE_MATERIAL + ); + if(meshMat == 0xFF) { + logError("Mesh entity without material component found\n"); + continue; + } + shadermaterial_t *material = entityMaterialGetShaderMaterial( + meshEnt, meshMat + ); + shader_t *shader = entityMaterialGetShader(meshEnt, meshMat); + if(shader == NULL) { + logError("Mesh entity with material component without shader found\n"); + continue; + } + + entityPositionGetTransform(meshEnt, meshPos, model); + + errorChain(shaderBind(shader)); + errorChain(shaderSetMatrix(shader, SHADER_UNLIT_PROJECTION, proj)); + errorChain(shaderSetMatrix(shader, SHADER_UNLIT_VIEW, view)); + errorChain(shaderSetMatrix(shader, SHADER_UNLIT_MODEL, model)); + errorChain(shaderSetMaterial(shader, material)); + // Mesh mesh_t *mesh = entityMeshGetMesh(meshEnt, meshComp); errorChain(meshDraw(mesh, 0, -1)); diff --git a/src/duskdolphin/display/shader/shaderdolphin.c b/src/duskdolphin/display/shader/shaderdolphin.c index 87c348a4..8ed06f04 100644 --- a/src/duskdolphin/display/shader/shaderdolphin.c +++ b/src/duskdolphin/display/shader/shaderdolphin.c @@ -159,6 +159,20 @@ errorret_t shaderSetTextureDolphin( errorOk(); } +errorret_t shaderSetColorDolphin( + shaderdolphin_t *shader, + const char_t *name, + color_t color +) { + assertNotNull(shader, "Shader must not be null"); + assertNotNull(name, "Uniform name must not be null"); + assertStrLenMin(name, 1, "Uniform name cannot be empty"); + + GX_SetChanMatColor(GX_COLOR0A0, (GXColor){ color.r, color.g, color.b, color.a }); + + errorOk(); +} + errorret_t shaderDisposeDolphin(shaderdolphin_t *shader) { assertNotNull(shader, "Shader must not be null"); diff --git a/src/duskdolphin/display/shader/shaderdolphin.h b/src/duskdolphin/display/shader/shaderdolphin.h index f64e8a5c..dd97dcb1 100644 --- a/src/duskdolphin/display/shader/shaderdolphin.h +++ b/src/duskdolphin/display/shader/shaderdolphin.h @@ -80,9 +80,23 @@ errorret_t shaderSetTextureDolphin( texture_t *texture ); +/** + * Sets a color uniform in the dolphin shader. + * + * @param shader Shader to set the color in. + * @param name Name of the uniform to set. + * @param color Color to set. + * @return Error code if failure. + */ +errorret_t shaderSetColorDolphin( + shaderdolphin_t *shader, + const char_t *name, + color_t color +); + /** * Disposes a dolphin shader. Basically does nothing. - * + * * @param shader Shader to dispose. * @return Error code if failure. */ diff --git a/src/duskdolphin/display/shader/shaderplatform.h b/src/duskdolphin/display/shader/shaderplatform.h index dab85d6c..071b84ba 100644 --- a/src/duskdolphin/display/shader/shaderplatform.h +++ b/src/duskdolphin/display/shader/shaderplatform.h @@ -15,4 +15,5 @@ typedef shaderdefinitiondolphin_t shaderdefinitionplatform_t; #define shaderBindPlatform shaderBindDolphin #define shaderSetMatrixPlatform shaderSetMatrixDolphin #define shaderSetTexturePlatform shaderSetTextureDolphin +#define shaderSetColorPlatform shaderSetColorDolphin #define shaderDisposePlatform shaderDisposeDolphin \ No newline at end of file diff --git a/src/duskdolphin/display/shader/shaderunlitdolphin.c b/src/duskdolphin/display/shader/shaderunlitdolphin.c index 8bb0f9f7..02d43783 100644 --- a/src/duskdolphin/display/shader/shaderunlitdolphin.c +++ b/src/duskdolphin/display/shader/shaderunlitdolphin.c @@ -8,5 +8,6 @@ #include "display/shader/shaderunlit.h" shaderdefinition_t SHADER_UNLIT_DEFINITION = { - 0 + .platform = { 0 }, + .upload = shaderUnlitUpload }; \ No newline at end of file diff --git a/src/duskgl/display/shader/shadergl.c b/src/duskgl/display/shader/shadergl.c index 2ca4ff1f..65a55fe2 100644 --- a/src/duskgl/display/shader/shadergl.c +++ b/src/duskgl/display/shader/shadergl.c @@ -20,6 +20,8 @@ errorret_t shaderInitGL(shadergl_t *shader, const shaderdefinitiongl_t *def) { assertNotNull(def, "Shader definition cannot be null"); memoryZero(shader, sizeof(shadergl_t)); + shader->definition = def; + #ifdef DUSK_OPENGL_LEGACY glm_mat4_identity(shader->view); glm_mat4_identity(shader->proj); @@ -31,8 +33,6 @@ errorret_t shaderInitGL(shadergl_t *shader, const shaderdefinitiongl_t *def) { assertNotNull(def->vert, "Vertex shader source cannot be null"); assertNotNull(def->frag, "Fragment shader source cannot be null"); - shader->setTexture = def->setTexture; - // Create vertex shader shader->vertexShaderId = glCreateShader(GL_VERTEX_SHADER); errorret_t err = errorGLCheck(); @@ -237,10 +237,36 @@ errorret_t shaderSetTextureGL( errorChain(errorGLCheck()); #else - if(shader->setTexture == NULL) { - assertUnreachable("Shader does not support setting textures."); - } - errorChain(shader->setTexture(shader, name, texture)); + assertNotNull(shader->definition, "Shader definition cannot be null"); + assertNotNull(shader->definition->setTexture, "Shader cannot do textures."); + errorChain(shader->definition->setTexture(shader, name, texture)); + #endif + + errorOk(); +} + +errorret_t shaderSetColorGL( + shadergl_t *shader, + const char_t *name, + color_t color +) { + assertNotNull(shader, "Shader cannot be null"); + assertStrLenMin(name, 1, "Uniform name cannot be empty"); + + #ifdef DUSK_OPENGL_LEGACY + glColor4ub(color.r, color.g, color.b, color.a); + errorChain(errorGLCheck()); + #else + GLint location; + errorChain(shaderParamGetLocationGL(shader, name, &location)); + glUniform4f( + location, + color.r / 255.0f, + color.g / 255.0f, + color.b / 255.0f, + color.a / 255.0f + ); + errorChain(errorGLCheck()); #endif errorOk(); diff --git a/src/duskgl/display/shader/shadergl.h b/src/duskgl/display/shader/shadergl.h index 470eb44e..b1e0db27 100644 --- a/src/duskgl/display/shader/shadergl.h +++ b/src/duskgl/display/shader/shadergl.h @@ -10,6 +10,7 @@ #include "display/texture/texture.h" typedef struct shadergl_s shadergl_t; +typedef union shadermaterial_u shadermaterial_t; typedef errorret_t (*shadersettexturefn_t)( shadergl_t *, @@ -17,7 +18,22 @@ typedef errorret_t (*shadersettexturefn_t)( texture_t * ); +typedef struct { + errorret_t (*setMaterial)(shadergl_t *, const shadermaterial_t *); + + #ifdef DUSK_OPENGL_LEGACY + void *nothing; + #else + errorret_t (*setTexture)(shadergl_t *, const char_t *, texture_t *); + + const char_t *vert; + const char_t *frag; + #endif +} shaderdefinitiongl_t; + typedef struct shadergl_s { + const shaderdefinitiongl_t *definition; + #ifdef DUSK_OPENGL_LEGACY mat4 view; mat4 proj; @@ -26,21 +42,9 @@ typedef struct shadergl_s { GLuint shaderProgramId; GLuint vertexShaderId; GLuint fragmentShaderId; - shadersettexturefn_t setTexture; #endif } shadergl_t; - -typedef struct { - #ifdef DUSK_OPENGL_LEGACY - void *nothing; - #else - const char_t *vert; - const char_t *frag; - shadersettexturefn_t setTexture; - #endif -} shaderdefinitiongl_t; - #if DUSK_OPENGL_LEGACY typedef struct { shadergl_t *boundShader; @@ -121,11 +125,11 @@ errorret_t shaderSetTextureGL( * @param color The color data to set. * @return An errorret_t indicating success or failure. */ -// errorret_t shaderSetColorGL( -// shadergl_t *shader, -// const char_t *name, -// color_t color -// ); +errorret_t shaderSetColorGL( + shadergl_t *shader, + const char_t *name, + color_t color +); /** * Disposes of a shader, freeing any associated resources. diff --git a/src/duskgl/display/shader/shaderplatform.h b/src/duskgl/display/shader/shaderplatform.h index 5c6e8efb..eb3975b2 100644 --- a/src/duskgl/display/shader/shaderplatform.h +++ b/src/duskgl/display/shader/shaderplatform.h @@ -15,5 +15,5 @@ typedef shaderdefinitiongl_t shaderdefinitionplatform_t; #define shaderBindPlatform shaderBindGL #define shaderSetMatrixPlatform shaderSetMatrixGL #define shaderSetTexturePlatform shaderSetTextureGL -// #define shaderSetColorPlatform shaderSetColorGL +#define shaderSetColorPlatform shaderSetColorGL #define shaderDisposePlatform shaderDisposeGL \ No newline at end of file diff --git a/src/duskgl/display/shader/shaderunlitgl.c b/src/duskgl/display/shader/shaderunlitgl.c index 95cbbf22..b5d009ed 100644 --- a/src/duskgl/display/shader/shaderunlitgl.c +++ b/src/duskgl/display/shader/shaderunlitgl.c @@ -9,7 +9,10 @@ #include "assert/assertgl.h" #ifdef DUSK_OPENGL_LEGACY - shaderdefinition_t SHADER_UNLIT_DEFINITION = { 0 }; + shaderdefinition_t SHADER_UNLIT_DEFINITION = { + .platform = { 0 }, + .upload = shaderUnlitUpload + }; #else errorret_t shaderUnlitSetTextureGL( shadergl_t *shader, @@ -75,7 +78,12 @@ errorOk(); } + + shaderdefinition_t SHADER_UNLIT_DEFINITION = { + .setMaterial = shaderUnlitSetMaterial, + .setTexture = shaderUnlitSetTextureGL, + .vert = #ifdef DUSK_OPENGL_ES "#version 300 es\n" @@ -115,6 +123,8 @@ " v_TexCoord = a_TexCoord;\n" "}\n", #endif + + .frag = #ifdef DUSK_OPENGL_ES "#version 300 es\n" @@ -124,6 +134,7 @@ "uniform int u_TextureType;\n" "uniform uint u_Colors[256];\n"// For paletted textures. "uniform int u_ColorCount;\n" + "uniform vec4 u_Color;\n" // Fragment shader inputs "in vec4 v_Color;\n" "in vec2 v_TexCoord;\n" @@ -131,11 +142,11 @@ "out vec4 FragColor;\n" "void main() {\n" " if(u_TextureType == 0) {\n"// No texture - " FragColor = v_Color;\n" + " FragColor = v_Color * u_Color;\n" " return;\n" " }\n" " if(u_TextureType == 1) {\n"// Regular texture - " FragColor = texture(u_Texture, v_TexCoord) * v_Color;\n" + " FragColor = texture(u_Texture, v_TexCoord) * v_Color * u_Color;\n" " return;\n" " }\n" " if(u_TextureType == 2) {\n"// Paletted texture @@ -146,11 +157,10 @@ " float g = float((palColor >> 16) & 0xFFu) / 255.0;\n" " float b = float((palColor >> 8) & 0xFFu) / 255.0;\n" " float a = float((palColor >> 0) & 0xFFu) / 255.0;\n" - " vec4 paletteColor = vec4(r, g, b, a);\n" - " FragColor = paletteColor;\n" + " FragColor = vec4(r, g, b, a) * u_Color;\n" " return;\n" " }\n" - " FragColor = v_Color;\n"// Unknown texture type? + " FragColor = v_Color * u_Color;\n"// Unknown texture type? "}\n", #else "#version 330 core\n" @@ -159,6 +169,7 @@ "uniform int u_TextureType;\n" "uniform uint u_Colors[256];\n"// For paletted textures. "uniform int u_ColorCount;\n" + "uniform vec4 u_Color;\n" // Fragment shader inputs "in vec4 v_Color;\n" "in vec2 v_TexCoord;\n" @@ -166,11 +177,11 @@ "out vec4 FragColor;\n" "void main() {\n" " if(u_TextureType == 0) {\n"// No texture - " FragColor = v_Color;\n" + " FragColor = v_Color * u_Color;\n" " return;\n" " }\n" " if(u_TextureType == 1) {\n"// Regular texture - " FragColor = texture(u_Texture, v_TexCoord) * v_Color;\n" + " FragColor = texture(u_Texture, v_TexCoord) * v_Color * u_Color;\n" " return;\n" " }\n" " if(u_TextureType == 2) {\n"// Paletted texture @@ -181,14 +192,11 @@ " float g = float((palColor >> 16) & 0xFFu) / 255.0;\n" " float b = float((palColor >> 8) & 0xFFu) / 255.0;\n" " float a = float((palColor >> 0) & 0xFFu) / 255.0;\n" - " vec4 paletteColor = vec4(r, g, b, a);\n" - " FragColor = paletteColor;\n" + " FragColor = vec4(r, g, b, a) * u_Color;\n" " return;\n" " }\n" - " FragColor = v_Color;\n"// Unknown texture type? + " FragColor = v_Color * u_Color;\n"// Unknown texture type? "}\n", #endif - - .setTexture = shaderUnlitSetTextureGL }; #endif \ No newline at end of file