.[ ČeskéHry.cz ].
OpenGL - vytažení hodnot z shaderu
Jdi na stránku 1, 2  Další
 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> 3D API / 3D Enginy
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
TeaTime



Založen: 17. 06. 2011
Příspěvky: 264

PříspěvekZaslal: 12. září 2013, 12:37:47    Předmět: OpenGL - vytažení hodnot z shaderu Odpovědět s citátem

Ahoj,

pro debugování shaderu by se mi hodilo, kdybych si mohl vypsat hodnotu gl_Position, kterou vypočetl vertex shader. Zjistil jsem, že by mi mohla pomoci funkce glGetBufferSubData. Ta zkopíruje data z gl bufferu do paměti procesu.

Do shaderu pošlu pomocnou proměnnou positionOut:
kód:

glGenBuffers( 1, &this->vboPositionOut );
glBindBuffer( GL_ARRAY_BUFFER, this->vboPositionOut );
glBufferData( GL_ARRAY_BUFFER, sizeof(float) * this->verticesNum * 3, this->positionOut, GL_STATIC_DRAW );
glEnableVertexAttribArray( shader->positionOut );
glVertexAttribPointer( shader->positionOut, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)0 );


Poté, co zavolám glDrawElements získám hodnoty bufferu takto:
kód:

glBindBuffer( GL_ARRAY_BUFFER, this->vboPositionOut );
glGetBufferSubData( GL_ARRAY_BUFFER,  0,  sizeof(float) * this->verticesNum * 3, this->positionOut );


Data která získám jsou stejná jako ta, která jsem tam poslal. Ale potíž je v tom, že když hodnotu změním ve vertex shadru, tak tato změna se nereflektuje ve výsledku volání funkce glGetBufferSubData.

Ve vertex shaderu mám proměnnou uvozenou takto:

kód:
in vec3 positionOut;


Tak nevím, kde a jak umožnit tu změnu. OpenGL dokumentace už mi leze na mozek neustálým žvaněním o nesmyslech, které můj problém neřeší, tak bych se rád zeptal vás, jak by se to mělo správně dělat.

Díky.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
perry



Založen: 28. 07. 2009
Příspěvky: 879

PříspěvekZaslal: 12. září 2013, 12:41:43    Předmět: Odpovědět s citátem

Jaká verze OpenGL ?
_________________
Perry.cz
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
TeaTime



Založen: 17. 06. 2011
Příspěvky: 264

PříspěvekZaslal: 12. září 2013, 12:52:40    Předmět: Odpovědět s citátem

perry napsal:
Jaká verze OpenGL ?


Hmm. No na počítači mám 4.2, jinak moc nevím, co ti mám přesně říct. Osobně požadavek na verzi nemám. Celé to dělám asi pomocí verze >=3, ale fakt ti to nemůžu říct s jistotou (protože tomu nerozumím Razz).
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
perry



Založen: 28. 07. 2009
Příspěvky: 879

PříspěvekZaslal: 12. září 2013, 12:58:54    Předmět: Odpovědět s citátem

No nevím jak je to tedy u OpenGL, znám to jen z DX. Každopádně idea: Pokud máš HW s podporou Compute Shaderů (právě DX11 asi OpenGL 4.2), tak by tam měl být buffer pro ty compute shadery, který by měl jít naplnit ve VS a pak normálně číst.

Jinak bez toho je řešení multi-render target, kdy z VS vysoupí ta pozice a uložíš ji do jednoho z targetl pro render a pak si ho načteš jako tetxuru na CPU a vytáhneš to ven.

Další řešení je použít speciální nástroje, které umí debugovat shadery Smile
_________________
Perry.cz
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
TeaTime



Založen: 17. 06. 2011
Příspěvky: 264

PříspěvekZaslal: 12. září 2013, 13:07:01    Předmět: Odpovědět s citátem

perry napsal:
No nevím jak je to tedy u OpenGL, znám to jen z DX. Každopádně idea: Pokud máš HW s podporou Compute Shaderů (právě DX11 asi OpenGL 4.2), tak by tam měl být buffer pro ty compute shadery, který by měl jít naplnit ve VS a pak normálně číst.

Jinak bez toho je řešení multi-render target, kdy z VS vysoupí ta pozice a uložíš ji do jednoho z targetl pro render a pak si ho načteš jako tetxuru na CPU a vytáhneš to ven.

Další řešení je použít speciální nástroje, které umí debugovat shadery Smile


No já bych to potřeboval vědět trochu praktičtěji, ale díky za radu. No kouknu se, co se kde píše o tom Compute Shaderu.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
nou



Založen: 28. 07. 2007
Příspěvky: 1050

PříspěvekZaslal: 12. září 2013, 13:34:03    Předmět: Odpovědět s citátem

myslim ze najvhodnejsie je na toto pouzit transform feedback. tam sa vystup z vertex shadera ulozi do bufferu ktory sa uz da normalne precitat.
_________________
Najjednoduchšie chyby sa najtažšie hľadajú.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
TeaTime



Založen: 17. 06. 2011
Příspěvky: 264

PříspěvekZaslal: 12. září 2013, 13:36:54    Předmět: Odpovědět s citátem

nou napsal:
myslim ze najvhodnejsie je na toto pouzit transform feedback. tam sa vystup z vertex shadera ulozi do bufferu ktory sa uz da normalne precitat.


Ohóó, převeliké díky, vypadá to, že přesně tohle hledám. Ozkouším to a dám vědět.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
pcmaster



Založen: 28. 07. 2007
Příspěvky: 1827

PříspěvekZaslal: 12. září 2013, 14:12:55    Předmět: Odpovědět s citátem

Na tom uplne prvom priklade mi nie je celkom jasne, preco si myslis, ze by sa mal ten buffer zmenit po glDraw* Smile Vsak ho len pripojis ako vertex attribute (READ-ONLY INPUT), a ze ty vo vertex shaderi nieco pomenis neznamena nic -- kam by sa to malo akoze zapisat? Vsak sa to len preda dalsej stage.

Jedina moznost, ako spravne napisal nou, je "transform-feedback" (v DX "stream-out"). No ok a teda aj compute shader, samozrejme.
_________________
Off-topic flame-war addict since the very beginning. Registered since Oct. 2003!
Interproductum fimi omne est.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
TeaTime



Založen: 17. 06. 2011
Příspěvky: 264

PříspěvekZaslal: 14. září 2013, 16:52:00    Předmět: Odpovědět s citátem

Tak jsem to tak nějak nastudoval a spustí se to bez chyby, ale výsledky nejsou.

Přesně před slinkováním gl programu (glLinkProgram):
kód:

const char * varyings[2];
varyings[0] = "gl_Position";
varyings[1] = 0;
glTransformFeedbackVaryings( this->programGpu, 1, varyings, GL_SEPARATE_ATTRIBS );


Výsek kódu kolem glDraw*:
kód:

//------------ inicializece bufferu pro TF ------------------------
float * data = new float[ this->trianglesNum * 3 * 4 ];
for( int i=0; i<this->trianglesNum * 3 * 4; i++ )
data[i] = 0.987654;

glGenBuffers( 1, &this->vboTransformFeedback );
glBindBuffer( GL_TRANSFORM_FEEDBACK_BUFFER, this->vboTransformFeedback );
glBufferData( GL_TRANSFORM_FEEDBACK_BUFFER, sizeof( float ) * this->trianglesNum * 3 * 4, data, GL_STATIC_READ );


//--------- nabindujeme buffer a inicializujeme TF ----------------
glBindBufferBase( GL_TRANSFORM_FEEDBACK_BUFFER, 0, this->vboTransformFeedback );
glBeginTransformFeedback( GL_TRIANGLES );

//------------- vykreslíme -------------
glDrawElements( GL_TRIANGLES, this->trianglesNum * 3, GL_UNSIGNED_INT, (GLvoid*)0 );

//----------- ukončíme TF ------------------
glEndTransformFeedback( );
glBindBufferBase( GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0 );

//------------ vypíšeme výsledky -----------------------
data = new float[ this->trianglesNum * 3 * 4 ];
glBindBuffer( GL_TRANSFORM_FEEDBACK_BUFFER, this->vboTransformFeedback );
glGetBufferSubData( GL_TRANSFORM_FEEDBACK_BUFFER,  0,  sizeof(float) * this->trianglesNum * 3 * 4, data );

cout << "Mesh: transform feedback results:";
for( int i=0; i<this->trianglesNum * 3 * 4; i++ )
   cout << " " << data[i];
cout << endl;


Proběhne to bez chyb, ale nedojde k žádné změně hodnoty bufferu this->vboTransformFeedback. Buffer je stále plný floatů o hodnotě 0.987654.

Možná celý problém může souviset s tím, že mi to nic nevykresluje i když bych už pomalu dal ruku do ohně za tom, že to něco vykreslovat musí. Už mi to něco vykreslovalo, ale pak jsem začal měnit data modelu, který to načítá a polohu kamery a pak už se mi nepovedlo v tom nic zobrazit. Nejdříve jsem myslel, že je prostě vše mimo pohled kamery, ale tahle teorie už odpadla. This->trianglesNum má kladnou hodnotu, souřadnice vertexů po vynásobení maticemi jsou v pořádku (nejsou mimo okno - pohled).

Nechybí mi v tom transform feedbacku něco?

Díky.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
nou



Založen: 28. 07. 2007
Příspěvky: 1050

PříspěvekZaslal: 14. září 2013, 17:52:33    Předmět: Odpovědět s citátem

este si tam vytvor query a zistuj kolko primitiv ti zapisalo do toho buffera
kód:
glGenQueries(1, &query);
glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query);
glBeginTransformFeedback();
glDrawArray();
glEndTransformFeedback();
glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
glGetQueryObjectiv(query, GL_QUERY_RESULT, &count);

_________________
Najjednoduchšie chyby sa najtažšie hľadajú.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
TeaTime



Založen: 17. 06. 2011
Příspěvky: 264

PříspěvekZaslal: 14. září 2013, 18:29:28    Předmět: Odpovědět s citátem

nou napsal:
este si tam vytvor query a zistuj kolko primitiv ti zapisalo do toho buffera


Dobrý nápad, díky. Do buffery se zapsalo 0 primitiv.

Tak to budu muset ještě zanalizovat ten můj kód. Moc mi není jasné, jak to může vykreslit nula trojůhelníků, když zavolám glDrawElements s count rovno šesti.

Tak zatím díky zkusím na tom zapracovat, přivítám další hinty Smile.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
TeaTime



Založen: 17. 06. 2011
Příspěvky: 264

PříspěvekZaslal: 14. září 2013, 23:30:43    Předmět: Odpovědět s citátem

Tak už to funguje, ale nechápu to. Aby to začalo fungovat, tak jsem musel zavolat:

kód:
glEnableVertexAttribArray( 0 );
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0 );


Tedy povolit atribut 0 (nevím, který atribut má pozici nula, ale není to nic důležitého) a dát do něj nějaká data. Když jsem tam nedal data, tak mi ovladač hodil segfault.

Můžete mi někdo naznačit, čím by to mohlo být? Zdá se mi to dost nesmyslné. Proč se bez toho nevykreslí žádné elementy?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
nou



Založen: 28. 07. 2007
Příspěvky: 1050

PříspěvekZaslal: 15. září 2013, 08:48:45    Předmět: Odpovědět s citátem

no ocividne niektory z atributov tu nulu ma. zisti si to cez glGetActiveAttrib()
_________________
Najjednoduchšie chyby sa najtažšie hľadajú.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
TeaTime



Založen: 17. 06. 2011
Příspěvky: 264

PříspěvekZaslal: 15. září 2013, 10:36:35    Předmět: Odpovědět s citátem

nou napsal:
no ocividne niektory z atributov tu nulu ma. zisti si to cez glGetActiveAttrib()


Tak je to atribut 'boneIds'. A model, na kterém to zrovna testuji nemá kostru.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
nou



Založen: 28. 07. 2007
Příspěvky: 1050

PříspěvekZaslal: 15. září 2013, 14:04:35    Předmět: Odpovědět s citátem

tak ale shader ktorym sa to snazis vykreslit ten atribut definovany ma. ale ak je dany attribut vypnuty cez glDisableVertexAttribArray() tak by malo brat hodnotu ktora sa nastavy pomocou glVertexAttrib() ktora je standartne nastavena na [0,0,0,1]

OpenGL specification 2.8.3 napsal:
If an array corresponding to a generic attribute required by a vertex shader is not enabled, then the corresponding element is taken from the current generic attribute state (see section 2.7).

_________________
Najjednoduchšie chyby sa najtažšie hľadajú.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> 3D API / 3D Enginy Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2  Další
Strana 1 z 2

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna