CX/src/shader.c
Marcel Plch fee012f56c
More threading stuff
So far it doesn't do anything,
but soon™ it will.
2024-11-09 21:29:02 +01:00

118 lines
3.1 KiB
C

#include "cx.h"
static int
load_code(const char *filepath, char **code) {
FILE *file;
int cursor;
int c;
file = fopen(filepath, "r");
if (file == NULL) {
fprintf(stderr, "Could not open %s.\n", filepath);
return 1;
}
*code = malloc(1024 * sizeof(char));
if (code == NULL) {
fprintf(stderr, "Out of memory");
return 1;
}
cursor = 0;
while ((c = fgetc(file)) != EOF) {
(*code)[cursor] = c;
cursor++;
}
(*code)[cursor] = '\0';
return 0;
}
static int
compile_code(const char *filepath, const char *code,
GLuint ShaderID, GLint *result) {
int InfoLogLength;
// Compile Shader
printf("Compiling shader: %s\n", filepath);
glShaderSource(ShaderID, 1, (const char **)&code, NULL);
glCompileShader(ShaderID);
// Check Shader
glGetShaderiv(ShaderID, GL_COMPILE_STATUS, result);
glGetShaderiv(ShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
char *ShaderErrorMessage = malloc(InfoLogLength+1);
glGetShaderInfoLog(ShaderID, InfoLogLength, NULL, ShaderErrorMessage);
printf("%s\n", ShaderErrorMessage);
free(ShaderErrorMessage);
return -1;
}
return 0;
}
int
LoadShaders(GLuint *programID, const char *vertex_file_path,
const char *fragment_file_path) {
int retval = -1;
char *vertex_code = NULL;
char *fragment_code = NULL;
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Read the Vertex Shader code from the file
if (load_code(vertex_file_path, (char **)&vertex_code)) {
goto end;
}
// Read the Fragment Shader code from the file
if (load_code(fragment_file_path, (char **)&fragment_code)) {
goto end;
}
GLint result = GL_FALSE;
// Compile Vertex Shader
if (compile_code(vertex_file_path, vertex_code, VertexShaderID, &result)) {
goto end;
}
// Compile Fragment Shader
if (compile_code(fragment_file_path, fragment_code, FragmentShaderID, &result)) {
goto end;
}
// Link the program
printf("Linking program\n");
*programID = glCreateProgram();
glAttachShader(*programID, VertexShaderID);
glAttachShader(*programID, FragmentShaderID);
glLinkProgram(*programID);
GLint InfoLogLength;
// Check the program
glGetProgramiv(*programID, GL_LINK_STATUS, &result);
glGetProgramiv(*programID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
char *ProgramErrorMessage = malloc(InfoLogLength+1);
glGetProgramInfoLog(*programID, InfoLogLength, NULL, ProgramErrorMessage);
printf("%s\n", ProgramErrorMessage);
}
glDetachShader(*programID, VertexShaderID);
glDetachShader(*programID, FragmentShaderID);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
// If code got here, it means it was successful
retval = 0;
end:
free(vertex_code);
free(fragment_code);
return retval;
}