Add a shader program registry

This commit is contained in:
Kienan Stewart 2020-02-10 23:41:33 -05:00
parent 9df2f0c64f
commit 30b00fc2c8
3 changed files with 120 additions and 8 deletions

View File

@ -106,6 +106,8 @@ int main(int argc, char** argv)
const char* shader_list = "shaders/list.txt";
static struct ShaderRegistry shader_registry;
loadShadersFromFile(shader_list, &shader_registry);
static std::vector<RegisteredShaderProgram> shader_program_registry;
loadShaderProgramsFromFile("shaders/shader_programs.txt", &shader_registry, &shader_program_registry);
messager.registerCallback(&debug_messagebus_callback);
while(!glfwWindowShouldClose(window)) {
glfwPollEvents();

View File

@ -7,11 +7,13 @@
#include <stdlib.h>
#include <sstream>
#include <unistd.h>
#include <vector>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
enum ShaderType {
invalid = 0,
vertex = GL_VERTEX_SHADER,
fragment = GL_FRAGMENT_SHADER,
geometry = GL_GEOMETRY_SHADER,
@ -26,10 +28,21 @@ struct RegisteredShader {
GLuint shaderID;
} RegisteredShader;
struct RegisteredShaderProgram {
class RegisteredShaderProgram {
char *programName;
GLuint programID;
} RegisteredShaderProgram;
public:
RegisteredShaderProgram(char *name, GLuint programID) {
int name_size = strlen(name);
char *n = (char*) calloc(name_size, sizeof(char));
strncpy(n, name, name_size);
this->programName = n;
this->programID = programID;
};
~RegisteredShaderProgram() {
free(this->programName);
}
};
struct ShaderRegistry {
struct RegisteredShader *list = 0;
@ -62,7 +75,7 @@ struct RegisteredShader* find_shader(struct ShaderRegistry *r, char *name) {
int i = 0;
struct RegisteredShader *s = 0;
for(i; i < r->size; i++) {
s = (r->list) + (i * sizeof(struct RegisteredShader));
s = &r->list[i];
if(strcmp(s->shaderName, name) == 0) {
return s;
}
@ -96,10 +109,10 @@ void remove_shader_by_name(struct ShaderRegistry *r, char *name) {
struct ShaderProgramRegistry {
class ShaderProgramRegistry {
struct RegisteredShareProgram *list = 0;
int size = 0;
} ShaderProgramRegistry;
};
GLuint compile_shader(const char* file_path, int t) {
@ -136,10 +149,106 @@ GLuint compile_shader(const char* file_path, int t) {
glGetShaderInfoLog(shader_id, InfoLogLength, NULL, &error_message[0]);
printf("%s\n", &error_message[0]);
}
else {
printf("compiled shader %d from source %s\n", shader_id, file_path);
}
return shader_id;
}
int loadShaderProgramsFromFile(const char* file_path, struct ShaderRegistry *shader_registry,
std::vector<RegisteredShaderProgram> *program_registry) {
FILE *fp;
char *line;
size_t size = 0;
const char *delim = ":";
const char *delim2 = ",";
fp = fopen(file_path, "r");
if (fp == NULL) {
return -1;
}
char *name;
char *program_list;
char *file_path_copy = (char*) calloc(strlen(file_path), sizeof(char));
strncpy(file_path_copy, file_path, strlen(file_path));
char *base = dirname((char*) file_path_copy);
while((size = getline(&line, &size, fp)) != -1) {
if(size == 0) {
// Skipping, line length 0
continue;
}
if(line[0] == '#') {
// Skipping, line is a comment
continue;
}
char *line_copy = (char*) calloc(size, sizeof(char*));
strncpy(line_copy, line, size);
printf("%s\n", line_copy);
// Format <name>,<type>,<filepath>
name = strtok(line_copy, delim);
program_list = strtok(NULL, delim);
printf("%s\n", program_list);
if (name == NULL || program_list == NULL) {
// Invalid line, not enough elements.
// @TODO Inform the user.
free(line_copy);
name = program_list = NULL;
continue;
}
// Start a new Shader Program
char *program_list_copy = (char*) calloc(strlen(program_list), sizeof(char));
strncpy(program_list_copy, program_list, strlen(program_list));
char *new_line_pos = strrchr(program_list_copy, '\n');
if (new_line_pos) {
new_line_pos[0] = 0;
}
printf("%s\n", program_list_copy);
char *shader_name = strtok(program_list_copy, delim2);
char *last_shader_name = NULL;
GLuint program = glCreateProgram();
GLint Result = GL_FALSE;
do {
if (last_shader_name != NULL && shader_name == last_shader_name) {
shader_name = NULL;
break;
}
printf("sname %s ; last_shader %s\n", shader_name, last_shader_name);
struct RegisteredShader *rs = find_shader(shader_registry, shader_name);
if (rs == NULL) {
// Should this be an error, or a warning?
// @TODO Inform the user
printf("could not find shader '%s'", shader_name);
continue;
}
printf("linking program %d with shader %d\n", program, rs->shaderID);
glAttachShader(program, rs->shaderID);
last_shader_name = shader_name;
shader_name = strtok(NULL, delim2);
}
while (shader_name != NULL);
glLinkProgram(program);
// Check the program
int InfoLogLength;
glGetProgramiv(program, GL_LINK_STATUS, &Result);
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0){
std::vector<char> ProgramErrorMessage(InfoLogLength+1);
glGetProgramInfoLog(program, InfoLogLength, NULL, &ProgramErrorMessage[0]);
printf("%s\n", &ProgramErrorMessage[0]);
}
// Add to program_registry
if (InfoLogLength == 0) {
program_registry->push_back(RegisteredShaderProgram(name, program));
}
free(program_list_copy);
free(line_copy);
}
return 0;
}
int loadShadersFromFile(const char* file_path, struct ShaderRegistry *registry) {
FILE *fp;
char *line;
@ -201,10 +310,10 @@ int loadShadersFromFile(const char* file_path, struct ShaderRegistry *registry)
shader_type = geometry;
}
else {
shader_type = 0;
shader_type = invalid;
}
if(shader_type == 0) {
if(shader_type == invalid) {
// Invalid line, unknown type.
// @TODO Inform the user.
free(line_copy);

View File

@ -1,5 +1,6 @@
#version 300 es
out vec3 color;
// the precision mediump is required in 3.0es
out mediump vec3 color;
void main(){
color = vec3(1,0,0);
}