بتـــــاريخ : 3/1/2011 9:29:01 PM
الفــــــــئة
  • الحـــــــــــاسب
  • التعليقات المشاهدات التقييمات
    0 7822 0


    كيف ترسم دائرة في OpenGL (خاص)

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

    كلمات مفتاحية  :
    رسم دائرة OpenGL

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

    هو طبعا مو خاص او حاجة فريدة .. ولكن انجزت هذا الكود دون أن انظر الى مثال جاهز .. لهذا هو انجاز و Exclusive :D .

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

    نبدأ :
    .. opengl لاتوفر طريقة مباشرة لرسم دائرة . .

    لذلك سنستفيد من الدوال المثلثية لانجاز الكود .

    " سأتكلم عن الدوال المثلثية ... في موضوع قادم ان شاء الله . "

    باختصار :

    باستخدام طريقة الرسم GL_POLYGON .. والتي تقوم بوصل النقطة بالنقطة التي تليها ثم يتم اغلاق الشكل ..

    فمثلا شاهد الصورة .. ستجد اننا رسمنا نقاط .. وسيتم تحويل هذه النقاط الى شكل.. حسب الطريقة GL_POLYGON .
    Posted Image

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

    كل شيء سهل الا رسم النقاط بشكل دائري ..

    هنا يبرز دور الدوال المثلثية .


    الحل :
    نخزن 360 نقطة ( دورة كاملة ) . . هكذا :

    void Init()
    {
             int degree =0;
             for(;degree<=360;degree++)
             {
                     
                     double d=(degree*(3.14/180));
                     cp[degree].x=sin(d);
                     cp[degree].y=cos(d);

             }
    }


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

    لكن باختصار : قمنا بتحويل الزاوية ثم بحساب قيم الدوال المثلثية
    ------------------------------

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


    الان الى الاستخدام في داخل الloop

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

                     glBegin(GL_POLYGON);
                     for(int i=0;i<360;i+=10)
                             glVertex2f(cp[i].x * 3,cp[i].y*3);
                     glEnd();
    }


    النتيجة هي رسم نقاط حسب قيم المصفوفة التي جاءت من الدوال المثلثية
    ثم توصيل هذه النقاط حسب طريقة GL_POLYGON

    لمزيد من الفهم :
    قم بتغيير الرقم 10 في السطر السابق
    for(int i=0;i<360;i+=10)
    الى الرقم 40 ثم الى الرقم 1 مثلا ...
    ماذا تلاحظ؟
    نلاحظ انه كلما زادت قيمته قل عدد النقاط المرسومة وبالتالي تقل نعومة الدائرة ,

    --

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

    struct CPOINT {
            float x,y;
    };

    CPOINT cp[360];
     
    //--------------- Draw Circle -----------------
            void glCircle(int radian,unsigned int softness,CPOINT cp[])
            {
                    glBegin(GL_POLYGON);
                     for(int i=0;i<360;i+=softness)
                             glVertex2f(cp[i].x * radian,cp[i].y*radian);
                     glEnd();
     
             }
    //--------------- Init Points---------------

    void Init()
    {
             for( int degree =0;degree<360;degree++)
             {
                     
                     double d=(degree*(3.14/180));
                     cp[degree].x=sin(d);
                     cp[degree].y=cos(d);

             }
    }


    /**************** Important *********************/

    void Render()
    {
            glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    ////2
            glLoadIdentity();
            glTranslatef(0,0,-12);
            glCircle(1,10,cp);
    ////1
            glLoadIdentity();
            glTranslatef(3,0,-12);
            glCircle(2,40,cp);


    }


    وتستطيع استخدام الDisplay Lists لتزيد من سرعة الرندر .

    ولو أردت ان ترسم دائرة بدوت تعبئتها بالالوان استخدم

            glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);


    المرفقات :
    التطبيق - وهو باستخدام OPENGL+ WINAPI + CPP .
     
    ملف مرفق(ملفات)
     
    ملف مرفق  glCircle.zip (56.94كيلو )

    كلمات مفتاحية  :
    رسم دائرة OpenGL

    تعليقات الزوار ()