Entropie git · main
Entropie festival game; first steps
C 88.5% Markdown 9.1% GLSL 2.3%git clone https://git.christianimmanuel.de/games/Entropie.gitwget https://git.christianimmanuel.de/games/Entropie/archive/Entropie.tar.gzentropie/src/render/shader.c raw
#include "render/shader.h"
#include "core/platform.h"
#include <SDL3/SDL.h>
static char *readAsset(const char *asset) {
char path[1024];
if (!Platform_assetPath(asset, path, sizeof(path))) {
SDL_Log("Asset path too long: %s", asset);
return NULL;
}
char *data = SDL_LoadFile(path, NULL); /* null-terminated */
if (!data) SDL_Log("Cannot read %s: %s", path, SDL_GetError());
return data;
}
#define GLSL_VERSION "#version 330 core\n"
#define COMMON_ASSET "shaders/common.glsl"
static GLuint compile(GLenum type, const char *common, const char *source, const char *name) {
const char *parts[] = { GLSL_VERSION, common, "\n#line 1\n", source };
GLuint shader = glCreateShader(type);
glShaderSource(shader, 4, parts, NULL);
glCompileShader(shader);
GLint ok = GL_FALSE;
glGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
if (!ok) {
char log[1024];
glGetShaderInfoLog(shader, sizeof(log), NULL, log);
SDL_Log("Shader compile error in %s:\n%s", name, log);
glDeleteShader(shader);
return 0;
}
return shader;
}
GLuint Shader_load(const char *vert_asset, const char *frag_asset) {
GLuint program = 0, vert = 0, frag = 0;
char *common = readAsset(COMMON_ASSET);
char *vert_src = readAsset(vert_asset);
char *frag_src = readAsset(frag_asset);
if (!common || !vert_src || !frag_src) goto done;
vert = compile(GL_VERTEX_SHADER, common, vert_src, vert_asset);
frag = compile(GL_FRAGMENT_SHADER, common, frag_src, frag_asset);
if (!vert || !frag) goto done;
program = glCreateProgram();
glAttachShader(program, vert);
glAttachShader(program, frag);
glLinkProgram(program);
GLint ok = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &ok);
if (!ok) {
char log[1024];
glGetProgramInfoLog(program, sizeof(log), NULL, log);
SDL_Log("Shader link error (%s + %s):\n%s", vert_asset, frag_asset, log);
glDeleteProgram(program);
program = 0;
}
done:
if (vert) glDeleteShader(vert);
if (frag) glDeleteShader(frag);
SDL_free(common);
SDL_free(vert_src);
SDL_free(frag_src);
return program;
}
void Shader_destroy(GLuint *program) {
if (*program) glDeleteProgram(*program);
*program = 0;
}