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

Aktuelle Zeit: Di Jul 15, 2025 17:23

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



Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Pointer Problem bezüglich Octrees
BeitragVerfasst: Mo Mai 31, 2004 21:15 
Offline
DGL Member

Registriert: Fr Jan 10, 2003 20:18
Beiträge: 88
Einen schönen guten Tag wünsche ich euch allen,
ist das Leben nicht herrlich...
draußen scheint die Sonne...
die Vögel singen aber....
WENN DIESER SCHEIß OCTREE MAL FUNTIONIEREN WÜRDE DANN...,ICH SCHMEISS DIE SCHEIßE GLEICH AUS DEM FENSTER... aber wir wollen mal alle ruhig bleiben und nun zu meinem Problem...

Wie schon wenige von euch wissen, bin ich dabei einen Octree zu programmieren,
jetzt habe ich einen Fehler festgestellt, bei dem ich mir ziehmlich sicher bin, dass dort ein falscher Pointer übergeben wird. Denn die Prozedure die einen Octree in 8 Würfelt teilt muss sich ja selbst wieder aufrufen um die erstellten Würfel nochmals zu teilen usw. usw. bis eine bestimme Bedingung erfüllt ist.
Als Parameter wird ein Pointer des zu teilenden Würfels übergeben.
Dort werden die 8 kleinen Würfel berechnet und ein der Parameter als Pointer an jeden klein Würfel gegeben, damit ich weiß welcher der Vater-Würfel ist.
Es funktioniert auch alles wunderbar allerdings wenn ich meine Würfel nacher überprüfe, ob der Vater-Würfel sichbar ist bekomme ich dort ein Nein obwohl dieser sichtbar ist.
Und es ist überhaupt alles durcheinander, manche Würfel sehe ich, andere nicht, stell ich den Vater-Test ab ;-) sind alle Würfel normal zu sehen, also die Berechnungen usw. sind korrekt.
Hier mal der Quelltext der Prozedur:

Ich rufe die Prozedure so auf:
DivideNode(@nodes[0]);

Code:
  1.  
  2. Procedure TOctree.DivideNode(n:PNode);
  3. var
  4.   childNodes:array[0..7] of TNode;  //Die 8 kleiner Würfel
  5.   i:Integer;
  6. begin
  7. ...
  8. //Positions- und Größen-Berechnung für die kleiner Würfel
  9. ...
  10.   for i:=0 to 7 do childNodes[i].owner:=n;      //da muss irgenbdwas nicht stimmen
  11.  
  12.   for i:=0 to 7 do
  13.   begin
  14.     if VerticesinNode(@childNodes[i])>0 then    //Überprüft, ob Würfel leer ist
  15.     begin
  16.       Inc(numn);
  17.       setLength(nodes,numn);            //Ist er nicht leer wird er in die array aufgenommen
  18.       nodes[numn-1]:=childNodes[i];
  19.       if nodes[numn-1].numn>1000 then       //Ist er noch zu voll, wird er nochmals geteilt
  20.         DivideNode(@nodes[numn-1]) ;        //HIER WIRD DIE PROZEDURE NOCHMALS AUFGERUFEN
  21.     end;
  22.   end;
  23. end;
  24.  



Ich habe den verdacht, dass irgendwelche, der Variabeln oder Parameter beim wiederaufrufen der Funktion verloren gehen.
Kann das sein, wenn ja wie kann ich das umgehen, ich wette ich gehe da irgendwie falsch mit dem Pointer um, denn der Parameter n ist ja ein
Pointer (PNode) und dieser zeigt erst auf den richtigen Würfel.

Danke schonmal[/pascal]


Zuletzt geändert von SoulChild am Di Jun 01, 2004 10:56, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mai 31, 2004 21:23 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Entweder gleich Objekte benutzen oder den Speicher für die Würfel mit GetMem oder New belegen. Wenn man die Würfel als lokale Variable deklariert
Code:
  1. childNodes:array[0..7] of TNode

sind sie nur so lange gültig bis die procedure beendet ist.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 01, 2004 11:00 
Offline
DGL Member

Registriert: Fr Jan 10, 2003 20:18
Beiträge: 88
Danke dir. Hat zwar funktioniert aber macht irgendwie keinen Sinn.

Wenn ich folgendes der Prozedure hinzufüge läuft es:

Code:
  1.  
  2. ...
  3. var
  4.   nt:PNode;
  5.   ..
  6. begin
  7.   New(nt);
  8.   nt:=n;
  9. ...
  10.  


Dann funktioniert es aber ich greife gar nicht auf die variabel nt zu, denn unten steht: Auf Variabel nt wird nie zugegriffen, also ich hab immer noch alles von n übernommen.
Warum funktioniert es so?
Kannst du mir das mir das mit den Objekten näher erklären? Bitte?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 01, 2004 13:12 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jul 12, 2002 07:15
Beiträge: 916
Wohnort: Dietzhölztal / Hessen
Programmiersprache: C/C++, Obj-C
Mir scheint das dir einiges an Grundlagen zur Speicherverwaltung und Pointer in Delphi fehlt. Wäre evtl. ratsam im Netz bzw. der Delphi-Hilfe mal nach entsprechenden Infos zu suchen.

Wenn dur ein Array innerhalb einer Funktion definierst, ist der Speicherbereich nach dem Verlassen der Funktion nicht mehr verfügbar. Wenn du aber mit New einen Speicherbereich anlegst, wird dieser von Delphi NICHT am Ende der Funktion freigegeben da du die Adresse in einer Struktur ablegst die zurückgeliefert wird. Aus diesem Grund funktioniert das so. Eines solltest Du jedoch beachten: dynamisch angelegter Speicher (mit Hilfe von New) sollte auch von dir beim Zerstören des Octrees wieder freigegeben werden.

P.S.: Mach doch einfach Klassen aus den Nodes. Mag evtl. etwas overkilled sein ist von der Verwaltung und vom Handling aber einfacher weil das meiste von Delphi gehändelt wird. Außerdem kannst du beim erstellen der Klasse im Constructur diverse Initialisierungen vornehmen.

_________________
Und was würdest Du tun, wenn Du wüsstest, dass morgen Dein letzter Tag auf dieser Erde ist?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 01, 2004 13:20 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Dez 13, 2002 12:18
Beiträge: 1063
Das mit dem "Nicht-Zugreifen" ist ein "Fehler" den Delphi manchmal macht, wenn Variablen Parameter in Routinen übergeben werden (Etwa bei New und GetMem). Abhilfe schafft, Pointer vorher (etwa am Anfang der Routine) mit NIL zu initialisieren, was ohnehin eine gute Idee ist.

Irgendwie solltest du aber deine Zeigerarithmetik ein wenig eindeutiger halten: mit deinem Kommando reservierst du Speicher und überschreibst den zurückgelieferten Zeiger sofort mit dem "ParentNode", resultierend in einem Speicherloch, das du nie wieder flicken kannst :roll:
Irgendwie habe ich den Verdacht, dass du wie wild mit Zeigern und dynamischen Arrays (die im Prinzip auch nichts anderes sind) herumspielst, ohne wirklich zu wissen, was im Hintergrund passiert (ist nicht böse gemeint).

Ein OctreeNode könnte z.B. so aussehen:

Code:
  1. Type
  2.   PNode = ^TNode;
  3.   TNode = record
  4.      Min, Max: TVec;  // bounding box
  5.      ...                      // Zusatzinformationen (Dreiecke, Objekte, was auch immer
  6.      Children: integer; // anzahl der Kinder, mit 0 vorinitialisieren!
  7.      Child: array[0..7] of PNode; // kann eh nie mehr als 8 Kinder haben - Länge fest zu vergeben macht Sinn, da schneller und kaum mehr Speicherverbrauch
  8.   end;
  9.  


Wenn du in der Routine SubDivide dem Node neue Kinder verpasst, machst du das dann z.B. mit folgenden Kommandos (temp ist vom Typ PNode)

Code:
  1.   New(n.Child[n.Children]); // Children ist mit 0 vorinitialisiert, ist die Anzahl der Kinder und gleichzeitig der Index eines eventuellen nächsten Kindes
  2.   Temp := n.Child[n.Children];  // oder auch GetMem(n.Child[n.Children], sizeof(TNode)); wenn dir das lieber ist - du solltest dich allerdings für GetMem/FreeMem oder New/Dispose entscheiden - die beiden beim selben Zeiger zu mischen ist keine gute Idee
  3.   inc(n.Children);
  4.   // jetzt kannst du in Temp die Informationen des neuen "Kindnodes" reinschreiben, da sie dann automatisch an der richtigen Stelle landen.
  5.  

_________________
Viel Spaß beim Programmieren,
Mars
http://www.basegraph.com/


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: Majestic-12 [Bot] und 15 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.007s | 15 Queries | GZIP : On ]