GLSL Linking problem

Started by
7 comments, last by weasalmongler 15 years, 11 months ago
Hi, I have a problem while linking a very simple shader with GLSL. After searching google for a while I am aware that NVIDIA seems to have some problems with their drivers, but I was wondering if it was something that could be fixed. The compilation fails at the linking stage with the following error messages: (0) : error C0000: syntax error, unexpected $end at token "<EOF>" (0) : error C0501: type name expected at token "<null atom>" The shaders themselves look like this. Vertex Shader:

varying vec3 vecNormal, vecUntranNormal;

uniform float radius;

void main()
{
	vecNormal 	= gl_NormalMatrix * gl_Normal;
	vecUntranNormal = gl_Normal;
	gl_TexCoord[0] 	= gl_MultiTexCoord0;
	gl_Position 	= gl_ModelViewProjectionMatrix * gl_Vertex;
}

Pixel Shader:

varying vec3 vecNormal, vecUntranNormal;

uniform sampler2D tex0;

void main()
{
	vec4 color;
	color = vec4(1.0, 0.0, 0.0, 1.0);
	gl_FragColor = color;
}

The bug exists on my Windows XP machine, with driver 169.21, and also on my Windows Vista machine, with driver 175.12. My vista machine is dual boot with Linux (Fedora 8) and it works fine on that. I have made sure that my shader text files have the correct line endings when taking them from linux (I typed them out again by hand in wordpad, so it should be in the correct windows format). I have also made sure that the buffer that I am loading the shaders into was cleared to zeros first (as stated by the phantom in another thread that I found). Nothing so far has worked. Does anyone have any ideas what is causing it or what I could do to fix it? Thanks in advance.
Advertisement
Output looks like something I saw yesterday - the compiler in the NV Windows XP driver, does not like nested block-comments, e.g.

/*
<GLSL CODE>
/*
<MORE GLSL CODE>
*/
<GLSL CODE>
*/

Is the shader code you post the complete string being sent to the driver?
I have a GF8800 GTS with the 169.21 drivers. Both shaders work for me on my Windows XP machine.

But I can reproduce nearly the same error message that you get when trying to compile an empty shader. That is I get the error after doing glCompileShader and then retrieving the GL_COMPILE_STATUS.
Yes, the shader code posted is the exact code that is loaded in the file and compiled. There are no comments so it can't be that unfortunately. My test XP machine has a 7800GTS and my Vista machine has an 8800GTX, so if anyone who has a similar machine and driver could test this shader then it'd be really useful.

I've decided to post the code that loads the shader as well in case there is a problem with it.

	std::fstream filestream;	char *vsdata, *psdata;	int filelength;	CXMLFile shaderfile(filename);	std::string error;	int compileresult = 0;	int infologLength = 0;    int charsWritten  = 0;    char *infoLog;    unsigned int uniformloc;		//Initialize internal variables	this->shadername 	= filename;	if(shaderfile.IsOpen())	{		this->vsname		= shaderfile.GetValue("/shader/vertex");		this->psname		= shaderfile.GetValue("/shader/pixel");	}	this->id			= 0;	this->loaded		= false;		//Attempt to load vertex shader data	filestream.open(this->vsname.data(), std::ios::in);		if(filestream.is_open())	{		//Load in our data		filestream.seekg(0, std::ios_base::end);		filelength = filestream.tellg();		filestream.seekg(0, std::ios_base::beg);		vsdata = new char[filelength+1];		memset(vsdata, 0, filelength+1);		filestream.read(vsdata, filelength);		filestream.close();	}	else	{		//Log which file cannot be opened		error =  "CShader::CShader - Vertex shader '";		error += this->vsname;		error += "' from the shader file '";		error += this->shadername;		error += "' could not be loaded";		g_cLog.WriteError(ERROR_WARNING, error);		return;	}		//Load the pixel shader	filestream.open(this->psname.data(), std::ios::in);			if(filestream.is_open())	{		//Load in our data		filestream.seekg(0, std::ios_base::end);		filelength = filestream.tellg();		filestream.seekg(0, std::ios_base::beg);		psdata = new char[filelength+1];		memset(psdata, 0, filelength+1);		filestream.read(psdata, filelength);		filestream.close();	}	else	{		//Log which file cannot be opened		error =  "CShader::CShader - Pixel shader '";		error += this->psname;		error += "' from the shader file '";		error += this->shadername;		error += "' could not be loaded";		g_cLog.WriteError(ERROR_WARNING, error);		return;	}		//Submit to OpenGL and link them	this->vsid = glCreateShader(GL_VERTEX_SHADER);	glShaderSourceARB(this->vsid, 1, (const char**)&vsdata,NULL);	glCompileShaderARB(this->vsid);		glGetShaderiv(this->vsid, GL_COMPILE_STATUS, &compileresult);	if (compileresult != GL_TRUE)	{		error =  "CShader::CShader - GLSL compilation of '";    	error += this->shadername;    	error += "' failed.";    	g_cLog.WriteError(ERROR_WARNING, error);			    			glGetShaderiv(this->vsid, GL_INFO_LOG_LENGTH, &infologLength);		if (infologLength > 0)	    {	    	infoLog = new char[infologLength];	    	glGetInfoLogARB(this->vsid, infologLength, &charsWritten, infoLog);			g_cLog.WriteError(ERROR_WARNING, infoLog);			delete[] infoLog;	    }		return;	}		this->psid = glCreateShader(GL_FRAGMENT_SHADER);	glShaderSourceARB(this->psid, 1, (const char**)&psdata,NULL);	glCompileShaderARB(this->psid);		glGetShaderiv(this->psid, GL_COMPILE_STATUS, &compileresult);	if (compileresult != GL_TRUE)	{		error =  "CShader::CShader - GLSL compilation of '";    	error += this->shadername;    	error += "' failed.";    	g_cLog.WriteError(ERROR_WARNING, error);    			glGetShaderiv(this->psid, GL_INFO_LOG_LENGTH, &infologLength);		if (infologLength > 0)		{			infoLog = new char[infologLength];	    	glGetInfoLogARB(this->psid, infologLength, &charsWritten, infoLog);			g_cLog.WriteError(ERROR_WARNING, infoLog);			delete[] infoLog;		}		return;	}		this->id = glCreateProgram();				glAttachShader(this->id,this->vsid);	glAttachShader(this->id,this->psid);	glLinkProgram(this->id);	//Check it linked ok	glGetProgramiv(this->id, GL_LINK_STATUS, &compileresult);	if (compileresult != GL_TRUE)	{		error =  "CShader::CShader - GLSL compilation of '";    	error += this->shadername;    	error += "' failed.";    	g_cLog.WriteError(ERROR_WARNING, error);    			glGetShaderiv(this->id, GL_INFO_LOG_LENGTH, &infologLength);		if (infologLength > 0)		{			infoLog = new char[infologLength];	    	glGetInfoLogARB(this->id, infologLength, &charsWritten, infoLog);			g_cLog.WriteError(ERROR_WARNING, infoLog);			delete[] infoLog;		}		return;	}	//Free our resources	if(vsdata)		delete[] vsdata;	if(psdata)		delete[] psdata;


If anyone can spot an error then I'd be much appreciated. I've spent all day today trying to fix this bug and I'm stuck. Thanks again.
OK. Looked through your code and this line is suspicious:

glShaderSourceARB(this->vsid, 1, (const char**)&vsdata,NULL);


Seems you tell the driver to read only 1 character from your "string". Then the driver performs correctly when failing. Try supplying the correct length of the string.
According to the documentation, the second parameter (1 in this case) is the number of strings being submitted in the 3rd parameter. As there is only 1 string, I've set it to 1. The last parameter is the size of each string, which I set to NULL so that it assumes the strings I submit to be null terminated. I have also tried getting the strings length and submitting this instead of NULL, but it made no difference. Thanks for the input though!
Sorry, you're right about the semantics of the arguments. Well, it is definitely a problem in your C++, I assume you make sure the string is null terminated?

EDIT: Noticed the memset... Well, most be related to the programming enviroment (C++ includes?!). Your shader source also works fine in my Java shader wrapper-class on Windows XP and if it was a bug in their WHQL driver it would have been found long ago.
Yeah, you are right, there is a bug in my code somewhere. For some reason the filelength found for the pixel shader is 0 and thus loads nothing at that point. I'm too tired to find the cause now, I'll look for it in the morning. Thanks for the help.
I've fixed it now, turned out that I needed a call to filestream.clear() in order to clear all the end of file flags and stuff after loading the first file. It works correctly now. Thanks for everyones help.

This topic is closed to new replies.

Advertisement