From bd57f345ed9dbed1d81683e48199626de2ea9044 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Fri, 27 Jun 2025 10:18:39 -0700 Subject: Restructure project --- src/core/shader.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/core/shader.c (limited to 'src/core/shader.c') diff --git a/src/core/shader.c b/src/core/shader.c new file mode 100644 index 0000000..dded084 --- /dev/null +++ b/src/core/shader.c @@ -0,0 +1,92 @@ +#include "shader.h" + +#include "gl_util.h" +#include + +#include +#include + +#include +#include + +static GLenum shader_type_to_gl(ShaderType type) { + switch (type) { + case VertexShader: + return GL_VERTEX_SHADER; + case FragmentShader: + return GL_FRAGMENT_SHADER; + } + FAIL("shader_type_to_gl(): missing case"); + return GL_INVALID_ENUM; +} + +static lstring make_defines_string(const ShaderDesc* desc) { + lstring defines = {0}; + for (size_t i = 0; i < desc->num_defines; ++i) { + const ShaderCompilerDefine* define = &desc->defines[i]; + lstring_append_cstr(&defines, "#define "); + lstring_append_cstr(&defines, sstring_cstr(&define->name)); + lstring_append_cstr(&defines, " "); + lstring_append_cstr(&defines, sstring_cstr(&define->value)); + lstring_append_cstr(&defines, "\n"); + } + return defines; +} + +/// Creates an OpenGL shader. +/// Returns non-zero on success, 0 on failure. +static GLuint create_shader(const ShaderDesc* desc) { + const GLuint shader = glCreateShader(shader_type_to_gl(desc->type)); + if (!shader) { + return 0; + } + +#if GFX_GL_CONTEXT == GFX_GL_CONTEXT_ES + const char* header = "#version 300 es\n\nprecision highp float;"; +#else + const char* header = "#version 400 core\n\n"; +#endif + + lstring defines = make_defines_string(desc); + + const char* source_bits[] = {header, lstring_cstr(&defines), desc->code}; + const GLint source_lengths[] = { + strlen(header), lstring_length(&defines), strlen(desc->code)}; + + glShaderSource(shader, 3, source_bits, source_lengths); + glCompileShader(shader); + GLint result; + glGetShaderiv(shader, GL_COMPILE_STATUS, &result); + if (result == GL_FALSE) { + GLint log_len; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_len); + if (log_len > 0) { + char* log = calloc(log_len, sizeof(char)); + glGetShaderInfoLog(shader, log_len, NULL, log); + static const char* sep = "----------"; + LOGE("Failed loading shader: %s\n%s\n%s\n%s", log, sep, desc->code, sep); + free(log); + } else { + LOGE("Failed loading shader:\n%s", desc->code); + } + glDeleteShader(shader); + return 0; + } + ASSERT_GL; + return shader; +} + +bool gfx_compile_shader(Shader* shader, const ShaderDesc* desc) { + shader->id = create_shader(desc); + return shader->id != 0; +} + +void gfx_del_shader(Shader* shader) { + assert(shader); + + if (shader->id) { + glDeleteShader(shader->id); + shader->id = 0; + } + ASSERT_GL; +} -- cgit v1.2.3