diff --git a/14_sdl_basics.txt b/14_sdl_basics.txt new file mode 100644 index 0000000..ea8520c --- /dev/null +++ b/14_sdl_basics.txt @@ -0,0 +1,115 @@ + +Először nézzük meg, hogy hogy is működik az SDL2. + +-------------------------------------------------------------------------------------------------------- + +Fontos tudni, hogy ez egy C könyvtár, ami úgy van megcisnálva, hogy működjön c++-al is! +Azaz: Csak structok vannak, és ezekbe nincsenek függvények! + +Szóval sok olyan függvénnyel fogunk találkozni: + +SDL_Renderer* r = SDL_CreateRenderer(...) + +SDL_GetRendererOutputSize(r, ...) +SDL_CreateTexture(r, ...) + +etc... + +Úgy érdemes erre gondolni, mitnha a this* paramétert, ami c++-ban eléhető minden osztály +tagfüggvényben, itt az első paraméterként adjuk be. + +-------------------------------------------------------------------------------------------------------- + +Az SDL egy relatíve szimpla könytár, gyakolratilag nem sokkal több, mint sok platform +fölötti absztrakciós réteg. + +Pl.: Minden platformon máshogy kell ablakot létrehozni, ablakra rajzolni, hangokat lejátszani, +bementete kezelni, fájlokat megynitni, stb. Az SDL gyakorlatilag csak ezeket csinálja meg nekünk, +egy egyesített interface-en keresztül. + +Elérhető benne egy software-es, és hardware-es renderer. A hardware-es rajzoló az jelenleg az OpenGL, +vagy a Vulkan lehet. + +A különbség közöttük: + +A software-es renderer a CPUt használva állítgatja be / számolgatja ki egy ablak pixeleinek értékét, +míg a hardware-es renderer a GPUt használva csinálja ugyanezt. + +Fontos tudni, hogy a software-es renderert jóval egyszerűbb használni / először beállítani, +mint a hardware-est. (Nem annyival nehezebb, de sok plussz kódot, és magyarázatot igényel, +inkább a szokatlansága miatt.) Ugyanis a gpu úgy működik, hogy mindent az ő általa egyszerűen +értelmezhető formátumba kell konvertálni, illetve külön manage-elni kell az egyéb dolgokat, +pl. a képeket fel kell neki tölteni. + +Viszont! A GPUkban több száz mag található, míg a cpukban általában csak 4-5! +Természetesen a hátránya a GPUs magoknak, hogy nagyon szimplák! + +De a lényeg az, hogy a softwares rajzolóknak az általános problémája, ha sok pixelt kell feldolgozniuk +nagyon gyorsan. Jóval kisebb az ilyen kimeneti teljesítményük. Hogy mennyi pixelt képesek feldolgozni, +az természetesen sokmindentől függ, én sajnos nem tudok erre pontos számokat. A lényeg, hogy tudjatok róla. + +Ettől függetlenül azért a softwares renderereknek van előnye, sőt képesek elég jó dolgokra is! +(Pl Quake, DOOM, Duke Nukem 3D, WolfEinstein 3D, etc... mind softwares renderereket használtak! Érdemes utánanézni, +hogy hogy működtek, vannak már róluk videók is a youtube-on.) + +Egyenlőre csak a software-est fogjuk használni. + +(Lehet, hogy majd egyszer a hardware-es renderert is belerakom. Majd kiderül.) + +Szóval: először a cél az, hogy az egyszerűbb felhasználás érdekében építsünk osztályokat az SDL2 +C API-ja köré. + +-------------------------------------------------------------------------------------------------------- + +==== Egy kis bevezető: ==== + +Elég csak az SDL.h-t includeolni a projektben! Így: +#include + +---- Rajzolás: ---- + +A legfőbb osztályok: + +SDL_Window: //SDL_render.h ban lehet megnézni a függvényeket + +Az ablak adatainak mutatója. Minden platformon más lessz kicsit mögötte. +Amikor létrehozatjuk, akkor hozatja létre az sdl maga az ablakot az operációs rendszerrel. +Az ablak módosításához van rá szükség. Pl át lehet nevezni, meg ilyenek. + +SDL_Renderer: //SDL_render.h ban lehet megnézni a függvényeket + +Az ablak mögötti rajzoló oszály mutatója. Lehet softwares, és hardwares is. +Rajzoláshoz van rá szükség. +Fontos tudni, hogy a softwares, és a hardwares renderert máshogy kell használni, szóval +sajnos nem triviális váltani közöttük! + +SDL_Surface: //SDL_surface.h, SDL_image.h ban lehet megnézni a függvényeket + +Egy képnek az adatait tartalmazza. Sokféle belső formátumot képes kezelni. + +SDL_Texture: //SDL_render.h ban lehet megnézni a függvényeket + +Ugyanúgy, mint egy SDL_Surface, egy kép adatait tartalmazza, viszont ez a softwares rajzoláshoz +optimalizált formában. + +---- Bemenet: ---- + +SDL_Event: //SDL_event.h ban lehet megnézni a függvényeket + +Egy struct, ami egy bemenet adatait tartalmazza. +Nagyon sok adattagja van, bármilyen eventet le tud tárolni. + +A bemenetek guis appoknál úgy működnek, hogy amikor a felhasználó valamit csinál, +pl megmozdítja az egeret, vagy lenyom egy billentyűt, akkor az eltárolódik, egy queue-ban, +és nekünk (a számunkra megfelelő helyen a programunkban) ki kell kéregetnünk ezeket az eventeket, +és fel kell őket dolgoznunk. + +Azaz, ha megmozdítjuk az egeret, akkor: +SDL_event type mezője SDL_MOUSEMOTION lesz, és az adatokat el fogjuk tuni érni a motion mezőben. + +---- Egyéb: ---- + +Audio, fájlok, etc, ugyan így működnek, nézzetek körbe a headerekben, illetve az SDL wiki jén, ha +használni szeretnétek őket, nem fogunk rájuk kitérni. + +(Legalábbis egyenlőre biztosan nem, talán majd egyszer.) diff --git a/15_color.txt b/15_color.txt new file mode 100644 index 0000000..aa4b60b --- /dev/null +++ b/15_color.txt @@ -0,0 +1,81 @@ + +Először, írjunk egy szín osztályt: + +Megj.: Csak a legszükségesebb dolgokat raktam bele, nyugodtan egészítsétek ki, ha akarjátok! + +|--------------------------------------------------------------------------| +| class Color | +|--------------------------------------------------------------------------| +| + uint32_t to_key() const; | <- lejjebb (hasznos lesz) +| + void from_key(const uint32_t key); | <- lejjebb +| | +| + Color(); | +| + Color(uint8_t p_r, uint8_t p_g, uint8_t p_b, uint8_t p_a = 255); | +| + Color(const uint32_t key); | +| + virtual ~Color(); | +| | +| + uint8_t r; | <- #include ban van, 8 bites előjel nélküli int -> 0-256 os értéket tud felvenni +| + uint8_t g; | +| + uint8_t b; | +| + uint8_t a; | +|--------------------------------------------------------------------------| + +uint32_t Color::to_key() const { + 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 + + //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 + + 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/temp/05_sdl_software_renderer.txt b/temp/05_sdl_software_renderer.txt index 909d6f9..634d559 100644 --- a/temp/05_sdl_software_renderer.txt +++ b/temp/05_sdl_software_renderer.txt @@ -10,3 +10,8 @@ vagy #include #include #include + + + +Megj.: WolfEinstein 3D rendererjét úgy hívják, hogy raycaster. Nem sok kód szükséges hozzá, pár száz sor csak +Vannak róla tutorialok a zoutube-on, még talán beimplementálni is érdemes.