An overview of the

This is a new series, learn OpengGl Es, actually is “OpenGl Es Application Development Practice Guide Android volume” study notes, interested can directly read this book, of course, this will record their own understanding, the following only as notes, in case you forget later

The first nine chapters of the book will then be analyzed in turn

Android OpenGl Es learning (a) : create an OpenGl Es program

Android OpenGl Es learning (2) : define vertices and shaders

Android OpenGl Es learning (3) : build shaders

Android OpenGl Es learning (4) : add color

Android OpenGl Es learning (5) : adjust the aspect ratio

Android OpenGl Es Learning (vi) : Enter 3d

Android OpenGl Es learning (7) : Using textures

Android OpenGl Es Learning (8) : Build simple objects

Add touch feedback to Android OpenGl Es

The end result is a simple game of hockey, something like this

Create a new project

Start by creating a new project with Android Studio

Initialize OpenGl

We use GLSurfaceView to initialize OpenGl, and GLSurfaceView handles the basic operations of OpenGl initialization, such as configuring display devices and rendering in background threads, GLSurfaceView can handle the Activity life cycle more quickly, and GLSurfaceView provides many helper methods for this purpose

Write GLSurfaceView in XML

 <android.opengl.GLSurfaceView
        android:id="@+id/glsurface"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
Copy the code

Initialize the GLSurfaceView in the Activity

        GLSurfaceView glSurfaceView = findViewById(R.id.glsurface);
Copy the code

Determine the supported OpenGl version

We use version 2.0, so determine if the phone supports version 2.0

 private boolean supportsEs2(a) {
        ActivityManager activityManager =
                (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        ConfigurationInfo configurationInfo = activityManager
                .getDeviceConfigurationInfo();
       
        final boolean supportsEs2 =
                configurationInfo.reqGlEsVersion >= 0x20000
                        || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1
                        && (Build.FINGERPRINT.startsWith("generic")
                        || Build.FINGERPRINT.startsWith("unknown")
                        || Build.MODEL.contains("google_sdk")
                        || Build.MODEL.contains("Emulator")
                        || Build.MODEL.contains("Android SDK built for x86")));

        return supportsEs2;
    }
Copy the code

Configure the render surface for OpenGl2.0

  private void initData(a) {
        if (supportsEs2()) {
            AirHockKeyRender myGlRender = new AirHockKeyRender(this);
            // Set the OpengL version
            glSurfaceView.setEGLContextClientVersion(2);
            glSurfaceView.setRenderer(myGlRender);
            RENDERMODE_WHEN_DIRTY and RENDERMODE_CONTINUOUSLY. The former is lazy and needs to be called manually
            / / glSurfaceView. RequestRender () will be updated, while the latter is constantly rendering.
            glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
        } else {
            Log.d("mmm"."Version 2.0 is not supported"); }}Copy the code

If version 2.0 is supported, set the version number in setup renderer

Fit the Activity lifecycle

  @Override
    protected void onResume(a) {
        super.onResume();
        glSurfaceView.onResume();
    }

    @Override
    protected void onPause(a) {
        super.onPause();
        glSurfaceView.onPause();
    }
Copy the code

Create the Renderer class

class AirHockKeyRender implements GLSurfaceView.Renderer {
    public AirHockKeyRender(Context context) {}@Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GlsurfaceView calls this method when the surface is created. This happens in the application
        It is also called when you first run it or when you return from another Activity

        GLES20.glClearColor(1.0 f.0.0 f.0.0 f.0.0 f);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // After the Surface is created, this method is called every time the Surface size changes, such as switching between horizontal and vertical screens

        GLES20.glViewport(0.0, width, height);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        // When drawing each frame of data, this method is called. This method must draw something, even if it is just to empty the screen
        // Because when this method returns, the data in the render area will be exchanged and displayed on the screen. If nothing else, you will see a flicker effectGLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); }}Copy the code

GlSurafceView will call render methods in a separate thread. By default, RenderMode will render continuously at the refresh rate of the device screen. RenderMode can also be selected on request. RENDERMODE_WHEN_DIRTY and RENDERMODE_CONTINUOUSLY, the former is lazy rendering, glSurfaceView. The need to manually call requestRender () will be updated, while the latter is constantly rendering.

methods describe
GLES20.glClearColor The first three parameters are red, green and blue and the last parameter is alpha for transparency. Above we set the first one to 1 and the rest to 0 for red
GLES20.glViewport Set the viewport size to tell OpengL the surface size for incoming rendering
GLES20.glClear Empty the screen and fill it with the color defined previously with glClearColor

The last

So now that we’ve written our first program, it looks something like this

The complete code

public class MainActivity extends AppCompatActivity {

    private GLSurfaceView glSurfaceView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        initData();
    }

    private void initData(a) {
        if (supportsEs2()) {
            AirHockKeyRender myGlRender = new AirHockKeyRender(this);
            // Set the OpengL version
            glSurfaceView.setEGLContextClientVersion(2);
            glSurfaceView.setRenderer(myGlRender);
            RENDERMODE_WHEN_DIRTY and RENDERMODE_CONTINUOUSLY. The former is lazy and needs to be called manually
            / / glSurfaceView. RequestRender () will be updated, while the latter is constantly rendering.
            glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
        } else {
            Log.d("mmm"."Version 2.0 is not supported"); }}private void initView(a) {
        glSurfaceView = findViewById(R.id.glsurface);
    }

    private boolean supportsEs2(a) {
        // Check if the system supports OpenGL ES 2.0.
        ActivityManager activityManager =
                (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        ConfigurationInfo configurationInfo = activityManager
                .getDeviceConfigurationInfo();
        // Even though the latest emulator supports OpenGL ES 2.0,
        // it has a bug where it doesn't set the reqGlEsVersion so
        // the above check doesn't work. The below will detect if the
        // app is running on an emulator, and assume that it supports
        / / OpenGL ES 2.0.
        final boolean supportsEs2 =
                configurationInfo.reqGlEsVersion >= 0x20000
                        || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1
                        && (Build.FINGERPRINT.startsWith("generic")
                        || Build.FINGERPRINT.startsWith("unknown")
                        || Build.MODEL.contains("google_sdk")
                        || Build.MODEL.contains("Emulator")
                        || Build.MODEL.contains("Android SDK built for x86")));

        return supportsEs2;
    }

    @Override
    protected void onResume(a) {
        super.onResume();
        glSurfaceView.onResume();
    }

    @Override
    protected void onPause(a) {
        super.onPause(); glSurfaceView.onPause(); }}Copy the code
class AirHockKeyRender implements GLSurfaceView.Renderer {

    public AirHockKeyRender(Context context) {}@Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GlsurfaceView calls this method when the surface is created. This happens in the application
        It is also called when you first run it or when you return from another Activity

        GLES20.glClearColor(1.0 f.0.0 f.0.0 f.0.0 f);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // After the Surface is created, this method is called every time the Surface size changes, such as switching between horizontal and vertical screens

        GLES20.glViewport(0.0, width, height);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        // When drawing each frame of data, this method is called. This method must draw something, even if it is just to empty the screen
        // Because when this method returns, the data in the render area will be exchanged and displayed on the screen. If nothing else, you will see a flicker effectGLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); }}Copy the code