Finished up color and image txts.

This commit is contained in:
Relintai 2021-04-07 18:44:07 +02:00
parent 17fb33ff81
commit 1db550fcbe
2 changed files with 225 additions and 128 deletions

View File

@ -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.

View File

@ -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();
}
------------------------------------------------------------------------------------------