2013-05-19 12 views
7

Il problema:

Sto imparando OpenGL da http://www.arcsynthesis.org/gltut/index.html tutorial, e ho avuto il tempo davvero difficile ottenere Tutorial 13: Impostors geometria lavoro (6+ ore), ed è ora lavorando dopo un cambiamento davvero minimo nel codice che dovrebbe essere in realtà no-op, e ho bisogno del tuo aiuto per scoprire perché cambia qualcosa.GLSL, blocco di interfaccia

Spiegazione - a cura:

Il problema era che con il codice inalterato lo shader frammento non ha ottenuto corretto input dal geometry shader, ma sia con la sostituzione geometry shader di fuori blocco dell'interfaccia per separare le variabili o dare il blocco un nome di istanza fa funzionare bene il programma. Ma questi cambiamenti dovrebbero essere vietati.

Il problema è probabilmente una collisione di nome.

Ti piace questa non funziona:

in VertexData 
{ 
    vec3 cameraSpherePos; 
    float sphereRadius; 
} vert[]; 

out FragData 
{ 
    flat vec3 cameraSpherePos; 
    flat float sphereRadius; 
    smooth vec2 mapping; 
}; 

void main() 
{ 
    mapping = 
    cameraSpherePos = 
    sphereRadius = 
    EmitVertex(); 
    /* mapping's value doesn't get to the fragment shader correctly */ 
} 

Ma in entrambi dando FragData un nome di istanza come la frammentazione, e l'utilizzo di frag.mappaing instad di mappatura, o utilizzando 3 variabili separate risolve il problema.

Perché non funziona senza un nome di istanza?

Modifica: sembra essere un problema di driver.

+0

Quale hardware è in esecuzione? –

+0

Il programma è in esecuzione #verison 330 su: Geforce GTS 360M - "3.30 NVIDIA tramite compilatore Cg" – IceCool

+0

Hm, più shader e codice C++ potrebbero aiutare a fornire una risposta più accurata. Nel tuo gs shader stai inizializzando/impostando ogni membro di FragData corretto per ogni iterazione del vertice, prima di chiamare EmitVertex(). Inoltre, se hai più invocazioni, assicurati di aver impostato correttamente FragData. – dinony

risposta

2

creare nomi di istanza per tutti i blocchi di interfaccia come:

FragData { // .. } gs2fs; 

E poi:

gs2fs.cameraCornerPos = vec4(vert[0].cameraSpherePos, 1.0); 
2

L'utilizzo di campioni GLSL spesso diventa noioso a causa di problemi di versione.

Alcuni generale consiglio di debug:

  • verificare che hai incluso la corretta tag versione nella sorgente dello shader
  • verificare che il driver OpenGL supporta in realtà che la versione chiamando glGetString(GL_SHADING_LANGUAGE_VERSION)
  • creare mezzi di shader di runtime -recompilazione (ad es. assegnandola ad un evento chiave)
  • e FOREMOST: utilizzare glGetShaderInfoLog() e glGetProgramInfoLog()!
+0

Sto usando #version 330 per il mio programma, che è supportato dalla mia GPU. Attualmente sto programmando in C++ non c, quindi uso la funzione che se la compilazione/collegamento non ha avuto successo, viene generata un'eccezione con il messaggio di registro come what(). Questo rende il codice un po 'più facile da leggere + Non devo creare un "char logbuffer [2000];" solo per poter chiamare la funzione infolog. – IceCool

+0

I livelli intermedi multipli non ti aiuteranno a isolare il bug, e dubito che le persone saranno troppo inclini a costruire un framework tanto solido quanto questo framework tuts solo per aiutarti. Quindi prova a costruire un esempio MINIMALE che riproduca l'assunto "bug" usando le misure di debug di GLSL che ti ho detto. – Solkar

1

Il problema in realtà era con non utilizzando il driver più recente.

Stavo eseguendo su linux e ho ottenuto l'ultimo driver dal gestore di pacchetti di Ubuntu: Nvidia 310-experimental. Ma anche se è sperimentale, è piuttosto vecchio. Con l'installazione manuale del 319 dal sito di nvidia, il codice funzionava bene senza alcuna modifica.

Morale della favola:

utilizzare sempre i driver più recenti.