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

أساسيات الرسم في OpenGL

مغلق
بدأه Abdullah.Alshammeri في 19 ديسمبر 2005 · 10 رد · 14,615 مشاهدة · في OpenGL
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

ما رأيك باسم السلسلة :) ,,,

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

اول شيء .. اين نضع دوال الرسم ..

الجواب .. اذا كانت المسألة اعداد الرسم .. مثلا نعد دالة تقوم بتغيير حجم الخط .

هنا نضعها في دالة اعداد الويندوز .. لاننا فقط نستدعيها مرة واحدة .. اما اذا اردنا الرسم .. فنضعها في الدالة التي أنشأناها في الدرس السابق وسميناها Render والتي تحدث باستمرار بسبب وجودها تحث تأثير while ...

void Render(GLvoid)          
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
	glLoadIdentity();  
	glTranslatef(0,0,-1.0);

	glBegin(GL_POINTS);
  
	glVertex3f(0,0,0);
   
	glEnd();

            
}

اولا عندنا الدالتين glBegin(GL_POINTS) و glEnd() .

جميع النقاط التي نرسمها ستكون بداخل هذه الداليتن .. وهناك دوال محددة فقط توضع بداخل هاتين الدالتين .. ولايجوز وضع أي دالة اخرى غير هذه الدوال :

glVertex*()
glColor*()
glIndex*()
glNormal*()
glTexCoord*()
glEdgeFlag*()
glMaterial*()
glArrayElement()
glEvalCoord*()
 glEvalPoint*()
glCallList()
glCallLists()

غير الدوال السابقة لايصلح ابدا وضعها داخل الدالتين glBegin و glEnd ..

الان glBegin تطلب بارمتر واحد وهو نوع الرسم الذي تريد ان ترسمه وهذه الانواع :

GL_POINTS

لرسم نقطة ..

GL_LINES

لرسم خط .. وهنا يلزمك نقطتين ..حيث كل نقطتين تمثل خط .. يعني لو وضعت ثلاث نقاط فلن يتم رسم الا خط واحد ..

GL_LINE_STRIP

رسم خطوط متصلة

GL_LINE_LOOP

نفس الامر السابق لكن يتم وصل اخر نقطة باول نقطة ليتم رسم شكل مغلق .

GL_TRIANGLES

لرسم مثلث .. وتحتاج الى ثلاث نقاط حيث كل ثلاث نقاط ترسم مثلث ..

GL_TRIANGLE_STRIP

لرسم مثلثات متصلة .

GL_TRIANGLE_FAN

لرسم مثلثات تتصل بنقطة المنتصف (غالبا تستخدم لرسم الاشكال الدائرية )

GL_QUADS

لرسم اشكال مربعة او مستطيلة ( يعني اشكال ذات اربع رؤوس )

وتحتاج الى اربع نقاط لرسم شكل رباعي واحد .. وثمان نقاط لرسم شكلين رباعيين ..

GL_QUAD_STRIP

لرسم اشكال رباعية متصلة .

GL_POLYGON

لرسم مضلع ..

وهذه صورة تبين تلك الانواع

0b91fb8700.gif

اعرف انك صدمت بكثرة تلك الطرق .. لكن الامر سهل ..

مثلا تستطيع رسم مربع باستخدام GL_TRIANGLES حيث ترسم مثلين متجاورين لكن ذلك يعتبر حماقة .. استخدم GL_QUADS وارتاح !!! الا اذا كان لديك سبب معقول .

الان سنبدأ بالتطبيقات العملية ..

في المثال السابق اخترنا رسم نقطة .. ولرسم النقاط نحتاج الى الدالة glVertex3f التي ترسم نقطة واحدة .. علما ان الدالة السابقى على عدة انواع كما شرحنا ذلك

هنا

***

فمثلا

glVertex2d ترسم نقطة لكن تحتاج الى بارمترين فقط .. السيني والصادي .. لاحظ الرقم 2 .

اما نوع البارمترين فهما متغيران من نوع d وهذا اختصار لـ GLdouble يعنيdouble ..

اما هذه الدالة

glVertex3d فتحتاج الى ثلاث بارمترات .. السيني والصادي والعيني x ,y ,z ..

لاحظ وجود الرقم 3 .

اما الحرف d فيدل على ان البارمترات من نوع GLdouble

مثلا

glVertex3f هنا الرقم ثلاثة يدل على وجود ثلاث بارمترات x . y . z والرحرف f يعني ان البارمترات من نوع float .

وهذه الانواع

glVertex2d

glVertex2f

glVertex2i

glVertex2s

glVertex3d

glVertex3f

glVertex3i

glVertex3s

glVertex4d

glVertex4f

glVertex4i

glVertex4s

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

لاحظ اننا في المثال السابق اخترنا الاحداثي السيني ذو الرقم صفر

والاحداثي الصادي صفر والعمق (z) صفر يعني نريده في منتصف الشاشة ..

تنبيه !

  glTranslatef(0,0,-1.0);

هي دالة الازاحة .. واستخدمناها هنا حتى نستطيع رؤية الجسم ..حيث جعلنا قيمة العمق = -1 .. حيث كل ما زادت هذه القيمة تدخل النفطة الى عمق الشاشة

وبالتالي تصغر .. جرب تكتبها -5 او -10 وهكذا لترى التأثير

الان سنختبر مدى ذكائنا المهول .. : )

void  Render()          
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
  glLoadIdentity();  

  glTranslatef(0,0,-1.0);

  glBegin(GL_POINTS);
  
  glVertex3f(0.1,0,0);
  glVertex3f(0,0.1,0);
  glVertex3f(0.2,0.2,0);
  


   
  glEnd();

           
}

لايوجد شيء غريب ..

اهم شيء تكون فاهم الاحداثيات .. هذا مايجب عليك تعلمه لاتقان المثال السابق

• الان سنتعلم كيف نغير حجم النقطة ,

لتغيير حجم النقطة نستخدم الدالة glPointSize

وصيغتها :

void APIENTRY glPointSize (GLfloat size);

وهي تطلب بارمتر واحد . وهو الحجم الذي تريده

مثلا

void  Render()          
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
  glLoadIdentity();  

  glTranslatef(0,0,-1.0);

  glPointSize(3);	

  glBegin(GL_POINTS);
  glVertex3f(0,0,0);
  glVertex2f(-0.3,-0.3 );
  glEnd();

           
}

الان رسمت نقطتين مختلفتي الحجم .

تنبيه !

يختلف الامر من حجهاز لاخر .. فبعض الاجهزة لايمكنها تحمل الاحجام الكبيرة من النقاط والبعض الاخر يمكنها ,, بالرغم من عدم حاجتك الى نقاط ذات احجام فلكية .. الا انه وفي كثير من الحالات تحتاج الى تكبير النقاط ..

الحل في هذه الحالة ان تفحص الهاردوير الذي تشتغل عليه وترى المدى المسموح به .

مثلا

float Point_Sizes[2];  
 float step;  

glGetFloatv(GL_POINT_SIZE_RANGE, Point_Sizes);
glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);

لايهم كثيرا شرح الكود السابق لكن ان احتجت هذا الكود مستقبلا فستجده هنا : )

انتهى الدرس الاول .

التطبيق بالمرفقات .

اذا كنت تعمل على GLUT فحمل الملف الاول .

اذا كنت تعمل على WIN API حمل الملف الثاني .

1_point_glut.zip

1_point_wnd.zip

تم تعديل هذه المشاركة بواسطة الشمري في 19 ديسمبر 2005 في 15:11

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

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

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#2

رسم خط :

انظر للكود

  glLoadIdentity(); 
  glTranslatef(0,0,-1.0);
  
  glBegin(GL_LINES);
  glVertex3f(0.1,0,0);
  glVertex3f(-0.1,0,0);
  
  glEnd();

الان اخترنا GL_LINES للدلالة على اننا نريد رسم خط حيث كل نقطتين تمثلان خط

glVertex3f(0.3,0,0);

تمثل النقطة الاولى واخترنا لها موقع

glVertex3f(-0.3,0,0);

واخترنا لها موقع

الان تم الوصل بين النقطتين لتمثلان خط

اذا .. كل نقطتين خط .. اربع نقاط خطان .. ست نقاط ثلاث خطوط ..

لكن

ثلاث نقاط خط واحد وتهمل النقطة الفردية .. خمس نقاط .. خطان وتهمل النقطة الفردية ..

*تغيير حجم الخط :

نستخدم الدالة glLineWidth وتطلب بارمتر واحد وهو الحجم الذي تريده .. وصيغتها

void APIENTRY glLineWidth (GLfloat width(;

مثلا :

glLoadIdentity(); 
  glTranslatef(0,0,-1.0);
  
  glLineWidth(2.0);
  
  glBegin(GL_LINES);
  glVertex3f(0.3,0,0);
  glVertex3f(-0.3,0,0);
  
  glEnd();

رسم عدة خطوط :

  glLoadIdentity(); 
  glTranslatef(0,0,-1.0);
  
  glLineWidth(2.0);
  
  glBegin(GL_LINES);
  glVertex3f(0.3,0,0);
  glVertex3f(-0.3,0,0);

  glVertex3f(0.3 ,0.3,0);
  glVertex3f(-0.3,0.3,0);

  glVertex3f(0.3,-0.3,0 );
  glVertex3f(-0.3,-0.3,0);
  
  glEnd();

الان سنتعلم رسم الخطوط بطريقة GL_LINE_STRIP

لن نغير بالمثال السابق الا شيء واحد وهو GL_LINE_STRIP

glLoadIdentity(); 
  glTranslatef(0,0,-1.0);
  glLineWidth(2.0);
  
  glBegin(GL_LINE_STRIP);
  
glVertex3f(0.3,0,0);
  glVertex3f(-0.3,0,0);

  glVertex3f(0.3 ,0.3,0);
  glVertex3f(-0.3,0.3,0);

  glVertex3f(0.3,-0.3,0 );
  glVertex3f(-0.3,-0.3,0);  
  glEnd();

كل ما صار هو وصل بين كل خط وخط اولا رسمنا الخط الذي يقع في المنتصف ثم رسمنا الخط الذي في الاعلى فتم الوصل بين الخطين .. ثم رسمنا الخط الذي في الاسفل فتم الوصل بين الخط الذي في الاعلى والخط الذي في الاسفل .

اما لو استخدمنا الطريقة :

GL_LINE_LOOP

فسيتم وصل اخر نقطة باول نقطة ويغلق الشكل ..

glLoadIdentity(); 
  glTranslatef(0,0,-1.0);
  glLineWidth(2.0);
  
  glBegin(GL_LINE_LOOP);
  
glVertex3f(0.3,0,0);
  glVertex3f(-0.3,0,0);

  glVertex3f(0.3 ,0.3,0);
  glVertex3f(-0.3,0.3,0);

  glVertex3f(0.3,-0.3,0 );
  glVertex3f(-0.3,-0.3,0);  
  glEnd();

2_line_glut.zip

2_line_wnd.zip

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

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

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#3

الرسم بطريقة GL_TRIANGLES

طبعا يلزمك هنا ثلاث نقاط او مضاعفات الثلاثة مثلا 3 نقاط او ستة او تسعة الخ ..

حيث يتم الوصل بين كل ثلاث نقاط لرسم مثلث ..

مثال :

  glLoadIdentity(); 
  glTranslatef(0,0,-3.0);
  
  
  glBegin(GL_TRIANGLES);
  glVertex3f(0.1,0,0);
  glVertex3f(-0.1,0,0);
 	 glVertex3f(0, 0.1,0);
  glEnd();

اولا رسمنا النقطة اليمنى ثم النقطة اليسرى ثم رأس المثلث وتم الوصل بين تلك النقاط لينتج المثلث .. لكن لو كتبنا مثلا .

glBegin(GL_TRIANGLES);
  glVertex3f(0.3,0,0);
  glVertex3f(-0.3,0,0);
 	 glVertex3f(0, 0.4,0);

 	 glVertex3f(0, 2,0);
 	 glVertex3f(1, 0.4,0);

  glEnd();

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

الرسم بطريقة GL_TRIANGLE_STRIP

حيث يتم الوصل بين المثلث الاول مع الثاني والثاني مع الثالث والثالث مع الرابع ...الخ

بتفصيل اكثر ..

انت رسمت مثلث له ثلاث نقاط .

نقطة 1

نقطة 2

نقطة 3

اذا رسمت

نقطة 4

يتم رسم المثلث الثاني الذي يتكون من نقطة 4 و3 و 2 .

اذا رسمت النقطة 5 يتم الوصل بين النقطة 5 و 4 و 3 ويتم رسم المثلث الثالث

اذا رسمت النقطة 6 يتم الوصل بين النقطة 6 و 5 و4 ..

مثال /

  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

  glLoadIdentity(); 
  glTranslatef(0,0,-3.0);
  
  
  glBegin(GL_TRIANGLE_STRIP);
  glVertex3f(0.3,-0.4,0);
    glVertex3f(-0.3,-0.4,0);
 	 glVertex3f(0, 0.0,0);

 	 glVertex3f(-0.3 ,0.0,0);//second

  glVertex3f(0,0.4,0);//third

 	 glEnd();

تنبيه ! الدالة glPolygonMode استخدمتها هنا لتوضيح الرسم .. ستعرف فائدتها في الدروس القادمة (واعتقد انك عرفت فائدتها) .

تنبيه!الطريقة السابقة قد تبدو صعبة في البداية لكن بالتكرار ستتعلمها ..

وتذكر انه لايجب عليك تعلم جميع الطرق ,, لكن زيادة الخير خيرين . : )

الرسم بطريقة GL_TRIANGLE_FAN

تستخدم عادة لرسم الاشكال الدائرية غالبا ..

يعني انت ترسم ثلاث نقاط

نقطة 1

نقطة 2

نقطة 3

فيتكون شكل مثلث ..

الان اذا رسمت

نقطة 4

فسيتم الوصل بين النقطة 1 و 3 و 4 .. ويتم رسم المثلث الثاني

اذا رسمت

النقطة 5 فسيتم الوصل بين النقطة 1 و 4 و 5 ويتم رسم المثلث الثالث

اذا رسمت

النقطة 6 فسيتم الوصل بين النقطة 1 و 5 و6 ويتم رسم المثلث الرابع .

اعتقد الامور واضحة .. اول نقطة هي نقطة الارتكاز ..

مثال :

  glLoadIdentity(); 
  glTranslatef(0,0,-6.0);
  
  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  glBegin(GL_TRIANGLE_FAN);
  glColor3f(0,1,0);
  glVertex3f(0.0,0,0);//first
    glVertex3f(0.0,0.4 ,0);//first
 	 glVertex3f(0.4, 0.0 ,0);//first

  glColor3f(1,0,0);
 	 glVertex3f(0.0 ,-0.4,0);//second
  glColor3f(1,0,0);
  glVertex3f(-0.4,0,0);//third

  glColor3f(1,1,0);
    glVertex3f(0.0,0.4 ,0);//fourth


 	 glEnd();

,النتيجة /

81e9cdf64b.gif

4_triangle_glut.zip

4_triangle_wnd.zip

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

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

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#4

الرسم بطريقة GL_QUADS

وهي مهمة جدا .

تحتاج الى اربع نقاط

مثال /

  glBegin(GL_QUADS);

  glVertex3f(0.3,0,0);//النقطة اليمنى السفلية

  glVertex3f(-0.3,0,0);//  النقطة اليسرى السفلية

  glVertex3f(-0.3 ,0.3,0); // النقطة العليا اليسرى

  glVertex3f( 0.3,0.3,0); //النقطة العليا اليمنى
  
  glEnd();

حيث يتم بين تلك النقاط بالترتيب ..

نعيد ونكرر .. كل اربع نقاط تمثل شكل رباعي .. ومضاعفات الاربعة

الرسم بطريقة GL_QUAD_STRIP

اعتقد واضحة ولاتحتاج شرح ..

المهم 4 نقاط ..ثمثل رباعي .. ثم كل نقطتين مربع اخر وهكذا ..

يعني :

4 نقاط في البداية لرسم شكل رباعي ثم 6 نقاط او 8 نقاط او 10 او 12 ...الخ

لاحظ ترتيب النقاط في الصورة الاساسية في اول الموضوع ..

هذا الشرح اقتبسته من كتاب Red Book .

اقتباس


GL_QUAD_STRIP 
Draws a series of quadrilaterals (four-sided polygons) beginning with v0, v1, v3, v2, then v2, v3, v5, v4, then v4, v5, v7, v6, and so on

وهو يوضح المقصود بكل تأكيد .

مثال :

/***********************************/
  void Render()
{
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );


  glLoadIdentity(); 
  glTranslatef(0,0,-3.0);
  
  	glPolygonMode(GL_FRONT,GL_LINE);

  glBegin(GL_QUAD_STRIP);

  glVertex3f(0.3,0,0); 

  glVertex3f(0.3,0.3,0); 

  glVertex3f(-0.3 ,0,0);  

  glVertex3f(- 0.3,0.3,0);  

  glVertex3f(-.6,0,0);

  glVertex3f(-.6,0.3,0);

  glEnd();





}


/***********************************/

ولاحظ هذه الصورة لعلها توضح المقصود ولو قليلا :

e4a9900a23.gif

الرسم بطريقة GL_POLYGON

لرسم مضلعات معقدة : ) ..

اذا رسمت ثلاث نقاط تحصل على شكل مثلث اذا رسمت 4 نقاط تحصل على شكل رباعي اذا رسمت خمس نقاط تحصل على شكل خماسي الخ ..

مثال /

  glBegin(GL_POLYGON);

  glVertex3f(-0.3,0,0);

  glVertex3f( 0.3,0,0);

  glVertex3f( 0.3 ,0.3,0);

  glVertex3f( -0.3 ,0.3,0);

  glVertex3f(-0.4 ,0.15,0);

  	
  glEnd();

تنبيه !

انتبه لاتجاه النقاط .. فكثيرا من المبرمجين المبتدئين في هذا المجال تنفقع مرارته من النتائج الخاطئة ..

;كما حصل معي مرارا وتكرارا .. والسبب خطأ في الاتجاهات مثلا

احذرك من الان قبل ما تنفقع مرارتك : )

الى هنا نختم هذه الجولة السريعة .. اذا فيه اخطاء او اضافة .. نتمنى ان نراها ..

5_square_glut.zip

5_square_wnd.zip

تم تعديل هذه المشاركة بواسطة الشمري في 19 ديسمبر 2005 في 15:54

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

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

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#5

اه .. نسيت .

بعض الدوال لم اشرحها .. مثل glColor .. اعتقد تشرح نفسها .. لكن اذا لم تفهمها .. فسيكون هناك موضوع خفيف .. عن الالوان و Opengl باذن الله .

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

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

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#6

جزاك الله خير

وقفة تأمل..

سعدبن معاذرضي الله عنه أسلم وله 30سنة ومات وله 36سنه

ولأجل 6سنوات اهتزله عرش الرحمن

ونحن

كم لنافي الإسلام؟ وماذاقدمنا له؟

#7

السلام عليكم ..

درس رائع .. جزاك الله خيرا

فعلا اساسيات مهمة ..

كان هذا المفروض اول درس أقوم بقراءته

..

سؤال صغير

اقتباس
((تنبيه ! الدالة glPolygonMode استخدمتها هنا لتوضيح الرسم ))

ممكن شوية توضيح .

..

اخي الكريم ممكن اطلب منك طلب ..

ارجو اعادة فهرسة الدروس في هذا المنتدى وإعادة ترتيبها .. خاصة دروسك اخي الكريم ..

ما شاء الله الدروس كثيرة .. وبصراحة تلخبط الواحد (هذا الصار معي، ولكي لا يحدث مع غيري)

يعني مثلا يتم فرز دروسك الى جزئين أساسيين ،

دروس الخاصة بأستخدام مكتبة glut

و الاخرى الخاصة ب win api

ثم يتم ترتيب الدروس حسب المستوى .. يعني ياريت ترقم الدروس

لأن القادم الى هذا المجال لا يعرف اين هي البداية وما هي الاولويات ..

بارك الله فيك ..

و اعانك على خدمة اخوانك المسلمين …

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#8
اقتباس
ممكن شوية توضيح .

hrwاقصد ان الدالة glPolygonMode استخدمتها حتى يصبح المثلث "" خطوط "" ,, وبالتالي ستعرف كم عدد المثلثات المرسومة ..

بالنسبة لتنظيم المواضيع .. سأفعل ان شاء الله .. لكن لا زلت انتظر من يضيف .. ويصحح ما فيها من اخطاء .. لانها مجرد محاولات .

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

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

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#10

متشكر كثير

لكن أنا بحاجة للملفات التالية

glut.h

glut.lib

glut.dll

من أين أحصل عليها؟

My_Sign.jpg
#11

هنا :

http://www.xmission.com/~nate/glut/glut-3.7.6-bin.zip

وراجع المواضيع المثبتة لمعرفة طريقة التثبيت ( فهرس دروس OpenGL - GLUT )

لكن لاحظ أن المكتبة تعمل الان على بيئة 32 بت .. يعني الاصدارات القديمة من المكتبة كانت زي كذا

--

glut.h

glut.lib

glut.dll

--

اما الان :

glut.h

glut32.lib

glut32.dll

--

الامثلة القديمة ..فقط قم بالحصول على السورس كود وقم بترجمته وسيعمل تحت بيئة 32 بت .

تم تعديل هذه المشاركة بواسطة الشمري في 24 سبتمبر 2006 في 22:31

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

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

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

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

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