0
votes

I'm very new to OpenGL and LibGdx. I started with these tutorials but wanted to apply a phong texture. I've tried to merge a number of examples but am having issues.

I've got a sphere and spinning cube on the center of the screen. I've still got hundreds of things to work out but for the moment, I don't understand why LibGdx is reporting that my uniform material can't be found...

Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: java.lang.IllegalArgumentException: no uniform with name 'uMvpMatrix' in shader

Pixel Shader

I don't believe the Fragment shader is relevant but it's at the bottom in case.

         #version 120
         uniform mat4 uMvpMatrix;
         varying vec3 diffuseColor; 
         // the diffuse Phong lighting computed in the vertex shader
         varying vec3 specularColor; 
         // the specular Phong lighting computed in the vertex shader
         varying vec4 texCoords; // the texture coordinates 

         void main()
         {                              
            vec3 normalDirection = 
               normalize(gl_NormalMatrix * gl_Normal);
            vec3 viewDirection = 
               -normalize(vec3(gl_ModelViewMatrix * gl_Vertex)); 
            vec3 lightDirection;
            float attenuation;

            if (0.0 == gl_LightSource[0].position.w) 
               // directional light?
            {
               attenuation = 1.0; // no attenuation
               lightDirection = 
                  normalize(vec3(gl_LightSource[0].position));
            } 
            else // point light or spotlight (or other kind of light) 
            {
               vec3 vertexToLightSource = 
                  vec3(gl_LightSource[0].position 
                  - gl_ModelViewMatrix * gl_Vertex);
               float distance = length(vertexToLightSource);
               attenuation = 1.0 / distance; // linear attenuation 
               lightDirection = normalize(vertexToLightSource);

               if (gl_LightSource[0].spotCutoff <= 90.0) // spotlight?
               {
                  float clampedCosine = max(0.0, dot(-lightDirection, 
                     gl_LightSource[0].spotDirection));
                  if (clampedCosine < gl_LightSource[0].spotCosCutoff) 
                     // outside of spotlight cone?
                  {
                     attenuation = 0.0;
                  }
                  else
                  {
                     attenuation = attenuation * pow(clampedCosine, 
                        gl_LightSource[0].spotExponent);
                  }
               }
            }

            vec3 ambientLighting = vec3(gl_LightModel.ambient); 
               // without material color!

            vec3 diffuseReflection = attenuation 
               * vec3(gl_LightSource[0].diffuse) 
               * max(0.0, dot(normalDirection, lightDirection)); 
               // without material color!

            vec3 specularReflection;
            if (dot(normalDirection, lightDirection) < 0.0) 
               // light source on the wrong side?
            {
               specularReflection = vec3(0.0, 0.0, 0.0); 
                  // no specular reflection
            }
            else // light source on the right side
            {
               specularReflection = attenuation 
                  * vec3(gl_LightSource[0].specular) 
                  * vec3(gl_FrontMaterial.specular) 
                  * pow(max(0.0, dot(reflect(-lightDirection, 
                  normalDirection), viewDirection)), 
                  gl_FrontMaterial.shininess);
            }

            diffuseColor = ambientLighting + diffuseReflection;
            specularColor = specularReflection;
            texCoords = gl_MultiTexCoord0;
            gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
         }

Setup

shader = new ShaderProgram(vertexShader, fragmentShader);
mesh = Shapes.genCube();
mesh.getVertexAttribute(Usage.Position).alias = "a_position";

Render

...
float aspect = Gdx.graphics.getWidth() / (float) Gdx.graphics.getHeight();
projection.setToProjection(1.0f, 20.0f, 60.0f, aspect);
view.idt().trn(0, 0, -2.0f);
model.setToRotation(axis, angle);
combined.set(projection).mul(view).mul(model);

Gdx.gl20.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

shader.begin();
shader.setUniformMatrix("uMvpMatrix", combined);
mesh.render(shader, GL20.GL_TRIANGLES);
shader.end();

Stack Trace

at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:113)
Caused by: java.lang.IllegalArgumentException: no uniform with name 'uMvpMatrix' in shader
at com.badlogic.gdx.graphics.glutils.ShaderProgram.fetchUniformLocation(ShaderProgram.java:283)
at com.badlogic.gdx.graphics.glutils.ShaderProgram.setUniformMatrix(ShaderProgram.java:539)
at com.badlogic.gdx.graphics.glutils.ShaderProgram.setUniformMatrix(ShaderProgram.java:527)
at com.overshare.document.Views.Test.onRender(Test.java:150)
    ...

Fragment Shader

#ifdef GL_ES
precision mediump float;
#endif
precision mediump float;       
varying vec4 v_Color;          
void main()                    
{                              
    gl_FragColor = v_Color;     
}                              

Can someone please tell me what I'm missing?

2

2 Answers

2
votes

I ran into something similar. I think because your shader doesn't use the "uMvpMatrix" uniform, it declaration gets optimized out, and so its "not there" when you go to set it. If you change your shader to reference the matrix in some way, you should get farther.

See (indirectly) Do (Unused) GLSL uniforms/in/out Contribute to Register Pressure?

I believe there are ways of developing and compiling shaders offline, so for a complex shader it may make sense to develop it outside of Libgdx (hopefully you'd get better error messages). Libgdx is just passing the giant string on to the lower layers, it doesn't do much with the shader itself, so there shouldn't be compatibility issues.

2
votes

Also, problem could be in precision specifier. On device(Nexus S) the next uniform defining will throw the same error:

uniform float yShift;

Using precision specifier solves the problem:

uniform lowp float yShift;

LibGDX allows to check shader compilation and get error log:

if(!shader.isCompiled()){
    String log = shader.getLog();
}

Finally, there's flag to ignore shader errors:

ShaderProgram.pedantic = false;