Seite 1 von 1
glGetUniformLocation(..) ständig ungültig
Verfasst: 14.07.2015, 09:50
von joggel
Hallo ZFX,
ich versuche mich gerade etwas in die OpenGL-Api reinzufitzen.
Also, ab Version 3.
Ich benutze dabei GLFW und GLEW als Hilfe.
Die Fixed-function-Pipeline ist ja nun schon lange vergessen und ich möchte mich nun endlich mal mit Shadern beschäftigen.
Das erstellen eines Fensters und das Zeichnen eines Quads funktioniert schon mal.
Ich kann auch im Shader festlegen, in welcher Farbe das Quad gezeichnet werden soll.
Also funktioniert schon mal das Verwenden der Shader.
Nun möchte ich eine uniform-Variable vewenden...
Das Problem ist nur, dass ich ständig -1 bei diesem Funktionsaufruf bekomme:
Code: Alles auswählen
GLint textureUniformID = glGetUniformLocation(mShader.mProgramID, "aUniformVar");
Obwohl ich aber im Shader-Code eindeutig diese Variable als uniform angegeben habe und
mShader.mProgramID scheint auch einen gültigen Wert zu haben.
Eigentlich bekomme ich ständig -1 als Rückgabewert bei dem "
glGetUniformLocation"-Aufruf.
Ich verstehe es nicht und so langsam werde ich frustriert.
Ich hoffe nun, dass mir hier einer einen entscheidenden Tipp geben kann...
Gruß
joggel
Re: glGetUniformLocation(..) ständig ungültig
Verfasst: 14.07.2015, 10:05
von joggel
Nun gut. Ich glaube, das Problem hat sich erledigt.
Ich müsste die uniform-Variable auch im Shader-Code verwenden...
Wenn man sie nur deklariert, dann optimiert OpenGL diese Variable eben weg. Ist ja auch sinnvoll.
Gut! Jetzt muss ich nur meine sampler2D-Variable korrekt verwenden.
Danke trotzdem für das eventuelle Lesen und beantworten dieser Frage :)
Re: glGetUniformLocation(..) ständig ungültig
Verfasst: 14.07.2015, 10:05
von Schrompf
Poste mal den Shadercode. Es kann nämlich sein, dass Du im Shader die Variable gar nicht verwendest. Dann wird sie rausoptimiert und hat demzufolge auch keine Location mehr.
[edit] HA! Siehste :-)
Und zum Thema Sampler: Sampler haben auch eine Uniform Location, aber Du musst im Code dem Ding im Nachhinein noch einen "Texturslot" oder wie ich ihn nennen soll zuweisen. So wie hier z.B.
Code: Alles auswählen
GLuint location = glGetUniformLocation( prgid, "MySampler");
// der Sampler wird ab sofort auf Slot 0 gemappt
glProgramUniform1i( prgid, idx, 0);
// damit Du später dann auf Slot 0 ne Textur und Sampler und so binden kannst
glActiveTexture( GL_TEXTURE0);
glBindTexture( GL_TEXTURE_2D, texid);
blBindSampler( 0, smplrid);
Re: glGetUniformLocation(..) ständig ungültig
Verfasst: 14.07.2015, 10:06
von joggel
Jopp. Das war es!
Re: glGetUniformLocation(..) ständig ungültig
Verfasst: 14.07.2015, 10:10
von Schrompf
Hab noch ne spekulative Antwort auf die Sampler-Frage reineditiert.
Re: glGetUniformLocation(..) ständig ungültig
Verfasst: 14.07.2015, 10:19
von joggel
Okay, danke.
Werd sehen ob mir das evtl. hilft.
Re: glGetUniformLocation(..) ständig ungültig
Verfasst: 15.07.2015, 11:14
von Jonathan
Man kann auch im Shader Code direkt per layout-Qualifier die location festlegen. Hat dann den Vorteil, dass man sie im Programm nicht abfragen muss, was meines Wissens nach einen Stall verursacht, weil die Grafikkarte den Wert erst ermitteln kann, wenn sie mit dem Rest fertig ist. Ob das eine Rolle spielt, wenn du 5 uniforms setzt und direkt danach renderst weiß ich nicht, aber für einfache Shader ist es ja kein Problem, die Werte festzulegen, weshalb man mit dieser Technik keine Nachteile haben sollte.
Weiß eigentlich jemand ob ineffizient ist, wenn man nicht die locations 0...n benutzt, sondern einfach irgendwelche und dann größere Lücken in seinen Benutzen IDs hat und evtl. auch sehr große IDs benutzt? Wird da irgendwie Speicherplatz verschwendet? Denn ich habe das manchmal gemacht, um für einige Standard-Uniforms feste locations zu haben (die fingen dann halt bei 10 an oder so).
Re: glGetUniformLocation(..) ständig ungültig
Verfasst: 15.07.2015, 17:15
von joggel
Also ich weiß dazu nichts, sorry.
Aber mich würde mal interessieren wie Du das konkret mit den layout meinst.
Ich verwende layout nur bei der Übergabe der Vertices und Texturkoordinaten.
Könntest du da vlt. etwas Code posten?
Ich frage deshalb, weil ich das mit den Samplern vs Layout nicht recht verstanden habe.
Wieso haben Texturen mehrere "Slots"?
und überhaupt.... :?:
Ich habe da mal etwas gegoogelt, und mir macht es den Eindruck, als seien Sampler irgend eine Neuerung um Texturen im Programm und Shader besser bzw. einfacher zu handeln.
Re: glGetUniformLocation(..) ständig ungültig
Verfasst: 15.07.2015, 21:02
von xq
Sampler = "Ding" zum Auslesen von Texturen inclusive Filtering
Slots: Deine Grafikkarte kann gleichzeitig bis zu n Texturen aktiv haben, das sind die Slots. Wenn du eben eine Textur in jedem Shader brauchst, bindest du die Textur in Slot 0, alle "temporären" packste in einen anderen Slot.
layout(location = x): Definiert die Location eines Inputs. Sei es Vertex Data (das hast du ja schon) oder seien es Uniforms (getUniformLocation entfällt, da "return value" eh hart gecoded)
Und sampler sind keine Neuerung, jedenfalls nicht mehr seit OpenGL 1 :D
das wäre mal die kurzfassung
Re: glGetUniformLocation(..) ständig ungültig
Verfasst: 16.07.2015, 08:47
von joggel
Ah, okay. Verstehe..
MasterQ32 hat geschrieben:
Und sampler sind keine Neuerung, jedenfalls nicht mehr seit OpenGL 1 :D
Ich meinte eigentlich auch Sampler Objects, sorry.
Re: glGetUniformLocation(..) ständig ungültig
Verfasst: 16.07.2015, 20:20
von Jörg
Jonathan hat geschrieben:Man kann auch im Shader Code direkt per layout-Qualifier die location festlegen. Hat dann den Vorteil, dass man sie im Programm nicht abfragen muss, was meines Wissens nach einen Stall verursacht, weil die Grafikkarte den Wert erst ermitteln kann, wenn sie mit dem Rest fertig ist.
Stimmt so nicht. Der Treiber hat eine Tabelle für jeden Shader zu halten, welche Namen/Strings auf eine Location abbildet (oder eine andere geignete Datenstruktur welche selbiges erlaubt).
Eine Abfrage der Location ist nichts weiter als eine Suche darin. Das spart man sich wenn man mit expliziten Locations arbeitet. Und selbst für Symbole mit expliziten Locations kann man die Abfrage durchführen (und sollte natürlich den erwarteten Wert erhalten).
Große Werte sollten keine Probleme machen. NurGL_MAX_UNIFORM_LOCATIONS nicht überschreiten.