4

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.

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
ArcticLord
  • 3,999
  • 3
  • 27
  • 47

3 Answers3

10

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.

Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
2

You need to declare a uniform before you set it through glUniform1f. So, make the myValue as uniform.

uniform float myValue;

The next thing is you need its location to bind a value. You can do that using glGetUniformLocation function.

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

And finally, you set a uniform for that location using the glUniform functions.

GLES20.glUniform1f(valuePosition, 0.5f);

And you can achieve the same result even using attributes. Attributes are efficient for constantly changing values, whereas uniforms are efficient for less changing values.

Sri Harsha Chilakapati
  • 11,744
  • 6
  • 50
  • 91
0

Try modifying following:

"attribute float myValue;\n" -> "uniform float myValue;\n"

and

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

Also, have a look at following documentation page, which shows more cleaner way of translating and scaling vertices.

http://developer.android.com/reference/android/opengl/Matrix.html

user3161880
  • 1,037
  • 6
  • 13