GLSL - Umschreiben von Shadern von # 330 auf # 130

7

Ich habe kürzlich ein Spiel ( LD21 ) erstellt, das einen Geometrie-Shader verwendet, um Punkte in strukturierte Dreiecke / Keulen umzuwandeln. Da ich den Eindruck hatte, dass die Unterstützung für # 330 weit verbreitet war, habe ich nur # 330-Shader geschrieben, aber es scheint, dass viele nicht so alte Hardware nur # 130 unterstützen (laut GLView)

Da ich nur mit der Kernfunktionalität von # 330 vertraut bin, habe ich Probleme, meine Shader auf # 130 umzuschreiben. Das Umschreiben des Fragment-Shaders war ziemlich trivial, aber ich habe es nur geschafft, meinen Scheitelpunkt- und Geometrie-Shader auf # 150 zu bringen.

Ist es also möglich, die Shader neu zu schreiben, oder wären viele Änderungen an meiner Rendering-Engine erforderlich?

Geometrie-Shader

#version 150
layout(points) in;
layout(triangle_strip, max_vertices = 4) out;
uniform mat4 oMatrix;
in VertexData
{
    vec4 position;
    vec4 texcoord;
    vec4 size;
} vert;

out vec2 gTexCoord;

void main()
{
    if(vert.position.x>-4f && vert.position.x<4f && vert.position.y>-2f && vert.position.y<2f)
    {
        gTexCoord=vec2(vert.texcoord.z,vert.texcoord.y);
        gl_Position = vert.position + vec4(vert.size.x,vert.size.y,0,0);
        EmitVertex();

        gTexCoord=vec2(vert.texcoord.x,vert.texcoord.y);
        gl_Position = vert.position + vec4(0.0,vert.size.y,0,0);
        EmitVertex();

        gTexCoord=vec2(vert.texcoord.z,vert.texcoord.w);
        gl_Position = vert.position + vec4(vert.size.x,0.0,0,0);
        EmitVertex();

        gTexCoord=vec2(vert.texcoord.x,vert.texcoord.w);
        gl_Position = vert.position;
        EmitVertex();

        EndPrimitive();
    }
}

Vertex-Shader

#version 150
#extension GL_ARB_explicit_attrib_location : enable

layout (location = 0) in vec2 position;
layout (location = 1) in vec4 textureCoord;
layout (location = 2) in vec2 size;
uniform mat4 oMatrix;
uniform vec2 offset;
out VertexData
{
    vec4 position;
    vec4 texcoord;
    vec4 size;
} outData;

void main()
{
    outData.position = oMatrix * vec4(position.x+offset.x,position.y+offset.y,0,1);
    outData.texcoord = textureCoord;
    outData.size = oMatrix * vec4(size.x,size.y,0,0);
}
nilstastisch
quelle
Vergessen Sie nicht, sich über die Funktionen zum Akzeptieren und Abstimmen zu informieren.
Christian Rau
2
"Vergessen Sie nicht, sich über die Funktionen zum Akzeptieren und Abstimmen zu informieren." Lesen Sie: "Akzeptieren Sie meine Antwort."
Jonathan Connell
1
@ Jonathan war nicht so gemeint. Es ist nicht unhöflich, nicht zu akzeptieren, wenn die Antwort nicht hilfreich war. Eigentlich hat das OP meine Antwort vielleicht zu schnell akzeptiert (sorry dafür). Aber ich sehe oft (selbst in meinem noch kurzen SO-Leben), dass einmalige Besucher eine Frage stellen und sie dann komplett vergessen (vielleicht haben sie sie 3 Minuten später selbst gelöst oder sie haben die Seite als Forum verwechselt). Das Reputationssystem ist jedoch die treibende Kraft dieser Feedback-orientierten Q & A-Site. Es war nicht beabsichtigt, meine Antwort sofort ohne nachzudenken zu akzeptieren, sondern wie geschrieben, sich der Akzeptanzfunktion bewusst zu sein (so wie es viele Neulinge nicht tun).
Christian Rau
@ Jonathan Und übrigens habe ich diese Erinnerungen bereits in ersten Fragen geschrieben, die ich nicht beantwortet habe. Aber Sie haben Recht damit, dass es hier ein bisschen eigennützig ist.
Christian Rau
1
@Christian Rau Dies passiert in der Tat manchmal, obwohl es wahrscheinlich am besten ist, den Menschen den Vorteil des Zweifels zu geben. Wenn Sie einen Kommentar schreiben möchten, "Willkommen, bitte lesen Sie die Site-Regeln" wäre IMO besser geeignet :) Oh und +1 für Ihre Antwort;)
Jonathan Connell

Antworten:

5

Zunächst einmal können Sie structs nicht zum Variieren von Daten verwenden (geändert um 1,50), aber Sie können weiterhin inund outanstelle von attributeund verwenden varying. Zusätzlich müssen Sie in die eingebaute Variable gl_Positionim Vertex-Shader schreiben (geändert um 1.40). Ersetzen Sie also in Ihrem Vertex-Shader die Deklaration von outDatadurch etwas Ähnliches wie

out vec4 texcoord;
out vec4 vSize;       //size already used

und verwenden gl_Positionstatt outData.position.

Ich bin nicht sicher, ob die Erweiterung ARB_explicit_attrib_location bereits der Kern ist. Vielleicht müssen Sie sie hinzufügen

#extension ARB_explicit_attrib_location : require

Verwenden Sie die layoutSyntax oder legen Sie einfach die Attributpositionen in der Anwendung fest, indem Sie glBindAttribLocationvor dem Verknüpfen des Shaders aufrufen , wenn diese Erweiterung nicht unterstützt wird.

Ändern Sie im Geometrie-Shader die Dekralierung von vert in so etwas wie

in vec4 texcoord[];      //names have to match vertex shader, of course
in vec4 vSize[];

Obwohl Sie nur eine einzige Eingabe erhalten (da Sie Punkte verwenden), müssen sie meiner Meinung nach immer noch Arrays sein (obwohl sie bei Verwendung immer mit indizieren [0]). Ändern Sie die Verwendung von vert.positionto gl_PositionIn[0].

Als nächstes denke ich, dass die layoutSyntax für den Geometrie-Shader in 1.50 eingeführt wurde, sodass Sie möglicherweise das Layout des Geometrie-Shaders in der Anwendung mithilfe von festlegen müssen glProgramParameteri.

Ich muss zugeben, dass ich nicht viel praktische Erfahrung mit Geometrie-Shadern oder der modernen Syntax habe, da ich immer noch auf 2.1-Hardware sitze, aber all diese Änderungen lassen sich aus den jeweiligen Spezifikationen ableiten . Schauen Sie sich einfach die Shader-Info-Protokolle an, wenn beim Kompilieren (oder Verknüpfen) keine Hinweise darauf erhalten werden, was möglicherweise falsch ist.

Das Fehlen der layoutSyntax sowohl im Scheitelpunkt als auch im Geometrie-Shader sind die einzigen Dinge, die möglicherweise einige kleine Ergänzungen zu Ihrem Anwendungscode erfordern, aber ich bin nicht ganz sicher, ob sie wirklich nicht unterstützt werden. Versuchen Sie es also zuletzt.

Sie können Ihre Frage auch aktualisieren, wenn ich etwas verpasst habe und die Shader immer noch nicht funktionieren, möglicherweise diesmal mit einigen Fehlermeldungen vom GLSL-Compiler.

Christian Rau
quelle
Vielen Dank! Ich habe es auf # 140 gebracht, aber # 130 ist in meiner Reichweite :)
Nilstastic
1
@nilstatic Also was hast du geändert und was funktioniert immer noch nicht. Vielleicht können Sie Ihre Frage so bearbeiten, dass sie die neuen 1,40-Shader enthält. Wenn Sie bereits 1.40 haben, müssen Sie möglicherweise nur die Verwendung Ihrer benutzerdefinierten positionvariierenden to gl_Position ändern.
Christian Rau