[size=1em]1 [size=1em]2 [size=1em]3 [size=1em]4 [size=1em]5 [size=1em]6 [size=1em]7 [size=1em]8 [size=1em]9 [size=1em]10 [size=1em]11 [size=1em]12 [size=1em]13 [size=1em]14 [size=1em]15 [size=1em]16 [size=1em]17 [size=1em]18 [size=1em]19 [size=1em]20 [size=1em]21 [size=1em]22 [size=1em]23 [size=1em]24 [size=1em]25 [size=1em]26 [size=1em]27 | [size=1em][size=1em]<manifest xmlns:android="http://schemas.android.com/apk/res/android" [size=1em] package="com.example.native_activity" [size=1em] android:versionCode="1" [size=1em] android:versionName="1.0"> [size=1em] <!-- This is the platform API where NativeActivity was introduced. --> [size=1em] <uses-sdk android:minSdkVersion="8" /> [size=1em] <!-- This .apk has no Java code itself, so set hasCode to false. --> [size=1em] <application android:label="@string/app_name" android:hasCode="false"> [size=1em] <!-- Our activity is the built-in NativeActivity framework class. [size=1em] This will take care of integrating with our NDK code. --> [size=1em] <activity android:name="android.app.NativeActivity" [size=1em] android:label="@string/app_name" [size=1em] android:configChanges="orientation|keyboardHidden"> [size=1em] <!-- Tell NativeActivity the name of or .so --> [size=1em] <meta-data android:name="android.app.lib_name" [size=1em] android:value="native-activity" /> [size=1em] <intent-filter> [size=1em] <action android:name="android.intent.action.MAIN" /> [size=1em] <category android:name="android.intent.category.LAUNCHER" /> [size=1em] </intent-filter> [size=1em] </activity> [size=1em] </application> [size=1em]</manifest> |
[size=1em]1 [size=1em]2 [size=1em]3 [size=1em]4 [size=1em]5 [size=1em]6 [size=1em]7 [size=1em]8 [size=1em]9 [size=1em]10 [size=1em]11 [size=1em]12 [size=1em]13 [size=1em]14 [size=1em]15 [size=1em]16 [size=1em]17 [size=1em]18 [size=1em]19 [size=1em]20 [size=1em]21 [size=1em]22 [size=1em]23 [size=1em]24 [size=1em]25 [size=1em]26 [size=1em]27 [size=1em]28 [size=1em]29 [size=1em]30 [size=1em]31 [size=1em]32 [size=1em]33 [size=1em]34 [size=1em]35 [size=1em]36 [size=1em]37 [size=1em]38 [size=1em]39 [size=1em]40 [size=1em]41 [size=1em]42 [size=1em]43 [size=1em]44 [size=1em]45 [size=1em]46 [size=1em]47 [size=1em]48 [size=1em]49 [size=1em]50 [size=1em]51 [size=1em]52 [size=1em]53 [size=1em]54 [size=1em]55 [size=1em]56 [size=1em]57 [size=1em]58 [size=1em]59 [size=1em]60 [size=1em]61 [size=1em]62 [size=1em]63 [size=1em]64 [size=1em]65 [size=1em]66 [size=1em]67 [size=1em]68 [size=1em]69 [size=1em]70 [size=1em]71 [size=1em]72 [size=1em]73 [size=1em]74 [size=1em]75 [size=1em]76 [size=1em]77 [size=1em]78 [size=1em]79 [size=1em]80 [size=1em]81 [size=1em]82 [size=1em]83 [size=1em]84 [size=1em]85 [size=1em]86 [size=1em]87 [size=1em]88 [size=1em]89 [size=1em]90 [size=1em]91 [size=1em]92 [size=1em]93 [size=1em]94 [size=1em]95 [size=1em]96 [size=1em]97 [size=1em]98 [size=1em]99 [size=1em]100 [size=1em]101 [size=1em]102 [size=1em]103 [size=1em]104 [size=1em]105 [size=1em]106 [size=1em]107 [size=1em]108 [size=1em]109 [size=1em]110 [size=1em]111 [size=1em]112 [size=1em]113 [size=1em]114 [size=1em]115 [size=1em]116 [size=1em]117 [size=1em]118 [size=1em]119 [size=1em]120 [size=1em]121 [size=1em]122 [size=1em]123 [size=1em]124 [size=1em]125 [size=1em]126 [size=1em]127 [size=1em]128 [size=1em]129 [size=1em]130 [size=1em]131 [size=1em]132 [size=1em]133 [size=1em]134 [size=1em]135 [size=1em]136 [size=1em]137 [size=1em]138 [size=1em]139 [size=1em]140 [size=1em]141 [size=1em]142 [size=1em]143 [size=1em]144 [size=1em]145 [size=1em]146 [size=1em]147 [size=1em]148 [size=1em]149 [size=1em]150 [size=1em]151 [size=1em]152 [size=1em]153 [size=1em]154 [size=1em]155 [size=1em]156 [size=1em]157 [size=1em]158 [size=1em]159 [size=1em]160 [size=1em]161 [size=1em]162 [size=1em]163 [size=1em]164 [size=1em]165 [size=1em]166 [size=1em]167 [size=1em]168 [size=1em]169 [size=1em]170 [size=1em]171 [size=1em]172 [size=1em]173 [size=1em]174 [size=1em]175 [size=1em]176 [size=1em]177 [size=1em]178 [size=1em]179 [size=1em]180 [size=1em]181 [size=1em]182 [size=1em]183 [size=1em]184 [size=1em]185 [size=1em]186 [size=1em]187 [size=1em]188 [size=1em]189 [size=1em]190 [size=1em]191 [size=1em]192 [size=1em]193 [size=1em]194 [size=1em]195 [size=1em]196 [size=1em]197 [size=1em]198 [size=1em]199 [size=1em]200 [size=1em]201 [size=1em]202 [size=1em]203 [size=1em]204 [size=1em]205 [size=1em]206 [size=1em]207 [size=1em]208 [size=1em]209 [size=1em]210 [size=1em]211 [size=1em]212 [size=1em]213 [size=1em]214 [size=1em]215 [size=1em]216 [size=1em]217 [size=1em]218 [size=1em]219 [size=1em]220 [size=1em]221 [size=1em]222 [size=1em]223 [size=1em]224 [size=1em]225 [size=1em]226 [size=1em]227 [size=1em]228 [size=1em]229 [size=1em]230 [size=1em]231 [size=1em]232 [size=1em]233 [size=1em]234 [size=1em]235 [size=1em]236 [size=1em]237 [size=1em]238 [size=1em]239 [size=1em]240 [size=1em]241 [size=1em]242 [size=1em]243 [size=1em]244 [size=1em]245 [size=1em]246 [size=1em]247 [size=1em]248 [size=1em]249 [size=1em]250 [size=1em]251 [size=1em]252 [size=1em]253 [size=1em]254 [size=1em]255 [size=1em]256 [size=1em]257 [size=1em]258 [size=1em]259 [size=1em]260 [size=1em]261 [size=1em]262 [size=1em]263 [size=1em]264 [size=1em]265 [size=1em]266 [size=1em]267 [size=1em]268 [size=1em]269 [size=1em]270 [size=1em]271 [size=1em]272 [size=1em]273 [size=1em]274 [size=1em]275 [size=1em]276 [size=1em]277 [size=1em]278 [size=1em]279 [size=1em]280 [size=1em]281 [size=1em]282 [size=1em]283 [size=1em]284 [size=1em]285 [size=1em]286 [size=1em]287 [size=1em]288 | [size=1em][size=1em]#include <jni.h> [size=1em]#include <errno.h> [size=1em]#include <EGL/egl.h> [size=1em]#include <GLES/gl.h> [size=1em]#include <android/sensor.h> [size=1em]#include <android/log.h> [size=1em]#include <android_native_app_glue.h> [size=1em]#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__)) [size=1em]#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__)) [size=1em]/** [size=1em] * Our saved state data. [size=1em] */ [size=1em]struct saved_state { [size=1em] float angle; [size=1em] int32_t x; [size=1em] int32_t y; [size=1em]}; [size=1em]/** [size=1em] * Shared state for our app. [size=1em] */ [size=1em]struct engine { [size=1em] struct android_app* app; [size=1em] ASensorManager* sensorManager; [size=1em] const ASensor* accelerometerSensor; [size=1em] ASensorEventQueue* sensorEventQueue; [size=1em] int animating; [size=1em] EGLDisplay display; [size=1em] EGLSurface surface; [size=1em] EGLContext context; [size=1em] int32_t width; [size=1em] int32_t height; [size=1em] struct saved_state state; [size=1em]}; [size=1em]/** [size=1em] * Initialize an EGL context for the current display. [size=1em] */ [size=1em]static int engine_init_display(struct engine* engine) { [size=1em] // initialize OpenGL ES and EGL [size=1em] /* [size=1em] * Here specify the attributes of the desired configuration. [size=1em] * Below, we select an EGLConfig with at least 8 bits per color [size=1em] * component compatible with on-screen windows [size=1em] */ [size=1em] const EGLint attribs[] = { [size=1em] EGL_SURFACE_TYPE, EGL_WINDOW_BIT, [size=1em] EGL_BLUE_SIZE, 8, [size=1em] EGL_GREEN_SIZE, 8, [size=1em] EGL_RED_SIZE, 8, [size=1em] EGL_NONE [size=1em] }; [size=1em] EGLint w, h, dummy, format; [size=1em] EGLint numConfigs; [size=1em] EGLConfig config; [size=1em] EGLSurface surface; [size=1em] EGLContext context; [size=1em] EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); [size=1em] eglInitialize(display, 0, 0); [size=1em] /* Here, the application chooses the configuration it desires. In this [size=1em] * sample, we have a very simplified selection process, where we pick [size=1em] * the first EGLConfig that matches our criteria */ [size=1em] eglChooseConfig(display, attribs, &config, 1, &numConfigs); [size=1em] /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is [size=1em] * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). [size=1em] * As soon as we picked a EGLConfig, we can safely reconfigure the [size=1em] * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ [size=1em] eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); [size=1em] ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format); [size=1em] surface = eglCreateWindowSurface(display, config, engine->app->window, NULL); [size=1em] context = eglCreateContext(display, config, NULL, NULL); [size=1em] if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { [size=1em] LOGW("Unable to eglMakeCurrent"); [size=1em] return -1; [size=1em] } [size=1em] eglQuerySurface(display, surface, EGL_WIDTH, &w); [size=1em] eglQuerySurface(display, surface, EGL_HEIGHT, &h); [size=1em] engine->display = display; [size=1em] engine->context = context; [size=1em] engine->surface = surface; [size=1em] engine->width = w; [size=1em] engine->height = h; [size=1em] engine->state.angle = 0; [size=1em] // Initialize GL state. [size=1em] glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); [size=1em] glEnable(GL_CULL_FACE); [size=1em] glShadeModel(GL_SMOOTH); [size=1em] glDisable(GL_DEPTH_TEST); [size=1em] return 0; [size=1em]} [size=1em]/** [size=1em] * Just the current frame in the display. [size=1em] */ [size=1em]static void engine_draw_frame(struct engine* engine) { [size=1em] if (engine->display == NULL) { [size=1em] // No display. [size=1em] return; [size=1em] } [size=1em] // Just fill the screen with a color. [size=1em] glClearColor(((float)engine->state.x)/engine->width, engine->state.angle, [size=1em] ((float)engine->state.y)/engine->height, 1); [size=1em] glClear(GL_COLOR_BUFFER_BIT); [size=1em] eglSwapBuffers(engine->display, engine->surface); [size=1em]} [size=1em]/** [size=1em] * Tear down the EGL context currently associated with the display. [size=1em] */ [size=1em]static void engine_term_display(struct engine* engine) { [size=1em] if (engine->display != EGL_NO_DISPLAY) { [size=1em] eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); [size=1em] if (engine->context != EGL_NO_CONTEXT) { [size=1em] eglDestroyContext(engine->display, engine->context); [size=1em] } [size=1em] if (engine->surface != EGL_NO_SURFACE) { [size=1em] eglDestroySurface(engine->display, engine->surface); [size=1em] } [size=1em] eglTerminate(engine->display); [size=1em] } [size=1em] engine->animating = 0; [size=1em] engine->display = EGL_NO_DISPLAY; [size=1em] engine->context = EGL_NO_CONTEXT; [size=1em] engine->surface = EGL_NO_SURFACE; [size=1em]} [size=1em]/** [size=1em] * Process the next input event. [size=1em] */ [size=1em]static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { [size=1em] struct engine* engine = (struct engine*)app->userData; [size=1em] if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { [size=1em] engine->animating = 1; [size=1em] engine->state.x = AMotionEvent_getX(event, 0); [size=1em] engine->state.y = AMotionEvent_getY(event, 0); [size=1em] return 1; [size=1em] } [size=1em] return 0; [size=1em]} [size=1em]/** [size=1em] * Process the next main command. [size=1em] */ [size=1em]static void engine_handle_cmd(struct android_app* app, int32_t cmd) { [size=1em] struct engine* engine = (struct engine*)app->userData; [size=1em] switch (cmd) { [size=1em] case APP_CMD_SAVE_STATE: [size=1em] // The system has asked us to save our current state. Do so. [size=1em] engine->app->savedState = malloc(sizeof(struct saved_state)); [size=1em] *((struct saved_state*)engine->app->savedState) = engine->state; [size=1em] engine->app->savedStateSize = sizeof(struct saved_state); [size=1em] break; [size=1em] case APP_CMD_INIT_WINDOW: [size=1em] // The window is being shown, get it ready. [size=1em] if (engine->app->window != NULL) { [size=1em] engine_init_display(engine); [size=1em] engine_draw_frame(engine); [size=1em] } [size=1em] break; [size=1em] case APP_CMD_TERM_WINDOW: [size=1em] // The window is being hidden or closed, clean it up. [size=1em] engine_term_display(engine); [size=1em] break; [size=1em] case APP_CMD_GAINED_FOCUS: [size=1em] // When our app gains focus, we start monitoring the accelerometer. [size=1em] if (engine->accelerometerSensor != NULL) { [size=1em] ASensorEventQueue_enableSensor(engine->sensorEventQueue, [size=1em] engine->accelerometerSensor); [size=1em] // We'd like to get 60 events per second (in us). [size=1em] ASensorEventQueue_setEventRate(engine->sensorEventQueue, [size=1em] engine->accelerometerSensor, (1000L/60)*1000); [size=1em] } [size=1em] break; [size=1em] case APP_CMD_LOST_FOCUS: [size=1em] // When our app loses focus, we stop monitoring the accelerometer. [size=1em] // This is to avoid consuming battery while not being used. [size=1em] if (engine->accelerometerSensor != NULL) { [size=1em] ASensorEventQueue_disableSensor(engine->sensorEventQueue, [size=1em] engine->accelerometerSensor); [size=1em] } [size=1em] // Also stop animating. [size=1em] engine->animating = 0; [size=1em] engine_draw_frame(engine); [size=1em] break; [size=1em] } [size=1em]} [size=1em]/** [size=1em] * This is the main entry point of a native application that is using [size=1em] * android_native_app_glue. It runs in its own thread, with its own [size=1em] * event loop for receiving input events and doing other things. [size=1em] */ [size=1em]void android_main(struct android_app* state) { [size=1em] struct engine engine; [size=1em] // Make sure glue isn't stripped. [size=1em] app_dummy(); [size=1em] memset(&engine, 0, sizeof(engine)); [size=1em] state->userData = &engine; [size=1em] state->onAppCmd = engine_handle_cmd; [size=1em] state->onInputEvent = engine_handle_input; [size=1em] engine.app = state; [size=1em] // Prepare to monitor accelerometer [size=1em] engine.sensorManager = ASensorManager_getInstance(); [size=1em] engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager, [size=1em] ASENSOR_TYPE_ACCELEROMETER); [size=1em] engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager, [size=1em] state->looper, LOOPER_ID_USER, NULL, NULL); [size=1em] if (state->savedState != NULL) { [size=1em] // We are starting with a previous saved state; restore from it. [size=1em] engine.state = *(struct saved_state*)state->savedState; [size=1em] } [size=1em] // loop waiting for stuff to do. [size=1em] while (1) { [size=1em] // Read all pending events. [size=1em] int ident; [size=1em] int events; [size=1em] struct android_poll_source* source; [size=1em] // If not animating, we will block forever waiting for events. [size=1em] // If animating, we loop until all events are read, then continue [size=1em] // to draw the next frame of animation. [size=1em] while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events, [size=1em] (void**)&source)) >= 0) { [size=1em] // Process this event. [size=1em] if (source != NULL) { [size=1em] source->process(state, source); [size=1em] } [size=1em] // If a sensor has data, process it now. [size=1em] if (ident == LOOPER_ID_USER) { [size=1em] if (engine.accelerometerSensor != NULL) { [size=1em] ASensorEvent event; [size=1em] while (ASensorEventQueue_getEvents(engine.sensorEventQueue, [size=1em] &event, 1) > 0) { [size=1em] LOGI("accelerometer: x=%f y=%f z=%f", [size=1em] event.acceleration.x, event.acceleration.y, [size=1em] event.acceleration.z); [size=1em] } [size=1em] } [size=1em] } [size=1em] // Check if we are exiting. [size=1em] if (state->destroyRequested != 0) { [size=1em] engine_term_display(&engine); [size=1em] return; [size=1em] } [size=1em] } [size=1em] if (engine.animating) { [size=1em] // Done with events; draw next animation frame. [size=1em] engine.state.angle += .01f; [size=1em] if (engine.state.angle > 1) { [size=1em] engine.state.angle = 0; [size=1em] } [size=1em] // Drawing is throttled to the screen update rate, so there [size=1em] // is no need to do timing here. [size=1em] engine_draw_frame(&engine); [size=1em] } [size=1em] } [size=1em]} |
欢迎光临 因仑“3+1”工程特种兵精英论坛 (http://bbs.enlern.com/) | Powered by Discuz! X3.4 |