'android'에 해당되는 글 13건

  1. 2015.11.14 android 4.4 kitkat debugging 디버거 접속 안되는 문제 해결하기
  2. 2015.08.28 android studio jar로 된 라이브러리 추가 하기
  3. 2014.07.17 android thread handler 설명
  4. 2014.07.16 안드로이드 쓰레드 정리 3
  5. 2010.12.24 믹사리 증강현실엔진에 데이타 넣기
  6. 2010.12.14 DefaultHttpClient로 SSL싸이트 접근하기
  7. 2010.12.04 java 의 스트링 인코딩이해( 자바 한글 깨짐해법을 위한연구)
  8. 2010.08.13 안드로이드 NDK R4 일리히트 연동하기 6
  9. 2010.03.27 오드로이드 구매했습니다.
  10. 2010.03.27 android os 에 일리히트엔진 올려보기 강좌.(irrlicht 엔진 1.7.1 base)

android 4.4 kitkat debugging 디버거 접속 안되는 문제 해결하기

|
LG-V400 미니페드를 쓸려는데 디버깅 연결이안되는 문제가 있었습니다.

이경우에는 MTP모드로 연결이 되어있는데 이것을 PTP모드로 바꾸어 접속하시면 디버깅연결이됩니다.

설정에 들어가시면 저장소 옵션에 설정하는것이 있습니다.






And

android studio jar로 된 라이브러리 추가 하기

|

파일->new -> new module





import JAR/AAR Package 선택




파일선택



여기까지하면 좌측 트리뷰에 원하는 모듈이 등록된걸볼수있다.





project structure-> 좌측 모듈탭에서 app 선택 -> dependency 탭 ->  +버튼 -> 3 Module dependency 선택





방금 추가한 모듈을 리스트에 뜨면 선택한다.

ok 하면 디펜던시리스트에 추가된것을 볼수있다.







And

android thread handler 설명

|

핸들러가 필요한이유는 다음과 같습니다.


안드로이드쓰레드는 특징이 하나 있습니다. 앞에서 쓰레드는 독립적인 스택공간을 가지지만 독립적인 전역 메모리 공간은 가지지못한다고했습니다.

그러면 지역변수들은 서로 분리가 되지만 쓰레드를 호출했던쪽의 쓰레드와 현재쓰레드는 같은 프로세스의 전역 메모리공간을 공유하게 됩니다. 그런데 서로 다른 쓰레드가 같은 전역 메모리를 접근할경우 임계영역 관련 이슈들이 나오게 됩니다. 그래서 안드로이드는 사전에 임계영역 관련 이슈를 원천차단하고자 쓰레드가 다르면 전역 메모리공간을 공유하지못하도록 했습니다. 다시 말해서 쓰레드객체의 멤버변수들은 다른 쓰레드에서 접근할수가없습니다.

다른쓰레드의 멤버에 접근해야할필요가 있으면 Handler를 통해서만 접근가능하도록 했습니다.



안드로이드에서 화면상에 버튼이나 텍스트박스등의 객체들의 인스턴스는 모두 ui 쓰레드에 있습니다.

따라서 위에서 설명한봐와같이 다른 thread 객체의 run함수 내에서는 ui쓰레드에 있는 객체들을 접근할수는 없습니다.

그래서 핸들러를 이용해서 우회적인 방법을 사용합니다.


public class MyHandler extends Handler {

        @Override

        public void handleMessage(Message msg) {


            Log.d(TAG,"handler call");


            mTextvw.append((String) msg.obj);

            mTextvw.append("\n");

        }

    }


핸들러는 위와 같이 정의 합니다.

Handler 에서 상속받고 handleMessage를 오버라이딩합니다. 그리고 핸들러 내부함수(handleMessage )에서는 ui쓰레드쪽 객체들을 사용할수 있습니다.

sendMessage 함수가 호출되면 handleMessage가 콜백 됩니다.


그리고 이것을 쓰레드나 러너블에서 상속 받은 클래스의 run 함수에서 sendMessage 함수를 호출해주면됩니다.

public void run() {     try {         Log.d(TAG,"1");         while (!Thread.currentThread().isInterrupted()) {             sleep(1000);             mHandler.sendMessage(mHandler.obtainMessage(1,0,0,"tick: " + System.currentTimeMillis()));             Log.d(TAG,"tick: " + System.currentTimeMillis());         }     } catch (InterruptedException e) {         e.printStackTrace();         Log.e(TAG,"InterruptedException");     } }


obtainMessage 함수로 메씨지 객체를 만들어서 넘겨줍니다.

이렇게 만들어진 객체는 handleMessage에서 Message 객체로 넘어오는 인자에 담겨지게됩니다.


obtainMessage 에 순서대로 what,arg1,arg2,obj 순서로 인자를 넘겨줍니다. 

받는쪽에서도 마찬가지로 what,arg1,arg2,obj 이름의 멤버변수로 넘겨운 인자들을 받아볼수있습니다.




MyActivity.java
package com.gbox3d.threadsample2; 
 
import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.TextView; 
 
 
public class MyActivity extends Activity { 
 
    public TextView mTextvw; 
 
    public Handler mHandler; 
    public Thread mThread; 
 
    private final String TAG = "Thread_sample2"; 
 
 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_my); 
 
        mTextvw = (TextView) findViewById(R.id.textvw); 
        mHandler = new MyHandler(); 
 
 
 
        findViewById(R.id.button1).setOnClickListener( 
                new View.OnClickListener() { 
                    @Override 
                    public void onClick(View view) { 
                        if(mThread != null) { 
 
                            mThread.interrupt(); 
                            mThread = null; 
 
                        } 
                        else { 
                            mThread = new Thread() { 
                                @Override 
                                public void run() { 
                                    super.run(); 
 
                                    Log.d(TAG,"start"); 
 
                                    try { 
                                        Log.d(TAG,"1"); 
 
 
                                        while (!Thread.currentThread().isInterrupted()) { 
 
                                            sleep(1000); 
 
                                            mHandler.sendMessage(mHandler.obtainMessage(1,0,0,"tick: " + System.currentTimeMillis())); 
                                            Log.d(TAG,"tick: " + System.currentTimeMillis()); 
 
                                        } 
 
                                    } catch (InterruptedException e) { 
                                        e.printStackTrace(); 
                                        Log.e(TAG,"InterruptedException"); 
                                    } 
                                } 
                            }; 
                            mThread.start(); 
 
                        } 
 
                    } 
                } 
        ); 
        //findViewById() 
 
 
    } 
 
    @Override 
    protected void onDestroy() { 
        super.onDestroy(); 
 
        mThread.interrupt(); 
 
        Log.d(TAG,"ondestroy"); 
    } 
 
 
    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
        // Inflate the menu; this adds items to the action bar if it is present. 
        getMenuInflater().inflate(R.menu.my, menu); 
        return true; 
    } 
 
    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
        // Handle action bar item clicks here. The action bar will 
        // automatically handle clicks on the Home/Up button, so long 
        // as you specify a parent activity in AndroidManifest.xml. 
        int id = item.getItemId(); 
        if (id == R.id.action_settings) { 
            return true; 
        } 
        return super.onOptionsItemSelected(item); 
    } 
 
    public class MyHandler extends Handler { 
        @Override 
        public void handleMessage(Message msg) { 
 
            Log.d(TAG,"handler call"); 
 
            mTextvw.append((String) msg.obj); 
            mTextvw.append("\n"); 
        } 
    } 
 
 
 
 
} 


And

안드로이드 쓰레드 정리

|

안드로이드에서 쓰레드란 어떤 의미일까요?

안드로이드앱은 기본적으로 쓰레드입니다. 우리가 흔히들 액티비티라고 하는것들 그것은 ui를 다루는 쓰레드입니다.

그래서 ui스레드라고도 합니다. 또는 앱의 기본이 되는 쓰레드 이므로 메인쓰레드라고도 합니다.

쓰레드는 실행단위입니다. 그러면서 독립적인 스택공간이 있습니다. 프로세스처럼 독립된 전역메모리 공간은 가지지못합니다.

쉽게 말해서 그냥 함수입니다.


그러나 일반적인 함수는 종속관계가 존재 합니다. 최종적으로 누군가의 부름을 받고 호출되어 실행되는게 우리가 일반적으로 아는 함수입니다.

쓰레드도 비슷합니다. 다른점은 일반적인 펑션콜은 호출 됐다가 실행점이 되돌아오길 기다립니다.

여기에 반해서 쓰레드는 호출되고 기다리지않습니다. 호출한쪽은 자기 볼일을 그대로 계속 보게됩니다.

그래서 동시에 여러개의 앱이 실행되는것도 쓰레드이기 때문에 가능 한것입니다.

또한 당연한 이야기 이겠지만 ui가 붙지않는 쓰레드도 존재합니다. 그것을 서비스라 부릅니다.


쓰레드 를 만드는 방법은 크게 두가지방법이 있고 또하나는 첫번째 방법을 간편하게 만드는 방법까지 총 3가지 방법 있습니다.

첫번째는 run함수를 오버라이딩해서 쓰레드상에서 동작하는 코드들을 그안에 넣는 방법이 있습니다.

두번째는 Runnable 인터페이스에서 상속받아서 그것을 Thread 객체의 생성자에 넣어 주는 방법입니다.


run 함수를 오바라이딩 받아서 하는 방식 입니다. 1000초 간격으로 틱값을 콘솔창에 출력하는 예제입니다.

class MyThread2 extends Thread { 
        @Override 
        public void run() { 
            super.run(); 
 
            while(!Thread.currentThread().isInterrupted()) 
            { 
                try 
                { 
                    Log.d(TAG, "thread 2 tick :" + System.currentTimeMillis()); 
                    sleep(1000); 
                } 
                catch (InterruptedException e) 
                { 
                    Log.e(TAG, "InterruptedException in thread. " + e.getMessage()); 
                    e.printStackTrace(); 
 
                    Thread.currentThread().interrupt(); 
 
                    //Log.d(TAG, "" + Thread.currentThread().isInterrupted()); 
 
                } 
 
 
 
            } 
 
        } 
    } 
 

위의 예제는 다음과 같이 사용되어 집니다.

MyThread2 mThread_test2 = new MyThread2(); 

mThread_test2.start();


다음은 러너블을 상속받아 구현한 예제일부분 입니다. 단순히 클래스를 new 해서 인스턴스를 얻은 다음 start해주면 됩니다.


class MyRunnable implements Runnable { 
 
        @Override 
        public void run() { 
            while(!Thread.currentThread().isInterrupted()) 
            { 
                try 
                { 
                    Log.d(TAG, "thread 3 tick :" + System.currentTimeMillis()); 
                    Thread.sleep(1000); 
                } 
                catch (InterruptedException e) 
                { 
                    Log.e(TAG, "InterruptedException in thread. " + e.getMessage()); 
                    e.printStackTrace(); 
 
                    Thread.currentThread().interrupt(); 
 
                    //Log.d(TAG, "" + Thread.currentThread().isInterrupted()); 
 
                } 
            } 
        } 
    } 


러너블을 이용한 방법은 다음과 같이 사용 되어 집니다.


mThread_test3 = new Thread(new MyRunnable()); mThread_test3.start();

러너블 클래스의 인스턴스를 생서자로 넘겨 줍니다.



간편쓰레드 만드는 방법도 있습니다.


mThread_test1 = new Thread() {     public void run() { 

//..쓰레드 구현 코드     } }; mThread_test1.start();





MyActivity.java
예제소스

package com.gbox3d.threadsample; import android.app.Activity; import android.content.DialogInterface; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; public class MyActivity extends Activity { public final String TAG="thread_test"; public Thread mThread_test1 = null; public Thread mThread_test2 = null; public Thread mThread_test3 = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); //첫번째 간편 쓰레드 생성하기 findViewById(R.id.button1).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { if(mThread_test1 == null) { //간편 만들기 mThread_test1 = new Thread() { public void run() { while(!Thread.currentThread().isInterrupted()) { try { sleep(1000); Log.d(TAG, "tick :" + System.currentTimeMillis()); } catch (InterruptedException e) { Log.e(TAG, "InterruptedException in thread. " + e.getMessage()); e.printStackTrace(); Thread.currentThread().interrupt(); //Log.d(TAG, "" + Thread.currentThread().isInterrupted()); } } } }; mThread_test1.start(); } else { mThread_test1.interrupt(); mThread_test1 = null; } } } ); //두번째 예제 findViewById(R.id.button2).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { if(mThread_test2 == null) { mThread_test2 = new MyThread2(); mThread_test2.start(); } else { mThread_test2.interrupt(); mThread_test2 = null; } } } ); //3번째 러너블을 이용한 방법 findViewById(R.id.button3).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { if(mThread_test3 == null) { mThread_test3 = new Thread(new MyRunnable()); mThread_test3.start(); } else { mThread_test3.interrupt(); mThread_test3 = null; } } } ); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.my, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } class MyThread2 extends Thread { @Override public void run() { super.run(); while(!Thread.currentThread().isInterrupted()) { try { Log.d(TAG, "thread 2 tick :" + System.currentTimeMillis()); sleep(1000); } catch (InterruptedException e) { Log.e(TAG, "InterruptedException in thread. " + e.getMessage()); e.printStackTrace(); Thread.currentThread().interrupt(); //Log.d(TAG, "" + Thread.currentThread().isInterrupted()); } } } } class MyRunnable implements Runnable { @Override public void run() { while(!Thread.currentThread().isInterrupted()) { try { Log.d(TAG, "thread 3 tick :" + System.currentTimeMillis()); Thread.sleep(1000); } catch (InterruptedException e) { Log.e(TAG, "InterruptedException in thread. " + e.getMessage()); e.printStackTrace(); Thread.currentThread().interrupt(); //Log.d(TAG, "" + Thread.currentThread().isInterrupted()); } } } } }


And

믹사리 증강현실엔진에 데이타 넣기

|
출처: http://code.google.com/p/mixare/wiki/DisplayYourOwnData
믹사리 엔진에서 처리할수있는 트윗 jSON 스트림 포멧 예제입니다.
{
   
"status": "OK",
   
"num_results": 3,
   
"results": [
       
{
           
"id": "2827",
           
"lat": "46.43893",
           
"lng": "11.21706",
           
"elevation": "1737",
           
"title": "Penegal",
           
"distance": "9.756",
           
"has_detail_page": "1",
           
"webpage": "http%3A%2F%2Fwww.suedtirolerland.it%2Fapi%2Fmap%2FgetMarkerTplM%2F%3Fmarker_id%3D2827%26project_id%3D15%26lang_id%3D9"
       
},
       
{
           
"id": "2821",
           
"lat": "46.49396",
           
"lng": "11.2088",
           
"elevation": "1865",
           
"title": "Gantkofel",
           
"distance": "9.771",
           
"has_detail_page": "0",
           
"webpage": ""
       
},
       
{
           
"id": "2829",
           
"lat": "46.3591",
           
"lng": "11.1921",
           
"elevation": "2116",
           
"title": "Roen",
           
"distance": "17.545",
           
"has_detail_page": "1",
           
"webpage": "http%3A%2F%2Fwww.suedtirolerland.it%2Fapi%2Fmap%2FgetMarkerTplM%2F%3Fmarker_id%3D2829%26project_id%3D15%26lang_id%3D9"
       
}
   
]
}
And

DefaultHttpClient로 SSL싸이트 접근하기

|

  1. Grab all required certificates (root and any intermediate CA’s)
  2. Create a keystore with keytool and the BouncyCastle provider and import the certs
  3. Load the keystore in your android app and use it for the secured connections
    • Don’t use the standard java.net.ssl.HttpsURLConnection for the secure connection. Use the Apache HttpClient (Version 4 atm) library, which is already built-in in android. It’s built on top of the java connection libraries and is, in my opinion, faster, better modularized and easier to understand.

대략 번역해보면 
안드로이드sdk에서 keytool이라는 유틸리티로 keystore 파일을 만든후
그것을 res/raw 에다가 넣고 앱에서 쓰는 형식이군요.

자세한 내용은 아래 출처에 있습니다.

출처 : http://blog.antoine.li/index.php/2010/10/android-trusting-ssl-certificates/
And

java 의 스트링 인코딩이해( 자바 한글 깨짐해법을 위한연구)

|
먼저 그동안 자바의 스트링 포멧에 대한 이해가 부족했었다.
안드로이드를 써서 euc-kr로 되어있는 한글홈페이지를 접근했었는데....
한글이 모두깨져 나왔다.

그래서 주로 c로 개발을 했던나로써는 바이트 문자열에 접근해서 코드체계를 직접 바꾸려는 시도를 하려고했었다.

그러나 나중에 자바의 스트링은 c언어의 문자열과는 차원이 다르게 고차원이라는것을 알았다.

 
new String("문자열","euc-kr"); 
최초 생성할때 이런식으로 인코딩자체를 지정해줄수도있다.

그래서 깨지는 문자열을

byte[] bytes = str.getBytes("euc-kr");
String newStr = new String(bytes,"utf-8");
TextVw.setText(newStr);

이와 같이 utf-8로 복원을 시키면 어떨까 생각하고 시도를 해봤지만 결과는 카오스.... ㅡ.ㅡ;;

무엇이 잘못됐을까 곰곰히 생각해보니 입력받을 당시에도 코드를 지정할수있다는 것을 발견할수있었다.
입력스트림 대상이 파일건 인터넷 http든 결국 inputstream으로 받아오는데...

InputStreamReader(InputStream in, String enc)
Constructs a new InputStreamReader on the InputStream in.

이런게 있다는 사실 발견!!

그렇다 처음부터 잘못받아온걸 다시 수정하려니 그게 문제였던거다.

그래서 스트림에서 받아올 시점에 아래와같이 두번째 인자를 "euc-kr" 로 줘서 해결 해줬다.

BufferedReader br = new BufferedReader(
new InputStreamReader(Httpconn.getInputStream(),"euc-kr"));

Httpconn 의 데이터 형은 HttpURLConnection이다.

-전체 소스-

public static String DownloadHtml(String addr) {
StringBuilder html = new StringBuilder(); 
try {
URL url = new URL(addr);
//HttpURLConnection conn = (HttpURLConnection)url.openConnection();
HttpURLConnection conn = null; 
            
            if (url.getProtocol().toLowerCase().equals("https")) { 
             //   trustAllHosts(); 
             //   HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); 
              //  https.setHostnameVerifier(DO_NOT_VERIFY); 
              //  conn = https; 
            } else { 
             conn = (HttpURLConnection) url.openConnection(); 
            } 
if (conn != null) {
conn.setConnectTimeout(10000);
conn.setUseCaches(false);
int resultcode = conn.getResponseCode();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream(),"euc-kr"));
for (;;) {
String line = br.readLine();
if (line == null) break;
html.append(line + '\n'); 
}
br.close();
}
conn.disconnect();
}
catch (Exception ex) {
Log.i("error",ex.getMessage());
return ex.getMessage();
//System.out.println(ex.getMessage());
}
return html.toString();
}


And

안드로이드 NDK R4 일리히트 연동하기

|
기존에 올린 강좌가 NDK R1으로 되어 있던거라서 최신버전 R4에서는 실행이 되지않는 다는 문의가 많이 들어와서
관련 프로잭트 파일을 통체로 올려드립니다.

R4기준이므로 다른 버전에서는 동작을 보장하지못합니다.

R4부터는 빌드 시스템이 바껴서 시그윈으로 해당프로잭트에가서 ndk-bulid만 치시면 빌드가 됩니다.

그래서 컴파일하는 방법은 간단하게....

anrl_exam1.zip

압축을 푸신 디랙토리에서 ndk-bulid만 하면됩니다.


위의 리소스는 mmt/sdcard에 넣고 실행시키면 다음과 같이 ㅡ.ㅡ;;;


안드로이드용 일리히트엔진 풀소스는 여기에 있습니다.






And

오드로이드 구매했습니다.

|

디자인은 좀 투박하지만 개발용으론 괜찬네요^^; 가격도 적당하고요.

사진 1

사진 2

사진 3


참고로

xp용 usb 드라이버 입니다. 
윈도7에서도 동작잘하는듯 합니다.
And

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
prev | 1 | 2 | next