[SOLVED] Shader in GLSL100 reports No matching function for call to mod(float, int)

I’ve had a user (on I believe an old system requiring GLSL100) report the following error with my shader:

RendererException: compile error in: ShaderSource[name=MatDefs/repeatingFrag.frag, defines, type=Fragment, language=GLSL100]
ERROR: 0:68: No matching function for call to mod(float, int)
ERROR: 0:69: No matching function for call to mod(float, int)
ERROR: 0:71: Use of undeclared identifier ‘progression’
ERROR: 0:71: Use of undeclared identifier ‘progression’
ERROR: 0:75: Use of undeclared identifier ‘calculatedTexCoord’

I believe because I’ve accidentally written my shader to be only GLSL150 compatible not GLSL100

  • Those errors I know look relatively self explanatory but other variables (e.g. color) look to be declared in the same way without recieving this error, what exactly is meant by “Use of undeclared identifier”?

  • I’ve also looked up the mod function and it appears available in all versions of openGl: mod - OpenGL 4 Reference Pages. Is there something else I need to do to make this GLSL100 compatible?

This is my fragment shader

#import "Common/ShaderLib/GLSLCompat.glsllib"

#if defined(HAS_GLOWMAP) || defined(HAS_COLORMAP) || (defined(HAS_LIGHTMAP) && !defined(SEPARATE_TEXCOORD))
    #define NEED_TEXCOORD1
#endif

#if defined(DISCARD_ALPHA)
    uniform float m_AlphaDiscardThreshold;
#endif

uniform float m_SunlightIntensity;
uniform vec4 m_Color;
uniform sampler2D m_ColorMap;
uniform sampler2D m_LightMap;

const vec2 unit = vec2(1,1);

varying vec2 texCoord1; //starts
varying vec2 texCoord2;
varying vec2 texCoord3; //ends
varying vec2 texCoord4; //0 to noOfRepeats over the quad
varying vec4 texCoord5; //this is the night (or source) color

varying vec4 vertColor;

void main(){

    vec4 color = vec4(1,1,1,1);

    vec2 progression = vec2 (mod (texCoord4.x, 1),
                            mod (texCoord4.y, 1));

    vec2 calculatedTexCoord = progression * texCoord3 + ( unit - progression ) * texCoord1  ;                


    #ifdef HAS_COLORMAP
        color *= texture2D(m_ColorMap, calculatedTexCoord);     
    #endif

    color.x *= max(vertColor.x * m_SunlightIntensity,texCoord5.x);
    color.y *= max(vertColor.y * m_SunlightIntensity,texCoord5.y);
    color.z *= max(vertColor.z * m_SunlightIntensity,texCoord5.z);
    color.a *= vertColor.a;

    #ifdef HAS_COLOR
        color *= m_Color;
    #endif

    #ifdef HAS_LIGHTMAP
        #ifdef SEPARATE_TEXCOORD
            color.rgb *= texture2D(m_LightMap, texCoord2).rgb;
        #else
            color.rgb *= texture2D(m_LightMap, texCoord1).rgb;
        #endif
    #endif

    #if defined(DISCARD_ALPHA)
        if(color.a < m_AlphaDiscardThreshold){
           discard;
        }
    #endif

    gl_FragColor = color;
}

Edit, the user reported their system as:
AMD Radeon R9 M370X
2048 MB
Intel Iris Pro 1536 MB

Which I think is an OpenGl2.1 system according to http://feedback.wildfiregames.com/report/opengl/device/Radeon%20R9%20M370X

Here’s a little tip, never ever (ever!) initialize floats in shaders without a dot as that will treat them like integers. Some versions of glsl then crash because there isn’t an explicit cast to float defined.

So,

vec4 color = vec4(1.0,1.0,1.0,1.0);

instead of

vec4 color = vec4(1,1,1,1);

Same goes for the mod params in your case. That should fix all of your problems.

Also another tip, if you’re developing on an Nvidia GPU, use glsl 110 instead. It’s the same as 100 but it doesn’t enable comptibility mode on nvidia cards so they throw the same errors that an AMD or Intel card would. I wish I had known that a long time ago, would’ve saved a ton of headaches.

3 Likes

Ah!

So:

vec4 color = vec4(1.0,1.0,1.0,1.0);

vec2 progression = vec2 (mod (texCoord4.x, 1.0),
                        mod (texCoord4.y, 1.0));

vec2 calculatedTexCoord = progression * texCoord3 + ( unit - progression ) * texCoord1  ;                

Are the “Use of undeclared identifier” problems caused by the problems on earlier lines (so false positives)

Do you mean declare my material as taking glsl 110, and committing that, or just for testing?

Yep.

It’s likely, everything regarding progression and calculatedTexCoord looks correct from what I can tell.

Well you can set that in the j3md on the 100 technique. For the end user there really shouldn’t be a difference if the shader is written right.

Note: there is no such thing as GLSL100. It’s not a real version. JME uses that as “no version” and so in 3.1 the shader will end up defaulting to wahtever the graphics driver wants. On an nVidia, this puts it into compatibility mode so will allow all kinds of non-compliant stuff.

You can solve this in two ways:
-use JME 3.2 For JME 3.2, GLSL100 will put the #version 110 line in your shader on desktop and the appropriate thing in your shader on mobile.
-specifically declare GLSL110 which is the first real OpenGL shader version. Your shaders will then throw proper errors locally… but will no longer work on mobile.

1 Like

The reporting user has just got back in touch and that resolves the problem! Thank you for your help!

@pspeed I have been meaning to upgrade so this may be the push to actually do it

2 Likes

In the mean time, if you just declare your shaders as GLSL110 instead of GLSL100 then you will find errors locally… there is no other side effect other than not being able to deploy to mobile devices.

1 Like