أساسيات الرسم في OpenGL >>> سلسلة هذا اللي أعرفه ( 1 ) :)

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

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

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



اول شيء .. اين نضع دوال الرسم ..
الجواب .. اذا كانت المسألة اعداد الرسم .. مثلا نعد دالة تقوم بتغيير حجم الخط .
هنا نضعها في دالة اعداد الويندوز .. لاننا فقط نستدعيها مرة واحدة .. اما اذا اردنا الرسم .. فنضعها في الدالة التي أنشأناها في الدرس السابق وسميناها 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
لرسم مضلع ..

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


Posted Image



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

مثلا تستطيع رسم مربع باستخدام 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 حمل الملف الثاني .
 
ملف مرفق(ملفات)