السلام عليكم :
Display Lists
هذا الوضوع مهم للغاية .
وأيضا ممتع .. وسهل .. ومفيد .. وو وو >>> يمدح مواضيعه .
الفائدة الاساسية من Display Lists هي تسريع التطبيق .
فمثلا لنفرض أنك تريد انشاء خمس وستين مكعب .. ( صناديق ) ,, لتضعها في لعبتك .
الحل البديهي هو .. شبيه بالتالي :
FOR(I=0;I<=65; I++)
{
glTranslatef(1,1,0);
CUBE(2);
}طبعا تضعها في Loop حتى ترسم وتبقى محدثة ,
لكن هذه ليست الطريقة السليمة .. فأثناء الLoop الجهاز يعاني الامرين من كثرة المضلعات التي تنشئها داخل Loop .. ولو كانت قليلة .. فما بالك بعدد ضخم من المكعبات .
قالوا الحل :
نرسم مكعب واحد خارج ال loop ثم نجعلها كقائمة واحدة .. ثم نستدعي هذه القائمة .. بعدد المرات التي نريد . ,,
طبعا هذه الطريقة تتضح فائدتها ,, عندما نرسم مضلعات كبيرة وكثيرة .. وتحتوي على اوامر ترهق المعالج .. مثل الدوال المثلثية .
الكتاب الاحمر .. ضرب مثال جدا واضح .. راجعه .
باختصار : ال Display List . . . هدفها عمل أشياء كثيرة خارج ال loop .. ثم اثناء ال Loop يكون كل شيء قد تم تجهيزه .
والجميل فيها انك تستطيع عمل اكثر من قائمة ( list ) .. ثم كل قائمة لها رقم محدد ..
وبالتالي تنادي هذه القائمة من خلال رقمها ..
واذا أردت مسح هذه القائمة تستطيع ذلك . . .
الامر جدا مفيد .
طيب .. خلونا نتناقش في مثال .. صغير .
اولا وضعت ثلاث دوال رئيسية .
الاولى اسمها
MakeList
وتصنع القوائم التي نريد .
الثانية اسمها :
Init
وسنضع فيها اعدادات opengl .. من اضاءة .. وغيرها .
الثالثة اسمها :
render
والتي سنرسم فيها :
void MakeList()
{
/*1*/ glNewList( 1, GL_COMPILE);
/*2*/ glutSolidTeapot(1);
/*3*/ glEndList();
}في السطر الاول : اعلنا عن بدء قائمة جديدة ..
البارمتر الاول رقم القائمة ..
اذا اردت لاحقا استدعائها فستستدعيها من خلال هذا الرقم .
البارمتر الثاني : يأخذ اما :
GL_COMPILE_AND_EXECUTE
او
GL_COMPILE
بصراحة ما ادري وش الفرق .. اذا أحد يعرف يقول .
في السطر الثاني ترسم او تنفذ الاشكال التي تريد .
في الساطر الثالث .. تنهي الList
void Init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
/*1*/ MakeList();
}ثم ننتقل الى دالة اعداد opengl والتي تنفذ مرة واحدة .. ونستدعي دالة MakeList التي عملناها قبل قليل ..
void render(void)
{
loop++;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*1*/ for(i=-4;i<=4;i+=2)
/*2*/ {
/*3*/ for(j=-4;j<=4;j+=4)
/*4*/ {
/*5*/ glPushMatrix();
/*6*/ glTranslatef(j,i,-20);
/*7*/ glRotatef(loop,0,1,0);
/*8*/ glCallList(1);
/*9*/ glPopMatrix();
/*10*/ }
/*11*/ }
glutSwapBuffers();
}هنا التطبيق العملي ..
سوينا حلقة تكرارية لرسم عدد كبير من المجسمات ,, واستفدنا من display list .. التي تسرع لنا العملية .
لاحظ في السطر الثامن طريقة استدعاء القائمة ..
قمنا باستدعاء القائمة رقم وحد التي انشأناها قبل قليل .
لكن لا تفرح كثيرا بسهولة ذلك الكود فهو ليس الطريقة المثالية المستخدمة .
المفترض أن نطلب من opengl ان تحجز عدد القوائم المطلوبة .. وبالتالي هي تخبرنا
بالقائمة الفارغة .. ونحن نستنتج ما يليها :
هكذا :
int DS =0; DS=glGenLists(3);
طلبنا من opengl حجز ثلاث ليستات .. ( قوائم) .. opengl ستعيد رقم قائمة فارغة ..
نحن نستنتج الباقي .
glNewList(DS,GL_COMPILE); . . . glEndList(); glNewList(DS+1,GL_COMPILE); . . . glEndList(); glNewList(DS+2,GL_COMPILE); . . . glEndList();
ثم نمسح القوائم عند انتهاء التطبيق ..
لاحظ
/*1*/ int first=0;
/*2*/ int second=0;
/*3*/ first = glGenLists(12);
/*4*/ second = glGenLists(1);
/*5*/ printf("one %d two %d ",(int)first,(int)second);في السطر الثالث حجزنا 12 قائمة جديدة .
ستكون قيمة المتغير first هي 1 .
اما المتغير second فهي 13 .. لاننا حجزنا قبله 12 قائمة .
أتمنى تكون الفكرة وصلت .
مثال :
GLuint first=0; first = glGenLists(12); glNewList(first,GL_COMPILE); drawCube(); glEndList(); glNewList(first+1,GL_COMPILE); drawCy(); glEndList(); glNewList(first+2,GL_COMPILE); drawSphere(); glEndList(); . . . . glCallList(first+1);
ثم اذا انتهيت من التطبيق تمسح القوائم من الذاكرة .
glDeleteLists(first,12);
تطلب بارمترين :
الاول : رقم اول قائمة عملتها .. وهي هنا first .
الثاني : رقم اخر قائمة عملتها ( القوائم التي حجزت ) .. وهي هنا 12
والقوائم التي بين 1 و 12 ستمسح ايضا .
وهذه بعض الملاحظات :
1- تستطيع بناء قائمة داخل قائمة ( قوائم متداخلة ) ,,
مثال :
glNewList(1,GL_COMPILE) Cube(3); glEndList() glNewList(2,GL_COMPILE) glCallList(1); glEndList();
ولكن لا تحاول ان تكثر من هذه الطريقة لان هناك حدود لك .. : ) ,, ابحث في هذا الرابط للمزيد .
3- يوجد بعض الاوامر التي لا يصلح وضعها داخل glNewList ..
راجعها في المراجع ..
4- من أهم تطبيقات DL تصيير النصوص . . . (Text Render)
تدريب :P
قم بعمل مثال يرسم الكثير من المضلعات ..
مرة باستخدام list
ومرة بدون استخدام list ..
وقم بحساب FPS .. لكل منهما ..,,, ولاحظ الفرق .
======
المرفق .. glut ..
بصراحة كنت أتمنى تغيير المثال .. الى مكعبات بدلا من teapot .. حتى تقل عدد المضلعات .. لكن تكاسلت !!

