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 that have nothing to do with OpenGL, but which have been the source of many problems in student programs developed for this class:
  2. Develop your GLSL shader programs a little bit at a time. Debugging can be tricky, especially if you write a couple hundred lines of code before seeing if any of it will compile and execute correctly. Start from something you know that works. Add a little; make sure it works; etc.
  3. 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 (made from our shaderIF->ppuLoc and shaderIF->pvaLoc, respectively) 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 the same 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.)
  4. The lookup routines (glGetUniformLocation and glGetAttribLocation – again, as called from our shaderIF->ppuLoc and shaderIF->pvaLoc, respectively) return -1 if the variable name cannot be located (i.e., is undefined). Passing an invalid index to attribute setting routines is an error. Not all OpenGL implementations actually log an error under all situations, however, and this is the source of the "common problem". If you call, say, glUniform* with a negative index, you may not see an error, hence you may mistakenly believe that you are setting the variable when in fact you are not. When debugging problems that are related to values of uniform variables, be sure to check that all such uniform locations returned by our lookup routines have reasonable values.
  5. 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.
  6. Don't forget to call glBindVertexArray in your render methods.