8.9 مكتبة SDL لبرمجة الألعاب | كتاب لينكس الشامل | >> |
هي اختصار لSimple DirectMedia Layer وهي مكتبة متعددة المنصات
تعمل في لينكس(إكس11) وويندوز وغيرها ، بإمكانك عمل
برامج (خاصة ألعاب وبرامج متعددة الوسائط) دون الحاجة
لإعادة كتابة البرنامج في كل نظام
كما في allegro و glut وهي أصغر بكثير من Allegro
ولكنها توفر مزايا أقل؛ فهي(SDL) توفر
تحميل صور وصوت والتعامل مع الزمن وتعدد خيوط المعالجة
والتعامل مع الأحداث (لوحة المفاتيح و Joystick)
إلا أنها على عكس allegro لا توفر وظائف لرسم الأشكال
مثل الدوائر والخطوط و المضلعات ثنائية وثلاثية الأبعاد
وتحويل الصور من عمق لوني إلى آخر وخوزرميات تسريع
وجداول بحث عن الألوان ومزجها والشفافية وجداول جيوب ...
إلا أن SDL تسمح لك (كما allegor) بالوصول المباشر لذاكرة
الصورة والكتابة فيها وعمل الوظائف التي تقوم بذلك
بنفسك أو استعمال مكتبة OpenGL.
انظر الوثائق التي تأتي مع حزمة التطوير
/usr/share/doc/SDL-devel-1.2.4/html/
لا يوجد الكثير لتتعلمه، قم بالعمليات الاستهلالية باستدعاء
SDL_Init
مع تمرير الأنظمة الفرعية التي تريد
استعمالها وهي في العادة
SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_TIMER
إذا أعطت الوظيفة قيمة سالبة فإن هناك شيئاً ما خطأ.
بعدها احجز شاشة بتمرير الطول والعرض والعمق اللوني(بالبت) وخيارات أخرى
للوظيفة SDL_SetVideoMode
والتي تعيد مؤشر من نوع
SDL_Surface
أما الخيارات التي يمكنك استعمالها فهي
العلامة flag | معناها |
---|---|
SDL_SWSURFACE | استعمال الذاكرة العادية |
SDL_HWSURFACE | استعمال ذاكرة الشاشة المسرعة، أضف الخيار
SDL_DOUBLEBUF للحصول على شاشة ثنائية |
SDL_FULLSCREEN | شاشة كاملة |
SDL_RESIZABLE | نافذة قابلة للتحجيم |
SDL_HWPALETTE | تطابق جدول الألوان الفعلي مع SDL فقط في طور 8بت |
SDL_OPENGL | شاشة OpenGL |
SDL_OPENGLBLIT | شاشة OpenGL إضافة للعمليات ثنائية الأبعاد العادية |
SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN
فإذا لم تنجح SDL_SWSURFACE
مع وضع متغير يوضح أيها نجح
لأن عملية تحديث الشاشة تختلف في كل منها، ففي SDL_SWSURFACE
نستدع
SDL_UpdateRect(screen, 0, 0, 0, 0)
طبعاً يمكنك أن تحدث جزء صغير من الشاشة بتعديل قيم
x
و y
و w
و h
كما في
SDL_UpdateRect(screen,x,y,w,h)
،
أما في الشاشة المسرعة في الحالة الأولى نستعمل
SDL_Flip(screen)
#include "SDL.h" #include <stdio.h> /* for exit() */ int main() { SDL_Surface *screen; printf("Initializing SDL.\n"); if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_TIMER)==-1)) { printf("Could not initialize SDL: %s.\n", SDL_GetError()); exit(-1); } printf("SDL initialized.\n"); screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set 640x480x16 video mode: %s\n", SDL_GetError()); exit(1); } /* this to exit */ SDL_Quit( ); return 0; }
SDL_Quit()
ليقوم
بتحرير الشاشة والذاكرة وكرت الصوت التي حجزها.
لتصنيف البرنامج استعمال الأداة sdl-config كما يلي
gcc MYFILE.C -o MYFILE `sdl-config --libs`
لتقوم بالرسم مباشرة على الشاشة(أو أي صورة أخرى) نستعمل المؤشر
pixels الذي هو جزء من SDL_Surface الذي تعيده وظيفة حجز الشاشة
وذلك بوضع قيمة اللون التي تحصل عليها من
SDL_MapRGB(bpp,r,g,b)
حيث r و g و b
هي قيم بين 0 و 255 تحدد الأحمر والأخضر والأزرق و bpp هي BitPerPixel
نضع هذه القيمة على بعد إزاحة معينة عن المؤشر pixels
تعتمد هذه الإزاحة على كم بايت في البيكسل وكم بايت في السطر
offset=(y*BytePerLine)+(x*BytePerPixel)
ويمكن الحصول على كم بايت في البيكسل بقسمة BitPerPixel على ثمانية وتقريب الناتج
لأقل رقم صحيح أكبر من أو يساوي الناتج Bpp=ceil(bpp)
.
أما كم بايت في السطر فنحصل عليه من ضرب القيمة السابقة في عرض
السطر الواحد أو بأخذها مباشرة من pitch .
ويجب الإنتباه إلى إغلاق الصورة قبل الوصول المباشر إليها
SDL_LockSurface()
وإزالة الإغلاق بعد الإنتهاء منها.
بإمكانك رسم مستطيل باستعمال
SDL_FillRect(surface,rect,color);
حيث rect
هو مؤشر إلى SDL_Rect
مع وضع قيم
x
و y
و w
و h
المناسبة.
أما رسم الصور فعليك أولاً تحميلها بالوظيفة
SDL_LoadBMP
ثم نقلها/رسمها
فوق صورة أخرى أو الشاشة بSDL_BlitSurface
مثلاً SDL_BlitSurface(image, NULL, surface, NULL)
حيث image
هي الصورة المصدر و surfce
هي الهدف
ويمنك تحديد مكان رسمها بوضع مؤشر إلى SDL_Rect
مكان NULL
الثانية،
فتؤخذ منه قيم x و y فقط ولتحديد الجزء الذي سيرسم من الصورة المصدر ضع
SDL_Rect
مكان NULL
الأولى.
تقوم هذه الوظيفة بعد الرسم بإعادة ضبط SDL_Rect
الثانية الخاصة بالهدف لتكون القيم التي تم استعمالها فعلياً
مثلاً عند رسم صورة جزء منها يخرج من الزاوية اليمنى السفلى
فإن عرض وطول الصورة التي ترسم فعلياً يكون أقل.
/* * sdltut.c: SDL tutorial by Moayyad Al-Sadi <alsadi[at]gmail.com> */ #include "SDL.h" #include <stdio.h> #include <math.h> /* this function draw some scratch to sraface */ void scratch(SDL_Surface *surface) { int x=100,y=100; char *file_name="./bmp/mybmp.bmp"; SDL_Surface image; Uint8 *ptr; /* bpp=BitPerPixel , Bpp=BytePerPexil*/ int bpp=surface->format->BitsPerPixel,Bpp=ceil(bpp/8.0); Uint32 c1=SDL_MapRGB(bpp,64,64,128); Uint32 c2=SDL_MapRGB(bpp,128,64,64); SDL_Rect r; /* load BMP file */ image = SDL_LoadBMP(file_name); if (image == NULL) { fprintf(stderr, "Couldn't load %s: %s\n", file_name, SDL_GetError()); return; } SDL_BlitSurface(image, NULL, surface, NULL); SDL_UpdateRect(surface, 0, 0, 0, 0); SDL_FreeSurface(image); /* draw rectangle */ r.x=10; r.y=10; r.w=200; r.h=200; SDL_FillRect(surface,&r,c1); SDL_UpdateRect(surface, 0, 0, 0, 0); /* direct access draw line */ SDL_LockSurface(surface); ptr = (Uint8 *)surface->pixels + y * surface->pitch + x * Bpp; switch(bpp) { case 1: for (;x<300;++x) *p++ = c2; break; case 2: for (;x<300;++x) *(Uint16 *)p++ = c2; break; case 4: for (;x<300;++x) *(Uint32 *)p++ = c2; break; } SDL_UnlockSurface(surface); } int main() { SDL_Surface *screen; SDL_Event event; printf("Initializing SDL.\n"); if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_TIMER)==-1)) { printf("Could not initialize SDL: %s.\n", SDL_GetError()); exit(-1); } printf("SDL initialized.\n"); screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set 640x480x16 video mode: %s\n", SDL_GetError()); exit(1); } /* draw scratch on screen */ scratch(screen); /* wait to exit */ while(1) { while( SDL_PollEvent( &event ) ) { switch( event.type ) { case SDL_KEYDOWN: if (event.key.keysym.sym==SDLK_ESCAPE) { SDL_Quit( ); exit(0); } break; case SDL_QUIT: SDL_Quit( ); exit(0); break; } } /* DO SOME THINGS HERE like move the scratch */ /* ... do it your self :-( */ } /* never come here */ return 0; }
PNM
و XPM
و XCF
و
PCX
و GIF
و JPG
و
TIF
و PNG
و LBM
إضافة إلى BPM
باستعمال الوظيفة IMG_load(file_name)
الموجودة في إضفة لهذه المكتبة اسمها SDL_image
ولا تنس إضافة السطر #include"SDL_image"
في برنامجك.
عد إلى فصل openGL واتبع نفس طريقة GLUT مع استبدال وظائف GLUT ب SDL. وهي كما يلي
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 6 ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); screen = SDL_SetVideoMode(640, 480, 16, SDL_OPENGL | SDL_FULLSCREEN); /* Draw things here ,the GL-way ... */ glViewport( 0, 0, 640, 480 ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glBegin( GL_TRIANGLE ); /* or what ever see opengl.html */ glEnd( ); /* update screen */ SDL_GL_SwapBuffers();
<< السابق | كتاب لينكس الشامل | التالي >> |