/** * Copyright (c) 2026 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "display/shader/shaderunlit.h" #include "assert/assertgl.h" #ifdef DUSK_OPENGL_LEGACY shaderdefinition_t SHADER_UNLIT_DEFINITION = { 0 }; #else errorret_t shaderUnlitSetTextureGL( shadergl_t *shader, const char_t *name, texture_t *texture ) { assertNotNull(shader, "Shader cannot be null"); assertStrLenMin(name, 1, "Uniform name cannot be empty"); assertStringEqual( name, SHADER_UNLIT_TEXTURE, "Only one texture supported in unlit shader." ); GLint locTexture, locType, locColorCount, locColors; errorChain(shaderParamGetLocationGL(shader, "u_TextureType", &locType)); // NULL textures if(texture == NULL) { glUniform1i(locType, 0); errorChain(errorGLCheck()); errorOk(); } // Set texture. glActiveTexture(GL_TEXTURE0); errorChain(errorGLCheck()); glBindTexture(GL_TEXTURE_2D, texture->id); errorChain(errorGLCheck()); errorChain(shaderParamGetLocationGL(shader, name, &locTexture)); glUniform1i(locTexture, 0); errorChain(errorGLCheck()); // Set texture type if(texture->format == TEXTURE_FORMAT_PALETTE) { glUniform1i(locType, 2); errorChain(errorGLCheck()); shaderParamGetLocationGL(shader, "u_ColorCount", &locColorCount); glUniform1i(locColorCount, texture->palette->count); errorChain(errorGLCheck()); shaderParamGetLocationGL(shader, "u_Colors", &locColors); GLuint paletteData[texture->palette->count]; for(size_t i = 0; i < texture->palette->count; i++) { color_t color = texture->palette->colors[i]; paletteData[i] = ( ((uint32_t)color.r << 24) | ((uint32_t)color.g << 16) | ((uint32_t)color.b << 8) | ((uint32_t)color.a << 0) ); } glUniform1uiv(locColors, texture->palette->count, paletteData); errorChain(errorGLCheck()); } else { glUniform1i(locType, 1); errorChain(errorGLCheck()); } errorOk(); } shaderdefinition_t SHADER_UNLIT_DEFINITION = { .vert = #ifdef DUSK_OPENGL_ES "#version 300 es\n" "precision mediump float;\n" // Attributes "layout(location = 0) in vec3 a_Pos;\n" "layout(location = 1) in vec2 a_TexCoord;\n" "layout(location = 2) in vec4 a_Color;\n" // Uniforms "uniform mat4 u_Proj;\n" "uniform mat4 u_View;\n" "uniform mat4 u_Model;\n" // Vertex shader outputs "out vec4 v_Color;\n" "out vec2 v_TexCoord;\n" "void main() {\n" " gl_Position = u_Proj * u_View * u_Model * vec4(a_Pos, 1.0);\n" " v_Color = a_Color;\n" " v_TexCoord = a_TexCoord;\n" "}\n", #else "#version 330 core\n" // Attributes "layout(location = 0) in vec3 a_Pos;\n" "layout(location = 1) in vec2 a_TexCoord;\n" "layout(location = 2) in vec4 a_Color;\n" // Uniforms "uniform mat4 u_Proj;\n" "uniform mat4 u_View;\n" "uniform mat4 u_Model;\n" // Vertex shader outputs "out vec4 v_Color;\n" "out vec2 v_TexCoord;\n" "void main() {\n" " gl_Position = u_Proj * u_View * u_Model * vec4(a_Pos, 1.0);\n" " v_Color = a_Color;\n" " v_TexCoord = a_TexCoord;\n" "}\n", #endif .frag = #ifdef DUSK_OPENGL_ES "#version 300 es\n" "precision mediump float;\n" // Uniforms "uniform sampler2D u_Texture;\n" "uniform int u_TextureType;\n" "uniform vec4 u_Colors[256];\n"// For paletted textures. "uniform int u_ColorCount;\n" // Fragment shader inputs "in vec4 v_Color;\n" "in vec2 v_TexCoord;\n" // Fragment shader output "out vec4 FragColor;\n" "void main() {\n" " if(u_TextureType == 0) {\n"// No texture " FragColor = v_Color;\n" " return;\n" " }\n" " if(u_TextureType == 1) {\n"// Regular texture " FragColor = texture(u_Texture, v_TexCoord) * v_Color;\n" " return;\n" " }\n" " if(u_TextureType == 2) {\n"// Paletted texture " vec4 texColor = texture(u_Texture, v_TexCoord);\n" " int index = int(floor(texColor.r * 255.0));\n" " vec4 paletteColor = u_Colors[index];\n" " FragColor = paletteColor;\n" " return;\n" " }\n" " FragColor = v_Color;\n"// Unknown texture type? "}\n", #else "#version 330 core\n" // Uniforms "uniform sampler2D u_Texture;\n" "uniform int u_TextureType;\n" "uniform uint u_Colors[256];\n"// For paletted textures. "uniform int u_ColorCount;\n" // Fragment shader inputs "in vec4 v_Color;\n" "in vec2 v_TexCoord;\n" // Fragment shader output "out vec4 FragColor;\n" "void main() {\n" " if(u_TextureType == 0) {\n"// No texture " FragColor = v_Color;\n" " return;\n" " }\n" " if(u_TextureType == 1) {\n"// Regular texture " FragColor = texture(u_Texture, v_TexCoord) * v_Color;\n" " return;\n" " }\n" " if(u_TextureType == 2) {\n"// Paletted texture " vec4 texColor = texture(u_Texture, v_TexCoord);\n" " uint index = uint(floor(texColor.r * 255.0));\n" " uint palColor = u_Colors[index];\n" " float r = float((palColor >> 24) & 0xFFu) / 255.0;\n" " 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" " return;\n" " }\n" " FragColor = v_Color;\n"// Unknown texture type? "}\n", #endif .setTexture = shaderUnlitSetTextureGL }; #endif