بسم الله الرحمن الرحيم يوما ما كنت قد أكملت لعبتك أو برنامج الرسومي, و لكن ظهر الأسوء في ذلك, بطء شديد و تشوه في العرض. سأفسر هذا: الشيفرة البرمجية ممكن أن تكون صغيرة و لكن لها طريق طويل للوصول إلى الشاشة. سيقوم السيد أوبن جي أل بتحميل البيانات (بيانات النقاط و الألوان و إحداثيات الإكساء ووو ) إلى الذاكرة , وفي كل مرة يدخل تطبيقك أو لعبتك الحلقة يعيد السيد أوبن جي أل تحميل تلك البيانات إلى الذاكرة مرة أخرى.ففي حالة عمل مجسمات متحركة ( مثلا: علم يرفرف أو سطح البحر أو أو كوكب يدور أو كل مجسم يتطلب الحركة تلقائيا ) و بإحدى الأنواع التالية: النوع الأول:عمل مجسمات متحركة, يتم تحديث بياناتها عن طريق دوال يوفرها مكتبة السيد أوبن جي أل. النوع الثاني: عمل مجسمات متحركة, يتم تحديث بياناتها عن طريق دوال نوفرها نجن في تطبيقاتنا. النوع الثالث: عمل مجسمات ثابتة, مثل الجدران و الأرض و كل شيء ثابت لا يتحرك و بمعنى أخر ليس لهذا المجسم بيانات متغيرة. ففي النوع الأول و النوع الثالث يكمل الإشكال, بحيث أن السيد أوبن جي أل , سيقوم بإرهاق نفسه جراء التحميل المتكرر للبيانات من ذاكرة النظام نحو ذاكرة بطاقة الرسوميات. أما النوع الثاتي فلا بأس به و يمكن إعتباره حل مقبول و لكن إن إستعملت ما نحن بصدده فذلك سيزيد من كفاءة التطبيق و يجعله متصلا إتصالا تاما مع بطاقة الرسوميات "graphic card". و الحل هو إستعمال كائن الذاكرة "buffer object". إن كائن الذاكرة له ميزات عديدة منها: -جعل البيانات مثل مصفوفة النقاط و مصفوفة الألوان و و و إلخ قرب بطاقة الرسوميات و بعيدا عن إدارة النظام. - سيتم التقليل من عملية التحميل من ذاكرة النظام نحو ذاكرة بطاقة الرسوميات, بحيث أنه سيتم معالجة البيانات بشكل أسرع مما كان عليه سابقا. (قفزة سريعة نحو مصفوفة النقاط"vertex array") لقد أصبحت مصفوفة النقاط جوهر و لب النسخة 1.1, مع إضافة بعض التغييرات المحسنة في النسخة 1.4, فقبل النسخة 1.5 كانت التطبيقات قادرة على تخزين بيانات مصفوفة النقاط فقط في العميل "client" إلى أن ظهرت النسخة 1.5 و التي كان بمقدورها تخزين البيانات كمصفوفة التقاط "vertex array" في الخادم "server". ( يطلق إسم الخادم على الجهة الخاصة بذاكرة بطاقة الرسوميات "VRAM" و العميل على الجهة الخاصة بذاكرة النظام "RAM" دلالة على نوع الذاكرة المستعملة. إنشاء و تفعيل كائن الذاكرة: 1- إنشاء كائن الذاكرة , بحيث سيقوم الأوبن جي أل بتعريف معرفات تخص الذاكرة المرغوب فيها و ذلك عن طريق الدالة التالية:
void glGenBuffers( GLsizei n, GLuint * buffers);
GLuint bufObjects[4];glGenBuffers(4,bufObjects);
void glDeleteBuffers( GLsizei n,const GLuint * buffers );
void glBindBuffer( GLenum target, GLuint buffer );
ARRAY_BUFFER خاص بالنقاطCOPY_READ_BUFFER خاص بالتعامل مع الذاكرةCOPY_WRITE_BUFFER خاص التعامل مع الذاكرةELEMENT_ARRAY_BUFFER خاص بالمفهرساتPIXEL_PACK_BUFFER خاصة بالبكسلاتPIXEL_UNPACK_BUFFER خاصة بالبكسلاتTEXTURE_BUFFER تخص الإكساءTRANSFORM_FEEDBACK_BUFFER خاص بالتغدية الإسترجاعية (يخص مجالات النقر و تحديد المجسمات في عالم الأوبن جي أل)UNIFORM_BUFFER خاص بالذاكرة المنتظمة (جديد النسخة أوبن جي أل 3.0 و النسخ الأحدث لمكتبة الأوبن جي أل)
void glBufferData( GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage );
STREAM_DRAWSTREAM_READSTREAM_COPYSTATIC_DRAWSTATIC_READSTATIC_COPYDYNAMIC_DRAWDYNAMIC_READDYNAMIC_COPY
void glBufferSubData( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data );
void * glMapBuffer( GLenum target, GLenum access );
GL_READ_ONLY الوصول إلى البيانات للقراءة منها فقطGL_WRITE_ONLY الوصول إلى اللبيانات للكتابة عليها فقطGL_READ_WRITE الوصول إلى البيانات للكتابة عليها أو للقراءة منها
GLvoid *glMapBufferRange(GLenum target, GLintptr offset, GLsizeIptr length, GLbitfield access);
MAP_READ_BIT لقراءة البياناتMAP_WRITE_BIT للكتابة على البياناتMAP_INVALIDATE_RANGE_BIT جعل جزء من كائن الذاكرة ( مثل بيانات الألوان و بيانات النقاط ) في حالة غير معرفة أي تعطيل مؤقت و بمعنى أخر إبطال مفعول بيانات هذا الجزء من بيانات كائن الذاكرةMAP_FLUSH_EXPLICIT_BIT تحديث جزء من البيانات في كائن الذاكرة و إستبدالها ببيانات يتم تحديدها عن طريق الدالة glFlushMappedBufferRange()MAP_INVALIDATE_BUFFER_BIT إبطال مفعول بيانات كائن الذاكرة بالكامل ( هنا لا يعني أن الغاية هي مسح البيانات بل تعطيلها فقط )MAP_UNSYNCHRONIZED_BIT جعل كائن الذاكرة يعمل على نمط الغير متزامن , يعني إمكانبة التخلص من القيم السابقة و الحفاظ على القيم الأخرى من ضمنها القيم الحالية داخل كائن الذاكرة
GLvoid glFlushMappedBufferRange( GLenum target, GLintptr offset, GLsizeiptr length );
boolean glUnmapBuffer( GLenum target );
GLfloat* data;data = (GLfloat*) glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);if (data != (GLfloat*) NULL) {for( i = 0; i < 8; ++i )data[3*i+2] *= 2.0; /* التعديل على قيم المحور ص Z */glUnmapBuffer(GL_ARRAY_BUFFER);} else {/* لاتوجد إمكانية تحديث البيانات */}
GLvoid glCopyBufferSubData(GLenum readbuffer, GLenum writebuffer, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size);
GLboolean glIsBuffer( GLuint buffer );
void glGenVertexArrays(GLsizei n, GLuint *arrays);
void glDeleteVertexArrays(GLsizei n, GLuint *arrays);
GLvoid gBindVertexArray(GLuint array);
#define BUFFER_OFFSET(offset) ((GLvoid*) NULL + offset)#define NumberOf(array) (sizeof(array)/sizeof(array[0]))typedef struct {GLfloat x, y, z;} vec3;typedef struct {vec3 xlate; /* Translation */GLfloat angle;vec3 axis;} XForm;enum { Cube, Cone, NumVAOs };GLuint VAO[NumVAOs];GLenum PrimType[NumVAOs];GLsizei NumElements[NumVAOs];XForm Xform[NumVAOs] = {{ { -2.0, 0.0, 0.0 }, 0.0, { 0.0, 1.0, 0.0 } },{ { 0.0, 0.0, 2.0 }, 0.0, { 1.0, 0.0, 0.0 } }};GLfloat Angle = 0.0;voidinit()