كائن مخزن مؤقت للرؤوس

كائن مخزن بيانات الرؤوس ( VBO ) هو ميزة في OpenGL توفر طرقًا لتحميل بيانات الرؤوس ( الموقع ، متجه السطح ، اللون، إلخ) إلى جهاز الفيديو لعرضها في وضع غير فوري. توفر كائنات VBO تحسينات كبيرة في الأداء مقارنةً بالعرض الفوري ، وذلك لأن البيانات موجودة في ذاكرة جهاز الفيديو وليس في ذاكرة النظام، وبالتالي يمكن عرضها مباشرةً بواسطة جهاز الفيديو. وهي تُعادل مخازن بيانات الرؤوس في Direct3D .

تم توحيد مواصفات كائن مخزن الرؤوس (VBO) من قِبل مجلس مراجعة بنية OpenGL ( مؤرشف بتاريخ 24 نوفمبر 2011 في Wayback Machine) اعتبارًا من إصدار OpenGL 1.5 (في عام 2003). كانت وظائف مماثلة متاحة قبل توحيد VBO عبر امتداد "نطاق مصفوفة الرؤوس" الذي أنشأته Nvidia [ 1 ] أو امتداد "كائن مصفوفة الرؤوس" الذي أنشأته ATI [ 2 ] .

وظائف VBO الأساسية

تشكل الوظائف التالية جوهر الوصول إلى VBO ومعالجته:

في OpenGL 1.4 :
glGenBuffersARB (sizei n, uint *buffers)
يُنشئ كائن VBO جديدًا ويعيد رقم تعريفه كعدد صحيح غير مُوقّع. الرقم 0 محجوز.
glBindBufferARB (enum target, uint buffer)
استخدم مخزنًا مؤقتًا تم إنشاؤه مسبقًا كـ VBO النشط.
glBufferDataARB (enum target, sizeiptrARB size, const void *data, enum usage)
قم بتحميل البيانات إلى VBO النشط.
glDeleteBuffersARB (sizei n, const uint *buffers)
يحذف العدد المحدد من VBOs من المصفوفة أو معرف VBO المقدم.
في OpenGL 2.1 ، [ 3 ] و OpenGL 3.x [ 4 ] وOpenGL 4.x : [ 5 ]
glGenBuffers (sizei n, uint *buffers)
يُنشئ كائن VBO جديدًا ويعيد رقم تعريفه كعدد صحيح غير مُوقّع. الرقم 0 محجوز.
glBindBuffer (enum target, uint buffer)
استخدم مخزنًا مؤقتًا تم إنشاؤه مسبقًا كـ VBO النشط.
glBufferData (enum target, sizeiptrARB size, const void *data, enum usage)
قم بتحميل البيانات إلى VBO النشط.
glDeleteBuffers (sizei n, const uint *buffers)
يحذف العدد المحدد من VBOs من المصفوفة أو معرف VBO المقدم.

مثال على الاستخدام

بلغة C، باستخدام OpenGL 2.1

// تهيئة VBO - يتم ذلك مرة واحدة فقط، في بداية البرنامج // إنشاء متغير لتخزين مُعرّف VBO GLuint triangleVBO ;// رؤوس مثلث (لف عكس اتجاه عقارب الساعة) float data [] = { 1.0 , 0.0 , 1.0 , 0.0 , 0.0 , -1.0 , -1.0 , 0.0 , 1.0 }; // جرب float data[] = {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0}; إذا لم ينجح ما سبق.// إنشاء VBO جديد واستخدام المتغير id لتخزين معرف VBO glGenBuffers ( 1 , & triangleVBO );// اجعل VBO الجديد نشطًا glBindBuffer ( GL_ARRAY_BUFFER , triangleVBO );// تحميل بيانات الرؤوس إلى جهاز الفيديو glBufferData ( GL_ARRAY_BUFFER , sizeof ( data ), data , GL_STATIC_DRAW );// قم بتفعيل VBO الجديد. كرر ذلك هنا في حال تغير منذ التهيئة glBindBuffer ( GL_ARRAY_BUFFER , triangleVBO );// رسم المثلث من VBO - يتم ذلك مع كل تغيير في نافذة الوقت أو نقطة العرض أو البيانات // تحديد إحداثياته ​​الثلاث لكل رأس بخطوة صفرية في هذه المصفوفة؛ ضروري هنا glVertexPointer ( 3 , GL_FLOAT , 0 , NULL );// إنشاء مصفوفة تحتوي على رؤوس (وليس متجهات عمودية، أو ألوان، أو إحداثيات نسيج، إلخ) glEnableClientState ( GL_VERTEX_ARRAY );// ارسم المثلث فعليًا، مع تحديد عدد الرؤوس المُقدمة glDrawArrays ( GL_TRIANGLES , 0 , sizeof ( data ) / sizeof ( float ) / 3 );// فرض رسم الشاشة الآن glFlush ();

في لغة C، باستخدام OpenGL 3.x و OpenGL 4.x

مُظلل الرؤوس:

/*----------------- "exampleVertexShader.vert" -----------------*/#version 150 // حدد إصدار GLSL الذي نستخدمه.// تم ربط in_Position بفهرس السمة 0("shaderAttribute") في vec3 in_Position ;void main () { gl_Position = vec4 ( in_Position . x , in_Position . y , in_Position . z , 1.0 ); } /*--------------------------------------------------------------*/

مُظلل الأجزاء:

/*---------------- "exampleFragmentShader.frag" ----------------*/#version 150 // حدد إصدار GLSL الذي نستخدمه.precision highp float ; // تتطلب برامج تشغيل بطاقة الفيديو هذا السطر لكي تعمل بشكل صحيحout vec4 fragColor ;void main () { fragColor = vec4 ( 1.0 , 1.0 , 1.0 , 1.0 ); // تعيين لون كل جزء إلى الأبيض } /*--------------------------------------------------------------*/

برنامج OpenGL الرئيسي:

/*--------------------- برنامج OpenGL الرئيسي ---------------------*//* إنشاء متغير لتخزين مُعرّف VBO */ GLuint triangleVBO ; /* هذا مُعرّف لبرنامج التظليل */ GLuint shaderProgram ;/* ستتلقى هذه المؤشرات محتويات ملفات كود مصدر التظليل الخاصة بنا */ GLchar * vertexSource , * fragmentSource ;/* هذه هي المقابض المستخدمة للإشارة إلى التظليلات */ GLuint vertexShader , fragmentShader ;const unsigned int shaderAttribute = 0 ;/* رؤوس المثلث (لف عكس اتجاه عقارب الساعة) */ float data [ 3 ][ 3 ] = { { 0.0 , 1.0 , 0.0 }, { -1.0 , -1.0 , 0.0 }, { 1.0 , -1.0 , 0.0 } };/*---------------------- تهيئة VBO - (ملاحظة: يتم ذلك مرة واحدة فقط، في بداية البرنامج) ---------------------*/ /* إنشاء VBO جديد واستخدام المتغير "triangleVBO" لتخزين معرف VBO */ glGenBuffers ( 1 , & triangleVBO );/* اجعل VBO الجديد نشطًا */ glBindBuffer ( GL_ARRAY_BUFFER , triangleVBO );/* تحميل بيانات الرؤوس إلى جهاز الفيديو */ glBufferData ( GL_ARRAY_BUFFER , sizeof ( data ), data , GL_STATIC_DRAW );/* حدد أن بيانات الإحداثيات الخاصة بنا ستدخل في فهرس السمة 0 (shaderAttribute)، وتحتوي على ثلاثة أرقام عشرية لكل رأس */ glVertexAttribPointer ( shaderAttribute , 3 , GL_FLOAT , GL_FALSE , 0 , 0 );/* تفعيل استخدام السمة ذات الفهرس 0 (shaderAttribute) */ glEnableVertexAttribArray ( shaderAttribute );/* اجعل مخزن بيانات الرأس الجديد نشطًا. */ glBindBuffer ( GL_ARRAY_BUFFER , triangleVBO ); /*-------------------------------------------------------------------------------------------------------*//*--------------------- تحميل تظليلات الرؤوس والقطع من الملفات وتجميعها --------------------*/ /* قراءة التظليلات إلى المخازن المؤقتة المناسبة */ vertexSource = filetobuf ( "exampleVertexShader.vert" ); fragmentSource = filetobuf ( "exampleFragmentShader.frag" );/* تعيين "اسم" لمقابضنا لكائنات التظليل الجديدة */ vertexShader = glCreateShader ( GL_VERTEX_SHADER ); fragmentShader = glCreateShader ( GL_FRAGMENT_SHADER );/* ربط مخازن التعليمات البرمجية المصدرية بكل مؤشر */ glShaderSource ( vertexShader , 1 , ( const GLchar ** ) & vertexSource , 0 ); glShaderSource ( fragmentShader , 1 , ( const GLchar ** ) & fragmentSource , 0 );/* تحرير الذاكرة المخصصة مؤقتًا */ free ( vertexSource ); free ( fragmentSource );/* تجميع كائنات التظليل */ glCompileShader ( vertexShader ); glCompileShader ( fragmentShader ); /*-------------------------------------------------------------------------------------------------------*//*-------------------- إنشاء برنامج تظليل، وإلحاق التظليلات به، ثم ربطه ---------------------*/ /* تعيين "اسم" لمقبض البرنامج */ shaderProgram = glCreateProgram ();/* ربط التظليلات الخاصة بنا ببرنامجنا */ glAttachShader ( shaderProgram , vertexShader ); glAttachShader ( shaderProgram , fragmentShader );/* ربط فهرس السمة 0 (shaderAttribute) بـ in_Position */ /* سيمثل "in_Position" محتويات مصفوفة "data" في مُظلل الرؤوس */ glBindAttribLocation ( shaderProgram , shaderAttribute , "in_Position" );/* ربط برنامج التظليل */ glLinkProgram ( shaderProgram ); /*-------------------------------------------------------------------------------------------------------*//* تعيين برنامج التظليل على أنه قيد الاستخدام النشط */ glUseProgram ( shaderProgram );/* تعيين لون الخلفية إلى الأسود */ glClearColor ( 0.0 , 0.0 , 0.0 , 1.0 );/* مسح الخلفية باللون الأسود */ glClear ( GL_COLOR_BUFFER_BIT );/* ارسم المثلث فعليًا، مع تحديد عدد الرؤوس المُقدمة بواسطة استدعاء glDrawArrays،  مع الإشارة إلى أن بياناتنا عبارة عن مثلث وأننا نريد رسم 0-3 رؤوس */ glDrawArrays ( GL_TRIANGLES , 0 , ( sizeof ( data ) / 3 ) / sizeof ( GLfloat )); /*---------------------------------------------------------------*/

مراجع

  1. "الورقة البيضاء لـ GL_NV_vertex_array_range" . مؤرشفة من الأصل بتاريخ 17-08-2004 . تم الاطلاع عليها بتاريخ 24-06-2024 .{{cite web}}: CS1 maint: bot: حالة عنوان URL الأصلي غير معروفة ( رابط )
  2. "ATI_vertex_array_object" . مؤرشف من الأصل بتاريخ 2012-07-04 . تم الاطلاع عليه بتاريخ 2011-08-12 .
  3. "مرجع وظائف OpenGL 2.1" . مؤرشف من الأصل بتاريخ 17 فبراير 2008. تم الاطلاع عليه بتاريخ 11 فبراير 2008 .
  4. "مرجع وظائف OpenGL 3.3" .
  5. "مرجع وظائف OpenGL 4.2" . مؤرشف من الأصل بتاريخ 15 يوليو 2013. تم الاطلاع عليه بتاريخ 6 أبريل 2012 .