OpenGL Vertexshader
-
Musste erstmal nachlesen was ftransform() macht, da ich es nie nutz.
Versuch mal folgendes:
... if (in_position != 0) { gl_Position = ftransform(); gl_Position = gl_Position + vec4(100,0,0,0); } ...
oder kürzer:
gl_Position.x += 100;
Wobei ich sagen muss, ich bin mir nicht sicher, ob man das so machen würde.
Bin selbst noch Anfänger (beschäftige mich erst seit 3 Tagen mit GLSL und HLSL).
-
Hmm also im RenderMonkey funktioniert der Code so wie er soll. Aber in meinem Programm wenn ich die Variable move so bestimme:
glUniform1i(glGetUniformLocation(ProgramObject, "move"),1);
passiert nichts.
Das ist jetzt mein Code vom Vertex-Shader:#version 120 uniform int move; void main(void) { gl_Position = ftransform(); if (move != 0) { gl_Position.x += 10.0f; } }
-
grübel - funktioniert bei mir einwandfrei.
Haste dir mal die InfoLogs ausgeben lassen von Shader und Program? Vlt. steht da was interessantes drin.
-
Ja, Infolog ist leer.
EDIT:
Vielleicht liegt es ja auch an ftransform(). Wie übergibst du denn die Vektoren an den Shader?EDIT 2:
Ok ich Idiot hab vergessen, dass ich vorher glUseProgram aufrufen muss
Allerdings bewegt sich mein Viereck Jetzt 400 Pixel weiter, wenn ich + 1.0f schreibe. Muss ich da noch die Modelview Matrix multiplizieren oder wie?
-
Pikkolini schrieb:
Ja, Infolog ist leer.
EDIT:
Vielleicht liegt es ja auch an ftransform(). Wie übergibst du denn die Vektoren an den Shader?Ich setz über glUniformMatrix4fv zwei uniform-Variablen (einmal die ModelViewMatrix und einmal die ProjectionMatrix).
Mit diesen beiden Matrizen rechne ich dann im VS die Clip-Koordinaten aus, die der VS dann eben ausgibt.Pikkolini schrieb:
EDIT 2:
Ok ich Idiot hab vergessen, dass ich vorher glUseProgram aufrufen muss
Allerdings bewegt sich mein Viereck Jetzt 400 Pixel weiter, wenn ich + 1.0f schreibe. Muss ich da noch die Modelview Matrix multiplizieren oder wie?[/quote]
ftransform() hat dies schon für dich erledigt. Soweit ich das verstanden hat macht die Funktion genau das, was ich selber mache (s.o.) - ist aber seit GLSL1.20 als deprecated markiert (weswegen ich sie nicht benutzte).Da addierst im Endeffekt einen Wert auf die Clip-Space-Koordinaten. Diese werden ja später noch weiter verarbeitet (clipping, Rasterization etc.)
Deswegen würde ich wie gesagt die Translation im Object-Space machen, da es dann am leichtesten nachzuvollziehen ist.
-
So ich hab es jetzt mal so gemacht, wie ich es verstanden habe.
#version 120 in vec2 in_position; uniform int move; void main(void) { if (move != 0) { in_position.x += 1.0f; } gl_Position = gl_ModelViewProjectionMatrix * vec4(in_position, 0, 0); }
Nur jetzt seh ich gar nichts mehr vom Viereck. Der Infolog ist auch leer.
Und wieso sind alle Sinnvollen Sachen wie ftransform() oder gl_ModelViewProjectionMatrix als deprecated makiert? Ich hab letztens noch auf opengl.org gelesen, dass man genau diese Benutzen soll, weil man sich damit eine Menge Arbeit ersparen kann.
Wie übergibt man zudem überhaupt die ModelView- und Projectionmatrix an den Shader?
Gibt es außerdem irgendein Praprozessor Paramter oder so, in dem man auch angeben kann, dass eine Warnung ausgegeben werden soll, wenn ich etwas deprecated Benutze? Weil Momentan sind die einzigen Warnungen die ich sehe, dass ich von int in float etc. caste.
-
Da du die Version deiner Shader mit 120 angibst, ist auch alles in Ordnung.
Testweise kannst du ja mal 130 oder höher angeben, dann sollte in den logs stehen, dass die entsprechenden built-ins oder Funktionen (z.B. ftransform(), gl_ModelViewProjectionMatrix, gl_Color, weiss der Kuckuck was alles) deprecated sind.Diese werden in späteren Versionen aus dem Core entfernt und du kannst sie nur noch im Compatibility-Mode nutzen.
Beispielsweise sind auch glLoadIdentity, glTransform, glRotate, glVertex etc.etc. alle deprecated.
Diese wurden früher benutzt (OpenGL 1.0,1.1 etc.) aber nun eben nicht mehr.
Man ist jetzt selbst dafür verantworlich seine Matrizen zu bearbeiten und zu speichern (auch glPushMatrix, glPopMatrix.. alles deprecated).
Nutzen kannst du die Funktionen noch, aber eben nur im Compatibility-Profile.
Schaust du dir die Reference-Pages von beispielsweise OpenGL 3.3 an, so wirst du feststellen, dass keine der Funktionen noch aufgeführt ist.Nachlesen kannst du das alles in den Specifications.
Einen schnellen Überblick geben die Reference Cards (alles was blau ist, ist deprecated).Der Grund warum ftransform und gl_ModelViewProjectionMatrix deprecated sind ist, dass man davon wegkommen möchte, dass OpenGL sich um die Matrix-Verwaltung und -manipulation kümmert. Das ist nun Aufgabe von Dir. Dafür gibst ja auch entsprechende librarys, die du nutzen kannst.
Ich speicher also meine Matrizen in arrays oder vektoren und übergebe sie dann den shadern über sendUniform4x4.
Diese können dann damit rechnen (oder es eben auch lassen - je nachdem was ich machen möchte).
-
Wieso muss alles so kompliziert werden?
Und wie speicherst du deine ganze Matrizen in Arrays, irgendwie hab ich von diesem ganzen neuem Zeug noch nichts gehört, und wär cool, wenn es irgendeine Seite gibt, wo mal einem Unwissenden auf die Sprünge geholfen wird.
Weißt du denn auch, wieso mit meinem aktuellen Shadercode nichts mehr angezeigt wird? Für mich sieht das alles richtig aus.
-
Versuch mal:
gl_Position = gl_ModelViewProjectionMatrix * vec4(in_position, 0, 1);
Vierter Wert also eine 1 anstelle einer 0.
Warum das alles so kompliziert sein muss frag ich mich auch.
Ist nicht einfach da durchzublicken und zu lernen. Kaum hat man was gelernt, stellt man fest, dass dies nicht mehr die aktuelle Vorgehensweise ist.
Hab mir damals die Tutorials auf delphigl.com und die NeHe Tutorials angeschaut (alles immidiate mode) um dann festzustellen, dass dies alles wieder gleich vergessen werden kann - da man nur noch mit VBOs arbeitet.Und so isses leider mit vielem
Wirklich aktuelle Tutorials und Literatur findet man für OpenGL leider extrem wenig. Da siehts bei DirectX / Direct3D ganz anders aus - super Tutorials gleich in der MSDN - wird sofort auf vertex buffer eingegangen, mit Shadern gearbeitet etc.
Sowas würde man sich auch für OpenGL wünschen.
-
gl_Position = gl_ModelViewProjectionMatrix * vec4(in_position, 0, 1);
Vierter Wert also eine 1 anstelle einer 0.
Pikkolini schrieb:
Und wie speicherst du deine ganze Matrizen in Arrays, irgendwie hab ich von diesem ganzen neuem Zeug noch nichts gehört, und wär cool, wenn es irgendeine Seite gibt, wo mal einem Unwissenden auf die Sprünge geholfen wird.
Naja, es handelt sich um 4x4 Matrizen, also 16 Werte (column-major-order).
Also hab speicher ich 16 Werte in nem vector (STL-Container) oder arrays und arbeite auf denen. Beim rendern übergeb ich sie einach an die shader.Warum das alles so kompliziert sein muss frag ich mich auch.
Ist nicht einfach da durchzublicken und zu lernen. Kaum hat man was gelernt, stellt man fest, dass dies nicht mehr die aktuelle Vorgehensweise ist.
Hab mir damals die Tutorials auf delphigl.com und die NeHe Tutorials angeschaut (alles immidiate mode) um dann festzustellen, dass dies alles wieder gleich vergessen werden kann - da man nur noch mit VBOs arbeitet.Und so isses leider mit vielem
Wirklich aktuelle Tutorials und Literatur findet man für OpenGL leider extrem wenig. Da siehts bei DirectX / Direct3D ganz anders aus - super Tutorials gleich in der MSDN - wird sofort auf vertex buffer eingegangen, mit Shadern gearbeitet etc.
Sowas würde man sich auch für OpenGL wünschen.
-
Also das Viereck seh ich jetzt wieder, nur ist da nichts verschoben...
Was gibt der vierte Wert eigentlich an?
Und ist es sinnvoll, zu D3D zu wechseln, wenn ich eh nur für Windows programmieren möchte?
-
Pikkolini schrieb:
Also das Viereck seh ich jetzt wieder, nur ist da nichts verschoben...
Was gibt der vierte Wert eigentlich an?Der Wert wird genutzt, um die NDC coordinate (normalized device coordinate) zu berechnen. Dabei werden die clip-Koordinaten durch diesen Wert (w) geteilt.
Dazu auch mal hier schaue: OpenGL TransformationPikkolini schrieb:
Und ist es sinnvoll, zu D3D zu wechseln, wenn ich eh nur für Windows programmieren möchte?
Das kann man so pauschal nicht sagen, das musst du für dich selbst entscheiden. Es gibt sowohl für OpenGL als auch für D3D pros und contras.
Die meisten empfinden allerdings das Erlernen von OpenGL einfacher, was natürlich immer ein subjektives Empfinden ist.
-
Ok, das mit der Transformation habe ich jetzt verstanden.
Alllerdings erklärt das nicht, wieso das Viereck nicht verschoben wird.
-
Ich glaube du darfst nicht direkt die Werte von in_position ändern.
Stattedessen erstellt du dir lokal eine Kopie und arbeitest damit weiter:
#version 120 in vec2 in_position; uniform int move; void main(void) { vec2 tmpPosition = in_position; if (move != 0) { tmpPosition.x += 1.0f; } gl_Position = gl_ModelViewProjectionMatrix * vec4(tmpPosition, 0, 0); }
-
Wie immer ist es richtig
Wie kannst du dir in so wenigen Tagen so viel Wissen aneignen?
Aber eine Frage bleibt noch immer.
Kann ich im Shader eine Variable definieren, die jeden Programablauf "überlebt"? Also das ganz ohne Umweg über den Hauptspeicher die Position um einen Pixel erhöht wird.
-
Ähm, verstehe jetzt nicht genau was du meinst.
Welchen Umweg über den Hauptspeicher?Ich lese die OpenGL Superbible und nebenbei noch "Beginning OpenGL - Game Programming 2nd Edition" und eben die Reference Pages und Specifications.
-
Also ich könnte ja jetzt in meinem C++ Programm die Variable move definieren und diese dann bei jedem Rendervorgang um eins erhöhen. Das meine ich mit Umweg über den Hauptspeicher.
Jetzt ist meine Frage, ob ich auch ohne diesen Umweg direkt im Shader eine Variable bei jedem Rendervorgang um 1 erhöhen kann.
-
Das Problem ist, dass der VertexShader nicht nur einmal aufgerufen wird pro render-Durchlauf, sondern eben für jedes Vertice. Daher wird das so nicht funktionieren und du musst eben über eine uniform-Variable gehen.