يونيفورم OpenGL هي طريقة أخرى لتمرير البيانات من المشروع إلى وحدة CPU ومن ثم إلى وحدة معالجة الرسومات GPU.[1]
مع ذلك قد يختلف يونيفورم OpenGL قليلاً عند المقارنة مع سمات Vertex.
حيث تعبر يونيفورم OpenGL عن متغيرات عامة ما يعني أنها متغيرات فريدة من نوعها لكل ظل من ظلال GLSL يجري استخدامه.[1]
تعمل متغيرات يونيفورم بشكل عام لحظة عمل المشروع ويتم الوصول إليها من قبل أي ظلال يتم تضمينها في عملية الرسم.[1]
وبالتالي يتم الاحتفاظ بكافة القيم طوال حياة البرنامج.
بينما يتم الإشارة إلى يونيفورم OpenGL بطريقة سهلة وبسيطة فهي تحمل العبارة uniform بالانجليزية مع نوع المتجه المراد استخدامه ومن ثم يتم تمريرها إلى المراحل القادمة من GLSL.[1]
البدء بتفعيل يونيفورم OpenGL
لقد قمنا بالإعلان عن متغير يونيفورم من نوع vec4 و قمنا بتسميته our Color في ملف Fragment Shader.[1]
وكذلك الأمر بالنسبة للمخرجات حيث تولت بذلك عملية إرسال القيم إلى وحدة المعالجة ملحوقة بالقيمة التي بداخلها.[1]
#version 330 core out vec4 color; uniform vec4 our Color; // We set this variable in the OpenGL code. void main() { color = our Color; }
وبما أن قيم يونيفورم عبارة عن متغيرات عامة بالتالي يمكن تحديدها بأي من الظلال.
بالتالي ليس هناك حاجة للعودة إلى قيم Vertex Shader وإعطاء ألوان أساسية منها.[1]
نلاحظ في الكود السابق بأن متغير يونيفورم OpenGL هو فارغ تمامًا في شيفرة المشروع ولم يتم إرفاق أية بيانات له.
ولذلك نحاول إجراء بعض التعديلات على البرنامج.[1]
تعيين الألوان من كود OpenGL
نحتاج الآن البحث عن أماكن index المفهرسة في سمات العناصر الخاصة بالظلال ، وبمجرد العثور على تلك الأماكن يمكن إجراء بعض التحديثات عليها بدلا من تمرير ألوان أحادية القيم.[1]
وبالرجوع إلى كود OpenGL نجري بعض الإضافات التالية لتبدو كما يلي:
GLfloat timeValue = glfwGetTime(); GLfloat greenValue = (sin(timeValue) / 2) + 0.5; GLint vertexColorLocation = glGetUniformLocation(shaderProgram, \"our Color\") ; glUseProgram(shaderProgram); glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
شيفرة اللون تخضع لمعادلات رياضية معقدة لا يمكن الخوض بها على الإطلاق.[1]
الدالة الأولى glfw GetTime(); سترجع قيمة باللون الأخضر وذلك من خلال جيب قيمة الوقت مقسومة على اثنين زائد قيمة سطحية FLoat.[1]
بعد ذلك نستعلم عن مكان الـ uniform باستخدام الدالة glGetUniformLocation.
والتي تمكننا من الإتصال بلغة GLSL وأنظمة الظلال لتخبرها باستلام قيمة من البرنامج. وفي حال تم إرجاع قيمة -1 فإن ذلك يعني تعذر الحصول على الموقع.
بينما تدل القيمة glUseProgram على استخدام الظلال وقد قمنا بشرحها في درس ظلال GLSL.[1]
وأخيرًا تعمل الدالة glUniform4f على إرسال اللون من يونيفورم OpenGL إلى GLSL وذلك من خلال ملئ قيمة اللون الأخضر من بين المتغيرات.[1]
لا ننسى أن نظام الألوان يعتمد على صيغة 8 بت و 24 بت كقيم RGBA.[2]
تفعيل الكود في البرنامج
الآن كل ما يمكن هو تفعيل القيم التي ذكرناها في السابق ويتطلب ذلك وضعها في حلقة While الخاصة بمكتبة OpenGL ، أو يمكن نقلها إلى دالة باسم render ومناداتها فيما بعد لكي تتضح الأمور شيئًا فشيئًا.
نضع بعين الاعتبار أن أي قيمة مرتبطة بالوقت فهي قيمة متشعبة ومتغيره عند وضعها في أي حلقة تكرارية.
حيث أننا قمنا بإحداث قيمة دائمة التغيير ستعمل على تغيير اللون في كل ثانية تمضي على وقت تشغيل البرنامج. نحاول الآن وضع كافة قيم يونيفورم OpenGL في حلقة التكرار تمامًا مثل الشيفرة التالية:
while(!glfwWindowShouldClose(window)) { // Check and call events glfwPollEvents(); // Render // Clear the colorbuffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // Be sure to activate the shader glUseProgram(shaderProgram); // Update the uniform color GLfloat timeValue = glfwGetTime(); GLfloat greenValue = (sin(timeValue) / 2) + 0.5; GLint vertexColorLocation = glGetUniformLocation(shaderProgram, \" our Color\"); glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f); // Now draw the triangle gl Bind VertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 3); gl Bind Vertex Array(0); }
عند تفعيل الشيفرة الخاصة بالبرنامج يمكن استنتاج بأن المربع ذات اللون الأخضر هو وامض ، بحيث تتغير درجاته صعودا ونزولاً وفقا لمعادلات المدى التي استخدمناها لتفعيل اللون الأخضر.
على سبيل المثال نقوم الآن بتغيير الكود ليعرض الأحمر بدلا من ذلك ، حيث أن التبديل بين القيمتين هو مفتاح الحل.
تماما مثل الشيفرة التالية:
glUniform4f(vertexColorLocation, redValue , 0.0f, 0.0f, 1.0f);
كل ما فعلناه هو تغيير اسم المتغير ليظهر بالإسم red Value وبعدها قمنا بتبديل القيم بينهما.