Android NDK के लिए Google Cardboard के लिए क्विकस्टार्ट

इस गाइड में आपको बताया गया है कि Android के लिए कार्डबोर्ड SDK टूल इस्तेमाल करके, वर्चुअल रिएलिटी (वीआर) वाले अनुभव कैसे बनाए जा सकते हैं.

स्मार्टफ़ोन को वीआर प्लैटफ़ॉर्म में बदलने के लिए, कार्डबोर्ड SDK टूल का इस्तेमाल किया जा सकता है. स्मार्टफ़ोन स्टीरियोस्कोपिक रेंडरिंग के साथ 3D सीन दिखा सकता है, सिर के मूवमेंट को ट्रैक कर सकता है और उस पर प्रतिक्रिया दे सकता है. साथ ही, उपयोगकर्ता के व्यूअर बटन दबाने का पता लगाकर, ऐप्लिकेशन के साथ इंटरैक्ट कर सकता है.

शुरू करने के लिए, आपको HelloCardboard का इस्तेमाल करना होगा. यह एक ऐसा डेमो गेम है जो कार्डबोर्ड SDK टूल की मुख्य सुविधाओं को दिखाता है. गेम में उपयोगकर्ता, चीज़ों को ढूंढने और इकट्ठा करने के लिए वर्चुअल दुनिया देखते हैं. इसमें आपको नीचे दिए गए काम करने का तरीका बताया गया है:

  • डेवलपमेंट एनवायरमेंट सेट अप करें
  • डेमो ऐप्लिकेशन को डाउनलोड करना और बनाना
  • कार्डबोर्ड व्यूअर के पैरामीटर सेव करने के लिए उसका क्यूआर कोड स्कैन करें
  • उपयोगकर्ता के सिर की गतिविधि को ट्रैक करना
  • हर आंख के लिए सही व्यू प्रोजेक्शन मैट्रिक्स सेट करके स्टीरियोस्कोपिक इमेज बनाएं

Hellocardboard, Android एनडीके का इस्तेमाल करता है. हर स्थानीय तरीका होता है:

  • खास तौर पर HelloCardboardApp क्लास वाले तरीके से जुड़ा हो या
  • उस क्लास का कोई इंस्टेंस बनाता या मिटाता है

डेवलपमेंट एनवायरमेंट सेट अप करें

हार्डवेयर से जुड़ी ज़रूरी शर्तें:

सॉफ़्टवेयर की ज़रूरतें:

  • Android Studio का 2022.1.1 "Electric Eel" या इसके बाद का वर्शन
  • Android SDK 13.0 "Taramisu" (एपीआई लेवल 33) या इसके बाद का वर्शन
  • Android एनडीके फ़्रेमवर्क का सबसे नया वर्शन

    इंस्टॉल किए गए SDK टूल की समीक्षा करने या उन्हें अपडेट करने के लिए, प्राथमिकताएं > दिखने का तरीका और व्यवहार पर जाएं

    Android Studio में सिस्टम सेटिंग > Android SDK टूल पर जाएं.

डेमो ऐप्लिकेशन को डाउनलोड करना और बनाना

कार्डबोर्ड SDK टूल को हर शेडर के लिए, पहले से कंपाइल की गई Vulkan हेडर फ़ाइल का इस्तेमाल करके बनाया गया है. हेडर फ़ाइलें नए सिरे से बनाने का तरीका यहां दिया गया है.

  1. GitHub से कार्डबोर्ड SDK और Hellocardboard डेमो ऐप्लिकेशन का क्लोन बनाने के लिए, नीचे दिए गए निर्देश चलाएं:

    git clone https://github.com/googlevr/cardboard.git
  2. Android Studio में, कोई मौजूदा Android Studio प्रोजेक्ट खोलें को चुनें. इसके बाद, वह डायरेक्ट्री चुनें जिसमें कार्डबोर्ड SDK और HelloCardboard डेमो ऐप्लिकेशन को क्लोन किया गया था.

    आपका कोड, Android Studio में प्रोजेक्ट विंडो में दिखेगा.

  3. कार्डबोर्ड SDK टूल को असेंबल करने के लिए, Gradle टैब (व्यू > टूल Windows > Gradle) में cardboard/:sdk/Tasks/build फ़ोल्डर में असेंबल करें विकल्प पर दो बार क्लिक करें.

  4. अपने फ़ोन पर Hello Cardboard डेमो ऐप्लिकेशन चलाने के लिए, चलाएं > चलाएं... चुनें और hellocardboard-android टारगेट चुनें.

क्यूआर कोड को स्कैन करें

डिवाइस के पैरामीटर सेव करने के लिए, कार्डबोर्ड व्यूअर पर क्यूआर कोड स्कैन करें:

अगर उपयोगकर्ता "SKIP" दबाता है और पहले से सेव किया गया कोई पैरामीटर मौजूद नहीं है, तो Cardboard Google Cardboard v1 (Google I/O 2014 पर लॉन्च किया गया) पैरामीटर सेव करता है.

डेमो आज़माएं

Hello Cardboard में, आपको 3D स्पेस में जियोडिसिक स्फ़ीर ढूंढकर इकट्ठा करने हैं.

किसी स्फ़ीयर को खोजने और इकट्ठा करने के लिए:

  1. अपने सिर को तब तक किसी भी दिशा में घुमाएं, जब तक आपको कोई तैरता हुआ आकार न दिखे.

  2. सीधे गोले की ओर देखें. इससे इसके रंग बदल जाते हैं.

  3. स्फ़ीयर को "इकट्ठा करने" के लिए कार्डबोर्ड व्यूअर बटन दबाएं.

डिवाइस कॉन्फ़िगर करें

जब उपयोगकर्ता कार्डबोर्ड व्यूअर को स्विच करने के लिए गियर आइकॉन पर टैप करता है, तो nativeSwitchViewer तरीके को कहा जाता है. nativeSwitchViewer ने CardboardQrCode_scanQrCodeAndSaveDeviceParams को कॉल किया. इससे दर्शक का क्यूआर कोड स्कैन करने के लिए विंडो खुलती है. क्यूआर कोड स्कैन होने के बाद, व्यूअर के लेंस डिस्टॉर्शन और दूसरे पैरामीटर अपडेट हो जाते हैं.

// Called by JNI method
void HelloCardboardApp::SwitchViewer() {
  CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}

Android Studio x86 एम्युलेटर चालू करें

Android Studio x86 एम्युलेटर के लिए, SDK टूल और सैंपल में दी गई build.gradle फ़ाइलों से नीचे दी गई लाइन हटाएं:

abiFilters 'armeabi-v7a', 'arm64-v8a'

इससे सभी एबीआई चालू हो जाते हैं और जनरेट की गई .aar फ़ाइल का साइज़ काफ़ी बढ़ जाएगा. ज़्यादा जानकारी के लिए, Android एबीआई देखें.

सिर के हिलने को ट्रैक करें

हेड ट्रैकर बनाएं

HelloCardboardApp के कंस्ट्रक्टर में हेड ट्रैकर एक बार बनाया जाता है:

HelloCardboardApp::HelloCardboardApp(JavaVM* vm, jobject obj, jobject asset_mgr_obj) {
  Cardboard_initializeAndroid(vm, obj); // Must be called in constructor
  head_tracker_ = CardboardHeadTracker_create();
}

VrActivity बनाने पर, nativeOnCreate तरीके का इस्तेमाल करके HelloCardboardApp क्लास का एक इंस्टेंस जनरेट किया जाता है:

public void onCreate(Bundle savedInstance) {
  super.onCreate(savedInstance);
  nativeApp = nativeOnCreate(getAssets());
  //...
}

हेड ट्रैकर को रोकें और फिर से शुरू करें

हेड ट्रैकर को रोकने, फिर से शुरू करने, और बंद करने के लिए CardboardHeadTracker_pause(head_tracker_), CardboardHeadTracker_resume(head_tracker_), और CardboardHeadTracker_destroy(head_tracker_) को क्रम से कॉल करना ज़रूरी है. "हैलो कार्डबोर्ड" ऐप्लिकेशन में, हम उन्हें nativeOnPause, nativeOnResume, और nativeOnDestroy में कॉल करते हैं:

// Code to pause head tracker in hello_cardboard_app.cc

void HelloCardboardApp::OnPause() { CardboardHeadTracker_pause(head_tracker_); }

// Call nativeOnPause in VrActivity
@Override
protected void onPause() {
  super.onPause();
  nativeOnPause(nativeApp);
  //...
}

// Code to resume head tracker in hello_cardboard_app.cc
void HelloCardboardApp::onResume() {
  CardboardHeadTracker_resume(head_tracker_);
  //...
}

// Call nativeOnResume in VrActivity
@Override
protected void onResume() {
  super.onResume();
  //...
  nativeOnResume(nativeApp);
}

// Code to destroy head tracker in hello_cardboard_app.cc
HelloCardboardApp::~HelloCardboardApp() {
  CardboardHeadTracker_destroy(head_tracker_);
  //...
}

// Call nativeOnDestroy in VrActivity
@Override
protected void onDestroy() {
  super.onDestroy();
  nativeOnDestroy(nativeApp);
  nativeApp = 0;
}

लेंस डिस्टॉर्शन

जब भी Cardboard एक नए क्यूआर कोड को स्कैन करता है, यह कोड सेव किए गए पैरामीटर को पढ़ता है. साथ ही, उसका इस्तेमाल करके लेंस डिस्टॉर्शन ऑब्जेक्ट बनाता है, जिससे रेंडर किए गए कॉन्टेंट के लिए सही लेंस डिस्टॉर्शन लागू होता है:

CardboardQrCode_getSavedDeviceParams(&buffer, &size);

CardboardLensDistortion_destroy(lens_distortion_);
lens_distortion_ = CardboardLensDistortion_create(
    buffer, size, screen_width_, screen_height_);

CardboardQrCode_destroy(buffer);

रेंडर करना

कार्डबोर्ड में कॉन्टेंट रेंडर करने के लिए ये चीज़ें ज़रूरी हैं:

  • बनावट बनाना
  • बाईं और दाईं आंखों के लिए व्यू और प्रोजेक्शन आव्यूह पाना
  • रेंडरर बनाना और डिस्टॉर्शन मेश सेट करना
  • हर फ़्रेम रेंडर हो रहा है

टेक्सचर बनाएं

सारा कॉन्टेंट, बाईं और दाईं आंखों के लिए सेक्शन में बांटा गया है. ये सेक्शन _leftEyeTexture और _rightEyeTexture में शुरू किए जाते हैं.

void HelloCardboardApp::GlSetup() {
  LOGD("GL SETUP");

  if (framebuffer_ != 0) {
    GlTeardown();
  }

  // Create render texture.
  glGenTextures(1, &texture_);
  glBindTexture(GL_TEXTURE_2D, texture_);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screen_width_, screen_height_, 0,
               GL_RGB, GL_UNSIGNED_BYTE, 0);

  left_eye_texture_description_.texture = texture_;
  left_eye_texture_description_.left_u = 0;
  left_eye_texture_description_.right_u = 0.5;
  left_eye_texture_description_.top_v = 1;
  left_eye_texture_description_.bottom_v = 0;

  right_eye_texture_description_.texture = texture_;
  right_eye_texture_description_.left_u = 0.5;
  right_eye_texture_description_.right_u = 1;
  right_eye_texture_description_.top_v = 1;
  right_eye_texture_description_.bottom_v = 0;

  //...
  CHECKGLERROR("GlSetup");
}

ये बनावट CardboardDistortionRenderer_renderEyeToDisplay में पैरामीटर के रूप में पास की जाती हैं.

बाईं और दाईं आंख के लिए व्यू और प्रोजेक्शन आव्यूह पाएं

सबसे पहले, बाईं और दाईं आंखों के लिए आंख के आव्यूह निकालें:

CardboardLensDistortion_getEyeFromHeadMatrix(
    lens_distortion_, kLeft, eye_matrices_[0]);
CardboardLensDistortion_getEyeFromHeadMatrix(
    lens_distortion_, kRight, eye_matrices_[1]);
CardboardLensDistortion_getProjectionMatrix(
    lens_distortion_, kLeft, kZNear, kZFar, projection_matrices_[0]);
CardboardLensDistortion_getProjectionMatrix(
    lens_distortion_, kRight, kZNear, kZFar, projection_matrices_[1]);

इसके बाद, हर आंख के लिए डिस्टॉर्शन मेश पाएं और उसे डिस्टॉर्शन रेंडरर को दें:

CardboardLensDistortion_getDistortionMesh(lens_distortion_, kLeft, &left_mesh);
CardboardLensDistortion_getDistortionMesh(lens_distortion_, kRight, &right_mesh);

रेंडरर बनाएं और सही डिस्टॉर्शन मेश सेट करें

रेंडरर को सिर्फ़ एक बार शुरू करना ज़रूरी है. रेंडरर बनाने के बाद, CardboardLensDistortion_getDistortionMesh फ़ंक्शन से मिले मेश वैल्यू के मुताबिक, बाईं और दाईं आंखों के लिए नया डिस्टॉर्शन मेश सेट करें.

distortion_renderer_ = CardboardOpenGlEs2DistortionRenderer_create();
CardboardDistortionRenderer_setMesh(distortion_renderer_, &left_mesh, kLeft);
CardboardDistortionRenderer_setMesh(distortion_renderer_, &right_mesh, kRight);

कॉन्टेंट रेंडर करना

हर फ़्रेम के लिए, CardboardHeadTracker_getPose से मौजूदा हेड ओरिएंटेशन वापस पाएं:

CardboardHeadTracker_getPose(head_tracker_, monotonic_time_nano, &out_position[0], &out_orientation[0]);

हर एक आंख के लिए व्यू प्रोजेक्शन मैट्रिक्स बनाने और स्क्रीन पर कॉन्टेंट रेंडर करने के लिए, व्यू और प्रोजेक्शन मैट्रिक्स के साथ मौजूदा हेड ओरिएंटेशन का इस्तेमाल करें:

// Draw eyes views
for (int eye = 0; eye < 2; ++eye) {
  glViewport(eye == kLeft ? 0 : screen_width_ / 2, 0, screen_width_ / 2,
             screen_height_);

  Matrix4x4 eye_matrix = GetMatrixFromGlArray(eye_matrices_[eye]);
  Matrix4x4 eye_view = eye_matrix * head_view_;

  Matrix4x4 projection_matrix =
      GetMatrixFromGlArray(projection_matrices_[eye]);
  Matrix4x4 modelview_target = eye_view * model_target_;
  modelview_projection_target_ = projection_matrix * modelview_target;
  modelview_projection_room_ = projection_matrix * eye_view;

  // Draw room and target. Replace this to render your own content.
  DrawWorld();
}

कॉन्टेंट में डिस्टॉर्शन लागू करने और कॉन्टेंट को स्क्रीन पर रेंडर करने के लिए, CardboardDistortionRenderer_renderEyeToDisplay का इस्तेमाल करें.

// Render
CardboardDistortionRenderer_renderEyeToDisplay(
    distortion_renderer_, /* target_display = */ 0, /* x = */ 0, /* y = */ 0,
    screen_width_, screen_height_, &left_eye_texture_description_,
    &right_eye_texture_description_);