成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何用 純C++(ndk)開發安卓應用 ?

開發 后端
如何安裝安卓的開發環境以及怎么設置ndk的環境變量等在前邊的文章已經有了詳細的講解,在這里我就不再說明,如果有不會安裝和設置環境的,請先參考安卓環境搭建的內容。

如何安裝安卓的開發環境以及怎么設置ndk的環境變量等在前邊的文章已經有了詳細的講解,在這里我就不再說明,如果有不會安裝和設置環境的,請先參考安卓環境搭建的內容。

好,假設以及安裝好了ndk,使用純c++開發安卓程序,下邊是詳細的步驟與說明:

1.編寫入口函數

android_main為入口函數,和C++中的main函數是一樣的。這里創建CELLAndroidApp的對象,直接調用main函數。

  1. void android_main(struct android_app* state)  
  2. {  
  3.     CELLAndroidApp    app(state);  
  4.  
  5.        app.main(0,0);  
  6. }  

說明:其中的 CELLAndroidApp是我們設計的一個圖形繪制類,稍后將對其做詳細說明

2.繪制類的實現說明

2.1類的成員說明

  1. protected:  
  2.     EGLConfig        _config;  
  3.     EGLSurface       _surface;  
  4.     EGLContext       _context;  
  5.     EGLDisplay       _display;  
  6.     android_app*     _app;  
  7.     int              _width;  
  8.     int              _height; 

部分參數說明:

_surface:用于繪制圖形,相當于windows繪圖中的位圖

_context:可以看做是opengl對象

_display:用于繪圖的設備上下文,類似于windows繪圖中的dc

2.2 構造函數說明

 

  1. CELLAndroidApp(android_app* app):_app(app)  
  2.     {  
  3.         _surface    =    0;  
  4.         _context    =    0;   
  5.         _display    =    0;  
  6.         _width        =    64;  
  7.         _height        =    48;  
  8.         app->userData        =    this//用戶數據  
  9.         app->onAppCmd         =     handle_cmd; //窗口的創建銷毀等  
  10.         app->onInputEvent     =    handle_input; //回調函數  
  11.     } 

值得注意的是,這里的app中的userData,傳入用戶數據,這里直接傳入this,onAppCmd傳入的handle_cmd回調函數,onInputEvent傳入的事handle_input回調函數

2.3 類中函數main()說明

  1. virtual    void     main(int argc,char** argv)  
  2.     {  
  3.         int ident;  
  4.         int    events;  
  5.         android_poll_source* source;  
  6.  
  7.         while (true)  
  8.         {          
  9.             while ((ident = ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0)   
  10.             {  
  11.                 if (source != NULL)  
  12.                     source->process(_app, source); //有觸摸事件,調用input函數,相當于dispatchmessage  
  13.  
  14.                 if (_app->destroyRequested != 0)  
  15.                     return;  
  16.             }  
  17.             render();  
  18.         }  
  19.     } 

其中的android_poll_source相當于windows中的消息隊列,用于存放消息,這個函數中模擬了windows中的消息機制。

ALooper_pollAll()函數,用于獲取消息。值得注意的是第一個參數,如果第一個參數傳入0,則不等待,調用后直接返回,類似于windows消息機制中的pickMessage()函數,如果傳入-1,則類似于windows消息機制中的SendMessage()函數。 返回值:如果返回值大于大于等于0表示獲取到數據,如果為-1則表示失敗,未獲取到數據。

其中發source如果不為空,則表示有觸摸事件,則調用process()函數,相當于windows中調用dispatchMessage()函數。

最后,調用render()函數,繪制圖形。

2.4 初始化設備函數initDevice()

  1. virtual void     initDevice()  
  2.     {  
  3.         const EGLint attribs[] =  
  4.         {  
  5.             EGL_SURFACE_TYPE, EGL_WINDOW_BIT,  
  6.             EGL_BLUE_SIZE, 8,   
  7.             EGL_GREEN_SIZE, 8,  
  8.             EGL_RED_SIZE, 8,  
  9.             EGL_NONE  
  10.         };  
  11.         EGLint     format;  
  12.         EGLint    numConfigs;  
  13.  
  14.         _display    =    eglGetDisplay(EGL_DEFAULT_DISPLAY);  
  15.  
  16.         eglInitialize(_display, 0, 0);  
  17.  
  18.         eglChooseConfig(_display, attribs, &_config, 1, &numConfigs);   
  19.  
  20.         eglGetConfigAttrib(_display, _config, EGL_NATIVE_VISUAL_ID, &format);  
  21.  
  22.         ANativeWindow_setBuffersGeometry(_app->window, 0, 0, format);   
  23.  
  24.         _surface    =     eglCreateWindowSurface(_display, _config, _app->window, NULL);  
  25.  
  26. #if 0  
  27.         EGLint contextAtt[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };  
  28.  
  29.         _context     =     eglCreateContext(_display, _config, 0, contextAtt);  
  30. #else  
  31.         _context     =     eglCreateContext(_display, _config, 0, 0);   
  32. #endif  
  33.  
  34.         if (eglMakeCurrent(_display, _surface, _surface, _context) == EGL_FALSE)  
  35.         {  
  36.             LOGW("Unable to eglMakeCurrent");   
  37.             return;  
  38.         }  
  39.  
  40.         eglQuerySurface(_display, _surface, EGL_WIDTH, &_width);   
  41.         eglQuerySurface(_display, _surface, EGL_HEIGHT, &_height);  
  42.  
  43.         onCreate();  
  44.  
  45.         // Initialize GL state.  
  46.         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);   
  47.         glEnable(GL_CULL_FACE);  
  48.         glShadeModel(GL_SMOOTH);  
  49.         glDisable(GL_DEPTH_TEST);  
  50.         glViewport(0,0,_width,_height);  
  51.         glOrthof(0,_width,_height,0,-100,100);  
  52.     } 

首先需要說明的是attribs數組,改數組中主要存儲了繪制圖形的一些屬性信息,他們是成對出現的,如EGL_SURFACE_TYPE則表示繪制圖形類型, EGL_WINDOW_BIT則表示繪制到窗口上。

eglGetDisplay()函數:表示獲取一個顯示設備

eglInitialize():表示初始化獲取到的顯示設備

eglChooseConfig():繪制屬性的配置

eglGetConfigAttrib():設置繪制格式

ANativeWindow_setBuffersGeometry():將格式應用到窗口

eglCreateWindowSurface():創建繪圖窗口

eglCreateContext():創建opengl的繪圖上下文

eglMakeCurrent():綁定到繪圖設備上下文

eglQuerySurface():獲取圖片的寬度和高度,具體獲取哪一個根據最后一個參數確定

glHint()、glEnable()和glOrthof()等函數則是與繪圖的投影相關的內容,包括初始化、設置模式等內容。

#p#

2.5 繪制函數render()

  1. virtual    void     render()  
  2.     {  
  3.         if(_display == 0)  
  4.         {  
  5.             return;  
  6.         }  
  7.         glClearColor(0,0,0, 1);   
  8.         glClear(GL_COLOR_BUFFER_BIT);  
  9.  
  10.         glEnableClientState(GL_VERTEX_ARRAY);   
  11.         if(g_arVertex.size() >= 2)  
  12.         {  
  13.             glColor4f(1,1,1,1);   
  14.             glVertexPointer(3,GL_FLOAT,0,&g_arVertex[0]);   
  15.             glDrawArrays(GL_LINE_STRIP,0,g_arVertex.size());  
  16.         }  
  17.  
  18.         eglSwapBuffers(_display,_surface); //雙緩存的交換緩沖區  
  19.     } 

render()函數主要用于繪制點,對主要的幾個函數做如下說明:

glClearColor():用于將屏幕清為黑色

glClear():清空顏色緩沖區

glEnableClientState():啟動定點數組

glVertexPointer():制定定點緩沖區

glDrawArrays():繪制點數組

eglSwapBuffers():類似雙緩存的交換緩沖區

2.6 handle_cmd()函數

  1. static void     handle_cmd(android_app* app, int32_t cmd)  
  2.     {  
  3.         CELLAndroidApp*    pThis    =    (CELLAndroidApp*)app->userData;  
  4.         pThis->cmd(app,cmd);  
  5.     }  

2.7 handle_input()函數

  1. static void     handle_input(android_app* app, AInputEvent* event)  
  2.     {  
  3.         CELLAndroidApp*    pThis    =    (CELLAndroidApp*)app->userData;  
  4.         pThis->input(app,event);  
  5.     }  

2.8 input()函數

  1. virtual    int     input(struct android_app* app, AInputEvent* event)  
  2.     {  
  3.         int32_t    evtType    =    AInputEvent_getType(event);  
  4.         switch(evtType)  
  5.         {  
  6.         case AINPUT_EVENT_TYPE_KEY:   
  7.             break;  
  8.         case AINPUT_EVENT_TYPE_MOTION:   
  9.             {  
  10.                 int32_t    sourceId    =     AInputEvent_getSource(event);  
  11.                 if(AINPUT_SOURCE_TOUCHSCREEN == sourceId)  
  12.                 {  
  13.                     int32_t id = AMotionEvent_getAction(event);   
  14.                     switch(id)  
  15.                     {  
  16.                     case AMOTION_EVENT_ACTION_MOVE:  
  17.                         {  
  18.                             size_t    cnt = AMotionEvent_getPointerCount(event);   
  19.                             forint i = 0 ;i < cnt; ++ i )  
  20.                             {  
  21.                                 float x = AMotionEvent_getX(event,i);  
  22.                                 float y = AMotionEvent_getY(event,i);  
  23.                                 float3 pt;  
  24.                                 pt.x = x;  
  25.                                 pt.y = y;  
  26.                                 pt.z = 0;  
  27.                                 g_arVertex.push_back(pt);  
  28.                             }  
  29.  
  30.                         }  
  31.                         break;  
  32.                     case AMOTION_EVENT_ACTION_DOWN:  
  33.                         {  
  34.                             size_t    cnt = AMotionEvent_getPointerCount(event);  
  35.                             forint i = 0 ;i < cnt; ++ i )  
  36.                             {  
  37.                                 float x = AMotionEvent_getX(event,i);  
  38.                                 float y = AMotionEvent_getY(event,i);  
  39.                             }  
  40.                         }  
  41.                         break;  
  42.                     case AMOTION_EVENT_ACTION_UP:  
  43.                         {  
  44.                             size_t    cnt = AMotionEvent_getPointerCount(event);  
  45.                             forint i = 0 ;i < cnt; ++ i )  
  46.                             {  
  47.                                 float x = AMotionEvent_getX(event,i);  
  48.                                 float y = AMotionEvent_getY(event,i);  
  49.                             }  
  50.                         }  
  51.                         break;  
  52.                     }  
  53.                 }  
  54.                 else if(AINPUT_SOURCE_TRACKBALL == sourceId)  
  55.                 {  
  56.                 }  
  57.             }  
  58.             break;  
  59.         }  
  60.         return    0;  
  61.     } 

該函數主要用于對輸入進行判斷,以確定是吉鍵盤、鼠標或遙感等,根據具體輸入做相應的操縱,這里就不再做過多的說明

AMotionEvent_getPointerCount():如果是多點觸控,則將各個點保存到vector中。

2.9 cmd()函數

  1. virtual int    cmd(struct android_app* app, int32_t cmd)  
  2.     {  
  3.         switch(cmd)  
  4.         {  
  5.         case APP_CMD_SAVE_STATE:  
  6.             break;  
  7.         case APP_CMD_INIT_WINDOW:  
  8.             initDevice();  
  9.             break;  
  10.         case APP_CMD_TERM_WINDOW:  
  11.             shutDownDevice();  
  12.             break;  
  13.         case APP_CMD_GAINED_FOCUS:  
  14.             break;  
  15.         case APP_CMD_LOST_FOCUS:  
  16.             break;  
  17.         }  
  18.         return    0;  
  19.     } 

根據傳入的命令,對窗口做相應的處理。

APP_CMD_INIT_WINDOW:表示初始化窗口

2.10 shutDownDevice()函數

  1. virtual void     shutDownDevice()  
  2.     {  
  3.         onDestroy();  
  4.  
  5.         if (_display != EGL_NO_DISPLAY)  
  6.         {  
  7.             eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);  
  8.             if (_context != EGL_NO_CONTEXT)  
  9.             {  
  10.                 eglDestroyContext(_display, _context);  
  11.             }  
  12.             if (_surface != EGL_NO_SURFACE)  
  13.             {  
  14.                 eglDestroySurface(_display, _surface);  
  15.             }  
  16.             eglTerminate(_display);  
  17.         }  
  18.         _display = EGL_NO_DISPLAY;  
  19.         _context = EGL_NO_CONTEXT;  
  20.         _surface = EGL_NO_SURFACE;  
  21.     } 

關閉設備,主要是將與設備相關的綁定清除,釋放綁定。

 

編寫完上邊的代碼后,編譯程序,將程序導入到模擬器中,最終運行的效果圖如下:

好了,該說的基本都說玩了,下邊附上源碼地址,趕緊去嘗試吧:

 示例程序下載

 
 
責任編輯:林師授 來源: OpenG
相關推薦

2021-04-04 08:00:39

C++編程語言軟件開發

2010-01-28 10:33:10

C++開發程序

2024-05-06 11:19:20

內存池計算機編程

2017-12-09 21:08:35

C++人工智能機器學習

2011-09-26 17:02:05

安卓蜂窩冰激凌三明治

2013-02-22 09:28:45

MEAP軟件移動應用開發HTML5

2017-11-27 17:29:43

深度學習TensorFlow安卓設備

2013-05-02 13:06:05

C++遇到iOS應用開SQLITE

2021-09-23 14:41:58

鴻蒙HarmonyOS應用

2010-01-28 09:44:08

C++應用程序

2018-06-04 09:30:07

編程語言安卓應用開發

2010-01-26 11:06:50

C++開發

2012-07-16 10:21:23

iPhone

2010-01-26 15:51:06

C++變量

2010-01-14 11:14:47

C++應用程序

2010-01-25 16:41:08

C++應用程序

2021-06-02 09:07:33

手機存儲垃圾清理雪豹速清

2014-06-26 15:17:17

安卓應用保存數據

2010-01-22 16:35:41

C++開發

2013-07-19 15:39:25

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 婷婷色国产偷v国产偷v小说 | 中文字幕免费视频 | 久久综合狠狠综合久久综合88 | 国产精品久久久久久妇女6080 | 黄色网址在线免费观看 | 亚洲国产一 | 欧美一级三级 | 国产黄色大片在线观看 | 欧美综合国产精品久久丁香 | 中文字幕在线免费观看 | 国产亚洲精品久久久优势 | 福利视频一区二区 | 亚洲福利在线观看 | 成人在线免费 | 91一区二区 | 91在线资源 | 欧美日韩视频在线 | 午夜资源 | 911精品国产| 亚洲国产区 | 日韩在线播放视频 | 在线一区 | 一级特黄视频 | 日韩免费视频 | 精品国产精品三级精品av网址 | 天天干视频| 久久久久久久久久久久久久av | 最近最新中文字幕 | 中文字幕亚洲精品 | 中文字幕亚洲欧美 | 国产精品久久久久久久岛一牛影视 | 精一区二区| 久久久久久久久99 | 精品一区二区电影 | 日日操视频 | 亚州春色| 久久久久久久久久久久久9999 | 一区二区精品电影 | 久久69精品久久久久久久电影好 | 久久精品屋 | 日韩精品无码一区二区三区 |