assaultfish/engine/src/gl_shader.c
2026-01-10 19:51:48 +09:00

107 lines
1.7 KiB
C

#include <GearBox/GL.h>
#include <GearBox/File.h>
#include <GearBox/Log.h>
static void err(const char* path, GLuint shader) {
GLint len, ret;
char* e;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
e = malloc(len);
e[len] = 0;
glGetShaderInfoLog(shader, len, &ret, e);
GBLog(GBLogError, "%s: %s\n", path, e);
free(e);
}
int GBGLShaderPrepare(GBGL gl, GLuint* shader, const char* vs, const char* fs) {
GLuint vsi;
GLuint fsi;
GBFile f;
int vsl = 0;
int fsl = 0;
char* vss;
char* fss;
GLint st;
if((f = GBFileOpen(gl->engine, vs)) != NULL) {
int sz = GBFileSize(f);
vss = malloc(sz + 1);
GBFileRead(f, vss, sz);
vss[sz] = 0;
GBFileClose(f);
} else {
return 0;
}
if((f = GBFileOpen(gl->engine, fs)) != NULL) {
int sz = GBFileSize(f);
fss = malloc(sz + 1);
GBFileRead(f, fss, sz);
fss[sz] = 0;
GBFileClose(f);
} else {
free(vss);
return 0;
}
vsi = glCreateShader(GL_VERTEX_SHADER);
fsi = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vsi, 1, (const GLchar**)&vss, NULL);
glShaderSource(fsi, 1, (const GLchar**)&fss, NULL);
glCompileShader(vsi);
glGetShaderiv(vsi, GL_COMPILE_STATUS, &st);
if(!st) {
err(vs, vsi);
glDeleteShader(vsi);
glDeleteShader(fsi);
free(vss);
free(fss);
return 0;
}
glCompileShader(fsi);
glGetShaderiv(fsi, GL_COMPILE_STATUS, &st);
if(!st) {
err(fs, fsi);
glDeleteShader(vsi);
glDeleteShader(fsi);
free(vss);
free(fss);
return 0;
}
free(vss);
free(fss);
*shader = glCreateProgram();
glAttachShader(*shader, vsi);
glAttachShader(*shader, fsi);
glDeleteShader(vsi);
glDeleteShader(fsi);
glLinkProgram(*shader);
glGetProgramiv(*shader, GL_LINK_STATUS, &st);
if(!st) {
glDeleteProgram(*shader);
return 0;
}
return 1;
}