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

Aktuelle Zeit: So Jul 20, 2025 22:51

Foren-Übersicht » Programmierung » Einsteiger-Fragen
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: Performance-Verbesserung Heightmap
BeitragVerfasst: Do Jun 10, 2010 12:26 
Offline
DGL Member

Registriert: Fr Mai 14, 2010 08:34
Beiträge: 54
Moin moin!

Zur Darstellung von Messdaten habe ich eine kleine OpenGl Anwendung in Delphi geschrieben, die einen 2D-Single-Array als Oberfläche darstellen kann. Die Höhe wird in Falschfarben dargestellt. Das Programm ist soweit fertig, allerdings geht bei sehr großen Arrays (ab ca. 2 Millionen Werten) die Performance in die Knie.

Bis jetzt habe ich folgendes gemacht:

Zunächst wird eine Renderliste (DisplayList) berechnet (auf Wunsch mit Schatten)
Code:
procedure RenderList;
var
  c : TSingleArray;
begin
    glNewList(DisplayList,GL_COMPILE);
    ...
    glBegin(GL_QUADS);
    for y:=0..M-1 do begin
       for x:=0..N-1 do begin
          if Shadow then begin
             ...
             glNormal3fv(@c);
          end;
          ...
          glColor3fv(@c);
          glVertex3f(x-1,y,Matrix[x-1,y]);
          glVertex3f(x-1,y-1,Matrix[x-1,y-1]);
          glVertex3f(x,y-1,Matrix[x,y-1]);
          glVertex3f(x,y,Matrix[x,y]);
       end;
    end;
    glEnd;
    glEndList;
end;


Gerendert wird so:

Code:
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  gluPerspective(45.0, ClientWidth/ClientHeight, NearClipping, FarClipping);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity;

  glTranslatef(shiftx, shifty, z);
  glRotatef(alpha,0,0,1);
  glRotatef(beta,1,0,0);
  if Shadow then glLightfv(GL_LIGHT0, GL_POSITION, @light_position[0]);

  //mittig platzieren
  glTranslatef(-(xmax+xmin)/2,-(ymax+ymin)/2,-(zmax+zmin)/2);

  glCallList(DisplayList);

  SwapBuffers(DC);


Habt ihr vielleicht noch Vorschläge zur Performance Verbesserung?
Wichtig ist, dass die Oberfläche möglichst detailliert gerendert wird. Vorallem beim reinzoomen sollten die einzelnen Pixel erkennbar sein.


Bereits aktiviert ist:
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_FLAT);

Vielen Dank!


Zuletzt geändert von j0hnnie am Do Jun 10, 2010 13:52, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Jun 10, 2010 12:43 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
j0hnnie hat geschrieben:
glShadeModel(GL_FLAT);

Das ist theoretisch langsamer als GL_SMOOTH.
Denn um Flat-Shading hinzubekommen muß jedes vertex mehrere Normalen haben, statt nur einer - denn im pro triangle müßen alle vertices dafür die selbe normale haben.

Zumindest früher als ich das mal spaßeshalber ausprobiert hatte ging die performance mit GL_FLAT ein ganzes stück runter.

Aya~


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Jun 10, 2010 12:43 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Du hast da so wie es da steht auf jeden Fall einen Fehler. Und zwar benutzt du glBegin(GL_QUADS) in der Schleife, hast aber glEnd nur hinter der Schleife. Performancetechnisch besser ist es zu dem, wenn du glBegin und glEnd nur möglichst selten aufrufst. Also glBegin vor der Schleife und glEnd nach der Schleife. OpenGL nimmt dann immer vier aufeinanderfolgende Vertices als ein Quad.

Ich weiß nicht genau, wie der Performancegewinn zwischen Displayliste und VBO ist, aber generell könntest du dir letzteres mal Anschauen:
VBO und VBO ohne glInterleavedArrays

greetings

_________________
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  
BeitragVerfasst: Do Jun 10, 2010 14:07 
Offline
DGL Member

Registriert: Fr Mai 14, 2010 08:34
Beiträge: 54
Aya hat geschrieben:
j0hnnie hat geschrieben:
glShadeModel(GL_FLAT);

Das ist theoretisch langsamer als GL_SMOOTH.

Hab in dem Programm nen Button mit dem man zwischen GL_FLAT und GL_SMOOTH wechseln kann. Macht aber kaum nen unterschied. Wobei ich das Gefühl habe, dass GL_FLAT ein wenig schneller ist. Dazu muss man sagen, dass das oben nur nen Code-Ausschnitt ist und dass in meinem Programm eigentlich vor jedem der vier Quad-Vertexe jeweils glColor aufgerufen wird, wenn GL_SMOOTH aktiviert ist. Also hat jeder Quad eigentlich vier Farben. Mit GL_SMOOTH macht OpenGL automatisch einen Verlauf daraus.

Lord Horazont hat geschrieben:
Du hast da so wie es da steht auf jeden Fall einen Fehler. Und zwar benutzt du glBegin(GL_QUADS) in der Schleife, hast aber glEnd nur hinter der Schleife. Performancetechnisch besser ist es zu dem, wenn du glBegin und glEnd nur möglichst selten aufrufst. Also glBegin vor der Schleife und glEnd nach der Schleife. OpenGL nimmt dann immer vier aufeinanderfolgende Vertices als ein Quad.

Ich weiß nicht genau, wie der Performancegewinn zwischen Displayliste und VBO ist, aber generell könntest du dir letzteres mal Anschauen:
VBO und VBO ohne glInterleavedArrays

Danke für den Hinweis. Habs korrigiert. Hab oben nur ein paar Code-Schnipsel reinkopiert und dabei ist das wohl durcheinander gekommen.
VBO hab ich irgendwo auch schonmal gelesen. Ich werd mich mal schlau machen. Im Zusammenhang mit VBO habe ich auch schonmal gelesen, dass man der Grafikkarte nicht zuviele Vertexe auf einmal übergeben soll, weil deren Speicher begrenzt ist. Deshalb sollte man der Grafikkarte lieber mehrere VBOs hintereinander übergeben. Oder so ähnlich ... :oops:

Was ich mir noch gedacht hatte ist, dass während des Rotieren/Zoomen die Oberfläche nur in geringer Auflösung gerendert wird. Ich habe schonmal die Auflösung eines solchen Arrays mittels Mittelwertbildung halbiert/geviertelt/usw., aber das war schon recht aufwändig und rechenintensiv (allerdings nur einmalig). Vielleicht stellt OpenGL ein rendern in geringer Auflösung ja schon von Haus aus zu Verfügung oder so?! :roll:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Jun 10, 2010 14:23 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
j0hnnie hat geschrieben:
Danke für den Hinweis. Habs korrigiert. Hab oben nur ein paar Code-Schnipsel reinkopiert und dabei ist das wohl durcheinander gekommen.
VBO hab ich irgendwo auch schonmal gelesen. Ich werd mich mal schlau machen. Im Zusammenhang mit VBO habe ich auch schonmal gelesen, dass man der Grafikkarte nicht zuviele Vertexe auf einmal übergeben soll, weil deren Speicher begrenzt ist. Deshalb sollte man der Grafikkarte lieber mehrere VBOs hintereinander übergeben. Oder so ähnlich ... :oops:

Stimmt, ich habs mal kurz durchgerechnet, mit 2 Mio Vertices kannst du schon ordentlich für Probleme im Speicher sorgen … Vielleicht ist das auch der Grund, warum deine Displayliste so langsam ist, sie passt eventuell nicht komplett in den Grafikkartenspeicher (mit einer kurzen Überschlagsrechnung kam ich auf 224MB, wohl eher mehr).

j0hnnie hat geschrieben:
Was ich mir noch gedacht hatte ist, dass während des Rotieren/Zoomen die Oberfläche nur in geringer Auflösung gerendert wird. Ich habe schonmal die Auflösung eines solchen Arrays mittels Mittelwertbildung halbiert/geviertelt/usw., aber das war schon recht aufwändig und rechenintensiv (allerdings nur einmalig). Vielleicht stellt OpenGL ein rendern in geringer Auflösung ja schon von Haus aus zu Verfügung oder so?! :roll:

Ne, das musst du selber machen. Sowas nennt sich übrigens LOD, Level of Detail. Ist ziemlich gängig und wird dir deine Performance retten. Wenn du dann reingezoomt bist kannst du vielleicht auch nur einzelne Teile der Heightmap rendern. Dazu musst du die natürlich in mehr Displaylisten als eine Aufteilen. So z.B. immer 100x100 oder 10x10 Quads. Mit einem Frustum-Test prüfst du dann, ob der "Patch" im Sichtbaren bereich liegt und nur dann zeichnest du auch.
Siehe dazu: Frustum, Tutorial: Frustum Culling, LOD, Tutorial: Terrain1 (Heightmapping allgemein), Tutorial: Terrain3 (Optimierung).

greetings

_________________
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  
BeitragVerfasst: Do Jun 10, 2010 14:27 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Im Zusammenhang mit VBO habe ich auch schonmal gelesen, dass man der Grafikkarte nicht zuviele Vertexe auf einmal übergeben soll, weil deren Speicher begrenzt ist. Deshalb sollte man der Grafikkarte lieber mehrere VBOs hintereinander übergeben. Oder so ähnlich ... :oops:

Das hast du falsch verstanden. Ein VBO darf ruhig groß sein. ABER: Du solltest nach Möglichkeit nur das rendern was auch wirklich sichtbar ist. Sonst muss die Grafikkarte das nämlich durchkauen ohne das hinterher irgendwas davon sichtbar ist.
Die Idee ist das man seine Heightmap in Blöcke teilt, sagen wir 64x64 Quads, und für jeden Block vor dem rendern testet ob er überhaupt im Sichtbereich der Kamera liegt. Diesen Sichtbarkeitstest kann man noch optimieren, wenn man z.B. einen Quadtree benutzt.

Für den Fall das du soweit rauszoomst, dass die ganzen Messdaten sichtbar sind solltest du dir überlegen ob vielleicht LevelOfDetail einsetzen möchtest. Stichwort wäre hier GeoMipMapping.

Falls Shader eine Option sind kannst du eine Menge Speicher sparen, weil du redundante Daten on-the-fly berechnen kannst...was häufig schneller ist als sie aus dem Grafikspeicher oder gar Hauptspeicher zu holen. Siehe dazu meinen Heightmap-Shader in der Shadersammlung.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Jun 10, 2010 19:26 
Offline
DGL Member

Registriert: Fr Mai 14, 2010 08:34
Beiträge: 54
Vielen Dank! Da hab ich ja erstmal was zu lesen/probieren. :roll:

Ich dachte vorher, dass OpenGL von sich aus nur das rendert, was im Sichtfeld der Kamera liegt. Die Framerate steigt auch tatsächlich, wenn man weit reinzoomt, aber nur sehr gering.
Dann werde ich meine Matrix wohl zerstückeln müssen.
Was ist eigentlich der Unterschied, ob ich meine Matrix in 64x64 VBOs oder 64x64 DisplayLists zerlege? Und wie setzte ich diese Stücke nachher am besten zusammen? Über gltranslate oder rechne ich in den einzelnen Abschnitten direkt in den richtigen Koordinaten?

Das mit dem LOD werde ich mir mal genauer anschauen. Unter "GeoMipMapping" habe ich schon ein paar beeindruckende Demos gefunden.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Jun 10, 2010 20:00 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Ich dachte vorher, dass OpenGL von sich aus nur das rendert, was im Sichtfeld der Kamera liegt.

Das ist auch richtig. Aber OpenGL (bzw. die Grafikkarte) hat keine andere Wahl jedes einzelne Dreieck (*) erst zu transformieren und dann zu testen ob es vollständig sichtbar, teilweise sichtbar oder unsichtbar ist. Im Falle von 'teilweise sichtbar' muss das Dreieck dann zusätzlich noch zurecht geschnitten werden. Der Vorgang nennt sich Clipping.
Logischerweise ist es schneller eine BoundingBox um einen 64x64-Block zu legen und diese zu testen als jedes Dreieck einzeln, auch wenn die Grafikkarte sowas verdammt schnell macht, irgendwann kommt die halt auch nicht mehr mit. Die BoundingBoxen kann man dann wieder zu größeren BoundingBoxen zusammenfassen, diese zu noch größeren usw...

Zitat:
Was ist eigentlich der Unterschied, ob ich meine Matrix in 64x64 VBOs oder 64x64 DisplayLists zerlege?

Mit VBOs hast du größere Kontrolle darüber wie die Daten im Speicher abgelegt werden. Z.B. kannst du Indices verwenden, was eine Menge Speicher sparen könnte: Bei deiner Heightmap wieder jeder Vertex im Schnitt 4 mal verwendet, d.h. du hast 4 mal identische Daten im Speicher. Du legst dann halt einen zweiten Buffer an der nur Integer-Indices auf den eigentlichen VBO enthält. So brauchst du jeden Vertex nur einmal speichern, aber du brauchst natürlich den Index-Buffer zusätzlich. Stichworte: glDrawElements, GL_ELEMENT_ARRAY_BUFFER

Zitat:
Über gltranslate oder rechne ich in den einzelnen Abschnitten direkt in den richtigen Koordinaten?

Ich denke glTranslate ist der übliche Weg. Letztlich ist das aber egal.

Zitat:
Die Höhe wird in Falschfarben dargestellt.

Um dir die Shader vielleicht etwas schmackhafter zu machen: Da sich deine Farben so wie ich das verstanden habe leicht aus der Höhe berechnen lassen kannst du hier eine Menge Speicher sparen. Letztlich brauchst du pro Vertex nur einen float, nämlich die Höhe speichern. Alles andere kannst du im Vertex- und Fragmentshader berechnen. Im Augenblick brauchst du 28 Byte pro Vertex (Position, Normale, Farbe) und speicherst jeden 4 mal. Bei 2 Mio. Werten komme ich da auf 213 Mb. Wenn du aber nur die Höhe einmal speichern musst kommst du auf gerade 7.6 Mb, zuzüglich ein paar kleinen Hilfsbuffern. Das kannst du noch um die Hälfte reduzieren wenn dir z.B. ein 16bit Integer für die Höhe ausreicht. Der Nachteil ist eigentlich nur das du eine Grafikkarte mit mindestens Shader Model 3.0 benötigst, damit du die Höhenwerte im Shader aus einer Textur lesen kannst. Der Shader dazu findet sich in der Shadersammlung. (Edit: Ups, wir sind hier im Einsteiger-Forum....vergiss die Shader erstmal ;) )


(*) Quads gibt's ja eigentlich gar nicht...

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Jun 14, 2010 14:47 
Offline
DGL Member

Registriert: Fr Mai 14, 2010 08:34
Beiträge: 54
So ich habe jetzt den Quellcode aus Tutorial_Terrain3 genommen und ihn für meine Verhältnisse angepasst (oder eher versucht anzupassen).

Nun habe ich leider ein paar Probleme mit dem Frustum Culling. Ich habe die TFrustumClass aus Tutorial_Frustum_Culling in das Projekt eingebaut und rufe nun immer in der Render-Procedur des Heightmap-Tutorials (ApplicationEvents1Idle) Frustum.Calculate auf. Und zwar nach den Transformationen:
Code:
...
  if Kamera then
  begin
    glRotatef(xRotation, 1, 0, 0);
    glRotatef(yRotation, 0, 1, 0);
    glTranslatef(-KameraPosition[0]/(QuadTreeLength - 1) * MapSizeWidth, -KameraPosition[1], -KameraPosition[2]/(QuadTreeLength - 1) * MapSizeHeight)
  end
  else begin
    Spin := Spin + 0.1;
    if Spin >= 360 then Spin := 0;
    glTranslatef(0, 0, -MapSizeWidth-100);
    glRotatef(45, 1.0, 0.0, 0.0);
    glRotatef(-Spin, 0.0, 1.0, 0.0);
    glTranslatef(-MapSizeWidth/2, 0, -MapSizeHeight/2);
  end;

  Frustum.Calculate;  //<-- eingefügt
...


Außerdem habe ich in der Unter-Procedur ShowQuadTreeCell folgendes
Code:
if (Size > 1) then
    begin
      HSize := Size div 2;
      ShowQuadTreeCell(X+ HSize, Z + HSize, HSize);
      ShowQuadTreeCell(X+ HSize, Z - HSize, HSize);
      ShowQuadTreeCell(X- HSize, Z + HSize, HSize);
      ShowQuadTreeCell(X- HSize, Z - HSize, HSize)
    end

durch
Code:
if (Size > 1) and (Frustum.IsBoxWithin(X,GetHeightMapHeight(X,Z) div 2,Z,HSize,GetHeightMapHeight(X,Z) div 2,HSize)) then
    begin
      HSize := Size div 2;
      ShowQuadTreeCell(X+ HSize, Z + HSize, HSize);
      ShowQuadTreeCell(X+ HSize, Z - HSize, HSize);
      ShowQuadTreeCell(X- HSize, Z + HSize, HSize);
      ShowQuadTreeCell(X- HSize, Z - HSize, HSize)
    end

ersetzt.

Irgendwie funktioniert das aber nicht so richtig. Wobei ich jetzt angenommen habe, dass die zu zeichnende Zelle einem Würfel von 2*HSize,GetHeightMapHeight(X,Z),2*HSize entspricht.
Was mache ich falsch?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Jun 14, 2010 16:00 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
Code:
Frustum.IsBoxWithin(X,GetHeightMapHeight(X,Z) div 2,Z,HSize,GetHeightMapHeight(X,Z) div 2,HSize)

Ist kein Würfel. Wenn Y immer gleich bleibt.

_________________
Es werde Licht.
glEnable(GL_LIGHTING);
Und es ward Licht.


Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"

on error goto next


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Jun 14, 2010 16:11 
Offline
DGL Member

Registriert: Fr Mai 14, 2010 08:34
Beiträge: 54
damadmax hat geschrieben:
Code:
Frustum.IsBoxWithin(X,GetHeightMapHeight(X,Z) div 2,Z,HSize,GetHeightMapHeight(X,Z) div 2,HSize)

Ist kein Würfel. Wenn Y immer gleich bleibt.


Die Funktion lautet function TFrustum.IsBoxWithin(const pX, pY, pZ, pB, pH, pT : Single) : Boolean. Es werden also Breite, Höhe, Tiefe als Parameter übergeben.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Jun 15, 2010 08:57 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Beschreib mal genau was nicht geht. Sieht man gar nichts, oder wird falsch gecullt? Ich hab das Tutorial ja geschrieben und in einer alten Octree-Demo mach ichs genauso und es klappt tadellos. Sicher dass du als Koordinaten auch die Mitte deiner Octree-Nodes übergibst?

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Jun 15, 2010 11:17 
Offline
DGL Member

Registriert: Fr Mai 14, 2010 08:34
Beiträge: 54
Um das Culling zu testen, habe ich quasi nichts am Quelltext geändert. Wenn ich die einzelnen Punkte der Triangles direkt vorm zeichnen überprüfe, dann klappt das Culling. Also prinzipiell scheint das Culling zu funktionieren. Allerdings will ich, dass erst garnicht die Childs gezeichnet werden, wenn das Parent nicht im Sichtbereich liegt. Das habe ich wie oben versucht zu implementieren. Aber er schneidet zu viele Polynome ab. Ein bissel was sehen tut man schon ;)

Die Funktion ShowQuadTreeCell scheint ja um X, Z herum jeweils um +/-Size zu zeichnen. Weiß nicht so recht ob ich das Culling an der richtigen Stelle mit den richtigen Parametern mache. Hab eigentlich das Tutorial nur an den Header 1.5 abgepasst und die TFrustumClass eingebunden und wie oben benutzt.

Danke schonmal für die Mühe :)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Jun 15, 2010 19:07 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Kann es sein, dass du nicht den kompletten Quader prüfst sondern nur seinen Mittelpunkt? Dann kann es dir passieren, dass der Mittelpunkt der Node außerhalb des Frustums ist, obwohl eigentlich ein Teil zu sehen ist. Dadurch fehlen dann ein paar Polygone.

greetings

_________________
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  
BeitragVerfasst: Mi Jun 16, 2010 10:08 
Offline
DGL Member

Registriert: Fr Mai 14, 2010 08:34
Beiträge: 54
Ich hatte nich beachtet, dass GetHeightVertex(X,Z); auch X und Z transformiert. Deshalb hatte die gezeichneten Nodes einen anderen Mittelpunkt.
Jetzt habe ich es folgendermaßen gelöst:

Code:
    FrustumVect : TVector;
    Draw : Boolean;
    ...

    FrustumVect:=GetHeightVertex(X,Z);
    Draw:=Frustum.IsBoxWithin(FrustumVect[0],FrustumVect[1]/2,FrustumVect[2],Size,FrustumVect[1]/2,Size);
    if (Size > 1) and (Draw) then
    begin
      HSize := Size div 2;
      ShowQuadTreeCell(X+ HSize, Z + HSize, HSize);
      ShowQuadTreeCell(X+ HSize, Z - HSize, HSize);
      ShowQuadTreeCell(X- HSize, Z + HSize, HSize);
      ShowQuadTreeCell(X- HSize, Z - HSize, HSize)
    end


Wobei ich das gefühl habe, dass er dennoch manchmal zuviel oder zuwenig abschneidet.

Außerdem treten sehr vereinzelt Cracks auf. Auf der Tutorial-Seite wird zwar erwähnt, dass der Algorithmus noch nicht perfekt ist, aber so ganz verstehe ich nicht, wie man den Algorithmus jetzt umschreiben muss.


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 » Programmierung » Einsteiger-Fragen


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.018s | 17 Queries | GZIP : On ]