OpenGL ES learning Chapter 3: Define a simple texture

You can read about it in this article

  • OpenGL ES draws the flow at the application layer
  • Define a simple triangle texture process
  • Define a simple triangle texture using native code

OpenGL ES draws in three steps

  • Define texture
  • Defining the renderer
  • Define the EGL environment

Define texture

Texture can be understood as a Bitmap used to draw on a View in Android page development. It has three life cycles: load, draw and release

  1. Loading textures
  2. textures
  3. Release the texture
  4. Helper method
1. Define the texture base class interface class, including the above lifecycle methods
interface ITexture {
    // Load the texture
    fun surfaceCreated(a)
    // Draw a texture
    fun updateTexImage(a){}
    // Release the texture
    fun surfaceDestroyed(a)
    // Auxiliary methods
    fun surfaceChanged(w: Int, h: Int){}
    fun setTextureSize(w: Int, h: Int){}}Copy the code
2. Define the simplest texture implementation: triangle texture

Vertex shader design: The triangle has only one plane. We define an array of vertices and submit it to the gl_Position variable in the vertex shader

private val vertexCoords = floatArrayOf(OpenGL world coordinate system
        -1f, -1f./ / lower left
        1f, -1f./ / right
        0f.0f/ / left
    )

private val vertexShader = "attribute vec4 aPosition;" +
            "void main(){" +
            " gl_Position=aPosition;" +
            "}"
Copy the code

Fragment shader design: The fragment shader colors vertex-submitted structures, in this case writing dead red

private val fragShader = "precision mediump float;" +
            "void main(){" +
            "Gl_FragColor =vec4(1.0, 0.0, 0.0, 1.0);" +
            "}"
Copy the code

You can then implement the texture’s three key life cycles using ShaderUtil as a utility class method. This method is relatively fixed, do not describe, see by yourself. I also advise you not to worry about the details. Once packaged, you will rarely see it unless you compile or link shader code to check for bugs.

override fun surfaceCreated(a) {
    vertexBuffer = ByteBuffer.allocateDirect(vertexCoords.size * 4).run {
        order(ByteOrder.nativeOrder())
        asFloatBuffer()
    }.apply {
        put(vertexCoords)
        position(0)
    }
    program = ShaderUtil.createProgram(vertexShader, fragShader)
    // Get the handle variable in the vertex shader, which is used to assign coordinates to triangles
    GLES20.glBindAttribLocation(program, aPositionIndex, "aPosition")}override fun updateTexImage(a) {
    GLES20.glUseProgram(program)
    // Assign values to vertices in the vertex shader. The second parameter size is 2, which means that the coordinates passed in are 2-dimensional
    GLES20.glVertexAttribPointer(aPositionIndex, 2, GLES20.GL_FLOAT, false.0, vertexBuffer)
    GLES20.glEnableVertexAttribArray(aPositionIndex)// Enable vertices
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0.3)/ / to draw
    GLES20.glDisableVertexAttribArray(aPositionIndex)
}

override fun surfaceDestroyed(a) {
    GLES20.glDisableVertexAttribArray(aPositionIndex)
    GLES20.glDeleteProgram(program)
}
Copy the code

A 2D texture triangle is then defined and can be drawn to the screen by the renderer

3. Supplement: Define the native implementation of triangle texture

The code is similar. Notice that the API version is changed from 2 to 3, and the shader usage is slightly changed. You can see that the code is much simpler to write in Native, so OpenGL development should mainly write in Native.

GLfloat vertices[] = {
        1.0 f.1.0 f.1.0 f.1.0 f.0.0 f.0.0 f
};
GLushort indices[] = {0.1.2};

void texture_triangle::surfaceCreated(a) {
    char vertexSource[] = "#version 300 es \n"
                          "layout(location=0) in vec4 vPosition; \n"
                          "void main() \n"
                          "{ \n"
                          " gl_Position=vPosition; \n"
                          "} \n";
    char fragmentSource[] = "#version 300 es \n"
                            "precision mediump float; \n"
                            "out vec4 fragColor; \n"
                            "void main() \n"
                            "{ \n"
                            "FragColor =vec4(1.0, 0.0, 0.0, 1.0); \n"
                            "} \n";
    program = ShaderUtil::createProgram(vertexSource, fragmentSource);
}
void texture_triangle::surfaceDestroyed(a) {
    if (program) {
        glDeleteProgram(program); program = GL_NONE; }}void texture_triangle::updateTexImage(a) {
    glUseProgram(program);
    glVertexAttribPointer(0.2, GL_FLOAT, GL_FALSE, 0, vertices);
    glEnableVertexAttribArray(0);
    glDrawArrays(GL_TRIANGLES, 0.3);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, indices);
    glUseProgram(GL_NONE);
}
Copy the code