I'm trying to read a basic Shader line by line from an external file I wrote for a C program. In the file there are two shaders: Vertex and Fragment. I created this function to read it line by line and also determine which shader it is reading and return the struct ParsedShader
.
typedef struct {
char* vertex;
char* fragment;
} ParsedShader;
static ParsedShader ParseShader(char *filepath) {
char* vert;
char* frag;
vert = "\n";
frag = "\n";
char line[128];
enum ShaderType {
NONE = -1,
VERTEX = 0,
FRAGMENT = 1
};
enum ShaderType type = NONE;
FILE* file;
fopen_s(&file, filepath, "r");
while (fgets(line, sizeof(line), file)) {
if (strstr(line, "#shader")) {
if (strstr(line, "vertex")) type = VERTEX;
else if (strstr(line, "fragment")) type = FRAGMENT;
}
else {
if (type == VERTEX) {
//Put Lines into vert char *
//Here is where I don't know what to do
}
else if (type == FRAGMENT) {
//Put Lines into frag char *
//Here I don't know what to do either
}
}
}
fclose(file);
ParsedShader result;
result.vertex = vert;
result.fragment = vert;
return result;
}
The problem is I have not been able to put text in the vert
and frag
variables because of memory. I know it must be done using the malloc
and realloc
functions, but just couldn't make it work. I already created a function which frees the memory:
static DeleteShader(ParsedShader* shader) {
if (shader) {
free(shader->vertex);
free(shader->fragment);
}
}
Initialiation:
vert = calloc(1, sizeof(char));
This will allocate one element and initialize it to zero (end of string).
Adding strings:
vert = realloc(vert, strlen(vert) + strlen(line) + 1);
strcat(vert, line);
This will re-allocate buffer to have the concatenated string (including end-of-string mark) and then concatenate strings.
You can do the same things for frag
.
This code is ineffective because it will scan strings many times to measure their length, but it should work for files whose sizes is upto a few KB.
Adding error checks for calloc
and realloc
will make the code safer.