自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何用 純C++(ndk)開發(fā)安卓應(yīng)用 ?

開發(fā) 后端
如何安裝安卓的開發(fā)環(huán)境以及怎么設(shè)置ndk的環(huán)境變量等在前邊的文章已經(jīng)有了詳細(xì)的講解,在這里我就不再說明,如果有不會(huì)安裝和設(shè)置環(huán)境的,請(qǐng)先參考安卓環(huán)境搭建的內(nèi)容。

如何安裝安卓的開發(fā)環(huán)境以及怎么設(shè)置ndk的環(huán)境變量等在前邊的文章已經(jīng)有了詳細(xì)的講解,在這里我就不再說明,如果有不會(huì)安裝和設(shè)置環(huán)境的,請(qǐng)先參考安卓環(huán)境搭建的內(nèi)容。

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

1.編寫入口函數(shù)

android_main為入口函數(shù),和C++中的main函數(shù)是一樣的。這里創(chuàng)建CELLAndroidApp的對(duì)象,直接調(diào)用main函數(shù)。

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

說明:其中的 CELLAndroidApp是我們?cè)O(shè)計(jì)的一個(gè)圖形繪制類,稍后將對(duì)其做詳細(xì)說明

2.繪制類的實(shí)現(xiàn)說明

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; 

部分參數(shù)說明:

_surface:用于繪制圖形,相當(dāng)于windows繪圖中的位圖

_context:可以看做是opengl對(duì)象

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

2.2 構(gòu)造函數(shù)說明

 

  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//用戶數(shù)據(jù)  
  9.         app->onAppCmd         =     handle_cmd; //窗口的創(chuàng)建銷毀等  
  10.         app->onInputEvent     =    handle_input; //回調(diào)函數(shù)  
  11.     } 

值得注意的是,這里的app中的userData,傳入用戶數(shù)據(jù),這里直接傳入this,onAppCmd傳入的handle_cmd回調(diào)函數(shù),onInputEvent傳入的事handle_input回調(diào)函數(shù)

2.3 類中函數(shù)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); //有觸摸事件,調(diào)用input函數(shù),相當(dāng)于dispatchmessage  
  13.  
  14.                 if (_app->destroyRequested != 0)  
  15.                     return;  
  16.             }  
  17.             render();  
  18.         }  
  19.     } 

其中的android_poll_source相當(dāng)于windows中的消息隊(duì)列,用于存放消息,這個(gè)函數(shù)中模擬了windows中的消息機(jī)制。

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

其中發(fā)source如果不為空,則表示有觸摸事件,則調(diào)用process()函數(shù),相當(dāng)于windows中調(diào)用dispatchMessage()函數(shù)。

最后,調(diào)用render()函數(shù),繪制圖形。

2.4 初始化設(shè)備函數(shù)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數(shù)組,改數(shù)組中主要存儲(chǔ)了繪制圖形的一些屬性信息,他們是成對(duì)出現(xiàn)的,如EGL_SURFACE_TYPE則表示繪制圖形類型, EGL_WINDOW_BIT則表示繪制到窗口上。

eglGetDisplay()函數(shù):表示獲取一個(gè)顯示設(shè)備

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

eglChooseConfig():繪制屬性的配置

eglGetConfigAttrib():設(shè)置繪制格式

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

eglCreateWindowSurface():創(chuàng)建繪圖窗口

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

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

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

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

#p#

2.5 繪制函數(shù)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); //雙緩存的交換緩沖區(qū)  
  19.     } 

render()函數(shù)主要用于繪制點(diǎn),對(duì)主要的幾個(gè)函數(shù)做如下說明:

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

glClear():清空顏色緩沖區(qū)

glEnableClientState():?jiǎn)?dòng)定點(diǎn)數(shù)組

glVertexPointer():制定定點(diǎn)緩沖區(qū)

glDrawArrays():繪制點(diǎn)數(shù)組

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

2.6 handle_cmd()函數(shù)

  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()函數(shù)

  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()函數(shù)

  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.     } 

該函數(shù)主要用于對(duì)輸入進(jìn)行判斷,以確定是吉鍵盤、鼠標(biāo)或遙感等,根據(jù)具體輸入做相應(yīng)的操縱,這里就不再做過多的說明

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

2.9 cmd()函數(shù)

  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.     } 

根據(jù)傳入的命令,對(duì)窗口做相應(yīng)的處理。

APP_CMD_INIT_WINDOW:表示初始化窗口

2.10 shutDownDevice()函數(shù)

  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.     } 

關(guān)閉設(shè)備,主要是將與設(shè)備相關(guān)的綁定清除,釋放綁定。

 

編寫完上邊的代碼后,編譯程序,將程序?qū)氲侥M器中,最終運(yùn)行的效果圖如下:

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

 示例程序下載

 
 
責(zé)任編輯:林師授 來源: OpenG
相關(guān)推薦

2021-04-04 08:00:39

C++編程語言軟件開發(fā)

2010-01-28 10:33:10

C++開發(fā)程序

2024-05-06 11:19:20

內(nèi)存池計(jì)算機(jī)編程

2017-12-09 21:08:35

C++人工智能機(jī)器學(xué)習(xí)

2011-09-26 17:02:05

安卓蜂窩冰激凌三明治

2017-11-27 17:29:43

深度學(xué)習(xí)TensorFlow安卓設(shè)備

2010-01-28 09:44:08

C++應(yīng)用程序

2021-09-23 14:41:58

鴻蒙HarmonyOS應(yīng)用

2018-06-04 09:30:07

編程語言安卓應(yīng)用開發(fā)

2010-01-26 11:06:50

C++開發(fā)

2013-05-02 13:06:05

C++遇到iOS應(yīng)用開SQLITE

2013-02-22 09:28:45

MEAP軟件移動(dòng)應(yīng)用開發(fā)HTML5

2012-07-16 10:21:23

iPhone

2010-01-26 15:51:06

C++變量

2021-06-02 09:07:33

手機(jī)存儲(chǔ)垃圾清理雪豹速清

2012-03-28 09:54:32

安卓開發(fā)初級(jí)教程

2012-03-26 09:27:40

谷歌安卓開發(fā)谷歌安卓

2010-01-22 16:35:41

C++開發(fā)

2014-06-26 15:17:17

安卓應(yīng)用保存數(shù)據(jù)

2010-01-14 11:14:47

C++應(yīng)用程序
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)