Sign in to follow this  
weasalmongler

GLSL Linking problem

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this