119 lines
2.8 KiB
C
119 lines
2.8 KiB
C
#include "shader.h"
|
|
#include "log.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
const char* readFileToMemory(const char* filepath) {
|
|
FILE* f = fopen(filepath, "r");
|
|
|
|
if (!f) {
|
|
perror("Failed to open file");
|
|
return NULL;
|
|
}
|
|
|
|
// determine file size
|
|
|
|
fseek(f, 0L, SEEK_END);
|
|
size_t size = ftell(f);
|
|
|
|
rewind(f);
|
|
|
|
// allocate buffer
|
|
char* buf = (char*)malloc(size + 1);
|
|
if (!buf) {
|
|
perror("Failed to allocate memory");
|
|
fclose(f);
|
|
return NULL;
|
|
}
|
|
|
|
// read file to buffer
|
|
fread(buf, 1, size, f);
|
|
|
|
// set null byte at end of buffer
|
|
buf[size] = '\0';
|
|
|
|
fclose(f);
|
|
return buf;
|
|
}
|
|
|
|
ShaderCompileResult readAndCompileShaderFromFile(const char* filepath, GLenum shaderType) {
|
|
ShaderCompileResult result = { .success = false, .shader = 0 }; // Initialize result to indicate failure by default
|
|
|
|
DEBUG("%s - Reading shader", filepath);
|
|
const char* shaderSource = readFileToMemory(filepath);
|
|
|
|
if (!shaderSource) {
|
|
FATAL("Could not read shader source file");
|
|
return result;
|
|
}
|
|
|
|
GLint shaderSize = strlen(shaderSource);
|
|
|
|
DEBUG("%s - Creating shader", filepath);
|
|
result.shader = glCreateShader(shaderType);
|
|
|
|
DEBUG("%s - Applying shader source", filepath);
|
|
glShaderSource(result.shader, 1, &shaderSource, &shaderSize);
|
|
|
|
DEBUG("%s - Compiling shader", filepath);
|
|
glCompileShader(result.shader);
|
|
|
|
GLint status;
|
|
glGetShaderiv(result.shader, GL_COMPILE_STATUS, &status);
|
|
if (!status) {
|
|
FATAL("Error compiling shader:");
|
|
GLchar infoLog[1024];
|
|
glGetShaderInfoLog(result.shader, 1024, NULL, infoLog);
|
|
FATAL("%s", infoLog);
|
|
|
|
result.success = false;
|
|
} else {
|
|
DEBUG("%s - Successfully compiled shader", filepath);
|
|
result.success = true;
|
|
}
|
|
|
|
free((void*)shaderSource);
|
|
|
|
return result; // Return the ShaderCompileResult struct
|
|
}
|
|
|
|
ProgramLinkResult linkShaderProgram(GLuint vertexShader, GLuint fragmentShader) {
|
|
ProgramLinkResult result = { .success = false, .program = 0 };
|
|
|
|
DEBUG("Creating program");
|
|
result.program = glCreateProgram();
|
|
|
|
DEBUG("Attaching Vertex Shader");
|
|
glAttachShader(result.program, vertexShader);
|
|
|
|
DEBUG("Attaching Fragment Shader");
|
|
glAttachShader(result.program, fragmentShader);
|
|
|
|
DEBUG("Linking Program");
|
|
glLinkProgram(result.program);
|
|
|
|
GLint status;
|
|
glGetProgramiv(result.program, GL_LINK_STATUS, &status);
|
|
if (!status) {
|
|
FATAL("Error linking program:");
|
|
GLchar infoLog[1024];
|
|
glGetProgramInfoLog(result.program, 1024, NULL, infoLog);
|
|
FATAL("%s", infoLog);
|
|
return result;
|
|
}
|
|
|
|
DEBUG("Validating Program");
|
|
glValidateProgram(result.program);
|
|
glGetProgramiv(result.program, GL_VALIDATE_STATUS, &status);
|
|
if (!status) {
|
|
FATAL("Error validating program:");
|
|
GLchar infoLog[1024];
|
|
glGetProgramInfoLog(result.program, 1024, NULL, infoLog);
|
|
FATAL("%s", infoLog);
|
|
return result;
|
|
}
|
|
|
|
result.success = true;
|
|
return result;
|
|
} |