GPU و GPGPU و OpenCL و OpenGL و CUDA و ما إلى ذلك

لقد قمت بكتابة العديد من المقالات السطحية هنا وهناك ، ومن الجيد أن أقوم بجمعها في مدونتي هذه :-) ، وهذه أحدها .

المرحلة الثانية - : GPU
بعد 12 سنة من ولادتي ، وتحديداً عندما انتهيت من الصف السادس الابتدائي ، ظهرت أفكار جديدة لعلاج مشاكل البرامج الرسومية و الألعاب ، وتتمحور حول مبدأ أساسي :
لماذا لا نضع معالج خاص + ذاكرة خاصة للبرامج الرسومية المبنية على OpenGL و أشباهها ؟
لماذا لا نسمح للمبرمج بكتابة معادلاته التي يريد تطبيقها على كل بكسل وعلى كل رأس Vertex ؟
بدأت الأفكار تطبخ وتطبخ حتى وصلت للنضوج مع دخولي للمرحلة الثانوية . فظهر أمامنا مفهوم GPU ( عفواً .. ليس مفهوم ، إنما Hardware وهو عبارة عن معالج مركزي خاص للمكتبات الرسومية مثل CG و OpenGL و Direct3D ) .
GPU : اختصار لمصطلح Graphics Processing Unit و الذي حصل باختصار ، أن عمليات المعالجة انتقلت من CPU إلى GPU ( طبعاً لا يعني هذا الاستغناء عن CPU ) ، فمثلاً علمية ضرب المصفوفات ، وعملية معالجة كل بكسل ، وعمليات أخرى تجري على وحدة GPU ومابين ذاكرة ومعالج البطاقة الرسومية .. فوصلنا لسرعة وقدرة عالية مع نتائج مبهرة .. وذلك لأنك أمام معالج رسومي عملاق و قوي .
المرحلة الثالثة - GPGPU :
الحسد طبيعة البشر ، والمبرمجين بشر ، فظهر طفيليون على مجال " الألعاب و الرسوميات " ، من أصحاب المحركات الفيزيائية أو برامج المحاكاة العلمية أو من أي مجال آخر عدا برمجة الألعاب و الرسوميات . الطفيليون " المبرمجون " فكروا في الاستفادة من وحد المعالجة الرسومية GPU لتسريع محرّك فيزيائي ( تسريع أنظمة الجزئيات الفيزيائية ، لمحاكاة فيضان المياه مثلاً .. ) ، أو لتسريع خوارزمية مستخدمة في محاكي للأبحاث العلمية . مستفيدين من سرعة العمليات التي تقوم بها GPU .. فبدلاً من أن نركن GPU دون استخدام .. فلماذا لا نستفيد منه في جوانب تطبيقية شتى . مع العلم أنه قد ظهر عائلة جديدة من المعالجات المختصة بالفيزياء باسم PPU .
من هنا ظهر مفهوم GPGPU : وهو اختصاراً لـ General Purpose Graphics Processing Unit .. يعني " الغايات العامّة من وحدة المعالجة الرسومية " .. فظهرت مقالات وتطبيقات تستفيد فعلاً من إمكانية GPU ، لم ننتظر طويلاً حتى ظهرت CUDA و OpenCL و مكتبة ثالثة لا أريد أن أعمل لها دعاية دون مقابل :/ .
نسيت أن أخبركم أن مفهوم GPGPU بد أ يتبلور عندما وطأت قدماي أرض الجامعة .
المرحلة الرابعة - OpenCL و CUDA :
ظهرت الحاجة لمكتبة قياسية تستفيد من العدد الضخم من الأنوية cores وبالتالي تطبيق مبدأ البرمجة المتوازية ، بل والاستفادة من قدرات GPU الحسابية السريعة و الدقيقة ، حتى لو لم يكن التطبيق رسومي .
لم أنتهي من المرحلة الجامعية إلا و مصنعوا البطاقات الرسومية قد طوّروا من قدرات GPU ، ليخدم قطاعات أخرى ، ولعل خطوة شركة انفيديا في هذا المجال هي الأبرز من حيث تطوير CUDA وهي معمارية ظهرت على يد شركة انفيديا وتعمل على بطاقات انفيديا الرسومية ، و يمكن من خلالها تطوير تطبيقات لا علاقة لها بالرسوميات ( ويمكن استخدامها طبعاً مع التطبيقات الرسومية ) ، وطبعاً يمكن الاستفادة من هذه المعمارية من خلال لغة C ولغات أخرى .
ومن ثم ظهرت مكتبة OpenCL من مختبرات Apple والتي أصبحت الآن تحت عهدة Khronos ( نفس الجهة التي تشرف على مواصفات OpenGL ) ، وبالتالي أصبحت مكتبة قياسية يشارك في وضع قياساتها ومن ثم عمل implementation لها ، عدة شركات ضخمة AMD, IBM, Intel, و Nvidia بالاضافة لـ Apple طبعاً .
تتميز OpenCL بقدرتها على العمل على أي قطعة hardware ,التي تسمى Device ، فهي قد تعمل على CPU وتستفيد من ,multi-core CPU .. وقد تعمل على GPU (لو كنت تملك واحداً ) . علماً أن عدد " أنوية " المعالج المركزي CPU قد تصل لثمانية أنوية أو أقل من هذا ( مثل Intel i7 ) .. أما في حالة GPU فأنت أمام عشرات الأنوية التي تتسابق لخد��تك ( قد تصل لمئات ) .
OpenCL و CUDA لهما نفس الهدف تقريباً .. ولكن التوجه الآن هو بدعم OpenCL بشكل كامل ، باعتبارها قياسية وستعمل على أكثر من بطاقة رسومية وعلى أكثر من نظام تشغيل ، بل وحتى على أكثر من لغة برمجية .بالتالي أصبحنا بغنى عن التطفل على مبرمجي الرسوميات واستخدام أدواتهم مثل لغة GLSL أو HLSL لاستغلال قوّة GPU في أمور غير رسومية ، بل هناك ما يسمّى بـ kernel في OpenCL وهي لغة خاصة صممّت لهذا الغرض ( مبنية على مواصفات لغة سي ) .
مالذي يمكنك أن تفعله باستخدام OpenCL ؟
OpenCL : هدفها الأساسي هو تسريع تنفيذ الخوارزميات ( معظمها ولكن ليس كلها ) ، فخذ مثلاً :
- لو حاولت إيجاد القيمة المطلقة abs لمجموعة أعداد موجودة في مصفوفة ،
يمكنك الاستفادة من Parallel programming التي تدعمها OpenCL ( البرمجة المتوازية أو المعالجة المتوازية Parallel Processing ) ، لتنفيذ هذه الفكرة ، وبالتالي تنفيذ هذه الخوارزمية على عشرات الأنوية ( Multi-core ) ، بدلاً من معالج واحد .. وبدلاً من البحث عن لغة برمجية مستقلة تدعم مفهوم البرمجة المتوازية ..
- يمكن أيضاً أن تتكامل OpenCL مع OpenGL أو Direct3D .. حيث البيانات يمكن تبادلها فيما بينهما ، أي أنه يمكن أن تخبر OpenCL بتغيير قيم مصفوفة بيانات ما .. وستتأثر OpenGL بشكل مباشر دون تدخل منك ، بمجرد أن تطلب من OpenCL ذلك عند إنشاء Context .
وهناك مسائل كثيرة ( تخيّل كثير من الخوارزميات فقط ) ،
ولإزالة اللبس الذي قد يحصل .. أقول :
OpenCL ليست مكتبة رسومية .. فقد تشاهد مثلاً تطبيق رسومي خلاّب تم تسريعه باستخدام OpenCL .. مثل عملية Raytracingالمعروفة ببطئها الشديد في السنوات الماضية ( تنتظر ساعات لترى النتيجة ) ، لذلك عملية الرسم هي من مسؤولية OpenGL ونحوها .. ولكن عملية تسريع الرسوميات ( وتطبيق مفهوم البرمجة المتوازية مثلاً ) يمكن تنفيذه باستخدام OpenCL أو CUDA ..
روابط قد تفيدنا :
مقطع فيديو متميز لشرح مبدأ عمل OpenCL والهدف منها
http://developer.app...troduction.html
http://cmsoft.com.br...d=99&Itemid=150
الخلاصة :
" لوحة مفاتيح " Microsoft رائعة جداً ، وكما ترى .. استطعت إنهاء المقالة والتحدث عن أشياء لها ثقلها دون أن أتوقف .. السر يكمن في لوحة مفاتيح Microsoft ، ولكن التحذير بشأن الصحة الذي يظهر خلف الكيبورد .. يجبرني على أن أتوقف هنا .
المقال : مكتوب بشكل سريع و دون مراجعة علمية ، وهو يفترض أن القارئ " يحب قراءة الجرائد " ، لذلك لا تعتمد عليه كثيراً في بعض النقاط العلمية

 

مقدمة

 

اشتريت قبل يومين " لوحة مفاتيح " Microsoft الأصلية ، الغالية الثمن ( سبعين ريال ) ، وهي متميزة وتثير لديك شهوة الكتابة عن أشياء لا تعرف عنها الكثير ، وهذا المقال من هذه الأشياء.

 

المرحلة الأولى - الحياة بسيطة 

 

قام الحاسوب على مفهوم Turing Machine ، وهو تصوّر جائنا من زميل المهنة Turing لجهاز الكمبيوتر .. خلاصته أن البيانات تنتقل من القرص الصلب Hard-desk إلى الذاكرة ، ومن يقوم بمعالجة تلك البيانات شيء اسمه معالج واختصاره هو CPU .. مرّت ثلاثين سنة على هذه الفكرة والتي أصبحت هي المعتمدة في كل جهاز حاسوب تقريباً في مطلع ثمانينات القرن الماضي .

 

بعد ولادتي بسنتين .. وقع حدثُ هام ( بالإضافة لحدث ظهوري على وجه البسيطة) ، حيث ظهرت مكتبة ( أصبحت قياسية ) ، تحمل اسم OpenGL وذلك في عام 1990 تقريباً . المكتبة الرسومية استفادت لاحقاً من " كونها قياسية " ، وصار كل صانع من صنّاع البطاقات الرسومية Graphics Card ، يعمل implementation خاص به ، يستفيد من قدرات Hardware لتسريع عملية الرسوم . المبرمج في ذلك الوقت وجد أمامه مجموعة من " الدوال " APIs ، التي يستدعيها ليقوم بتغيير حالة متغيرات معينة ، فتقوم " بطاقة الرسوميات " بالاستجابة لهذه التغييرات.. مثال :

 

   1:  
   2:  void display()
   3:  {
   4:  
   5:   // Tell the Graphics Card to clear the color buffer.
   6:   clearTheBuffer()
   7:  
   8:  
   9:   // Load Data Into the main memory
  10:   loadData()
  11:  
  12:  
  13:   // Do Some Math Calculations
  14:   Matrix result = modelMatrix * viewMatrix * projectionMatrix
  15:  
  16:  
  17:   // Tell the Graphics Card to change the alpha state to " Enabled " 
  18:   enableAlphaTesting(1,LessThan)
  19:  
  20:  
  21:   // Draw
  22:   drawMesh(data);
  23:  
  24:  
  25:   disableAlphaTesting()
  26:  
  27:  }

 

 

- لاحظ أن أغلب البيانات ، سنجدها في الذاكرة الرئيسية Main Memory ، حسب نصيحة زميل المهنة Turing .

- لاحظ أن عملية ضرب المصفوفات تحتاج إلى CPU ، وهو المسؤول عنها .

- لاحظ أنك تطلب من البطاقة الرسومية تفعيل " الشفافية " ومن ثم رسم المجسم ومن ثم ايقاف الشفافية حتى لا تتأثر بقية الأجسام .

 

البرامج الرسومية و الألعاب تصيب المعالج بإجهاد كبير ، وعملية نقل البيانات من المعالج إلى الذاكرة الرئيسية إلى البطاقة الرسومية ، تستهلك وقت وجهد ، بل أن النموذج السابق يحمل اسم Fixed-pipeline ، ويعني أن OpenGL كمكتبة رسومية قائمة على أمور ثابتة ومبرمجة مسبقاً ، بحيث تطلب من البطاقة الرسومية تغيير حالة ما .. فيظهر هذا على الشاشة .. فلا تستطيع مثلاً أن تتحكم بالمعادلة المسؤولة عن الشفافية .. فكل ما عليك أن تقوله هو : فعّل أو لا تفعّل .. Enable Or Disable .

 

المرحلة الثانية - GPU

 

بعد 12 سنة من ولادتي ، وتحديداً عندما انتهيت من الصف السادس الابتدائي ، ظهرت أفكار جديدة لعلاج مشاكل البرامج الرسومية و الألعاب ، وتتمحور حول مبدأ أساسي :

لماذا لا نضع معالج خاص + ذاكرة خاصة للبرامج الرسومية المبنية على OpenGL و أشباهها ؟

لماذا لا نسمح للمبرمج بكتابة معادلاته التي يريد تطبيقها على كل بكسل وعلى كل رأس Vertex ؟

بدأت الأفكار تطبخ وتطبخ حتى وصلت للنضوج مع دخولي للمرحلة الثانوية . فظهر أمامنا مفهوم GPU ( عفواً .. ليس مفهوم ، إنما Hardware وهو عبارة عن معالج مركزي خاص للمكتبات الرسومية مثل CG و OpenGL و Direct3D ) .

 

GPU : اختصار لمصطلح Graphics Processing Unit و الذي حصل باختصار ، أن عمليات المعالجة انتقلت من CPU إلى GPU ( طبعاً لا يعني هذا الاستغناء عن CPU ) ، فمثلاً علمية ضرب المصفوفات ، وعملية معالجة كل بكسل ، وعمليات أخرى تجري على وحدة GPU ومابين ذاكرة ومعالج البطاقة الرسومية .. فوصلنا لسرعة وقدرة عالية مع نتائج مبهرة .. وذلك لأنك أمام معالج رسومي عملاق و قوي .

 

المرحلة الثالثة - GPGPU

 

الحسد طبيعة البشر ، والمبرمجين بشر ، فظهر طفيليون على مجال " الألعاب و الرسوميات " ، من أصحاب المحركات الفيزيائية أو برامج المحاكاة العلمية أو من أي مجال آخر عدا برمجة الألعاب و الرسوميات . الطفيليون " المبرمجون " فكروا في الاستفادة من وحد المعالجة الرسومية GPU لتسريع محرّك فيزيائي ( تسريع أنظمة الجزئيات الفيزيائية ، لمحاكاة فيضان المياه مثلاً .. ) ، أو لتسريع خوارزمية مستخدمة في محاكي للأبحاث العلمية . مستفيدين من سرعة العمليات التي تقوم بها GPU .. فبدلاً من أن نركن GPU دون استخدام .. فلماذا لا نستفيد منه في جوانب تطبيقية شتى . مع العلم أنه قد ظهر عائلة جديدة من المعالجات المختصة بالفيزياء باسم PPU .

 

من هنا ظهر مفهوم GPGPU : وهو اختصاراً لـ General Purpose Graphics Processing Unit .. يعني " الغايات العامّة من وحدة المعالجة الرسومية " .. فظهرت مقالات وتطبيقات تستفيد فعلاً من إمكانية GPU ، لم ننتظر طويلاً حتى ظهرت CUDA و OpenCL و مكتبة ثالثة لا أريد أن أعمل لها دعاية دون مقابل :/ .

 

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

 

المرحلة الرابعة - OpenCL و CUDA

 

ظهرت الحاجة لمكتبة قياسية تستفيد من العدد الضخم من الأنوية cores وبالتالي تطبيق مبدأ البرمجة المتوازية ، بل والاستفادة من قدرات GPU الحسابية السريعة و الدقيقة ، حتى لو لم يكن التطبيق رسومي .

لم أنتهي من المرحلة الجامعية إلا و مصنعوا البطاقات الرسومية قد طوّروا من قدرات GPU ، ليخدم قطاعات أخرى ، ولعل خطوة شركة انفيديا في هذا المجال هي الأبرز من حيث تطوير CUDA وهي معمارية ظهرت على يد شركة انفيديا وتعمل على بطاقات انفيديا الرسومية ، و يمكن من خلالها تطوير تطبيقات لا علاقة لها بالرسوميات ( ويمكن استخدامها طبعاً مع التطبيقات الرسومية ) ، وطبعاً يمكن الاستفادة من هذه المعمارية من خلال لغة C ولغات أخرى .

 

ومن ثم ظهرت مكتبة OpenCL من مختبرات Apple والتي أصبحت الآن تحت عهدة Khronos ( نفس الجهة التي تشرف على مواصفات OpenGL ) ، وبالتالي أصبحت مكتبة قياسية يشارك في وضع قياساتها ومن ثم عمل implementation لها ، عدة شركات ضخمة AMD, IBM, Intel, و Nvidia بالاضافة لـ Apple طبعاً .

تتميز OpenCL بقدرتها على العمل على أي قطعة hardware ,التي تسمى Device ، فهي قد تعمل على CPU وتستفيد من ,multi-core CPU .. وقد تعمل على GPU (لو كنت تملك واحداً ) . علماً أن عدد " أنوية " المعالج المركزي CPU قد تصل لثمانية أنوية أو أقل من هذا ( مثل Intel i7 ) .. أما في حالة GPU فأنت أمام عشرات الأنوية التي تتسابق لخدمتك ( قد تصل لمئات ) .

 

OpenCL و CUDA لهما نفس الهدف تقريباً .. ولكن التوجه الآن هو بدعم OpenCL بشكل كامل ، باعتبارها قياسية وستعمل على أكثر من بطاقة رسومية وعلى أكثر من نظام تشغيل ، بل وحتى على أكثر من لغة برمجية .بالتالي أصبحنا بغنى عن التطفل على مبرمجي الرسوميات واستخدام أدواتهم مثل لغة GLSL أو HLSL لاستغلال قوّة GPU في أمور غير رسومية ، بل هناك ما يسمّى بـ kernel في OpenCL وهي لغة خاصة صممّت لهذا الغرض ( مبنية على مواصفات لغة سي ) .

 

 

 

مالذي يمكنك أن تفعله باستخدام OpenCL ؟

OpenCL : هدفها الأساسي هو تسريع تنفيذ الخوارزميات ( معظمها ولكن ليس كلها ) ، فخذ مثلاً :

- لو حاولت إيجاد القيمة المطلقة abs لمجموعة أعداد موجودة في مصفوفة ،

يمكنك الاستفادة من Parallel programming التي تدعمها OpenCL ( البرمجة المتوازية أو المعالجة المتوازية Parallel Processing ) ، لتنفيذ هذه الفكرة ، وبالتالي تنفيذ هذه الخوارزمية على عشرات الأنوية ( Multi-core ) ، بدلاً من معالج واحد .. وبدلاً من البحث عن لغة برمجية مستقلة تدعم مفهوم البرمجة المتوازية ..

 

- يمكن أيضاً أن تتكامل OpenCL مع OpenGL أو Direct3D .. حيث البيانات يمكن تبادلها فيما بينهما ، أي أنه يمكن أن تخبر OpenCL بتغيير قيم مصفوفة بيانات ما .. وستتأثر OpenGL بشكل مباشر دون تدخل منك ، بمجرد أن تطلب من OpenCL ذلك عند إنشاء Context .

 

وهناك مسائل كثيرة ( تخيّل كثير من الخوارزميات فقط ) ،

 

 

ولإزالة اللبس الذي قد يحصل .. أقول :

OpenCL ليست مكتبة رسومية .. فقد تشاهد مثلاً تطبيق رسومي خلاّب تم تسريعه باستخدام OpenCL .. مثل عملية Raytracingالمعروفة ببطئها الشديد في السنوات الماضية ( تنتظر ساعات لترى النتيجة ) ، لذلك عملية الرسم هي من مسؤولية OpenGL ونحوها .. ولكن عملية تسريع الرسوميات ( وتطبيق مفهوم البرمجة المتوازية مثلاً ) يمكن تنفيذه باستخدام OpenCL أو CUDA ..

 

روابط قد تفيدنا :

 

 

 

 

 

 

 

الخلاصة

 

" لوحة مفاتيح " Microsoft رائعة جداً ، وكما ترى .. استطعت إنهاء المقالة والتحدث عن أشياء لها ثقلها دون أن أتوقف .. السر يكمن في لوحة مفاتيح Microsoft ، ولكن التحذير بشأن الصحة الذي يظهر خلف الكيبورد .. يجبرني على أن أتوقف هنا .

 

 

 

المقال : مكتوب بشكل سريع و دون مراجعة علمية ، وهو يفترض أن القارئ " يحب قراءة الجرائد " ، لذلك لا تعتمد عليه كثيراً في بعض النقاط العلمية الدقيقة .

التعليقات (8) -

  • وسام البهنسي

    25/10/2010 04:30:25 م | الرد

    مقالة غاية في اللطافة! أغبطك على موهبتك في التبسيط والطرح الجذاب... أعجبتني جداً فكرة ربط تواريخ الأحداث بالتواريخ الهامة في حياتك الشخصية! Laughing

    شكراً على هذه التدوينة اللطيفة التي علمتني بعض الأمور عن OpenCL..

  • ashemari

    26/10/2010 04:57:28 م | الرد

    شكراً على تعليقك اللطيف أخ وسام ، أسلوب الكتابة بطريقة مختلفة حاولت أن أتعلمه منك ومن الأخ " سلوان الهلالي " ، أحب أسلوبكم في الكتابة كثيراً .. ولا أخفيك ، أني أحاول تقليدكم Smile .

  • d

    14/04/2012 05:46:25 م | الرد

    #include <windows.h>
    #include <GL/glut.h>

    void draw(void)
    {
      glClear(GL_COLOR_BUFFER_BIT);//مسح الشاشة
      glFlush();
    }

    // الدالة الرئيسية
    void main()
    {
    //تحديد حجم النافذة
    glutInitWindowSize(160,160);
    glutInitDisplayMode(GLUT_RGB);
    //انشاء نافذة وتسميتها
    glutCreateWindow("Empty Screen");
    //  استعاء لدالة الرسم
    glutDisplayFunc(draw);
    // لون خلفية النافذة
    glClearColor(1.0, 1.0, 1.0, 0.0);//
    glOrtho(0.0, 100.0, 0.0, 100.0, 0.0, 1.0);
    glutMainLoop();
    }

  • d

    14/04/2012 05:50:46 م | الرد

    void draw(void)
    {
      glClear(GL_COLOR_BUFFER_BIT);/مسح الشاشة
    //حجم النقطة الأولى  
      glPointSize(4);
    // دالة رسم النقطةالاولى                                    
      glBegin(GL_POINTS);
    // لون النقطة الأولى    
      glColor3f(0, 0, 1);
    // موقع النقطة الأولى      
      glVertex2i(40,40);
      glEnd();
    //حجم النقطة الثانية
      glPointSize(10);                                  
      glBegin(GL_POINTS);
    //لون النقطة الثانية        
      glColor3f(0.8, 0.5, 0.0);
    // موقع النقطة الثانية        
      glVertex2i(50,50);
      glEnd();
    // حجم النقطة الثالثة  
      glPointSize(20);                                  
      glBegin(GL_POINTS);
    //لون النقطة الثالثة    
      glColor3f(0.5, 0.0, 0.2);
    // موقع النقطة الثالثة      
      glVertex2i(60,60);  
      glEnd();

    glFlush();
    }

    void main()
    {
      glutInitWindowSize(300,300);
      glutInitDisplayMode(GLUT_RGB);
      glutCreateWindow("Points");
      glutDisplayFunc(draw); //  استعاء لدالة الرسم
      glClearColor(1.0,1.0, 1.0, 0.0);
      glOrtho(0.0, 100.0, 0.0, 100.0, 0.0, 1.0);
      glutMainLoop();
    }

  • d

    14/04/2012 05:53:14 م | الرد

    ---------------------------------------------------------------------------------------
    برنامج يقوم برسم مثلث قبل وبعد الازاحة
    #include <windows.h>
    #include <GL/glut.h>

    void redraw(void)
    {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        //  رسم مثلث باللون الأخضر الغامق
      glColor3ub (0, 102,0);
      glBegin(GL_TRIANGLES);
      glVertex2f(1,1);
      glVertex2f(5,5);
      glVertex2f(9,1);
      glEnd();
      // ازاحة المثلث
      glTranslatef(7,8,0);
      glPushMatrix();  
      // رسم المثلث بلون اخضر فاتح بعد ازاحته
      glColor3ub (0, 204,0);
      glBegin(GL_TRIANGLES);
      glVertex2f(1,1);
      glVertex2f(5,5);
      glVertex2f(9,1);
      glEnd();
      glPopMatrix();
      glFlush();
    }

    void main()
    {
      glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH );
      glutInitWindowPosition(300,300); // دالة لتحديد موقع نافذة الرسم
      glutInitWindowSize(600,600);
      glutCreateWindow("2D Translate");
      glutDisplayFunc(redraw);
      glClearColor(0.95, 0.90, 0.85, 0.0);
      glOrtho(-21.0, 21.0, -21.0, 21.0, -20.0, 20.0);
      glutMainLoop();
    }

  • d

    14/04/2012 05:54:35 م | الرد


    برنامج يقوم برسم مثلث متحرك في اتجاه الإكس الموجب

    #include <windows.h>
    #include <GL/glut.h>

    //قيمة ابتدائية لمكان تحرك الجسم
    float  tx=30;

    void display (void)
    {
      glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

      glPushMatrix();
      
      //  رسم المثلث المتحرك
      glTranslatef(tx,0,0);
      glColor3ub (246, 199, 0);
      glBegin(GL_TRIANGLES);
      glVertex2f(1,1);
      glVertex2f(50,50);
      glVertex2f(90,10);
      glEnd();
      //خطوات تحرك الجسم  للجة اليمنى
      if(tx>=30)
        {
          tx=tx+0.01;
             }
       glPopMatrix();
      glutSwapBuffers();
    }

    void main (int argc, char **argv)
    {
      glutInit (&argc, argv);
      glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
      glutInitWindowSize (900, 900);
      glutInitWindowPosition (100, 100);
      glutCreateWindow ("Translate always");
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(0.0, 160.0, 0.0, 160.0,-160.0,160.0);
      glutDisplayFunc (display);
      glutIdleFunc (display);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      glutMainLoop();
    }

  • d

    14/04/2012 05:56:06 م | الرد

    #include <windows.h>
    #include <GL/glut.h>

    void redraw(void)
    {
      glClear(GL_COLOR_BUFFER_BIT);
      glColor3f(0.0, 0.0, 0.0);
      // x محور
      glBegin(GL_LINES);
      glColor3f (0.0, 0.0, 0.0);
      glVertex2f (19,0);
      glVertex2f (-19,0);
      // y محور
      glVertex2f (0,-19);
      glVertex2f (0,19);
      glEnd();
      // رسم مثلث باللون الأزرق الغامق
      glColor3ub (37, 66, 101);
      glBegin(GL_TRIANGLES);
      glVertex2f(4,3);
      glVertex2f(8,12);
      glVertex2f(12,3);
      glEnd();
      //  دوران الجسم
      glRotatef(180,0,0,0);
      //  رسم الجسم بعد دورانه
      glColor3ub (112, 153,202);
      glBegin(GL_TRIANGLES);
      glVertex2f(4,3);
      glVertex2f(8,12);
      glVertex2f(12,3);
      glEnd();
      glutSwapBuffers();
    }

    void main()
    {
      glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
      glutInitWindowPosition(100,100);
      glutInitWindowSize(800,800);
      glutCreateWindow("2D Rotate1");
      glutDisplayFunc(redraw);
      glClearColor(0.95, 0.90, 0.85, 0.0);
      glOrtho(-21.0, 21.0, -21.0, 21.0, -20.0, 20.0);
      glutMainLoop();
    }

  • d

    14/04/2012 05:57:37 م | الرد

    void redraw(void)
    {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
      // دوال الاضاءة
      glEnable(GL_DEPTH_TEST);
      glEnable(GL_LIGHTING);
      glEnable(GL_LIGHT0);
      glDisable(GL_CULL_FACE);
      glEnable(GL_COLOR_MATERIAL);
      //  رسم ابريق باللون الأخضر الغامق
      glPushMatrix();
      glColor3ub (0, 53,33);
      glRotatef(45,1,0,0);
      glTranslatef(8,6,3);
      glutSolidTeapot(4.5);
      glPopMatrix();
      glFlush();
    }

    void main (int argc, char **argv)
    {
      glutInit (&argc, argv);
      glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH );
      glutInitWindowSize (900, 900);
      glutInitWindowPosition (100, 100);
      glutCreateWindow("3D Rotate");
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glClearColor(1.0, 1.0, 1.0, 0.0);
      glOrtho(-21.0, 21.0, -21.0, 21.0, -20.0, 20.0);
      glutDisplayFunc (redraw);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();  
      glutMainLoop();
    }

أضف تعليقاً

Loading