تبليغاتX
OpenGL & Computer graphics - مقالات آموزش OpenGL قسمت هشتم

 

 

 

Chapter3

 

طراحي در فضا : اشكال اوليه هندسي و بافرها

 

آنچه در اين فصل خواهيد آموخت:

 

 

كاري كه تابع انجام ميدهد

 

 

تابع

كشيدن نقاط و خطوط و اشكال

 

GlBegin/glEnd/glVertex

اشكال را به صورت سيمي

 wire frameيا جامد

 solidدر مي آورد

 

GlPolygonMode

اندازه نقاط را براي طراحي معين ميكند

 

GlPointSize

پهناي خط كشيده شده را مشخص ميكند

 

GlLineWidth

سطوح مخفي را پاك ميكند

 

GlCullFace/glClear

الگويي را براي خطوط شكسته معين ميكند

 

GlLineStipple

الگوي پر كردن چند ضلعي ها

polygon را معين ميكند

 

GlPolygonStipple

استفاده از جعبه تقسيم

scissor در openGL

 

GlScissor

استفاده از بافر براي الگو برداري

 

GlStencilFunc/glStencilMask/glStencilOp

 

همانطور كه ميدانيد تمام اشكال موجود در دنيا از كتاب و ساختمان گرفته تا همين كامپيوتر را ميتوان به كمك مثلثهايي طراحي كرد . در كار با نرم افزار هاي سه بعدي هم شما تمام اشيا را بوسيله ي چند ضلعي هاي پايه كه به اصطلاح به آنها primitive ميگويند ميسازيد . در كار با openGL هم از اين قاعده استفاده ميكنيم.

تمام چند ضلعي ها يك بعدي (مانند خطوط) يا دو بعدي هستند (مثل اشكال پايه).در اين بخش ياد ميگيريد كه چطور از اين اشياي دو بعدي صحنه هاي سه بعدي درست كنيد.

 

تعريف پيكسل: پيكسل كوچك ترين جزء در مانيتور شما و در سيستم رنگ بندي است و هر پيكسل ميتواند هر رنگي داشته باشد.

 

شما ميتوانيد از نرم افزارهاي سه بعدي براي كشيدن اشكال مورد نظرتان استفاده كنيد.  اما در OpenGL كار مقداري فرق ميكند. درOpenGL شما نبايد نگران مختصات صفحه نمايش يا پيكسل هاي آن باشيد بلكه بايد حواستان به موقعيت مختصات ديدتان باشد.  كارهايي مانند كشيدن خطوط و اشكال و برپايي صحنه سه بعدي مورد نظر و بالاخره تبديل آن به صحنه دو بعدي را خود OpenGL  انجام ميدهد.

اين بخش و بخش بعد به امور پايه در API هايي مانند OpenGL ميپردازد.  در اين بخش در مورد اينكه چطور تصاوير سه بعدي در مانيتور شما به صورت دو بعدي در مي آيند صحبت ميكنيم.

بعلاوه چگونگي  تغيير شكل جسم( چرخش و جابجايي و تغيير اندازه ) را خواهيم آموخت.

 

Vertex: نقطه سه بعدي

براي تعيين يك نقطه براي شروع كار طراحي از تابع glVertex استفاده ميكنيم كه بيشترين كار برد را در OpenGLدارد. ورتكس سطح پايين ترين جز در چند ضلعي هاي پايه ي OpenGL است.  ورتكس نقطه اي در فضاي سه بعدي است.

تابع زير نقطه اي را در فضاي سه بعدي براي ما ميكشد.  اين تابع ميتواند تا چهار آرگومان را قبول كند كه در درسهاي بعد درباره آنها بيشتر صحبت ميكنيم.

 

glVertex3f(50.0f, 50.0f, 0.0f);

تابع بالا نقطه اي را در  x=50 , y=50 , z=0 براي ما ميكشد.

 

 

 

اين تابع ميتواند از دو تا چهار آرگومان را قبول كند كه بسته به شرايط ميتوانيد از آنها استفاده كنيد.  براي مثال نقطه بالا را ميتوان به صورت زير هم تعريف كرد:

 

glVertex2f(50.0f, 50.0f);

در اين حالت z همواره صفر خواهد بود  .

 

گفتم كه اين تابع چهار آرگومان را ميپذيرد (glVertex4) و آرگومان چهارم كه پهنا را تعيين ميكند در صورت مشخص نشدن همواره 1 فرض ميشود . از آرگومان چهارم يا همان پهنا ميتوان براي تغيير اندازه (scale) استفاده كرد  در بخش هاي بعد توضيح بيشتري در اين مورد خواهيم داد.

 

براي شروع كار ما تعريف هندسي vertex را مي آوريم:

در هندسه بر خلاف دنياي cyber كه vertex را نقطه اي در فضا در نظر مي گيريدvertex  نقطه برخورد دو خط يا منحني تعريف ميشود . و همين تعريف پايه اشكال اوليه (primitives ) را تشكيل ميدهد  .

 

 

Primitive: اشكال اوليه در حقيقت پايه و شرحي هستند بر اجسام بزرگ تر و به بيان ديگر مجموعه اي از vertex ها كه به شكل خاصي بر روي صفحه نمايش نشان داده شده اند.

 

در OpenGL 10 نوع پايه از اين اشكال وجود دارند.  از يك vertex ساده شروع و تا يك n ضلعي بسته ادامه دارند.يك راه براي كشيدن اين اشكال استفاده از دو تابع glBegin و glEnd ميباشد.

 

با glBegin به برنامه ميگوييد كار دسته بندي و شرح يك سري از vertex ها را براي رسم يك شكل شروع كند و با استفاده از glEnd كار تعريف اين راس ها (vertex ) را به پايان ميرسانيد.

 

براي شروع نقطه اي را در فضا رسم ميكنيم:

glBegin(GL_POINTS);                // Select points as the primitive
glVertex3f(0.0f, 0.0f, 0.0f);        // Specify a point
    glVertex3f(50.0f, 50.0f, 50.0f);     // Specify another point
 
glEnd();                    // Done drawing points

آرگوماني كه در تابع glBegin به كار رفته يعني GL_POINT به OpenGL ميگويد كه راس های(vertex)

 به كار رفته در اين تابع براي نمايش يك نقطه به كار ميروند. بدنه تابع بالا دو نقطه را با مختصاتشان

مشخص ميكندو هر دو رسم ميشوند.

مثالي كه زديم نكته مهمي را در رابطه با دو تابع glBegin و glEnd براي ما مشخص ميكند. اينكه شما

ميتوانيد به تعداد دلخواه از اشكال پايه را در بين اين دو تابع ايجاد كنيد به شرطي كه همه اين

اشكال (primitive) از يك نوع باشند.مثلا در تابع بالا ميتوانستيم براي رسم نقطه دوم يك بار ديگر

از glBegin  و glEnd استفاده كنيم اما از آنجا كه ما قصد داشتيم دو نقطه را رسم كنيم و همانطور كه

بديهي است دو نقطه از يك جنس هستند هر دو را درون يك تابع glBegin/glEnd رسم كرديم. اما اگر

ميخواستيم بر فرض مثال دايره اي رسم كنيم بايد دوباره از تابع glBegin/glEnd استفاده ميكرديم.

دقت كنيد كه اگر تابع بالا را دو قسمتي مينوشتيم سرعت كار پايين مي آمد.

 

glBegin(GL_POINTS);        // Specify point drawing
        glVertex3f(0.0f, 0.0f, 0.0f);   //this
glEnd();   //this
 
glBegin(GL_POINTS);        // Specify another point
        glVertex3f(50.0f, 50.0f, 50.0f);   //this
glEnd();   //this
 

پس اين نكته را به خاطر داشته باشيد كه براي كشيدن تعداد دلخواه شكل پايه به شرطي كه همگي از

يك نوع باشند ميتوان از يك تابع  glBegin/glEndاستفاده كرد.

 

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

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

صورت مارپيچ به بالا حركت ميديم.

دقت كنيد كه از تابع setupRC براي تعيين رنگ نقاط به رنگ سبز استفاده كرده ايم.

 

// Define a constant for the value of PI
 
#define GL_PI 3.1415f
 
 
 
// This function does any needed initialization on the rendering
 
// context.
 
void SetupRC()
 
    {
 
    // Black background
 
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
 
 
 
    // Set drawing color to green
 
    glColor3f(0.0f, 1.0f, 0.0f);
 
    }
 
 
 
 
 
// Called to draw scene
 
void RenderScene(void)
 
    {
 
    GLfloat x,y,z,angle; // Storage for coordinates and angles
 
 
 
    // Clear the window with current clearing color
 
    glClear(GL_COLOR_BUFFER_BIT);
 
 
 
    // Save matrix state and do the rotation
 
    glPushMatrix();
 
    glRotatef(xRot, 1.0f, 0.0f, 0.0f);
 
    glRotatef(yRot, 0.0f, 1.0f, 0.0f);
 
 
 
    // Call only once for all remaining points
 
    glBegin(GL_POINTS);
 
 
 
    z = -50.0f;
 
    for(angle = 0.0f; angle <= (2.0f*GL_PI)*3.0f; angle += 0.1f)
 
        {
 
        x = 50.0f*sin(angle);
 
        y = 50.0f*cos(angle);
 
 
 
        // Specify the point and move the Z value up a little
 
        glVertex3f(x, y, z);
 
        z += 0.5f;
 
        }
 
 
 
    // Done drawing points
 
    glEnd();
 
 
 
    // Restore transformations
 
    glPopMatrix();
 
 
 
    // Flush drawing commands
 
    glFlush();
 
    }

اين كد ها مقادير x و y را بر حسب درجه اي كه سيستم محاسبه ميكند به ما برميگردانند.اين درجه بين

0 تا 360 متغير است.سپس  سيستم با استفاده از مختصات x,y,z نقطه اي را رسم ميكند.

در انتها دستور z += 0.5f; ارتفاع را مقداري افزايش ميدهد.
 
 
 
فكر بقيه توابعي كه در كد اصلي استفاده شده نباشيد.تمام انها را در دروس بعدي مورد مطالعه قرار
 ميدهيم.
 
نكته:
 
 
اگر رياضيات دبيرستان را مطالعه كرده باشيد ميدانيد كه شكل بالا نمايشگر صفحه مختصات است.
همانطور كه مشاهده ميكنيد خطي كه ابتداي آن مركز مختصات و انتهاي آن نقطه اي روي دايره است
 يك زاويه را تشكيل ميدهد.
توابع sin و cos در حقيقت نمايان گر طول (x) و عرض (y) نقطه مورد نظر است. دقت كنيد كه توابع sin() 
و cos() در زبان Cزاويه را بر حسب راديان محاسبه ميكنند. يك دايره 2pi راديان است.
 
خوب اگر به اين موضوع علاقه داريد ميتونيد pdf اون رو كه ساسان ميذاره دانلود كنيد.چون تو اين پست به 
خاطر اديتور مزخرف بلاگفا احتمال داره تو توابع بعضي موقع ها علامتها قاطي شده باشه.اما تو نسخه 
pdf اين مشكل وجود نداره.
 
ادامه دارد............
 
 
منبع : كتاب OpenGL SuperBible 3rd Edition  
 ترجمه و تنظیم : محمد عباسی
 
نسخه PDF این مقاله را میتوانید از این آدرس دریافت نمایید :
 

 

 

+ نوشته شده توسط ( ساسان و محمد ) در چهارشنبه بیست و پنجم مرداد 1385 و ساعت |
Image and video hosting by TinyPic