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

Aktuelle Zeit: Mo Jul 07, 2025 22:02

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



Ein neues Thema erstellen Auf das Thema antworten  [ 23 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: 3DS Loader
BeitragVerfasst: Mi Apr 09, 2008 14:50 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
ich habe versucht einen eigenen 3DS loader zu schreiben....habe aber festgestellt das die procedure zu einem zu frühen Zeitpunkt verlassen wird, kann mir aber nicht erklären warum

hier die entsprechende Zeile :
Code:
  1.  
  2. TRI_INDICES :
  3. .
  4. .
  5. .  
  6.   SetLength(Result.Meshs[MeshCount - 1].Normals, Count * 3);  
  7.   SetLength(Result.Meshs[MeshCount - 1].Indices, Count * 3);
  8.  


wenn ich die beiden arrays durch lokale arrays ersetze läuft die procedure bis zum ende durch

der restliche Code :

// Edit Lossy: Code entfernt


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 09, 2008 15:02 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Bitte solche riesen Codestücke nicht in die Beiträge einfügen. Dadurch leidet nur die Übersicht. Da es sich um eine ganze Unit handelt lieber die Unit als zip packen und anhängen. Du kannst deinen Beitrag auch nachträglich noch bearbeiten und die Unit anhängen. Danke.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 09, 2008 16:01 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
Das ist jetzt sehr ungünstig ... ich hab (dummerweise) den code einer Unit eingefügt und zu diesem noch aus anderen Units code hinzugefügt um nicht alle verwendeten Units hochzuladen .... somit hatte ich allen meiner meinung nach relevanten Code zusammen im vohrigen Beitrag und kann jetzt den Code wieder neu zusammensuchen... :cry:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 09, 2008 16:04 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
..


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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 09, 2008 17:09 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
The download does not seem to work for me. So i cannot test it but:

Do you properly initialize: Result.Meshs[MeshCount - 1] ?
Also try Result := Localvar;
Or rewrite it to avoid the use of Result. E.g. make it a loaderclass.

The 3ds format is not easiest fileformat on the planet. My 3ds loader is largely complete, but still has room for improvement (http://www.noeska.com/dogl/gl3ds.aspx).

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 09, 2008 17:16 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
I also tryed this but doesn't work... the error is just at an other position :(
I checked the with the debugger if there is a reason, but MeshCount has a correct value....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 09, 2008 18:00 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Okay. Ich hätte nicht erwartet, dass das deine einzige Kopie ist. Aber um mich zu verteidigen. Hätte ich es nicht entfernt hätte es sicher jemand anders gemacht. Ich war nur schneller.

Nichts desto trotz habe ich den Code noch und habe gerade mal verglichen. Der einzige Unterschied besteht darin, dass die letzte große Schleife (Zeile 528) auskommentiert ist. Solltest du ihn benötigen kann ich ihn dir auch noch mal zukommen lassen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Apr 09, 2008 18:08 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
schon gut ,dass das der einzige unterschied ist leigt darin das ich alles neu rausgesuch und dann gemerkt :idea: haben das der letzte Teil auskopmmentiert werden sollte da dieser weder fertig noch 1mal durchgelaufen ist....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 10, 2008 09:56 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Result ist vergleichbar wie eine lokale Variable. Dessen Speicher ist nicht initialisiert. Das sieht man sehr schön, wenn man in TModelData ein zusätzliches Feld wie "Test2: array[0..99] of Integer;" einbringt. Dort stehen nur willenlose Zahlen drinne. Aber anscheinend macht er bei dynamischen Arrays ein Spezialhandling.

Wenn du ein dynamisches Array mit SetLength erweiterst wird der Speicher aber auf 0 initialisiert. Von daher dürfte die Initialisierungsthematik eher nicht zum tragen kommen, da dein Hauptrecord nur aus 2 dynamischen Arrays besteht.

Aber ich könnte mir fast vorstellen, dass es da mit den Records und den dynamischen Arrays zu Problemen kommen kann. Denn du arbeitest eigentlich nur mit dynamischen Arrays und Records. Das sollte eigentlich keine Probleme machen aber ich meine schön öfter mal erlebt zu haben, dass eine übermäßige Benutzung/Verschachtelung davon zu Problemen führt. Denn intern muss beim Erweitern Speicher kopiert werden und er muss sich merken auf welche Dinge wie und wo zugegriffen wird. Und da könnte es sein, dass Delphi durcheinander kommen kann. Ich meine mich zu mindest an so etwas zu erinnern. Ich selbst verwende solche Konstrukte eher nicht (zu mindest nicht so komplex) weswegen ich jetzt keinen direkten Fall habe wo so etwas passiert ist.

Ich würde aber auch eher das vorschlagen was noeska schon erwähnt hatte. Also eine Struktur auf Klassenbasis mit Listen von Meshs die auch wieder Klassen wären. Das würde außerdem auch dafür sorgen, dass intern nicht so viel Speicher hin und her kopiert werden muss.

Im Zweifel würde ich dir in jedem Fall empfehlen die Bereichsprüfung, die Überlaufprüfung und die I/O Prüfung zu aktivieren. Evtl kann es auch sein, dass du zufällig mal über die Grenzen eines Arrays hinwegschreibst was durch die Bereichsprüfung eigentlich überprüft werden sollte. Das ergäbe dann Exceptions und du wüsstest, dass irgendwas falsch ist. Dann eigentlich auch wo es Falsch läuft.

Ich kann es aber nicht Testen und 3DS ist auch nicht mein Spezialgebiet. Im Code hatte ich aber zu mindest keine groben/auffälligen Auffälligkeiten entdeckt. Wobei mir da gerade was auffällt, was durchaus hässlich enden kann.

Code:
  1.         TRI_VERTEXL :
  2.         Begin
  3.           GetMem(Result.Meshs[MeshCount - 1].Vertices, Count * SizeOf(TVector3f));
  4.           AStream.Read(Result.Meshs[MeshCount - 1].Vertices, Count * SizeOf(TVector3f));
  5.         End;

Und zwar verlangt Stream.Read/Write als ersten Parameter grundsätzlich IMMER einen Datenbuffer. Denn diese Methoden bekommen durch das das const/var der Parameter immer nur den Pointer auf den Speicher übergeben. Bei Integer ist das okay. Bei Pointern (Strings und dyn arrays sind auch pointer) musst du aber explizit die erste Stelle des Speichers angeben. Denn sonst bekommt die Methode nur den Pointer deiner Pointervariable übergeben. Also im Falles des obrigen Beispieles bekommt Read nicht den mit GetMem erstellten Speicher sondern die Variable Vertices übergeben. Da Vertices normal massiv Daten enthalten denke ich wird er dir einiges deiner Strukturen überschreiben. Deswegen musst du an diesen Stellen IMMER expliziet dereferenzieren. Bei Dyn Array musst du auch immer die erste Arraystelle angeben [0]. Bei Strings das erste Zeichen [1]. Denn sonst würde er dir wieder anderen Speicher überschreiben.

Bei den TexCoords genau das Gleiche. Der Rest sollte aber gehen.

Außerdem sind die Farben als 4f deklariert aber du ließt nur 3f ein. Da solltest du sicher stellen, dass die der Alphawert auch initalisiert wird, denn ansonsten steht der durch die Initialisierung auf 0.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 10, 2008 15:00 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
Zitat:
Da Vertices normal massiv Daten enthalten denke ich wird er dir einiges deiner Strukturen überschreiben

Diese Problem ist bisher noch nicht aufgetreten...
das ganze hatte auch bis auf angesprochenes Problem funktioniert ... heist ich konnte alle Vertices als Punkte darstellen soweit ich das beuteilen kann hat auch keiner gefehlt(ich habe das Model welches ich zum testen benutze selber gemacht)
Frage wenn ich mit getmem Speicher resaviere zeigt der Pointer nicht automatisch auf den Anfang des entsprechenden Speichers.. und wenn ich dann bei AStream.Read die anzahl Bytes angebe wird dann nicht in den folgenden Speicher geschrieben :?: :?: :?:

Zitat:
Außerdem sind die Farben als 4f deklariert aber du ließt nur 3f ein.

Das ist kein Problem, da in der ich in der assign Methode meiner Klassen entsprechend die Daten aus der Datei verwende(Alphawert zuweisen usw.)

Ich hatte mir überlagt das ganze mit den Records zu machen, da ich für den fall das ich noch ein weiteres Dateiformat unterstützen will, nicht noch einmal meine Mesh bzw Material Klasse umschreiben müsste....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 10, 2008 15:51 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Ich weiß nicht wie du auf den Pointer zugreifst. Ich weiß auch nicht ob Delphi und FPC da evtl unterschiede machen, wenn du FPC benutzen solltest? Ich weiß auch nicht ob dieser Chunk immer existiert. Aber in Delphi ist es so, dass man an Read/Write einen Speicherbereich übergeben muss. Und ein Pointer besteht genau genommen aus zwei Speicherbereichen. Und zwar ein mal dem eigentlichem Datenbereich und ein mal der Variable in der der Pointer gespeichert ist. Folgendes Beispiel.

Code:
  1. TMyRec = record
  2.   A: array of integer;
  3.   B: integer;
  4.   C: Integer;
  5. end;
  6.  
  7. var
  8.   My: TMyRec;
  9. begin
  10.   SetLength(My.A, 3);
  11.  
  12.   // Das sorgt dafür, dass A, B und C befüllt werden, da der
  13.   // Speicherbereich in den Read die Daten packen soll die
  14.   //  Variable des Pointers für das dynamische Array ist.
  15.   Stream.Read(My.A, 3*SizeOf(Integer));
  16.  
  17.   // wärend aber durch die Angabe der ersten Stelle explizit der
  18.   // Datenbereich benutzt wird
  19.   Stream.Read(My.A[0], 3*SizeOf(Integer));
  20. end;

Bei Strings oder Pointer mit GetMem ist das Prinzip genau das Gleiche. Die Variable die man benutzt ist grundsätzlich immer ein Pointer. Nur Delphi verschleiert das um die Handhabung zu vereinfachen. Bei der ersten Methode kann es passieren, dass er auch über das eigentliche Record hinwegschreibt und sogar andere Strukturen überschreibt. Und beim nächsten Zugriff auf die anderen Strukturen kracht es. Was evtl auch erklären könnte warum so eine "lächerliche" stelle wie ein SetLength durchknallt. Wenn du dir ausversehen die Daten zerschossen hast.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 10, 2008 16:42 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
ware schön :cry: aber wenn ich diesen chunk einfach ignoriere erhalte ich nicht mehr die Faces meines Meshs kann diesen aber als Punkte wie oben gesagt darstellen und das klappt auch problemlos...auserdem dürfte es dann keinen fehler an dieser stelle geben das es ja egal ist was ein dyn array enthält wenn man die länge ändern will...

wie würde mann dann untypisierte pointer aus einem Stream lesen bzw in einen schreiben(hoffe es ist verständlich was ich damit meine)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 10, 2008 16:50 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Dazu sollte man zuerst immer die länge der Daten in den Stream schreiben und danach dann den Inhalt des Pointers. Beim Auslesen liest man zuerst die größe aus und kann so den Speicher für den Pointer reservieren:
Code:
  1.  
  2. var
  3.   BlockSize: Integer;
  4.   Data: Pointer;
  5. begin
  6.   GetMem(Data, BlockSize);
  7.   try
  8.     // Füll Data mit irgendeinem kram
  9.     Stream.Write(BlockSize, SizeOf(Integer)); // Die größe des Pointers schreiben
  10.     Stream.Write(Data^, BlockSize); // Den Inhalt des Speichers schreiben
  11.   finally
  12.     FreeMem(Data);
  13.   end;
  14. end;
  15.  


Fürs auslesen dann eben mit Read und so.

Gruß Lord Horazont

_________________
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:
BeitragVerfasst: Do Apr 10, 2008 17:56 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
also müsste ich bei meinem code
Code:
  1. AStream.Read(Result.Meshs[MeshCount - 1].Vertices, Count * SizeOf(TVector3f));

so verändern??
Code:
  1. AStream.Read(Result.Meshs[MeshCount - 1].Vertices^, Count * SizeOf(TVector3f));


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 10, 2008 18:14 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Wenn Vertices ein Pointer ist, ja.

Gruß Lord Horazont

_________________
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  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 23 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 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.012s | 15 Queries | GZIP : On ]