4

Finally isolated the issue of my shader not being able to be used to it failing to compile.

Here is my shader loading routine. The first part reads in the shader:

void GLSLShader::LoadFromFile(GLenum whichShader, const string filename) { ifstream fp; // Attempt to open the shader fp.open(filename.c_str(), ios_base::in); // If the file exists, load it if(fp) { // Copy the shader into the buffer string buffer(std::istreambuf_iterator<char>(fp), (std::istreambuf_iterator<char>())); // Debug output to show full text of shader errorLog.writeSuccess("Shader debug: %s", buffer.c_str()); LoadFromString(whichShader, buffer); } else { errorLog.writeError("Could not load the shader %s", filename.c_str()); } } 

After it has loaded it into a string, it sends it to be loaded:

void GLSLShader::LoadFromString(GLenum type, const string source) { // Create the shader GLuint shader = glCreateShader(type); // Convert the string const char * ptmp = source.c_str(); glShaderSource(shader, 1, &ptmp, NULL); // Compile the shader glCompileShader(shader); // Check to see if the shader has loaded GLint status; glGetShaderiv (shader, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { GLint infoLogLength; glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &infoLogLength); GLchar *infoLog= new GLchar[infoLogLength]; glGetShaderInfoLog (shader, infoLogLength, NULL, infoLog); errorLog.writeError("could not compile: %s", infoLog); delete [] infoLog; } _shaders[_totalShaders++]=shader; } 

I am getting the debug output "could not compile: " and it seems that the error buffer is empty. This has been driving me crazy for the past 3 days. Does anyone see my error?

Here are the very simple shaders:

#version 330 layout (location = 0) in vec4 position; layout (location = 1) in vec4 color; smooth out vec4 theColor; void main() { gl_Position = position; theColor = color; } #version 330 smooth in vec4 theColor; out vec4 outputColor; void main() { outputColor = theColor; } 

UPDATE

It looks like for some reason there is crap being added to the end of the shader in memory. I am not sure why. I have tried reading it in to a char* and a string. Here is the output:

<-!-> Shader: #version 330 layout (location = 0) in vec4 position; layout (location = 1) in vec4 color; smooth out vec4 theColor; void main() { gl_Position = position; theColor = color; } n <-!-> Shader: #version 330 smooth in vec4 theColor; out vec4 outputColor; void main() { outputColor = theColor; } nts/Resources 

Notice the 'n' at the end of the first shader and the 'nts/Resources' at the end of the second one. Any idea why?

ANOTHER UPDATE

The crap at the end was caused by an extra line at the end. I removed it and it is back to outputting the correct shader text. Still no luck thought with compiling.

I am at a loss here. The Superbible has their extensive libraries that are unoptimized and I don't need. There doesn't seem to be a damn decent shader compiler for Mac. I really don't mind how simple it is. It just needs to work with shaders. Does anyone have an example?

9
  • Have you tried allocating the error string with malloc instead? Commented Jul 23, 2012 at 4:16
  • Having read very quickly, I'd be willing to bet reasonable money that your OpenGL implementation is incorrectly returning zero for GL_INFO_LOG_LENGTH. Try clamping it to a reasonable minimum (256 bytes, say) and using that, just for kicks. Broadly, my experience has been that the more obscure glGet*() enumerants tend to work at something around 50% reliability between implementations. Commented Jul 23, 2012 at 4:35
  • Also when you step through in the debugger, are you verifying that the read from disk happened correctly? Commented Jul 23, 2012 at 4:43
  • @user1118321 Yes, the shader text outputs correctly. Possible that it has an extra space or something. Just a guess. Commented Jul 23, 2012 at 5:30
  • @AndyRoss I forced the buffer to 256 and still no output... Commented Jul 23, 2012 at 5:39

1 Answer 1

2

You're calling glShaderSource without supplying the length of each string in the sources array. Hence the string supplied is assumed to be terminated by a null byte ('\0'). The way you're reading the file into memory does not terminate the shader source with an additional null byte. So the GLSL compiler will read beyond the end of the shader source into random memory, where it finds… garbage.

Solution: Either add a terminating null byte, or supply the shader text lengths parameter.

Sign up to request clarification or add additional context in comments.

2 Comments

Though your answer sounds reasonable, considering the garbage at the end of his shaders, I cannot see where he could read garbage. He reads it into a std::string (which doesn't need any explicit NUL appended) and then obtains the C-string from this with c_str(), which in turn guarantees NUL-termination.
@ChristianRau: Buggy STL implementation maybe. Anyway, the simple solution, that works regardless of a null terminator present or not is just supplying the length of the strings provided to glShaderSource. One should do this anyway.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.