Techneck/code/source-c/shaders.c

109 lines
3.3 KiB
C

#include "shaders.h"
char * load_file(char *path, int *out_len)
{
FILE *file = NULL;
if((file = fopen(path, "r")) != NULL)
{
fseek(file, 0, SEEK_END);
int length = ftell(file);
fseek(file, 0, SEEK_SET);
char *content = malloc(length+1);
fread(content, 1, length, file);
if(out_len != NULL)
{
*out_len = length;
}
fclose(file);
return content;
}
return NULL;
}
tc_shader_program_s tc_make_shader_program(char *vertex_path, char *fragment_path)
{
int vertex_shader = glCreateShader(GL_VERTEX_SHADER);
int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
int len_vertex_source = 0;
const char *vertex_source = load_file(vertex_path, &len_vertex_source);
const char *const *vsource = &vertex_source;
int len_fragment_source = 0;
const char *fragment_source = load_file(fragment_path, &len_fragment_source);
const char *const *fsource = &fragment_source;
glShaderSource(vertex_shader, 1, vsource, &len_vertex_source);
glShaderSource(fragment_shader, 1, fsource, &len_fragment_source);
glCompileShader(vertex_shader);
glCompileShader(fragment_shader);
free(vertex_source);
free(fragment_source);
int vertex_compile_status = 0;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &vertex_compile_status);
if(vertex_compile_status != GL_TRUE)
{
int log_length = 0;
glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &log_length);
char *info_log = malloc(log_length+1);
glGetShaderInfoLog(vertex_shader, log_length, &log_length, info_log);
printf("VERTEX SHADER FAILED COMPILING! ERROR: %s\n", info_log);
tc_shader_program_s invalid_program;
invalid_program.program_id = 0;
return invalid_program;
}
int fragment_compile_status = 0;
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &fragment_compile_status);
if(fragment_compile_status != GL_TRUE)
{
int log_length = 0;
glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &log_length);
char *info_log = malloc(log_length+1);
glGetShaderInfoLog(fragment_shader, log_length, &log_length, info_log);
printf("FRAGMENT SHADER FAILED COMPILING! ERROR: %s\n", info_log);
tc_shader_program_s invalid_program;
invalid_program.program_id = 0;
return invalid_program;
}
int program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
tc_shader_program_s shader_program;
shader_program.program_id = program;
return shader_program;
}
void tc_shader_uniform_mat4f(tc_shader_program_s *program, char *location, tc_mat4f_s matrix)
{
int location_id =
glGetUniformLocation(program->program_id, location);
glUniformMatrix4fv(location_id, 1, GL_TRUE, &matrix.values[0][0]);
}