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

Aktuelle Zeit: Fr Jul 18, 2025 11:54

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



Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Sa Dez 03, 2005 16:54 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 06, 2005 18:34
Beiträge: 362
Wohnort: Hamburg
Hi ...

Ich habe gerade versucht den BoxInFrustum-Test in inline Assembler umzusetzen ...
Der Code wird auch ausgeführt, aber leider gibt er nie false zurück, d.h. es wird immer alles gerendert...
Ich hoffe mir kann dabei einer helfen ...

Hier der Code:
Code:
  1.  
  2. bool CFrustum::BoxInFrustum(float x,float y,float z,float width,float height,float depth)
  3. {
  4.     static float **p = m_Frustum;
  5.  
  6.     float minX = (x - width),  maxX = (x + width);
  7.     float minY = (y - height), maxY = (y + height);
  8.     float minZ = (z - depth),  maxZ = (z + depth);
  9.  
  10.     bool within = true;
  11.  
  12.     _asm
  13.     {
  14.         mov eax,-1
  15.         mov ecx,p
  16.         sub ecx,4
  17. _loop:
  18.         add eax,1
  19.         cmp eax,6
  20.         jge _end
  21.  
  22.         add ecx,4
  23.  
  24.         mov ebx,dword ptr [ecx]    // ebx = &m_Frustum[eax]
  25.  
  26.         // eine Ecke der Box prüfen
  27.         fld dword ptr [ebx+0]    // m_Frustum[eax][0] laden
  28.         fmul minX                     // mal minX
  29.         fld dword ptr [ebx+4]    // m_Frustum[eax][1] laden
  30.         fmul minY                     // mal minY
  31.         fadd                             // beides addieren
  32.         fld dword ptr [ebx+8]    // m_Frustum[eax][2] laden
  33.         fmul minZ                     // mal minZ
  34.         fadd                             // addieren
  35.         fadd dword ptr [ebx+12]  // m_Frustum[eax][3] addieren
  36.         fldz                                 // 0.0 auf den stack laden
  37.         fcompp                           // die obersten beiden werte auf dem stack vergleichen und löschen
  38.         jg _loop                         //  wenn wert > 0 weiter in der schleife
  39.  
  40.         // hier folgen die anderen 7 Ecken, bis auf die X/Y/Z-Werte das gleiche, keiner der Blöcke wird überhaupt ausgeführt, der 1. beendet bereits die funktion
  41.  
  42.         mov within,0    // box ist nicht im frustum
  43. _end:
  44.     }
  45.  
  46.     return within;
  47. }
  48.  


Hoffe hier kennt sich jemand damit aus ...

Gruß
Shai


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Dez 03, 2005 17:11 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Nov 13, 2004 11:00
Beiträge: 229
Wohnort: Steinhude
Bei dem code sind son paar sachen die nicht stimmen.

Zunächst mal, was dein fehler sein dürfte: fcom setzt nicth die flags in der CPU sondern nur in der fpu.
versuchs mal mit

Code:
  1.  
  2. push ax
  3. fcompp
  4. fstsw ax
  5. fwait
  6. pop ax
  7. sahf
  8.  

oder schöner, setzt einen pentium pro oder höher voraus:
Code:
  1. fcomip

statt dem fcompp

weiterhin wird sowie ich dass sehe in jedemfall within auf 0 gesetzt, da dieser mov befehl nicht überspringen wird. hier müsste noch ein conditional jump oder ein conditional mov

Weiterhin füllst du den fpu stack durchgängig mit werten auf ohne diese wieder vom stack zu nehmen. Da iirc eine fehler erzeugt wird, wenn der stack voll ist und versucht wird weitere werte hineinzuladen, ist dies auch nicht grad vorteilhaft.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Dez 03, 2005 17:42 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Schau dir mal lieber den Code den der Compiler erzeugt. Da dürfte nicht viel rauszuholen sein. Eine andere Optimierung ist nur den Punkt der Box zu testen, der die größte Entfernungzur Ebene hat.

Code:
  1. x=plane[0]<0 ? min.x:max.x;
  2. y=plane[1]<0 ? min.y:max.y;
  3. z=plane[2]<0 ? min.z:max.z;
  4.  
  5. Punkt (x,y,z) testen


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Dez 03, 2005 18:15 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 06, 2005 18:34
Beiträge: 362
Wohnort: Hamburg
Hi ...

erstmal danke für die Antworten ...

@Lars
Ich mach das nicht unbedingt um da performance rauszuholen, sondern viel mehr ums zu lernen ...

@Grizzly
werd mir das mal anschauen und verbessern ...

Gruß
Shai


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Dez 03, 2005 22:12 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 17, 2005 13:19
Beiträge: 98
Wohnort: Jahnsdorf
@Grizzly: SAHF muss vor PUSH AX kommen, da ansonstensonsten der falsche Wert in die Flags rutscht.

Ansonsten sollte man für Vergleiche mit 0 die FTST-Anweisung der FPU benutzen. Diese führt die gleiche Operation wie FLDZ \ FCOMIP bereits in einer Anweisung aus.

Ein Beispiel zur Verwendung findest Du z.B. in der Unit OMathVector.pas in Funktion Vector3DNormalize für Projekt Omorphia.

HTH.

_________________
Administrator of Project Omorphia
Bild


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: 0 Mitglieder und 5 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.008s | 16 Queries | GZIP : On ]