Milyen gyorsan lehet betűket a képernyőre írni?
console, terminal, gdi, directx, vulkan, opengl, metal, opentk
2025-10-13
Drawing Text Isn't Simple: Benchmarking Console vs. Graphical Rendering
console, terminal, gdi, directx, vulkan, opengl, metal, opentk
2025-10-13
Miért és hogyan használjunk 3rd party libraryket frontend projektekben?
frontend, library, 3rd party
2025-08-31
Heti gondolkodó 2025W31
weekly
2025-08-03
Heti gondolkodó 2025W30
weekly
2025-07-26
Kiszervezett gondolkodás
ai
2025-07-04
Csináljunk legacyból modern szoftvert, egy Angular frontend projekt élményei
angular, frontend, legacy
2025-06-30
Miért utálják az IT-sek a HR-eseket?
hr, recruitment, it
2025-01-19
PHP kódminőség fenntartás
php, qa, static code checking, phpunit, phpcs, phpmd, phpstan, churn, phpdd, psalm, phplint, phan
2024-10-17
Failed: bson encoding error: BSON element key cannot contain null bytes
mongo, mongodb, bson, null, key
2024-08-24
Nem bízol a kollégáidban? Akkor valamit rosszul csinálsz!
bizalom vezetokent
2023-05-03
Dolgok, amikről a programozók azt hiszik, hogy tudják, de tévednek
programozoi-tevhitek-falsehoods
2023-04-08
A programozóktól meg kell szabadulni
chatgpt no-code low-code
2023-01-22
Miért fontosak a személyes adatok egyáltalán?
privacyaware, privacy
2023-01-07
Egy tanmese a szerény, de tehetséges informatikusról, akit én csak Gézának hívok
privacyaware, privacy
2023-01-02
Beskatulyáznád magad egy termékkel? Gondold át még egyszer!
learning, vendorlockin, risky
2022-12-11
Rekrúterekről és állásajánlatokról
bérsáv, recruiter, relevancia
2022-10-30
"A hídon akkor kell átmenni, amikor odaérünk."​ - YAGNI
yagni, pagni
2022-10-17
"A lényeg, hogy a munka készen legyen!"
agile, estimation, becsles, scrum, home office
2022-08-20
Munka vs. hivatás, a klasszikus dilemma
hr, hobbi, munka, egyensuly, hivatas
2022-07-18
Miért nem fogok nálatok technikai interjún részt venni?
technikai interju, hr, recruit, leet code, coding challenge, take home challenge
2022-07-04
"Hogyan építsek kapcsolati tőkét, ha karriert szeretnék váltani?"
linkedin, tippek, trukkok
2022-06-10
Junior/Medior/Senior, hogyan mérjük?
junior, medior, senior, hr, grade, level, experience
2022-05-09
11 tipp frontendeseknek, hogyan tegyék hatékonyabbá a munkájukat
frondend, vscode, angular
2021-10-31
Motion zoom - mozgás alapú képrekonstrukció
#52het
2021-06-01
Gesture Launcher
#52het
2021-05-31
CellEvent, első Android alkalmazásom
#52het
2021-05-19
Notebookcheck, azaz hogyan válasszuk ki a legjobb ár-érték arányú eszközt
#52het
2021-05-18
Torrent multiplexer
#52het
2021-05-17
Process watcher, logger
#52het
2021-05-05
Lazy loading material dialog content
lazy loading, angular, material, dialog
2020-12-28
Runtime configuration loading in Angular
angular, runtime, configuration, settings, environment, production
2020-03-29
How to start an Angular project?
angular
2020-03-11
Az 52 hét projekt
#52het
2020-01-01
Akkutöltöttség-jelző
#52het
2020-01-01
NetClub - Kollégiumi internetszolgáltató
#52het
2019-12-31
DeeJayy - Lost Terminal
#52het
2019-12-31
Counter Strike monitor
#52het
2019-12-31
Kollégiumi CS bajnokság 2005
#52het
2019-12-31
Mozgásérzékelős képrögzítő, Camera Capture
#52het
2019-12-30
Többszörös host pingelő
#52het
2019-12-30
Sávszélesség mérő, tesztelő
#52het
2019-12-30
Generáljunk hamis adatokat
#52het
2019-12-30
SQL lekérdezések parancssorból, odbc-vel
#52het
2019-12-30
Nonogram generátor (aka. "Fesse feketére")
#52het
2019-12-30
Egyedi chat alkalmazás, kliens és szerver
#52het
2019-12-29
FontSelector - betűtípusválasztó / font preview
#52het
2019-12-28
Saját hálózati kommunikációs segédszoftver - sox
#52het
2019-12-28
Csoportos e-mail küldő szoftver Delphiben
#52het
2019-12-28
Universal Api caller module for Angular 7-9 With NGRX state management
Ngrx, API, Effects, HttpClient
2019-07-02
A leghosszabb projekt
#52het
2019-04-19
Legelső kioszk projektem: Stari Sör Jukebox
#52het
2019-02-28
BPM számláló
#52het
2018-11-01
Assembly féléves beadandók
#52het
2018-11-01
Chatbot before it was cool
#52het
2018-10-30
StartX - Cseréljük ki a windows tálcáját és a Start menüt
#52het
2018-10-28
What? - fájltípus azonosító
#52het
2018-10-27
Transport Tycoon DirectX
#52het
2018-10-26
Diff - fájlösszehasonlító
#52het
2018-10-26
De Facto - Szoftverfelügyelet
#52het
2018-10-25
CD és DVD katalogizáló
#52het
2018-09-24
MP3 segédeszközök
#52het
2018-09-24
Keylogger - azaz billentyűleütés-figyelő és naplózó alkalmazás
#52het
2018-08-29
Az örök projekt: személyes weboldal és blog
#52het
2018-08-14
Szógyakorló nyelvtanuláshoz
#52het
2018-08-13
Warzone 2100 mentett játék szerkesztő
#52het
2018-08-13
Rejtett Windows-beállításokat konfiguráló program: TweakMaster
#52het
2018-08-13
A DrótPostaGalamb levelezőprogram adatfájljainak dekódolása
#52het
2018-08-13
Privacy jegyzet
2018-07-30
Egy éve ilyenkor
2018-07-25
The Matrix - konzol szimuláció
#52het
2018-07-13
Kakaóreceptkönyv
kakaó
2018-06-29
Crackelés!
#52het
2018-06-22
A K.I.T.T. challenge
#52het
2018-06-18
Doom 2 botokkal
#52het
2018-06-16
Römi játék Delphiben
#52het
2018-06-09
MeetsCow & DeeJayy - Intro
#52het
2018-06-09
Direct viewer - bitmap megjelenítő
#52het
2018-06-09
bazMAG
#52het
2018-06-09
Console Vision - Konzolos ablakkezelő Delphiben
#52het
2018-05-01
Quake 2 egy floppyn
#52het
2018-04-20
Játék-kitömörítők
#52het
2018-04-12
Tetszőleges program elrejtése Windows tálcáról
#52het
2018-04-05
Személyre szabás
#52het
2018-03-28
A year with Angular 5, 6 - Angular 2018
#angular5 #angular #resources #articles
2018-03-16
Az ikon evolúciója
#52het
2018-03-14
Betűtípusok
#52het
2018-03-04
Billentyűzet-gyakorló
#52het
2018-02-28
Zenél is a DeeJayy?
#52het
2018-02-22
Térképrajzoló az Ascii 3D labirintushoz
#52het
2018-02-19
Ascii 3D labyrinth
#52het
2018-02-14
52 hét - 52 projekt, avagy #eletem
#52het
2018-02-14
Dockerezzünk virtualizált környezetben!
docker, xen, ubuntu
2017-11-12
A cloud-initramfs-copymods hatásai paravirtualizált környezetben
ubuntu, xen, copymods, docker, docker-ce, docker.io
2017-11-11
Virtualizáljunk Xen 4.6-tal Ubuntu 16-on (Xenial)
ubuntu, xen, virtualizálás, hypervisor, debootstrap
2017-11-04
Álláskeresésem története
álláskeresés, it, fejvadászok, linkedin, job
2017-10-24
FAR Manager competitors
far manager, file managers
2010-01-01
Blog
blog
2001-01-02

Rajzoljunk betűket a képernyőre - mi lehet ennél egyszerűbb

A dolog úgy indult, hogy Go-t kellene tanulnom. Azt mondják a polyglotok (akik az átlagnál sokkal több nyelven tudnak beszélni), hogy a legjobb módszer a nyelvtanulásra az, ha úgy tanuljuk, hogy valami élvezetes dolgot csinálunk vele. Van, aki filmeket néz az adott nyelven, mások olvasnak, megint mások kártya segítségével tanulnak szavakat, és vannak, akik a mélyvízbe ugranak és nulla szókinccsel elkezdenek beszélni.

Hiszem, hogy ezt a módszert a programozási nyelvekre is lehet alkalmazni, így a képlet eredménye az lett, hogy elkezdek írni egy szöveges módú fájlkezelőt. A legtöbben a Norton Commanderre emlékeznek (esetleg a Dos Navigatorra), de van egy aktívan fejlesztett alternatíva, a FAR (File and ARchive) Manager. A mai napig ezt a szoftvert úgy tartom nyilván, hogy ez képes a legjobban támogatni a produktivitást. Ez az alkalmazás az egyik fő oka, hogy nem váltok linuxra vagy mac-re.

A FAR Manager tárgyalásába nem megyek most bele, megérne egy önálló esszét.

Amiért le akarom cserélni

Bár a fejlesztése továbbra is aktív, egetrengető újdonságok nem nagyon jelennek meg benne. Mindeközben elkezdtem átnézni a konkurrens fájlkezelőket (van belőlük pár), amikben viszont vannak hasznos, a FAR-ból hiányzó dolgok. Lehetne plugineket írni, de nem mindenre, sokkal inkább a fő forráskódot kellene módosítani, ha értelmes módon akarnám ezeket hozzátenni. De az meg olyan nyelven van, amit nem beszélek (és egyelőre nincs is tervben).

Úgy döntöttem, hogy inkább nekiállok újraírni - mi sem egyszerűbb! Nyilván tudom, hogy ez egy nagyjából lehetetlen küldetés, de már hozzászoktam, hogy az ilyen projekteket nem fejezem be, így hát nagyot álmodtam, aztán jutok, amíg jutok. Ahogy egy híres ember mondta:

Célozd meg a Holdat! Még ha elhibázod is, a csillagok közt landolsz.

Az elképzelt fájlkezelő terve

Az titkos. Még mindig van esély, hogy megcsinálom, szóval nem szórom el az ötleteimet csak úgy! Két fő modulra viszont fényt derítek: bevitel kezelés (egér, billentyűzet) és kimenet kezelés (betűk rajzolása a képernyőre).

Bemenet

Az első modul relatív unalmas, miután átverekedtem magamat a konzolos bevitel minden buktatóján. Az egyik, hogy a Windows - annak érdekében, hogy közelebb hozza magához a linux ökoszisztémát és megteremtse a linux desktop évét - átvette a VT (azaz Virtual Terminal) beviteli- és kimeneti módot a parancssori (konzolos) ablakban. Ez annyit jelent, hogy a bevitel butább, a kimenet meg lassabb lett.

Miért buta? A VT egy nagyon régi protokoll, amit még akkor találtak ki, amikor mainframe-ek és valódi terminálok voltak. Viszont az azóta elmúlt 50 évben történt néhány technológiai fejlesztés, amiről a VT nem vett tudomást, részben azért, hogy tartsa a visszafelé kompatibilitást. Az egyik ilyen jól tettenérhető buktató például az, hogy amikor a felhasználó lenyomja a Shift gombot a billentyűzetén, akkor arról a VT-ben futó program nem kap értesítést, majd csak akkor, amikor egy betűt is lenyom hozzá a delikvens és mondjuk egy nagy "A" betű formájában érkezik meg a programhoz. Ez egy olyan kompromisszum, amit semmiképpen nem akartam megkötni, hiszen a cél nem egy butább, hanem egy okosabb fájlkezelő létrehozása.

A másik buktatót a Windows maga prezentálta a saját visszafelé-kompatibilitásával, amikor megpróbálta átvenni a speciális billentyűkombinációk (pl. Ctrl+C) kezelését. Mint kiderült, ez olyan edge case-eket eredményez, mint például, ha egymás után sorrendben lenyomtam a shift+ctrl+alt gombokat, majd fordított sorrendben felengedtem, akkor a felengedésről nem kapott értesítést a program, míg ha alt+ctrl+shift volt a lenyomás sorrendje, akkor minden esemény gond nékül megérkezett.

Szerencsére mindkét buktatóra volt érdemi megoldás, így a billentyűzetkezelés egészen nagy részben le is van már fedve.

Kimenet

A hosszú bevezető után térjünk rá a lényegre: a kimenet. Azaz, szögegyszerűen fogalmazva, rajzoljunk betűket a képernyőre. Erre a célre a konzolos felületen több módszer is rendelkezésre áll, az egyik, hogy a betűk listáját és a színkódokat felszórjuk a képernyőre hosszában-keresztben (WriteConsoleOutputW - régi módszer). A másik, hogy a színkódokat beépítjük a szövegbe (VT módszer) és soronként felírjuk a képernyőre (WriteConsoleW - új módszer). Utóbbinál elég hamar kiesik, hogy ez bizony lassabb, mint a régi módszer, úgy kb. fele a sebesség.

Miután elégedetlen voltam ezzel a teljesítménnyel a középkategóriás számítógépemen (értsd: a mai 3D-s játékok még elfutnak rajta), úgy gondoltam, kell, hogy legyen ennél jobb megoldás. Közben kaptam is ajánlásokat kollégáktól, hogy vannak már GPU-gyorsításra épülő betűrajzoló programok (terminálok) is, amik zökkenőmentes képfrissítést produkálnak. Más ötlet híján belenéztem ebbe a vonalba is.

Miután napokat kalapáltam a Go-t, fórumokat és LLM-eket kérdezgettem, kiderült, hogy a Go egyáltalán nem alkalmas ilyesmire. Így hát, dobtam a programnyelvet és lecseréltem egy olyanra, ami már bizonyított: C#-ra. (Aki azt találja mondani, hogy minden programnyelv alkalmas mindenre, azt kérem egy döglött heringgel arcon kínálni. Amúgy persze, alkalmas, csak milyen áron?)

Így az utazásom a .NET felé vette az irányt, amiben többek között komoly 3D-s játékokat is fejlesztenek, tehát ezzel nem futhatok lukra! Három módszerrel estem neki a megjelenítésnek. Az egyik a klasszikus grafikus eszköz kimenet, amit a Windows már 30 éve kínál: GDI (Graphics Device Interface). Azaz, fogtam a szöveget, amit ki akartam rakni a képernyőre és kiírás helyet megrajzoltattam a betűket. A GDI-ről annyit kell tudni, hogy az régen is és ma is alkalmas volt grafikus megjelenítésre dedikált videókártya nélkül is (ma már azért ritkán kapni ilyen gépet). Ez tehát elvileg lassabb, mintha a dedikált videókártyával, gyorsított módon rajzolnánk a képernyőre.

A következő próbálkozás a DirectX volt, ami konkrétan arra van, hogy fejlett, részletgazdag 3D-s játékokat maximális képfrissítés mellett futtasson. Gondoltam akkor, hogy ez a roppant bonyolult "rajzoljunk betűket a képernyőre" meg sem fog neki kottyanni, egyrészt mert gyors rajzolásra találták ki, másrész a feladat nem lehetne ennél egyszerűbb!

Az utolsó jelölt egy, szintén játékok számára készített rajzolási mód, az OpenGL utódja, a Vulkan megjelenítő volt. Nagyon sok megközelítésben hasonlít a a DirectX-hez, az egyik vitathatatlan előnye viszont, hogy nem csak Windows platformra van. Bár nem volt cél, de azért mégiscsak jobban hangzik, ha minden oprendszer támogatott.

Ígyhát csináltam is egy-egy alternatívát minden megközelítéssel, ami egyelőre szóba jött, hogy megmérjem, melyikre érdemes építeni az alkalmazásomat. A feladatot direkt nehezítettem: a szöveges alkalmazások többsége viszonylag kis szórással alkalmaz különböző szöveg- és háttérszíneket a megjelenítéskor, én mégsem akartam arra apellálni, hogy "egyszínű konzolban gyors, de ahogy bonyolultabb lesz, elkezd szaggatni". Ez egy olyan kompromisszum lett volna, amit szintén nem akartam meghozni.

Ezért a tesztképernyő valahogy így néz ki:

Én is tudom, hogy a valóságban erre nem igazán lesz példa, de úgy voltam vele, ha ezt elviszi, akkor mindent elvisz.

Beállítottam a konzolméretet 240x63 karakterre (ennyi fér ki a képernyőmre fullhd-ban 8x16-os ASCII betűtípussal) illetve 80x25-re (a klasszikus DOS képernyőméret) és lefuttattam a teszteket, hogy melyik milyen képújrarajzolási sebességre képes (FPS - frames per second):

Megjelenítés 240x63 80x25
WriteConsoleOutputW 20.3 64.5
WriteConsoleW 12.9 64.5
GDI 22.2 64.5
Vulkan 23.5 175.2
DirectX 17.6 130.5

A konklúzió az, hogy mindegyikkel gyötrelmesen rossz a képújrarajzolási sebesség (pedig már van benne némi optimalizáció is). Természetesen, valós kimenettel ezek a számok sokkal barátságosabban alakulnának, például fekete alapon fehér betűkkel:

Megjelenítés 240x63 80x25
WriteConsoleOutputW 64.5 64.5
WriteConsoleW 64.5 64.5
GDI 62.4 64.5
Vulkan 114.4 733.0
DirectX 140.2 944.5

Közelítsük meg máshogy

Elég világos, hogy a probléma elsősorban nem a grafikai felület rajzolási képességein van, hanem a Windows betűrajzoló algoritmusában. Így tehát egy unortodox megközelítéssel folytattam: vegyük le ezt a terhet (nagyrészben) a Windows-ról és miután megrajzolt egy betűt, tároljuk el a képét. A teszthez ugye a 8x16-os cellaméretű betűtípust használtam, és 128 pixelt eltárolni, mozgatni könnyebb, mint egy komplex ívekkel és koordinátákkal leírt karaktert újra és újra megrajzolni. Ezzel a feladat leegyszerűsödik textúramásolássá és -tárolássá, amivel nagyságrendi sebességnövekedést lehetett elérni (egy korlátig).

Felbontás Megjelenítés FPS
240x63 DirectX textúrázás 66.4
80x25 DirectX textúrázás 450.1

Nincs jó megoldás

A textúrázás, bár jól hangzik a számok alapján, tartogat egy buktatót. A teljesítménye ugyanis nem optimalizálható szignifikánsan, míg a sima szövegírásé igen. Itt ugye arról van szó, hogy amikor betűk képét kell másolni ide-oda, akkor azokat csak egyesével lehet még akkor is, ha mindegyik egyszínű és ugyanolyan stílusú (félkövér, dőlt). Szöveget írni viszont, ha a szín és stílus is egyezik, lehet tömegével, ami jelentős gyorsulást eredményez. Például ha egy komplett sort ki lehet írni azonos tulajdonságokkal, akkor az 200x-os gyorsulást is eredményezhet, így elég hamar át lehet lépni a kezdeti korlátokon és a 20 FPS helyett (teoretikusan) 2000 FPS-sel írni a betűket. A gyakorlat azért nem mutat ilyen mértékű sebességkövekedést, csak 5-7x-est.

Összehasonlításképpen, extrém felhasználás:

Felbontás DX + betűírás DX + textúra változás
240x63 17.6 66.4 377% +
80x25 130.5 450.1 345% +

Összehasonlításképpen, normál felhasználás:

Felbontás DX + betűírás DX + textúra változás
240x63 140.2 66.4 47% -
80x25 944.5 450.1 47% -

Konklúzió, az minden cikk végére kell

Szóval úgy tűnik, hogy a lokális optimum az a DirectX + betűírás módszer marad, de az is egészen jó kihívás lenne, ha mondjuk opcióban hagynám a többi megjelenítőt is (ha komolyan gondolom például a multiplatform megjelenítést).