0

I have used the below fragment shader on a number of Windows 7 & 8 PCs without problem.

#ifndef STRINGIFY
#define STRINGIFY(a) #a
#endif

char *fsFont  = STRINGIFY(

precision mediump float;
varying vec2 v_texCoord;
vec2 v_texCoord;
uniform sampler2D s_texture;
uniform vec4      vColor4;

varying lowp vec4 DestinationColor;

void main()
{
  gl_FragColor = vec4( 1, 1, 1, texture2D( s_texture, v_texCoord).a ) * vColor4;
}

);

Recently I tried running my app on a Windows 10 machine and I get the following errors when I try to compile the shader:

0x0059f3dc "0(1) : warning C7022: unrecognized profile specifier "mediump"
0(1) : warning C7022: unrecognized profile specifier "precision"
0(1) : error C1038: declaration of "v_texCoord" conflicts with previous declaration at 0(1)
0(1) : error C0000: syntax error, u"

And if I comment out the precision mediump float line..

0x0137f2c8 "0(1) : error C0000: syntax error, unexpected identifier, expecting "::" at token "lowp"
"

What's the problem? Is it because the PC I'm using supports a different version of OpenGL than I'm expecting?

UPDATE: This post suggests that precision mediump float line is only for OpenGL ES. That still doesn't explain why it works on most of my PCs. Moving on, what's wrong with the lowp declaration?

Here's my SDL initialisation code which chooses the OpenGL profile/version:

#ifndef _WIN32
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES );
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 2 );
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 0 );
#else
  // Use OpenGL 3.1 core 
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 ); 
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
#endif

UPDATE: Here is the updated shader which is now working thanks to the comments from everybody:

char *fsFont  = 

"#version 330\n"
"precision mediump float;\n"
"varying vec2 v_texCoord;\n"

"uniform sampler2D s_texture;"
"uniform vec4      vColor4;"

"varying lowp vec4 DestinationColor;"

"void main()"
"{"
  "gl_FragColor = vec4( 1, 1, 1, texture2D( s_texture, v_texCoord).a ) * vColor4;"
"}"

;                 

UPDATE: I've removed STRINGIFY from all of my shaders, moved to OpenGL 3.3. All of my shaders compile with one exception:

    char *vs3DShader  = 

    "#version 330\n"
    "layout (location = 0) in vec3 Position;"
    "layout (location = 1) in vec4 color;"
    "layout (location = 2) in vec3 normal;"

    "out vec4 frag_color;"

    "uniform mat4 transform;"

    "void main()"
    "{"
    "  gl_Position = transform * vec4( Position.x, Position.y, Position.z, 1.0 );"

    "  // Pass vertex color to fragment shader.."
    "  frag_color = color;"
    "}"
;

Error:

0x0055f370 "(0) : error C0000: syntax error, unexpected $end at token "<EOF>"
"
SparkyNZ
  • 6,266
  • 7
  • 39
  • 80
  • 2
    Which OpenGL profile are you targeting? In OpenGL3 Core Profile, there is no varying keyword. And what should `v_texCoord` be? You are also missing a `#version ...` line. – BDL Mar 05 '18 at 19:26
  • 4
    Please read the error messages. The variable `v_texCoord` is declared twice! – Rabbid76 Mar 05 '18 at 19:29
  • @BDL I should be using OpenGL3.1. I'll paste the SDL initialisation code I'm using into my question. Do you always need to put #version lines in shaders? I had a lot of confusion about this when trying to get my app to use an OpenGL shader (on Windows) and an OpenGL ES shader (on Android). – SparkyNZ Mar 05 '18 at 19:30
  • 2
    Absence of a `#version` directive implies `#version 110` which is rarely what you want. So always specify. – genpfault Mar 05 '18 at 19:35
  • The desktop glsl spec says to precision qualifiers: "Precision qualifiers are added for code portability with OpenGL ES, not for functionality. They have the same syntax as in OpenGL ES, as described below, but they have no semantic meaning, which includes no effect on the precision used to store or operate on variables." They are no problem, but they are of no use either. – BDL Mar 05 '18 at 19:41
  • @genpfault OK I'll put #version 310 into my shader(s). For some reason I thought #version didn't work but it may have been because of the stringify macro I used. Happy to get rid of that though. – SparkyNZ Mar 05 '18 at 19:41
  • 1
    `#version 310` is not a thing. You want [`#version 140`](https://en.wikipedia.org/wiki/OpenGL_Shading_Language#Versions). As far as `#` in macros goes I use [this](https://stackoverflow.com/a/13874526/44729) for embedding GLSL programs. – genpfault Mar 05 '18 at 19:43
  • 1
    Also note, that your `STRINGIFY` macro does **not** preserve newline characters. So whenever you need a new line (for example after the version), you'll have to add a \n. [Source](https://stackoverflow.com/questions/19741257/c-preprocessor-stringification-that-preserves-newlines) – BDL Mar 05 '18 at 19:44
  • @Rabbid76 Good spotting. I probably copied it to comment it out before posting :) – SparkyNZ Mar 05 '18 at 19:46
  • @genpfault Why is #version 310 not a thing - is that not the OpenGL version but the GLSL version? – SparkyNZ Mar 05 '18 at 19:47
  • @genpfault I appear to have used #version 330 in my other shaders. – SparkyNZ Mar 05 '18 at 19:49
  • 1
    Read [the page I linked to](https://en.wikipedia.org/wiki/OpenGL_Shading_Language#Versions): there's never been a `#version 310`, embedding the OpenGL major/minor version numbers into the GLSL `#version` string didn't start until OpenGL 3.3 with `#version 330`. – genpfault Mar 05 '18 at 19:49
  • 2
    @SparkyNZ: Please use raw string literals when you need to do stuff like this, not "STRINGIFY" macros. – Nicol Bolas Mar 05 '18 at 19:50
  • @NicolBolas. Noted. My other shaders don't use it and I won't be using it any more. :) – SparkyNZ Mar 05 '18 at 19:54
  • OK, its working fine now with #version 330. Its happy with or without mediump float as somebody mentioned above. Feel free to add an answer and I'll accept it. I'm still confused as to why this works on some PCs. I guess different machines must default to different versions of OpenGL defaults if not specified? – SparkyNZ Mar 05 '18 at 19:57
  • 4
    I still highly doubt that everything works as it should. If you are really using #version 330, then you should get tons of errors because varying has been removed and replaced by in/out. Also using OpenGL 3.1 with 3.3 shaders sounds fishy. – BDL Mar 05 '18 at 20:03
  • @BDL I'll change the SDL initialisation to use 3.3 instead of 3.1. – SparkyNZ Mar 05 '18 at 20:13
  • 2
    It would be soo much easier if you would show us a up-to-date and complete version of your code. As for now: You are missing some new lines. For example, the comment line starting with // will make everything until the next newline to a comment. In your case: Everything till the end of your code. – BDL Mar 05 '18 at 20:19
  • @BDL I'll copy the updated original shader for you. Aha, of course. I see what you mean about the comment now. I changed this shader from using STRINGIFY so that's why the comment became a problem. – SparkyNZ Mar 05 '18 at 20:35
  • How do you "comment out" the line? If you try to use `//` you get undefined behavior, because use of a `//` comment in a macro argument is undefined according to the standard... – Chris Dodd Mar 06 '18 at 00:53
  • @ChrisDodd The original shader in question didn't have any comments in it. While applying #version to all of the other shaders, one of the shaders which was not using the STRINGIFY() macro had a comment in it. GLSL must allow comments. – SparkyNZ Mar 06 '18 at 01:03

1 Answers1

0

The shader wouldn't compile because:

  • there was no #version line in the shader source (version was undefined and could have been any default on the different machines)
  • STRINGIFY() macro doesn't work with # characters so it would be better to load the shader as text from a file or specify it with double quotes around each line, remembering to use \n after lines starting with '#' or comments - preferably each line to be on the safe side
  • when attempting to remove STRINGIFY(), new line characters must be added after any comments, otherwise everything that is appended after the comment will be commented out
  • a duplicate variable had been introduced while trying to figure out why warnings/errors were being generated for mediump and varying keywords
  • Correct GLSL #version must be used that corresponds to the version of OpenGL being used as indicated by genpfault in this table (ie. OpenGL3.1 must use #version 140)
SparkyNZ
  • 6,266
  • 7
  • 39
  • 80