最新首發Eclipse+CDT+android-ndk寫純c++安卓應用(附openGL Es)

來源:互聯網
上載者:User

標籤:android   des   blog   http   color   使用   

首先下載eclipse和cdt,我的版本號碼依次是:Version: Indigo Service Release 2和Version: 1.0.0.201202111925,再下載windows的ndk,我使用的是android-ndk-r9d

什麼cygwin這等東西,太噁心了,下載慢,大的要命!複雜,今天給一個最爽的編譯教程。

前面的cdt外掛程式怎麼這裡pass,網上教程很多的。直接配置。。。

啟動eclipse,然後點Windows-Prefrences-C/C++-Build-Envionment,添加以下路徑


然後建立一個android工程,把代碼全部刪除,資源全部刪除,AndroidManifest.xml內容如下

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    package="com.example.native_activity"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="9"        tools:ignore="UsesMinSdkAttributes" />    <application        android:hasCode="false"        android:label="純CPP應用"        tools:ignore="AllowBackup,MissingApplicationIcon" >        <activity            android:name="android.app.NativeActivity"            android:configChanges="orientation|keyboardHidden" >            <!-- Tell NativeActivity the name of or .so -->            <meta-data                android:name="android.app.lib_name"                android:value="native-activity" />            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest> 

然後建立jni目錄,裡面放三個檔案,依次是Android.mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := native-activityLOCAL_SRC_FILES := main.cppLOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv1_CMLOCAL_STATIC_LIBRARIES := android_native_app_glueinclude $(BUILD_SHARED_LIBRARY)$(call import-module,android/native_app_glue)

Application.mk

APP_PLATFORM := android-14

main.cpp

#include <jni.h>#include <errno.h>#include <EGL/egl.h>#include <GLES/gl.h>#include <string.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__))/** * Our saved state data. */struct saved_state {float angle;int32_t x;int32_t y;};/** * Shared state for our app. */struct engine {struct android_app* app;ASensorManager* sensorManager;const ASensor* accelerometerSensor;ASensorEventQueue* sensorEventQueue;int animating;EGLDisplay display;EGLSurface surface;EGLContext context;int32_t width;int32_t height;struct saved_state state;};/** * Initialize an EGL context for the current display. */static int engine_init_display(struct engine* engine) {// initialize OpenGL ES and EGL/* * Here specify the attributes of the desired configuration. * Below, we select an EGLConfig with at least 8 bits per color * component compatible with on-screen windows */const EGLint attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE,8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_NONE };EGLint w, h, dummy, format;EGLint numConfigs;EGLConfig config;EGLSurface surface;EGLContext context;EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);eglInitialize(display, 0, 0);/* Here, the application chooses the configuration it desires. In this * sample, we have a very simplified selection process, where we pick * the first EGLConfig that matches our criteria */eglChooseConfig(display, attribs, &config, 1, &numConfigs);/* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). * As soon as we picked a EGLConfig, we can safely reconfigure the * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format);surface = eglCreateWindowSurface(display, config, engine->app->window,NULL);context = eglCreateContext(display, config, NULL, NULL);if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {LOGW("Unable to eglMakeCurrent");return -1;}eglQuerySurface(display, surface, EGL_WIDTH, &w);eglQuerySurface(display, surface, EGL_HEIGHT, &h);engine->display = display;engine->context = context;engine->surface = surface;engine->width = w;engine->height = h;engine->state.angle = 0;// Initialize GL state.glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);glEnable(GL_CULL_FACE);glShadeModel(GL_SMOOTH);glDisable(GL_DEPTH_TEST);return 0;}/** * Just the current frame in the display. */static void engine_draw_frame(struct engine* engine) {if (engine->display == NULL) {// No display.return;}// Just fill the screen with a color.glClearColor(((float) engine->state.x) / engine->width, engine->state.angle,((float) engine->state.y) / engine->height, 1);glClear(GL_COLOR_BUFFER_BIT);eglSwapBuffers(engine->display, engine->surface);}/** * Tear down the EGL context currently associated with the display. */static void engine_term_display(struct engine* engine) {if (engine->display != EGL_NO_DISPLAY) {eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE,EGL_NO_CONTEXT);if (engine->context != EGL_NO_CONTEXT) {eglDestroyContext(engine->display, engine->context);}if (engine->surface != EGL_NO_SURFACE) {eglDestroySurface(engine->display, engine->surface);}eglTerminate(engine->display);}engine->animating = 0;engine->display = EGL_NO_DISPLAY;engine->context = EGL_NO_CONTEXT;engine->surface = EGL_NO_SURFACE;}/** * Process the next input event. */static int32_t engine_handle_input(struct android_app* app,AInputEvent* event) {struct engine* engine = (struct engine*) app->userData;if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {engine->animating = 1;engine->state.x = AMotionEvent_getX(event, 0);engine->state.y = AMotionEvent_getY(event, 0);return 1;}return 0;}/** * Process the next main command. */static void engine_handle_cmd(struct android_app* app, int32_t cmd) {struct engine* engine = (struct engine*) app->userData;switch (cmd) {case APP_CMD_SAVE_STATE:// The system has asked us to save our current state.  Do so.engine->app->savedState = malloc((size_t)sizeof(struct saved_state));*((struct saved_state*) engine->app->savedState) = engine->state;engine->app->savedStateSize = sizeof(struct saved_state);break;case APP_CMD_INIT_WINDOW:// The window is being shown, get it ready.if (engine->app->window != NULL) {engine_init_display(engine);engine_draw_frame(engine);}break;case APP_CMD_TERM_WINDOW:// The window is being hidden or closed, clean it up.engine_term_display(engine);break;case APP_CMD_GAINED_FOCUS:// When our app gains focus, we start monitoring the accelerometer.if (engine->accelerometerSensor != NULL) {ASensorEventQueue_enableSensor(engine->sensorEventQueue,engine->accelerometerSensor);// We'd like to get 60 events per second (in us).ASensorEventQueue_setEventRate(engine->sensorEventQueue,engine->accelerometerSensor, (1000L / 60) * 1000);}break;case APP_CMD_LOST_FOCUS:// When our app loses focus, we stop monitoring the accelerometer.// This is to avoid consuming battery while not being used.if (engine->accelerometerSensor != NULL) {ASensorEventQueue_disableSensor(engine->sensorEventQueue,engine->accelerometerSensor);}// Also stop animating.engine->animating = 0;engine_draw_frame(engine);break;}}/** * This is the main entry point of a native application that is using * android_native_app_glue.  It runs in its own thread, with its own * event loop for receiving input events and doing other things. */void android_main(struct android_app* state) {struct engine engine = {0};// Make sure glue isn't stripped.app_dummy();state->userData = &engine;state->onAppCmd = engine_handle_cmd;state->onInputEvent = engine_handle_input;engine.app = state;// Prepare to monitor accelerometerengine.sensorManager = ASensorManager_getInstance();engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager, ASENSOR_TYPE_ACCELEROMETER);engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager, state->looper, LOOPER_ID_USER, NULL, NULL);if (state->savedState != NULL) {// We are starting with a previous saved state; restore from it.engine.state = *(struct saved_state*) state->savedState;}// loop waiting for stuff to do.while (true) {// Read all pending events.int ident;int events;struct android_poll_source* source;// If not animating, we will block forever waiting for events.// If animating, we loop until all events are read, then continue// to draw the next frame of animation.while ((ident = ALooper_pollAll(engine.animating ? 0 : -1, NULL,&events, (void**) &source)) >= 0) {// Process this event.if (source != NULL) {source->process(state, source);}// If a sensor has data, process it now.if (ident == LOOPER_ID_USER) {if (engine.accelerometerSensor != NULL) {ASensorEvent event;while (ASensorEventQueue_getEvents(engine.sensorEventQueue,&event, 1) > 0) {LOGI("accelerometer: x=%f y=%f z=%f", event.acceleration.x, event.acceleration.y, event.acceleration.z);}}}// Check if we are exiting.if (state->destroyRequested != 0) {engine_term_display(&engine);return;}}if (engine.animating) {// Done with events; draw next animation frame.engine.state.angle += .01f;if (engine.state.angle > 1) {engine.state.angle = 0;}engine_draw_frame(&engine);}}}

建立完成收工,然後建立另外一個工程。路徑必須是剛才建立工程的jni目錄,名字隨便,重點看圖


好了點完成,然後開啟main.cpp發現N多錯誤,直接下設定一下環境變數,右鍵工程,屬性(是剛建立的C++工程)


接下來看圖,把所有的庫加進去。



最後加一個Symbol,其實就是定義一個宏,告訴編譯器我現在的平台是Android,add


最後點OK,所有的函數都能正常識別,提示功能也可以用了。開發效率高多了。編譯直接點鎚子就行了。


然後在原來的工程運行安裝就行了!


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.