diff --git a/15_sdl_color.txt b/15_sdl_color.txt index aa4b60b..7663631 100644 --- a/15_sdl_color.txt +++ b/15_sdl_color.txt @@ -20,62 +20,88 @@ Megj.: Csak a legszükségesebb dolgokat raktam bele, nyugodtan egészítsétek | + uint8_t a; | |--------------------------------------------------------------------------| -uint32_t Color::to_key() const { + +--------------------------------------------------------------------------------------------------------------------------- +--------------------------------------------------------------------------------------------------------------------------- + +to_key: uint32_t val = 0; - //<< = left shift int típusoknál -> azaz az intek bitjeit eltolja eggyel balra: - //pl.: 001010101 ből lesz: 010101010, aztán 101010100, aztán 010101000 etc - - //az r az uint8_t, azaz egy 8 bites int (unsigned byte típus pl java/c#-ban) - //tehát alakítsuk át 32 bites uint-é: static_cast(r) - //Ez az új c++-os castolás, lehetne így is: (uint32_t) r - //De, nem ajánlják már, mert ez 4-5 ilyen static_cast, dynamic_cast etc függvényt - //próbál végig, megadott sorrendben, és csak kiírtam a megfelelőt expliciten. - - //static_cast(r) << 24: (8db 0) (8db 0) (8db 0) (r száma) Ez lessz: (r száma) (8db 0) (8db 0) (8db 0) - //static_cast(g) << 24: (8db 0) (8db 0) (8db 0) (g száma) Ez lessz: (8db 0) (g száma) (8db 0) (8db 0) - //static_cast(b) << 24: (8db 0) (8db 0) (8db 0) (b száma) Ez lessz: (8db 0) (8db 0) (b száma) (8db 0) - //static_cast(a) << 24: (8db 0) (8db 0) (8db 0) (a száma) Ez lessz: (8db 0) (8db 0) (8db 0) (a száma) - - //| a bináris vagy -> a számok birtjeit össze bináris vagyolja -> azaz ahol valaho 1 van, ott az eredmény be egy lesz: 00100 | 00010 -> 00110 - //|= -> bináris vagy egyenlő - val |= static_cast(r) << 24; val |= static_cast(g) << 16; val |= static_cast(b) << 8; val |= static_cast(a) << 0; - //azaz a végeredmény: - //1 uint32t, aminek a bitjei: (r száma) (g száma) (b száma) (a száma) - return val; -} -void Color::from_key(const uint32_t key) { - //A to_key függvény megfordítása. +--------------------------------------------------------------------------------------------------------------------------- - //& itt a bináris és. - //azok a bitek lesznek 1ek, amik mindkét operandusba 1-ek: 001010 & 111110 -> 001010 +Nézzük meg, hogy itt mi is történik: - //A 16-os számrendszerbeli számokat 0x formában lehet megadni. +<< = left shift int típusoknál -> azaz az intek bitjeit eltolja eggyel balra: +pl.: 001010101 ből lesz: 010101010, aztán 101010100, aztán 010101000 etc - //Azért használtam 16os számrendszerbeli számokat, mert itt sokkal szemléletesebbek. - //Ugyanis-> 0xF = 1111 - //Azaz minden F 4db 1es bitet jelöl. - //Így már biztosan látszik, hogy mit csinálunk +az r az uint8_t, azaz egy 8 bites int (unsigned byte típus pl java/c#-ban) +tehát alakítsuk át 32 bites uint-é: static_cast(r) +Ez az új c++-os castolás, lehetne így is: (uint32_t) r +De, nem ajánlják már, mert ez 4-5 ilyen static_cast, dynamic_cast etc függvényt +próbál végig, megadott sorrendben, és csak kiírtam a megfelelőt expliciten. - //key & 0xFF000000 kiszedjük a legelől levő 8 bitet (Minden más bit biztosan 0 lesz.), etc +static_cast(r) << 24: (8db 0) (8db 0) (8db 0) (r száma) Ez lessz: (r száma) (8db 0) (8db 0) (8db 0) +static_cast(g) << 16: (8db 0) (8db 0) (8db 0) (g száma) Ez lessz: (8db 0) (g száma) (8db 0) (8db 0) +static_cast(b) << 8: (8db 0) (8db 0) (8db 0) (b száma) Ez lessz: (8db 0) (8db 0) (b száma) (8db 0) +static_cast(a) << ö: (8db 0) (8db 0) (8db 0) (a száma) Ez lessz: (8db 0) (8db 0) (8db 0) (a száma) + +| a bináris vagy -> a számok birtjeit össze bináris vagyolja -> azaz ahol valaho 1 van, ott az eredmény be egy lesz: 00100 | 00010 -> 00110 +|= -> bináris vagy egyenlő + +A kód: + val |= static_cast(r) << 24; + val |= static_cast(g) << 16; + val |= static_cast(b) << 8; + val |= static_cast(a) << 0; + +szóval a végeredmény: + 8bit 8bit 8bit 8bit +1 uint32t (uint32 = 32 bites előjel nélküli int -> 4x 8bit), aminek a bitjei: (r száma) (g száma) (b száma) (a száma) + +--------------------------------------------------------------------------------------------------------------------------- +--------------------------------------------------------------------------------------------------------------------------- + +from_key: r = (key & 0xFF000000) >> 24; g = (key & 0x00FF0000) >> 16; b = (key & 0x0000FF00) >> 8; a = (key & 0x000000FF) >> 0; - //>> az itt a right shift, ugyan az mint a left shift, csak itt a biteket jobbra mozgatjuk - - //Nyilván, egyéb módon is meg lehet csinálni ezt a függvényt. - //pl csak right shiftelgetni, és castolni uint8_t-vé az eredményt, etc. - //Azért cisnáltam így, mert szerintem ezt a módszert a leghasznosabb látni hosszú távon. - //Pl. ugyan így lehet hálózati csomagokat méretre optimalizálni. -} +--------------------------------------------------------------------------------------------------------------------------- + +A to_key függvény megfordítása. + +& itt a bináris és. +azok a bitek lesznek 1ek, amik mindkét operandusba 1-ek: 001010 & 111110 -> 001010 + +A 16-os számrendszerbeli számokat 0x formában lehet megadni. + +Azért használtam 16os számrendszerbeli számokat, mert itt sokkal szemléletesebbek. +Ugyanis-> 0xF = 1111 +Azaz minden F 4db 1es bitet jelöl. +Így már biztosan látszik, hogy mit csinálunk + +key & 0xFF000000 kiszedjük a legelől levő 8 bitet (Minden más bit biztosan 0 lesz.), etc + +A kód: + r = (key & 0xFF000000) >> 24; + g = (key & 0x00FF0000) >> 16; + b = (key & 0x0000FF00) >> 8; + a = (key & 0x000000FF) >> 0; + +>> az itt a right shift, ugyan az mint a left shift, csak itt a biteket jobbra mozgatjuk + +Nyilván, egyéb módon is meg lehet csinálni ezt a függvényt. +pl csak right shiftelgetni, és castolni uint8_t-vé az eredményt, etc. + +Azért cisnáltam így, mert szerintem ezt a módszert a leghasznosabb látni hosszú távon. +Pl. ugyan így lehet hálózati csomagokat méretre optimalizálni. diff --git a/16_sdl_image.txt b/16_sdl_image.txt index 908a431..abea94f 100644 --- a/16_sdl_image.txt +++ b/16_sdl_image.txt @@ -1,4 +1,26 @@ +Í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" |---------------------------------------------------------------------------------------| @@ -32,8 +54,8 @@ | | | + void blit_surface(const Image &source, const Rect2 &srcrect, const Rect2 &dstrect); | | | -| + void lock(); | -| + void unlock(); | +| + void lock(); | -> a pixelek módosításához le kell zárni a surface-t, +| + void unlock(); | -> majd fel kell oldani | | | + void free(); | | | @@ -52,40 +74,45 @@ | - SDL_Surface *_surface; | |---------------------------------------------------------------------------------------| +------------------------------------------------------------------------------------------ -void Image::create(const Uint32 flags, const int width, const int height) { - if (_surface) { +create: + if (_surface): free(); - } + //SDL_PIXELFORMAT_RGBA8888 SDL_pixels.h ból SDL_CreateRGBSurfaceWithFormat(flags, width, height, 32, SDL_PIXELFORMAT_RGBA8888); -} -void Image::enable_transparent_color(const Color &color) { - if (!SDL_SetColorKey(_surface, 1, color.to_key())) { +------------------------------------------------------------------------------------------ + +enable_transparent_color: + if (!SDL_SetColorKey(_surface, 1, color.to_key())): printf("enable_transparent_color error.\n"); - } -} + +------------------------------------------------------------------------------------------ -void Image::disable_transparent_color() { - if (!SDL_SetColorKey(_surface, 0, 0)) { +disable_transparent_color: + if (!SDL_SetColorKey(_surface, 0, 0)): printf("disable_transparent_color error.\n"); - } -} + +------------------------------------------------------------------------------------------ -bool Image::has_transparent_color() { +has_transparent_color: return SDL_HasColorKey(_surface); -} -Color Image::get_transparent_color() { + +------------------------------------------------------------------------------------------ + +get_transparent_color: uint32_t key; SDL_GetColorKey(_surface, &key); return Color(key); -} -Color Image::get_color_mod() { +------------------------------------------------------------------------------------------ + +get_color_mod: Uint8 r; Uint8 g; Uint8 b; @@ -93,34 +120,43 @@ Color Image::get_color_mod() { SDL_GetSurfaceColorMod(_surface, &r, &g, &b); return Color(r, g, b); -} -void Image::set_color_mod(const Color &color) { - SDL_SetSurfaceColorMod(_surface, color.r, color.g, color.b); -} -Color Image::get_alpha_mod() { +------------------------------------------------------------------------------------------ + +set_color_mod: + SDL_SetSurfaceColorMod(_surface, color.r, color.g, color.b); + +------------------------------------------------------------------------------------------ + +get_alpha_mod: Uint8 a; SDL_GetSurfaceAlphaMod(_surface, &a); return a; -} -void Image::set_alpha_mod(const Uint8 alpha) { - SDL_SetSurfaceAlphaMod(_surface, alpha); -} -SDL_BlendMode Image::get_blend_mode() { +------------------------------------------------------------------------------------------ + +set_alpha_mod: + SDL_SetSurfaceAlphaMod(_surface, alpha); + +------------------------------------------------------------------------------------------ + +get_blend_mode: SDL_BlendMode mode; SDL_GetSurfaceBlendMode(_surface, &mode); return mode; -} -void Image::set_blend_mode(const SDL_BlendMode mode) { - SDL_SetSurfaceBlendMode(_surface, mode); -} -Rect2 Image::get_clip_rect() { +------------------------------------------------------------------------------------------ + +set_blend_mode: + SDL_SetSurfaceBlendMode(_surface, mode); + +------------------------------------------------------------------------------------------ + +get_clip_rect: SDL_Rect r; SDL_GetClipRect(_surface, &r); @@ -133,8 +169,10 @@ Rect2 Image::get_clip_rect() { rect.h = r.h; return rect; -} -void Image::set_clip_rect(const Rect2 &rect) { + +------------------------------------------------------------------------------------------ + +set_clip_rect: SDL_Rect r; r.x = rect.x; @@ -143,17 +181,19 @@ void Image::set_clip_rect(const Rect2 &rect) { r.h = rect.h; SDL_SetClipRect(_surface, &r); -} -void Image::duplicate(Image *into) { - if (into == nullptr) { +------------------------------------------------------------------------------------------ + +duplicate: + if (into == nullptr): return; - } + into->_surface = SDL_DuplicateSurface(_surface); -} -void Image::fill_rect(const Rect2 &rect, const Color &color) { +------------------------------------------------------------------------------------------ + +fill_rect: SDL_Rect r; r.x = rect.x; @@ -162,44 +202,56 @@ void Image::fill_rect(const Rect2 &rect, const Color &color) { r.h = rect.h; SDL_FillRect(_surface, &r, color.to_key()); -} -void Image::fill_rects(const Vector &rects, const Color &color) { +------------------------------------------------------------------------------------------ + +fill_rects: SDL_Rect *r = new SDL_Rect[rects.size()]; - for (int i = 0; i < rects.size(); ++i) { + 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; -} -void Image::set_pixel(const int x, const int y, const Color &color) { - if (_surface == nullptr) { +------------------------------------------------------------------------------------------ + +set_pixel: + if (_surface == nullptr): return; - } - + Uint32 *p = reinterpret_cast(_surface->pixels); p[x * _surface->w + y] = color.to_key(); -} -Color Image::get_pixel(const int x, const int y) { - if (_surface == nullptr) { + +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]); -} -void Image::blit_surface(const Image &source, const Rect2 &srcrect, const Rect2 &dstrect) { + +set_pixel megjegyzése ide is érvényes. + +------------------------------------------------------------------------------------------ + +blit_surface: SDL_Rect sr; sr.x = srcrect.x; @@ -215,69 +267,88 @@ void Image::blit_surface(const Image &source, const Rect2 &srcrect, const Rect2 dr.h = dstrect.h; SDL_BlitSurface(source._surface, &sr, _surface, &dr); -} -void Image::lock() { +------------------------------------------------------------------------------------------ + +lock: SDL_LockSurface(_surface); -} -void Image::unlock() { - SDL_UnlockSurface(_surface); -} -void Image::free() { +------------------------------------------------------------------------------------------ + +unlock: + SDL_UnlockSurface(_surface); + +------------------------------------------------------------------------------------------ + +free: SDL_FreeSurface(_surface); _surface = nullptr; -} -void Image::load_bmp(const String &file_name) { - if (_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) { + 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; - } -} + +------------------------------------------------------------------------------------------ -void Image::save_bmp(const String &file_name) { +save_bmp: SDL_SaveBMP(_surface, file_name.c_str()); -} -Uint32 Image::get_width() const { - if (_surface == nullptr) { +------------------------------------------------------------------------------------------ + +get_width: + if (_surface == nullptr): return 0; - } + return _surface->w; -} -Uint32 Image::get_height() const { - if (_surface == nullptr) { + +------------------------------------------------------------------------------------------ + +get_height: + if (_surface == nullptr): return 0; - } + return _surface->h; -} -SDL_Surface *Image::get_surface() { +------------------------------------------------------------------------------------------ + +get_surface: return _surface; -} -Image::Image() { +------------------------------------------------------------------------------------------ + +Image(): _surface = nullptr; -} -Image::Image(const String &file_name) { + +------------------------------------------------------------------------------------------ + +Image(const String &file_name): _surface = nullptr; load_bmp(file_name); -} -Image::~Image() { + +------------------------------------------------------------------------------------------ + +~Image: free(); -} \ No newline at end of file + +------------------------------------------------------------------------------------------ \ No newline at end of file