شروع سریع برای Google Cardboard برای Android NDK

این راهنما به شما نشان می‌دهد که چگونه از Cardboard SDK برای Android برای ایجاد تجربیات واقعیت مجازی (VR) خود استفاده کنید.

می توانید از Cardboard SDK برای تبدیل گوشی هوشمند به پلتفرم VR استفاده کنید. یک گوشی هوشمند می‌تواند صحنه‌های سه بعدی را با رندر استریوسکوپیک نمایش دهد، حرکات سر را ردیابی کند و به آن واکنش نشان دهد، و با تشخیص زمانی که کاربر دکمه بیننده را فشار می‌دهد، با برنامه‌ها تعامل داشته باشد.

برای شروع، از HelloCardboard ، یک بازی آزمایشی که ویژگی‌های اصلی Cardboard SDK را نشان می‌دهد، استفاده خواهید کرد. در این بازی، کاربران برای یافتن و جمع آوری اشیاء به دنیای مجازی نگاه می کنند. به شما نشان می دهد که چگونه:

  • محیط توسعه خود را تنظیم کنید
  • برنامه دمو را دانلود و بسازید
  • کد QR یک نمایشگر Cardboard را اسکن کنید تا پارامترهای آن ذخیره شود
  • ردیابی حرکات سر کاربر
  • با تنظیم ماتریس نمایش تصویر صحیح برای هر چشم، تصاویر استریوسکوپی را ارائه دهید

HelloCardboard از Android NDK استفاده می کند. هر روش بومی این است:

  • محدود به روش کلاس HelloCardboardApp یا
  • نمونه ای از آن کلاس را ایجاد یا حذف می کند

محیط توسعه خود را تنظیم کنید

الزامات سخت افزاری:

نرم افزار مورد نیاز:

  • Android Studio نسخه 2022.1.1 "Electric Eel" یا بالاتر
  • Android SDK 13.0 "Tiramisu" (سطح API 33) یا بالاتر
  • آخرین نسخه فریم ورک اندروید NDK

    برای بررسی یا به‌روزرسانی SDK‌های نصب شده، به Preferences > Appearance and Behavior بروید

    تنظیمات سیستم > Android SDK در Android Studio.

برنامه دمو را دانلود و بسازید

Cardboard SDK با استفاده از یک فایل هدر Vulkan از پیش کامپایل شده برای هر شیدر ساخته شده است. مراحل ساخت فایل های هدر از ابتدا را می توانید در اینجا بیابید.

  1. دستور زیر را برای کلون کردن Cardboard SDK و برنامه آزمایشی HelloCardboard از GitHub اجرا کنید:

    git clone https://github.com/googlevr/cardboard.git
  2. در Android Studio، Open an موجود Android Studio Project را انتخاب کنید، سپس دایرکتوری را انتخاب کنید که در آن Cardboard SDK و برنامه نمایشی HelloCardboard در آن کلون شده است.

    کد شما در پنجره Project در Android Studio ظاهر می شود.

  3. برای مونتاژ Cardboard SDK، روی گزینه assemble در پوشه cardboard/:sdk/Tasks/build در برگه Gradle دوبار کلیک کنید (View > Tool Windows > Gradle).

  4. برنامه نمایشی HelloCardboard را با انتخاب Run > Run... روی گوشی خود اجرا کنید و هدف hellocardboard-android را انتخاب کنید.

کد QR را اسکن کنید

برای ذخیره پارامترهای دستگاه، کد QR را در نمایشگر Cardboard اسکن کنید:

اگر کاربر "SKIP" را فشار دهد و هیچ پارامتر قبلاً ذخیره شده ای وجود نداشته باشد، Cardboard پارامترهای Google Cardboard v1 (راه اندازی شده در Google I/O 2014) را ذخیره می کند.

نسخه ی نمایشی را امتحان کنید

در HelloCardboard، کره های ژئودزیکی را در فضای سه بعدی جستجو و جمع آوری خواهید کرد.

برای پیدا کردن و جمع آوری یک کره:

  1. سر خود را در هر جهت به اطراف حرکت دهید تا زمانی که یک شکل شناور ببینید.

  2. به طور مستقیم به کره نگاه کنید. این باعث تغییر رنگ آن می شود.

  3. دکمه نمایشگر Cardboard را برای "جمع آوری" کره فشار دهید.

دستگاه را پیکربندی کنید

وقتی کاربر روی نماد چرخ‌دنده ضربه می‌زند تا بینندگان Cardboard را تغییر دهد، روش nativeSwitchViewer فراخوانی می‌شود. nativeSwitchViewer CardboardQrCode_scanQrCodeAndSaveDeviceParams را فراخوانی می کند که پنجره ای را برای اسکن کد QR بیننده باز می کند. اعوجاج لنز بیننده و سایر پارامترها پس از اسکن کد QR به روز می شوند.

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

شبیه ساز Android Studio x86 را فعال کنید

برای ساخت شبیه ساز Android Studio x86، خط زیر را از فایل های build.gradle در SDK و Sample حذف کنید:

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

این همه ABI ها را فعال می کند و اندازه فایل .aar تولید شده را به میزان قابل توجهی افزایش می دهد. برای اطلاعات بیشتر به Android ABI مراجعه کنید.

ردیابی سر

ایجاد ردیاب سر

ردیاب سر یک بار در سازنده 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 ایجاد می شود، نمونه ای از کلاس HelloCardboardApp با فراخوانی متد nativeOnCreate ایجاد می شود:

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

مکث و از سرگیری ردیاب سر

برای مکث، ازسرگیری و از بین بردن ردیاب سر، به ترتیب CardboardHeadTracker_pause(head_tracker_) ، CardboardHeadTracker_resume(head_tracker_) و CardboardHeadTracker_destroy(head_tracker_) باید فراخوانی شوند. در برنامه «HelloCardboard»، آنها را در 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 یک کد QR جدید را اسکن می‌کند، کد زیر پارامترهای ذخیره‌شده را می‌خواند و از آنها برای ایجاد شی اعوجاج لنز استفاده می‌کند، که اعوجاج لنز مناسب را روی محتوای رندر شده اعمال می‌کند:

CardboardQrCode_getSavedDeviceParams(&buffer, &size);

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

CardboardQrCode_destroy(buffer);

رندرینگ

ارائه محتوا در Cardboard شامل موارد زیر است:

  • ایجاد بافت
  • دریافت ماتریس های دید و طرح ریزی برای چشم چپ و راست
  • ایجاد رندر و تنظیم مش اعوجاج
  • رندر کردن هر فریم

بافت ایجاد کنید

تمام محتوا روی یک بافت کشیده می شود که به بخش هایی برای چشم چپ و راست تقسیم می شود. این بخش ها به ترتیب در _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_);