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

Aktuelle Zeit: Fr Apr 19, 2024 07:40

Foren-Übersicht » Sonstiges » Community-Projekte
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 20 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: [Header] dglOpenGL und .NET 1.1
BeitragVerfasst: Fr Nov 24, 2006 11:15 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Ich bin derzeit dabei in den Header OpenGL 2.1 und die GF8 Extensions einzubauen und dabei sind mir mal wieder ein paar Dinge aufgefallen. Ich habe darüber bereits seit mehereren Tagen nachgedacht und bin zu dem Ergebniss gekommen, dass ich zu keinem Ergebniss gekommen bin. Deswegen möchte ich das einfach mal hier in den Raum stellen und eine Diskussion dazu anfangen.

Wo liegt jetzt genau mein Problem. Zu Zeiten von .NET 1.1 haben wir einige Dinge einbauen müssen, weil .NET nicht so ganz mit dem Header klar gekommen ist. Und genau diese Sachen sind mir ein Dorn im Auge. Denn der Punkt ist, dass man für eine neue OpenGL Methode folgende Schritte durchführen muss.
1. Typ der Methoden anlegen (TglBlah = Procedure (Blah, Blah));
2. Variable des Typens anlegen (glBlah: TglBlah)
3. Die Variable in der entsprechenden Methode (Extension oder Core) laden.
4. Pseudofunktion (STUB_glBlah) erstellen die seinerseits den Methodenpointer noch einmal extra lädt und dann die Methode ausführt.
5. Pseudofunktion in die Methode InitStubs hinzufügen damit diese beim Start auf die Variablen zuweisen werden.

Den Schritt 1 und 2 könnte man normal auch zusammen legen aber da im späteren Verlauf (auch für .NET) noch mal ein Typ benötigt wird ist das wohl nicht möglich. Der Aufwand dafür ist aber verschwindend gering. Weswegen mich das überhaupt nicht stört.

Mir geht es hauptsächlich um die Schritte 4 und 5 (Stubs). Diese Stubs existieren einzig und allein nur deswegen weil .NET 1.1 so extreme Probleme hat mehrere Funktionen an einem Stück zu laden (Dauert zu lange). Der Aufwand das zu verwalten ist ziemlich hoch. Aus dem Grund das Laden zu vereinfachen existiert auch für jede Extension eine Methode um die Funktionspointer zu laden. Bzw eine für den Core. Fakt ist aber, dass alleine beim Core ca 90-95% der geladenen Methoden gar nicht aufgerufen werden.

Punkte für Stubs.
- Das Laden der Methoden geht wesentlich schneller, da keine Methoden mehr geladen werden müssen. Sie werden nur dann geladen wenn sie auch tatsächlich benötigt werden. Bei nicht .NET ist der Geschwindigkeitsvorteil auch vorhanden auch wenn nur in wesentlich geringerem Ausmaß.
- Lange genug etabliert und rege Benutzung selbst bei nicht .NET Anwendungen.

Contra Stubs.
- Wesentlich erhöhterer Implementationsaufwand von neuen Extension. Ich habe alleine für die 6 Methoden von 2.1 ca 15 - 20 Minuten gebraucht. Und das obwohl da jeweils nur der Name anders ist. Ich mag gar nicht dran denken wie ie GF8 Extensions reinhauen. Grob geschätzt sind das 80 Methoden die alle komplett anders sind. :-/
- Teilweise ist es nicht erlaubt wglGetProcAddress in einem glBegin und glEnd Block aufzurufen. Es gibt somit teilweise zu Begin einmal eine Invalid Operation. Trotz des Fehlers scheint es richtig geladen zu werden und zu arbeiten. Aber es ist ein Fehler der durch einen Workaround des Headers entsteht.
- (nicht wichtig) Alleine durch das auskommentieren der Methode InitStubs wird die exe mal eben um ca 150 KB kleiner. Und der Header wird um die Hälfte kleiner wenn die Stubs entfernt sind.

In erster Linie geht es mir darum den Header zu vereinfachen. Ich möchte nicht die .NET Unterstützung ausbauen sondern nur wenn möglich vereinfachen. Ich bin lange genug Softwareentwickler um zu wissen, dass man nicht einfach mal eben so die Funktionsweise einer Schnittstelle ändert. Vor allem nicht dann wenn diese schon recht weit verbreitet ist und das möchte ich von dem Header ja wohl mal meinen. Leider ist es auch so, dass viele nicht .NET Benutzer nicht expliziet die Methodenpointer laden. Somit werden da dann auch unbewusst die Stubs verwendet. Was das Ganze dann wiederrum auf den Win32 Bereich (mit ~80-90% der Hauptbereich) ausdehnt. Wenn man das jetzt entfernen würde wären sehr viele Leute sehr traurig, da deren Anwendungen beim Starten eine Zugriffsverletzung auslösen würden und keiner so genau wüsste wo das Problem liegt.

Diese ganze Diskussion ist im übrigen auch überflüssig, wenn .NET 2.0 ähnliche Probleme hat wie es bei 1.1 der Fall ist. Also, dass die Methoden superlangsam geladen werden. Auch weiß ich gar nicht ob überhaupt irgend jemand die Kombination dglOpenGL und .NET benutzt. Lars benutzt mittlerweile C# somit ist der einzige mir bekannte Benutzer der Kombi abgewandert.

---------------------------------------------------------------------------------

Etwas was nicht ganz zum obrigen Thema gehört mir aber seit dessen Implementation ein Dorn im Auge ist sind die Hilfsfunktionen für .NET. Als Beispiel wäre da die Methode glTexImage2D. Für .NET wurden dort 4 Überladungen geschrieben. Eine bei der man zum Beispiel ein Bitmap übergeben kann und diese Methode holt sich automatisch die Daten aus dem Bitmap. Oder bei glGenTextures wo das Ergebniss nicht als Parameter sondern als Rückgabewert zurück kommt bzw die anderen Überladungen die sogar gleich eine komplette Textur erstellt und ein paar Textureigenschaften setzen ohne zu prüfen ob die überhaupt unterstützt werden. etc.

Dort bin ich nach wie vor der fensten Überzeugung, dass diese Methode in einem Schnittstellenheader nichts verlohren haben. Sondern wenn dann gehört das in eine extra Unit und das ist dann nicht mehr unsere Sache. Sondern die des entsprechenden Entwicklers. Denn der Punkt ist, dass da so der Eindruck erweckt wird, dass OpenGL das unterstützt und außerdem ist es nur für eine Hand voll Methoden gemacht worden, die auch nur unter .NET verfügbar sind. Spezialhandling was dort eigentlich nicht so wirklich hingehört halt.

Das als Zweites, nicht ganz so wichtiges Thema. Aber diese Methoden würde ich am Liebsten komplett entfernen wollen. Und OpenGL in seiner unbehandelten Form anbieten wie es schon immer hätte sein sollen. ;-)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 24, 2006 11:54 
Offline
DGL Member

Registriert: Do Mai 30, 2002 18:48
Beiträge: 1617
Warum diese Methoden nicht einfach in eine kleine DGLUtils Klasse auslagern? Dann sind sie nicht verloren, man muss sie nicht erst schreiben wenn man sie mal auf die schnelle braucht und man erkennt, daß sie Original nicht zu OpenGl gehören, aber unter .Net ist es sehr sehr naheliegend, diese Funktionen zur Verfügung zu haben, da sich die Programmierung von OpenGl so prima in .Net einfügt.
Mir ist aber da noch aufgefallen, daß man die Header auch mal ganz simple als Assembly samt dll zusammenstellen kann - dann kann man sie auch sehr einfach in eigenen Projekten verwenden, selbst wenn diese in einer anderen Sprache geschrieben wurden.
Andererseits hab ich so den Verdacht, daß der Aufwandt um neue Funktionen in den Header zu implementieren langsam deutlich überhand nimmt. Ist es nicht ökonomischer den Header anhand einer Funktionendatei automatisch erstellen zu lassen? Man muss dann nur noch die Funktionen in eine Textdatei eintragen, evtl. noch ein paar Optionen dazu und fertig. Wenn man das richtig macht, kann man dann auch den Header Erzeuger austauschbar schreiben und so automatsich Header für recht beliebige Sprachen bekommen - ist aber nur so eine Idee.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 24, 2006 12:46 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 03, 2002 15:08
Beiträge: 662
Wohnort: Hamburg
Programmiersprache: Java, C# (,PhP)
Auch wenn ich die Header nicht nutze, kann ich mir Nicos Vorschlag die jeweiligen Elemente auszulagern nur anschließen. Wer will schon mehr Last mit sich rumtragen als wirklich notwendig ist. Der einmalige Aufwand zum auslagern ist vielleicht größer, aber der nachhaltige Nutzen sollte diesen Aufwand aufwiegen.

Dies wird bei anderen Sprachen die auf OGL zugreifen doch auch gemacht.

Kann man für die Schritte 4 und 5 nicht Lazy Loading verwenden? Oder geht das unter Delphi/.Net nicht?

_________________
(\__/)
(='.'=)
(")_(")


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 24, 2006 13:55 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Helperfunktionen:
Die zusätzlichen Methoden in eine andere Unit auslagern hatte ich früher schon mal angedacht jetzt aber gar nicht mehr dran gedacht. Klar damit der Code nicht verlohren geht macht das sicherlich Sinn. Es ist dort zu mindest besser aufgehoben als im Header selbst. Denke mal das werde ich mal tun. Evtl kann man da ja dann auch später so typen wie 2 Byte Floats oder so was implementieren.

Assembly:
Muss ich passen. Mit .NET kenne ich mich auch überhaupt nicht aus. Die Sachen die dort eingebaut sind lasse ich so weit es geht in ruhe eben um nicht gefahr zu laufen was kaput zu machen. Kann somit also auch nicht ausprobieren ob das so überhaupt alles noch funktioniert etc. Und entsprechend habe ich überhaupt keine Ahnung was ich machen muss um ein Assambly zu erzeugen bzw was das für einen Aufwand darstellt. Sinnvoll und praktisch wäre so etwas mit Sicherheit schon.

Generation:
Ich hatte für die erste Version des Header schon mal ein Tool geschrieben was den Originalen C++ Header parst und diesen dann in einen Pascalheader umwandelt. Allerdings war es so, dass da immer wieder neue Typen definiert wurden und man letzten Endes noch reichlich nacharbeiten musste. Dort besteht aber auch wieder das Problem wie schaut das aus. Das muss man irgendwie pflegen bzw falls eine neue Core Version hinzukommt muss die Abfrage erweitert werden etc. In der Extension GL_EXT_timer_query haben die einen Typen namens GLuint64EXT definiert. Na fällt euch was auf? Den Typen gibt es in Delphi nicht. Das wird wohl auf ein Int64 (mit Vorzeichen) hinauslaufen. Aber wie gesagt ist das mit dem Header bis auf die Punkte 4 und 5 eigentlich alles sehr einfach. Nur eben diese Punkte machen das ganze recht mühsam. Und da frage ich mich halt ob man das derzeit wirklich noch braucht. Wo ja .NET 2.0 draußen ist und wesentlich offener ist.

Wobei ich die Idee mit so einem Tool auf jeden Fall sehr gut finde. So ist es nicht. Nur denke, dass der Aufwand dieses so hinzubekommen, dass es funktioniert und sich leicht pflegen lässt zeitlich ein wenig den Rahmen sprengt. Zu mindest meinen.

Lazy Loading:
Beschreibe das mal bitte. Sagt mir so gerade gar nichts. Dummerweise muss so etwas kompatibel mit Delphi, Free Pascal und .NET sein.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 24, 2006 14:26 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 03, 2002 15:08
Beiträge: 662
Wohnort: Hamburg
Programmiersprache: Java, C# (,PhP)
Lazy Loading ist ein DesignPattern zum Laden von Objekten zum Zeitpunkt ihrer Notwendigkeit.
http://en.wikipedia.org/wiki/Lazy_loading

Funktioniert allerdings nur in der OOP. Wie man das bei der prozeduralen Programmierung umsetzen sollte ist mir unklar.

Hab mal eben geschaut wie das bei der LJWGL OGL Binding für Java gemacht wurde. Da generieren wir sehr viel über Metadaten. Einmal die Funktions Signatur schreiben und die Metadaten (Annotations angeben) und und aus dem Template wird eine kompilierbare Java Datei erzeugt.

Sowas muss es doch für Delphi auch geben.

_________________
(\__/)
(='.'=)
(")_(")


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 24, 2006 16:06 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Lazy Loading:
Genau das wird durch die Stubs ja in Procedural gemacht. Also vom Prinzip her. Es wird für jede Methode eine Zusatzmethode gemacht die beim ersten Aufruf den Methodenpointer lädt und den dann noch aufruft.

Generation:
Ja das stimmt ja durchaus. Ideal wäre es, wenn man eine XML Datei machen würde in der alle Extensions -> Konstanten und Funktionen aufgelistet sind. Dann kann man dort alle benötigten Typen definieren. Mit hilfe eines Templates könnte man dann einen Header für X oder Y erzeugen. Nur das muss erst einmal alles gemacht werden und im Endeffekt steht und funktioniert der Header so wie er ist. Und da ist es für mich und meine sehr begrenzte Zeit einfacher die Extension auf herkömmlichen Weise einzufügen als mehr oder weniger wieder bei 0 anzufangen. Wenn du so willst bin ich der einzige "Überlebende" des Headersteams. Und solch riesige umbauten lasse meine Zeit nicht zu. Vor allem, da der Header nicht mein einziges Projekt ist. ;-) Das es nicht ideal ist wie es ist, steht völlig außer Frage. Nur macht mir da die Zeit einen Strich durch die Rechnung.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 24, 2006 16:43 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Stubs:
Die Stubs sind da weil die Funktionszeiger bei .Net 1.1 nur über einen Trick in Delegates umgewandelt werden können und Delphi nur .Net 1.1 kann. Ab .Net 2.0 gibt es dafür direkt eine Funktion. Das heißt wenn Delphi irgendwann mal 2.0 kann, können die eh weg. Da aber niemand Delphi für .Net 1.1 nutzt(warum auch) können sie eigentlich auch jetzt schon raus.

Bei .Net 2.0 ist das Laden nicht langsam. Die Funktionsaufrufe sind nur dann im Debugger relativ langsam, wenn man die entsprechenden Sicherheitsüberprüfungen an hat.

Hilfsfunktionen:
Die Funktionen mit wirklicher zusätzlicher Funktionalität können meinetwegen raus, allerdings müssen die entsprechenden abgewandelten .Net Funktionen wie z.B. Array statt Zeiger enthalten bleiben. Ansonsten kann man damit nicht programmieren, denn es ist relativ umständlich einen Zeiger zu bekommen und z.B. bei glVertex3fv() ist ein array of Single das entsprechende Gegenstück zu einem PSingle und intern wird auch einfach direkt der Zeiger auf das Array übergeben.
Allerdings ist fraglich warum solche Sache wie CreateRenderingContext da drin sind. Das sollte am besten auch alles ausgelagert werden.

XML:
Man sollte das auf jeden Fall von XML her generieren lassen. Es ist ja auch angedacht, dass die Extension Spezifikationen in Zukunft mit einer XML Beschreibung kommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Nov 25, 2006 14:29 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Stubs: Na ja. .NET würde ja dennoch funktionieren. So ist es ja nicht. Allerdings würden die Methoden nicht automatisch geladen werden. Und da befürchte ich, dass viele das automatische Laden auch so verwenden. Das ist meine Zwickmühle. Aber ich denke wenn man das genau kommuniziert sollte es eigentlich machbar sein.

Funktionen: Es wäre dann sicherlich konsequent, wenn dann alle Hilfsfunktionen ausgelagerrt würden. Das stimmt auf jeden Fall. Aber neue Funktionen kommen nicht hinzu. Nicht jetzt.

XML: Für später falls man zu viel Zeit hat ist das sicher noch eine interessante Alternative. Wie meinste das eigentlich mit den Spezifikationen? Sollen die später als xml herrauskommen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Nov 25, 2006 15:47 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Das mit dem XML stand mal in einem von den Newslettern oder irgendwo anders auf opengl.org. Man könnte allerdings auch die Extensions direkt aus den Spezifikationen lesen. Die Abschnitte beginnen ja immer mit "New Tokens" und "New Procedures and Functions".

Bei Delphi3d.net gibt es so etwas schon.
Liste aller Extensions: http://www.delphi3d.net/download/metaglext.xml

Tool zum Generieren des XML aus den Spezifikationen:http://www.delphi3d.net/download/metaglext.zip


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 29, 2006 12:03 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7804
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Das mit dem gernerieren hat einen gewissen Charme. Vorallem, dass dadurch bei der Headerpflege etwas Zeit frei würde. Allerdings müsste da massiv Zeit investiert werden um das soweit einsatzfähig zu machen. Auch die Möglichkeit DGL-Header für andere Sprachen gernerieren zu können würde sich astrein in die entwicklung (weg von Delphi+OpenGL hin zu OpenGL allgemein) von DGL einpassen.

Ich kann allerdings sehr gut nachvollziehen, dass Lossy das nicht allein machen kann. Falls aber noch 1-2 Leute ihn unterstützen könnten, wäre diese Lösung vermutlich die beste.

Vorrübergehend (also für die nächste Headerversion) kann man ja so vorgehen wie Lars das beschrieben hat.
Also offiziell machen das .Net1.1 nicht mehr unterstützt wird, den .Net1.1 overhead rauswerfen und die unnötigen zusatzfunktionen auslagern.

Die vereinfachung/verkürzung des Headers käme dann auch der Headergenerierung zu gunsten, da ein einfacher Header leichter verstanden und erzeugt werden kann. (Denk ich doch mal... ;) )

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 29, 2006 12:54 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Nur um die Verwirrung mal komplett zu machen. Mir ging es primär nur um die Entfernung der Stubs, die nur für .Net erstellt wurden. Aber laut Lars benutzt .Net 1.1 für Delphi eh niemand. Von daher würde sich auch keiner darüber aufregen wenn man .Net ganz entfernen würde. Und dann müsste man die Zusatzfunktionen auch nicht mehr auslagern weil der Großteil dann nicht mehr existieren würden. Das waren dann nur noch die Methoden CreateRenderingContext, ActivateRenderingContext, DeactivateRenderingContext, DestroyRenderingContext. Und alleine die auszulagern würde sich nicht wirklich lohnen.

Ich denke ich werde .Net dann komplett entfernen und im Falle des großen Wiederstandes kann man die Änderungen für OpenGL 2.1 ja in den 2.0 Header einmergen und denn dann auch anbieten. So lange kann man dann evtl auch beide zur Verfügung stellen. Nur für den unwahrscheinlich Fall, dass tatsächlich einer .Net benutzen sollte.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 29, 2006 13:46 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Es wird ja auch mal ein Delphi für .Net 2.0 geben, dass benutzbar sein wird.
Mit .Net 2.0 kann man einfach über wglGetProcAdress laden und braucht auch keine Stubs mehr weil das schnell genug ist, aber man braucht weiterhin die Typenamen für die Funktionen. Daher sollten die drin bleiben.
Andererseits ist die Sprache bei .Net ja eh egal und man braucht keine Delphi Header sondern kann einen beliebigen anderen nehmen. Die brauchbaren OpenGL Anbindungen benötigen aber aus den gleichen Gründen aber alle auch .Net 2.0. Daher ist fraglich ob es sich überhaupt ab 2.0 noch lohnt für Delphi da speziell was zu machen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 29, 2006 14:18 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Ah. Okay. Die Typen hätte ich mit entfernt. Aber um da mal Butter bei die Fische zu tun.

Momentan
Code:
  1.   glBegin := TglBegin(glProcedure('glBegin'{$IFDEF CLR}, typeof(TglBegin){$ENDIF}));


.Net 2.0
Code:
  1.   glBegin := TglBegin(glProcedure('glBegin'));


Das sollte für .Net 2.0 ausreichen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 29, 2006 14:38 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Ne, die Funktion Marshal.DelegateFromFunctionPtr benötigt explizit den Type. Vielleicht könnte man das auch so machen:

Code:
  1. glProcedure(const name:string;var ptr:Pointer);
  2. glProcedure('glBegin',glBegin);


und bei .Net ignoriert man den Zeiger und nutzt stattdessen Reflektion um die Variable über den Namen zu setzen. Dann müßten die Variablen alle so heißen wie im String angegeben.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 29, 2006 15:05 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Öhm. Okay. Verstehe von dem .Net Zeugs zwar nichts. Aber ja ich denke das ließe sich durchaus machen.


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 30 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.780s | 19 Queries | GZIP : On ]