Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Do Mär 28, 2024 14:31

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 28 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Autor Nachricht
BeitragVerfasst: Sa Aug 17, 2013 18:46 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Es stimmt weiterhin, dass das VAO die Lesevorschrift ist und das VBO die eigentlichen Vertexdaten enthält. Du füllst das VAO, indem du (während es gebunden ist) glVertexAttribPointer aufrufst. Mit dieser Funktion gibst du ja die Offsets für Position, Normale, Texturkoordinaten usw. im VBO an - und zwar geht es dabei um das VBO, das gerade gebunden ist, während glVertexAttribPointer aufgerufen wird.

Trotzdem wird im VAO nicht das gebundene VBO in dem Sinne gespeichert, dass ein Aufruf von glBindVertexArray einen Aufruf von glBindBuffer impliziert. Es kommt nämlich (wie wir in diesem Thread herausgefunden haben) beim Rendern gar nicht darauf an, welches VBO gerade gebunden ist - wichtig ist, welches bei der Initialisierung des VAOs gebunden war.

Bezüglich des anderen Threads, habe ich auch schon mehrfach überlegt, ob ich meine Aussage von gestern zurückziehen müsste. Letztendlich bin ich aber zu dem Schluss gekommen, dass sie richtig ist. Das VAO merkt sich alle mit glVertexAttribPointer vorgenommenen Einstellungen - wozu die Verknüpfung mit dem VBO gehört - aber es schert sich selbst nicht um den Status von GL_ARRAY_BUFFER. Offiziell nachlesen kannst du das hier (auf englisch).

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Sa Aug 17, 2013 23:26 
Offline
DGL Member

Registriert: Sa Apr 14, 2012 14:28
Beiträge: 52
Programmiersprache: c++
Um das ganze mal zu konkretisieren, ist das folgende korrekt?:

Wenn ich VAO und VBO initialisiert habe und dann beide wieder entbinde, brauche ich beim Rendern nur noch das VAO erneut binden, weil das VAO zwar das VBO nicht mitbindet, aber zumindest weiß aus welchem VBO es seine Daten her kriegt.
So könnte ich mir beispielsweise ein VBO anlegen in dem ich die Daten für zwei Dreiecke speichere. Auch wenn es technisch keinen Sinn macht, könnte ich nun mein erstes VAO binden, den AttibPointer auf die Daten vom ersten Dreieck setzen und anschließend das gleiche mit dem zweiten VAO und den Daten des zweiten Dreiecks machen, während das VBO gebunden ist.

Durch binden des jeweiligen VAOs kann ich dann unabhängig vom gerade gebundenen VBO Dreieck 1 oder 2 rendern. Soweit korrekt?

Dann wäre in diesem Fall das VBO nur noch ein reiner Speicher und das VAO ne Art Pointer auf den Speicher mit Interpretationsvorschrift. Das würde dann auch das "Pointer" in glVertexAttribPointer erklären...

Das Thema ist doch komplexer als ich gedacht habe...

MfG der Troll


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Aug 18, 2013 09:03 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Der Troll hat geschrieben:
Wenn ich VAO und VBO initialisiert habe und dann beide wieder entbinde, brauche ich beim Rendern nur noch das VAO erneut binden, weil das VAO zwar das VBO nicht mitbindet, aber zumindest weiß aus welchem VBO es seine Daten her kriegt.

Ja.

Der Troll hat geschrieben:
So könnte ich mir beispielsweise ein VBO anlegen in dem ich die Daten für zwei Dreiecke speichere. Auch wenn es technisch keinen Sinn macht, könnte ich nun mein erstes VAO binden, den AttibPointer auf die Daten vom ersten Dreieck setzen und anschließend das gleiche mit dem zweiten VAO und den Daten des zweiten Dreiecks machen, während das VBO gebunden ist.

Durch binden des jeweiligen VAOs kann ich dann unabhängig vom gerade gebundenen VBO Dreieck 1 oder 2 rendern. Soweit korrekt?

Nein, das geht so nicht. Edit: Doch, das geht so.

Das VAO beschreibt, wie ein Vertex aufgebaut ist. Also zum Beispiel:
3 floats für Position aus VBO 1
2 floats für TexCoords aus VBO 1

Damit weiß OpenGL, womit es die Variablen mit in bzw. attribute des Vertexshaders füttern muss.
Welche und wie viele Vertices nun in diesem Format gerendert werden, bestimmst du immer noch mit deinem DrawCall (also zum Beispiel bei glDrawArrays mit den letzten beiden Parametern).

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Zuletzt geändert von glAwesome am So Aug 18, 2013 15:48, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Aug 18, 2013 12:16 
Offline
DGL Member

Registriert: Sa Apr 14, 2012 14:28
Beiträge: 52
Programmiersprache: c++
glAwesome hat geschrieben:
Der Troll hat geschrieben:
So könnte ich mir beispielsweise ein VBO anlegen in dem ich die Daten für zwei Dreiecke speichere. Auch wenn es technisch keinen Sinn macht, könnte ich nun mein erstes VAO binden, den AttibPointer auf die Daten vom ersten Dreieck setzen und anschließend das gleiche mit dem zweiten VAO und den Daten des zweiten Dreiecks machen, während das VBO gebunden ist.

Durch binden des jeweiligen VAOs kann ich dann unabhängig vom gerade gebundenen VBO Dreieck 1 oder 2 rendern. Soweit korrekt?

Nein, das geht so nicht. Das VAO beschreibt, wie ein Vertex aufgebaut ist. Also zum Beispiel:
3 floats für Position aus VBO 1
2 floats für TexCoords aus VBO 1

Damit weiß OpenGL, womit es die Variablen mit in bzw. attribute des Vertexshaders füttern muss.
Welche und wie viele Vertices nun in diesem Format gerendert werden, bestimmst du immer noch mit deinem DrawCall (also zum Beispiel bei glDrawArrays mit den letzten beiden Parametern).


Dass es keinen Sinn macht ist mir schon klar, aber rein theoretisch wäre es denkbar. Ich versuch es mal mit ner laxen Pseudocodebeschreibung:

Initialisierung:
Code:
  1.  
  2. vertexdaten = [P1, P2, P3, P4, P5, P6]  // PX = x,y,z
  3.  
  4. glGenVertexArrays(1, &VAO1);
  5. glBindVertexArray(VAO1);
  6.  
  7. glGenBuffers(1, &VBO);
  8. glBindBuffer(GL_ARRAY_BUFFER, VBO);
  9.  
  10. glBufferData(GL_ARRAY_BUFFER,sizeof(vertexdaten), vertexdaten, GL_STATIC_DRAW);
  11.  
  12. glEnableVertexAttribArray(0);
  13. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
  14.  
  15. // soweit alles normal, jetzt VAO 2:
  16.  
  17. glGenVertexArrays(1, &VAO2);
  18. glBindVertexArray(VAO2);
  19.  
  20. glEnableVertexAttribArray(0);
  21. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, sizeof(P) * 3); // auf den Offset achten
  22.  
  23.  


Rendern:
Code:
  1.  
  2.  
  3. glBindVertexArray(VAO1);
  4. glDrawArrays(GL_TRIANGLES, 0, 3); // Zeichnet Dreieck 1
  5. glDrawArrays(GL_TRIANGLES, 0, 6); // Zeichnet Dreieck 1 und 2;
  6.  
  7. glBindVertexArray(VAO2);
  8. glDrawArrays(GL_TRIANGLES, 0, 3); // Zeichnet Dreieck 2
  9. glDrawArrays(GL_TRIANGLES, 0, 6); // Erzeugt nen Fehler weil ich über das Ende hinaus lese;
  10.  
  11.  


Das sollte doch eigentlich funktionieren. Dass diese Art des Renderns keinen Sinn macht, da ineffektiv, ist mir klar. Es geht mir nur darum genau zu verstehen wie VAOs funktionieren. In diesem Fall wollte ich einfach mal herumspinnen, wie VAOs genutzt werden könnten um den selben Datensatz unterschiedlich zu interpretieren.

MfG Der Troll


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Aug 18, 2013 12:48 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Edit: Hier steht Unsinn. Überspringe diesen Post.

Hiermit
Code:
  1. glEnableVertexAttribArray(0);
  2. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, sizeof(P) * 3); // auf den Offset achten
sagst du OpenGL, dass ein (!) Vertex die Größe von 12 floats hat. Und zwar beginnt jeder Vertex mit 9 floats (sizeof(P) * 3) Datenmüll und endet mit 3 floats Positionsdaten.

Dadurch würde dieser Aufruf
Code:
  1. glBindVertexArray(VAO2);
  2. glDrawArrays(GL_TRIANGLES, 0, 3);
bereits zu einem Fehler führen, denn du weist OpenGL an, 3 Vertices = 3*12 floats = 36 floats aus dem VBO zu lesen. Dein VBO besteht aber nur aus 6*3 = 18 floats.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Zuletzt geändert von glAwesome am So Aug 18, 2013 15:46, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Aug 18, 2013 13:39 
Offline
DGL Member

Registriert: Sa Apr 14, 2012 14:28
Beiträge: 52
Programmiersprache: c++
glAwesome hat geschrieben:
Hiermit
Code:
  1. glEnableVertexAttribArray(0);
  2. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, sizeof(P) * 3); // auf den Offset achten
sagst du OpenGL, dass ein (!) Vertex die Größe von 12 floats hat. Und zwar beginnt jeder Vertex mit 9 floats (sizeof(P) * 3) Datenmüll und endet mit 3 floats Positionsdaten.


Der letzte Wert, also sizeof(P)*3 gibt doch nur den Offset an, ab dem ich Anfange meine Daten im VBO zu lesen (" pointer is treated as a byte offset into the buffer object's data " siehe http://www.khronos.org/opengles/sdk/doc ... ointer.xml ), was in dem Fall ein Offset von 9 floats wäre, sprich dem ersten Dreieck.

Die Größe eines Vertex gebe ich ihm mit dem zweiten und 3 Wert an. 3 * sizeof(GL_FLOAT). Auf die selbe Weise strukturiert man doch auch Farbwerte oder Normalenwerte, nur hier habe ich es für Positionsdaten genutzt, wo mein "Lesekopf" in beiden VAOs unterschiedlich gesetzt wird.

EDIT: Glaube du verwechselst das mit dem stride Eingabeparameter, den ich auf 0 gesetzt habe. Der gibt nämlich an, wieviele Werte zwischen jedem Vertex übersprungen werden sollen.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Aug 18, 2013 13:58 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Jetzt hast du mich doch verunsichert. :? Ich hab mir nochmal die verschiedenen Artikel (hier, hier und in unserem Wiki) zu glVertexAttribPointer angeschaut. Danach komme ich zu folgendem Schluss:
- der letzte Parameter gibt tatsächlich den Abstand von Beginn des VBOs zum ersten Vorkommen des Attributs an
- stride (der vorletzte Parameter) gibt den Abstand zum selben Attribut im jeweils nächsten Vertex an (falls stride == 0, wird automatisch die Größe des Attributs genommen), sollte also sinnvollerweise auf die Größe des gesamten Vertex gesetzt werden.

Demnach müsste ich meinen letzten Post zurückziehen. Kann das bitte jemand bestätigen oder widerlegen?

@Der Troll: Hast du das Programm ausprobiert? Stürzt es tatsächlich erst beim letzen glDrawArrays ab?

Edit: Für die Diskussion über ein Tutorial habe ich einen eigenen Thread aufgemacht.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Zuletzt geändert von glAwesome am So Aug 18, 2013 14:39, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Aug 18, 2013 14:17 
Offline
DGL Member

Registriert: Sa Apr 14, 2012 14:28
Beiträge: 52
Programmiersprache: c++
Das war bisher eher nur ein Gedankenspiel, aber ich kann das nachher mal in meinem derzeitigen Projekt testen. Ich denke ich würde, sobald ich das alles hier vollständig gerafft und alles mal ausgetestet habe versuchen einen kleinen Wiki-Artikel zu verfassen "VAOs und VBOs for Dummies" :mrgreen:. Das Ganze dann mit ganz vielen Bildern, damit es leichter zu raffen geht als aus purem Text. Ich denke mir hätte sowas ziemlich geholfen, da das ganze Thema schon nicht soooo trivial ist.

MfG Der Troll


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Aug 18, 2013 15:35 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
glAwesome hat geschrieben:
Danach komme ich zu folgendem Schluss:
- der letzte Parameter gibt tatsächlich den Abstand von Beginn des VBOs zum ersten Vorkommen des Attributs an
- stride (der vorletzte Parameter) gibt den Abstand zum selben Attribut im jeweils nächsten Vertex an (falls stride == 0, wird automatisch die Größe des Attributs genommen), sollte also sinnvollerweise auf die Größe des gesamten Vertex gesetzt werden.

Demnach müsste ich meinen letzten Post zurückziehen. Kann das bitte jemand bestätigen oder widerlegen?

Ja, ich kann das bestätigen. Wenns nötig ist, kann ich das auch anhand eines kleineren (Linux32bit/Pascal) Demo-Programms beweisen.

Stride ist identisch mit SizeOf(Vertex) (das steht auch in einem etwas älteren Wiki-Artikel von mir, den schon einige Leute für sich adaptiert haben).

Der Letzte "Pointer" Parameter von glVertexAttribPointer kann dazu verwendet werden, den Vertex-Offset eines Modells in einem VBO anzugeben, wenn man mehrere Modelle in einem einzigen VBO unterbringen will.

Funktioniert wunderbar.

Viele Grüße,
Traude


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Aug 18, 2013 20:03 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Mir kam gerade noch eine Frage auf:
glAwesome hat geschrieben:
Mit [glVertexAttribPointer] gibst du ja die Offsets für Position, Normale, Texturkoordinaten usw. im VBO an - und zwar geht es dabei um das VBO, das gerade gebunden ist, während glVertexAttribPointer aufgerufen wird.
[...]
Es kommt nämlich [...] beim Rendern gar nicht darauf an, welches VBO gerade gebunden ist - wichtig ist, welches bei der Initialisierung des VAOs gebunden war.

Galt das eigentlich auch schon zu OpenGL 2.0 Zeiten (wo man noch keine VAOs kannte)? Die offiziellen Specs werden ja leider (naja, eigentlich ist es gut) immer an den aktuellen Stand angepasst. Weiß das jemand?

Edit: Gemeint ist das Unterstrichene: Also ob es früher auch schon so war, dass das gebundene VBO nur während des glVertexAttribPointer-Aufrufs von Bedeutung war. Ich frage, weil es bei einer Anpassung des Wiki-Artikels berücksichtigt werden sollte, falls es früher noch anders war.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Aug 18, 2013 21:56 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Du müsstest die Specs von 2.1 Laden, um das raus zu finden, dort sind die Korrekturen rot makiert.
Alles was raus geflogen ist, wird rot durchgestrichen und alles was hinzu kommt wird einfach nur rot geschrieben.
Oft gibt es auch noch Quotes für welche Versionen es gültig ist.

Witzig wird das ganze mit OpenGL4.4, wo man nun auch Buffer Storage Objects hat.
Diese können jede Art von Daten enthalten, welche durch eine neue layout Syntax im Shader definiert werden.
Der Programmierer von G-Truc glaubt ja, dass mit 4.5 die meisten Object Typen raus fliegen werden, weil BSO so ziemlich jedes ersetzen kann. Texture und Shader Objects wird es aufjedenfall weiter hin geben aber Texturen muss man nur noch einmal beim Laden binden und kann dann den Pointer im VRAM abfragen und im BSO mit hinterlegen. So ist OGL 4.4 auch in der Lage 2^64 Texturen gleichzeitig zu zu greifen ohne Bind.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Aug 19, 2013 09:49 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
glAwesome hat geschrieben:
Gemeint ist das Unterstrichene: Also ob es früher auch schon so war, dass das gebundene VBO nur während des glVertexAttribPointer-Aufrufs von Bedeutung war. Ich frage, weil es bei einer Anpassung des Wiki-Artikels berücksichtigt werden sollte, falls es früher noch anders war.

Ich hab gerade meine OpenGL2.1 Engine befragt.

Dort steht grundsätzlich Folgendes:
1. VBO/IBO binden
2. glEnableVertexAttribArray/glVertexAttribPointer aufrufen
3. Zeichnen


Ich habe das eigentlich nie in Frage gestellt.


Aber jetzt habe ich das folgendermaßen geändert:
1. VBO/IBO binden
2. glEnableVertexAttribArray/glVertexAttribPointer aufrufen
3. VBO entbinden (!)
4. Zeichnen

Zu meiner großen Überraschung zeichet er IMMER NOCH.
Genügt Dir das?

Übrigens: Die 2.1 Reference Pages kann man einsehen: http://www.opengl.org/sdk/docs/man2/


@Thomas:
Du willst uns verwirren, gib's zu. :wink:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Apr 08, 2016 11:15 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Hallo Leute, eher zufällig bin ich jetzt auf das Thema und damit über diesen Thread (meinen ersten in diesem Forum) gestoßen und möchte noch was ergänzen. Traude hat ja auf Seite 1 geschrieben, dass VAOs sich laut OpenGL-Spezifikation den gebundenen Indexbuffer merken, die Grafiktreiber dies aber offenbar nicht umsetzen. Ich hatte mir dann gemerkt, dass man im VAO nur das Vertexformat des VBOs einstellen kann und man den IBO vor dem Rendern jedes Mal neu binden muss. Dies ist aber falsch! Ich war schon etwas schockiert, dass ich in den 2,5 Jahren in denen ich nun mit VAOs arbeitete, mein Falschwissen nicht bemerkt hatte. Es besteht die Möglichkeit, dass einige von euch es sich ebenso falsch gemerkt haben, deshalb hier die späte Richtigstellung.

Ich zitiere mal aus der OpenGL 3.3-Spezifikation:
OpenGL 3.3 Spezifikation, Kapitel 2.10 (Seite 50) hat geschrieben:
The resulting vertex array object is a new state vector, comprising all the state values listed in tables 6.4 and 6.5.
Tabelle 6.5 befindet sich auf Seite 281 und enthält ELEMENT_ARRAY_BUFFER_BINDING.

Noch klarer macht es das OpenGL-Wiki:
OpenGL-Wiki hat geschrieben:
The index buffer binding is stored within the VAO. If no VAO is bound, then you cannot bind a buffer object to GL_ELEMENT_ARRAY_BUFFER.


Stimmt es also, dass die Treiber die Spezifikation nicht umsetzen? Nun, wie es 2013 war, kann ich nicht sagen. Aber für heute kann ich Entwarnung geben. Getestet habe ich:
- Windows/AMD
- Windows/Nvidia
- Windows/Intel
- Linux/AMD (r600)
- Linux/Nvidia (nouveau)
- Linux/Intel
Alle Treiber funktionierten diesbezüglich wie von der Spezifikation gefordert. So soll es sein. :) Den Code, mit dem ich getestet habe, habe ich angehängt (Wer erkennt ihn wieder? :wink: ).

Eine Sache ist allerdings zu beachten: Man muss erst das VAO erzeugen und binden, *danach* kann man den IBO binden. Nur wenn man es in dieser Reihenfolge macht, merkt sich das VAO den IBO. Schlimmer noch - ein Indexbuffer kann nicht gebunden werden, wenn es kein VAO gibt (siehe Zitat aus OpenGL-Wiki). Allein deshalb muss das VAO zuerst gebunden werden.

Den Artikel Vertex Array Object habe ich angepasst. 8200 Views... huiuiui, da habe ich aber Falschwissen verbreitet. Es darf sich jeder berufen fühlen, Fehler in der korrigierten Fassung zu finden.


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 28 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 40 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.078s | 19 Queries | GZIP : On ]