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

Aktuelle Zeit: Fr Jul 18, 2025 14:01

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



Ein neues Thema erstellen Auf das Thema antworten  [ 17 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: OpenGL dämpfer!
BeitragVerfasst: Fr Aug 22, 2008 17:41 
Offline
DGL Member

Registriert: So Jan 23, 2005 13:21
Beiträge: 46
Wohnort: Vietnam
Servus!

Ich würd gern mal wissen, was so alles die Grafikkarte beschleunigt bzw nicht dämpft. Naja, OpenGL ganz weg lassen, dann hat die Grafikkarte wenig zu tun, dass is mir klar ;-). Was ich aber meine sind Sachen, die man einfach wissen sollte. Wie folgende BSP:

1. Texturen so wenig wie oft binden. Daher auch Animation in eine Texture verpacken. Wie auch Objekte mit der selben Texture zusammenhaun, einmal die Texture binden und dann alle Objekte gleich auf einmal mit der Texture zeichnen.

oder auch:

Falsch:
Code:
  1. for (int counter = 0; counter < 1000; counter++) {
  2.     glBegin(GL_QUADS);
  3.         gl.glTexCoord2f(0.0f, 1.0f);    gl.glVertex3d(A[counter].x, 0.0, 0.0);
  4.         gl.glTexCoord2f(1.0f, 1.0f);    gl.glVertex3d(B[counter].x, 0.0, 0.0);
  5.         gl.glTexCoord2f(1.0f, 0.0f);    gl.glVertex3d(C[counter].x, 1.0, 0.0);
  6.         gl.glTexCoord2f(0.0f, 0.0f);    gl.glVertex3d(D[counter].x, 1.0, 0.0);
  7.     glEnd();
  8. }


sondern Richtig:
Code:
  1. glBegin(GL_QUADS);
  2.     for (int counter = 0; counter < 1000; counter++) {
  3.         gl.glTexCoord2f(0.0f, 1.0f);    gl.glVertex3d(A[counter].x, 0.0, 0.0);
  4.         gl.glTexCoord2f(1.0f, 1.0f);    gl.glVertex3d(B[counter].x, 0.0, 0.0);
  5.         gl.glTexCoord2f(1.0f, 0.0f);    gl.glVertex3d(C[counter].x, 1.0, 0.0);
  6.         gl.glTexCoord2f(0.0f, 0.0f);    gl.glVertex3d(D[counter].x, 1.0, 0.0);
  7.     }
  8. glEnd();
  9.  


oder auch:
Alle Modelle, Texturen, etc am Anfang laden und Speichern. Damit die Grafikkarte später nur mehr mit dem Darstellen beschäftigt ist.

Was sollte man da noch beachten? Ich finde so ne Sammlung wäre nicht schlecht. Damit kann man sicher als Anfänger seine Programme um einiges performanter gestallten und man muss sich dann nicht so sorgen um die Laufzeit machen.

hoffe, das der thread nützlich sein wird... (vorallem anfängern wie mir :-D )

_________________
"As the enemy went to heaven,
we stayed in hell!"


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 22, 2008 18:32 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 27, 2005 12:44
Beiträge: 393
Wohnort: Berlin
Programmiersprache: Java, C++, Groovy
Hallo,

hmm...was mir noch einfällt...bei kostspieligen Aktionen wie z.B. glReadPixels oder glDrawPixels alle unnötigen Zustände ausschalten, GL_LIGHTING, GL_DEPTH_TEST usw...

Viele Grüße
dj3hut1

_________________
Wenn Gauß heute lebte, wäre er ein Hacker.
Peter Sarnak, Professor an der Princeton University


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 22, 2008 19:02 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
ISAS: Dein Richtig ist leider auch nicht ganz Richtig. ;) Denn um genau zu sein ist der Imediate Mode seit OpenGL 1.5 überholt und das ist seit ca 5-6 Jahren draußen. Deine Zweite Variante ist in jedem Falle besser als die erste Variante. Das ja. Wobei ich persönlich auch einen Unterschied festgestellt habe ob ich einen Pointer auf ein Array übergeben oder ob ich die einzelnen 3 Floats per Hand übergebe. Der Grund dafür. Die Parameter werden über den Stack gereicht und da ist ein 32 Bit Pointer kleiner als 3x 32 Bit Werte. Zu mal Floats auch immer über die FPU gehen.

Ganz Richtig wäre die Verwendung von Vertex Buffer Objects. Denn und jetzt kommts. Die GPU arbeitet asynchron. Das Beste was du der GPU tun kannst ist ihr zu sagen. Hier ist meine Szene und nun mach. Aber das geht normal nicht deswegen kann der Treiber auch Befehle speichern und sie später ausführen. Aber es gibt verschiedene Aktionen die eine Synchronisation erzwingen. Mit anderen Worten das Ganze aubremsen. Das Problem hierbei. Es kommt da a) auf den Treiber an und b) gibt es eine vielzahl an Befehlen die das auslösen können.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Aug 23, 2008 01:15 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Leider bist du du auch nicht merh Up2Date Lossy :p
Mitlerweile ist die performanteste Variante ein Vertex Objekt Array mit mehreren Vertex Buffer Objekts gefüllt, leider kann man dies bisher nur auf NV Grakas mit OpenGL 3.0 betatreiber machen xD.

nicht zu kleine und zu große happen, also so um die 4KB sollten es sein. Vertice so sortieren, dass die Vertice häuffig nacheinander wieder auftreten, da so der sehr stark beeinflussende Cache ausgenutzt wird. ATI bietet ein Tool für das reordering an, NV vieleicht auch.
Vertice sollten auch innen nach aussen sortiert werden, damit die overdraws möglichst klein sind(kann das gleiche ATI tool auch).

Wenn möglich immer DXT verwenden, da es weniger speicher braucht und an allen Stellen schneller ist.

DDS oder ein DDS ähnliches Format für Texturen verwenden, da das laden aus diesem Format mit einen Read bewerktstelligbar ist und die Daten schon aufbereitet vorliegen und kein Konvertieren notwendig ist. Der Unterschied von einer 512x512 Textur BMP und DDS war bei mir um den Faktor 10 beim laden und die FPS ist einfach zu unterschiedlich zwischen den Grakas und den dargestellten Szenen(eine Textur voll auf den Bildschirm gepackt ist z.B. ~3-4mal schneller, da man pro lookup 4 Texel raus bekommt).

Immer 2 Passes verwenden, erst einen reinen z-buffer Pass, der die Geometry in den Tiefenpuffer zeichnet und dann mit aktiven Tiefenpuffer Test den 2. Pass normal in den Backbuffer zeichnen. Das reduziert den Overdraw auf ein Minimum und kann gerade beim einsatz von Shadern extreme Perfschübe bringen.

Immer Triangle Stripes vewenden, die sind Cachefreundlicher und damit schneller.

Immer Mip-Maps verwenden, da dies Artefakte auf größerer Distanz reduziert und die Performance steigert(sonnst muss über die ganze Textur interpoliert werden und gerade bei Full-HD der tot jeder graka).

Immer POT Texturen verwenden und wenn man doch mal unbedingt welche braucht, die NPot sind, dann schreibt euch ne kleine Klasse, die die Textur in eine POT textur kopiert und die Texturkoordinaten entsprechend anpasst.
Damit hat man mehr power, keine extra Ladezeit beim Up oder Downsampling und die damit verbundenen Artefakte entfallen auch.
Gerade bei GUI extrem sinnvoll.

Benutzte Formate, die Serializeable sind, also in einen zug geladen, offsets zu pointer verarbeitet werden und sofort als Objekte zur verfügung stehen.
Das ist die schnellste Lademethode, die bis dato möglich ist.
Für Models hab ich im Wiki mal ein Artikel geschrieben. http://wiki.delphigl.com/index.php/Modelformat

Alle berechnnung in Float durchführen, statt integer, da schon seit einigen CPU Generationen float default schneller ist als int.

Compiler:
Bei Delphi so wenig wie möglich an Procedure/Funktion/Methoden verwenden, da Delphi im gegensatz zu FreePascal sehr auf korrektheit bei den Parametern und rückgabewerten legt und die immer überprüft. Gerade in verbindung mit unserer Loop of Death xD, fallen solche oft völlig unnötigen überprüfungen stark auf. Generell rate ich die release auf FPC zu erstellen, da dieser den Speichereffizientesten Code und auch um einiges schnelleren Code generiert und auch prima CPU erweiterungen wie MMX,SSE1-3 in den Code einbauen kann.
So wenig wie möglich(am besten garnicht), auf RTTI in der zeichenschleife aufrufen, es gibt nicht vieles was noch langsamer ist.
Lösung: Zur laufzeit die Infos versuchen fest zu linken, also im ersten durchlauf an Variablen oder so fest verdrahten und beim 2. aufruf dann diese verwenden, statt nochmal die RTTI zu verwenden.

Wenn man Sinus/Cosinus, für z.B. Camera, durch Arrays mit passender genauigkeit ersetzen, dann ist das auch förderlich.

SzeneGraph, oft wird viel CPU für unsauberes Managment der Szene vergeuldet.
Ein SG kann nicht nur durch Caches und Hashlisten viel Performance bieten, er macht die ganze Sache übersichtlicher, erlaubt einfacheres Optimieren, da alles an einen Punkt gebündelt vorliegt.
Ein einfacher SG kann schon mit 100-200Zeilen Code bewerkstelligt werden und ist auch nicht wirklich schwer zu verstehen.

Zum schluss fällt mir nur noch eines ein. Nur Optimieren, wenn es wirklich notwendig ist, also man unter die 60FPS auf dem Zielsystem fällt.
Alles andere ist völlig verschwendete Zeit und hat niemanden was gebracht.

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

Projekte: https://github.com/tak2004


Zuletzt geändert von TAK2004 am Mo Aug 25, 2008 11:57, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Aug 23, 2008 07:33 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
@Tak2004 schrieb:
Zitat:
Alle berechnnung in Float durchführen, statt integer, da schon seit einigen CPU Generationen float default schneller ist als int.

Ich hab es eigentlich immer anders gehört/gelesen. Vielleicht bin ich ja auch OutOfDate. Kannst Du das belegen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Aug 23, 2008 08:15 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
TAK2004 hat geschrieben:
Leider bist du du auch nicht merh Up2Date Lossy :p

So schnell kanns gehen. ;)

Und zum Thema optimieren. Sagen wir so. Das es unnütz ist würde ich so nicht sagen. Man sollte zu mindest wissen was man und sein Kompiler tut. Dann kann man gewisse Schwachstellen vermeiden. Damit werden einige Stellen von Hause aus schneller. Die Longstrings/dynamische Arrays in Delphi erzeugen reichlich Code den man so nicht sieht. Je nachdem wie kritisch eine Stelle ist kann das schon etwas unangenehm werden. Also man muss nicht optimieren wie ein Berserker es genügt zu wissen was dort passiert (CPU Fenster von Delphi ist sehr praktisch) und dann eben solchen Aufwand zu vermeiden.

Float vs Int: Ich denke da kann man sehr viel mit MMX, SSE und dessen Erweiterungen machen. Wenn es denn möglich ist. Damit kann man dann 2, 4 oder 8 Werte gleichzeitig berechnen. Besonders für Vektor und Matrizen Berechnungen ist das gut geeignet. das ist dann noch mal gut ein Stück schneller. Wobei aber auch da gilt. Aufwand den man vermeiden kann (sei es durch eine andere Struktur) ist immer die beste Lösung. Sofern das Überprüfen des Aufwandes nicht irgendwann zu groß wird.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Aug 23, 2008 11:17 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
MMX = Mitunter mühsame Xuche nach Abkürzungen? 8)

OK ich bin DEFINITIV OutOfDate.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Aug 23, 2008 11:40 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 27, 2005 12:44
Beiträge: 393
Wohnort: Berlin
Programmiersprache: Java, C++, Groovy
ein paar gute Tips zur Performance gibt es auch unter http://opengl.org/resources/faq/technical/performance.htm

_________________
Wenn Gauß heute lebte, wäre er ein Hacker.
Peter Sarnak, Professor an der Princeton University


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Aug 23, 2008 13:20 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Jetzt ein Example für float und int zu schreiben ist mir zu mühselig aber als ich mein vorletzten Algotex geschrieben habe, da wurde mir nahe getragen die Texturgenerierung über Float zu machen, da diese schneller ist und als ich ein bischen auf float umgestellt hatte, lief es auf meinen AMD X2 tatsächlich schneller. Das hängt wohl damit zusammen, das mehr rechenwerk für Gleitkomma berechnung als für Ganzzahlige Zahlen zur verfügung steht.(Mal sehen, vieleicht kann ein kleinen Benchmark mit in die Bachelorarbeit rein quetschen, dann sieht man mal den Unterschied.)

_________________
"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  
 Betreff des Beitrags:
BeitragVerfasst: Mo Aug 25, 2008 10:55 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jan 04, 2008 21:29
Beiträge: 419
Wohnort: Lübeck
moin, hab mir gerade den thread durchgelesen (auch wenn die tak Beiträge etwas anstrengend sind^^) und da ist mir doch ein kleines Detail aufgefallen bei dem ich mir nu nicht ganz sicher bin ob ich das so verstanden hab, wie es gemeint sein soll. Soll ich in zukunft tatsächlich alle meine POT texturen in NPOT zerlegen und wenn es geht von vorneherein NPOT verwenden? NON-power-of-two hört sich nähmlich etwas schädlich an für die Arbeitslust meiner kleinen Graka. Kann ja auch nur ein Flüchtigkeitsfehler sein.
mag ja etwas kleinkariert erscheinen, aber im gegensatz zu einigen anderen Sachen die hier mit angesprochen wurden, sind das Dinge, die Anfänger verwenden und gerne falsch machen. Immerhin sollte sich dieser Thread ja nicht auf "wie spar ich 0,2ms für meinen nextgen shooter, weil ich ein GraPro bin?" beziehen, sondern OpenGl speziefische funktionen, die in falscher Nutzung die Anwendung bremsen, ohne dass es beim Programmieren den anschein gemacht hätte.

_________________
Klar Soweit?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Aug 25, 2008 11:56 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Hilfe, dass dies keinen so schnell aufgefallen xD Ich hab POT und NPOT verdreht, ich fixe das mal schnell.
Natürlich soll man POT Texturen verwenden, NPOT wird ja erst mit neuerer Hardware supportet aber ist trotzdem nicht so schnell wie POT.

_________________
"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  
 Betreff des Beitrags:
BeitragVerfasst: Mo Aug 25, 2008 12:13 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Ich hab am wochenende auf einem Deutschen Entwicklerforum ein neuen Artikel gesehen, der war ziemlicher mist aber 2 dinge, die er angesprochen hat sollten doch noch hier erwähnt werden.

Vermeidung von Bind/Unbind:
Code:
  1. //langsam
  2. for i:=0 to 9 do
  3. begin
  4. glbegin(GL_TRIANGLES);
  5. .....
  6. glEnd();
  7. end;
  8.  
  9. //schnell
  10. glBegin(GL_TRIANGLES);
  11. for i:=0 to 9 do
  12. begin
  13. ...
  14. end;
  15. glEnd();

Für Textur,Shader und VBO bindings sollte man die Szene vorsortieren, Nach Textur,Shader,VBO.

Die 2. Sache ist selbst in meinen Code noch zu finden.
Dabei geht es um if,case abfragen die man in den meisten fälle einfach mit einen array von methoden um ein vielfaches beschleunigen kann.
Code:
  1. ...
  2. const
  3.   blupp=0;
  4.   blupper=1;
  5.   blups=2
  6.   MAXCASES=blups;
  7. ...
  8. //ungünstiges If konstrukt
  9. If bla=blupp then
  10. ...
  11. else
  12.   if bla=blupper then
  13.   else
  14.     ...
  15.  
  16. //ungünstiges case konstrukt
  17. case bla of
  18.   blupp:...
  19.   blupper:...
  20. end;
  21.  
  22. //performante Lösung
  23. var blacallbackarray:array [MAXCASES] of procedure;
  24. ...
  25. blacallbackarray[blupp]=myblupp;
  26. blacallbackarray[blupper]=myblupper;
  27. blacallbackarray[blups]=myblups;
  28. ...
  29. blacallbackarray[bla]();

_________________
"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  
 Betreff des Beitrags:
BeitragVerfasst: Mo Sep 01, 2008 14:12 
Offline
DGL Member
Benutzeravatar

Registriert: Do Aug 25, 2005 16:00
Beiträge: 189
Programmiersprache: Java, C#
Hm, ich grübel grad über das mit den if- und case-Abfragen...
Die stellen wo das wirklich funktioniert sind doch eigentlich relativ rar gesäht, ich mein sobald da ein else steht wars das mit der Optimierungsmöglichkeit, z.B:
Code:
  1. if (testvar = 0) then
  2.    //irgendwas machen

funktioniert nich, genauso wenig wie:
Code:
  1. if (testvar = 0) then
  2.   //irgendwas machen
  3. else
  4.   //was anderes machen

oder
Code:
  1. case i of
  2.  0: //irgendwas
  3.  1: //noch was
  4. else
  5.   //was ganz anderes
  6. end;



Die einzige Möglichkeit so zu optimieren wäre wirklich bei so ner Abfrage:
Code:
  1. case i of
  2.   0: //irgendwas
  3.   1: //was anderes
  4.   2: //und noch was ganz anderes
  5. end;


Oder versteh ich da grad was völlig falsch? Denn so Codestellen wie im letzten Stück sind doch eigentlich wirklich sowas wie ne absolute ausnahme (zumindest kann ich mich nicht dran erinnern sowas schon oft gesehen zu haben)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Sep 01, 2008 16:39 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Code:
  1. //eine Zahl zwischen 0 bis 9
  2. case myindex of
  3.   1:writeln('1');
  4.   2:writeln('2');
  5.   3:writeln('3');
  6.   4:writeln('4');
  7.   5:writeln('5');
  8.   6:writeln('6');
  9.   7:writeln('7');
  10.   8:writeln('8');
  11.   9:writeln('9');
  12.   0:writeln('0');
  13.   else
  14.     writeln('unknown');
  15. end;
  16.  
  17. //alternativ
  18. if (myindex<=9) then
  19.   writeln(inttostr(myindex));
  20. else
  21.   writeln('unknown');


Code:
  1. const MAXSELECT=10;
  2. procedure num0(); begin writeln('0'); end;
  3. procedure num1(); begin writeln('1'); end;
  4. procedure num2(); begin writeln('2'); end;
  5. procedure num3(); begin writeln('3'); end;
  6. procedure num4(); begin writeln('4'); end;
  7. procedure num5(); begin writeln('5'); end;
  8. procedure num6(); begin writeln('6'); end;
  9. procedure num7(); begin writeln('7'); end;
  10. procedure num8(); begin writeln('8'); end;
  11. procedure num9(); begin writeln('9'); end;
  12. procedure numErr(); begin writeln('unknown'); end;
  13.  
  14. myindex[0]=num0;
  15. myindex[1]=num1;
  16. myindex[2]=num2;
  17. myindex[3]=num3;
  18. myindex[4]=num4;
  19. myindex[5]=num5;
  20. myindex[6]=num6;
  21. myindex[7]=num7;
  22. myindex[8]=num8;
  23. myindex[9]=num9;
  24. myindex[10]=numErr;
  25.  
  26. ...
  27. number0till9check[min(myindex,MAXSELECT)];


Prinzipiell ist die Variante schreibaufwändiger aber immer schneller.
Die Beispiel sind ein bischen Blöd aber wo es sich wirklich lohnt ist halt mehr aufwand an Code zu schreiben, drum nur so kleine pille palle beispiele.
Im Bereich KI,Physik oder Parsen geht sowas sehr gut, bei anderen dingen ist es eher Erbsenzählerei und unnötig.

_________________
"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  
 Betreff des Beitrags:
BeitragVerfasst: Mo Sep 01, 2008 17:43 
Offline
DGL Member
Benutzeravatar

Registriert: Do Aug 25, 2005 16:00
Beiträge: 189
Programmiersprache: Java, C#
Ah, k, jetzt versteh ich eher wie sowas auszusehen hat. Thx. :D


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


Wer ist online?

Mitglieder in diesem Forum: Google [Bot] und 6 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 ]