If I had a syntax error in my GLSL, it would fail at link time, shouldn't it?
Anyway, I tried running my program in glslDevil (never used this program before) and it just keeps repeating wglGetCurrentContext(). I'm not sure if it's supposed to do that, or it's getting confused because it's a CLR app.
Is there an easier way to check for syntax errors in my GLSL code?
It appears to be the fragment shader that's causing the problem....here's the code if needed:
#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 > 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 > 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 < gNumPointLights ; i++) {
TotalLight += CalcPointLight(i, Normal);
}
FragColor = texture2D(gSampler, TexCoord0.xy) * TotalLight;
}
Edit: Specifically, I get GL_INVALID_OPERATION when I call glUseProgram. The docs say:
GL_INVALID_OPERATION is generated if program is not a program object.
GL_INVALID_OPERATION is generated if program could not be made part of current state.
GL_INVALID_OPERATION is generated if glUseProgram is executed between the execution of glBegin and the corresponding execution of glEnd.
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.
struct BaseLight, but it's not a declaration, it's a usage. I got this from a tutorial, but I thought that looked funny.... Edit: Hah! It was.glGetShaderInfoLog()) and link (glGetProgramInfoLog()) logs?