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

Aktuelle Zeit: Fr Jul 18, 2025 15:52

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



Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Frustum Culling
BeitragVerfasst: Mo Jun 12, 2006 18:50 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jun 12, 2006 16:56
Beiträge: 5
Hallo an die ganze Community!

Ich bin noch nich lange mit OGL am Werkeln und hab Probleme mit dem Frustum-Culling Tutorial von wikigl.

Ich habe den Quelltext umgeschrieben (bin C++ Anhänger) und in ein Programm eingebaut. In diesem habe ich für jedes
geladene Modell eine Kugel (xm,ym,zm und den Radius). Diese Kugel prüfe ich dann mit der Frustum Fkt. aus dem Tutorial.
Mein Problem besteht jetzt darin, dass es anscheind nicht richtig funktioniert. Ich kann mich bewegen und auf einmal ist ein Modell
weg, rotiere ich ein kleines Stück um eine Achse ist es wieder da, ein Stück weiter und es ist wieder weg.
Hat jemand eine Ahnung, wieso?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jun 12, 2006 19:36 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2068
Programmiersprache: C++
Ohne Quellcode und oder Bildern leider nicht :(


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jun 12, 2006 20:55 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jun 12, 2006 16:56
Beiträge: 5
so, hier der modifizierte Code fürs Frustum:

Code:
  1. void c_frustum::calculate( void )
  2. {
  3.     GLfloat project_matrix[16];
  4.     glGetFloatv(GL_PROJECTION_MATRIX, project_matrix);
  5.    
  6.     GLfloat modell_matrix[16];
  7.     glGetFloatv(GL_MODELVIEW_MATRIX, modell_matrix);
  8.    
  9.     GLfloat clip[16];
  10.     clip[ 0] = modell_matrix[ 0]*project_matrix[ 0] + modell_matrix[ 1]*project_matrix[ 4] + modell_matrix[ 2]*project_matrix[ 8] + modell_matrix[ 3]*project_matrix[12];
  11.     clip[ 1] = modell_matrix[ 0]*project_matrix[ 1] + modell_matrix[ 1]*project_matrix[ 5] + modell_matrix[ 2]*project_matrix[ 9] + modell_matrix[ 3]*project_matrix[13];
  12.     clip[ 2] = modell_matrix[ 0]*project_matrix[ 2] + modell_matrix[ 1]*project_matrix[ 6] + modell_matrix[ 2]*project_matrix[10] + modell_matrix[ 3]*project_matrix[14];
  13.     clip[ 3] = modell_matrix[ 0]*project_matrix[ 3] + modell_matrix[ 1]*project_matrix[ 7] + modell_matrix[ 2]*project_matrix[11] + modell_matrix[ 3]*project_matrix[15];
  14.     clip[ 4] = modell_matrix[ 4]*project_matrix[ 0] + modell_matrix[ 5]*project_matrix[ 4] + modell_matrix[ 6]*project_matrix[ 8] + modell_matrix[ 7]*project_matrix[12];
  15.     clip[ 5] = modell_matrix[ 4]*project_matrix[ 1] + modell_matrix[ 5]*project_matrix[ 5] + modell_matrix[ 6]*project_matrix[ 9] + modell_matrix[ 7]*project_matrix[13];
  16.     clip[ 6] = modell_matrix[ 4]*project_matrix[ 2] + modell_matrix[ 5]*project_matrix[ 6] + modell_matrix[ 6]*project_matrix[10] + modell_matrix[ 7]*project_matrix[14];
  17.     clip[ 7] = modell_matrix[ 4]*project_matrix[ 3] + modell_matrix[ 5]*project_matrix[ 7] + modell_matrix[ 6]*project_matrix[11] + modell_matrix[ 7]*project_matrix[15];
  18.     clip[ 8] = modell_matrix[ 8]*project_matrix[ 0] + modell_matrix[ 9]*project_matrix[ 4] + modell_matrix[10]*project_matrix[ 8] + modell_matrix[11]*project_matrix[12];
  19.     clip[ 9] = modell_matrix[ 8]*project_matrix[ 1] + modell_matrix[ 9]*project_matrix[ 5] + modell_matrix[10]*project_matrix[ 9] + modell_matrix[11]*project_matrix[13];
  20.     clip[10] = modell_matrix[ 8]*project_matrix[ 2] + modell_matrix[ 9]*project_matrix[ 6] + modell_matrix[10]*project_matrix[10] + modell_matrix[11]*project_matrix[14];
  21.     clip[11] = modell_matrix[ 8]*project_matrix[ 3] + modell_matrix[ 9]*project_matrix[ 7] + modell_matrix[10]*project_matrix[11] + modell_matrix[11]*project_matrix[15];
  22.     clip[12] = modell_matrix[12]*project_matrix[ 0] + modell_matrix[13]*project_matrix[ 4] + modell_matrix[14]*project_matrix[ 8] + modell_matrix[15]*project_matrix[12];
  23.     clip[13] = modell_matrix[12]*project_matrix[ 1] + modell_matrix[13]*project_matrix[ 5] + modell_matrix[14]*project_matrix[ 9] + modell_matrix[15]*project_matrix[13];
  24.     clip[14] = modell_matrix[12]*project_matrix[ 2] + modell_matrix[13]*project_matrix[ 6] + modell_matrix[14]*project_matrix[10] + modell_matrix[15]*project_matrix[14];
  25.     clip[15] = modell_matrix[12]*project_matrix[ 3] + modell_matrix[13]*project_matrix[ 7] + modell_matrix[14]*project_matrix[11] + modell_matrix[15]*project_matrix[15];
  26.    
  27.     //right
  28.     frustum[0][0] = clip[ 3] - clip[ 0];
  29.     frustum[0][1] = clip[ 7] - clip[ 4];
  30.     frustum[0][2] = clip[11] - clip[ 8];
  31.     frustum[0][3] = clip[15] - clip[12];
  32.     normalize_plane(0);
  33.    
  34.     //left
  35.     frustum[1][0] = clip[ 3] + clip[ 0];
  36.     frustum[1][1] = clip[ 7] + clip[ 4];
  37.     frustum[1][2] = clip[11] + clip[ 8];
  38.     frustum[1][3] = clip[15] + clip[12];
  39.     normalize_plane(1);
  40.    
  41.     //bottom
  42.     frustum[2][0] = clip[ 3] + clip[ 1];
  43.     frustum[2][1] = clip[ 7] + clip[ 5];
  44.     frustum[2][2] = clip[11] + clip[ 9];
  45.     frustum[2][3] = clip[15] + clip[13];
  46.     normalize_plane(2);
  47.    
  48.     //top
  49.     frustum[3][0] = clip[ 3] - clip[ 1];
  50.     frustum[3][1] = clip[ 7] - clip[ 5];
  51.     frustum[3][2] = clip[11] - clip[ 9];
  52.     frustum[3][3] = clip[15] - clip[13];
  53.     normalize_plane(3);
  54.    
  55.     //back
  56.     frustum[4][0] = clip[ 3] - clip[ 2];
  57.     frustum[4][1] = clip[ 7] - clip[ 6];
  58.     frustum[4][2] = clip[11] - clip[10];
  59.     frustum[4][3] = clip[15] - clip[14];
  60.     normalize_plane(4);
  61.    
  62.     //front
  63.     frustum[5][0] = clip[ 3] + clip[ 2];
  64.     frustum[5][1] = clip[ 7] + clip[ 6];
  65.     frustum[5][2] = clip[11] + clip[10];
  66.     frustum[5][3] = clip[15] + clip[14];
  67.     normalize_plane(5);
  68. }
  69.  
  70. void c_frustum::normalize_plane( int plane )
  71. {
  72.     float magnitude = sqrt(sqrt(frustum[plane][0])+sqrt(frustum[plane][1])+sqrt(frustum[plane][2]));
  73.     frustum[plane][0]=frustum[plane][0]/magnitude;
  74.     frustum[plane][1]=frustum[plane][1]/magnitude;
  75.     frustum[plane][2]=frustum[plane][2]/magnitude;
  76.     frustum[plane][3]=frustum[plane][3]/magnitude;
  77. }
  78.  
  79.  
  80. bool c_frustum::point_inside( float px, float py, float pz )
  81. {
  82.     for( int i = 0;i<6;i++)
  83.     {
  84.         if( frustum[i][0]*px + frustum[i][1]*py + frustum[i][2]*pz + frustum[i][3] <= 0)
  85.         {
  86.             return false;
  87.         }
  88.     }  
  89.     return true;
  90. }
  91.  
  92.  
  93. bool c_frustum::box_inside( float px, float py, float pz, float b, float h, float d )
  94. {
  95.     for ( int i=0;i<6;i++)
  96.     {
  97.         if (frustum[i][0]*(px-b) + frustum[i][1]*(py-h) + frustum[i][2]*(pz-d) + frustum[i][3]>0)
  98.             continue;
  99.         if (frustum[i][0]*(px+b) + frustum[i][1]*(py-h) + frustum[i][2]*(pz-d) + frustum[i][3]>0)
  100.             continue;
  101.         if (frustum[i][0]*(px-b) + frustum[i][1]*(py+h) + frustum[i][2]*(pz-d) + frustum[i][3]>0)
  102.             continue;
  103.         if (frustum[i][0]*(px+b) + frustum[i][1]*(py+h) + frustum[i][2]*(pz-d) + frustum[i][3]>0)
  104.             continue;
  105.         if (frustum[i][0]*(px-b) + frustum[i][1]*(py-h) + frustum[i][2]*(pz+d) + frustum[i][3]>0)
  106.             continue;
  107.         if (frustum[i][0]*(px+b) + frustum[i][1]*(py-h) + frustum[i][2]*(pz+d) + frustum[i][3]>0)
  108.             continue;
  109.         if (frustum[i][0]*(px-b) + frustum[i][1]*(py+h) + frustum[i][2]*(pz+d) + frustum[i][3]>0)
  110.             continue;
  111.         if (frustum[i][0]*(px+b) + frustum[i][1]*(py+h) + frustum[i][2]*(pz+d) + frustum[i][3]>0)
  112.             continue;
  113.        
  114.         return false;
  115.     }
  116.    
  117.     return true;
  118.    
  119. }
  120.  
  121.  
  122. bool c_frustum::sphere_inside( float px, float py, float pz, float r )
  123. {
  124.     for( int i = 0;i<6;i++)
  125.     {
  126.         if( frustum[i][0]*px + frustum[i][1]*py + frustum[i][2]*pz + frustum[i][3] <= -r)
  127.         {
  128.             return false;
  129.         }
  130.     }
  131.     return true;
  132. }



Mit Bild is gerade nen bisschen ungünstig :oops:
Ich kanns aber beschreiben:
Man sieht normal ein Terrain: Hügel, ein paar kleine Figuren und im Hintergrund eine Skybox.
Wenn man nun die Kamera ein Stück bewegt, isr die Skybox weg, wie abgeschnitten, nur noch schwarz, als wenn man über die Alpen guckt, und der Himmel
fehlt :-\

edit: Codeformatierung durch Flash


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jun 12, 2006 21:44 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2068
Programmiersprache: C++
Bitte für den Code die [cpp][/cpp]-Tags benutzen.

Ansonsten hat deine Skybox doch nichts mit Frustum Culling zu tun.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 13, 2006 08:10 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
Das Problem ist deine BoxInside Funktion.
Ich kenn mich zwar nicht mit c aus, aber du lieferst false, wenn keiner der Punkte im Frustum ist. Dies ist nur die halbe Wahrheit. :)
Das mit dem 'mindestens ein punkt liegt im Frustum' ist nur einer der Fälle, die zu prüfen sind.

Schreib die Funktion mal so um:
Jeder Punklt wird gegen die Ebenen des Frustums geprüft und für jede Ebene gibst Du ein Flag zurück, ob er innerhalb oder ausserhalb dieser Ebene liegt (Abstand <=0 oder >0). Die Ergebnisse schreibst Du in ein Bitfeld, und zwar nach dem Schema:
ist er oben auserhalb, setzt Du das erste Bit, rechts das zweite, unten das dritte, links das vierte, vorne das fünfte und hinten das sechste.

Jetzt ist die Box im Frustum, wenn:
a) mindestens ein Ergebnis=0; // hier ist ein Punkt innerhalb
b) alle Ergebnise &-Verknüpft =0; // hier liegen zwar alle Punkte auserhalb, aber mindestens zwei an verschiedenen Seiten und mindestens eine Kante verläuft teilweise innerhalb
[/pascal]

_________________
Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 13, 2006 08:21 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jun 12, 2006 16:56
Beiträge: 5
Danke euch erstmal. Das mit der BoxInside Fkt. is mir noch gar nich aufgefallen, aber die benutzte ich ja auch nicht :!: . Es wird jedes Modell durch eine Kugel repräsentiert und dann mit der SphereInside Fkt. überprüft. Die Skybox besteht dann aus 6 Quads, also auch 6 "Kugeln".
Und hier tritt dieses merkwürdige Verhalten auf :(


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 13, 2006 09:54 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
Ich täusch mich sicher, aber Du benutzt für die Ebenendarstellung die Achsenschnittpunkte (normalisiert).
Bei der sphere_inside- Funktion nimmst Du diese Koordinaten dann als Vektor und berechnest den Abstand des Ursprungs der sphäre zu diesem Vektor, also Abstand Vektor-Vektor. Falls das überhaupt funktionieren kann, musst Du vorher den Mittelpunkt und Radius der Kugel normalisieren, also mit projektions-und Modelmatrix verrechnen.
Ich würde die Parameterdarstellung für die Ebenen (A+rB+sC, 3x3 Matrix: 1.Spalte Ankerpunkt, 2.Spalte 1. Richtungsvektor, 3.Spalte 2.Richtungsvektor) wählen (und zwar nicht normalisiert) und dann den Abstand Punkt-Ebene (siehe Formelsammlung) berechnen.

_________________
Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jun 19, 2006 19:43 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jun 12, 2006 16:56
Beiträge: 5
Danke dir Sidorion, deine Einwände mit dem Normalisieren sind berechtigt.
Normalisieren is ja nix anderes als
Code:
  1. float length = sqrt(px*px + py*py + pz*pz);

und dann jeden wert durch length oder täusch ich mich wieder?
Naja, auf jeden Fall ist es immer noch nich korrekt.
Deinem letztem Teil kann ich gar nicht folgen. Kann das jemand für Anfänger erklären, oder gibts hier nen ausgedehntes Tut zur Matrizenrechnung in OGL? Wär super;-)[/code]


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jun 19, 2006 20:15 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jun 12, 2006 16:56
Beiträge: 5
Hi ihr nochmal, mir is gerade noch was aufgefallen.
Das beschriebene Wegbleiben des Bildes passiert immer dann, wenn der Rotationswinkel um die y-Achse 0<angle_y<90 ist, könnte das jemandem helfen?


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


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.011s | 15 Queries | GZIP : On ]