Common Problems Running OpenGL Programs

These are a few common problems that cause people no small amount of consternation. If you have suggestions for things to be added to this list, please send them to me.

  1. For starters, don't overlook the possibility of these very common C/C++ errors:
  2. If you declare per-vertex ("in") or per-primitive ("uniform") variables in a GLSL shader program, but do not use them in such a way that they have the potential of actually affecting the output of your program, the compiler will not allocate storage for them, and calls to glGetUniformLocation and glGetAttribLocation will fail. For example, storage for scaleTrans will not be allocated, and your program will report a failure to locate both scaleTrans and mcPosition if your vertex shader looks like the following:
    #version 420 core
    
    in vec2 mcPosition;
    uniform vec4 scaleTrans;
    
    void main()
    {
    	gl_Position = vec4(0, 0, 0, 1);
    }

    Even if you use them like:

    #version 420 core
    
    in vec2 mcPosition;
    uniform vec4 scaleTrans;
    
    void main()
    {
    	float ldsX = scaleTrans[0]*mcPosition.x + scaleTrans[1];
    	float ldsY = scaleTrans[2]*mcPosition.y + scaleTrans[3];
    	gl_Position = vec4(0, 0, 0, 1);
    }
    the result will be similar because GLSL is so clever that it says "Hey, even though you actually used scaleTrans, it didn't actually affect the program (because the results did not get passed on), so I am not going to allocate storage for it." (The error message for mcPosition does not always appear in this variation.)
  3. Our framework initializes all PVA index and PPU location variables to -2. This is an easily testable invalid value that allows us, for example, to determine whether a variable has been initialized. The lookup routines (glGetAttribLocation and glGetUniformLocation) return -1 if the variable name is either invalid or cannot be located.

    Passing any invalid index to any PVA-related routine will log an error. According to the API description, passing any invalid index except -1 to glUniform* will log an error. (There are reasons that the invalid uniform location -1 is "special", but we will not go into that here.) Not all OpenGL implementations log an error when negative locations less than -1 are passed, however, and this is the source of the "common problem". If you are calling glUniform* with negative indices, you may not see any errors, hence you may mistakenly believe that you are setting uniforms when in fact you are not. When debugging problems that are related to values of uniform variables, be sure to check that all such locations have reasonable values. One debugging workaround would be to initialize all uniform location variables to large positive integers so that, if not assigned following program compilation, you will at least see error messages when they are used.

  4. Be sure you declare variables passed through shader stages identically in all shader programs. For example, errors from declaring such variables with different types will not be caught, but they will cause anomalous results in your programs. Consider, for example, the following vertex-fragment shader pair.

    Vertex shader:
    #version 420 core
    
    in float somePerVertexVariable;
    out float somePerVertexVariableToFS;
    
    void main()
    {
        somePerVertexVariableToFS = somePerVertexVariable;
        …
    }
    
    Fragment shader:
    #version 420 core
    
    in int somePerVertexVariableToFS; // uh-oh - should have been "float"
    
    void main()
    {
        …
    }
    
    The program will compile and run without generating errors, but your variable (somePerVertexVariableToFS) will most likely have an unexpected value.
  5. Don't forget to call glBindVertexArray in your render methods.