mirror of
https://github.com/Relintai/programming_tutorials.git
synced 2025-04-21 21:51:22 +02:00
Finished up color and image txts.
This commit is contained in:
parent
17fb33ff81
commit
1db550fcbe
104
15_sdl_color.txt
104
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<uint32_t>(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<uint32_t>(r) << 24: (8db 0) (8db 0) (8db 0) (r száma) Ez lessz: (r száma) (8db 0) (8db 0) (8db 0)
|
||||
//static_cast<uint32_t>(g) << 24: (8db 0) (8db 0) (8db 0) (g száma) Ez lessz: (8db 0) (g száma) (8db 0) (8db 0)
|
||||
//static_cast<uint32_t>(b) << 24: (8db 0) (8db 0) (8db 0) (b száma) Ez lessz: (8db 0) (8db 0) (b száma) (8db 0)
|
||||
//static_cast<uint32_t>(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<uint32_t>(r) << 24;
|
||||
val |= static_cast<uint32_t>(g) << 16;
|
||||
val |= static_cast<uint32_t>(b) << 8;
|
||||
val |= static_cast<uint32_t>(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<valami> 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<uint32_t>(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<uint32_t>(r) << 24: (8db 0) (8db 0) (8db 0) (r száma) Ez lessz: (r száma) (8db 0) (8db 0) (8db 0)
|
||||
static_cast<uint32_t>(g) << 16: (8db 0) (8db 0) (8db 0) (g száma) Ez lessz: (8db 0) (g száma) (8db 0) (8db 0)
|
||||
static_cast<uint32_t>(b) << 8: (8db 0) (8db 0) (8db 0) (b száma) Ez lessz: (8db 0) (8db 0) (b száma) (8db 0)
|
||||
static_cast<uint32_t>(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<uint32_t>(r) << 24;
|
||||
val |= static_cast<uint32_t>(g) << 16;
|
||||
val |= static_cast<uint32_t>(b) << 8;
|
||||
val |= static_cast<uint32_t>(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<valami> 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.
|
||||
|
249
16_sdl_image.txt
249
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<Rect2> &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<Uint32 *>(_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 <int_types.h>/ban van, a másik az sdl/ben.)
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
|
||||
get_pixel:
|
||||
if (_surface == nullptr):
|
||||
return Color();
|
||||
}
|
||||
|
||||
Uint32 *p = reinterpret_cast<Uint32 *>(_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();
|
||||
}
|
||||
|
||||
------------------------------------------------------------------------------------------
|
Loading…
Reference in New Issue
Block a user