يشتمل Android على رسومات ثنائية وثلاثية الأبعاد عالية الأداء من خلال Open Graphics Library (OpenGL®)، لا سيما واجهة OpenGL ES API. OpenGL هو واجهة برمجة تطبيقات للرسومات عبر الأنظمة الأساسية تحدد واجهة برنامج قياسية لأجهزة معالجة الرسومات ثلاثية الأبعاد. أمّا OpenGL ES، فهو يتطابق مع مواصفات OpenGL المصمّمة للأجهزة المضمّنة. يتوافق نظام التشغيل Android مع العديد من إصدارات واجهة برمجة التطبيقات OpenGL ES:
- OpenGL ES 2.0 - تتوافق مواصفات واجهة برمجة التطبيقات هذه مع الإصدار Android 2.2 (المستوى 8 لواجهة برمجة التطبيقات) والإصدارات الأحدث.
- OpenGL ES 3.0 - يتم دعم مواصفات واجهة برمجة التطبيقات هذه في الإصدار Android 4.3 (المستوى 18) والإصدارات الأحدث.
- OpenGL ES 3.1 - تتوافق مواصفات واجهة برمجة التطبيقات هذه مع الإصدار Android 5.0 (المستوى 21 من واجهة برمجة التطبيقات) والإصدارات الأحدث.
- OpenGL ES 3.2 - تتوافق مواصفات واجهة برمجة التطبيقات هذه مع الإصدار Android 7.0 (المستوى 24 من واجهة برمجة التطبيقات) والإصدارات الأحدث.
تحذير: بغض النظر عن إصدار نظام Android الأساسي، لا يمكن للجهاز استخدام واجهة برمجة التطبيقات OpenGL ES 3.0 ما لم توفّر الشركة المصنّعة للجهاز عملية تنفيذ لمسار الرسومات هذا. وإذا حدّدت في البيان أنّ OpenGL ES 3.0 مطلوب، يمكنك التأكّد من توفّر هذا الإصدار على الجهاز. إذا حددت أن يلزم استخدام إصدار من مستوى أدنى، ولكنك تريد استخدام ميزات الإصدار 3.0 في حال توفرها، يجب التحقق في وقت التشغيل لمعرفة إصدار OpenGL المتوافق مع الجهاز. ولمزيد من المعلومات حول طريقة إجراء ذلك، يمكنك الاطّلاع على التحقق من إصدار OpenGL ES.
ملاحظة: يتوافق Android مع OpenGL ES 1.0 و1.1، ولكن تم إيقاف هذَين الإصدارَين من واجهة برمجة التطبيقات نهائيًا ويجب ألا يتم استخدامهما في التطبيقات الحديثة.
ملاحظة: تشبه واجهة برمجة التطبيقات المحددة التي يوفرها إطار عمل Android واجهة برمجة التطبيقات J2ME JSR239 OpenGL ES API، ولكنها ليست متطابقة. إذا كنت على دراية بمواصفات J2ME JSR239، ننصحك بالانتباه إلى أي اختلافات.
راجع أيضًا
الأساسيات
يدعم Android برنامج OpenGL من خلال واجهة برمجة التطبيقات لإطار العمل وحزمة تطوير البرامج الأصلية (NDK). يركز هذا الموضوع على واجهات إطار عمل Android. لمزيد من المعلومات حول NDK، راجع Android NDK.
هناك فئتان أساسيتان في إطار عمل Android تتيحان لك إنشاء الرسومات ومعالجتها باستخدام OpenGL ES API، وهما: GLSurfaceView
وGLSurfaceView.Renderer
. إذا كان هدفك هو استخدام OpenGL في تطبيق Android،
فيجب أن يكون هدفك الأول هو فهم كيفية تنفيذ هذه الفئات في نشاط معيّن.
GLSurfaceView
- هذه الفئة هي
View
يمكنك فيها رسم العناصر ومعالجتها باستخدام طلبات البيانات من واجهة برمجة التطبيقات OpenGL، وهي تتشابه في وظيفتها معSurfaceView
. يمكنك استخدام هذه الفئة من خلال إنشاء مثيلGLSurfaceView
وإضافةRenderer
إليه. وإذا أردت تسجيل أحداث الشاشة التي تعمل باللمس، عليك توسيع الفئةGLSurfaceView
لتنفيذ أدوات معالجة اللمس، كما هو موضَّح في درس تدريب OpenGL، الاستجابة لأحداث اللمس. GLSurfaceView.Renderer
- تحدِّد هذه الواجهة الطرق المطلوبة لرسم الرسومات في
GLSurfaceView
. يجب توفير تنفيذ هذه الواجهة كفئة منفصلة وإرفاقها بمثيلGLSurfaceView
باستخدامGLSurfaceView.setRenderer()
.تتطلب واجهة
GLSurfaceView.Renderer
تنفيذ الطرق التالية:-
onSurfaceCreated()
: يطلب النظام هذه الطريقة مرة واحدة عند إنشاءGLSurfaceView
. استخدِم هذه الطريقة لتنفيذ الإجراءات التي يجب تنفيذها مرة واحدة فقط، مثل ضبط معلَمات بيئة OpenGL أو إعداد كائنات رسومات OpenGL. -
onDrawFrame()
: يستدعي النظام هذه الطريقة عند كل عملية إعادة سحب لـGLSurfaceView
. استخدِم هذه الطريقة كنقطة تنفيذ أساسية لرسم عناصر رسومية (وإعادة رسمها). -
onSurfaceChanged()
: يطلب النظام هذه الطريقة عندما يتغيّر الشكل الهندسيGLSurfaceView
، بما في ذلك التغيُّرات في حجمGLSurfaceView
أو اتجاه شاشة الجهاز. على سبيل المثال، يطلب النظام هذه الطريقة عندما يتغيّر الجهاز من الاتجاه العمودي إلى الاتجاه الأفقي. استخدِم هذه الطريقة للاستجابة للتغييرات في حاويةGLSurfaceView
.
-
حزم OpenGL ES
بعد إنشاء عرض حاوية لـ OpenGL ES باستخدام GLSurfaceView
وGLSurfaceView.Renderer
، يمكنك البدء في استدعاء واجهات برمجة تطبيقات OpenGL باستخدام الفئات التالية:
- فئة واجهة برمجة التطبيقات OpenGL ES 2.0
android.opengl.GLES20
- توفِّر هذه الحزمة واجهة OpenGL ES 2.0 وتتوفّر بدءًا من Android 2.2 (المستوى 8 من واجهة برمجة التطبيقات).
- حِزم واجهة برمجة التطبيقات OpenGL ES 3.0/3.1/3.2
android.opengl
- توفِّر هذه الحزمة الواجهة لفئات OpenGL ES 3.0/3.1. يتوفّر الإصدار 3.0 بدءًا من Android 4.3 (المستوى 18 من واجهة برمجة التطبيقات). يتوفر الإصدار 3.1 بدءًا من Android 5.0 (المستوى 21 من واجهة برمجة التطبيقات). يتوفّر الإصدار 3.2 بدءًا من Android 7.0 (المستوى 24 من واجهة برمجة التطبيقات).
إذا أردت البدء في إنشاء تطبيق باستخدام OpenGL ES على الفور، اتّبِع الفئة عرض الرسومات باستخدام OpenGL ES.
تعريف متطلبات OpenGL
إذا كان تطبيقك يستخدم ميزات OpenGL غير المتوفّرة على جميع الأجهزة، يجب تضمين هذه المتطلبات في ملف AndroidManifest.xml. في ما يلي بيانات بيان OpenGL الأكثر شيوعًا:
- متطلبات إصدار OpenGL ES: إذا كان تطبيقك يتطلب إصدارًا معيّنًا من OpenGL ES، يجب الإفصاح عن هذا الشرط عن طريق إضافة الإعدادات التالية إلى بيان التطبيق كما هو موضّح أدناه.
بالنسبة إلى OpenGL ES 2.0:
<!-- Tell the system this app requires OpenGL ES 2.0. --> <uses-feature android:glEsVersion="0x00020000" android:required="true" />
تؤدي إضافة هذا البيان إلى منع Google Play من تثبيت تطبيقك على الأجهزة التي لا تتوافق مع OpenGL ES 2.0. إذا كان تطبيقك مخصّصًا حصريًا للأجهزة التي تتوافق مع OpenGL ES 3.0، يمكنك أيضًا تحديد ذلك في البيان:
بالنسبة إلى OpenGL ES 3.0:
<!-- Tell the system this app requires OpenGL ES 3.0. --> <uses-feature android:glEsVersion="0x00030000" android:required="true" />
بالنسبة إلى OpenGL ES 3.1:
<!-- Tell the system this app requires OpenGL ES 3.1. --> <uses-feature android:glEsVersion="0x00030001" android:required="true" />
بالنسبة إلى OpenGL ES 3.2:
<!-- Tell the system this app requires OpenGL ES 3.2. --> <uses-feature android:glEsVersion="0x00030002" android:required="true" />
ملاحظة: تتوافق واجهة برمجة التطبيقات OpenGL ES 3.x مع الإصدارات القديمة من 2.0 API، ما يعني أنّه يمكنك أن تصبح أكثر مرونة عند تنفيذ OpenGL ES في تطبيقك. وبعد الإعلان عن تضمين OpenGL ES 2.0 API في ملف البيان، يمكنك استخدام إصدار واجهة برمجة التطبيقات هذا كإعداد تلقائي، والتأكّد من توفّر واجهة برمجة التطبيقات 3.x API في وقت التشغيل، ثم استخدام ميزات OpenGL ES 3.x إذا كان الجهاز يتيح استخدامها. لمزيد من المعلومات حول التحقق من إصدار OpenGL ES المتوافق مع الجهاز، يمكنك الاطّلاع على التحقق من إصدار OpenGL ES.
- متطلبات ضغط البنية - إذا كان التطبيق يستخدم تنسيقات
ضغط الهيئة، يجب الإفصاح عن التنسيقات التي يدعمها تطبيقك في ملف البيان
باستخدام
<supports-gl-texture>
. للمزيد من المعلومات حول تنسيقات ضغط البنية المتاحة، يمكنك الاطّلاع على إتاحة ضغط الهيئة.يؤدي تعريف متطلبات ضغط البنية في البيان إلى إخفاء تطبيقك عن المستخدمين الذين لديهم أجهزة لا تتوافق مع نوع واحد على الأقل من أنواع الضغط التي أفصحتَ عنها في البيان. للحصول على مزيد من المعلومات حول آلية عمل فلاتر Google Play لضغط المواد، يمكنك الاطّلاع على قسم Google Play وفلترة ضغط البنية ضمن مستندات
<supports-gl-texture>
.
تعيين إحداثيات للكائنات المرسومة
تتمثل إحدى المشكلات الأساسية في عرض الرسومات على أجهزة Android في أن شاشاتها قد تختلف من حيث الحجم والشكل. يفترض OpenGL نظام إحداثيات مربعًا موحدًا، ويرسم افتراضيًا تلك الإحداثيات بسعادة على شاشتك غير المربعة عادةً كما لو كانت مربعة تمامًا.
يوضح الرسم التوضيحي أعلاه نظام الإحداثيات الموحّد المُفترض لإطار OpenGL على اليسار، وكيف يتم ربط هذه الإحداثيات بشاشة جهاز عادية في اتجاه أفقي على اليمين. ولحل هذه المشكلة، يمكنك تطبيق أوضاع عرض OpenGL وعروض الكاميرا لتحويل الإحداثيات حتى تكون العناصر الرسومية لديك النسب الصحيحة على أي شاشة.
لتطبيق الإسقاط وطرق عرض الكاميرا، يمكنك إنشاء مصفوفة عرض ومصفوفة عرض الكاميرا وتطبيقهما على مسار عرض OpenGL. تعيد مصفوفة العرض حساب إحداثيات الرسومات بحيث يتم ربطها بشكل صحيح مع شاشات أجهزة Android. تنشئ مصفوفة عرض الكاميرا عملية تحويل تعرض الكائنات من موضع عين معين.
الإسقاط وعرض الكاميرا في OpenGL ES 2.0 والإصدارات الأحدث
في واجهات برمجة التطبيقات ES 2.0 و3.0، يمكنك تطبيق الإسقاط وعرض الكاميرا من خلال إضافة عضو مصفوفة أولاً إلى عناصر تظليل الرؤوس لكائنات الرسومات. مع إضافة عضو المصفوفة هذا، يمكنك بعد ذلك إنشاء وتطبيق مصفوفات عرض الكاميرا والإسقاط على الكائنات الخاصة بك.
- إضافة مصفوفة إلى أدوات تظليل الرأس - يمكنك إنشاء متغيّر لمصفوفة إسقاط طريقة العرض
وتضمينه كمُضاعِف لموضع أداة التظليل. في المثال التالي لرمز أداة تظليل الرأس، يتيح لك العنصر
uMVPMatrix
المضمَّن تطبيق مصفوفات العرض والكاميرا على إحداثيات العناصر التي تستخدم أداة التظليل هذه.Kotlin
private val vertexShaderCode = // This matrix member variable provides a hook to manipulate // the coordinates of objects that use this vertex shader. "uniform mat4 uMVPMatrix; \n" + "attribute vec4 vPosition; \n" + "void main(){ \n" + // The matrix must be included as part of gl_Position // Note that the uMVPMatrix factor *must be first* in order // for the matrix multiplication product to be correct. " gl_Position = uMVPMatrix * vPosition; \n" + "} \n"
Java
private final String vertexShaderCode = // This matrix member variable provides a hook to manipulate // the coordinates of objects that use this vertex shader. "uniform mat4 uMVPMatrix; \n" + "attribute vec4 vPosition; \n" + "void main(){ \n" + // The matrix must be included as part of gl_Position // Note that the uMVPMatrix factor *must be first* in order // for the matrix multiplication product to be correct. " gl_Position = uMVPMatrix * vPosition; \n" + "} \n";
ملاحظة: يحدِّد المثال أعلاه عضوًا في مصفوفة تحويل واحدة في أداة تظليل الرأس التي تطبِّق عليها مصفوفة عرض مدمجة ومصفوفة عرض الكاميرا. بناءً على متطلبات التطبيق، قد تحتاج إلى تحديد أعضاء مصفوفة عرض منفصلة وأعضاء مصفوفة عرض الكاميرا في مظلات الرأس حتى تتمكن من تغييرها بشكل مستقل.
- الوصول إلى مصفوفة أداة التظليل: بعد إنشاء خطاف في مظلات الرأس لتطبيق العرض والكاميرا، يمكنك الوصول إلى ذلك المتغير لتطبيق مصفوفات العرض
والكاميرا. يوضِّح الرمز التالي كيفية تعديل طريقة
onSurfaceCreated()
لتنفيذGLSurfaceView.Renderer
للوصول إلى متغيّر المصفوفة المحدّد في أداة تظليل الرأس أعلاه.Kotlin
override fun onSurfaceCreated(gl: GL10, config: EGLConfig) { ... muMVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix") ... }
Java
public void onSurfaceCreated(GL10 unused, EGLConfig config) { ... muMVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix"); ... }
- إنشاء مصفوفات الإسقاط وعرض الكاميرا - قم بإنشاء مصفوفات الإسقاط والعرض لتطبيق الكائنات الرسومية. يعرض الرمز في المثال التالي كيفية تعديل طريقتَي
onSurfaceCreated()
وonSurfaceChanged()
لتنفيذGLSurfaceView.Renderer
لإنشاء مصفوفة عرض الكاميرا ومصفوفة عرض استنادًا إلى نسبة العرض إلى الارتفاع في شاشة الجهاز.Kotlin
override fun onSurfaceCreated(gl: GL10, config: EGLConfig) { ... // Create a camera view matrix Matrix.setLookAtM(vMatrix, 0, 0f, 0f, -3f, 0f, 0f, 0f, 0f, 1.0f, 0.0f) } override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) { GLES20.glViewport(0, 0, width, height) val ratio: Float = width.toFloat() / height.toFloat() // create a projection matrix from device screen geometry Matrix.frustumM(projMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f) }
Java
public void onSurfaceCreated(GL10 unused, EGLConfig config) { ... // Create a camera view matrix Matrix.setLookAtM(vMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); } public void onSurfaceChanged(GL10 unused, int width, int height) { GLES20.glViewport(0, 0, width, height); float ratio = (float) width / height; // create a projection matrix from device screen geometry Matrix.frustumM(projMatrix, 0, -ratio, ratio, -1, 1, 3, 7); }
- تطبيق مصفوفات الإسقاط وعرض الكاميرا - لتطبيق تغييرات الإسقاط
وعرض الكاميرا، اضرب المصفوفتين معًا ثم ضعهما في شكل الرأس. يوضّح الرمز في المثال التالي كيفية تعديل طريقة
onDrawFrame()
في تنفيذGLSurfaceView.Renderer
لدمج مصفوفة العرض وعرض الكاميرا التي تم إنشاؤها في الرمز أعلاه ثم تطبيق الطريقة على كائنات الرسومات التي سيتم عرضها باستخدام OpenGL.Kotlin
override fun onDrawFrame(gl: GL10) { ... // Combine the projection and camera view matrices Matrix.multiplyMM(vPMatrix, 0, projMatrix, 0, vMatrix, 0) // Apply the combined projection and camera view transformations GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, vPMatrix, 0) // Draw objects ... }
Java
public void onDrawFrame(GL10 unused) { ... // Combine the projection and camera view matrices Matrix.multiplyMM(vPMatrix, 0, projMatrix, 0, vMatrix, 0); // Apply the combined projection and camera view transformations GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, vPMatrix, 0); // Draw objects ... }
للحصول على مثال كامل حول طريقة تطبيق العرض وعرض الكاميرا باستخدام OpenGL ES 2.0، يمكنك الاطّلاع على الفئة عرض الرسومات باستخدام OpenGL ES.
تشكيل الوجوه المتعرجة
في OpenGL، يكون وجه الشكل عبارة عن سطح يتم تحديده بثلاث نقاط أو أكثر في مساحة ثلاثية الأبعاد. تحتوي مجموعة النقاط الثلاث أو أكثر (تسمى الرؤوس في OpenGL) على وجهين أمامي وخلفي. كيف تعرف الوجه الأمامي والخلفي؟ هذا سؤال وجيه. تتعلق الإجابة بالاتجاه المتعرج، أو بالاتجاه الذي تحدد فيه نقاط الشكل.
في هذا المثال، يتم تحديد نقاط المثلث بترتيب يتم رسمها في اتجاه عكس عقارب الساعة. يحدد الترتيب الذي يتم به رسم هذه الإحداثيات الاتجاه المتعرج للشكل. وفقًا للإعدادات التلقائية، في OpenGL، يكون الوجه المرسوم عكس اتجاه عقارب الساعة هو الوجه الأمامي. يتم تعريف المثلث المعروض في الشكل 1 بحيث تنظر إلى الوجه الأمامي للشكل (كما يتم تفسيره بواسطة OpenGL) والجانب الآخر هو الوجه الخلفي.
لماذا من المهم معرفة وجه الشكل هو الوجه الأمامي؟ تتعلق الإجابة بميزة OpenGL الشائعة المعروفة باسم "اختيار الوجه". تعتبر ميزة اختيار الوجه خيارًا في بيئة OpenGL، وهي تتيح لمسار العرض تجاهُل (عدم احتساب أو رسم) الوجه الخلفي للشكل، ما يوفّر الوقت والذاكرة ودورات المعالجة:
Kotlin
gl.apply { // enable face culling feature glEnable(GL10.GL_CULL_FACE) // specify which faces to not draw glCullFace(GL10.GL_BACK) }
Java
// enable face culling feature gl.glEnable(GL10.GL_CULL_FACE); // specify which faces to not draw gl.glCullFace(GL10.GL_BACK);
إذا حاولت استخدام ميزة انتقاء الوجوه بدون معرفة جوانب الأشكال في الأمام والخلف، فستبدو رسومات OpenGL قليلاً، أو قد لا تظهر على الإطلاق. لذا، يجب دائمًا تحديد إحداثيات OpenGL بترتيب رسم عكس اتجاه عقارب الساعة.
ملاحظة: من الممكن ضبط بيئة OpenGL لتتعامل مع الوجه في اتجاه عقارب الساعة باعتباره الوجه الأمامي، إلا أن إجراء ذلك يتطلب المزيد من الرموز وقد يؤدي إلى إرباك مطوّري OpenGL ذوي الخبرة عندما تطلب منهم المساعدة. لذا لا تفعل ذلك.
إصدارات OpenGL وتوافقها مع الأجهزة
تتوافق مواصفات OpenGL ES 1.0 و1.1 API منذ نظام Android 1.0. تختلف برمجة الرسومات مع OpenGL ES 1.0/1.1 API إلى حد كبير عن استخدام الإصدار 2.0 والإصدارات الأحدث. يتوافق OpenGL ES 2.0 على جميع أجهزة Android التي تبدأ بالإصدار Android 2.2 (المستوى 8 من واجهة برمجة التطبيقات) وهو الإصدار الأقدم المقترَح للتطبيقات الجديدة التي يتم تطويرها باستخدام OpenGL ES. يتوافق OpenGL ES 3.0 مع الإصدار Android 4.3 (المستوى 18 لواجهة برمجة التطبيقات) والإصدارات الأحدث على الأجهزة التي توفّر إمكانية تنفيذ OpenGL ES 3.0 API. وللحصول على معلومات حول العدد النسبي للأجهزة التي تعمل بنظام التشغيل Android والتي تتوافق مع إصدار معيّن من OpenGL ES، يُرجى الاطّلاع على لوحة بيانات إصدار OpenGL ES.
يجب عليك التفكير بعناية في متطلبات الرسومات واختيار إصدار واجهة برمجة التطبيقات المناسب لتطبيقك بشكل أفضل. لمزيد من المعلومات، يُرجى الاطّلاع على اختيار إصدار OpenGL API.
توفّر واجهة OpenGL ES 3.0 API ميزات إضافية وأداءً أفضل مقارنةً بالإصدار 2.0 API، وهي متوافقة أيضًا مع الأنظمة القديمة. وهذا يعني أنّه يمكنك على الأرجح كتابة تطبيقك الذي يستهدف OpenGL ES 2.0 وتضمين ميزات رسومات OpenGL ES 3.0 بشكل مشروط في حال توفّرها. لمزيد من المعلومات حول التحقق من مدى توفّر 3.0 API، يمكنك الاطّلاع على التحقق من إصدار OpenGL ES.
إتاحة ضغط الهيئة
يمكن أن يؤدي ضغط الهيئة إلى زيادة أداء تطبيق OpenGL بشكل كبير عن طريق تقليل متطلبات الذاكرة والاستفادة بشكل أكثر فعالية من معدل نقل بيانات الذاكرة. يوفّر إطار عمل Android إمكانية استخدام تنسيق ضغط ETC1 كميزة عادية، بما في ذلك
فئة الأدوات ETC1Util
وأداة الضغط etc1tool
(المتوفّرة في حزمة تطوير البرامج (SDK) لنظام التشغيل Android على <sdk>/tools/
). للحصول على مثال على تطبيق Android يستخدم
ضغط الهيئة، اطّلِع على نموذج الرمز البرمجي CompressedTextureActivity
في حزمة تطوير البرامج (SDK) لنظام التشغيل Android
(<sdk>/samples/<version>/ApiDemos/src/com/example/android/apis/graphics/
).
يتوافق تنسيق ETC1 مع جميع أجهزة Android المتوافقة مع OpenGL ES 2.0 أو الإصدارات الأحدث.
ملاحظة: لا يدعم تنسيق ضغط البنية ETC1 الزخارف ذات الشفافية (قناة ألفا). إذا كان التطبيق يتطلب زخارف بشفافية، فيجب التحقق من تنسيقات ضغط البنية الأخرى المتاحة على الأجهزة المستهدفة. تتمثل طريقة عرض زخارف قناة ألفا باستخدام ETC1 في ربط كائنين من كائنات نسيج ETC1: الأول مع بيانات اللون، والثاني مع بيانات قناة ألفا، ثم دمج القيم من اثنين من الزخارف في أداة تظليل الأجزاء.
يمكن ضمان توفُّر تنسيقات ضغط البنية ETC2/EAC عند استخدام واجهة برمجة التطبيقات OpenGL ES 3.0. يوفر تنسيق المظهر هذا نسب ضغط ممتازة مع جودة مرئية عالية ويدعم التنسيق أيضًا الشفافية (قناة ألفا).
بالإضافة إلى تنسيقات ETC، تتيح أجهزة Android ضغط القوام استنادًا إلى شرائح وحدة معالجة الرسومات وعمليات تنفيذ OpenGL. يجب عليك التحقق من إمكانية استخدام ضغط المظهر على الأجهزة التي تستهدفها لتحديد أنواع الضغط التي يجب أن يدعمها تطبيقك. لتحديد تنسيقات الزخرفة المتوافقة مع جهاز معيّن، يجب إجراء طلب بحث عن الجهاز ومراجعة أسماء إضافات OpenGL، التي تحدد تنسيقات ضغط البنية (وميزات OpenGL الأخرى) المتوافقة مع الجهاز. في ما يلي بعض تنسيقات ضغط الهيئة التي تكون شائعة الاستخدام:
- ضغط الهيئة القابل للتكيّف والقابل للتوسع (ASTC) - تنسيق لضغط الهيئة تم تصميمه ليحل محل التنسيقات السابقة. أكثر مرونة من التنسيقات السابقة بسبب توافقها مع أحجام قوالب مختلفة.
GL_KHR_texture_compression_astc_ldr
GL_KHR_texture_compression_astc_hdr
(النطاق الديناميكي العالي)
- S3TC (DXTn/DXTC): هناك عدة أشكال لضغط البنية S3 (S3TC) (من DXT1 إلى DXT5) وهي متاحة بشكل أقل على نطاق واسع. يتوافق هذا التنسيق مع زخارف RGB مع قنوات ألفا 4 بت أو 8 بت. ويتم تمثيل هذه التنسيقات باسم إضافة OpenGL
التالي:
GL_EXT_texture_compression_s3tc
GL_EXT_texture_compression_dxt1
تعتبر تنسيقات ضغط المادة التالية تنسيقات قديمة ولا يُنصح باستخدامها في التطبيقات الجديدة:
- ATITC (ATC) - يتوفر ضغط بنية ATI (ATITC أو ATC) على مجموعة متنوعة من الأجهزة ويتيح الضغط بمعدل ثابت لزخارف نموذج أحمر أخضر أزرق مع قناة ألفا أو بدونها. قد يتم تمثيل هذا التنسيق بالعديد من أسماء إضافات OpenGL، على سبيل المثال:
GL_AMD_compressed_ATC_texture
GL_ATI_texture_compression_atitc
- PVRTC - يتوفر ضغط المظهر (PVRTC) على مجموعة متنوعة من الأجهزة ويتوافق مع زخارف 2 بت و4 بت لكل بكسل مع قناة ألفا أو بدونها.
ويتم تمثيل هذا التنسيق باسم إضافة OpenGL التالي:
GL_IMG_texture_compression_pvrtc
- 3DC - تنسيق ضغط البنية 3DC (3DC) هو تنسيق أقل استخدامًا ويتيح استخدام زخارف نموذج أحمر أخضر أزرق مع قناة ألفا. ويتم تمثيل هذا التنسيق باسم إضافة OpenGL التالي:
GL_AMD_compressed_3DC_texture
تحذير: إنّ تنسيقات ضغط البنية هذه غير متوافقة على جميع الأجهزة. وقد يختلف اعتماد هذه التنسيقات حسب الشركة المصنّعة والجهاز. للحصول على معلومات حول كيفية تحديد تنسيقات ضغط البنية على جهاز معين، يُرجى الاطّلاع على القسم التالي.
ملاحظة: بعد تحديد تنسيقات ضغط البنية التي سيتوافق معها تطبيقك، احرص على تعريفها في بيان التطبيق باستخدام <supports-gl-texture> . يؤدي استخدام هذا البيان إلى تفعيل الفلترة حسب الخدمات الخارجية مثل Google Play، بحيث يتم تثبيت تطبيقك فقط على الأجهزة التي تتوافق مع التنسيقات التي يتطلبها تطبيقك. للحصول على التفاصيل، يُرجى الاطّلاع على بيانات بيان OpenGL.
تحديد إضافات OpenGL
تختلف عمليات تنفيذ OpenGL حسب جهاز Android من حيث الإضافات المتوافقة مع OpenGL ES API. تتضمن هذه الإضافات ضغطات القوام، ولكنها عادةً ما تتضمن أيضًا إضافات أخرى إلى مجموعة ميزات OpenGL.
لتحديد تنسيقات ضغط البنية وإضافات OpenGL الأخرى المتوافقة مع جهاز معيّن:
- شغِّل الرمز التالي على الأجهزة المستهدفة لتحديد تنسيقات ضغط المادة المتوافقة:
Kotlin
var extensions = gl.glGetString(GL10.GL_EXTENSIONS)
Java
String extensions = gl.glGetString(GL10.GL_EXTENSIONS);
تحذير: تختلف نتائج هذه المكالمة حسب طراز الجهاز. يجب إجراء هذا الطلب على عدة أجهزة مستهدفة لتحديد أنواع الضغط المتوافقة بشكل شائع.
- راجِع نتائج هذه الطريقة لتحديد إضافات OpenGL المتوافقة مع الجهاز.
حزمة إضافات Android (AEP)
يضمن AEP أن تطبيقك يتوافق مع مجموعة موحّدة من إضافات OpenGL بما يتجاوز المجموعة الأساسية الموضّحة في مواصفات OpenGL 3.1. يؤدي تجميع هذه الإضافات معًا إلى تعزيز استخدام مجموعة متسقة من الوظائف على مستوى الأجهزة، مع السماح للمطوّرين بالاستفادة الكاملة من أحدث نسخة من أجهزة وحدة معالجة الرسومات على الأجهزة الجوّالة.
يحسّن AEP أيضًا إمكانية احتواء الصور والتخزينات الاحتياطية لأدوات تظليل الأجزاء والعدادات البسيطة في أدوات تظليل الأجزاء.
ولكي يتمكّن التطبيق من استخدام AEP، يجب أن يوضِّح بيان التطبيق أنّه مطلوب. بالإضافة إلى ذلك، يجب أن يكون إصدار النظام الأساسي متوافقًا.
يتم تضمين جميع الميزات الإضافية المحددة في AEP في مواصفات OpenGL ES 3.2 الأساسية. إذا كان تطبيقك يتطلب OpenGL ES 3.2، لن تحتاج إلى طلب AEP.
يُرجى تعريف متطلبات سياسة AEP في البيان على النحو التالي:
<uses-feature android:name="android.hardware.opengles.aep" android:required="true" />
للتحقّق من أنّ إصدار النظام الأساسي يتوافق مع AEP، استخدِم الإجراء hasSystemFeature(String)
وتمرير FEATURE_OPENGLES_EXTENSION_PACK
كوسيطة. يوضح مقتطف الرمز التالي مثالاً على كيفية القيام بذلك:
Kotlin
var deviceSupportsAEP: Boolean = packageManager.hasSystemFeature(PackageManager.FEATURE_OPENGLES_EXTENSION_PACK)
Java
boolean deviceSupportsAEP = getPackageManager().hasSystemFeature (PackageManager.FEATURE_OPENGLES_EXTENSION_PACK);
إذا كانت الطريقة صحيحة، يعني هذا أنّ AEP متاح.
لمزيد من المعلومات حول AEP، يُرجى الانتقال إلى صفحته على Khronos OpenGL ES Registry.
التحقُّق من إصدار OpenGL ES
تتوفّر العديد من إصدارات OpenGL ES على أجهزة Android. يمكنك تحديد الإصدار الأدنى من واجهة برمجة التطبيقات التي يتطلبها تطبيقك في البيان، ولكن قد ترغب أيضًا في الاستفادة من الميزات المتوفرة في واجهة برمجة تطبيقات أحدث في الوقت نفسه. على سبيل المثال، تتوافق واجهة برمجة التطبيقات OpenGL ES 3.0 مع الإصدار 2.0 من واجهة برمجة التطبيقات، لذا قد تحتاج إلى كتابة بيانات تطبيقك بحيث يستخدم ميزات OpenGL ES 3.0، ولكنه يعود إلى الإصدار 2.0 API إذا لم تكُن واجهة برمجة التطبيقات 3.0 متاحة.
قبل استخدام ميزات OpenGL ES من إصدار أعلى من الحد الأدنى المطلوب في بيان التطبيق، يجب أن يتحقّق التطبيق من إصدار واجهة برمجة التطبيقات المتاحة على الجهاز. يمكنك القيام بذلك بطريقتين:
- حاوِل إنشاء سياق OpenGL ES بمستوى أعلى (
EGLContext
) وتحقَّق من النتيجة. - أنشئ سياق OpenGL ES المتاح بالحد الأدنى وتحقَّق من قيمة الإصدار.
يوضّح الرمز في المثال التالي كيفية التحقّق من إصدار OpenGL ES المتاح من خلال إنشاء EGLContext
والتحقّق من النتيجة. يوضح هذا المثال كيفية التحقق من
إصدار OpenGL ES 3.0:
Kotlin
private const val EGL_CONTEXT_CLIENT_VERSION = 0x3098 private const val glVersion = 3.0 private class ContextFactory : GLSurfaceView.EGLContextFactory { override fun createContext(egl: EGL10, display: EGLDisplay, eglConfig: EGLConfig): EGLContext { Log.w(TAG, "creating OpenGL ES $glVersion context") return egl.eglCreateContext( display, eglConfig, EGL10.EGL_NO_CONTEXT, intArrayOf(EGL_CONTEXT_CLIENT_VERSION, glVersion.toInt(), EGL10.EGL_NONE) ) // returns null if 3.0 is not supported } }
Java
private static double glVersion = 3.0; private static class ContextFactory implements GLSurfaceView.EGLContextFactory { private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; public EGLContext createContext( EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { Log.w(TAG, "creating OpenGL ES " + glVersion + " context"); int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, (int) glVersion, EGL10.EGL_NONE }; // attempt to create a OpenGL ES 3.0 context EGLContext context = egl.eglCreateContext( display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); return context; // returns null if 3.0 is not supported; } }
إذا عرضت طريقة createContext()
أعلاه قيمة فارغة، يجب أن ينشئ الرمز سياق OpenGL
ES 2.0 بدلاً من ذلك وأن يعود إلى استخدام واجهة برمجة التطبيقات هذه فقط.
يوضح مثال الرمز البرمجي التالي كيفية التحقق من إصدار OpenGL ES عن طريق إنشاء حدّ أدنى من السياق المتوافق أولاً، ثم التحقّق من سلسلة الإصدار:
Kotlin
// Create a minimum supported OpenGL ES context, then check: gl.glGetString(GL10.GL_VERSION).also { Log.w(TAG, "Version: $it") } // The version format is displayed as: "OpenGL ES <major>.<minor>" // followed by optional content provided by the implementation.
Java
// Create a minimum supported OpenGL ES context, then check: String version = gl.glGetString(GL10.GL_VERSION); Log.w(TAG, "Version: " + version ); // The version format is displayed as: "OpenGL ES <major>.<minor>" // followed by optional content provided by the implementation.
باستخدام هذه الطريقة، إذا اكتشفت أنّ الجهاز يتوافق مع إصدار واجهة برمجة تطبيقات بمستوى أعلى، يجب محو الحد الأدنى من سياق OpenGL ES وإنشاء سياق جديد باستخدام إصدار واجهة برمجة التطبيقات الأعلى المتاح.
اختيار إصدار OpenGL API
يوفّر الإصداران 2.0 و3.0 من OpenGL ES واجهات رسومات عالية الأداء لإنشاء ألعاب ثلاثية الأبعاد وعروض مرئية وواجهات مستخدم. وتشابه إلى حد كبير تطوير الرسومات للإصدارين 2.0 و3.0 من OpenGL ES، حيث يمثل الإصدار 3.0 مجموعة فرعية من واجهة برمجة التطبيقات 2.0 مع ميزات إضافية. تختلف برمجة OpenGL ES 1.0/1.1 API عن OpenGL ES 2.0 و3.0 بشكل كبير، ولا يُنصح بها للتطبيقات الجديدة. يجب على المطورين التفكير بعناية في العوامل التالية قبل البدء في التطوير باستخدام واجهات برمجة التطبيقات هذه:
- التوافق مع الجهاز: على المطوّرين مراعاة أنواع الأجهزة وإصدارات Android وإصدارات OpenGL ES المتوفّرة لعملائهم. لمزيد من المعلومات حول توافق OpenGL على جميع الأجهزة، يُرجى مراجعة القسم إصدارات OpenGL وتوافقها مع الأجهزة.
- التوافق مع المظهر: توفّر واجهة برمجة التطبيقات OpenGL ES 3.0 أفضل توافق مع ضغط القوام لأنه يضمن توفّر تنسيق ضغط ETC2 الذي يتوافق مع الشفافية. تتضمن عمليات تنفيذ واجهة برمجة التطبيقات 2.0 إمكانية استخدام ETC1، إلا أن تنسيق المظهر هذا لا يتيح الشفافية. لتطبيق الشفافية في الزخارف المضغوطة، يجب إما استخدام زخارف ETC1 (التقسيم بين اللون وألفا) أو توفير الموارد بتنسيقات ضغط أخرى متوافقة مع الأجهزة التي تستهدفها. لمزيد من المعلومات، يُرجى الاطّلاع على إتاحة ضغط الهيئة.
على الرغم من أنّ التوافق والزخرفة قد يؤثران في قرارك، يجب اختيار إصدار OpenGL API استنادًا إلى ما تعتقد أنّه يوفّر أفضل تجربة للمستخدمين.