程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 如何用 純C++(ndk)開發安卓應用 ?(1)

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

編輯:C++入門知識

如何安裝安卓的開發環境以及怎麼設置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()等函數則是與繪圖的投影相關的內容,包括初始化、設置模式等內容。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved