HTML

Az élet kódjai

Csináld maga. Senki nem csinálja meg helyetted.

Friss topikok

Oh, my bug

2022.10.03. 23:23 Travis.CG

Az utóbbi időkben a demóim silányságában az is szerepet játszott, hogy nem tudtam két menetben renderelni. Mikor az új engine-t írtam, a Domestic violence-ből átemeltem a framebufferbe renderelés elemeit, becsomagoltam egy tetszetős C++ osztályba, majd vártam a csodás.

A csoda elmaradt. Közben volt néhány demóparti, amire újabb elemekkel bővítettem a kódhalmazt, ez a feature meg közben elmaradt. De eléggé idegesített, hogy amit annak idején viszonylag könnyen leprogramoztam, most nem akar működni. Ezért mident félretettem, és elkezdtem kutatni a hiba okát.

A framebuffer létrehozásáról már írtam korábban. Most csak arról szeretnék írni, hogy milyen lépések és milyen hibaforrások lehetnek. Először is, létre kell hozni a Framebuffer objektumot, textúrákkal, mélységi pufferrel (1). Utána kell egy shader, ami ebbe a pufferbe rajzol (2). Kell maga a geometria kirajzolása (3). Ez az első lépés. A második lépésnél a képernyőt tesszük alapértelmezettnek (4), rajzolunk egy téglalapot (5), és egy második shaderrel kirakjuk rá az előző lépésnél elkészített textúrát (6). Bármelyik lépésnél kudarcot vallunk, nem látunk semmit.

Először egy tutorial alapján újra átnéztem minden utasítást. Természetesen nem találtam a hibát, mint ahogy az előző több tíz alkalommal sem. Ha csak simán a képernyőre rajzoltam a geometriát, akkor minden megjelent, tehát a (2) és (3) jó. A kód összehasonlításánál az (1) is jónak tűnt. Az (5) is jónak tűnt, mert ha a második shadernél csak piros színt raktam ki, akkor az egész képernyő piros lett. Ebből arra következtettem, hogy a (6) lépés is stimmel. A (4) pedig csak egy glBindFramebuffer(0), tehát az is jó. Minden jó, mégsem működik.

Még egyszer végigmentem a lépéseken, másodszor sem láttam a hibát. Harmadszor is végignéztem egy tutorial kóddal összehasonlítva, továbbra sem láttam a megoldást. Viszont volt egy ügyes trükk a kódban. A képernyőtörlést más színnel végezte a két rajzolás alatt. Ezt én is megléptem. Az első framebuffer szürkét kapott, a második, képernyőre író pedig fehéret.

Az eredmény szürke képernyő volt. Tehát (1) jó, (2) jó, (3) nem jó. Ami ellentmondásban volt a korábbi tesztekkel, ahol Framebuffer bűvészkedés nélkül a geometria megjelent. Rájöttem, hogy ha tovább akarok lépni, akkor segítségre van szükségem.

A segítség az NVidia NSight volt, amivel Linux alatt is tudok debuggolni. Még Slackware alá is fel tudtam telepíteni. Egyetlen gondom az volt, hogy visított, hogy régi a videokártyám, ezért nem lesz minden funkció elérhető. De erre csak legyintettem.

Ez a debugger kilistázza a rajzoló műveleteket úgy, ahogy meghívásra kerülnek, nem kell a millió osztály referencián keresztül végigkövetni, mi is történik. Kirajzolja a textúrákat, puffereket, szóval nagyon jól működött. Kb. fél óra után már átláttam, mit is csinál, mire kell klikkelni. Elég intuitív.

Ekkor jött a meglepetés. (3) jó. A textúra ott virított, ahol lennie kellett.(6) megkapta a megfelelő textúrát, mégis csak a nagy szürkeséget rajzolta ki belőle.

Ekkor fogtam magam, átírtam a kódot és a framebufferes textúra helyett egy közönséges jpg-t adtam meg neki. Azt sem rajzolta ki. Illetve olyan volt, mintha csak a textúra teteje jelenne meg, de az is teljesen homogén módon.

Ekkor már tudtam, hogy közel vagyok. Most már egészen biztos voltam, hogy (5) és (6) között lesz a hiba. Ezért nem a (6) shadert kezdtem el használni, hanem a (2)-t, mert az bizonyította, hogy jól működik. Ez egy hiba volt a részemről, mert a két shader ég és föld volt. Aztán elkezdtem heggeszteni a kódot, hogy az inkompatibilitások ellenére is működjön, ezzel pedig rengeteg időt vesztegettem, mert újabb hibaforrásokat vittem az amúgy hibás rendszerbe. De pont ez hozta el a megoldást.

Ugyanis (2) shaderben a vertex shader kicsit bonyolultabb, mert normál vektorokat is kezel a geometria miatt. De a teljes képernyős négyzet esetén nincs szükségem normálokra. Ezért átírtam a kód elejét, mire hirtelen minden tökéletesen megjelent.

A kód akkor már nagyon össze-vissza volt a sok toldozgatás-foltozgatás miatt, ezért további egy óra ment el arra, hogy mindent úgy írjak vissza eredetibe, hogy közben ne vétsek új hibát. (Ezért kell verziókövető rendszert használni, nem igaz?)

Szóval ez a sok hűhó egyetlen sorra vezethető vissza:

layout (location = 2) in vec2 texc;

Átírtam location = 1-re, és minden jó volt. Mint abban a gyerekversben, ahol a szög miatt a patkó elveszett.

Szólj hozzá!

Címkék: programozás opengl

A bejegyzés trackback címe:

https://cybernetic.blog.hu/api/trackback/id/tr3517943444

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása