title: My GLSL shader program links fine, but errors when I try to use it -- how do I debug this?
body: <p>If I had a syntax error in my GLSL, it would fail at link time, shouldn't it?</p>
  
  <p>Anyway, I tried running my program in glslDevil (never used this program before) and it just keeps repeating <code>wglGetCurrentContext()</code>. I'm not sure if it's supposed to do that, or it's getting confused because it's a CLR app.</p>
  
  <p>Is there an easier way to check for syntax errors in my GLSL code?</p>
  
  <p>It appears to be the fragment shader that's causing the problem....here's the code if needed:</p>
  
  <pre><code>#version 330
  
  const int MAX_POINT_LIGHTS = 2;
  
  in vec2 TexCoord0;
  in vec3 Normal0;
  in vec3 WorldPos0;
  
  out vec4 FragColor;
  
  struct BaseLight
  {
      vec3 Color;
      float AmbientIntensity;
      float DiffuseIntensity;
  };
  
  struct DirectionalLight
  {
      struct BaseLight Base;
      vec3 Direction;
  };
  
  struct Attenuation
  {
      float Constant;
      float Linear;
      float Exp;
  };
  
  struct PointLight
  {
      struct BaseLight Base;
      vec3 Position;
      Attenuation Atten;
  };
  
  uniform int gNumPointLights;
  uniform DirectionalLight gDirectionalLight;
  uniform PointLight gPointLights[MAX_POINT_LIGHTS];
  uniform sampler2D gSampler;
  uniform vec3 gEyeWorldPos;
  uniform float gMatSpecularIntensity;
  uniform float gSpecularPower;
  
  vec4 CalcLightInternal(struct BaseLight Light, vec3 LightDirection, vec3 Normal)
  {
      vec4 AmbientColor = vec4(Light.Color, 1.0f) * Light.AmbientIntensity;
      float DiffuseFactor = dot(Normal, -LightDirection);
  
      vec4 DiffuseColor  = vec4(0, 0, 0, 0);
      vec4 SpecularColor = vec4(0, 0, 0, 0);
  
      if (DiffuseFactor &gt; 0) {
          DiffuseColor = vec4(Light.Color, 1.0f) * Light.DiffuseIntensity * DiffuseFactor;
  
          vec3 VertexToEye = normalize(gEyeWorldPos - WorldPos0);
          vec3 LightReflect = normalize(reflect(LightDirection, Normal));
          float SpecularFactor = dot(VertexToEye, LightReflect);
          SpecularFactor = pow(SpecularFactor, gSpecularPower);
          if (SpecularFactor &gt; 0) {
              SpecularColor = vec4(Light.Color, 1.0f) *
                              gMatSpecularIntensity * SpecularFactor;
          }
      }
  
      return (AmbientColor + DiffuseColor + SpecularColor);
  }
  
  vec4 CalcDirectionalLight(vec3 Normal)
  {
      return CalcLightInternal(gDirectionalLight.Base, gDirectionalLight.Direction, Normal);
  }
  
  vec4 CalcPointLight(int Index, vec3 Normal)
  {
      vec3 LightDirection = WorldPos0 - gPointLights[Index].Position;
      float Distance = length(LightDirection);
      LightDirection = normalize(LightDirection);
  
      vec4 Color = CalcLightInternal(gPointLights[Index].Base, LightDirection, Normal);
      float Attenuation =  gPointLights[Index].Atten.Constant +
                           gPointLights[Index].Atten.Linear * Distance +
                           gPointLights[Index].Atten.Exp * Distance * Distance;
  
      return Color / Attenuation;
  }
  
  void main()
  {
      vec3 Normal = normalize(Normal0);
      vec4 TotalLight = CalcDirectionalLight(Normal);
  
      for (int i = 0 ; i &lt; gNumPointLights ; i++) {
          TotalLight += CalcPointLight(i, Normal);
      }
  
      FragColor = texture2D(gSampler, TexCoord0.xy) * TotalLight;
  }
  </code></pre>
  
  <hr>
  
  <p><strong>Edit:</strong> Specifically, I get <code>GL_INVALID_OPERATION</code> when I call <code>glUseProgram</code>. The docs say:</p>
  
  <blockquote>
    <p>GL_INVALID_OPERATION is generated if program is not a program object.</p>
    
    <p>GL_INVALID_OPERATION is generated if program could not be made part of
    current state.</p>
    
    <p>GL_INVALID_OPERATION is generated if glUseProgram is executed between
    the execution of glBegin and the corresponding execution of glEnd.</p>
  </blockquote>
  
  <p>But I don't think it can be the first or last case, because the program ran fine until I tweaked the shader. "could not be made part of the current state" doesn't give me much to go on.</p>