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";
|
const char* shader_list = "shaders/list.txt";
|
||||||
static struct ShaderRegistry shader_registry;
|
static struct ShaderRegistry shader_registry;
|
||||||
loadShadersFromFile(shader_list, &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);
|
messager.registerCallback(&debug_messagebus_callback);
|
||||||
while(!glfwWindowShouldClose(window)) {
|
while(!glfwWindowShouldClose(window)) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
enum ShaderType {
|
enum ShaderType {
|
||||||
|
invalid = 0,
|
||||||
vertex = GL_VERTEX_SHADER,
|
vertex = GL_VERTEX_SHADER,
|
||||||
fragment = GL_FRAGMENT_SHADER,
|
fragment = GL_FRAGMENT_SHADER,
|
||||||
geometry = GL_GEOMETRY_SHADER,
|
geometry = GL_GEOMETRY_SHADER,
|
||||||
|
@ -26,10 +28,21 @@ struct RegisteredShader {
|
||||||
GLuint shaderID;
|
GLuint shaderID;
|
||||||
} RegisteredShader;
|
} RegisteredShader;
|
||||||
|
|
||||||
struct RegisteredShaderProgram {
|
class RegisteredShaderProgram {
|
||||||
char *programName;
|
char *programName;
|
||||||
GLuint programID;
|
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 ShaderRegistry {
|
||||||
struct RegisteredShader *list = 0;
|
struct RegisteredShader *list = 0;
|
||||||
|
@ -62,7 +75,7 @@ struct RegisteredShader* find_shader(struct ShaderRegistry *r, char *name) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
struct RegisteredShader *s = 0;
|
struct RegisteredShader *s = 0;
|
||||||
for(i; i < r->size; i++) {
|
for(i; i < r->size; i++) {
|
||||||
s = (r->list) + (i * sizeof(struct RegisteredShader));
|
s = &r->list[i];
|
||||||
if(strcmp(s->shaderName, name) == 0) {
|
if(strcmp(s->shaderName, name) == 0) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -96,10 +109,10 @@ void remove_shader_by_name(struct ShaderRegistry *r, char *name) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct ShaderProgramRegistry {
|
class ShaderProgramRegistry {
|
||||||
struct RegisteredShareProgram *list = 0;
|
struct RegisteredShareProgram *list = 0;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
} ShaderProgramRegistry;
|
};
|
||||||
|
|
||||||
|
|
||||||
GLuint compile_shader(const char* file_path, int t) {
|
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]);
|
glGetShaderInfoLog(shader_id, InfoLogLength, NULL, &error_message[0]);
|
||||||
printf("%s\n", &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;
|
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) {
|
int loadShadersFromFile(const char* file_path, struct ShaderRegistry *registry) {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *line;
|
char *line;
|
||||||
|
@ -201,10 +310,10 @@ int loadShadersFromFile(const char* file_path, struct ShaderRegistry *registry)
|
||||||
shader_type = geometry;
|
shader_type = geometry;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
shader_type = 0;
|
shader_type = invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(shader_type == 0) {
|
if(shader_type == invalid) {
|
||||||
// Invalid line, unknown type.
|
// Invalid line, unknown type.
|
||||||
// @TODO Inform the user.
|
// @TODO Inform the user.
|
||||||
free(line_copy);
|
free(line_copy);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#version 300 es
|
#version 300 es
|
||||||
out vec3 color;
|
// the precision mediump is required in 3.0es
|
||||||
|
out mediump vec3 color;
|
||||||
void main(){
|
void main(){
|
||||||
color = vec3(1,0,0);
|
color = vec3(1,0,0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue