OpenGL Vertexshader



  • Ok danke, alle Fragen beantwortet 🙂



  • Wobei, eine Frage habe ich noch.
    Da uniform ja nicht antwort auf meine Frage war, wie kann ich jetzt z.B. an den Shader neue Werte übergeben, z.B. wenn sich die Position meines Vierecks nach einem Tastendruck um 10 Pixel verschoben hat?



  • Und ich hab direkt noch eine Frage.
    Ich wollte jetzt mal 2 Quads zeichnen und habe mein Array dementsprechend angepasst:

    GLint vertices[] = {100,100,300,100,300,300,100,300, 0, 0, 10, 0, 10, 10, 0, 10};
    

    Allerdings wird mit

    gl_Position = ftransform();
    

    nur das erste Quad gerendert. Muss ich meinen Shader irgendwie anpassen, dass ich soviele Quads rendern kann, wie im Array stehen?



  • Du hast mehrere Möglichkeiten was dsa Verschieben angeht.
    Du könntest den Wert als uniform setzen und im VS zu den entsprechenden Werte des Vertices addieren. Danach würdest du transformieren.

    Du könntest auch gleich die Modelview-Matrix ändern und diese als uniform übergeben um zu transformieren.

    Die Frage ist halt, wie verschoben werden soll - und vorallem in welchem Bezugssystem (Object-Space, World-Space, Viewing-Space)

    Zu Frage 2:
    auch an

    glDrawArrays(GL_QUADS, 0, 8);
    

    gedacht?



  • inter2k3 schrieb:

    Du hast mehrere Möglichkeiten was dsa Verschieben angeht.
    Du könntest den Wert als uniform setzen und im VS zu den entsprechenden Werte des Vertices addieren. Danach würdest du transformieren.

    Du könntest auch gleich die Modelview-Matrix ändern und diese als uniform übergeben um zu transformieren.

    Die Frage ist halt, wie verschoben werden soll - und vorallem in welchem Bezugssystem (Object-Space, World-Space, Viewing-Space)

    Das versteh ich nicht ganz.
    Soweit ich verstanden habe, kann man einer Uniform variable einmal einen Wert zuweisen und dann wars das.
    Was ich aber jetzt z.B. vorhabe ist, dass wenn sich die Position von (10|10) zu (20|10) ändert, das Viereck auch dort gezeichnet wird. Mit glVertexAttribPointer komme ich da irgendwie nicht weit.

    inter2k3 schrieb:

    Zu Frage 2:
    auch an

    glDrawArrays(GL_QUADS, 0, 8);
    

    gedacht?

    Natürlich nicht 🙄



  • Pikkolini schrieb:

    Das versteh ich nicht ganz.
    Soweit ich verstanden habe, kann man einer Uniform variable einmal einen Wert zuweisen und dann wars das.
    Was ich aber jetzt z.B. vorhabe ist, dass wenn sich die Position von (10|10) zu (20|10) ändert, das Viereck auch dort gezeichnet wird. Mit glVertexAttribPointer komme ich da irgendwie nicht weit.

    Nein - du kannst die uniforms in jedem render-Durchlauf neu setzen.
    kleines Beispiel:

    uniform mat4 mvmatrix;		// modelviewmatrix
    uniform mat4 projmatrix;	// projectionmatrix
    
    in vec3 vinvertex;		// incoming vertex
    in vec3 vincolor;		// incoming color
    in vec2 vintex;			// incoming texture-coord
    
    out vec3 voutcolor;		// pass color to frag-shader
    out vec2 vouttex;		// pass texture-coord to frag-shader
    
    void main()
    {
    	vouttex = vintex;
    	voutcolor = vincolor;
    	gl_Position =  projmatrix * ( mvmatrix * vec4(vinvertex,1.0));
    }
    

    mvmatrix und projmatrix werden in jedem render-Durchlauf gesetzt, da es ja durchaus sein kann, dass man Objekte rotiert oder verschiebt 🙂



  • Ich hab jetzt diesen Code im Vertex-Shader:

    #version 120
    
    uniform int in_position;
    
    in vec4 in_color;
    
    varying vec4 ex_color;
    
    void main(void)
    {
     ex_color = in_color;
     if (in_position != 0)
     {
      gl_Position = ftransform() + vec4(100,0,0,0);
     } else {
      gl_Position = ftransform();
     }
    }
    

    Also ich versteh den so, dass wenn in_position ungleich null ist, mein Viereck 100 px versetzt gezeichnet wird.
    Der C++ Code sieht dann so aus:

    glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, vertices);
    glEnableVertexAttribArray(0);
    glUniform1i(glGetUniformLocation(ProgramObject, "in_position"),1);
    

    Aber versetzen tut sich da gar nichts.



  • 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 Transformation

    Pikkolini 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.


Anmelden zum Antworten