Shader compilation and on-screen drawing

   Regarding the shader language of opengl es, I recommend an address: http://imgtec.eetrend.com/blog/1948, this article is quite well written, if you are interested, you can take a look.

    I briefly summarize here, uniform is read-only in shader and cannot be modified, its value can only be injected by OpenGL ES API. Attribute is equivalent to the API of OpenGL ES to inject data into vertex shaders. The difference between it and uniform is: uniform is a global constant, which is visible to both vertex shaders and fragment shaders; Attributes are for each Vertex input data, and can only be used in vertex shaders. varying is used to pass data from the vertex shader to the fragment shader. During the rasterization stage, varying variables will be linearly interpolated.

 

     Let's move on to compiling shaders.

     In Android, shader files are always placed under the raw folder, so we need to read the content into memory first. The next steps are as follows:

      1. Create a new shader object.

          int shaderID = GLES20.glCreateShader(type);

        The type here can represent GLES20.GL_VERTEX_SHADER for vertex shaders, and GLES20.GL_FRAGMENT_SHADER for fragment shaders.

     2. Upload and compile the source code of the shader

         GLES20.GLES20.glShaderSource(shaderID, shaderCode);
        GLES20.glCompileShader(shaderID);

      The shaderCode here represents the string content of the vertex shader or fragment shader read from the raw folder.

     3. Perform the first and second steps on the vertex shader and fragment shader.

     4. Create a new opengl program. Note that the program here refers to the components in opengl.

        int programID = GLES20.glCreateProgram();

      5. Attach the IDs of the vertex shader and fragment shader we created earlier to this opengl program.

       GLES20.glAttachShader(programID, vertexShaderID);
       GLES20.glAttachShader(programID, fragmentShaderID);

      6. Link the program, link the vertex shader with the fragment shader.

       GLES20.glLinkProgram(programID);

       7. Use the opengl program we created

        GLES20.glUseProgram(programID);

 

        Then we talk about how to inject data into the shader through the opengl es interface. Let's take the shader below as an example:

vertex shader

attribute vec4 a_Position;

void main()
{
    gl_Position = a_Position;
}

Fragment shader:

precision mediump float;

uniform vec4 u_Color;

void main()
{
    gl_FragColor = u_Color;
}

        Inject data into the uniform property:

        1. GLES20. Get the location of the uniform

         String U_COLOR = "u_Color";

         int  colorPosition = GLES20.glGetUniformLocation(program, U_COLOR);

         2. Pass data to uniform

         GLES20.glUniform4f(colorPosition, 1, 1, 1, 1);

 

         Inject data into the Attribute property:

         1. Get the location of the property

         String A_POSITION = "a_Position";

         positionLocation = GLES20.glGetAttribLocation(program, A_POSITION);

         2. An array of associated attributes and vertex data

          GLES20.glVertexAttribPointer(positionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, 0, vertexArray);

        3. Start the vertex array

        GLES20.glEnableVertexAttribArray(positionLocation);

 

        In addition to the drawing part, drawing can be divided into three drawing methods: array drawing, vertex index drawing, and buffer drawing

        1. Array drawing, GLES20.glDrawArrays(type, startPosition, count);

        2. Vertex index drawing, GLES20.glDrawElements(type, indexCount, dataType, indexArray);

        3. Buffer drawing is divided into buffer object creation and buffer drawing. Buffers are divided into vertex buffers and index buffers.

         For example, the creation of vertex buffer objects:

              int buffers[] = new int[1];

              GLES20.glGenBuffers(length,)//Generate buffer

              bufferID = buffers[0];

              GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);//Bind buffer

               FloatBuffer vertexArray = ................//Generate floatBuffer and inject data

                vertexArray.position(0);

           GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexArray.capacity()*BYTES_PER_FLOAT, vertexArray, GLES20.GL_STATIC_DRAW); //Pass the data in native to GPU

               GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);//Unbind

 

        Creating an index buffer object is similar to creating a vertex buffer object, just make the following changes to the above code:

              1. Use short[] and ShortBuffer as types             

              2. Use GLES20.GL_ELEMENT_ARRAY_BUFFER instead of GLES20.GL_ARRAY_BUFFER

           Drawing through the buffer, you can use GLES20.glDrawElements(), but you need to bind and unbind the buffer before and after use.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325459192&siteId=291194637