تفعيل شاشة OpenGL يتطلب منا اجراء عملية الربط التي تحدثنا عنها في الدرس الأول.
وبالتالي قمنا بتفعيل مكتبتي GLEW و GLFW على بيئه محرر Visual Studio.سنقوم بمسح أي صفحة قمنا بفحصها سابقا أثناء تفعيل شاشة OpenGL للمعاينة.
والآن سنوضح بإيجاز بعض المهام الرئيسية التي نحتاجها خلال عملية تشغيل الشيفرة.
على سبيل المثال سنعمل على اضافة ملف جديد باسم main.cpp. يحتوي على دالة لغة سي الرئيسية main. ثم بعد ذلك سنقوم بتضمين صفحات أخرى إن لزم الأمر.
تدل ملفات 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 , بالتالي إضافة دوال التمثيل في الدالة 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 على تمكين وتعطيل تكبيرتصغير صندوق العرض عند بناء الشيفرة.
يمكننا كائن الشاشة GLFW window* من الإمساك بحدود الرسم طوال حياة البرنامج[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 من تنسيق وإدارة المؤشرات والوظائف في مكتبة OpenGL, ولذلك كان لا بد لنا من استدعاء بعض المهام الإضافية منها.[1] بالتالي يمكننا الأمر glow Experimental من إدارة وتحسين وظائف المكتبة الرسومية بتقديم مهام أكثر ديناميكية.[1] نقوم الآن بنسخ الكود التالي في بداية دالة main.cpp.[1]
glewExperimental = GL_TRUE;
في حال ظهور أخطاء تتعلق بــ MSVCRT , قم بمسح glow Experimental من الشيفرة.
يمكن العثور عليه في داخل مكتبة GLEW في الامتداد الذي قمنا بإعداده سابقًا.
C:GLglew-2.2.0-win32glew-2.2.0inReleaseWin32
وفي حال أعددت مكان آخر للمكتبة فلا بأس في ذلك , ولكن يتعين عليك نسخ ملف glew32.dll داخل ملفات المشروع في ملف Debug , لكي تعمل المكتبة.
قبل البدء في العرض يتطلب أن تعلم مكتبة OpenGL لمنافذ العرض التي ستبنى عليها شاشة العرض. على سبيل المثال , توفر لك دالة glViewport نقاط يتم اعتمادها من بطاقة العرض. بالتالي فإن العرض سيتم بناء على نقاط البداية والنهاية.
glViewport(0, 0, 800, 600);
عند نسخ الدالة السابقة في المشروع ستجد أن منفذ العرض مكون من احداثيات البدء في النقاط X Y. على سبيل المثال , فإن قيمتي 0 و 0 هما اقصى يسار النافذة التي سيتم فتحها.[1] بالإضافة إلى إحداثيات النهاية والمتمثلة بـ x=800 للعرض و y = 600 للارتفاع.
تمثل القيم السابقة حجز مساحة من مكان العرض عند تفعيل شاشة OpenGL.[1] لا تمثل viewport اماكن استدعاء الكائنات , بينما تحدد المساحة التي سيتم خلالها تمثيل الاستدعاءات.
نلاحظ عند تشغيل الشيفرة السابقة سوف يفتح البرنامج ثم ينتهي بالاغلاق فوراً, وذلك بسبب أننا لم نمكن أحداث الشاشة من العمل باستمرار.[1] ولتجاوز تلك المسألة يتوجب علينا وضع حلقة تكرارية تمكن الشاشة من عرض الإطارات باستمرار.[1]
while(!glfwWindowShouldClose(window)) { glfwPollEvents(); glfwSwapBuffers(window); }
تفحص الدالة glfwWindowShouldClose فيما لو أننا لم نقم باغلاق التطبيق , وبالتالي تبقى تعمل باستمرار دون الخروج التلقائي. بينما الدالة glfwPollEvents تحدد قيمة callback المتعلقة بتفاعل المستخدم مع الشاشة مثل استخدام الفأرة أو لوحة المفاتيح وتمرر بيانات الإدخال إلى المكتبة ليتم معالجتها.
تتولى دالة glfwSwapBuffers تمرير القيم الجديدة من الإحداثيات مع استمرار الرسم وملئ كل بيكسل بالألوان التي تأثرت بقيم الإدخال أو معادلة الرسم.
تتولى دالة glfwTerminate عمليات تنظيف الذاكرة بعد الخروج من البرنامج , فهي تضمن عدم تراكم كومة القمامة في ذاكرة الحاسوب.
glfwTerminate();
على سبيل المثال , تعمل glfwTerminate على الخروج من البرنامج بشكل صحيح. يجب أن تسير الأمور على ما يرام , لترى النتائج كما في الصورة التالية. لكن في حال واجهتك صعوبة في تشغيل الكود فيمكنك رؤية المصادر الأم في تفعيل شاشة OpenGL.