Zobrazit předchozí téma :: Zobrazit následující téma |
Autor |
Zpráva |
TeaTime
Založen: 17. 06. 2011 Příspěvky: 264
|
Zaslal: 12. září 2013, 12:37:47 Předmět: OpenGL - vytažení hodnot z shaderu |
|
|
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 |
|
 |
perry

Založen: 28. 07. 2009 Příspěvky: 879
|
Zaslal: 12. září 2013, 12:41:43 Předmět: |
|
|
Jaká verze OpenGL ? _________________ Perry.cz |
|
Návrat nahoru |
|
 |
TeaTime
Založen: 17. 06. 2011 Příspěvky: 264
|
Zaslal: 12. září 2013, 12:52:40 Předmět: |
|
|
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 ). |
|
Návrat nahoru |
|
 |
perry

Založen: 28. 07. 2009 Příspěvky: 879
|
Zaslal: 12. září 2013, 12:58:54 Předmět: |
|
|
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  _________________ Perry.cz |
|
Návrat nahoru |
|
 |
TeaTime
Založen: 17. 06. 2011 Příspěvky: 264
|
Zaslal: 12. září 2013, 13:07:01 Předmět: |
|
|
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  |
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 |
|
 |
nou

Založen: 28. 07. 2007 Příspěvky: 1050
|
Zaslal: 12. září 2013, 13:34:03 Předmět: |
|
|
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 |
|
 |
TeaTime
Založen: 17. 06. 2011 Příspěvky: 264
|
Zaslal: 12. září 2013, 13:36:54 Předmět: |
|
|
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 |
|
 |
pcmaster

Založen: 28. 07. 2007 Příspěvky: 1827
|
Zaslal: 12. září 2013, 14:12:55 Předmět: |
|
|
Na tom uplne prvom priklade mi nie je celkom jasne, preco si myslis, ze by sa mal ten buffer zmenit po glDraw* 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 |
|
 |
TeaTime
Založen: 17. 06. 2011 Příspěvky: 264
|
Zaslal: 14. září 2013, 16:52:00 Předmět: |
|
|
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 |
|
 |
nou

Založen: 28. 07. 2007 Příspěvky: 1050
|
Zaslal: 14. září 2013, 17:52:33 Předmět: |
|
|
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 |
|
 |
TeaTime
Založen: 17. 06. 2011 Příspěvky: 264
|
Zaslal: 14. září 2013, 18:29:28 Předmět: |
|
|
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 . |
|
Návrat nahoru |
|
 |
TeaTime
Založen: 17. 06. 2011 Příspěvky: 264
|
Zaslal: 14. září 2013, 23:30:43 Předmět: |
|
|
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 |
|
 |
nou

Založen: 28. 07. 2007 Příspěvky: 1050
|
Zaslal: 15. září 2013, 08:48:45 Předmět: |
|
|
no ocividne niektory z atributov tu nulu ma. zisti si to cez glGetActiveAttrib() _________________ Najjednoduchšie chyby sa najtažšie hľadajú. |
|
Návrat nahoru |
|
 |
TeaTime
Založen: 17. 06. 2011 Příspěvky: 264
|
Zaslal: 15. září 2013, 10:36:35 Předmět: |
|
|
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 |
|
 |
nou

Založen: 28. 07. 2007 Příspěvky: 1050
|
Zaslal: 15. září 2013, 14:04:35 Předmět: |
|
|
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 |
|
 |
|