0
\$\begingroup\$

I'm very new to Android development and OpenGL ES 2.0.

I have been working through a book called "OpenGL ES 2 for Android A Quick Start Guide" which has been useful, but at times I get a bit lost as it doesn't explain some topics in enough depth in my opinion.

I currently have a vertex_shader.glsl file that looks like the following:

uniform mat4 u_Matrix;

attribute vec4 a_Position;
attribute vec4 a_Color;

varying vec4 v_Color;

//uniform double vehicleWidth;
//uniform double screenHeight;

void main() {
    v_Color = a_Color;

    gl_Position = u_Matrix * a_Position;
    //gl_PointSize = vehicleWidth * (2.0 / screenHeight);
    gl_PointSize = 15.0;
}

The parts that are commented out is what I wish to implement into the program. The vehicleWidth is something that will be a static value at the start of the page, but can change when the user inputs a different value for it. The screenHeight variable is the minimum value my camera can see in Google Maps. This value will change as often as the user changes the zoom level of the screen.

The information is being sent through two other classes: Color Shader Program

public class ColorShaderProgram extends ShaderProgram {
    // Uniform locations
    private final int uMatrixLocation;

    // Attribute locations
    private final int aPositionLocation;
    private final int aColorLocation;

    public ColorShaderProgram(Context context){
        super(context, R.raw.simple_vertex_shader,
            R.raw.simple_fragment_shader);
        // Retrieve uniform locations for the shader program.
        uMatrixLocation = glGetUniformLocation(program, U_MATRIX);
        //Retrieve attribute locations for the shader program.
        aPositionLocation = glGetAttribLocation(program, A_POSITION);
        aColorLocation = glGetAttribLocation(program, A_COLOR);
    }

    public void setUniforms(float[] matrix){
        // Pass the matrix into the shader program.
        glUniformMatrix4fv(uMatrixLocation, 1, false, matrix, 0);
    }

    public int getPositionAttributeLocation() {
        return aPositionLocation;
    }

    public int getColorAttributeLocation() {
        return aColorLocation;
    }
}

And the Shader Program:

public class ShaderProgram {
    // Uniform constants
    protected static final String U_MATRIX = "u_Matrix";
    protected static final String U_TEXTURE_UNIT = "u_TextureUnit";

    // Attribute constants
    protected static final String A_POSITION = "a_Position";
    protected static final String A_COLOR = "a_Color";
    protected static final String A_TEXTURE_COORDINATES = "a_TextureCoordinates";

    // Shader program
    protected final int program;
    protected ShaderProgram(Context context, int vertexShaderResourceId,
                        int fragmentShaderResourceId){
        // Compile the shaders and link the program.
        program = ShaderHelper.buildProgram(
            TextResourceReader.readTextFileFromResource(
                    context, vertexShaderResourceId),
            TextResourceReader.readTextFileFromResource(
                    context, fragmentShaderResourceId));
    }

    public void useProgram() {
        // Set the current OpenGL shader program to this program.
        glUseProgram(program);
    }
}

My question is, how do I set up the vertex_shader.glsl file so that I can send in dynamic information every time it renders?

EDIT: Also, how would I alter my ColorShaderProgram/ShaderProgram classes to allow me to send dynamic information into the GLSL file?

\$\endgroup\$
1
\$\begingroup\$

You're already halfway there since you send matrix data every frame.

A little bit of history. attributes used to be called varying because their value varies depending on the vertex in the buffer. uniforms are called such because their data is uniform across every vertex of the buffer. Since your matrix is uniform the GPU can handle it being changed at runtime since it's just one blob of data for the whole buffer. See what I'm getting at? You're already changing your uniform matrix every frame. Your matrix is "dynamic".

So just do what you did with the matrix.

When you setup your shader, you can get the location of the vehicleWidth uniform in your shader with:

uVehicleWidth = glGetUniformLocation(program, "vehicleWidth");

Then in your setUniforms method you can just send the vehicle width with:

glUniform1f(uVehicleWidth, vehicleWidth);

Just make sure that vehicleWidth is actually updated every frame.

The glUniformX calls are documented here: http://docs.gl/es2/glUniform

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.