0

I've been trying to load my vertex shader from a file in c. Here is my code for loading the characters in a file into a string:

char* path = "shaders/vertex_shader.glsl";

if (!fopen(path, "r")) {
    printf("Could not open shader file! %s", path);
    exit(1);
}

FILE* shader = fopen(path, "r");
fseek(shader, 0, SEEK_END);
long file_size = ftell(shader);
rewind(shader);
char *vertex_shader_code = malloc(sizeof(char) * file_size + 1);
fread(vertex_shader_code, sizeof(char), file_size, shader);

vertex_shader_code[file_size] = '\0';
printf("%s", vertex_shader_code);
fclose(shader);

The vertex_shader.glsl file looks like this:

#version 330 core

layout (location = 0) in vec3 positions;

void main() {
   gl_Position = vec4(positions.x, positions.y, positions.z, 1.0);
}

However, whenever I print out the vertex_shader_code string I get a bunch of garbage characters at the bottom of the file:

#version 330 core

layout (location = 0) in vec3 positions;

void main() {
   gl_Position = vec4(positions.x, positions.y, positions.z, 1.0);
}
════════

Also whenever, I try to compile the shader I get the following error:

 0(8) : error C0000: syntax error, unexpected $undefined at token "<undefined>"

Code for compiling the vertex shader:

void checkShaderCompilation(int shader_type_number, GLuint shader) {
    int success;
    char log[512];
    char* shader_type;

    switch (shader_type_number) {
        case 0: 
            shader_type = "Vertex Shader";
            break;
        case 1:
            shader_type = "Fragment Shader";
            break;
        default:
            printf("Invalid number has been provided for the shader_type_number (check function declaration)\n");
            return;
    }

    glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
    
    if (!success) {
        glGetShaderInfoLog(shader, 512, NULL, log);
        printf(" %s \n Compilation ERROR:\n %s\n", shader_type, log);
        exit(1);
    }
    else {
        printf("%s compiled successfully!\n", shader_type);
    }
}

/* Compiling the vertex shader */
vertex_shader_object = glCreateShader(GL_VERTEX_SHADER); 
glShaderSource(vertex_shader_object, 1, &vertex_shader_code, NULL);
glCompileShader(vertex_shader_object);
checkShaderCompilation(0, vertex_shader_object);
Ali Awan
  • 180
  • 10
  • You're writing out-of-bounds with `vertex_shader_code[file_size] = '\0';`. You also read one `char` too many from the file with `fread(vertex_shader_code, sizeof(char), file_size, shader);`. – G.M. May 08 '22 at 10:31
  • I still get the garbage characters after removing the +1 when I was initializing file_size and after having removed this line `vertex_shader_code[file_size] = '\0';` – Ali Awan May 08 '22 at 10:36
  • You're also leaking a file from the first `fopen`. – interjay May 08 '22 at 11:19
  • Do I have to run `fclose(shader)` in the if statement as well? – Ali Awan May 08 '22 at 11:44

2 Answers2

2

You have various off-by-one errors in your code. That part that calculates file_size and reads the shader should be (untested)...

long file_size = ftell(shader);
rewind(shader);
char *vertex_shader_code = malloc(sizeof(char) * file_size + 1);
fread(vertex_shader_code, sizeof(char), file_size, shader);

vertex_shader_code[file_size] = '\0';

Notes:

  1. I've removed the cast of the value returned by malloc. See here.
  2. sizeof(char) is essentially redundant as it always evaluates to 1.
G.M.
  • 12,232
  • 2
  • 15
  • 18
  • Even after replacing my code with yours I still get the garbage characters at the end of the string and I still get the same errors when I try to compile the shader. – Ali Awan May 08 '22 at 11:48
  • @AliAwan Please add an update to your question showing the updated code. – G.M. May 08 '22 at 11:53
  • I've updated the code now. – Ali Awan May 08 '22 at 14:59
  • @AliAwan Please undo the last edit to your post and append the updated code as an *extra* section otherwise the original question/erroneous code is lost and the post becomes misleading. – G.M. May 08 '22 at 15:12
  • @AliAwan I've tried the code in my answer on various input files and it all appears to be functionally correct. Are you sure you haven't accidentally included the extra characters in your shader file? Have you checked the output of `cat shaders/vertex_shader.glsl`? – G.M. May 08 '22 at 15:15
  • I have and it all seems to be correct. I can't figure out why my gpu can't compile the shader. – Ali Awan May 08 '22 at 15:20
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/244593/discussion-between-ali-awan-and-g-m). – Ali Awan May 08 '22 at 19:17
0

It appears that I just had to open the file in binary mode:

FILE* shader  = fopen(path, "rb");
Ali Awan
  • 180
  • 10