OpenGL ES | Drawing Graphics

This article comes from translation:  Draw shapes

draw graphics

After defining graphics, you may want to draw them. Drawing graphics using OpenGL ES 2.0 requires a bit more code than you might think, because the API provides a lot of control over the graphics rendering pipeline.

This lesson explains how to use the OpenGL ES 2.0 API to draw the shapes defined in the previous lesson.

Initialize graphics

Before drawing, you must initialize and load the graphics you want to draw, unless the graphics structure changes during runtime. In order to efficiently use memory and processing efficiency, you should initialize them in the renderer's OnSurfaceCreated() .

public class MyGLRenderer implements GLSurfaceView.Renderer {

    ...
    private Triangle mTriangle;
    private Square   mSquare;

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        ...

        // initialize a triangle
        mTriangle = new Triangle();
        // initialize a square
        mSquare = new Square();
    }
    ...
}

draw graphics

Using OpenGL ES 2.0 to draw defined graphics requires a lot of code, and you have to be prepared. The reason why you need a lot of code is because you have to provide detailed information for the rendering pipeline. Generally, you must define it as follows:

Vertex Shader - Vertex shader for OpenGL ES rendering graphics vertices.
Fragment Shader - OpenGL ES fragment shader for rendering graphics surfaces using texture or color.
Program - An OpenGL ES OpenGL ES object containing one or more vertex shaders used to draw graphics.

You need at least a vertex shader to draw the graphics and a fragment shader to shade the surface of the graphics. These shaders must be compiled and put into the OpenGL ES program, which can then be used to draw the graphics. The following is in the triangle An example of a defined shader that can be used to draw graphics:

public class Triangle {

    private final String vertexShaderCode =
        "attribute vec4 vPosition;" +
        "void main() {" +
        "  gl_Position = vPosition;" +
        "}";

    private final String fragmentShaderCode =
        "precision mediump float;" +
        "uniform vec4 vColor;" +
        "void main() {" +
        "  gl_FragColor = vColor;" +
        "}";

    ...
}

Shaders contain OpenGL Shading Language (GLSL) code and must be precompiled before use. To compile this code, create a public method in your renderer class:

public static int loadShader(int type, String shaderCode){

    // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
    // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
    int shader = GLES20.glCreateShader(type);

    // add the source code to the shader and compile it
    GLES20.glShaderSource(shader, shaderCode);
    GLES20.glCompileShader(shader);

    return shader;
}

In order to draw graphics, you must mutate the shader code and add them to the OpenGL ES program object, and then establish a link. Execute in the construction method of drawing graphics, and only need to operate in sequence.

Notice:

Compiling an OpenGL ES shader and linking it with the program is very time consuming in terms of CPU cycles and processing time, so try to avoid doing more than one operation. If you don't know what the shader is doing at runtime, you should just do it like that Created sequentially and then cached for subsequent use.

 

public class Triangle() {
    ...

    private final int mProgram;

    public Triangle() {
        ...

        int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
                                        vertexShaderCode);
        int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
                                        fragmentShaderCode);

        // create empty OpenGL ES Program
        mProgram = GLES20.glCreateProgram();

        // add the vertex shader to program
        GLES20.glAttachShader(mProgram, vertexShader);

        // add the fragment shader to program
        GLES20.glAttachShader(mProgram, fragmentShader);

        // creates OpenGL ES program executables
        GLES20.glLinkProgram(mProgram);
    }
}

Now, you are ready to use the actual call to draw your graphics. Drawing graphics using OpenGL ES requires you to provide several parameters to tell the rendering pipeline what you want to draw and how to draw them. Since the drawing options may vary depending on the graphics Different, so it's best to let the graph contain its own drawing logic.

Create a draw() method for drawing graphics. This code sets the drawing start point for the vertex shader, sets the color for the fragment shader, and then executes the draw method:

public void draw() {
    // Add program to OpenGL ES environment
    GLES20.glUseProgram(mProgram);

    // get handle to vertex shader's vPosition member
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

    // Enable a handle to the triangle vertices
    GLES20.glEnableVertexAttribArray(mPositionHandle);

    // Prepare the triangle coordinate data
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                                 GLES20.GL_FLOAT, false,
                                 vertexStride, vertexBuffer);

    // get handle to fragment shader's vColor member
    mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

    // Set color for drawing the triangle
    GLES20.glUniform4fv(mColorHandle, 1, color, 0);

    // Draw the triangle
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

    // Disable vertex array
    GLES20.glDisableVertexAttribArray(mPositionHandle);
}

As long as all the code is correct, to draw the graphic just call the draw() method of the graphic object in renderer.onDrawFrame()

Once you have all this code in place, drawing this object just requires a call to the draw() method from within your renderer’s onDrawFrame() method:

public void onDrawFrame(GL10 unused) {
    ...

    mTriangle.draw();
}

Then run the program, it should look like this:


There are a couple of problems with the code sample. It can't surprise your friends. Second, the triangle is deformed a bit and when you change the orientation of the device screen, the shape also changes. The reason the graph is deformed is that the vertices of the graph are on the screen The scale of the GLSurfaceView in the display area is not being corrected. You can fix this in the next lesson using projection and camera perspective.

In the end, the triangle is static and not interesting. In the next lesson (adding motion), you can use the OpenGL ES graphics pipeline to spin it up and do more interesting things!

Next: OpenGL ES|Application Projection and Camera Perspective

 
 

Guess you like

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