android os 에 일리히트엔진 올려보기 강좌.(irrlicht 엔진 1.7.1 base)

|


전체화면은 더블클릭입니다.
동영상은 윈도우 7 에서만 보실수있습니다.

- 교재 - 
0. 개요

일리히트엔진버전 1.7.1 기반의 소스로 android ndk에서 컴파일하여 안드로이드에 올려봤습니다.

장좌는 일식편집기와 ndk 개발 환경이 세팅된 상태라는 가정하에서 진행하겠습니다.

1. 설치법

1-1. 엔진코어바이너리


1)  첨부파일의 압축을 풀면 include와 lib폴더가 나온다.
2) [안드로이드ndk디랙토리]/andrlicht 에 include,lib폴더를 복사해 넣는다.

위 과정은 최초 한번만 해주면된다. 추가적인 작업은 1-2부터 반복해 주면된다.


1-2. makefile 넣기

다음을 압축을 풀어서 [프로잭트 디랙토리] 루트 에 그냥 풀어준다.(그냥 현재폴더에 압축풀기)


     +-Android.mk
     +-/src
Application.mk

위에것들이 추가된것을 확인한다.


2. 자바 부분 코딩하기

Activity 클래스안에 다음을 추가해준다.

 static {
// 실제 만들어진 so파일이름을 앞부분 lib 을 빼주고써주면된다.
        System.loadLibrary("andrlicht_sample1");  
    }
    
    public native void nativeInit();
    public native void nativeSetResDirectory(String path);
    public native void nativeResize(int width, int height);
    public native void nativeOnEvent(irrEvent event);
    public native void nativeUpdate();

이벤트 클래스 만들어준다.

public class irrEvent {
public int m_Action;
public float m_PosX;
public float m_PosY;

}

오픈지엘 뷰클래스를 추가해준다.

class irrlichtGLview extends GLSurfaceView {
private main m_ac;

public irrlichtGLview(main ac){
super(ac);
m_ac = ac;
setRenderer(new irrlichtRenderer(m_ac));
}
public boolean onTouchEvent(final MotionEvent event){
return true;
}
}

class irrlichtRenderer implements GLSurfaceView.Renderer {
private main m_ac; 
public irrlichtRenderer(main ac){
m_ac = ac;
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
m_ac.nativeInit();
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
m_ac.nativeResize(width, height);
}
public void onDrawFrame(GL10 gl) {
m_ac.nativeUpdate();
}
}



3. C/C++ 부분 코딩하기

3-1. 헤더파일 자동성생하기

bin폴더에서 액티비티 클래스를 인자로 javah를 실행시킨다.

예>
[project디랙토리]/bin/javah com.andrlicht.sample.main

생성된 헤더파일을 jni/src 에 카피한다.

3-2. 연결코드 예

#include "com_andrlicht_sample1_main.h"
#include <irrlicht.h>

irr::IrrlichtDevice *pDevice;
irr::video::IVideoDriver *pVideo;
irr::scene::ISceneManager *pSmgr;
irr::gui::IGUIEnvironment *pGuiEnv;

void init()
{
pDevice = irr::createDevice(
irr::video::EDT_OGLES1,
irr::core::dimension2du(480,778)
);

pDevice->setWindowCaption(L"Type-A2");

pVideo = pDevice->getVideoDriver();
pSmgr = pDevice->getSceneManager();
pGuiEnv = pDevice->getGUIEnvironment();

pSmgr->addCameraSceneNode(0, irr::core::vector3df(0,0,-5), irr::core::vector3df(0,0,0));

}

void update()
{
static irr::u32 uLastTick=0;
//밀리세컨드값얻기
irr::u32 uTick = pDevice->getTimer()->getTime();
irr::f32 fDelta = ((float)(uTick - uLastTick)) / 1000.f; //델타값 구하기
uLastTick = uTick;
irr::video::S3DVertex Vertices[4];
irr::u16 Indice[6];

Vertices[0] = irr::video::S3DVertex(-.5,-.5,0, 0,0,-1,irr::video::SColor(0,0,255,255),0,1);
Vertices[1] = irr::video::S3DVertex(-.5,.5,0, 0,0,-1,irr::video::SColor(0,255,0,255),0,0);
Vertices[2] = irr::video::S3DVertex(.5,.5,0, 0,0,-1,irr::video::SColor(0,255,255,0),1,0);
Vertices[3] = irr::video::S3DVertex(.5,-.5,0, 0,0,-1,irr::video::SColor(0,0,255,0),1,1);

Indice[0] = 0;
Indice[1] = 1;
Indice[2] = 2;
Indice[3] = 3;
Indice[4] = 0;
Indice[5] = 2;
pVideo->beginScene(true, true, irr::video::SColor(255,100,101,140));

pSmgr->drawAll();
pGuiEnv->drawAll();

//직접 그리기
{
irr::core::matrix4 mat;//단위행렬로초기화
mat.makeIdentity();
pVideo->setTransform(irr::video::ETS_WORLD, mat); //변환초기화

irr::video::SMaterial m;
m.Lighting = false;  //라이트를꺼야 색이 제데로나온다.
//m.ZBuffer = false;

pVideo->setMaterial(m);
}

pVideo->drawIndexedTriangleList(
Vertices,
4,
Indice,
2
);

pVideo->endScene();
}

void resize(int w,int h)
{
irr::core::dimension2du size(w,h);
pVideo->OnResize(size);
}

#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_andrlicht_sample1_main
 * Method:    nativeInit
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_andrlicht_sample1_main_nativeInit
  (JNIEnv *env, jobject obj)
  {
   init();
  }

/*
 * Class:     com_andrlicht_sample1_main
 * Method:    nativeSetResDirectory
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_andrlicht_sample1_main_nativeSetResDirectory
  (JNIEnv *env, jobject obj, jstring str)
  {
  }

/*
 * Class:     com_andrlicht_sample1_main
 * Method:    nativeResize
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_com_andrlicht_sample1_main_nativeResize
  (JNIEnv *env, jobject obj, jint w, jint h)
  {
   resize(w,h);
  }

/*
 * Class:     com_andrlicht_sample1_main
 * Method:    nativeOnEvent
 * Signature: (Lcom/andrlicht/sample1/irrEvent;)V
 */
JNIEXPORT void JNICALL Java_com_andrlicht_sample1_main_nativeOnEvent
  (JNIEnv *env, jobject obj1, jobject obj2)
  {
  }

/*
 * Class:     com_andrlicht_sample1_main
 * Method:    nativeUpdate
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_andrlicht_sample1_main_nativeUpdate
  (JNIEnv *env, jobject obj)
  {
   update();
  }

#ifdef __cplusplus
}
#endif



이런식으로 만든 cpp파일을 jni/scr에 생성한다.

4. 컴파일 하기
Application.mk파일을 내용에 맞게 수정한다.

APP_MODULES      := [프로잭트이름]


jni/adroid.mk 를 내용을 맞게 수정한다.

MYAPP_SRC = [컴파일할 cpp 파일이름들]

LOCAL_MODULE := [프로잭트이름]

시크윈에서 ndk 디랙토리를 찾아가서 make APP=[프로잭트이름] 해서 컴파일을 한다.





5. 실행하기

일식편집기에서 꼭 리프레쉬를 한번 한후에 실행시켜야한다.
(일식편집기 패키지뷰어에서 .so 파일 확인 필수!)



6. 보너스
안된다고 하시는 분들이 계셔셔 확인된 샘플코드 까지 추가로 올려드립니다.
디랙토리구조 확인해두시고요.
app폴더에 andrilicht_sample1.zip을 압축푸셔셔 andrilicht_sample1이름으로 만든 디랙토리에 푸시고요.
(app/andrilicht_sample1)

씨그윈에서 아래 스샷에 나와있는 위치에서
make APP=andrilicht_sample1
으로 컴파일합니다.














And