189 lines
6.1 KiB
C
189 lines
6.1 KiB
C
/**
|
|
* 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 |