تفعيل شاشة OpenGL : دورة OpenGL لغة c++ الدرس الثاني


تفعيل شاشة OpenGL يتطلب منا اجراء عملية الربط التي تحدثنا عنها في الدرس الأول وبالتالي قمنا بتفعيل مكتبتي GLEW و GLFW على بيئه محرر Visual Studio.سنقوم بمسح أي صفحه قمنا بفحصها سابقا أثناء تفعيل شاشة OpenGL للمعاينة.  والآن سنوضح بإيجاز بعض المهام الرئيسية التي نحتاجها خلال عملية تشغيل الشيفرة ,على سبيل المثال سنعمل على اضافة ملف جديد باسم main.cpp. سيحتوي على دالة لغة سي الرئيسية main. ثم بعد ذلك سنقوم بتضمين صفحات أخرى إن لزم الأمر.

في حال واجهتك صعوبة في الاستمرار فإننا ندعوك للعودة الى دورة c++ المستوى الأول والتعرف على الأساسيات اللازمة ومن ثم استئناف هذه الدورة.



التحقق من ملفات GLEW



تدل ملفات static على تكوين الربط الثابت للمكتبة , حيث أنه سيتم من خلاله تشغيل المكتبة عن طريق ملفات Binaries. [1] بالتالي لا حاجة لنا بالحديث عن آلية عملها لكن فقط يتطلب منا تحرير الملف الثنائي الفردي.[1]

بينما عمليه الربط الديناميكي للمكتبه تتم وفقا لملفات dll. والتي سيتم تضمينها لاحقا داخل ملفات المشروع ,  ما يشكل عزل كامل عن الشيفرة التي نقوم بوضعها.[1] وذلك يساعد في حجز مساحات قليلة للبرنامج وخاصة في المشاريع الكبيرة.[1]

وأما في حال قررت ربط مكتبة GLEW الثابتة.[1] فقد يتطلب منك ذلك تعيين متغير ثابت قبل ملفات include , لتصبح تمامًا مثل :

#define GLEW_STATIC
#include <GL/glew.h>

وعلى سبيل المثال ستبدو صفحة main.cpp الرئيسية بعد عملية الربط على النحو التالي:

#include <iostream>

#define GLEW_STATIC
#include <glew.h>

#include <glfw3.h>

void main()
{

}

في حال قمت ببناء المشروع يجب أن تنجح العملية وفي حال العثور على الأخطاء , يرجى التأكد من ربط المكتبات التي تحدثنا عنها في درس مكتبة اوبن جل.

التحقق من ربط المكتبات
صورة يظهر من خلالها التحقق من ربط المكتبات قبل الوصول إلى تفعيل شاشة OpenGL.

 


أدوات تفعيل شاشة OpenGL



وبالتالي نحن على أتم الإستعداد لبناء الشيفرة التعليمية الخاصة بنا , وسنناقش بالفعل عملية الربط بين هذه المكتبات.

 عند تفعيل شاشة OpenGL , يجب أن يتم تضمين(include) ملف GLEW قبل ملف GLFW لكي تعمل الشيفرة دون خلل.[1]

 

بعد ذلك سنعمل على تمثيل الصفحات الأولى في تفعيل شاشة OpenGL , بالتالي إضافة دوال التمثيل في الدالة main.cpp. ونضع بالاعتبار إجراء عملية build في كل مرة نعمل على تعديل الشيفرة لكي يتم السيطرة على مسار الأخطاء.

glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

 

يتم تفعيل دالة التهيئة glfwInit , وهي تقوم بتحضير صفحة الرسم باعتبارها أول وظيفة من وظائف تفعيل شاشة OpenGL.[1]  بينما يليها وظائف glfwWindowHint والتي تتعلق باعدادات صندوق العرض وكرت الألوان في البطاقة القياسية.[2]

على سبيل المثال , تدل القيمة GLFW_RESIZABLE على تمكين وتعطيل تكبير\تصغير صندوق العرض عند بناء الشيفرة.

 


كائن الشاشة



يمكننا كائن الشاشة GLFWwindow* من الإمساك بحدود الرسم طوال حياة البرنامج[1] , فعند تفعيل شاشة OpenGL يتم إخضاع البرنامج لقواعد لا يتم تجاوزها مثل أبعاد الطول والعرض الثابتة وعنوان الشاشة الرئيسية بالإضافة إلى بعض القيم التي سنتطرق لها في مراحل أخرى.

يحمل المتغير GLFWwindow* صفة المؤشر في لغة c++ , وفي حال لم تكن لتعرف شيء عنها يمكنك مراجعة درس المؤشرات.

الآن بعد أن شرحنا كائن الشاشة , يتطلب منا تعريف واحدًl منه باسم window ليتم الاعلان عنه خارج حدود دالة main.cpp لنا تمامًا مثل الشيفرة التالية:

GLFWwindow* window;

وبداخل الدالة main ينبغي علينا المباشرة في ارجاع القيم له عن طريق الشيفرة التالية :

GLFWwindow* window = glfwCreateWindow(800, 600, "First OpenGL Page", nullptr, nullptr);

بعد ذلك يمكن أن نضيف شرط التحقق في نجاح تكوين الشاشة من فشلها بإضافة الشيفرة التالية :

if (window == nullptr)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
    }

عبارة شرطية بسيطة تكشف أخطاء تفعيل شاشة OpenGL , بالتالي هي ليست إلزامية وإنما من المستحسن إضافتها في الكود. وفي حال كنت تستخدم دالة main من نوع int يفضل إضافة return -1 بداخلها ليتم كشف حالة التكوين من شاشة الكونسول.

glfwMakeContextCurrent(window);

الأمر glfwMakeContextCurrent وهو سياق وخيوط المعالجة التي تستلم نتائج وعمليات كائن الشاشة المنطقية. تعمل هذه الدالة على تفعيل معالجة البيانات التي تم تعبئتها مسبقًا فهي تعمل بمثابة نظام Context خلال تفعيل شاشة OpenGL.

 


إدارة المؤشرات glew



تمكننا مكتبة glew من تنسيق وإدارة المؤشرات والوظائف في مكتبة OpenGL, ولذلك كان لا بد لنا من استدعاء بعض المهام الإضافية منها.[1] بالتالي يمكننا الأمر glewExperimental من إدارة وتحسين وظائف المكتبة الرسومية بتقديم مهام أكثر ديناميكية.[1]

نقم الآن بنسخ الشيفرة التالية في ببداية دالة main.cpp.[1]

glewExperimental = GL_TRUE;

 

 في حال ظهور أخطاء تتعلق بــ MSVCRT , قم بمسح glewExperimental من الشيفرة.

 


ملف glew32.dll



يمكن العثور عليه في داخل مكتبة GLEW في الامتداد الذي قمنا باعداده سابقًا.

C:\GL\glew-2.2.0-win32\glew-2.2.0\bin\Release\Win32

وفي حال أعددت مكان آخر للمكتبة فلا بأس في ذلك , ولكن يتعين عليك نسخ ملف glew32.dll داخل ملفات المشروع في ملف Debug , لكي تعمل مكتبة GLEW.

نسخ ملف glew32
صورة يظهر فيها نسخ ملف glew32.dll داخل ملفات المشروع قبل تفعيل شاشة OpenGL.

 


ضبط منفذ العرض viewport



قبل البدء في العرض يتطلب أن تعلم مكتبة OpenGL لمنافذ العرض التي ستبنى عليها شاشة العرض. على سبيل المثال , توفر لك دالة glViewport نقاط يتم اعتمادها من بطاقة العرض. بالتالي فإن العرض سيتم بناء على نقاط البداية والنهاية.

glViewport(0, 0, 800, 600);

عند نسخ الدالة السابقة في المشروع ستجد أن منفذ العرض مكون من احداثيات البدء لنقاط X Y. على سبيل المثال , فإن قيمتي 0 و 0 هما اقصى يسار النافذة التي سيتم فتحها.[1] بالإضافة إلى إحداثيات النهاية والمتمثلة بـx=800 للعرض و y = 600 للإرتفاع. تمثل القيم السابقة حجز مساحة من مكان العرض عند تفعيل شاشة OpenGL.[1]

لا تمثل viewport اماكن استدعاء الكائنات , بينما تحدد المساحة التي سيتم خلالها تمثيل الاستدعاءات.

 


تفعيل شاشة OpenGL بشكل دائم



نلاحظ عند تشغيل الشيفرة السابقة سوف يفتح البرنامج ثم ينتهي بالاغلاق فوراً, وذلك بسبب أننا لم نمكن أحداث الشاشة من العمل باستمرار.[1] ولتجاوز تلك المسألة يتوجب علينا وضع حلقة تكرارية تمكن الشاشة من عرض الإطارات باستمرار.[1]

while(!glfwWindowShouldClose(window))
{
glfwPollEvents();
glfwSwapBuffers(window);
}

تفحص الدالة glfwWindowShouldClose فيما لو أننا لم نقم باغلاق التطبيق , وبالتالي تبقى تعمل باستمرار دون الخروج التلقائي. بينما الدالة glfwPollEvents تحدد قيمة callback المتعلقة بتفاعل المستخدم مع الشاشة مثل استخدام الفأرة أو لوحة المفاتيح وتمرر بيانات الإدخال إلى المتكبة ليتم معالجتها.

تتولى دالة glfwSwapBuffers تمرير القيم الجديدة من الإحداثيات مع استمرار الرسم وملئ كل بيكسل بالألوان التي تأثرت بقيم الإدخال أو معادلة الرسم.

 

يتم استخدام Double buffer خلال عرض المشهد , وذلك بسبب أن مخزن واحد سيعمل على وميض الصفحة أثناء المجريات الجديدة مثل حركة الكائنات أو تغيير الإضاءة [1], بالتالي فإن خصائص Double buffer تمكن تفعيل شاشة OpenGL بانسيابية مع اخفاء كواليس الرسم والتحويل.[1]

 


تنظيف الذاكرة



تتولى دالة glfwTerminate عمليات تنظيف الذاكرة بعد الخروج من البرنامج , فهي تضمن عدم تراكم كومة القمامة في ذاكرة الحاسوب.

glfwTerminate();

على سبيل المثال , تعمل glfwTerminate على الخروج من البرنامج بشكل صحيح.

يجب أن تسير الأمور على ما يرام , لترى النتائج كما في الصورة التالية. لكن في حال واجهتك صعوبة في تشغيل الشيفرة فيمكنك رؤية المصادر الأم في تفعيل شاشة OpenGL.

تشغيل صفحة اوبن جل
صورة يظهر فيها عملية تفعيل شاشة OpenGL.

 

 

 

 

 

المراجع
  1. [1]^ كتاب ـــــــ offline learnOpenGL created by Joey de Vries.
  2. [2]^ GLFW Window guide ______ window hint.
هل أعجبك المقال؟

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني.

 - 
Arabic
 - 
ar
Bengali
 - 
bn
German
 - 
de
English
 - 
en
French
 - 
fr
Hindi
 - 
hi
Indonesian
 - 
id
Portuguese
 - 
pt
Russian
 - 
ru
Spanish
 - 
es