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

Aktuelle Zeit: Mo Jul 14, 2025 18:03

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 33 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste
Autor Nachricht
 Betreff des Beitrags: glColorPointer - wie verwenden?
BeitragVerfasst: So Mai 20, 2012 13:35 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Ich zeichne mir derzeit ein Schachbrett mit GL_Quads. Da sie statisch sind dachte ich mir: gut packst du die Vertices in einen Buffern und fertig.
Gesagt getan, es klappt auch alles. Nur haben die Felder natürlich Farben.
Also habe ich einen zweiten Buffer angelegt und dort meine Farbdaten (float array: float[4][]) reingeschoben. Das Array besteht lauter 4 stelligen Einträgen die RGBA Daten enthalten.
Nun switche ich zum Vertex Buffer, Pointer ihn mit glVertexPointer und zeichne dann mit glDrawArrays. Ich sehe nach wie vor mein Grid (die schwarzen jedenfalls), aber keine anderen. Weiße und testweise blaue werden nicht angezeigt, also nicht coloriert.

Meine Buffer Methode sieht so aus:
Code:
  1.  
  2. static Buffer CacheShapes(const Shape[] shapes) {
  3.     Vertex[] v = [];
  4.     float[4][] c = [];
  5.  
  6.     foreach (const Shape s; shapes) {
  7.         const Vector2f[] vertices = s.GetVertices();
  8.  
  9.         foreach (const Vector2f vec; vertices) {
  10.             v ~= Vertex(vec.x, vec.y);
  11.         }
  12.        
  13.         const Color[] colors = s.GetColor();
  14.  
  15.         foreach (const Color col; colors) {
  16.             c ~= col.GLConvert();
  17.         }
  18.     }
  19.  
  20.     writefln(" >> Vertices: %d, Colors: %d", v.length, c.length);
  21.  
  22.     Buffer b = new Buffer(Type.ArrayBuffer, 2);
  23.    
  24.     b[0].Cache(c.ptr, c.length * float.sizeof * 4);
  25.     b[1].Cache(v);
  26.    
  27.     v.clear();
  28.     c.clear();
  29.    
  30.     return b;
  31. }
  32.  


Ich sammle alle Vertices und speicher sie in einer struct namens Vertex und buffer sie. Und dann sammle ich alle Farben und speicher den void* pointer auf das erste Element und gebe als Größe eben die Anzahl der Elemente mal 4 (wegen RGBA) mal float.sizeof. Ist das falsch?

Das Cachen funktioniert einwandfrei, wie das zeichnen des eigentlichen Grids ja beweist.
Die Pointer Methode sieht so aus:
Code:
  1.  
  2. void PointerTo(const PtrType type) const {
  3.     this.Bind();
  4.  
  5.     final switch (type) {
  6.         case PtrType.Vertex:
  7.             glCheck(glEnableClientState(GL_VERTEX_ARRAY));
  8.  
  9.             glCheck(glVertexPointer(3, GL_FLOAT, 0, null));
  10.         break;
  11.  
  12.         case PtrType.TexCoord:
  13.             glCheck(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
  14.  
  15.             glCheck(glTexCoordPointer(3, GL_FLOAT, 0, null));
  16.         break;
  17.  
  18.         case PtrType.Color:
  19.             glCheck(glEnableClientState(GL_COLOR_ARRAY));
  20.  
  21.             glCheck(glColorPointer(3, GL_FLOAT, 0, null));
  22.         break;
  23.     }
  24. }
  25.  


Also aktivieren tue ich auch eig. alles.
Texturen sind zwar auch parallel aktiviert, aber das sollte ja nicht das Problem sein, oder? Die schwarzen Kacheln werden ja problemlos korrekt angezeigt.

Hier noch zwei Bilder:
Wie es mit dem Buffer aussieht:
http://s14.directupload.net/file/d/2896 ... tc_png.htm
und wie es eigentlich aussehen sollte:
http://s14.directupload.net/file/d/2896 ... 4a_png.htm


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glColorPointer - wie verwenden?
BeitragVerfasst: So Mai 20, 2012 13:59 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Sehe ich das richtig, dass deine Vertex- und Farbdaten sequentiell im Puffer liegen und nicht interleaved? Dann müsstest du bei glColorPointer noch ein Offset angeben, das sich aus der Anzahl der Vertices mal der Größe berechnet (als 4. Parameter).

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glColorPointer - wie verwenden?
BeitragVerfasst: So Mai 20, 2012 17:26 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Ich frag mal ganz blöd: Wie würde ich sie denn interleaved in den Buffer schreiben? Indem ich es abwechselnd buffere?

edit:
Und inwiefern gebe ich das offset an? Das ist doch ein Pointer?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glColorPointer - wie verwenden?
BeitragVerfasst: So Mai 20, 2012 18:37 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Nen Pointer ist auch nur ne Zahl ;). Einfach das Offset in Bytes nehmen, auf Pointer casten und dann geht das.

Interleaved: Weiß nicht wie man das in D baut, aber halt einfach immer abwechselnd Vertex und Farbe in den Puffer schreiben.

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glColorPointer - wie verwenden?
BeitragVerfasst: So Mai 20, 2012 19:30 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Ah danke vielmals, das werde ich direkt mal probieren. Aber gibt es keine Möglichkeit, das als interleaved anzusehen?
Mit glSecondaryColorPointer oder glInterleavedArrays?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glColorPointer - wie verwenden?
BeitragVerfasst: Mo Mai 21, 2012 14:43 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
glSecondaryColorPointer hat damit nichts zu tun. glInterleavedArrays schon, das ist aber auch nur eine Bequemlichkeitsfunktion für ein sehr eingeschränktes Set von Vertexbufferkonfigurationen. Wir haben auch ein Tutorial, wo darauf genauer eingegangen wird: VBO ohne glInterleavedArrays.

Du „markierst“ das ja schon als Interleaved, wenn du die Offsets einfach richtig setzt. Mehr ist interleaving ja nicht ;).

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glColorPointer - wie verwenden?
BeitragVerfasst: Mo Mai 21, 2012 16:15 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Also wie würde das aussehen, so?
Code:
  1.  
  2. void PointerTo(const PtrType type) const {
  3.     this.Bind();
  4.  
  5.     final switch (type) {
  6.         case PtrType.Vertex:
  7.             glCheck(glEnableClientState(GL_VERTEX_ARRAY));
  8.  
  9.             glCheck(glVertexPointer(3, GL_FLOAT, 0, null));
  10.         break;
  11.  
  12.         case PtrType.TexCoord:
  13.             glCheck(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
  14.  
  15.             glCheck(glTexCoordPointer(3, GL_FLOAT, 0, null));
  16.         break;
  17.  
  18.         case PtrType.Color:
  19.             glCheck(glEnableClientState(GL_COLOR_ARRAY));
  20.  
  21.             const void* ptr = this.GetBufferNum() == 1 ? null : cast(void*)(this._sizeof[0]);
  22.  
  23.             glCheck(glColorPointer(3, GL_FLOAT, 0, ptr));
  24.         break;
  25.     }
  26. }
  27.  

In Anbetracht, dass die CacheShapes Methode so aussieht:
Code:
  1.  
  2. static Buffer CacheShapes(const Shape[] shapes) {
  3.     Vertex[] v = [];
  4.     float[4][] c = [];
  5.  
  6.     foreach (const Shape s; shapes) {
  7.         const Vector2f[] vertices = s.GetVertices();
  8.  
  9.         foreach (const Vector2f vec; vertices) {
  10.             v ~= Vertex(vec.x, vec.y);
  11.         }
  12.        
  13.         const Color[] colors = s.GetColor();
  14.  
  15.         foreach (const Color col; colors) {
  16.             c ~= col.GLConvert();
  17.         }
  18.     }
  19.  
  20.     debug {
  21.         writefln(" >> Vertices: %d, Colors: %d", v.length, c.length);
  22.     }
  23.  
  24.     Buffer b = new Buffer(Type.ArrayBuffer, 2);
  25.    
  26.     b[0].Cache(v);
  27.     b[1].Cache(c.ptr, c.length * float.sizeof * 4); // maybe falsche Größe?
  28.    
  29.     v.clear();
  30.     c.clear();
  31.    
  32.     return b;
  33. }
  34.  


Also der Vertex in Buffer 0 und der Color in Buffer 1 wandert.

Rendern tue ich beides so:
Code:
  1.  
  2. b2[0].PointerTo(Buffer.PtrType.Vertex);
  3. b2[1].PointerTo(Buffer.PtrType.Color);
  4.  
  5. b2.DrawArrays(Shape.Type.Quad);
  6.  


Doch das klappt nicht, ich bekomme immer noch dieses Bild: http://s14.directupload.net/file/d/2896 ... tc_png.htm . Ist mein Offset falsch?

Mein "_sizeof" ist folgendermaßen definiert:
Code:
  1.  
  2. this._sizeof[this._current_buffer] = vertices.length; // bei den vertex daten
  3. // ...
  4. this._sizeof[this._current_buffer] = size; // bei Color; size wird beim Aufruf von "Cache" übergeben
  5.  


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glColorPointer - wie verwenden?
BeitragVerfasst: Mo Mai 21, 2012 16:25 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Ok, ich muss sagen, ich weiß nicht, was diese Buffer-Klasse macht. Kannst du mal sagen, in welcher reihenfolge die Daten im Speicher liegen?

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glColorPointer - wie verwenden?
BeitragVerfasst: Mo Mai 21, 2012 16:36 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Das sind die beiden Cache Methoden:
Code:
  1.  
  2. void Cache(const void* data, uint size, const GLenum usage = Usage.Static.Draw) {
  3.         this.Bind();
  4.  
  5.         this._sizeof[this._current_buffer] = size;
  6.  
  7.         glCheck(glBufferData(this._type, size, data, usage));
  8.     }
  9.  
  10.     void Cache(const ref Vertex[] vertices, const GLenum usage = Usage.Static.Draw) {
  11.         this.Bind();
  12.  
  13.         this._sizeof[this._current_buffer] = vertices.length;
  14.  
  15.         glCheck(glBufferData(this._type, vertices.length * Vertex.sizeof, vertices.ptr, usage));
  16.     }
  17.  


Zunächst liegen n viele Vertices in Buffer 1 und danach n / 4 viele Farben im RGBA Format im Buffer 2.
Für die Größe der Buffer nehme ich beim ersten die Anzahl an Vertices * sizeof(Vertex) (Vertex ist hier eine Struktur mit 3 floats für x, y und z) und beim zweiten die Anzahl an Farben (also n / 4) * sizeof(float) * 4. Missachte ich irgendwas? Oder ist noch was unklar? :)
Danke schon einmal für deine Mühe bisher.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glColorPointer - wie verwenden?
BeitragVerfasst: Mo Mai 21, 2012 18:01 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Jetzt sehe ich den Käfer.

Also die Cache-Methode für Color ist inkorrekt. Vergleiche dazu mal glBufferData und glBufferSubData. Der Punkt hier ist, dass du den Puffer immer neu erzeugst (was schonmal ineffizient ist; Du solltest auch für vertices auf glBufferSubData umsteigen[1]). Im Falle von Cache mit const void* data als erstem Argument bedeutet das, dass du einen Puffer der Größe size erzeugst und ihn mit dem einen Wert bzw Werteblock, der gerade in data steht, befüllst. Ist das klar soweit?

Das nötige Vorgehen wäre also entweder, das in ein Stream-Artiges Interface umzubauen, wo du einfach immer sequentiell in den VBO schreibst (z.B. mit glBufferSubData) oder im Programm selber den Inhalt des puffers cachest und dann komplett hochlädst. Weiterhin benutzt du (anscheinened) zwei unterschiedliche Vertex Buffer Objects. Du kannst aber nur eins gleichzeitig benutzen um zu Zeichnen. Du müsstest also die Daten entweder Interleaved oder Sequentiell in einen Puffer packen. Interleaved ist im allgemeinen schneller (Caching und so, Coolcat oder Tak haben bei sowas viel ahnung).

grüße

[1]: Grund: Bei glBufferData wird ein neues VB-Objekt auf der Grafikkarte bzw. im Treiber erzeugt. Außerdem werden die gesamten Daten neu übertragen. Bei glBufferSubData verwendest du das aktuelle Objekt (kannst dementsprechend auch nicht die Gesamtgröße ändern) und schreibst nur einen Teil davon neu. Um also glBufferSubData gut verwenden zu können, musst du auch noch einen kleinen Speichermanager implementieren. Eine (mehr oder weniger einfache) Implementation in C++ findet sich zum Beispiel hier: GenericBuffer.hpp und GenericBuffer.cpp.

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glColorPointer - wie verwenden?
BeitragVerfasst: Mo Mai 21, 2012 18:08 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Ich erzeuge diesen Buffer vor meiner GameLoop und cache dann alles und danach rufe ich die Cache Methode eig. nicht mehr auf. Ist das trotzdem schlimm? Denn wenn ich die Cache Methode nur einmal verwende sollte das doch klar gehen. Wie sähe es denn aus, wenn ich nun anstelle von glBufferData, glBufferSubData verwenden würde, dann würde ich doch nie einen VBO erzeugen. Mit glGenBuffer registriere ich mir ja lediglich eine ID für einen solchen. Oder hab ich das jetzt falsch verstanden? Oder sollte ich, nachdem ich einmal mittels glBufferData Daten in den Buffer übertragen habe, ein bool flag auf true setzen und _danach_ immer mit glBufferSubData arbeiten?

Ich verstehe nicht ganz, inwiefern meine Cache Methode für Color denn falsch sein soll. Oder ist es einzig und allein die Tatsache, dass ich glBufferData statt glBufferSubData verwende?

Und magst du mir evtl. (ich weiß, ist vllt. etwas viel verlangt), zeigen, wie ich an meinem Code denn dann ein interleaved Buffer machen würde? Also wie und was ich an meiner "CacheShapes" Methode ändern müsste? Das wäre super.

edit:
Danke für die Links, die werden direkt mal angeguckt.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glColorPointer - wie verwenden?
BeitragVerfasst: Di Mai 22, 2012 16:11 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Ich muss sagen, dass ich mit D nicht so familiar bin. Aber ich sehe gerade dass der Pufferinhalt bei dir dennoch korrekt sein sollte. Du fügst ja erst alle Color-Elemente aneinander und schreibst die dann in einem Rutsch in den Puffer. Ich hab gedacht du schreibst sie einzeln in den VBO, das habe ich falsch gelesen.

Okay, dennoch hast du immer noch das Problem, dass du nur einen Puffer gleichzeitig verwenden kannst.

Und was das Interleaved betrifft: Naja, das Ziel was du erreichen willst ist, dass die Daten so auf der Grafikkarte liegen:
[x1] [y1] [z1] [r1] [g1] [b1] [a1] [x2] [y2] …

Wie du das jetzt in den Puffer überträgst ist deiner Phantasie überlassen. Ich habe es in dem Geometriepuffer (hpp, cpp) so gemacht, dass man über Views dann darauf zugreifen kann und die Elemente einzeln setzen… Ein bisschen abgefahren zugegebenermaßen, funktioniert aber ausreichend performant, solange man die Daten nicht zu oft ändert ;).

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glColorPointer - wie verwenden?
BeitragVerfasst: Di Mai 22, 2012 16:19 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Also ist das mein einziger Weg, dass ich die Farbigen sehen kann? Dann brauche ich ja nur einen Buffer, oder sehe ich das falsch?
Ich hätte es eig. eher gerne getrennt, geht denn das nicht auch irgendwie? Sprich irgendwie zusammen mischen?

Ansonsten: wie würde mein foreach dann aussehen? Weil ich müsste ja dann quasi nach jedem Vertice ein Color aufnehmen.
also
Code:
  1. float[][] vert_col;
  2. foreach (const Shape s; shapes) {
  3.         const Vector2f[] vertices = s.GetVertices();
  4.  
  5.         foreach (const Vector2f vec; vertices) {
  6.             vert_col ~= [vec.x, vec.y];
  7.         }
  8.        
  9.         const Color[] colors = s.GetColor();
  10.  
  11.         foreach (const Color col; colors) {
  12.             vert_col ~= [col.r, col.g, col.b, col.alpha];
  13.         }
  14.     }


Und dann vert_col als void* in den Buffer.
Seh ich das so richtig? Oder ist das falsch/unperformant/unelegant?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glColorPointer - wie verwenden?
BeitragVerfasst: Di Mai 22, 2012 16:22 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
hm, bin mir gerade nicht hundertprozentig sicher, wie der ~-Operator in D funktionierte. Kommt da dann [[x, y, z], [r, g, b, a], [x, y, z], ...] raus oder [x, y, z, r, g, b, a, x, y, z, ...]? Ersteres ist falsch und wird nicht funktionieren, letzteres funktioniert.

Du kannst, wie gesagt, nur einen Geometriepuffer zum Zeichnen verwenden. Du kannst deine Daten aneinanderhängen und in *einen* Puffer packen. Ist nicht sonderlich performant, aber geht. Besser ist halt Interleaved.

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: glColorPointer - wie verwenden?
BeitragVerfasst: Di Mai 22, 2012 16:25 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Zweiteres wäre aber dann korrekt? Und dieses interleaven ist der performanteste Weg (nur um nochmal ganz sicher zu gehen ;))?


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 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:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.011s | 16 Queries | GZIP : On ]