2 Fragen
-
inter2k3 schrieb:
Du gibst ja nur die Matrizen mit glUniform an. Den Pointer auf die daten gibst du über glVertexAttribPointer an. Die Vertex-Attribute werden im VBO gespeichert, die Matrizen allerdings nicht.
Also Schritt-für-Schritt:- Matrizen berechnen
- Vertice-Attribute berechnen oder festlegen
- VBO erstellen und Vertice-Daten in VBO laden
- über glUniform dem Vertex-Shader die Matrizen zugänglich machen
- über glVertexAttribPointer den Shadern die Vertice-Attribute zugänglich machen
- DrawCall aufrufen.
Ja die Vektoren habe ich in einem VBO, aber die Matrizen eben nicht. Mir ist aber auch gerade aufgefallen, dass das wenig Sinn machen würde.
inter2k3 schrieb:
Du interpretierst dort aber right und left, top und bottom falsch
Du teilst beispielsweise beim ersten Element 2.0/width, wobei width die Fensterbreite ist. Allerdings ist mit right-left nicht die Fensterbreite gemeint, sondern die Werte, die man normalerweise bei glOrtho angeben würde.Die Matrix für glOrtho (-2,2,-2,2,1,2) würde so aussehen:
float projection_matrix[16] = { 2.0f / (2-(-2), 0.0f, 0.0f, 0.0f, // erste Spalte 0.0f, 2.0f / (2-(-2), 0.0f, 0.0f, // zweite Spalte 0.0f, 0.0f, -2.0f / (2-1) , 0.0f, // dritte Spalte 0.0f, 0.0f, -(2+1)/2-1), 1.0f // vierte Spalte };
alse letztendlich:
float projection_matrix[16] = { 0.5f, 0.0f, 0.0f, 0.0f, // erste Spalte 0.0f, 0.5f, 0.0f, 0.0f, // zweite Spalte 0.0f, 0.0f, -2.0f, 0.0f, // dritte Spalte 0.0f, 0.0f, -3.0f, 1.0f // vierte Spalte };
Wenn ich glOrtho benutze, habe ich bei einer Fensterbreite von 800 und Höhe von 600 immer das hier im Code stehen:
glOrtho(0,800,0,600,-1,1);
Und wenn ich so wie glOrtho meine eigene Matrix berechnen will, dann solte doch das herauskommen, was ich da stehen habe.
inter2k3 schrieb:
Ah verstehe. Hm - da bin ich auch ein wenig überfragt gerade (da selbst noch Anfänger). Eine Möglichkeit wäre die Farben ebenfalls als Uniform zu übergeben und dann über gl_VertexID zu entscheiden, wann welcher Farbwert genommen werden soll.
Du hättest also ein vec3 Array als uniform und setzt die Farbe dann im Shader in der Art:// nicht selbst versucht, einfach so ne Idee im Kopf gerade. vec3 col = colarray[(gl_VertexID/5];
Für die ersten 5 Vertices würde jeweils 0 als arrayIndex rauskommen, für die nächsten 5 würde 1 rauskommen etc.
Ist aber ziemlich umständlich. Da wäre es wohl einfach, einfach für jedes Vertice einen Farbvektor anzugeben.Danke, das war schonmal ein Gedankenanstoß. Wenn es da keine andere Methode gibt, werde ich es mal so probieren.
-
Dank GLM klappt jetzt alles
Hier der relevante Code f+r die Matrizen:glm::mat4 projection_matrix = glm::ortho(0.0f, width, 0.0f, height); glm::mat4 modelview_matrix = glm::mat4(1.0f); glUniformMatrix4fv(glGetUniformLocation(Shader,"projection_matrix"), 1, false, glm::value_ptr(projection_matrix)); glUniformMatrix4fv(glGetUniformLocation(Shader,"modelview_matrix"), 1, false, glm::value_ptr(modelview_matrix));
-
Jup - sieht gut aus.
Man muss sich ein wenig in glm einarbeiten, aber danach ist es recht intuitiv.
Dann happy coding
-
Ich hab noch mal eine Frage.
Ist das hier deprecated? Aus den OpenGL Specs kann ich das nicht genau erkennen.void init { // ... unsigned short pindices[3]; pindices[0] = 0; pindices[1] = 1; pindices[2] = 2; glGenBuffers(1,&indexid); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexid); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*3, pindices, GL_STATIC_DRAW); // ... } void draw { glUseProgram(Shader); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexid); glDrawElements(GL_TRIANGLES,3,GL_UNSIGNED_SHORT,0); glUseProgram(0); }
Die Shader werden natrülich auch in der Init funktion erstellt und die vertices auch in den Buffer geschrieben.
Mit geht es hier um glDrawElements() und das ich vorher noch den ELEMENT_ARRAY_BUFFER binden muss.
-
Nein, das sind alles core-functions - nichts deprecated.
Einen schnellen Überblick darüber, was deprecated ist oder nicht siehst du in den Quick Reference-Cards. Alles was in blauer Schrift geschrieben ist, ist nur über ein compatibility-profile zugänglich.
-
Danke, die Seiten sidn echt gut
Nur stellen sich mir dadurch wieder 2 Fragen
1. Kann man jetzt wirklich nurnoch Punkte, Linien und Dreiecke zeichnen? Wenn ja, wär das ziemlich mies.
2. Wie soll man Sachen jetzt texturieren. Im Internet findet man nur Tutorial mit gl_TexCoord[] oder glMultiTexcoord0 etc. Aber die sind ja alle deprecated...
-
Matrize schrieb:
Danke, die Seiten sidn echt gut
Nur stellen sich mir dadurch wieder 2 Fragen
1. Kann man jetzt wirklich nurnoch Punkte, Linien und Dreiecke zeichnen? Wenn ja, wär das ziemlich mies.Ja - als Primitiven sind keine quadriliterale mehr erlaubt. Aber da man jedes Rechteck ganz einfach durch 2 Dreiecke zeichnen kann ist dies kein wirklich grosses Problem (oder durch triangle-strip, dann kann man die gleichen 4 Koordinaten verwenden).
Matrize schrieb:
2. Wie soll man Sachen jetzt texturieren. Im Internet findet man nur Tutorial mit gl_TexCoord[] oder glMultiTexcoord0 etc. Aber die sind ja alle deprecated...
Texturkoordinaten werden wie Farbwerte, Vertex-Koordinaten etc. auch ganz normal als Vertex-Attribut an die shader übergeben und durch den rasterizer dann entsprechen für jedes Fragment interpoliert.
Die Texturen werden als uniform sampler übergeben und im shader erfolgt das lookup dann durch eine der vielen LookUp-Funktionen.
-
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?
-
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?Im Normalfall schon ja.
-
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 TextureWenn 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.).