cg1_tut_bin/src/shader.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;
}