如何安装Android开发环境,如何设置ndk环境变量,在上一篇文章中已经详细讲解,这里不再赘述。如果您不知道如何安装和设置环境,请参考Android环境搭建的内容。好了,假设已经安装了ndk,使用纯C++开发Android程序,下面是详细的步骤和说明:1.编写入口函数android_main作为入口函数,和C++中的main函数是一样的。这里创建CELLAndroidApp的对象,直接调用main函数。voidandroid_main(structandroid_app*state){CELLAndroidAppapp(state);app.main(0,0);}说明:CELLAndroidApp是我们自己设计的图形绘制类,后面会详细介绍2.绘图类的实现描述2.1类成员描述protected:EGLConfig_config;EGLSurface_surface;EGLContext_context;EGLDisplay_display;android_app*_app;int_width;openglobject_display:绘图的设备上下文,类似于windows绘图中的dc2.2。构造函数说明CELLAndroidApp(android_app*app):_app(app){_surface=0;_上下文=0;_显示=0;_宽度=64;_height=48;app->userData=this;//用户数据app->onAppCmd=handle_cmd;//窗口创建和销毁等app->onInputEvent=handle_input;//回调函数}值得注意的是这里app中的userData,用户数据传入,这里直接传入this,onAppCmd传入handle_cmd回调函数,onInputEvent传入handle_input回调函数2.3Functionmain()inclassDescriptionvirtualvoidmain(intargc,char**argv){intident;意图;android_poll_source*来源;while(true){while((ident=ALooper_pollAll(0,NULL,&events,(void**)&source))>=0){if(source!=NULL)source->process(_app,source);//有触摸事件,调用输入函数Number,相当于dispatchmessageif(_app->destroyRequested!=0)return;}使成为();其中android_poll_source相当于windows中的消息队列,用于存储消息,该函数模拟windows中的消息机制ALooper_pollAll()函数,用于获取消息。值得注意的是第一个参数,如果第一个参数传入0,则调用后直接返回,无需等待,类似于windows消息机制中的pickMessage()函数,如果传入-1,它类似于windows消息机制中的SendMessage()函数。返回值:如果返回值大于等于0,则表示已经获取到数据,如果为-1,则表示失败,没有获取到数据。其中,如果source不为空,说明有touch事件,调用process()函数,相当于调用windows中的dispatchMessage()函数。最后调用render()函数绘制图形。2.4初始化设备初始化设备()virtualvoidinitDevice(){constEGLintattribs[]={EGL_SURFACE_TYPE,EGL_WINDOW_BIT,EGL_BLUE_SIZE,8,EGL_GREEN_SIZE,8,EGL_RED_SIZE,8,EGL_NONE};EGLint格式;EGLintnumConfigs;_display=eglGetDisplay(EGL_DEFAULT_DISPLAY);eglInitialize(_display,0,0);eglChooseConfig(_display,attribs,&_config,1,&numConfigs);eglGetConfigAttrib(_display,_config,EGL_NATIVE_VISUAL_ID,&格式);ANativeWindow_setBuffersGeometry(_app->window,0,0,format);_surface=eglCreateWindowSurface(_display,_config,_app->window,NULL);#if0EGLintcontextAtt[]={EGL_CONTEXT_CLIENT_VERSION,2,EGL_NONE,EGL_NONE};_context=eglCreateContext(_display,_config,0,contextAtt);#else_context=eglCreateContext(_display,_config,0,0);#endifif(eglMakeCurrent(_display,_surface,_surface,_context)==EGL_FALSE){LOGW("UnabletoeglMakeCurrent");返回;}eglQuerySurface(_display,_surface,EGL_WIDTH,&_width);eglQuerySurface(_display,_surface,EGL_HEIGHT,&_height);onCreate();//初始化GLstate.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);}首先要说明的是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()virtualvoidrender(){if(_display==0){return;}glClearColor(0,0,0,1);glClear(GL_COLOR_BUFFER_BIT);glEnableClientState(GL_VERTEX_ARRAY);if(g_arVertex.size()>=2){glColor4f(1,1,1,1);glVertexPointer(3,GL_FLOAT,0,&g_arVertex[0]);glDrawArrays(GL_LINE_STRIP,0,g_arVertex.size());}eglSwapBuffers(_display,_surface);//双缓冲swapbuffer}render()函数主要用于绘制点,主要函数解释如下:glClearColor():用于清屏变黑glClear():清除颜色缓冲区区域glEnableClientState():启动定点数组glVertexPointer():制作定点缓冲区glDrawArrays():绘制点数组eglSwapBuffers():Swapbuffer类似于双缓冲区2.6handle_cmd()函数staticvoidhandle_cmd(android_app*app,int32_tcmd){CELLAndroidApp*pThis=(CELLAndroidApp*)app->userData;pThis->cmd(app,cmd);}2.7handle_input()函数staticvoidhandle_input(android_app*app,AInputEvent*event){CELLAndroidApp*pThis=(CELLAndroidApp*)app->userData;pThis->输入(应用程序,事件);}2.8input()函数virtualinput(structandroid_app*app,AInputEvent*event){int32_tevtType=AInputEvent_getType(event);开关(evtType){caseAINPUT_EVENT_TYPE_KEY:中断;caseAINPUT_EVENT_TYPE_MOTION:{int32_tsourceId=AInputEvent_getSource(事件);如果(AINPUT_SOURCE_TOUCHSCREEN==sourceId){int32_tid=AMotionEvent_getAction(事件);开关(id){caseAMOTION_EVENT_ACTION_MOVE:{size_tcnt=AMotionEvent_getPointerCount(事件);对于(inti=0;i
