0

I'm trying to use simple glsl shader loaded from file. This is what I have:

GLuint
shdld(char *path) {
    GLuint shd;
    GLint cflag, nlog;
    FILE *fp;
    int i, c;
    GLchar source[1000], elog[1000];


    fp = fopen(path, "r");
    if (fp == NULL) {
        printf("Unable to open file %s\n", path);
        return 0;
    }

    for (i = 0; (c = getc(fp)) != EOF; i++)
        source[i] = c;
    source[i++] = '\0';

    fclose(fp);

    shd = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(shd, 1, source, NULL);
    glCompileShader(shd);

    cflag = GL_FALSE;
    glGetShaderiv(shd, GL_COMPILE_STATUS, &cflag);
    if (cflag == GL_FALSE) {
        glGetShaderInfoLog(shd, sizeof elog, NULL, elog);
        printf("Unable to compile shader %s\n", path);
        printf("%s\n", elog);
        glDeleteShader(shd);
        return 0;
    }
    return shd;

}

Unfortunately the shader doesn't compile and what is worse elog contains some garbage content instead the log message. My question is: How to get the error message and display it into stdout in order to debug my shader?

ghi
  • 1
  • 1

2 Answers2

2

How are you sure that the file does not contain more than 1000 characters, either increase the buffer size, or

Change this part

for (i = 0; (c = getc(fp)) != EOF; i++)
    source[i] = c;
source[i++] = '\0';

if you simply get the file size, this is one possible way to get it

size_t fileSize;

fseek(fp, 0, SEEK_END);
fileSize = ftell(fp);
rewind(fp);

then you can declare source as GLchar *source, and allocate it dynamically

source = malloc((1 + fileSize) * sizeof(GLchar));
if (source == NULL) /* always check the output of malloc */
    return SOME_INVALIDE_GLuint;
source[fileSize] = '\0';     

then

fread(source, szeof(GLchar), fileSize, fp); // check return value to ensure fileSize bytes were read
fclose(fp);

and at the end don't forget to

free(source);
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
1

This should not even compile if you have any kind of strict error checking. At the very least it should give you a warning if you have a reasonable warning level enabled.

In this call:

GLchar source[1000], elog[1000];
...
glShaderSource(shd, 1, source, NULL);

The 3rd argument has the wrong type. The prototype of glShaderSource() is:

void glShaderSource(GLuint shader, GLsizei count, const GLchar **string, const GLint *length);

Note that the 3rd argument is a pointer to a pointer, while you pass an array, which decays to a pointer when you pass it as function argument.

The call needs to be:

GLchar* sourcePtr = source;
glShaderSource(shd, 1, &sourcePtr, NULL);
Reto Koradi
  • 53,228
  • 8
  • 93
  • 133