Ví dụ về OpenGL ES trong android

Xin chào các bạn trong bài viết trước mình đã giới thiệu qua về các thành phần cơ bản của OpenGL ES trong android. Trong bài viết hôm nay mình sẽ giới thiệu cho các bạn cách áp dụng OpenGL trong ứng dụng android và làm một ví dụ về OpenGL ES.

Nếu các bạn chưa đọc qua phần 1 của bài viết thì có thể tham khảo tại đây: https://viblo.asia/nghicv.57/posts/NbmebaqZGYO

Việc đầu tiên chúng ta cần làm đó là tạo một android projec với tên là OpenELAndroidExample và setup OpenGL ES cho project

2016-12-17.png

Khai báo yêu sử dụng các tính năng của OpenGL ES 2.0 cho những thiết bị không hỗ trợ

<uses-feature
        android:glEsVersion="0x00020000"
        android:required="true"/>

Như đã giới thiệu trong bài viết trước, hai thành phần quan trọng nhất khi implement OpenGL ES vào ứng dụng đó là GLSurfaceViewGLSurfaceView.Renderer, sau khi tạo thành công project chúng ta sẽ tiến hành cài đặt thêm 2 class này .

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    mGLSurfaceView = new GLSurfaceView(this);

    // Check if the system supports OpenGL ES 2.0.
    final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
    final boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;

    if (supportsEs2)
    {
        // Request an OpenGL ES 2.0 compatible context.
        mGLSurfaceView.setEGLContextClientVersion(2);

        // Set the renderer to our demo renderer, defined below.
        mGLSurfaceView.setRenderer(new LessonOneRenderer());
    }
    else
    {
        // This is where you could create an OpenGL ES 1.x compatible
        // renderer if you wanted to support both ES 1 and ES 2.
        return;
    }

    setContentView(mGLSurfaceView);
}

Render:

private GLSurfaceView.Renderer mRenderer = new GLSurfaceView.Renderer() {
        @Override
        public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
        }

        @Override
        public void onSurfaceChanged(GL10 gl10, int i, int i1) {

        }

        @Override
        public void onDrawFrame(GL10 gl10) {

        }
    };

Tiếp theo chúng ta cần tạo lớp đối tượng mà chúng ta cần vẽ, openGL ES trong android cung câp rất nhiều phuơng thức cho phép chúng ta có thể vẽ trên GLSurfaceView tuy nhiên những nó chỉ là những hàm về vẽ điểm, đường thẳng, đa giác chứ không có những hàm vẽ những khối 3D phức tạp mà để làm điều này chúng ta cần vẽ những thành phần đơn giản như lưới đa giác để tạo nên hình phức tạp . Ví dụ lớp đối tượng:

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);
    }
}

Hàm vẽ

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);
}

Thực hiện vẽ

public void onDrawFrame(GL10 unused) {
    ...

    mTriangle.draw();
}

Kết quả:

ogl-triangle.png