HTML

Az élet kódjai

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

Friss topikok

OpenGL apróságok

2011.02.26. 21:45 Travis.CG

A legújabb demónknál elhatároztam, hogy OpenGL 4.1-t fogok használni. Az interneten fellelhető dokumentációk jelentős része még a régebbi verziószámú rendszerre érhető el, ezért előfordul, hogy értetlenül nézek a képernyőre és nem értem, miért nem jelenik meg semmi.

Most, hogy a korábbi módszerek helyett minden shaderből megy, egyrészt jó, mert megadja azt a szabadságot, amit elvárhatok a rendszertől, másrészt elvesz néhány kényelmi szolgáltatást. Értem ez alatt a glRotate (forgatás) és glTranslate (eltolás) függvényeket. Mivel nem erős oldalam a matematika, ezek elvesztése fájt.

A három dimenziós alakzatokat puffereken keresztül lehet megadni, ahol később mi magunk mondjuk meg, hogy az adott puffer milyen szerepet töltsön be. Tehát vázlatosan valami ilyesmi kódot lát az ember:

glGenBuffer...
glBindBuffer...
glBufferData...

Ezzel nem is volt különösebb problémám. Megadunk egy puffert az alakzatunk csúcspontjának, a normálvektor irányának és a textúrák koordinátájának. Ezt szépen össze lehet fogni olyan függvényekbe, mint loadMesh() és utána minden demóban lehet használni. Ahol nekem most problémám akadt, mindezt hogyan mondjuk meg a shaderünknek?

A dokumentáció és a példaalkalmazások alapján előttem két út rajzolódott ki:

  1. A shader linkelése előtt explicit megadjuk, hogy hányadik puffer melyik shader változónak felel meg, a glBindAttribLocation() függvény segítségével.
  2. Linkelés után lekérdezzük a shader változó azonosítóját (glGetAttribLocation), majd hozzákapcsoljuk a megfelelő puffert (glBindBuffer, glVertexAttribPointer, glEnableVertexAttribArray).

Az első megoldás kényelmes, de én egy általános shader betöltőt akartam írni, ami nem foglalkozik azzal, hogy milyen változók vannak a shaderben és azoknak mi a szerepe. Csak betölti a shadert valami loadShader() függvénnyel, ami egyedül a fájl nevét kapja meg. Megjegyzem, még ebben az esetben is lehet használni az első módszert, de a glBindAttribLocation() meghívása után ki kell adni egy glLinkProgram() utasítást is. Tehát valami ilyesmi kódunk lesz:

shaderprg = loadShader("winnershader.vert", "winnershader.frag"); // van benne glLinkProgram
glBindAttribLocation(shaerprg, 0, "coolvariable");
glLinkProgram(shaderprg);

Ez viszont nem tetszik. Miért hívjak meg többször egy függvényt? A második módszer jobban tetszett. Meg is írtam a rutint. És nem működött. Ez azért is érdekes, mert Norbert Nopper kollégának működött. Már kezdtem azt hinni, hogy kénytelen leszek a béna első módszert használni, amikor Nopper programját tüzetesen megvizsgálva észrevettem a megoldást. Nevezetesen ki kell adni a glBindVertexArray-t is. Utólag belegondolva logikus is, hiszen több VertexArray-el is dolgozhatunk.

A módosítás hatására a program az elvárt végeredményt mutatta.

Ugyancsak fontos, hogy megfelelő időben aktiváljuk shader programunkat. A glUseProgram mindig előzze meg a glGetUniformLocation és glUniform parancsokat, különben GL_IVALID_OPERATION hibaüzenetet kapunk, amit nehéz felderíteni.

Szólj hozzá!

Címkék: programozás demoscene opengl

A bejegyzés trackback címe:

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

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