118 lines
3.1 KiB
C
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;
|
|
}
|
|
|