الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

مثال : رسم صورة وتحريكها في OpenGL ( مع الشرح)

مغلق
بدأه Abdullah.Alshammeri في 22 يوليو 2007 · 0 رد · 6,055 مشاهدة · في OpenGL
مشاركة: واتساب X فيسبوك تيليجرام
#1

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

لاحظت أنه يوجد عدد من الاخوة يسأل عن رسم الصور في OpenGL وتحريكها .. كنت في السابق أنصح بالاكساء لانه أكثر احترافية " وممكن أيضا أكثر سرعة " .

لكن للتبسيط والتسهيل .. سنرسم صورة ونحركها باستخدام شيء اسمه Pixels و Bitmap في OpenGL .

.

قبل أن أبدأ ., هناك أمور أساسية تحتاجها ,, مثل انشاء نافذة , واستقبال الاوامر من الكيبورد , وماالى ذلك ,

قم بمراجعة المواضيع المثبة التي تغطي الاساسيات ,, مثلا خذ هذا الرابط :

/index.php?showtopic=38215

وللعلم .. لن أتعمق كثيرا في الشرح .. للتسهيل .. لكن اقرأ هذا الموضوع اللي يشرح المفاهيم

مثال على استخدام glDrawPixels مع الشرح.

فالجديد في موضوعي هذا .. هو فقط تحميل الصورة ... فقط ! . . بدلا من انشائها يدويا ,

----------

عشان نرسم صورة نحتاج لمعرفة عدة أمور :

* طول الصورة بالبكسل .

* عرض الصورة بالبكسل .

* بيانات الصورة ( أقصد الالوان اللي تكون الصورة وهذه نخزنها في مصفوفة . )

ونحتاج لامور اخرى مثل طريقة تخزين الالوان " نظام الالوان " ونحن سنستخدم ال GL_RGB .

عشان تحمل صورة تحتاج تكتب سطور كثيرة .. لكن لحسن الحظ يوجد مكتبة اسمها glaux تحمل لنا الصورة بسطر واحد .

اذا كنت لا تملك هذه المكتبة " يعني ماعندك الفيجوال " فأخبرني حتى أرفعها .. ( ابحث في قوقل قبل ذلك ) .

انظر لهذا الكود :

AUX_RGBImageRec *image;

int yPos= 100;
void display(void)
{
   glClear (GL_COLOR_BUFFER_BIT);
   glLoadIdentity();

   glRasterPos2i( 100,yPos );
   glDrawPixels(image->sizeX,image->sizeY,GL_RGB,GL_UNSIGNED_BYTE,image->data);

   glutSwapBuffers();
}

void reshape (int w, int h)
{
   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   gluOrtho2D(0,w,0,h);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
 }

void special(int key, int x, int y)
{
	switch(key)
	{
 	case GLUT_KEY_UP :
		yPos-=5;
		break;

 	case GLUT_KEY_DOWN :
		yPos+=5;
		break;

	}
	glutPostRedisplay();
}


int main(int argc, char** argv)
{

   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
   glutInitWindowSize (500, 500); 
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);
   glutSetWindowTitle("Load and Display Images .. using glDrawPixels ");

   /*******************************/
   image = new AUX_RGBImageRec();
   image = auxDIBImageLoad("image.bmp");
   /*******************************/


   glutDisplayFunc(display); 
   glutReshapeFunc(reshape);
   glutSpecialFunc(special);
   glutMainLoop();
   return 0;
}

تحميل الصورة :

لتحميل الصورة نحتاج لكتابة هذه الاسطر :

AUX_RGBImageRec *image;
 image = new AUX_RGBImageRec();
 image = auxDIBImageLoad("image.bmp");

الشرح :

AUX_RGBImageRec *image

هنا أعلنا عن تركيب (structure) وهو يتكون من ثلاث عناصر

sizeX عرض الصورة

sizeY طول الصورة

data البيانات او الالوان اللي تتكون منها الصورة

 image = auxDIBImageLoad("image.bmp");

حملنا الصورة باستخدام الدالة auxDIBImageLoad التي تعيد نفس التركيب السابق بعد ان قامت مشكورة بوضع جميع البيانات اللي نحتاجها .. مبروك حملناالصورة

ملاحظة : يجب ان تكون الصورة هي BMP

رسم الصورة :

لرسم الصورة .. يوجد عدة طرق .. استخدمت الدالة اللي تراها

 glDrawPixels(image->sizeX,image->sizeY,GL_RGB,GL_UNSIGNED_BYTE,image->data);

البارمتر الاول : عرض الصورة

البارمتر الثاني : طول الصورة

البارمتر الثالث نظام الالوان ... دائما ضعه RGB .. الا اذا كانت الصورة بخلاف ذلك .. وهذه امور متقدمة شوي .. وتحتاج تفصيل .

البارمتر الرابع .. نوع البيانات او المصفوفة التي تحمل الالوان

نحن نستخدم في الغالب unsigned char اي بايت واحد لكل قناة لونية ..

البارمتر الاخير بيانات الصورة .

مبروك لقد رسمت الصورة :

تحريك الصورة وتغيير موقعها :

نستخدم الدالة

glRasterPos2i( 100,yPos );

نحدد الاحداثي السيني والصادي للصورة ,

لاحظ ان نقطة الاصل بالنسبة للصورة هي في الجهة السفلية اليسرى . انتبه .

أيضا وحتى تتمرن أكثر .. جعلت الاحداثي الصادي متغير .. وغيرت قيمته عندما يضغط المستخدم احد المفاتيح كما هو ظاهر أمامك

 	case GLUT_KEY_UP :
		yPos-=5;
		break;

 	case GLUT_KEY_DOWN :
		yPos+=5;
		break;

نظام الاحداثيات .. تنبيه هام جدا :

يجب أن تعرف أخي ان نظام الاحداثيات في OpenGL يبدأ من الزاوية السفلية اليسرى ..

يعني يجب أن تبدأ الرسم من الزاوية السفلية اليسرى .

نحن كتبنا هذا الكود :

		  gluOrtho2D(0,w,0,h);

اذا نقطة الاصل هي بالزاوية اليسرى السفلية .

كما تلاحظ بالصورة .

post-42837-1185071565_thumb.jpg

أما لو كتبت

		  gluOrtho2D(-200,200,200,-200);
		  .
		  .
		  ثم
		  .
		  .
		   glRasterPos2i( 0,0 );

فان نظام الاحداثيات والنتيجة هي .

post-42837-1185071540_thumb.jpg

وباختصار .. لو أنك حددت الاحداثيات بالنقطة -10 و -10

			glRasterPos2i( -10,-10 );

وكان طول الصورة وعرضها 100 بكسل .

فان النتيجة هي انه سيتم رسم الصورة من النقطة ( -10 , -10 ) والى ان ستم عرض كل الصورة بغض النظر عن الاحداثيات ,, وهذا ما لاحظته ,

وسيتم عرضها على الشاشة بحسب نظام الاحداثيات اللي أنت حددته

ايضا .. سأستعير هذا التعليق من الاخ حسن في موضوعه اللي أشرت اليه في الاعلى :

اقتباس
فالظاهر ان drawPixels يرسم النقط على شكل pixels حقيقية, بغض النظر عن الـ projection matrix هذا اللذي حددنها في gluOrtho2D؟!

أيضا ملاحظة أخيرا ,, حسب ما لاحظت ,, انه يجب أن يكون موقع الصور اللي حددته في glRaster يقع في داخل ال View Port والا فانه لن يتم رسم الصورة حتى لو كان جزء منها داخل الفيوبورت

طبعا كل هالملاحظات تحتمل الخطأ والصواب .. لم اعتمد حتى الان على مرجع .. انما بالتجارب ,,

هناك أمور أخرى يجب أن نتحدث عنها .. ولكن لنارجعة ان شاء الله مع هكذا مواضيع .. لان الشرح بهذه الطريقة فيه سطحية .. ولكن أتوقع.. هذا مايريده اغلب المبتدئين . في هذا المجال .. خاصة الطلاب .

glDrawPixel.zip

تم تعديل هذه المشاركة بواسطة الشمري في 22 يوليو 2007 في 06:23

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

هذا الموضوع مغلق.

مواضيع مشابهة