بتـــــاريخ : 3/1/2011 3:51:10 AM
الفــــــــئة
  • الحـــــــــــاسب
  • التعليقات المشاهدات التقييمات
    0 1805 0


    لنتعلم كيفية الربط بين openGL و WIN API رح نسوي اللي نقدر عليه ......

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

    كلمات مفتاحية  :
    تعلم الربط openGL WIN API

    بسم الله الرحمن الرحيم

    لا ادعي الخبرة .. عشان ما تفهمونا غلط .... لكن هي محاولة لفهم عمل هذه المكتبة الرائعة GL

    ===

    ربط opengl بالنافذة .. وبالنظام .... بوجه عام .. يتم عن عدة طرق ... اهمها عن طريق المكتبة glut او دوال النظام (API)

    API طويلة نوعا ما ... لكن لا اتصور لعبة تعمل على الويندوز ولاتستخدم دوال API .

    لذا سأفترض انك :
    1- تجيد لغة السي .
    2- تملك اساسا جيدا في win api .

    الكود طويل نوعا ما ..
    لكن ما اريدك ان تفهمه.. هو على أي اساس .. انشأنا مثل هذا الكود .
    هل يجب ان يكون 21 سطر .. او 68 سطر ..
    هل المسألة قص ولصق .
    ام فهم . ام حفظ .

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

    اريدك ان تنظر الى الكود نظرو واحدة وتعرف اجزائه ...


    اولا نقسم عملنا الى عدة أقسام بهدف التنظيم .((دوال )).. اعيد واكرر ... تنظيم .

    قسم يقوم باعداد النافذة ويربط نافذتنا بopengl ونسميه

    CreateGLWindow()

    وقسم يقوم بإعدادات opengl العامة ونسمي الدالة مثلا هممممم:

    IntiGL()

    ولكن اعدادات opengl كثيرة في البداية ستكون قليلة لكن بعد ان نتقدم سنتعلم كيف نعد الاضاءة والاكساء والماتيريال ونحو ذلك لذا سنقسم الدالة السابقة IntiGL() الى عدة اجزاء مثلا دالة ضوء دالة اكساء وهكذا ..
    الان مبتدئين ..لذا لانحتاج الا الى اشياء بسيطة ,,

    القسم الثالث او الدالة الثالثة هي التي ستعرض لنا مانرسمه وسنرسم بداخل هذه الدالة وسنسميها
    render()
    الدالة الرابعة هي التي ستقوم بتظبيط العرض او منفذ الرؤية على حسب حجم النافذة وسنسميها
    ReShape(GLsizei width,GLsizei height)
    قد تكون الدالة السابقة غير واضحة لكن لايهم ..

    الدالة الخامسة هي الدالة التي ستمسح اثار لعبتنا .. وسنسميها
    ShutDown()
    هكذا سنقسم برنامجنا طبعا لايلزمك ان تتقيد بهذا التقسيم وطبعا لايجب ايضا التقيد باسماء الدوال لكن كل مانقوم به هو للتنظيم
    ---




    اذا الشكل العام لبرنامجنا

    --------------------
    استدعاء المكتبات
    -----------------------

    ----------------------------
    الاعلان عن المتغيرات العامة
    -----------------------------

    -------------------------------
    الاعلان عن الدوال العامة
    -----------------------------


    -----
    دالة 1
    -----

    -----
    دالة 2
    -----

    -----
    دالة 3
    -----

    -----
    دالة 4
    -----

    -----
    دالة 5
    -----

    -----
    دالة التعامل مع الراسائل المعروفة
    -----
    كما قلنا تقسيم البرنامج يساعد على استيعاب الدروس فقط .. وليس الزامي ..

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

    * اخر دالة ستكون دالة التعامل مع الرسائل التي تعلمتها في WIN API

    -----------





    الدوران ...(LOOP)

    هذا احد اهم المفاهيم التي ستبني عليه العابك ...

    حسن الجودي سبقني ... :)
    http://www.arabteam2...showtopic=82793



    لكن كنت كتبتها من فترة ... ولا مانع من عرضها .


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

    لكن هناك دوال لابد ان تستدعيها عدة مرات وهي
    1- دالة الرسم :: والتي اتفقنا على تسميتها بrender ..هذه الدالة تحتاجها طوال فترة البرنامج .. مثلا :
    قمت برسم مربع .. وتريد تحريكه ؟؟ كيف ستحركه وانت لم تستدعيه الا مرة واحدة .
    هذا يسمى اطار .. frame
    فكل مرة نرجع ونستدعي دالة الرسم .. والتي ستحدث البيانات الموجودة على الشاشة لتضمن بقاء اللعبة في طور الحياة .. :)

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

    اذا كيف نجعل اللعبة
    تدور ... وتحدث نفسها ؟
    الجواب باستخدام الحلقة التكرارية
    while
    مثال عام :
    نعلن عن متغير من نوع boolean و قيمته اما صحيحة او خاطئة مثلا
    bool EXIT =false;
    اعلنا عن متغير وسميناه EXIT حتى يكون اسم واضح .. واعطيناه قيمة خطا

    نقول :
    مادام قيم EXIT = خطا ..
    اذا قم بعمل التالي
    1- استدعي دالة الرسم
    rende()
    2- عالج اوامر الادخال مثلا الكيبورد ..
    اذا ضغط على الزر مثلا esc فاجعل قيمة المتغير EXIT = صح وبالتالي يختل شرط الحلقة الدوارانية فنخرج من اللعبة

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

    الكود:

    يجب ان تكون فاهم دوال API لمعرفة هذا الكود :
    MSG        uMsg;



            while( uMsg.message != WM_QUIT )
            {
      if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
      {
            TranslateMessage( &uMsg );
            DispatchMessage( &uMsg );
      }
            else
            render();
            }

            shutDown();
    نقول
    while( uMsg.message != WM_QUIT )
    مادام الرسالة uMsg.message ليست دالة الخروج WM_QUIT اذا قم بالدخول في الحلقة الدورانية وهي :
    if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
      {
            TranslateMessage( &uMsg );
            DispatchMessage( &uMsg );
      }
    نقول اذا لاحظنا اي رسالة جديدة جاءتنا من الكيبورد او الماوس ونحو ذلك عندئذ قم بتحليل تلك الرسالة ..((ونحن نعرف من دوال API )) اننا نرسل الرسالة الى دالة الرسائل والتي عادة مانسميها WndProc
    طيب اذا لم تصلنا اي ضغطة كيبورد ولا نقرة ماوس ماذا نفعل ؟
    else
            render();
    }
    فاذا لم يصلنا اي حدث عندها قم باستدعاء دالة الرسم .. طبعا والتي نضع فيها بعض الرسم مثلا رسم مربع او مثلث .. الخ

    وهكذا ..
    ندور وندور حتى يصلنا رسالة الخروج WM_QUIT فاذا لم تأتي فان الحلقة ستدور وتحلل الرسائل ثم تستدعي دالة الرسم ...
    طيب نفرض جاءنا امر الخروج WM_QUIT ... عندئذ سنخرج من الحلقة ونكمل ما بعد الحلقة الدوارانية ... ماذا يوجد بعدها ؟؟ لاحظ
    shutDown();
    اذا تدور اللعبة حتى ياتي امر الخروج عندئذ يتم الخروج من الحلقة لتجد الدالة shutDown(); التي تقوم بمسح اثار اللعبة ومن ثم الخروج من اللعبة نهائيا ..والعودة للويندوز ..

    هذه صورة من كتاب red book توضح المقصودر بالفريم
    Posted Image
    هذه هي الفكرة اتمنى قبل ان تواصل ان تكون استوعبت الفكرة ..
    انا كنت ارى مثل تلك الامور لكن لا اهتم لها .. فكان كل مايهمني شرح دالة ترسم مربع او مثلث .؟؟؟
    هذا ليس مهم ..
    المهم ان تعرف كيف تتم الامور في لعبتك ...

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

    اذا لم تفهم السابق او تجاهلته .. فلا تحاول اكمال الطريق لانك وبكل اسف ستفشل !!

    كلمات مفتاحية  :
    تعلم الربط openGL WIN API

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