2 Fragen



  • Irgendwie gehen mir die Fragen nicht aus 😃
    Wenn ich jetzt eine 2D-Szene zeichnen will, in der ich ein paar Vierecke habe, die sich bewegen und rotieren etc., ist es dann sinnvoller, die Vektoren von den Vierecken zu verändern, damit sie sich bewegen, oder die ModelviewMatrix zu verändern?



  • Du könntest natürlich für jedes Quadrat jedesmal die Koordinaten neu berechnen, dann jedesmal ein neues VBO erstellen oder die VBOs updaten und sie dann zeichnen lassen.

    Ich änder lieber die MV-Matrix aus dem einfachen Grund, dass ich dann nur ein VBO brauch, an dem ich auch nichts ändern muss. Das einzige was ich bei jedem Durchgang neu setzen muss wäre also die MV-Matrix. Ist übersichtlicher find ich und auch schneller.
    Grundgedanke: Ein Quader ist immer ein Quader, egal wie er orientiert ist, wo er sich befindet und ob er gestaucht oder gestreckt ist. Also geb ich auch nur einmal an, wie er aussieht - und Position, Rotation und Skalierung geb ich nur noch über die MV-Matrix an.



  • Matrize schrieb:

    Weil ich es mit den Texturen noch nicht ausprobiert habe:
    Kann ich ein Viereck, dass ich durch GL_TRIANGLE_STRIP gezeichnet habe, genauso wie eins, dass ich durch GL_QUADS gezeichnet habe, texturiert werden?

    Wenn du früher GL_QUADS verwendet hast hat sich einfach der Grafiktreiber intern drum gekümmert deine Quads in Dreiecke zu zerlegen da es sowieso praktisch keine Grafikkarte gibt die wirklich in der Lage ist Quads als Primitiv zu rendern (ich bin mir sicher dass natürlich irgendwer irgendwann schonmal sowas gebaut hat darum will ich die Existenz derartiger Hardware nicht ganz ausschließen, aber das was man heutzutage so als Grafikkarte verwendet kann nur Dreiecke rasterisieren).

    Matrize schrieb:

    Wenn ich jetzt eine 2D-Szene zeichnen will, in der ich ein paar Vierecke habe, die sich bewegen und rotieren etc., ist es dann sinnvoller, die Vektoren von den Vierecken zu verändern, damit sie sich bewegen, oder die ModelviewMatrix zu verändern?

    Naja, das hängt davon ab was genau du machst. Hast du einen haufen Vierecke die alle zusammen ein starres Objekt repräsentieren bzw. eben alle die selbe Bewegung durchführen!? Wenn ja ist es natürlich sinnvoll (weil extrem viel effizienter) die Ausrichtung über Matritzen zu bestimmen. Wenn du einen Haufen Vierecke hast die sich alle unabhängig voneinander bewegen wird es evtl. sinnvoller sein ein dynamisches VBO zu haben und die Positionen der Vertices darin in jedem Frame neu hochzuladen um nicht so viele einzelne draw calls und state changes zu haben.



  • Das mit dem texturieren bekomme ich nicht ganz hin.

    1. Ich finde bei google immer nur den Shader Code. Wie ich die Textur nun an den Shader übergebe steht irgenwie nirgends.

    2. In allen Tutorials werden immer nur die depreacted Variablen gl_TexCoord[0] und gl_MultiTextCoord0. Wieso reicht hier ein Vertex und wie binde ich die Koordinaten ohne die beiden depreacted Variablen ein?



  • Schau mal hier: GLSL Sampler
    oder auch Binding A Texture

    Wenn das noch nicht hilft oder weiterhin Fragen offen sind, sag nochmal bescheid.



  • Ich habe mir die Seiten mal durchgelesen, aber bei mir erscheint einfach gar nichts auf dem Bildschirm.
    Hier mal der Code:

    void print() {
    for (unsigned int i = 0; i < lines.size(); i++) {
    		MVP::instance()->translate(MODELVIEW, x, y - h * i);
    		for (unsigned int j = 0; j < lines[i].size(); ++j) {
    			glUseProgram(ProgramObject);
    			glUniformMatrix4fv(glGetUniformLocation(ProgramObject,"ModelViewProjectionMatrix"), 1, false, MVP::instance()->ptr());
    			glBindBuffer(GL_ARRAY_BUFFER, vboids[lines[i][j]]);
    			glVertexAttribPointer(glGetAttribLocation(ProgramObject,"in_position"), 2, GL_FLOAT, GL_FALSE, 0, 0);
    			glEnableVertexAttribArray(glGetAttribLocation(ProgramObject,"in_position"));
    			glBindBuffer(GL_ARRAY_BUFFER, texids[lines[i][j]]);
    			glVertexAttribPointer(glGetAttribLocation(ProgramObject, "inTexCoord"), 2, GL_FLOAT, GL_FALSE, 0, 0);
    			glEnableVertexAttribArray(glGetAttribLocation(ProgramObject,"inTexCoord"));
    			glUniform1i(glGetUniformLocation(ProgramObject, "texture"), 0);
    			glActiveTexture(GL_TEXTURE0);
    			glBindTexture(GL_TEXTURE_2D, texids[lines[i][j]]);
    			glDrawArrays(GL_TRIANGLE_STRIP,0,4);
    			glUseProgram(0);
    		}
    	}
    }
    
    // Vertex Shader
    #version 120
    
    uniform mat4 ModelViewProjectionMatrix;
    in vec2 in_position;
    in vec2 inTexCoord;
    varying vec2 texCoord;
    
    void main(void)
    {
       texCoord = inTexCoord;   
       gl_Position =  ModelViewProjectionMatrix * vec4(in_position, 0, 1);
    }
    
    // Fragment Shader
    #version 120
    
    uniform sampler2D texture;
    varying vec2 texCoord;
    
    void main (void)
    {
     gl_FragColor = texture2D(texture, texCoord);
    }
    

    Die Variable lines ist ein std::vectorstd::string. MVP ist eine singleton Klasse für meine ModelViewProjectionMatrix.
    Die Texture wird richtig erzeugt. Das habe ich schon alles ausprobiert. Also muss ich irgendwas beim Shader oder so falsch machen.



  • Hm, wenn ich mich jetzt recht erinnere verwendest du ein core-Profile.
    GLSL ver.120 ist deprecated und aus dem core entfernt worden.

    Dies gilt z.b. auch für den varying qualifier.

    Vlt. klappt es die Versionsangabe entsprechend deiner OpenGL Version anpasst und statt varying in und out verwendest.

    P.S.: Und immer schön die Infologs anzeigen lassen 🙂 Da steht meist auch, was das Problem ist.



  • Das mit den Varyings habe ich geändert.
    Meine GraKa kann nicht mehr als 1.20 von daher....
    Und der Infolog ist wieder leer. Beim AMD RenderMonkey klappt der Shader auch.



  • Hm, wenn du das core-Profile benutzt musst du ja mindestens OpenGL Version 3.2 nutzen (vorher gabs keine profiles).
    Zu OpenGL 3.2 gehört GLSL Ver 1.50 - die Version sollte also eigentlich unterstützt werden.



  • inter2k3 schrieb:

    Hm, wenn ich mich jetzt recht erinnere verwendest du ein core-Profile.

    Wann hab ich das gesagt/gezeigt?
    Aber GLSL hin oder her, stimmt mein Programm den überhaupt? Denn mich wundert es, dass ich nur eine Texturkoordinate angebe. Wenn ich z.B. eine 100x100 Textur habe und ich damit ein 100x100 Quadrat texturieren will, würde ich nach diesem Beispiel nur die Koordinate 0|0 angeben. Aber was ist mit dem Rest? Ich versteh nicht ganz, wie das ganze System beim texturieren funktioniert.



  • Du gibst für jedes Vertice Texturkoordinaten an (und falls du gleich mehrere Texturen verwendest evtl auch nochmal für jede dieser Texturen welche).

    Zeichnest du also (zur Vereinfachung) ein Quadrat und möchtest die Textur über das komplette Quadrat legen, dann würde unten links das Vertice die Texturkorrdinate (0.0f,0.0f) bekommen, unten recht das vertice (1.0f,0.0f), oben rechts (1.0f,1.0f) und oben links (0.0f,1.0f).

    Würdest du dieses Quadrat nun nicht durch ein quad zeichnen, sondern sagen wir mal durch 4 quads wobei dann müsstest du entsprechend die Texturkoordinaten ändern. Angenommen das ganze Quadrat hat eine Seitenlänge von 2 und jedes der vier kleinen quads (die ja das gesamte Quadrat darstellen später) hat eine Seitenlänge von 1, dann würden die Texturkoordinaten für das quad oben links z.b. folgendermassen lauten (wieder in der Vertice-Reihenfolge unten-links, unten-rechts, oben-rechts, oben-links):
    (0.0f,0.5f)
    (0.5f,0.5f)
    (0.5f,1.0f)
    (0.0f,1.0f)

    Texturkoordinaten sind im Berech [0.0f,1.0f]. Natürlich kann man auch negative Werte oder grössere Werte nehmen. Diese Werte liegen eigentlich ausserhalb der Textur und in Abhängigkeit davon, welche Einstellungen du vorgenommen hast wird dann verfahren (clamp-to-edge, clamp-to-border, repeat etc.).



  • Ja das habe ich schon verstanden, aber mich hat es irritiert, dass für jedes Fragment eine Koordinate gebraucht wird, und nicht für jeden Vektor.
    Dann habe ich noch einen Denkfehler gefunden:

    glBindTexture(GL_TEXTURE_2D, texids[lines[i][j]]);
    

    müsste eigentlich

    glBindTexture(GL_TEXTURE_2D, textures[lines[i][j]]);
    

    heißen.
    Aber das bringt auch nichts.
    Wenn ich im Fragmentshader die Farbe einfach nur bestimme, werden auch untexturierte Quadrate gezeichnet. Also muss das Problem ja irgendwo beim texturieren liegen.
    Hier ist mal der Code, wie ich die Buffer etc erstelle:

    glBindTexture(GL_TEXTURE_2D, tex_base[ch]);
    	float largest_supported_anisotropy;
    	glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy);
    	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);
    	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, expanded_data.begin()._Ptr);
    
    	glm::vec2 vertices[4] = {
    		glm::vec2(0, bitmap.rows),
    		glm::vec2(0, 0),
    		glm::vec2(bitmap.width, bitmap.rows),
    		glm::vec2(bitmap.width, 0)
    	};
    
    	glBindBuffer(GL_ARRAY_BUFFER,vboids[ch]);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2)*4, vertices, GL_STATIC_DRAW);
    
    	float x = static_cast<float>(bitmap.width) / static_cast<float>(width);
    	float y = static_cast<float>(bitmap.rows) / static_cast<float>(height);
    	glm::vec2 texcoord[4] = {
    		glm::vec2(0,0),
    		glm::vec2(0,y),
    		glm::vec2(x,y),
    		glm::vec2(x,0)
    	};
    
    	glBindBuffer(GL_ARRAY_BUFFER,texids[ch]);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2)*4, texcoord, GL_STATIC_DRAW);
    

    Meine Vorlage war das Freetype Tutorial von NeHe, wobei ich den Zeichencode aktualisieren wollte.
    In glBufferData Werte mit glm::vec2 zu übergeben hat bisher immer geklappt, und das Anisotropische Filtern hat auch nichts mit em Problem zu tun.



  • wie schauts aus wenn du für die Textur noch folgendes angibst?

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    


  • Ja da kommt das gleiche raus, meint ich ja.
    Ich hab mal den Code hochgeladen:
    http://pastebin.com/i875mRCK
    Und die Shader:

    // Vertex
    #version 120
    
    uniform mat4 ModelViewProjectionMatrix;
    in vec2 in_position;
    in vec2 in_TexCoord;
    out vec2 texcoord;
    
    void main(void)
    {
       texcoord = in_TexCoord;
       gl_Position =  ModelViewProjectionMatrix * vec4(in_position, 0, 1);
    }
    
    //Fragment
    #version 120
    
    uniform sampler2D texture;
    in vec2 texcoord;
    
    void main (void)
    {
     gl_FragColor = texture2D(texture, texcoord);
    }
    

    Ich denke, dass in dem Code ein Logikfehler ist. Den einzigen den ich bisher gefunden habe ist, dass theoretisch alle Buchstaben einer Reihe übereinander stehen. Aber das ist fürs erste egal und nicht unlösbar 😉
    Errorlog meckert auch nicht.



  • Sorry, aber da ich noch nicht mit FreeType gearbeitet habe ist es mir jetzt zuviel Aufwand mich da reinzulesen.

    Ich sehe dass du in make_vbo keine Filter für magnification und minification angibst.

    Grundsätzlich wäre es vielleicht erstmal ne gute Idee klein anzufangen - sprich erstmal zu schauen wie das ganze funktioniert mit den texture units, Texturkoordinaten etc. anhand eines extrem simplen Beispiels wie einem einzelnen Quadrat oder Dreieck.


Anmelden zum Antworten