السلام عليكم ,
المصادر :
http://www.codesampl...rc/oglsrc_4.htm
http://www.opengl.or...ers/discard.php
Color Key مصطلح في برمجة الالعاب (خاصة ال2D ) . الهدف منه هو ( أن تحدد لون موجود في صورة .. يحيث هذا اللون لا يظهر عند عرض الصورة على الشاشة )
مثال ، هذه الصورة :
نحن نريد عرض جميع الالوان الموجودة في الصورة ماعدى اللون الوردي , اللون الوردي هو يحمل القيمة التالية
R:236
G:0
B:140
ثلاث قنوات ( RGB) .
بالتالي , عندما ترسم الصورة على الشاشة ( قم برسم جميع الالوان .. باستثناء اللون الذي يحمل القيمة )
RGB=233 0 140
هذه الفكرة ببساطة . التطبيق باستخدام OpenGL ( وينفع تستخدم هذه الطريقة مع أي مكتبة جرافكس تدعم خاصية مزج الالوان (Blending ).في OpenGL بعد أن يتم تحميل الصورة .. وتحويلها الى اكساء .. يتم عرض كامل الصورة ..( بما فيها اللون الوردي الذي لا نريده ان يظهر ). بالتالي هنا نستخدم الColors Blending .. بحيث نستعين بقناة ألفا ,, وسنشرح الطريقة ..
1- نفرض أن الصورة التي تريد أن تحملها هي من نسق RGBA أي تحمل قناة ألفا ..
أو لنفرض أنك تستخدم المكتبة DevIL ( التي توفر أمر يقوم بتحويل الصورة الى RGBA . ) .
هنا الامر سهل .. الصورة تحمل قناة ألفا ... كل ما نحتاج أن نقوم به هو التالي :
1- حمل الصورة .. واحصل على البيانات التي يحتاجها OpenGL ..وهي :
1- طول وعرض الصورة .
2-عدد قنوات الصورة ونوعها (RGB - RGBA الخ ) .
3- بيانات الصورة ( أي الالوان نفسها التي تكون الصورة ).
عندئذ تقوم بشيء شبيه بالتالي
int r= 236 , g = 0 , b=140
Image image = LoadRGBAImage ( " my image.bmp");
int size = image.width * image.height* 4; // 4 means 4 channels ( R G B A )
unsigned char *newData = new unsigned char[size];
data = image.data;
for(int i=0;i<size;i+=4)
{
newData= image.data;
neData[i+1]=image.data[i+1];
newData[i+2]=image.data[i+2];
if( newData== r &&
newData[i+1] == g &&
newData[i+2] == b)
newData[i+3]== 0
else
newData[i+3] == 255
}
glCreaetTexture( image.width,image.height,RGBA , newData )
/--------------------------------------------
draw
/--------------------------------------------الشرح :
حملنا صورة .. وحصلنا على البيانات المطلوبة .
وحصلنا على حجم الصورة ( أو لنقل على حجم بيانات الصورة) وليس الحجم الفعلي .
المقصود بالحجم هنا هو عدد الالوان .
فلو كانت الصورة تتكون من 14 لون .. .. من نوع RGBA
بالتالي هنا نحتاج الى بايت واحد لكل قناة .. بالتالي نحتاج الى 4بايت لكل لون بالتالي نحتاج الى 4 * 14 = 56 بايت لجميع الالوان الاربع عشر .
راجع فهرس المنتدى للتعرف أكثر على الصور .
الان جميع الالوان موجود في المتغير newData
اللون الاول نحصل عليه كالتالي :
newData[0] = R , newData[1]=G ,newData[2]=B,newData[3]=A
أما هذه الاسطر :
if( newData== r && newData[i+1] == g && newData[i+2] == B)
فتقوم بمقارنة اللون الاول للصورة مع اللون الذي حددناه ( اللون الوردي ) فاذا كان اللون هو لون وردي فاننا نجعل قيمة alpha صفر .. أي ان اللون لن يظهر
والا اجعل الالفا = 255 وهذا يعني ان اللون سيظهر حتى ان كان وردي.
ثم أنشأنا الاكساء الذي نريده باالعتماد على الnewData الجديدة التي أنشاناها ..
بقي شيء واحد .. يجب تفعيل خاصية مزج الالوان في OpenGL لتقوم OpenGL بتجاهل اللون الذي يحمل قيمة alpha=0 ..
عن طريق هذا السطر :
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
2-اما لو لم تكن الصورة هي RGBA فلامشكلة ابدا .. تستطيع ان تحول الصورة بنفسك إلى RGBA
بشكل شيبه التالي
unsigned char* data= new unsignedchar[sizeOfImage];
for(int i=0;i<size;i+=4)
{
data=image.data;
data[i+1]=image.data[i+1];
data[i+2]=image.data[i+2];
data[i+3]=255;
}أو اجعل للقناة ألفا أي قيمة تحب ,, المهم ان تتغير بعد ذلك ..
وضعت عدة أمثلة للتعامل مع مختلف الحالات . .
1- مثال على صورة من نوع RGB نحولها الى RGBA ونطبق عليها الKey Color
هذا المثال يحتاج الى مكتبة اسمها glaux وهي تأتي بشكل تلقائي مع مترجمات مايكروسوفت
2- مثال على صورة لا نعلم نوعها .. هل هي RGB او RGBA .. ولكننا في كل الاحوال نحولها الى RGBA اذا لزم الامر .
ثم نطبق عليها ال KeyColor
هذا المثال مبني على المكتبة المتميزة DevIL ..
يجب عليك تحميل المكتبة.. وتثبيتها .. قبل ان تنفذ الكود .
