Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [SOLVED] Loading a shader: pre-mature EOF parse error  (Read 11324 times)

0 Members and 1 Guest are viewing this topic.

DragonDePlatino

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
[SOLVED] Loading a shader: pre-mature EOF parse error
« on: July 12, 2016, 02:53:55 am »
For my game project, I have a fog of war shader that hides out-of-view enemies:

Code: [Select]
uniform sampler2D objtexture;
uniform sampler2D fogtexture;
uniform sampler2D lighttexture;

void main()
{
    // Load textures into pixels
    vec4 objpixel = texture2D(objtexture, gl_TexCoord[0].xy);
    vec4 fogpixel = texture2D(fogtexture, gl_TexCoord[0].xy);
    vec4 lightpixel = texture2D(lighttexture, gl_TexCoord[0].xy);
   
    // Draw objects if a lighttexture pixel is fully-transparent
    // Otherwise, hide objects behind fog
    bool changealpha = bool(ceil(lightpixel.a));
    objpixel = vec4((lightpixel.rgb) * float(changealpha) + objpixel.rgb * float(!changealpha), lightpixel.a * float(changealpha) + objpixel.a * float(!changealpha));
    objpixel = mix(objpixel, fogpixel, fogpixel.a);
   
    gl_FragColor = objpixel;
}

When running the program from Code::Blocks, everything works fine. Running the executable, it isn't finding fog.frag file. I could include the fog.frag in the download, but I'd rather not have users cheat and edit the shader. As a solution, I tried embedding the shader in my program like the example shown here.

After running it through a Notepad++ macro to eliminate any human error, my shader now looks like this:

Code: [Select]
const std::string shaderdata = "uniform sampler2D objtexture;" \
"uniform sampler2D fogtexture;" \
"uniform sampler2D lighttexture;" \
"" \
"void main()" \
"{" \
"    // Load textures into pixels" \
"    vec4 objpixel = texture2D(objtexture, gl_TexCoord[0].xy);" \
"    vec4 fogpixel = texture2D(fogtexture, gl_TexCoord[0].xy);" \
"    vec4 lightpixel = texture2D(lighttexture, gl_TexCoord[0].xy);" \
"    " \
"    // Draw objects if a lighttexture pixel is fully-transparent" \
"    // Otherwise, hide objects behind fog" \
"    bool changealpha = bool(ceil(lightpixel.a));" \
"    objpixel = vec4((lightpixel.rgb) * float(changealpha) + objpixel.rgb * float(!changealpha), lightpixel.a * float(changealpha) + objpixel.a * float(!changealpha));" \
"    objpixel = mix(objpixel, fogpixel, fogpixel.a);" \
"    " \
"    gl_FragColor = objpixel;" \
"}";

Unfortunately, if I compile, I get this error:

Code: [Select]
Failed to compile fragment shader:
Fragment shader failed to compile with the following errors:
ERROR: 0:1: error(#131) Syntax error: pre-mature EOF parse error
ERROR: error(#273) 1 compilation errors.  No code generated

If I print out my shaderdata string, it looks just fine. If I remove all of the comments, line breaks and empty lines, I get the same exact error. Looking at the special characters in Notepad++, all I see are line breaks, tabs and spaces. Could someone please explain what I'm doing wrong?
« Last Edit: July 27, 2016, 12:34:02 am by DragonDePlatino »

Lee R

  • Jr. Member
  • **
  • Posts: 86
    • View Profile
Re: Loading a shader: pre-mature EOF parse error
« Reply #1 on: July 26, 2016, 02:28:48 pm »
I'd hazard a guess that the GLSL parser has problems reading certain code fragments when they're all munged together: since no newline character appears inside of the quoted strings, the expression used to initialize 'shaderdata' evaluates to a single line of text.

Try using C++11 raw string literals (or, if you're stuck with an older compiler, place a \n on the end of each string):
const std::string shaderdata = R"(
uniform sampler2D objtexture;
uniform sampler2D fogtexture;
uniform sampler2D lighttexture;

void main()
{
    // Load textures into pixels
    vec4 objpixel = texture2D(objtexture, gl_TexCoord[0].xy);
    vec4 fogpixel = texture2D(fogtexture, gl_TexCoord[0].xy);
    vec4 lightpixel = texture2D(lighttexture, gl_TexCoord[0].xy);

    // Draw objects if a lighttexture pixel is fully-transparent
    // Otherwise, hide objects behind fog
    bool changealpha = bool(ceil(lightpixel.a));
    objpixel = vec4((lightpixel.rgb) * float(changealpha) + objpixel.rgb * float(!changealpha), lightpixel.a * float(changealpha) + objpixel.a * float(!changealpha));
    objpixel = mix(objpixel, fogpixel, fogpixel.a);

    gl_FragColor = objpixel;
})"
;
 

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Loading a shader: pre-mature EOF parse error
« Reply #2 on: July 26, 2016, 03:11:56 pm »
If the whole shader is on the same line, everything that appears after the first // is commented out, leaving an unfinished shader code.

Your code should work without comments, but yes raw string literals are better.
Laurent Gomila - SFML developer

Lee R

  • Jr. Member
  • **
  • Posts: 86
    • View Profile
Re: Loading a shader: pre-mature EOF parse error
« Reply #3 on: July 26, 2016, 03:47:46 pm »
Quote from: Laurent
Your code should work without comments [...]

You would think so, but apparently it didn't:
Quote
If I remove all of the comments, line breaks and empty lines, I get the same exact error.

DragonDePlatino

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
Re: Loading a shader: pre-mature EOF parse error
« Reply #4 on: July 27, 2016, 12:33:52 am »
Raw string literals? Hmm! I've never heard of those. And considering I'm learning C++ as I go, that's not a huge surprise.

Anyways, that works great! Now I can run the executable without an external fog.frag. Thank you for your help. Also, could the tutorial here be updated with this information?

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Re: [SOLVED] Loading a shader: pre-mature EOF parse error
« Reply #5 on: July 29, 2016, 10:07:09 am »
Raw string literals are "new" (in C++11).

As for normal literals: Just look at the following snippet. All the strings are essentially the same, since they're concatenated and the line breaks are outside the strings:

const char *a = "Hello World!";
const char *b = "Hello"" ""World!";
const char *c = "Hello"
                " "
                "World!";