Search code examples
opengl-esglsles

Some uniforms work others don't


I'm having trouble with OpenGLES shader pipeline. I have a shader with 3 uniforms

attribute vec4 position;

uniform mat4 modelViewProjection;
uniform vec3 objectColor;
uniform vec2 positionObject;

void main()
{
    vec4 pos = vec4(-positionObject.x + objectColor.x, 0, -positionObject.y, 0);
    gl_Position =  modelViewProjection * (position + pos);
}

modelViewProjection and positionObject work just fine, however while trying to get fragment shader to work I noticed that objectColor doesn't do anything so I tried experimenting in vertex shader, and then eventually found out that it always stayed initial value no matter what order it is defined, what type it is, it's name etc.

I'm following the standard procedure of the shader pipeline:

compiling -> linking -> use program -> get location -> initialize uniform

and the objectColor uniform even gets an ID of being an active uniform and it is counted towards active uniforms, however whenever I try to change it's value it always stays at zero.

Here's the snippets of the code:

Uniform location:

private void BindUniforms()
{
    glUniforms[(int)UNIFORMS_T.MODEL_VIEW_PROJECTION] = GL.GetUniformLocation(glProgramId, "modelViewProjection");
    glUniforms[(int)UNIFORMS_T.OBJECT_POSITION] = GL.GetUniformLocation(glProgramId, "positionObject");
    glUniforms[(int)UNIFORMS_T.OBJECT_COLOR] = GL.GetUniformLocation(glProgramId, "objectColor");
}

Rendering part 1:

protected override void OnRenderFrame(FrameEventArgs e)
{
    base.OnRenderFrame(e);

    GL.ClearColor(0f, 0f, 0f, 1f);
    GL.Clear((uint)All.ColorBufferBit);
    GL.UseProgram(shader.glProgram);

    GL.UniformMatrix4(shader.GetUniform(Shader.UNIFORMS_T.MODEL_VIEW_PROJECTION), 1, false, ref modelViewProjection.Row0.X);
    GL.Uniform3(shader.GetUniform(Shader.UNIFORMS_T.OBJECT_COLOR), 1, 1, 1);

    lattice.Draw();

    SwapBuffers();
}

Rendering part 2:

    public void Draw()
    {
        //Update Uniform
        GL.Uniform2(shader.GetUniform(Shader.UNIFORMS_T.OBJECT_POSITION), 1, ref m_vec2Position.X);
        GL.Uniform3(shader.GetUniform(Shader.UNIFORMS_T.OBJECT_COLOR), 1, 1, 1);

        var colVal = new Vector3(-1, -1, -1); //becomes 0, 0, 0
        var posVal = new Vector2(-1, -1);     //becomes arbitrary value
        GL.GetUniform(shader.glProgram, shader.GetUniform(Shader.UNIFORMS_T.OBJECT_COLOR), ref colVal.X);
        GL.GetUniform(shader.glProgram, shader.GetUniform(Shader.UNIFORMS_T.OBJECT_POSITION), ref posVal.X);

        // Update attribute values.
        GL.BindBuffer(All.ArrayBuffer, glVBO);
        GL.VertexAttribPointer((int)Shader.ATTRIBUTES_T.VERTEX_POSITION, 3, All.Float, false, sizeof(float) * 3, IntPtr.Zero);
        GL.EnableVertexAttribArray((int)Shader.ATTRIBUTES_T.VERTEX_POSITION);

        GL.BindBuffer(All.ElementArrayBuffer, glVBI);
        GL.DrawElements(All.LineStrip, Indices.Length, All.UnsignedShort, IntPtr.Zero);

        GL.BindBuffer(All.ArrayBuffer, 0);
        GL.BindBuffer(All.ElementArrayBuffer, 0);
    }

I'm most likely missing something trivial but I can't seem to find it... Using Xamarin with Android.


Solution

  • Nevermind, it seems that GL.Uniform* overload that takes individual values instead of reference outright don't work at least in OpenGLES20.