Írjunk egy Kép osztályt: Ez az osztály az SDL_Surface-eket segít majd nekünk kezelni. A függvények pszeudokódja az UML diagram alatt található. Amit fontos tudni, hogy egy SDL_Surface sok formátumot tud kezelni. (Ezek elérhetőek az SDL_pixels.h-ban.) Mi a kép osztályt úgy fogjuk megírni, hogy alapból csak az RGBA8888 formátumot tudja kezelni. (SDL_PIXELFORMAT_RGBA8888 enum az SDL_pixels.h-ban.) Ez azt jelenti, hogy minden pixel 1 byte-os, és egy pixel 4 színből áll, r(red) g(green) b(blue) a(alpha) sorrendben. (Pontosan ezért van a Color osztályban to_key, és form_key függvény.) Szóval a kép adatai Uint8 tömbként: r0, g0, b0, a0, r1, g1, b1, a1, ... Ezt egy egy dimenziós tömbként kell tuni kezelni. Erre a képlet: "x * _surface->w + y" |---------------------------------------------------------------------------------------| | class Image | |---------------------------------------------------------------------------------------| | + void create(const Uint32 flags, const int width, const int height); | | | | + void enable_transparent_color(const Color &color); | | + void disable_transparent_color(); | | + bool has_transparent_color(); | | + Color get_transparent_color(); | | | | + Color get_color_mod(); | | + void set_color_mod(const Color &color); | | | | + Color get_alpha_mod(); | | + void set_alpha_mod(const Uint8 alpha); | | | | + SDL_BlendMode get_blend_mode(); | | + void set_blend_mode(const SDL_BlendMode mode); | | | | + Rect2 get_clip_rect(); | | + void set_clip_rect(const Rect2 &rect); | | | | + void duplicate(Image *into); | | | | + void fill_rect(const Rect2 &rect, const Color &color); | | + void fill_rects(const Vector &rects, const Color &color); | | + void set_pixel(const int x, const int y, const Color &color); | | + Color get_pixel(const int x, const int y); | | | | + void blit_surface(const Image &source, const Rect2 &srcrect, const Rect2 &dstrect); | | | | + void lock(); | -> a pixelek módosításához le kell zárni a surface-t, | + void unlock(); | -> majd fel kell oldani | | | + void free(); | | | | + void load_bmp(const String &file_name); | | + void save_bmp(const String &file_name); | | | | + Uint32 get_width() const; | | + Uint32 get_height() const; | | | | + SDL_Surface *get_surface(); | | | | + Image(); | | + Image(const String &file_name); | | + virtual ~Image(); | | | | - SDL_Surface *_surface; | |---------------------------------------------------------------------------------------| ------------------------------------------------------------------------------------------ create: if (_surface): free(); //SDL_PIXELFORMAT_RGBA8888 SDL_pixels.h ból SDL_CreateRGBSurfaceWithFormat(flags, width, height, 32, SDL_PIXELFORMAT_RGBA8888); ------------------------------------------------------------------------------------------ enable_transparent_color: if (!SDL_SetColorKey(_surface, 1, color.to_key())): printf("enable_transparent_color error.\n"); ------------------------------------------------------------------------------------------ disable_transparent_color: if (!SDL_SetColorKey(_surface, 0, 0)): printf("disable_transparent_color error.\n"); ------------------------------------------------------------------------------------------ has_transparent_color: return SDL_HasColorKey(_surface); ------------------------------------------------------------------------------------------ get_transparent_color: uint32_t key; SDL_GetColorKey(_surface, &key); return Color(key); ------------------------------------------------------------------------------------------ get_color_mod: Uint8 r; Uint8 g; Uint8 b; SDL_GetSurfaceColorMod(_surface, &r, &g, &b); return Color(r, g, b); ------------------------------------------------------------------------------------------ set_color_mod: SDL_SetSurfaceColorMod(_surface, color.r, color.g, color.b); ------------------------------------------------------------------------------------------ get_alpha_mod: Uint8 a; SDL_GetSurfaceAlphaMod(_surface, &a); return a; ------------------------------------------------------------------------------------------ set_alpha_mod: SDL_SetSurfaceAlphaMod(_surface, alpha); ------------------------------------------------------------------------------------------ get_blend_mode: SDL_BlendMode mode; SDL_GetSurfaceBlendMode(_surface, &mode); return mode; ------------------------------------------------------------------------------------------ set_blend_mode: SDL_SetSurfaceBlendMode(_surface, mode); ------------------------------------------------------------------------------------------ get_clip_rect: SDL_Rect r; SDL_GetClipRect(_surface, &r); Rect2 rect; rect.x = r.x; rect.y = r.y; rect.w = r.w; rect.h = r.h; return rect; ------------------------------------------------------------------------------------------ set_clip_rect: SDL_Rect r; r.x = rect.x; r.y = rect.y; r.w = rect.w; r.h = rect.h; SDL_SetClipRect(_surface, &r); ------------------------------------------------------------------------------------------ duplicate: if (into == nullptr): return; into->_surface = SDL_DuplicateSurface(_surface); ------------------------------------------------------------------------------------------ fill_rect: SDL_Rect r; r.x = rect.x; r.y = rect.y; r.w = rect.w; r.h = rect.h; SDL_FillRect(_surface, &r, color.to_key()); ------------------------------------------------------------------------------------------ fill_rects: SDL_Rect *r = new SDL_Rect[rects.size()]; for (int i = 0; i < rects.size(); ++i): r[i].x = rects[i].x; r[i].y = rects[i].y; r[i].w = rects[i].w; r[i].h = rects[i].h; SDL_FillRects(_surface, r, rects.size(), color.to_key()); delete[] r; ------------------------------------------------------------------------------------------ set_pixel: if (_surface == nullptr): return; Uint32 *p = reinterpret_cast(_surface->pixels); p[x * _surface->w + y] = color.to_key(); Megj.: (lehetne Uint8-á is castolni, akkor vissza lehetne szedni egyesével a pixelek értékeit, nyilván ekkor az indexet-et meg kell szorozni 4-el. -> mivel 1 intben 4db byte van.) (Uint8, és uint8_t, Uint32 és uint32_t ugyan az, csak az egyik az /ban van, a másik az sdl/ben.) ------------------------------------------------------------------------------------------ get_pixel: if (_surface == nullptr): return Color(); Uint32 *p = reinterpret_cast(_surface->pixels); return Color(p[x * _surface->w + y]); set_pixel megjegyzése ide is érvényes. ------------------------------------------------------------------------------------------ blit_surface: SDL_Rect sr; sr.x = srcrect.x; sr.y = srcrect.y; sr.w = srcrect.w; sr.h = srcrect.h; SDL_Rect dr; dr.x = dstrect.x; dr.y = dstrect.y; dr.w = dstrect.w; dr.h = dstrect.h; SDL_BlitSurface(source._surface, &sr, _surface, &dr); ------------------------------------------------------------------------------------------ lock: SDL_LockSurface(_surface); ------------------------------------------------------------------------------------------ unlock: SDL_UnlockSurface(_surface); ------------------------------------------------------------------------------------------ free: SDL_FreeSurface(_surface); _surface = nullptr; Megj.: Deallokálja a surface-t. Azért nem a destruktor csinálja ezt, mert közben is tudni kell surface-eket deallokálni. Pl load_bmp(), etc ------------------------------------------------------------------------------------------ load_bmp: if (_surface != nullptr): free(); _surface = SDL_LoadBMP(file_name.c_str()); if (_surface != nullptr && _surface->format->format != SDL_PIXELFORMAT_RGBA8888): //Nem ARGB8888 as formátum, konvertáljuk át SDL_Surface *n = SDL_ConvertSurfaceFormat(_surface, SDL_PIXELFORMAT_RGBA8888, 0); free(); _surface = n; ------------------------------------------------------------------------------------------ save_bmp: SDL_SaveBMP(_surface, file_name.c_str()); ------------------------------------------------------------------------------------------ get_width: if (_surface == nullptr): return 0; return _surface->w; ------------------------------------------------------------------------------------------ get_height: if (_surface == nullptr): return 0; return _surface->h; ------------------------------------------------------------------------------------------ get_surface: return _surface; ------------------------------------------------------------------------------------------ Image(): _surface = nullptr; ------------------------------------------------------------------------------------------ Image(const String &file_name): _surface = nullptr; load_bmp(file_name); ------------------------------------------------------------------------------------------ ~Image: free(); ------------------------------------------------------------------------------------------