درس : view port " منفذ الرؤية " في OpenGL ..

الناقل : elmasry | الكاتب الأصلى : الشمري | المصدر : www.arabteam2000-forum.com

السلام عليكم :


من أهم تطبيقات الviewport .. إنشاء العاب تتميز بوجود دعم لاكثر من لاعب عن طيق انقسام الشاشة . , ايضا من التطبيقات .. ما هو موجود ف يالثري دي ماكس وماشابهه من برامج .
المقصود بالViewport في OpenGL .. هو عبارة عن منقطة رباعية الشكل .. تحدد أبعادها بنفسك .. عندها ستقوم OpenGL بعمل Clipping (قص)لاي شكل مرسوم خارج هذه المنطقة المحددة .

اعتدنا دائما على أن نكتب :

 glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   gluPerspective(45,(float)(w/h),.1,-

100);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();


حيث w و h هما عرض وطول النافذة .
بالتالي نحن دائما كنا نرسم على كامل النافذة .

سنقوم الان بتعديل بسيط .. سننشئ أكثر من viewport .. :

لنفرض أن لدينا نافذة تحمل الأبعاد التالية :
400 بكسل * 400 بكسل .
ونريد إنشاء اثنين من الviewport .. ينصفان النافذة الى قسمين .. كما في الصورة .

ارفق صورة : monthly_08_2007/post-42837-1186248125.jpg

لانشاء vp1 , نحتاج إلى أربع معلومات .. الزاوية اليسرى السفلية ونحددها من خلال متغيرين x,y / الزاوية اليمنى العلوية ونحددها عن طريق width

,height .
لاحظ أننا بدأنا من x=y=0 .
انتهينا عند x=200 ( أي عند منتصف النافذة ) ., و y=400 أي الى أعلى النافذة .. وبالكود :

// x ,y, width, height
glViewport(0 ,0, 200, 400);// viewport رقم واحد


أما الvp2 .. فقد بدأنا من x=200 أي عند منتصف النافذة .. الى x=200 أي نهاية النافذة .. وذلك لأن 200 + 200 = 400 وهو عرض النافذة .
أما y فلم يتغير كثيرا .


الكود بشكله الكامل :
glClear (GL_COLOR_BUFFER_BIT);
   
        /* مهم */
   //              x    ,y,     width,  height  
        glViewport(0    ,0,     200,    400);// viewport رقم واحد
        /* مهم */
        glGetIntegerv(GL_VIEWPORT,vp);
        cout<<" viewport 1 "<<endl;
        cout<<" x " <<vp[0]<< " y " << vp[1] << " width "<<vp[2] <<" height "<<vp[3] <<endl;


        glMatrixMode (GL_PROJECTION);
        glLoadIdentity ();
        //                      left , right, bottom, top
        gluOrtho2D( 0 , 200 , 0 , 400);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(0,0,0);

        glBegin(GL_LINES);
        glVertex2f(0,0);
        glVertex2f(200,400);
        glEnd();

        /* مهم */
   //              x    ,y,     width,  height  
        glViewport(200 ,0,     200,    400);// viewport رقم اثنين
        /* مهم */
        glGetIntegerv(GL_VIEWPORT,vp);
        cout<<" viewport 2 "<<endl;
        cout<<" x " <<vp[0]<< " y " << vp[1] << " width "<<vp[2] <<" height "<<vp[3] <<endl;

        glMatrixMode (GL_PROJECTION);
        glLoadIdentity ();
        //                      left , right, bottom, top
        gluOrtho2D( 0 , 200 , 0 , 400);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(0,0,0);

        glBegin(GL_LINES);
        glVertex2f(0,0);
        glVertex2f(200,400);
        glEnd();



 
 

   glutSwapBuffers();


لاحظ في viewport الاول :

ستجد أننا حددنا إحداثيات الخط .

ثم انظر الى viewprt الثاني :
ستجد أننا حددنا احداثيات الخط الثاني .. وكأننا في نافذة جديدة .. حيث حددنا نقطة البداية هي صفر , صفر .. ومع ذلك رسم من منتصف النافذة ..

وذلك لاننا في الviewport الجديد .. حددنا احداثياته من جديد ... وجعلنا المنطقة السفلية اليسرى هي نقطة الاصل عن طريق الدالة glortho .



أتمنى يكون الشرح واضح .

عموما بقي إعطاء بعض التلميحات :

* خطوات تنفيذ viewport :
1- أنشئ viewport .
2- عدل الاحداثيات عن طريق glortho أو gluperspective ,
3- انتقل الى modelview وقم برسم الشكل الذي تريده .

4- أنشىء viewport ثاني .
5- طبق الخطوة رقم 2 و 3 السابقة .

وهكذا ..


* لاحظ أن كل الviewport التي تنشئها .. لها خلفية واحدة .. بمعنى أنك لاتستطيع أن تخصص لكل viewport لون خلفية محدد عن طريق glClearColor
ونفس الامر مع glutSwapBuffers .
 
ملف مرفق(ملفات)
 
ملف مرفق  Viewport.zip (2.21كيلو )