가상 현실 Android 앱을 처음부터 개발하는 방법 배우기
게시 됨: 2015-11-16이 문서에서는 Android 앱 개발의 기본 사항을 이미 알고 있다고 가정하고 가상 현실 Android 앱을 처음부터 개발하는 방법을 안내합니다.
요구 사항
- 안드로이드 스튜디오 1.0 이상
- Android SDK 버전 19
- Android 16(Jelly Bean) 이상을 실행하는 실제 Android 기기
매니페스트 파일
<발표... <사용 권한 android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <사용 권한 android:name="android.permission.VIBRATE" /> ... <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="19"/> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> <신청 ... <활동 android:name=".MainActivity" android:screenOrientation="가로"> ... <의도 필터> <액션 android:name="android.intent.action.MAIN" /> <카테고리 android:name="android.intent.category.LAUNCHER" /> <category android:name="com.google.intent.category.CARDBOARD" /> </intent-filter> </활동> </응용 프로그램> </manifest>
권한 설명:
- <uses-sdk android:minSdkVersion=”16″/> 은 기기가 API 레벨 16(Jellybean) 이상을 실행해야 함을 나타냅니다.
- <uses-sdk android:targetSdkVersion=”19″/> 은 앱이 API 레벨 19(KitKat)를 대상으로 하고 있음을 나타냅니다.
- <uses-feature android:glEsVersion=”0x00020000″ android:required=”true” /> 는 앱이 그래픽을 사용하므로 OpenGL ES 2.0을 지원해야 함을 나타냅니다.
- android:screenOrientation="landscape" 는 액티비티의 필수 화면 방향이 "가로"임을 나타냅니다. VR 앱에 대해 설정해야 하는 방향입니다. Cardboard SDK에서 사용하는 보기인 CardboardView는 전체 화면 및 가로(가로, reverseLandscape, sensorLandscape) 모드에서만 렌더링됩니다.
- android:configChanges=”orientation|keyboardHidden” 설정 도 권장되지만 필수는 아닙니다.
- android.permission.NFC 권한은 Cardboard SDK에서 Cardboard의 NFC 태그에 액세스하는 데 필요합니다.
- android.permission.READ_EXTERNAL_STORAGE 및 android.permission.WRITE_EXTERNAL_STORAGE . 이러한 권한은 사용자의 휴대전화를 VR 뷰어와 페어링하기 위해 Cardboard SDK에서 필요합니다.
- android.permission.VIBRATE 권한은 사용자에게 어떤 일이 발생했음을 알리기 위해 전화를 진동시키려면 데모 앱에서 필요합니다.
- 인텐트 필터, 특히 com.google.intent.category.CARDBOARD 는 이 활동이 Cardboard와 유사한 뷰어와 호환된다고 명시합니다. 이 카테고리는 Cardboard 앱에서 사용자의 휴대폰에 설치된 호환 가능한 앱을 나열하는 데 사용됩니다.
판지 활동 확장:
CardboardActivity는 카드보드 앱 코딩을 위한 시작점입니다. CardboardActivity는 Cardboard 장치와의 손쉬운 통합을 제공하는 기본 활동입니다. Cardboards와 상호 작용하는 이벤트를 노출하고 VR 렌더링을 위한 활동을 만들 때 일반적으로 필요한 많은 세부 정보를 처리합니다.
CardboardActivity는 시스템 UI가 숨겨져 있고 콘텐츠가 전체 화면을 차지하는 고정 몰입형 모드를 사용합니다. 이것은 활동이 전체 화면 모드일 때만 CardboardView가 렌더링되기 때문에 VR 앱의 요구 사항입니다.
Android 4.4(API 레벨 19)에는 앱을 진정한 "전체 화면"으로 전환할 수 있는 setSystemUiVisibility()에 대한 새로운 SYSTEM_UI_FLAG_IMMERSIVE 플래그가 도입되었습니다. 이 플래그를 SYSTEM_UI_FLAG_HIDE_NAVIGATION 및 SYSTEM_UI_FLAG_FULLSCREEN 플래그와 결합하면 탐색 및 상태 표시줄을 숨기고 앱에서 화면의 모든 터치 이벤트를 캡처할 수 있습니다.
CardBoardView 정의:
Android 앱의 모든 사용자 인터페이스 요소는 보기를 사용하여 빌드됩니다. Android용 Cardboard SDK는 VR 렌더링에 사용할 수 있는 GLSurfaceView의 편리한 확장인 자체 보기인 CardboardView를 제공합니다. CardboardView는 콘텐츠를 스테레오로 렌더링합니다. 데모 앱이 활동 레이아웃 xml 파일에서 다음과 같은 방식으로 aCardboardView를 정의하는 방법을 확인할 수 있습니다.
<com.google.vrtoolkit.cardboard.CardboardView android:fill_parent" android:layout_height="fill_parent" />
그런 다음 기본 활동 클래스에서 onCreate() 메서드에서 CardboardView를 초기화합니다.
** * 보기를 CardboardView로 설정하고 사용할 변환 행렬을 초기화합니다. * 장면을 렌더링합니다. * @param storedInstanceState */ @우세하다 공개 무효 onCreate(저장된 인스턴스 상태 번들) { super.onCreate(저장된 인스턴스 상태); setContentView(R.layout.common_ui); CardboardView cardboardView = (CardboardView) findViewById(R.id.cardboard_view); // CardboardView.StereoRenderer를 cardboardView와 연결합니다. 판지보기.setRenderer(이); // 이 액티비티와 cardboardView를 연결합니다. setCardboardView(판지 보기); // 여기에서 다른 객체를 초기화합니다. .... }
뷰 렌더링
CardboardView를 얻으면 렌더러와 연결한 다음 CardboardView를 활동과 연결합니다. Cardboard는 두 종류의 렌더러를 지원하지만 시작하는 가장 빠른 방법은 데모 앱에서 사용하는 CardboardView.StereoRenderer를 사용하는 것입니다.
CardboardView.StereoRenderer에는 다음과 같은 주요 메서드가 포함되어 있습니다.
- onNewFrame(), 앱이 렌더링될 때마다 호출됩니다.
- onDrawEye(), 다른 눈 매개변수를 사용하여 각 눈에 대해 호출됩니다.
이를 구현하는 것은 일반적으로 OpenGL 응용 프로그램에 대해 수행하는 것과 유사합니다. 이러한 방법은 다음 섹션에서 더 자세히 설명합니다.
onNewFrame 구현
onNewFrame() 메서드를 사용하여 개별 눈이 렌더링되기 전에 렌더링 논리를 인코딩합니다. 단일 보기에 국한되지 않은 모든 프레임별 작업은 여기에서 발생해야 합니다. 이것은 모델을 업데이트하기에 좋은 곳입니다. 이 스니펫에서 변수 mHeadView는 머리의 위치를 포함합니다. 이 값은 나중에 사용자가 보물을 보고 있는지 확인하는 데 사용하기 위해 저장해야 합니다.
/** * 프레임을 그리기 전에 OpenGL ES를 준비합니다. * @param headTransform 새 프레임의 머리 변환입니다. */ @우세하다 공개 무효 onNewFrame(HeadTransform headTransform) { ... headTransform.getHeadView(mHeadView, 0); ... }
onDrawEye 구현
눈별 구성을 수행하려면 onDrawEye()를 구현하십시오.
이것은 렌더링 코드의 핵심이며 일반 OpenGL ES2 애플리케이션을 구축하는 것과 매우 유사합니다. 다음 스니펫은 뷰 변환 행렬과 원근 변환 행렬을 가져오는 방법을 보여줍니다. 낮은 대기 시간으로 렌더링해야 합니다. Eye 객체는 눈에 대한 변환 및 투영 행렬을 포함합니다. 이벤트 순서는 다음과 같습니다.
- 보물은 눈 공간에 온다.
- 투영 행렬을 적용합니다. 이것은 지정된 눈에 대해 렌더링된 장면을 제공합니다.
- Cardboard SDK는 자동으로 왜곡을 적용하여 최종 장면을 렌더링합니다.
/** * 눈의 프레임을 그립니다. * * @param eye 렌더링할 눈. 필요한 모든 변환을 포함합니다. */ @우세하다 공개 무효 onDrawEye(눈 눈) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); ... // 카메라에 눈 변환을 적용합니다. Matrix.multiplyMM(mView, 0, eye.getEyeView(), 0, mCamera, 0); // 빛의 위치 설정 Matrix.multiplyMV(mLightPosInEyeSpace, 0, mView, 0, LIGHT_POS_IN_WORLD_SPACE, 0); // ModelView 및 ModelViewProjection 행렬을 빌드합니다. // 큐브 위치와 빛을 계산하기 위해. float[] 원근 = eye.getPerspective(Z_NEAR, Z_FAR); Matrix.multiplyMM(mModelView, 0, mView, 0, mModelCube, 0); Matrix.multiplyMM(mModelViewProjection, 0, 원근감, 0, mModelView, 0); 드로큐브(); // 나머지 장면을 그립니다. ... }
입력 처리
Cardboard 뷰어에는 자석을 사용하는 푸시 버튼이 포함되어 있습니다. 자석을 누르면 자기장이 바뀌고 휴대전화의 자력계가 이를 감지합니다. 이러한 자석 이벤트는 Cardboard SDK에서 감지합니다.
사용자가 자석을 당길 때 맞춤 동작을 제공하려면 앱 활동에서 overrideCardboardActivity.onCardboardTrigger()를 사용하세요. 보물찾기 앱에서 보물을 발견하고 자석을 당기면 보물을 보관할 수 있습니다.
/** * 점수를 높이고, 개체를 숨기고, 사용자가 자석을 당기는 동안 피드백을 제공합니다. * 물체를 바라보는 것. 그렇지 않으면 사용자에게 무엇을 해야 하는지 상기시킵니다. */ @우세하다 공개 무효 onCardboardTrigger() { if (isLookingAtObject()) { m점수++; mOverlayView.show3DToast("찾았습니다! 다른 것을 찾아보세요.\nScore = " + mScore); ... } 또 다른 { mOverlayView.show3DToast("객체를 찾기 위해 주위를 둘러보세요!"); } // 항상 사용자 피드백을 제공합니다. mVibrator.vibrate(50); }
나만의 프로젝트 시작
이제 Android용 Cardboard SDK에 더 익숙해졌으므로 자신만의 애플리케이션을 만들 차례입니다.
처음부터 시작하는 새로운 프로젝트이든 기존 프로젝트이든 상관없이 다음은 수행해야 할 작업입니다.
1) 두 개의 JAR 파일을 다운로드합니다. 다운로드하려면 여기를 클릭하십시오
2) 복사하여 app/libs 폴더에 붙여넣습니다(Android Studio 프로젝트 구조의 프로젝트 보기에서 찾기).
3) 라이브러리를 마우스 오른쪽 버튼으로 클릭하고 "라이브러리로 추가"를 선택합니다.
그런 다음 프로젝트의 app/build.gradle 파일에 다음 줄이 있는지 확인합니다.
종속성 { ... 컴파일 fileTree(dir: 'libs', 포함: ['*.jar']) }
가상 현실 앱 개발을 시작할 준비가 되었습니다!