
Question on shaders
Posted Thursday, 10 June, 2010 - 16:50 by fireshadow4126 inHello. I'm working on an 3d gaming application, and I'm trying to use per-pixel lighting. However, when I run what I have, the application closes before showing anything and my log file shows SHADER_COMPILATION_ERROR. My vertex and fragment shaders are exactly the ones from Beginning OpenGL Game Programming 2nd Edition by Luke Benstead with Dave Astle and Kevin Hawkings. Here they are:
Vertex:
uniform mat4 projection_matrix; uniform mat4 modelview_matrix; uniform mat3 normal_matrix; uniform vec4 material_ambient; uniform vec4 material_diffuse; uniform vec4 material_specular; uniform vec4 material_emissive; uniform float material_shininess; struct light { vec4 position; vec4 diffuse; vec4 specular; vec4 ambient; float constant_attenuation; float linear_attenuation; float quadratic_attenuation; } uniform light light0; in vec3 a_Vertex; in vec2 a_TexCoord0; in vec3 a_Normal; out vec2 texCoord0; out vec3 normal; out vec3 lightDir; out vec3 halfVector; out vec4 vertDiffuse; out vec4 vertAmbient; out float dist; void main(void) { normal = normalize(normal_matrix * a_Normal); vec4 pos = modelview_matrix * vec4(a_Vertex, 1.0); vec3 lightPos = (modelview_matrix * light0.position).xyz; lightDir = lightPos - pos.xyz; vec3 E = -(pos.xyz); dist = length(lightDir); lightDir = normalize(lightDir); halfVector = normalize(lightPos + E); vertDiffuse = material_diffuse * light0.diffuse; vertAmbient = material_ambient * light0.ambient; texCoord0 = a_TexCoord0; gl_Position = projection_matrix * pos; }
Fragment:
uniform sampler2D texture0; uniform vec4 material_ambient; uniform vec4 material_diffuse; uniform vec4 material_specular; uniform vec4 material_emissive; uniform float material_shininess; struct light { vec4 position; vec4 diffuse; vec4 specular; vec4 ambient; float constant_attenuation; float linear_attenuation; float quadratic_attenuation; }; uniform light light0; in vec2 texCoord0; in vec3 normal; in vec3 lightDir; in vec3 halfVector; in vec4 vertDiffuse; in vec4 vertAmbient; in float dist; out vec4 outColor; void main(void) { vec3 N = normalize(normal); float NdotL = max(dot(N, normalize(lightDir)), 0.0); vec4 color = vec4(0.0); if (NdotL > 0.0) { color += vertDiffuse * NdotL; vec3 HV = normalize(halfVector); float NdotHV = max(dot(N, HV), 0.0); color += material_specular * light0.specular * pow(NdotHV, material_shininess); } float attenuation = 1.0 / (light0.constant_attenuation + light0.linear_attenuation * dist + light0.quadratic_attenuation * dist * dist); outColor = ((color * attenuation) + vertAmbient) * texture(texture0, texCoord0.st); }
Relevant parts of my GLSLProgram class:
public sealed class GLSLProgram { struct GLSLShader { public int id; public string filename; public string source; } private GLSLShader vertex_Shader; private GLSLShader fragment_Shader; private Dictionary<string, int> uniformMap; private Dictionary<string, int> attribMap; private int programID; public GLSLProgram(string vertShaderFile, string fragShaderFile) { vertex_Shader = new GLSLShader(); fragment_Shader = new GLSLShader(); uniformMap = new Dictionary<string, int>(); attribMap = new Dictionary<string, int>(); vertex_Shader.filename = vertShaderFile; fragment_Shader.filename = fragShaderFile; readShaderSources(); } public bool Init() { Thread.Sleep(1); programID = GL.CreateProgram(); vertex_Shader.id = GL.CreateShader(ShaderType.VertexShader); fragment_Shader.id = GL.CreateShader(ShaderType.FragmentShader); if (!(vertex_Shader.filename.Equals("INTERNAL")) && !(fragment_Shader.filename.Equals("INTERNAL"))) { readShaderSources(); } if (vertex_Shader.source.Equals(String.Empty) || fragment_Shader.source.Equals(String.Empty)) { SurviveErrors.SetErrorFlag("SHADER_SOURCE_NONEXISTANT_ERROR"); return false; } GL.ShaderSource(vertex_Shader.id, vertex_Shader.source); GL.ShaderSource(fragment_Shader.id, fragment_Shader.source); if (!compileShader(vertex_Shader) || !compileShader(fragment_Shader)) { SurviveErrors.SetErrorFlag("SHADER_COMPILATION_ERROR"); return false; } GL.AttachShader(programID, vertex_Shader.id); GL.AttachShader(programID, fragment_Shader.id); GL.LinkProgram(programID); return true; } public void Unload() { GL.DetachShader(programID, vertex_Shader.id); GL.DetachShader(programID, fragment_Shader.id); GL.DeleteShader(vertex_Shader.id); GL.DeleteShader(fragment_Shader.id); GL.DeleteProgram(programID); } private bool compileShader(GLSLShader shader) { GL.CompileShader(shader.id); int result = 12047375; GL.GetShader(shader.id, ShaderParameter.CompileStatus, out result); if (result == 0) { Console.Error.WriteLine("Your shader has errors. Please validate."); return false; } return true; } private void readShaderSources() { using (TextReader reader = File.OpenText(vertex_Shader.filename)) { while (reader.Peek() > -1) { vertex_Shader.source += reader.ReadLine(); } } using (TextReader reader = File.OpenText(fragment_Shader.filename)) { while (reader.Peek() > -1) { fragment_Shader.source += reader.ReadLine(); } } } public void BindShader() { GL.UseProgram(programID); } }
I'm on Windows XP 32-bit Professional. I have an Intel I7 Core Duo and an NVIDIA GeForce 210.
Please help! Thanks in advance.


Comments
Re: Question on shaders
Check what
GL.GetShaderInfoLog(shader.id)returns when the shader fails to compile. It should point to the exact location of the error (line number and error type).Re: Question on shaders
ouch. I did that for just the vertex shader to try it and it returned this:
What is this?!
Re: Question on shaders
Now that's a good question...
I have a feeling that readShaderSources() truncates line endings, confusing the compiler. Try this, instead:
Re: Question on shaders
ReadAllText() seemed to help a little bit. Note that I also changed my code to get errors from both the vertex shader and the fragment shader. What's weird is that the fragment shader produces no errors, and it didn't even before I used ReadAllText(). Anyway, the log file now becomes:
Re: Question on shaders
You need to specify #version 130 (or higher) to use "in" and "out" specifiers. (Previous versions used "attribute" and "varying" instead.)
Moreover, your vertex shader seems to be missing a semicolon after the closing bracket of the light struct:
Re: Question on shaders
I just saw that before you posted. I added the #version 130 line to the top of both shaders and removed the light struct and replaced it with uniforms. The code doesn't produce any errors in the log file now, but when I run my code I see a window for a split second before it exits out. (Sigh)