JNI를 이용하면 C++로 작성된 irrlicht 엔진을 Android 플랫폼에서도 돌아가게 할 수 있다.
인터넷 검색 및 삽질(-_-)끝에 알아낸 것들을 정리해둔다.
--------------------------------------------------------------
1. 프로그램 및 SDK 준비
. Cygwin 설치
- http://www.cygwin.com/
- 설치시 git 플러그인을 같이 설치하는게 좋다.
git를 이용해서 android로 포팅된 irrlicht 엔진 소스를 얻어오는데
외부 프로그램으로 하려면 좀 귀찮아서... ㅡ,.ㅡ;
. JDK 설치
- http://www.oracle.com/technetwork/java/javase/downloads/index.html
. Android SDK 설치
- http://developer.android.com/sdk/index.html
. Android NDK 설치
- http://developer.android.com/sdk/ndk/index.html
- NDK 설치 후 설치 경로를 시스템 환경변수 PATH에 추가시키자. 나중에 커맨드 칠때 편하다;
2. Android Irrlcht 소스 받기
. Cygwin을 실행시킨 후 소스를 받을 디렉토리로 이동 후에 다음 커맨드를 입력한다.
좀 기다리면 irrlichtandroid란 폴더에 소스가 다운받아져 있을 것이다.
3. Static Library로 빌드
. irrlichtandroid/project/include/IrrCompileConfig.h 파일을 열어서 102번째 줄의 선언문을 다음같이 변경한다.
//++ ellis ++ #define _IRR_POSIX_API_
//++ ellis ++ #define _IRR_COMPILE_WITH_X11_DEVICE_
//++ ellis ++ // Three lines added for android
#define _IRR_ANDROID_PLATEFORM_
#define _IRR_COMPILE_WITH_ANDROID_DEVICE_
#define _IRR_COMPILE_WITH_OGLES1_
// #define _IRR_COMPILE_WITH_OGLES2_ // <- 주석처리!
#define _DEBUG
- OpenGL ES1 이나 ES2중 하나만 선택해야 빌드가 될텐데 일단 ES1으로 선택한다.
(나중에 CreateDevice 함수로 Irrlicht Device를 만들때도 이때 선택한 그래픽옵션으로 만들어야 한다)
. irrlichtandroid/project/jni/Android.mk 파일을 다음과 같이 수정한다.
# COSOperator.cpp was removed from IRROTHEROBJ
LOCAL_PATH := $(call my-dir)
# 1. Build Static library (.a)
#
IRRMESHWRITER = CColladaMeshWriter.cpp CIrrMeshWriter.cpp CSTLMeshWriter.cpp COBJMeshWriter.cpp CPLYMeshWriter.cpp
IRRMESHOBJ = $(IRRMESHLOADER) $(IRRMESHWRITER) CSkinnedMesh.cpp CBoneSceneNode.cpp CMeshSceneNode.cpp CAnimatedMeshSceneNode.cpp CAnimatedMeshMD2.cpp CAnimatedMeshMD3.cpp CQ3LevelMesh.cpp CQuake3ShaderSceneNode.cpp
IRROBJ = CBillboardSceneNode.cpp CCameraSceneNode.cpp CDummyTransformationSceneNode.cpp CEmptySceneNode.cpp CGeometryCreator.cpp CLightSceneNode.cpp CMeshManipulator.cpp CMetaTriangleSelector.cpp COctreeSceneNode.cpp COctreeTriangleSelector.cpp CSceneCollisionManager.cpp CSceneManager.cpp CShadowVolumeSceneNode.cpp CSkyBoxSceneNode.cpp CSkyDomeSceneNode.cpp CTerrainSceneNode.cpp CTerrainTriangleSelector.cpp CVolumeLightSceneNode.cpp CCubeSceneNode.cpp CSphereSceneNode.cpp CTextSceneNode.cpp CTriangleBBSelector.cpp CTriangleSelector.cpp CWaterSurfaceSceneNode.cpp CMeshCache.cpp CDefaultSceneNodeAnimatorFactory.cpp CDefaultSceneNodeFactory.cpp
IRRPARTICLEOBJ = CParticleAnimatedMeshSceneNodeEmitter.cpp CParticleBoxEmitter.cpp CParticleCylinderEmitter.cpp CParticleMeshEmitter.cpp CParticlePointEmitter.cpp CParticleRingEmitter.cpp CParticleSphereEmitter.cpp CParticleAttractionAffector.cpp CParticleFadeOutAffector.cpp CParticleGravityAffector.cpp CParticleRotationAffector.cpp CParticleSystemSceneNode.cpp CParticleScaleAffector.cpp
IRRANIMOBJ = CSceneNodeAnimatorCameraFPS.cpp CSceneNodeAnimatorCameraMaya.cpp CSceneNodeAnimatorCollisionResponse.cpp CSceneNodeAnimatorDelete.cpp CSceneNodeAnimatorFlyCircle.cpp CSceneNodeAnimatorFlyStraight.cpp CSceneNodeAnimatorFollowSpline.cpp CSceneNodeAnimatorRotation.cpp CSceneNodeAnimatorTexture.cpp
IRRDRVROBJ = CNullDriver.cpp COGLESDriver.cpp COGLESTexture.cpp COGLESExtensionHandler.cpp
IRRDRVOBJ2 = COGLES2Driver.cpp COGLES2FixedPipelineShader.cpp COGLES2ParallaxMapRenderer.cpp COGLES2SLMaterialRenderer.cpp COGLES2ExtensionHandler.cpp COGLES2NormalMapRenderer.cpp COGLES2Renderer2D.cpp COGLES2Texture.cpp
IRRVIDEOOBJ = CVideoModeList.cpp CFPSCounter.cpp $(IRRDRVROBJ) $(IRRIMAGEOBJ)
IRRSWRENDEROBJ = CSoftwareDriver.cpp CSoftwareTexture.cpp CTRFlat.cpp CTRFlatWire.cpp CTRGouraud.cpp CTRGouraudWire.cpp CTRTextureFlat.cpp CTRTextureFlatWire.cpp CTRTextureGouraud.cpp CTRTextureGouraudAdd.cpp CTRTextureGouraudNoZ.cpp CTRTextureGouraudWire.cpp CZBuffer.cpp CTRTextureGouraudVertexAlpha2.cpp CTRTextureGouraudNoZ2.cpp CTRTextureLightMap2_M2.cpp CTRTextureLightMap2_M4.cpp CTRTextureLightMap2_M1.cpp CSoftwareDriver2.cpp CSoftwareTexture2.cpp CTRTextureGouraud2.cpp CTRGouraud2.cpp CTRGouraudAlpha2.cpp CTRGouraudAlphaNoZ2.cpp CTRTextureDetailMap2.cpp CTRTextureGouraudAdd2.cpp CTRTextureGouraudAddNoZ2.cpp CTRTextureWire2.cpp CTRTextureLightMap2_Add.cpp CTRTextureLightMapGouraud2_M4.cpp IBurningShader.cpp CTRTextureBlend.cpp CTRTextureGouraudAlpha.cpp CTRTextureGouraudAlphaNoZ.cpp CDepthBuffer.cpp CBurningShader_Raster_Reference.cpp
IRRIOOBJ = CFileList.cpp CFileSystem.cpp CLimitReadFile.cpp CMemoryFile.cpp CReadFile.cpp CWriteFile.cpp CXMLReader.cpp CXMLWriter.cpp CZipReader.cpp CPakReader.cpp CNPKReader.cpp CTarReader.cpp CMountPointReader.cpp irrXML.cpp CAttributes.cpp lzma/LzmaDec.c
IRROTHEROBJ = CIrrDeviceConsole.cpp CIrrDeviceStub.cpp CLogger.cpp Irrlicht.cpp os.cpp
IRRGUIOBJ = CGUIButton.cpp CGUICheckBox.cpp CGUIComboBox.cpp CGUIContextMenu.cpp CGUIEditBox.cpp CGUIEnvironment.cpp CGUIFileOpenDialog.cpp CGUIFont.cpp CGUIImage.cpp CGUIInOutFader.cpp CGUIListBox.cpp CGUIMenu.cpp CGUIMeshViewer.cpp CGUIMessageBox.cpp CGUIModalScreen.cpp CGUIScrollBar.cpp CGUISpinBox.cpp CGUISkin.cpp CGUIStaticText.cpp CGUITabControl.cpp CGUITable.cpp CGUIToolBar.cpp CGUIWindow.cpp CGUIColorSelectDialog.cpp CDefaultGUIElementFactory.cpp CGUISpriteBank.cpp CGUIImageList.cpp CGUITreeView.cpp
JPEGLIBOBJ = jpeglib/jcapimin.c jpeglib/jcapistd.c jpeglib/jccoefct.c jpeglib/jccolor.c jpeglib/jcdctmgr.c jpeglib/jchuff.c jpeglib/jcinit.c jpeglib/jcmainct.c jpeglib/jcmarker.c jpeglib/jcmaster.c jpeglib/jcomapi.c jpeglib/jcparam.c jpeglib/jcprepct.c jpeglib/jcsample.c jpeglib/jctrans.c jpeglib/jdapimin.c jpeglib/jdapistd.c jpeglib/jdatadst.c jpeglib/jdatasrc.c jpeglib/jdcoefct.c jpeglib/jdcolor.c jpeglib/jddctmgr.c jpeglib/jdhuff.c jpeglib/jdinput.c jpeglib/jdmainct.c jpeglib/jdmarker.c jpeglib/jdmaster.c jpeglib/jdmerge.c jpeglib/jdpostct.c jpeglib/jdsample.c jpeglib/jdtrans.c jpeglib/jerror.c jpeglib/jfdctflt.c jpeglib/jfdctfst.c jpeglib/jfdctint.c jpeglib/jidctflt.c jpeglib/jidctfst.c jpeglib/jidctint.c jpeglib/jmemmgr.c jpeglib/jmemnobs.c jpeglib/jquant1.c jpeglib/jquant2.c jpeglib/jutils.c jpeglib/jcarith.c jpeglib/jdarith.c jpeglib/jaricom.c
LIBPNGOBJ = libpng/png.c libpng/pngerror.c libpng/pngget.c libpng/pngmem.c libpng/pngpread.c libpng/pngread.c libpng/pngrio.c libpng/pngrtran.c libpng/pngrutil.c libpng/pngset.c libpng/pngtrans.c libpng/pngwio.c libpng/pngwrite.c libpng/pngwtran.c libpng/pngwutil.c
LIBAESGM = aesGladman/aescrypt.cpp aesGladman/aeskey.cpp aesGladman/aestab.cpp aesGladman/fileenc.cpp aesGladman/hmac.cpp aesGladman/prng.cpp aesGladman/pwd2key.cpp aesGladman/sha1.cpp aesGladman/sha2.cpp
BZIP2OBJ = bzip2/blocksort.c bzip2/huffman.c bzip2/crctable.c bzip2/randtable.c bzip2/bzcompress.c bzip2/decompress.c bzip2/bzlib.c
ANDROID = importgl.cpp CIrrDeviceAndroid.cpp
LOCAL_MODULE := irrlicht
LOCAL_CFLAGS := -O3 -DANDROID_NDK -DDISABLE_IMPORTGL -I./../include/ -I./include/
$(ANDROID) \
$(IRRVIDEOOBJ) $(IRRDRVOBJ2) \
$(IRRMESHOBJ) $(IRROBJ) $(IRRPARTICLEOBJ) $(IRRANIMOBJ) \
$(IRRSWRENDEROBJ) $(IRRIOOBJ) $(IRROTHEROBJ) \
$(IRRGUIOBJ) $(ZLIBOBJ) $(JPEGLIBOBJ) $(LIBPNGOBJ) $(LIBAESGM) \
$(BZIP2OBJ)
# 2. Build Shared library (.so)
#
. irrlichtandroid/project/jni 폴더로 이동한 후 ndk로 빌드하면 .a 파일이 생성!
- 멀티코어를 이용해서 빌드하면 빌드속도가 꽤 많이 단축되니 꼭 멀티코어 빌드로 하자.
다만, 멀티코어 빌드시 별 이유없이 실패할 때가 있는데 그땐 그냥 obj 폴더를 지우고
다시 빌드하면 된다. (아마도 버그인듯;)
. 빌드가 성공하면 irrlichtandroid/project/obj/local/armeabi 폴더에 libirrlicht.a 파일이 생성되있을것이다.
같이 생성된 so파일(libfakeIrrlicht.so)는 사용하지 않으니 무시할 것! (어차피 빈 껍데기 ㅋ)
. irrlicht 프로젝트에서 사용하는 방법은 다음글에 계속..


