السلام عليكم و رحمة الله لعل هناك سؤالا ملحا يدور في أذهان الكثيرين, ألا و هو كيف يقوم الحاسوب بالرسم على الشاشة؟ أغلب المبتدئين في السي و السي بلص بلص يبدأون عادة مع برامج الكونسول (الشاشة السوداء الشبيهة بالدوز DOS), و بالنسبة لهم فكل ما يستطيعون فعله على الشاشة هو كتابة الحروف, و لكنهم لا يتعاملون مع الشاشة ابدا على اساس انها شي تستطيع ان ترسم عليه ما تشاء! لننظر اولا الى الشاشة نفسها, كيف تعمل؟ و كيف تظهر الصور عليها؟ طبعا لن نشرح تفاصيل عمل الشاشة كجهاز, لأن ما يهمنا هو طريقة عملها من وجهة نظر البرنامج. الشاشة عبارة عن مساحة مستطيلة, مكونة من نقاط, كل نقطة تسمى pixel, و الصورة المرسومة على الشاشة مكونة من هذه النقاط, فيمكننا ان نتخيل الشاشة و كأنها جدول كبير, يتكون من عدة خلايا (هي النقاط), و تتكون الصورة اللتي نراها عليها عن طريق ملئ كل خلية (نقطة) باللون المناسب. طيب, كيف نقوم بوضع هذه الألوان؟ او بمعنى ادق, كيف نقوم بتلوين النقاط pixels؟ و سؤال آخر, كيف نقوم بتغيير الصورة على الشاشة؟ بمعنى اننا نعرف ان الشاشة مكونة من مجموعة نقاط, و لكننا نلاحظ ان صورة الشاشة تتغير باستمرار, فهي ليست صورة جامدة! بل فيها حركة و animation, فكيف نقوم بتغيير هذه الصورة باستمرار؟ هنا نأتي الى نقطة مهمة, و هي محور الاجابة على هذين السؤالين. من أين تأخذ الشاشة الوان الـ pixels؟ كيف تعرف ما هو اللون اللذي يجب ان ياخذه كل بكسل؟ الجواب و ببساطة, ان هناك مكان معين في الذاكرة يحتوي buffer او مصفوفة طويلة من الارقام, كل رقم يمثل لون معين, و هذه الألوان هي الوان النقاط اللتي تكون الشاشة. هنا يوجد سؤالين: - كيف يتم استخدام الارقام للتعبير عن الألوان؟ - كيف يتم تحديد لون نقطة معينة من هذا الـ buffer؟ أولا: - كيف يتم استخدام الارقام للتعبير عن الألوان؟ المسألة بسيطة .. و هناك عدة طرق لعمل ذلك .. و لكن ابسط طريقة هي استخدام ثلاث أرقام للون: لون يمثل درجة الحمرة (بضم الحاء و سكون الميم), و لون يمثل درجة الخضرة, و لون يمثل درجة الزرقة. فكما نعلم, جميع الالوان يمكن تشكيلها عن طريق مزج هذه الألوان الأساسية بدرجات مختلفة, مثلا, اللون الأصفر يمكن الحصول عليه عن طريق مزج الأخضر و الازرق! تذكرو اننا هناك نتكلم عن الوان الضوء, و خصائص مزج الالوان هنا مختلفة قليلا عن مزج الألوان على الورق, على كل حال, لا اريد تحويل المسألة الى درس عن الألوان! قلنا اننا نستخدم ثلاثة ارقام لتحديد درجات الحمرة و الزرقة و الخضرة. مثلا, الرقم اللذي يحدد الحمرة, لو كان 0, فلن يكون هناك اي لون أحمر, اما لو كان 255 فسيكون اقصى درجات الحمرة! و لو كان مثلا 100, فسيكون احمر بدرجة معقولة .. يعني ..و نفس الشي لبقية الألوان! فلو اردنا التعبير عن لون معين بهذه الأرقام الثلاثة: 100, 30, 70 و لو فرضنا ان اول لون هو مقدار الحمرة, و الثاني هو مقدار الخضرة, و الثالث هو مقدار الزرقة, فإن هذا اللون هو مزيج من حمرة بمقدار 100, مع خضرة بمقدار 30, و زرقة بمقدار 70 افضل طريقة لفهم العملية هي الذهاب الى فوتوشوب و قم بتحريك المؤشرات على الـ R (احمر) و الـ G (اخضر) و الـ B (ازرق) و انظر كيف يتم مزج الألوان!! لماذا نستخدم الارقام من 0 الى 255 بالذات؟ لأننا نستخدام byte واحد من اجل تخرين الرقم .. و البايت الواحد لا يستطيع تخزين قيمة اكبر من 255! فإذا, لتخزين لون معين على شكل رقم, نحتاج الى 3 بايتات على الأقل! لتخزين الألوان الثلاثة RGB على فكرة, RGB تعني red green blue و لكننا لا نستخدم 3 بايتات لتخزين الرقم .. بل اربعة! و البايت الرابع عادة يكون مهملا! لماذا؟ لان الاجهزة لا تحب التعامل مع 24 بت, بل مع 32 بت! لماذا؟ اشياء معقدة ليس لها علاقة بموضوعنا! إذا, نستخدم 4 بايتات لتخزين لون واحد, حيث يتكون هذا اللون من 3 بتات لتحديد قيم RGB و البايت الرابع من أجل لا شيء (سد فراغ)!! الـ buffer هو عبارة عن سلسلة طويلة من البايتات bytes, كل اربع بايتات على حدة تشكل لونا معينا, لنقل ان اول بايت هو R و ثاني بايت هو G و ثالث بايت هو B, و الرابع هو لسد الفراغ .. إذا, لو كان هناك buffer معرف بهذا الشكل (على فرض ان هناك نوع اسمه byte):
byte buffer[8];buffer[0] = 100; //Rbuffer[1] = 200; //Gbuffer[2] = 40; //Bbuffer[3] = 12; // ignore ..buffer[4] = 134; //Rbuffer[5] = 12; //Gbuffer[6] = 217; //Bbuffer[7] = 103; // ignore ..
i = x + (y-1) * w
//change pixel at 3,4 to be redscreenBuffer[84] = 255; //RscreenBuffer[85] = 0; //GscreenBuffer[86] = 0; //BscreenBuffer[87] = 0; //ignore .. we don't really need to change this
i = x + y * w