How to use glUniform1f in this example?

android, java, opengl-es, textureview

Solution

You're mixing the concepts of `attribute` and `uniform` variables.

Since you declared your `myValue` variable as an `attribute` in the shader, you need to set the value with `glVertexAttrib()`:

glVertexAttrib1f(valuePosition, 1.5f);

If you want it to be a `uniform`, change the declaration in the vertex shader to:

uniform float myValue;

and the call to get the location to:

int valuePosition = GLES20.glGetUniformLocation(mProgram, "myValue");

Both solutions are valid. As the name suggests, `uniform` variables are ideal for values that do not change much, i.e. they ideally stay the same for the whole frame. `attribute` variables are more efficient for values that change frequently while rendering a frame.

Problem

I've searched for, read and tried many different examples on how to pass a value into a GLSL program. But sadly every try was a fail :( What I plan to do is very simple: Just a little open gl 3d animation inside my Android App. Resulting from my GUI design I prefer to use a TextureView as OpenGl Surface. I found some code that fits perfect to my project. But my problem seems to be completely inside this example. When I compile and run it, it does exactly what it is supposed to do. Draw one single triangle on screen. Then I modified the Vertex Shader like this: ``` final String vertexShaderSource = "attribute vec4 position;\n" + "attribute float myValue;\n" + "void main () {\n" + "vec4 oo;\n"+ "oo[0] = position[0];\n"+ "oo[1] = position[1] * myValue;\n"+ "oo[2] = position[2];\n"+ "oo[3] = position[3];\n"+ "gl_Position = oo;\n" + "}"; ``` And now, I want to pass a value to the attribute `myValue`. So here are my modifications to the run method. ``` public void run() { initGL(); int attribPosition = GLES20.glGetAttribLocation(mProgram, "position"); checkGlError(); int valuePosition = GLES20.glGetAttribLocation(mProgram, "myValue"); checkGlError(); System.out.println("att id:"+ attribPosition + " val id:" + valuePosition); //[...] while (true) { checkCurrent(); mVertices.position(0); GLES20.glVertexAttribPointer(attribPosition, 3, GLES20.GL_FLOAT, false, 0, mVertices); checkGlError(); GLES20.glUniform1f(valuePosition, 1.5f); checkGlError(); //[...] } } ``` From my understanding, this should expand the triangle on y-axis with factor 1.5f. But it is not working. The ouput of my debug line is: ``` I/System.out(22427): att id:1 val id:0 ``` So these should be correct locations since none of them has -1 content. But by passing the value `1.5f` to `myValue` with `glUniform1f`, the only result I can achieve is the continuous `OpenGL Error 0x502` output. There is no triangle anymore, because the shader script will not receive the `1.5f` and will use the value 0 to expand it. I really hope someone could explain me, how to get this done. Because it is something so fundamental I think I am missing something very obvious here.

Original source