يوضّح لك هذا الدليل كيفية استخدام حزمة تطوير البرامج (SDK) لـ Cardboard. لـ Android لإنشاء تجارب الواقع الافتراضي (VR).
يمكنك استخدام حزمة تطوير برامج Cardboard لتحويل هاتف ذكي إلى نظام أساسي للواقع الافتراضي. هاتف ذكي عرض مشاهد ثلاثية الأبعاد مع عرض مجسم، وتتبع حركات الرأس والتفاعل معها، والتفاعل مع التطبيقات من خلال رصد ضغط المستخدم على زرّ العرض
للبدء، يمكنك استخدام HelloCardboard، وهي لعبة تجريبية توضّح الجوانب الأساسية. لميزات حزمة تطوير البرامج (SDK) في Cardboard. في اللعبة، ينظر المستخدمون حول عالم افتراضي للعثور وجمع العناصر. وتوضّح لك كيفية:
- إعداد بيئة التطوير
- تنزيل التطبيق التجريبي وإنشاؤه
- مسح رمز الاستجابة السريعة لعارض Cardboard لحفظ معلماته
- تتبع حركات رأس المستخدم
- عرض صور مجسَّمة من خلال ضبط مصفوفة إسقاط العرض الصحيحة لكل عين
يستخدم HelloCardboard Android NDK. تتميّز كل طريقة من الطرق المدمجة مع المحتوى بما يلي:
- ترتبط بشكل فريد بطريقة الفئة
HelloCardboardApp
- إنشاء مثيل لهذا الصف أو حذفه
إعداد بيئة التطوير
متطلبات الأجهزة:
- جهاز Android يعمل بالإصدار 8.0 "Oreo" من Android (المستوى 26 من واجهة برمجة التطبيقات) أو الإصدارات الأحدث
- عارض Cardboard
متطلبات البرامج:
- الإصدار 2022.1.1 "Electric Eel" من Android Studio أو أعلى
- الإصدار 13.0 من حزمة تطوير البرامج (SDK) لنظام التشغيل Android "تيراميسو" (المستوى 33 من واجهة برمجة التطبيقات) أو مستوى أعلى
أحدث إصدار من إطار عمل Android NDK
لمراجعة حِزم SDK المثبّتة أو تحديثها، انتقِل إلى الإعدادات المفضَّلة >. المظهر والسلوك
إعدادات النظام > حزمة تطوير البرامج (SDK) لنظام التشغيل Android في "استوديو Android".
تنزيل التطبيق التجريبي وإنشاؤه
صُمِّمت حزمة تطوير البرامج (SDK) لـ Cardboard باستخدام Vulkan مجمّع مسبقًا ملف العنوان لكل أداة تظليل. يمكن العثور على خطوات إنشاء ملفات العناوين من البداية هنا.
شغّل الأمر التالي لاستنباط حزمة تطوير البرامج (SDK) لـ Cardboard والعرض التوضيحي HelloCardboard من جيت هب:
git clone https://github.com/googlevr/cardboard.git
في "استوديو Android"، اختَر فتح مشروع حالي على استوديو Android، ثم اختَر الدليل الذي تم فيه استنساخ حزمة تطوير البرامج (SDK) وتطبيق HelloCardboard التجريبي.
سيظهر الرمز في نافذة "المشروع" في "استوديو Android".
لتجميع حزمة Cardboard SDK، انقر مرّتين على خيار التجميع داخل cardboard/:sdk/Tasks/build في علامة التبويب Gradle (عرض > Tool Windows > Gradle).
شغِّل تطبيق HelloCardboard التجريبي على هاتفك عن طريق اختيار تشغيل > تشغيل... و اختَر الهدف "
hellocardboard-android
".
المسح الضوئي لرمز الاستجابة السريعة
لحفظ معلمات الجهاز، امسح رمز الاستجابة السريعة على نظّارة Cardboard:
إذا ضغط المستخدم على "التخطّي" وما مِن معلمات محفوظة سابقًا، عمليات حفظ Cardboard Google Cardboard v1 (الذي تمّ إطلاقه في مؤتمر Google I/O 2014)
النسخة التجريبية
في HelloCardboard، ستبحث عن الكرويات الجيوديسية وتجمعها في مساحة ثلاثية الأبعاد.
للعثور على كرة وجمعها:
حرِّك رأسك في أي اتجاه حتى ترى شكلاً عائمًا.
انظر مباشرة إلى الكرة. هذا يتسبب في تغيير ألوانها.
اضغط على زر نظّارة Cardboard من أجل "الجمع" الكرة.
إعداد الجهاز
عندما ينقر المستخدم على رمز الترس لتبديل عارضات Cardboard، يتم تغيير nativeSwitchViewer
المريض. مكالمتان (nativeSwitchViewer
)
CardboardQrCode_scanQrCodeAndSaveDeviceParams
، يفتح نافذة المسح الضوئي
رمز الاستجابة السريعة للمشاهد. يتم تعديل تشوّه عدسة المشاهد والمعلَمات الأخرى مرّة واحدة.
يتم مسح رمز الاستجابة السريعة ضوئيًا.
// Called by JNI method
void HelloCardboardApp::SwitchViewer() {
CardboardQrCode_scanQrCodeAndSaveDeviceParams();
}
تفعيل محاكي Android Studio x86
لإنشاء محاكي Android Studio x86، يمكنك إزالة السطر التالي من
ملفان (build.gradle
) في حزمة تطوير البرامج (SDK)
والنموذج:
abiFilters 'armeabi-v7a', 'arm64-v8a'
ويتيح ذلك جميع واجهات التطبيق الثنائية (ABI) وسيزيد بشكل كبير من حجم الواجهة
ملف .aar
. الاطّلاع على واجهات التطبيق الثنائية (ABI) في 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
، يتم إنشاء مثيل للفئة 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 رمز استجابة سريعة جديدًا، يقرأ الرمز التالي المعلمات المحفوظة. وتستخدمها لإنشاء كائن تشوّه العدسة، ما يؤدي إلى تطبيق التشوّه المناسب في العدسة على المحتوى المعروض:
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_);