2013-05-19 16 views
7

Das Problem:

Ich lerne OpenGL von http://www.arcsynthesis.org/gltut/index.html Tutorial, und ich hatte wirklich harte Zeit, Tutorial 13: Geometrie Impostors Arbeits (6+ Stunden), und es ist jetzt arbeite nach einer wirklich kleinen Änderung im Code, der eigentlich kein Op sein sollte, und ich brauche deine Hilfe, um herauszufinden, warum es irgendetwas ändert.GLSL, Schnittstellenblock

Erklärung - bearbeitet:

Das Problem war, dass die Fragment-Shader mit dem unveränderten Code nicht korrekt Eingabe von den Geometrie-Shader bekommen haben, aber mit entweder Geometrie-Shader die aus Schnittstellenblock ersetzen Variablen zu trennen oder geben der Block ein Instanzname macht das Programm gut. Aber diese Änderungen sollten no-op sein.

Das Problem ist wahrscheinlich eine Namenskollision.

Wie dies funktioniert es nicht:

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 */ 
} 

Aber entweder geben FragData einen Instanznamen wie frag, und mit frag.mappaing instad von Mapping oder mit 3 separaten Variablen löst das Problem.

Warum funktioniert es nicht ohne einen Instanznamen?

Edit: Es scheint ein Treiberproblem zu sein.

+0

Mit welcher Hardware betreiben Sie das? –

+0

Programm läuft #verison 330 on: Geforce GTS 360M - "3.30 NVIDIA via CG-Compiler" – IceCool

+0

Hm, mehr Shader und C++ - Code würde helfen, eine genauere Antwort zu geben. In Ihrem gs-Shader initialisieren/setzen Sie jedes Member von FragData für jede Vertex-Iteration korrekt, bevor Sie EmitVertex() aufrufen. Wenn Sie mehrere Aufrufe haben, stellen Sie sicher, dass Sie die FragData korrekt eingestellt haben. – dinony

Antwort

2

für alle Schnittstellenbausteine ​​Instanznamen erstellen wie:

FragData { // .. } gs2fs; 

Und dann:

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

Das Arbeiten mit GLSL-Samples wird oft aufgrund von fiesen Versionsproblemen mühsam.

Einige allgemeine Debugging-Tipps:

  • überprüfen, ob Sie die richtige Version Tags in Ihrem Shader Quelle
  • enthalten
  • , dass Ihre OpenGL überprüfen Treiber tatsächlich unterstützt diese Version von glGetString(GL_SHADING_LANGUAGE_VERSION)
  • Aufruf mittels Laufzeit-Shader erstellen -Recompilation (z. B. durch Zuordnen zu einem Schlüsselereignis)
  • und FOREMOST: glGetShaderInfoLog() und glGetProgramInfoLog() verwenden!
+0

Ich verwende die #version 330 für mein Programm, das von meiner GPU unterstützt wird. Eigentlich programmiere ich in C++ nicht c, also benutze ich die Funktion, dass, wenn die Kompilierung/Verknüpfung nicht erfolgreich war, eine Ausnahme mit der Protokollmeldung als what() ausgelöst wird. Das macht den Code ein bisschen einfacher zu lesen + Ich muss keinen "char logbuffer [2000];" nur um die Infolog-Funktion aufrufen zu können. – IceCool

+0

Mehrere Zwischenschichten werden Ihnen nicht helfen, den Fehler zu isolieren, und ich bezweifle, dass Leute übermäßig geneigt sein werden, ein Framework so dick zu erstellen, dass es Ihnen nur hilft. Versuchen Sie also, ein MINIMAL-Beispiel zu konstruieren, das den angenommenen "Bug" mit den GLSL-Debugging-Maßnahmen reproduziert, die ich Ihnen gesagt habe. – Solkar

1

Das Problem war eigentlich mit nicht den neuesten Treiber verwenden.

Ich lief dies auf Linux, und bekam den neuesten Treiber von Ubuntu Paket-Manager: die Nvidia 310-experimental. Aber obwohl es experimentell ist, ist es ziemlich alt. Mit der manuellen Installation des 319 von der Nvidia-Website funktionierte der Code ohne Änderungen.

Moral der Geschichte:

Verwenden Sie immer die neuesten Treiber.