I will not describe how to install the android development environment and how to set ndk environment variables in front of the article, if any environment is not installed or set up, please refer to the content set up in the android environment first.
Good. If ndk is installed and Android is developed using pure c ++, the detailed steps and instructions are as follows:
1. Compile the entry function
Android_main is the entry function, which is the same as the main function in C ++. Create the CELLAndroidApp object and directly call the main function.
- void android_main(struct android_app* state)
- {
- CELLAndroidApp app(state);
-
- app.main(0,0);
- }
Note: CELLAndroidApp is a graphic drawing class we designed. It will be described in detail later.
2. Implementation of the drawing class
2.1 class member description
- protected:
- EGLConfig _config;
- EGLSurface _surface;
- EGLContext _context;
- EGLDisplay _display;
- android_app* _app;
- int _width;
- int _height;
Some parameter descriptions:
_ Surface: used to draw a graph, which is equivalent to a bitmap in windows plotting.
_ Context: can be viewed as an opengl object.
_ Display: The device context used for drawing, similar to the dc in windows plotting
2.2 constructor description
- CELLAndroidApp (android_app * app): _ app (app)
- {
- _ Surface = 0;
- _ Context = 0;
- _ Display = 0;
- _ Width = 64;
- _ Height = 48;
- App-> userData = this; // user data
- App-> onAppCmd = handle_cmd; // window creation and destruction
- App-> onInputEvent = handle_input; // callback function
- }
It is worth noting that the app's userData here is used to pass in user data. Here, this is passed in directly, the handle_cmd callback function passed in by onAppCmd, And the handle_input callback function passed in by onInputEvent.
Main () Description of the class
- Virtual void main (int argc, char ** argv)
- {
- Int ident;
- Int events;
- Android_poll_source * source;
-
- While (true)
- {
- While (ident = ALooper_pollAll (0, NULL, & events, (void **) & source)> = 0)
- {
- If (source! = NULL)
- Source-> process (_ app, source); // There is a touch event that calls the input function, which is equivalent to dispatchmessage
-
- If (_ app-> destroyRequested! = 0)
- Return;
- }
- Render ();
- }
- }
Android_poll_source is equivalent to a message queue in windows used to store messages. This function simulates the message mechanism in windows.
The ALooper_pollAll () function is used to obtain messages. It is worth noting that the first parameter, if the first parameter is passed in 0, will not wait, and will be returned directly after the call, similar to the pickMessage () function in windows message mechanism. If-1 is passed in, it is similar to the SendMessage () function in windows message mechanism. Return Value: If the returned value is greater than or equal to 0, the data is obtained. If the returned value is-1, the data is failed and not obtained.
If the source is not empty, it indicates there is a touch event, and the process () function is called, which is equivalent to the dispatchMessage () function in windows.
Finally, call the render () function to draw a graph.
2.4 device initialization function initDevice ()
- virtual void initDevice()
- {
- const EGLint attribs[] =
- {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_BLUE_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_RED_SIZE, 8,
- EGL_NONE
- };
- EGLint format;
- EGLint numConfigs;
-
- _display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-
- eglInitialize(_display, 0, 0);
-
- eglChooseConfig(_display, attribs, &_config, 1, &numConfigs);
-
- eglGetConfigAttrib(_display, _config, EGL_NATIVE_VISUAL_ID, &format);
-
- ANativeWindow_setBuffersGeometry(_app->window, 0, 0, format);
-
- _surface = eglCreateWindowSurface(_display, _config, _app->window, NULL);
-
- #if 0
- EGLint contextAtt[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };
-
- _context = eglCreateContext(_display, _config, 0, contextAtt);
- #else
- _context = eglCreateContext(_display, _config, 0, 0);
- #endif
-
- if (eglMakeCurrent(_display, _surface, _surface, _context) == EGL_FALSE)
- {
- LOGW("Unable to eglMakeCurrent");
- return;
- }
-
- eglQuerySurface(_display, _surface, EGL_WIDTH, &_width);
- eglQuerySurface(_display, _surface, EGL_HEIGHT, &_height);
-
- onCreate();
-
- // Initialize GL state.
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
- glEnable(GL_CULL_FACE);
- glShadeModel(GL_SMOOTH);
- glDisable(GL_DEPTH_TEST);
- glViewport(0,0,_width,_height);
- glOrthof(0,_width,_height,0,-100,100);
- }
The first thing to note is the attribs array, which mainly stores some attribute information of the drawing image. They appear in pairs. For example, EGL_SURFACE_TYPE indicates the drawing type, EGL_WINDOW_BIT indicates that it is drawn to the window.
EglGetDisplay () function: obtains a display device.
EglInitialize (): indicates the display device obtained during initialization.
EglChooseConfig (): configure the painting attributes
EglGetConfigAttrib (): sets the drawing format.
ANativeWindow_setBuffersGeometry (): Apply the format to the window
EglCreateWindowSurface (): Creates a drawing window.
EglCreateContext (): Creates the drawing context of opengl.
EglMakeCurrent (): bound to the drawing device context
EglQuerySurface (): Get the width and height of the image. Determine which one is obtained based on the last parameter.
GlHint (), glable (), glOrthof () and other functions are related to the projection of the drawing, including initialization, setting mode, and so on.