Add a shader program registry
This commit is contained in:
parent
9df2f0c64f
commit
30b00fc2c8
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue