Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
Hallo Leute! Ich war leider schon länger nicht mehr hier und stolpere natürlich auch gleich mit einem neuen Problem in die Tür.
Es geht diesmal um OpenGL4 und GLSL4 unter Windows7 mit NVidia Quadro 4000 und NVidia GTX 560 Ti (aktuellste Treiber). Programmieren tue ich in C# mittels OpenTK.
Das eigentliche Problem: Ich versuche einen einfachen Standardshader (Vertex+Fragment) zum Laufen zu bekommen. Das scheitert allerdings jedesmal bei glUseProgram(). Der Fehlercode, der mir anschließend von glGetError() gegeben wird ist immer "GL_INVALID_OPERATION". Was mich daran wundert ist, dass alle vorherigen Aufrufe bezüglich des Shaders (Sourcen laden, compilien, attachen, linken) keinen Fehler generieren und auch die InfoLogs nach kompilieren und linken leer sind. Aus der Spezifikation von glUseProgram hab ich heraus gelesen, dass besagter Fehlercode auf eine falsche ID zurückgeführt werden könnte, was ich aber sicher ausschließen kann. Die übergebene ID ist in jedem Fall richtig. Laut NVidia decken die beiden Grafikkarten OpenGL bis Version 4.4 und 4.5 vollständig ab, nutzen tue ich jedoch lediglich "#version 400" in den Shadern. Beide Karten zeigen das gleiche verhalten.
Die Frage ist jetzt, was könnte sich dahinter verbergen? Wo könnte ich meine Fehlersuche fortsetzen? Hat eventuell jemand ein solches Problem schon selbst gehabt und eine Lösung parat?
Gruß, Sellmann.
Vertexshader:
Code:
#version 400
layout(location =0)invec3 vertex_position;
layout(location =1)invec3 vertex_color;
outvec3 color;
void main ()
{
color = vertex_color;
gl_Position=vec4(vertex_position,1.0);
}
Fragmentshader:
Code:
#version 400
invec3 color;
outvec4 fragColor;
void main()
{
fragColor =vec4(color,1.0);
}
Edit: Ich hab gerade noch einen Typ-Fehler im Fragmentshader behoben. Das Problem besteht aber weiterhin.
_________________ Klar Soweit?
Zuletzt geändert von Sellmann am Mo Dez 08, 2014 09:57, insgesamt 2-mal geändert.
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Das wäre wohl zu einfach, wenn das der Fehler wäre, aber überprüf das mal:
opengl.org hat geschrieben:
GL_INVALID_OPERATION is generated if transform feedback mode is active.
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Dann ist es auch nicht aktiv. Es muss was anderes sein...
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Noch 2 Ideen: - Bist du ganz sicher, dass erst glUseProgram den Fehler auslöst und nicht schon ein Funktionsaufruf davor? - Hast du auch tatsächlich einen OpenGL 4.0 (oder höher)-Kontext erstellt? Also forward-compatible, wie hier beschrieben: Tutorial OpenGL3 Zeichenkontext
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
Zu 1: Ja, da bin ich mir sehr sicher. Das Programm besteht bisher nur aus einem Kontext, Viewport Initialisierung und der Erzeugung der Shader. Nach jedem glXyz() frag ich mittels glGetError() einmal die Fehler ab und erst nach glUseProgram() steht was anderes als "GL_NO_ERROR" drin.
Zu 2: Da ich die mitgelieferte GlControl Komponente aus dem OpenTK-Framework verwende, kann ich nicht genau sagen, ob das intern tatsächlich geklappt hat mit dem GL4-Kontext. Ich geh dem mal auf den Grund und meld mich gleich zurück.
Edit: Ich hab mir jetzt die Kontextgenerierung angeschaut und bin mir sicher, dass ich einen Kontext mit OpenGl v4.4.0 und GlSl v4.40 habe.
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Dann müsste der Fehler ja ebenfalls auftreten, wenn du aus deinem Shader alle OpenGL3+-Spezialitäten entfernst:
Code:
// Vertexshader
attributevec3 vertex_position;
attributevec3 vertex_color;
varyingvec3 color;
void main ()
{
color = vertex_color;
gl_Position=vec4(vertex_position,1.0);
}
Code:
// Fragmentshader
varyingvec3 color;
void main()
{
gl_FragColor=vec4(color,1.0);
}
Tut er das?
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
Mit dem von dir genannten Shader funktioniert es gar nicht mehr. Es wird zumindest nichts mehr auf den Bildschirm gezeichnet. Nicht einmal die ClearColor wird dargestellt. Scheinbar gibt es dann ein Problem damit, dass ich das CoreProfile von GL4.4 verwende. Ich müsste mich dann mal umschauen, wie ich das CompatibilityProfile mit dem GlControl aktiviere, um auch noch alles verwenden zu dürfen, was ab 3.x als deprecated eingestuft wurde.
Edit: Der Kontext sagt mir zur Laufzeit, dass er im CompatibilityProfile läuft, obwohl das eigentlich nicht der Fall sein sollte. Merkwürdigerweise sollte dein Shader dann doch funktionieren, oder nicht?
Edit2: Ich lese gerade, dass das Core und Compatibility ab 3.2+ identisch sein sollen, was ich irgendwie komisch finde.
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
Ja, die Routine funktioniert. Zumindest erhalte ich beim Kompilieren keinen Fehler, das Infolog ist leer und wenn ich den Sourcecode vom Shader abfrage, erhalte ich auch exakt den Inhalt der Datei wieder zurück.
Edit: Ich probier gerade das ganze mit freepascal zum Laufen zu bekommen, um zu gucken, ob es vielleicht am OpenTK Framework liegt. Das Problem ist, dass ich gerade kein Beispiel finden kann, wie ich einen OpenGL 3.x+ Kontext in freepascal erzeuge. Die Beispiele die ich habe sind in C++ und nutzen alle den Typ "PIXELFORMATDESCRIPTOR", den ich nicht finden kann. Sollte es nicht mal eine Methode geben einen 3.x+ Kontext zu erstellen, ohne zuvor einen 2.1 Kontext generieren zu müssen?
Edit2: Hab jetzt den Kontext. Ich kannte die Methode "CreateRenderingContextVersion" noch nicht. Ich schreib dann nochmal, wenn ich den Rest übersetzt hab.
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
Okay, das ist merkwürdig. Der oben genannte Shader lässt sich ohne Weiteres in freepascal verwenden. Es scheint wohl am Framework selbst zu liegen. Ich glaube dann wende ich mich besser an die Entwickler von OpenTK. Ich kann mir das zwar nicht wirklich vorstellen, weil ich scheinbar der einzige mit dem Problem bin, aber möglich wäre es ja...
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
Ich verstehe die Welt nicht mehr!
Ich hab das obige Beispiel in freepascal auf Anhieb zum Laufen bekommen. Jetzt habe ich das ganze erweitert, dass ich meine Scene zunächst in mehrere Texturen render und anschließend als Fullscreen Quad auf den Bildschirm bringe. Klassisches Deffered Rendering halt. Soweit ist auch alles gut. Möchte ich jetzt allerdings den Geometry Shader aus dem Wiki verwenden, um die TBN Matrix für den Normalbuffer zu berechnen, passiert genau das gleiche wie vorher. Alles kompiliert und linkt, aber glUseProgram scheitert. Klammere ich den Geometry Shader aus, erhalte ich zumindest eine gerenderte Szene, ansonsten bleibt das Bild schwarz.
Hierzu sei erwähnt, dass ich den Shader an meinen Vokabular angepasst habe, weil mir die Variablenbezeichnungen nicht gepasst haben. Außerdem hab ich das Versiontag von 330 auf 400 gesetzt und die Variablenübergabe zwischen den Shadern in structs gepackt.
Ich habe ehrlich gesagt keinerlei Ahnung, wie ich die Fehlersuche gestalten soll, da ich ja keine konkreten Hinweise von der Fehlerauswertung erhalte, außer, dass der Geometryshader wohl der ausschlaggebende Punkt ist. Fehlt vielleicht eine Extension? Hab ich eine Namenskonvention verletzt?
Hier einmal alle drei Shader, die ich verwende:
Code:
//Vertexshader
#version 400
layout(location =0)invec3 vertexPosition;
layout(location =1)invec3 vertexNormal;
layout(location =2)invec2 vertexUVCoord;
uniformmat4 Projection;
uniformmat4 View;
uniformmat4 Model;
out VertToGeom
{
vec3 Position;
vec3 Color;
vec3 Normal;
vec2 uvCoord;
} DataOut;
void main ()
{
DataOut.Position=(View * Model *vec4(vertexPosition,1.0)).xyz;
DataOut.Color=vec3(1.0,1.0,1.0);
DataOut.Normal=normalize((View * Model *vec4(vertexNormal,0.0)).xyz);
//DataOut.Normal = vertexNormal;
DataOut.uvCoord= vertexUVCoord;
gl_Position= Projection * View * Model *vec4(vertexPosition,1.0);
}
Code:
//Geometryshader
#version 400
layout(triangles)in;
layout(triangle_strip, max_vertices=3)out;
// Variablen, die vom Vertex- an den Geometry-Shader weitergereicht werden:
in VertToGeom
{
vec3 Position[];
vec3 Color[];
vec3 Normal[];
vec2 uvCoord[];
} DataIn;
// Variablen, die vom Geometry- an den Fragment-Shader weitergereicht werden:
vec3 n = texture(NormalMap, DataIn.uvCoord).xyz*2.0-1.0;
vec3 n_transformed = TBN * n;
fragNormal =vec4(n_transformed*0.5+0.5,1.0);
}
Edit: Der auskommentierte Code im Fragmentshader kommt von einer anderen Seite, mit deren Hilfe ich zuerst versuchte die TBN-Matrix zuberechnen, aber die Ergebnisse waren irgendwie nicht richtig, deshalb wollte ich das mit dem Geometryshader aus dem Wiki vergleichen. Ich suche den Link dazu mal rauß.
Klammere ich den Geometry Shader aus, erhalte ich zumindest eine gerenderte Szene, ansonsten bleibt das Bild schwarz.
Dies ist irgendwie komisch, ich habe ein kleines Test-Programm mit einem Geometrie-Shader. Wen ich dort den Geo-Shader ausklammere, dann bekomme ich einen Link-Fehler, geschwiegen von einem gerenderten Bild.
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
Nein, bisher habe ich noch keine Geometryshader verwendet. Ist quasi meine Jungfernfahrt auf dem Gebiet.
Edit: Das mit dem Linkerfehler kann daran liegen, dass die Vertex- und Fragmentshader ja ebenfalls mit dem Geometryshader verdrahtet werden. Das löse ich natürlich auch auf, wenn ich den Geometryshader ausklammere. Man könnte sagen, ich passe das Interface dazwischen an, damit keine Abhängigkeit mehr entsteht. Die Funktionsweise der beiden Shader bleibt allerdings gleich. Das Ergebnis ist, dass Vertex- und Fragmentshader problemlos zusammenarbeiten und auch alle Daten und Zugriffe von Texturen, VBOs, VAOs und FBOs richtig verarbeitet werden. Das ganze platzt erst, wenn der Geometryshader eingefügt wird. Wobei jedoch noch angemerkt werden muss, dass der Geometryshader beim Kompilieren keinen Fehler meldet und auch das Shaderprogramm beim Linken den Geometryshader ohne Weiteres zu akzeptieren scheint.
Edit2: Ich häng nochmal die Routine dran, mit der ich den Shader erzeuge. Vielleicht ist da ja noch etwas, was nicht ganz sauber ist. Die glGetError-Aufrufe hab ich der Übersichtlichkeit entfernt.
Code:
procedure TForm1.LoadSceneShader();
var sl: TStringList;
vertSource, geomSource, fragSource :string;
vertLength, geomLength, fragLength :integer;
vert, geom, frag : GLhandle;
begin
sl := TStringList.Create();
sl.LoadFromFile('.\Shader\scene.vs');
vertSource := sl.Text;
sl.Clear();
sl.LoadFromFile('.\Shader\scene.gs');
geomSource := sl.Text;
sl.Clear();
sl.LoadFromFile('.\Shader\scene.fs');
fragSource := sl.Text;
sl.Clear();
FreeAndNil(sl);
vert := glCreateShader(GL_VERTEX_SHADER);
vertLength :=Length(vertSource);
glShaderSource(vert,1,@vertSource,@vertLength);
glCompileShader(vert);
geom := glCreateShader(GL_GEOMETRY_SHADER);
geomLength :=Length(geomSource);
glShaderSource(geom,1,@geomSource,@geomLength);
glCompileShader(geom);
frag := glCreateShader(GL_FRAGMENT_SHADER);
fragLength :=Length(fragSource);
glShaderSource(frag,1,@fragSource,@fragLength);
glCompileShader(frag);
self.fSceneShaderProgram:= glCreateProgram();
glAttachShader(self.fSceneShaderProgram, vert);
glAttachShader(self.fSceneShaderProgram, geom);
glAttachShader(self.fSceneShaderProgram, frag);
glLinkProgram(self.fSceneShaderProgram);
glDeleteShader(vert);
glDeleteShader(geom);
glDeleteShader(frag);
glUseProgram(self.fSceneShaderProgram);// <= hier tritt das erste mal eine GL_INVALID_OPERATION auf (Fehlercode 1282)
Mitglieder in diesem Forum: 0 Mitglieder und 6 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.