- UID
- 1
- 精华
- 积分
- 76361
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
我讨厌Eclipse.各种麻烦,配置还需要下载各种包,各种不爽!
也许是我用不来,也许是我笨。总之在我的电脑上它从来没正常运行过。
好吧。那我就用c4droid进行开发。先在电脑上用Notepad++写代码,完了以后仍手机用c4droid变异。
首先我们需要一个Makefile- all: ndkapp.so
- ndkapp.so: napp.o
- $(CC) -o ndkapp.so napp.o -shared -lEGL -lGLESv1_CM -lm
- clean:
- rm ndkapp.so napp.o
复制代码 我们是把napp.c这个源文件编译为napp.o,然后链接得到ndkapp.so这个可执行文件(安卓的可执行文件……?)
算了,不纠结这个。继续。
这个源码运行的效果就是屏幕上会显示一个正方形,然后你用手摸屏幕的时候正方形会跟着走。
我决定以后在安卓上开发程序都采取用OpenGL自己绘制界面的这种方式了。我更喜欢这种模式的编程。- #include<jni.h>
- #include<errno.h>
- #include<math.h>
- #include<sys/time.h>
- #include<EGL/egl.h>
- #include<GLES/gl.h>
- #include<android/sensor.h>
- #include<android/log.h>
- #include<android_native_app_glue.h>
- #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO,"native-activity",__VA_ARGS__))
- #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN,"native-activity",__VA_ARGS__))
- //程序挂起恢复时存储的数据
- typedef struct
- {
- int32_t x;
- int32_t y;
-
- float AccX,AccY,AccZ;
- }SavedState,*SavedStateP;
- //程序数据
- typedef struct
- {
- struct android_app *pApp;
- //传感器
- ASensorManager *pSensorManager;
- const ASensor *pAccelerometerSensor;
- ASensorEventQueue *pSensorEventQueue;
-
- //图形引擎
- EGLDisplay Display;
- EGLSurface Surface;
- EGLContext Context;
- int32_t Width;
- int32_t Height;
-
- //存储的状态
- SavedState State;
- }AppData,*AppDataP;
- //=============================================================================
- //InitDisplay:
- //初始化显示的部分,OpenGL ES
- //-----------------------------------------------------------------------------
- int InitDisplay(AppDataP pThis)
- {
- const EGLint Attribs[]=
- {
- EGL_SURFACE_TYPE,EGL_WINDOW_BIT,
- EGL_BLUE_SIZE,8,
- EGL_GREEN_SIZE,8,
- EGL_RED_SIZE,8,
- EGL_DEPTH_SIZE,8,
- EGL_NONE
- };
- EGLint W,H;
- EGLint Dummy,Format;
- EGLint NbConfigs;
- EGLConfig Configs;
- EGLDisplay Display;
- EGLSurface Surface;
- EGLContext Context;
-
- Display=eglGetDisplay(EGL_DEFAULT_DISPLAY);
- eglInitialize(Display,0,0);
- eglChooseConfig(Display,Attribs,&Configs,1,&NbConfigs);
- eglGetConfigAttrib(Display,Configs,EGL_NATIVE_VISUAL_ID,&Format);
- ANativeWindow_setBuffersGeometry(pThis->pApp->window,0,0,Format);
- Surface=eglCreateWindowSurface(Display,Configs,pThis->pApp->window,NULL);
- Context=eglCreateContext(Display,Configs,NULL,NULL);
- if(eglMakeCurrent(Display,Surface,Surface,Context)==EGL_FALSE)
- {
- LOGW("Unable to eglMakeCurrent");
- return 0;
- }
- eglQuerySurface(Display,Surface,EGL_WIDTH,&W);
- eglQuerySurface(Display,Surface,EGL_HEIGHT,&H);
-
- pThis->Display=Display;
- pThis->Context=Context;
- pThis->Surface=Surface;
- pThis->Width=W;
- pThis->Height=H;
-
- glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_FASTEST);
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
- glClearColor(0.0f,0.0f,0.0f,0.0f);
- glClearDepthf(1.0f);
- glShadeModel(GL_FLAT);
-
- glViewport(0,0,W,H);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- return 1;
- }
- //=============================================================================
- //CleanupDisplay:
- //清理显示的部分,释放内存。和InitDisplay配套的
- //-----------------------------------------------------------------------------
- void CleanupDisplay(AppDataP pThis)
- {
- if(pThis->Display!=EGL_NO_DISPLAY)
- {
- eglMakeCurrent(pThis->Display,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
- if(pThis->Context!=EGL_NO_CONTEXT)
- eglDestroyContext(pThis->Display,pThis->Context);
- if(pThis->Surface!=EGL_NO_SURFACE)
- eglDestroySurface(pThis->Display,pThis->Surface);
- eglTerminate(pThis->Display);
- }
- pThis->Display=EGL_NO_DISPLAY;
- pThis->Context=EGL_NO_CONTEXT;
- pThis->Surface=EGL_NO_SURFACE;
- }
- GLfloat Model[3*6]=//模型
- {
- -0.1,-0.1,0.5,//两个三角形组成一个四边形
- 0.1,-0.1,0.5,
- -0.1, 0.1,0.5,
- 0.1,-0.1,0.5,
- 0.1, 0.1,0.5,
- -0.1, 0.1,0.5
- };
- //圆周率之类的东西
- #define PI 3.141592653589793238462643
- //=============================================================================
- //DrawFrame:
- //在屏幕上画一帧图像
- //-----------------------------------------------------------------------------
- void DrawFrame(AppDataP pThis)
- {
- GLfloat Aspect;
- double CurTime;
- struct timeval tv;
- GLfloat Matrix[4*4];
- if(!pThis->Display)
- return;
-
- gettimeofday(&tv,NULL);//取得时间
- CurTime=tv.tv_sec+tv.tv_usec*0.000001;//以秒为单位的时间
- Aspect=(GLfloat)(pThis->Height)/(GLfloat)(pThis->Width);//宽高比
-
- //清空图形缓冲区
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
-
- //加载模型
- glVertexPointer(3,GL_FLOAT,0,Model);
- glEnableClientState(GL_VERTEX_ARRAY);
-
- //设置矩阵
- glLoadIdentity();//载入单位矩阵
-
- memset(&Matrix,0,sizeof(Matrix));
- Matrix[10]=Matrix[15]=1;
-
- //绕Z轴旋转
- Matrix[0]=(GLfloat)sin(CurTime);
- Matrix[1]=(GLfloat)cos(CurTime);
- Matrix[4]=-Matrix[1];
- Matrix[5]=Matrix[0];
-
- //宽高比缩放
- Matrix[0]*=Aspect;
- Matrix[4]*=Aspect;
-
- //位移
- Matrix[12]=((GLfloat)(pThis->State.x)/(GLfloat)(pThis->Width))*2-1;
- Matrix[13]=1-((GLfloat)(pThis->State.y)/(GLfloat)(pThis->Height))*2;
- glMultMatrixf(Matrix);
-
- glColor4f(0,1,0,1);//绿色
- glDrawArrays(GL_TRIANGLES,0,6);//画模型
-
- glFlush();
- eglSwapBuffers(pThis->Display,pThis->Surface);//把缓冲区的图像刷到屏幕上
- }
- //=============================================================================
- //CmdProc:
- //处理窗口消息
- //-----------------------------------------------------------------------------
- static void CmdProc(struct android_app*pApp,int32_t cmd)
- {
- # define pThis ((AppDataP)pApp->userData)
- switch(cmd)
- {
- case APP_CMD_SAVE_STATE://保存状态
- pThis->pApp->savedState=malloc(sizeof(SavedState));
- if(pThis->pApp->savedState)
- {
- memcpy(pThis->pApp->savedState,&(pThis->State),sizeof(SavedState));
- pThis->pApp->savedStateSize=sizeof(SavedState);
- }
- break;
- case APP_CMD_INIT_WINDOW://初始化窗口
- if(pThis->pApp->window)
- {
- InitDisplay(pThis);
- DrawFrame(pThis);
- }
- break;
- case APP_CMD_TERM_WINDOW://结束窗口
- CleanupDisplay(pThis);
- break;
- case APP_CMD_GAINED_FOCUS://取得焦点
- if(pThis->pAccelerometerSensor)
- {
- ASensorEventQueue_enableSensor(pThis->pSensorEventQueue,pThis->pAccelerometerSensor);
- ASensorEventQueue_setEventRate(pThis->pSensorEventQueue,pThis->pAccelerometerSensor,50000);
- }
- break;
- case APP_CMD_LOST_FOCUS://失去焦点
- if (pThis->pAccelerometerSensor)
- ASensorEventQueue_disableSensor(pThis->pSensorEventQueue,pThis->pAccelerometerSensor);
- break;
- }
- # undef pThis
- }
- //=============================================================================
- //InputProc:
- //处理触摸操作
- //-----------------------------------------------------------------------------
- static int32_t InputProc(struct android_app*pApp,AInputEvent*pEvent)
- {
- # define pThis ((AppDataP)pApp->userData)
- if(AInputEvent_getType(pEvent)==AINPUT_EVENT_TYPE_MOTION)
- {
- pThis->State.x=AMotionEvent_getX(pEvent,0);
- pThis->State.y=AMotionEvent_getY(pEvent,0);
- return 1;
- }
- return 0;
- # undef pThis
- }
- //=============================================================================
- //android_main:
- //程序入口点
- //-----------------------------------------------------------------------------
- void android_main(struct android_app*pApp)
- {
- AppData This;
- // Make sure glue isn't stripped.
- app_dummy();
- memset(&This,0,sizeof(This));
- pApp->userData=&This;
- pApp->onAppCmd=CmdProc;
- pApp->onInputEvent=InputProc;
- This.pApp=pApp;
- //初始化传感器
- This.pSensorManager=ASensorManager_getInstance();
- This.pAccelerometerSensor=ASensorManager_getDefaultSensor(This.pSensorManager,ASENSOR_TYPE_ACCELEROMETER);
- This.pSensorEventQueue=ASensorManager_createEventQueue(This.pSensorManager,pApp->looper,LOOPER_ID_USER,NULL,NULL);
- if(pApp->savedState)//从已有的状态恢复回来
- memcpy(&(This.State),pApp->savedState,sizeof(SavedState));
- for(;;)
- {
- int iIdent;
- int iEvents;
- struct android_poll_source*pSource;
-
- //从传感器读取事件
- while((iIdent=ALooper_pollAll(0,NULL,&iEvents,(void**)&pSource))>=0)
- {
- //处理事件
- if(pSource)
- pSource->process(pApp,pSource);
- //如果传感器有数据,处理它
- if(iIdent==LOOPER_ID_USER)
- {
- if(This.pAccelerometerSensor)
- {
- ASensorEvent sEvent;
- while(ASensorEventQueue_getEvents(This.pSensorEventQueue,&sEvent,1)>0)//取得加速度传感器的采样
- {
- This.State.AccX=sEvent.acceleration.x;
- This.State.AccY=sEvent.acceleration.y;
- This.State.AccZ=sEvent.acceleration.z;
- }
- }
- }
- if(pApp->destroyRequested)//退出消息
- {
- CleanupDisplay(&This);
- return;
- }
- }
- DrawFrame(&This);//更新显示
- }
- }
复制代码 |
|