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

Aktuelle Zeit: So Jul 20, 2025 00:33

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



Ein neues Thema erstellen Auf das Thema antworten  [ 4 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Partikel Performance verbessern
BeitragVerfasst: Fr Okt 26, 2007 13:22 
Offline
DGL Member

Registriert: Mi Mai 30, 2007 15:15
Beiträge: 20
Ich habe ein kleines PartikelSystem programmiert wobei ich aber Probleme mit der Performance habe.
Liegt es jetzt an der Anzahl der Dreicke? Dann müsste doch die Performance besser werden wenn ich die Partikel Grösse erhöhe und die Anzahl verringere. Das trifft aber nicht zu. 10000 QUADS sollten doch kein Problem sein oder?

Code:
  1. type
  2.  
  3.   TPartikel = class
  4.   protected
  5.     Color: TGLColor;
  6.     LifeTime: int64;
  7.     StartTime: int64;
  8.     x,y,z: double;
  9.     speedx, speedy, speedz: double;
  10.     alpha: double;
  11.     size: double;
  12.   public
  13.     procedure setSize(aSize: double);
  14.     procedure setPositions(ax, ay, az: double);
  15.     procedure paint(const Right,Up,View: TVektor);
  16.     function move(vergangendeZeit: int64): boolean; //result=Kollision mit Rand
  17.     constructor CreateParam(ax, ay, az, axspeed, ayspeed, azspeed: double; aLifetime: int64; aColor: TGLColor);
  18.     destructor Destroy; override;
  19.   end;
  20.  
  21.   TParticelControl = class
  22.   protected
  23.     x,y,z: double;
  24.     Partikel: TObjectlist;
  25.     Partikelspeed: integer;
  26.     starttime: int64;
  27.     Effektdauer: integer;
  28.     nureinmal: boolean;
  29.     gestartet: boolean;
  30.     fTexture: TglBitmap2D;
  31.   public
  32.     procedure paint; virtual;
  33.     function move(vergangendeZeit: int64): boolean; virtual; //result=Effekt fertig
  34.     constructor Create(); virtual;
  35.     procedure start(ax,ay,az: double); virtual;
  36.     procedure stop; virtual;
  37.     destructor Destroy; override;
  38.   end;
  39.  
  40. implementation
  41.  
  42. constructor TParticelControl.Create;
  43. begin
  44.   Effektdauer := MAXINT;
  45.   Partikel:= TObjectlist.Create(true);
  46.   nureinmal:=true;
  47.  
  48.   fTexture := TglBitmap2D.Create(); // Instanz erstellen und Datei laden
  49.   fTexture.LoadFromFile(ExtractFilePath(ParamStr(0))+'Texturen\point.bmp');
  50.   //fTexture.AddAlphaFromColorKey(0,0,0,50) ;
  51.   //fTexture.AddAlphaFromFile(ExtractFilePath(ParamStr(0))+'point.bmp');
  52.   fTexture.GenTexture; // geladene Textur an OpenGL übergeben
  53.  
  54.  
  55.   gestartet :=false;
  56. end;
  57.  
  58. destructor TParticelControl.Destroy;
  59. begin
  60.   Partikel.Clear;
  61.   Partikel.Free;
  62.   fTexture.Free;
  63.   inherited;
  64. end;
  65.  
  66. procedure TParticelControl.paint;
  67. var
  68.   i: integer;
  69.   Matrix: array [0.. 15] of single;
  70.   Right,Up,View: TVektor;
  71. begin
  72.   if gestartet then
  73.   begin
  74.     glGetFloatv( GL_MODELVIEW_MATRIX, @Matrix );
  75.     Right.x := Matrix[0]/sqrt(sqr(Matrix[0])+sqr(Matrix[4])+sqr(Matrix[8]));
  76.     Right.y := Matrix[4]/sqrt(sqr(Matrix[0])+sqr(Matrix[4])+sqr(Matrix[8]));
  77.     Right.z := Matrix[8]/sqrt(sqr(Matrix[0])+sqr(Matrix[4])+sqr(Matrix[8]));
  78.     Up.x := Matrix[1]/sqrt(sqr(Matrix[1])+sqr(Matrix[5])+sqr(Matrix[9]));
  79.     Up.y := Matrix[5]/sqrt(sqr(Matrix[1])+sqr(Matrix[5])+sqr(Matrix[9]));
  80.     Up.z  := Matrix[9]/sqrt(sqr(Matrix[1])+sqr(Matrix[5])+sqr(Matrix[9]));
  81.     View.x := Matrix[2];
  82.     View.y := Matrix[6];
  83.     View.z := Matrix[10];
  84.  
  85.     glDepthMask(false);
  86.     glEnable(GL_BLEND);
  87.     glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  88.     glEnable(GL_TEXTURE_2D);
  89.     //glEnable(GL_ALPHA_TEST);
  90.     //glAlphaFunc(GL_GREATER, 0.1);
  91.     fTexture.Bind;
  92.  
  93.     glBegin(GL_QUADS);
  94.     for i := 0 to Partikel.Count - 1 do
  95.     begin
  96.       TPartikel(Partikel.items[i]).paint(Right,Up,View);
  97.     end;
  98.     glEnd();
  99.  
  100.     fTexture.Unbind();
  101.     glDisable(GL_TEXTURE_2D);
  102.     glDepthMask(true);
  103.     glDisable(GL_BLEND);
  104.   end;
  105.   //glDisable(GL_ALPHA_TEST);
  106.  
  107. end;
  108.  
  109. function TParticelControl.move(vergangendeZeit: int64): boolean;
  110. var
  111.   i: integer;
  112. begin
  113.   result:=false;
  114.  
  115.   if gestartet then
  116.   begin
  117.     for i := Partikel.Count - 1 downto 0 do
  118.     begin
  119.       if TPartikel(Partikel.items[i]).move(vergangendeZeit) then
  120.         Partikel.Delete(i);
  121.     end;
  122.  
  123.     if ((timegettime-starttime)>Effektdauer) then
  124.     begin
  125.       result := true;
  126.       gestartet:=false;
  127.       //Partikel.clear;
  128.     end;
  129.   end;
  130.  
  131. end;
  132.  
  133. procedure TParticelControl.start(ax,ay,az: double);
  134. begin
  135.   x:=ax;
  136.   y:=ay;
  137.   z:=az;
  138.  
  139.   Partikel.Clear;
  140.  
  141.   starttime:=timegettime;
  142.   gestartet:=true;
  143. end;
  144.  
  145. procedure TParticelControl.stop;
  146. begin
  147.   gestartet:=false;
  148. end;
  149.  
  150. { TPartikel }
  151.  
  152. constructor TPartikel.CreateParam(ax, ay, az, axspeed, ayspeed, azspeed: double; aLifetime: int64; aColor: TGLColor);
  153. begin
  154.   x:=ax;
  155.   y:=ay;
  156.   z:=az;
  157.   color := aColor;
  158.  
  159.   speedx := axspeed;
  160.   speedy := ayspeed;
  161.   speedz := azspeed;
  162.   StartTime := timegettime;
  163.   LifeTime := aLifetime;
  164.  
  165.   size := 4.0
  166. end;
  167.  
  168. destructor TPartikel.Destroy;
  169. begin
  170.  
  171.   inherited;
  172. end;
  173.  
  174. function TPartikel.move(vergangendeZeit: int64): boolean;
  175. begin
  176.   result := false;
  177.   x := x+(speedx*vergangendeZeit/(1000));
  178.   y := y+(speedy*vergangendeZeit/(1000));
  179.   z := z+(speedz*vergangendeZeit/(1000));
  180.   if (timegettime - StartTime)>LifeTime then result := true;
  181. end;
  182.  
  183. procedure TPartikel.paint(const Right,Up,View: TVektor);
  184. begin
  185.  
  186.   alpha := 1-(timegettime - StartTime)/LifeTime;
  187.   if alpha>1.0 then alpha := 1.0;
  188.  
  189.  
  190.   glColor4f(color[0], color[1],color[2], alpha);
  191.   glNormal3f(View.x,View.y,View.z);
  192.  
  193.  
  194.   glTexCoord2f(0,0);
  195.   glVertex3f(x+Up.x*size,y+Up.y*size,z+Up.z*size);
  196.   glTexCoord2f(0,1);
  197.   glVertex3f(x+0,y+0,z+0);
  198.   glTexCoord2f(1,1);
  199.   glVertex3f(x+Right.x*size,y+Right.y*size,z+Right.z*size);
  200.   glTexCoord2f(1,0);
  201.   glVertex3f(x+(Right.x+Up.x)*size,y+(Right.y+Up.y)*size,z+(Right.z+Up.z)*size);
  202.  
  203. end;
  204.  
  205. procedure TPartikel.setSize(aSize: double);
  206. begin
  207.   size := asize;
  208. end;
  209.  


Code:
  1.  
  2. type
  3.   TExplossionsEffekt = class(TParticelControl)
  4.   protected
  5.     spawnStartTime: int64;
  6.     Color: TGLcolor;
  7.     radius: double;
  8.   public
  9.     procedure setradius(aradius: double);
  10.     function move(vergangendeZeit: int64): boolean; override; //result=Effekt fertig
  11.     procedure start(ax,ay,az: double; aColor: TGLcolor; aradius: double; aEffektdauer: integer); reintroduce;
  12.   end;
  13.  
  14. implementation
  15.  
  16. { TExplossionsEffekt }
  17.  
  18. function TExplossionsEffekt.move(vergangendeZeit: int64): boolean;
  19. var
  20.   i,u: integer;
  21.   PartikelCount: integer;
  22.   PartikelLifeTime: integer;
  23.   xspeed,yspeed,zspeed: double;
  24.   theta1,theta2: double;
  25.   colorTemp: TGlColor;
  26.   tempPartikellifetime: integer;
  27. begin
  28.  
  29.   PartikelCount := 15;
  30.   Partikelspeed:=25;
  31.   PartikelLifeTime := round(Partikelspeed*radius);
  32.  
  33.   if gestartet then
  34.   begin
  35.     if not ((timegettime-starttime)>(Effektdauer-tempPartikellifetime)) and  ((timegettime-spawnStartTime)>150) then
  36.     begin
  37.       for u:=0 to PartikelCount do
  38.       begin
  39.         theta1 := degtorad(random(360));
  40.  
  41.         for i:=0 to PartikelCount do
  42.         begin
  43.           theta2 := degtorad(random(360));
  44.  
  45.           xspeed := Partikelspeed*((90+random(20))/100)*cos(theta1) * cos(theta2);
  46.           yspeed := Partikelspeed*((90+random(20))/100)*sin(theta1);
  47.           zspeed := Partikelspeed*((90+random(20))/100)*cos(theta1) * sin(theta2);
  48.  
  49.           colorTemp[0] := color[0]*((80+random(20))/100);
  50.           colorTemp[1] := color[1]*((80+random(20))/100);
  51.           colorTemp[2] := color[2]*((80+random(20))/100);
  52.         Partikel.Add(TPartikel.CreateParam(x-2+random(4),y-2+random(4),z-2+random(4),xspeed,yspeed,zspeed,PartikelLifeTime,colorTemp));
  53.           TPartikel(Partikel.last).setSize(12);
  54.         end;
  55.       end;
  56.  
  57.       spawnStartTime := timegettime;
  58.  
  59.     end;
  60.   end;
  61.  
  62.  
  63.   result := inherited move(vergangendeZeit);
  64. end;
  65.  
  66. procedure TExplossionsEffekt.start(ax, ay, az: double; aColor: TGLcolor; aradius: double; aEffektdauer: integer);
  67. begin
  68.   inherited start(ax, ay, az);
  69.   spawnStartTime := timegettime;
  70.   color := acolor;
  71.   radius := aradius;
  72.   Effektdauer := aEffektdauer;
  73. end;
  74.  


Das wichtigste dürfte in TExplossionsEffekt.move und in TParticelControl.paint sein.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Okt 26, 2007 13:40 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
Ich bin mir nicht sicher, aber kann es nicht sein, dass hier die CPU ein wenig zu leiden hat ?
So wie ich das sehe ist bei dir jedes Partikel eine eigene Klasse mit vielen untertypen. ich habe versucht, meine partikel so minimalistisch wie möglich zu gestalten, also records mit wenigen informationen und so viel es geht in den emitter auslagern.
des weiteren solltest du schauen, ob du immer alle 10000 partikel zeichnen musst, oder ob du zB Frustrum culling einsetzen kannst.


mfg


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Okt 26, 2007 14:20 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
In jedem Falle solltest du die Zeiten messen die die einzelnen Funktionen benötigen. Dazu solltest du dir mal QueryPerformanceFrequency und QueryPerformanceCounter etwas näher anschauen. Denn dann kannst du erst richtig abschätzen was wie lange die einzelnen Teile benötigen.

Was ich persönlich ziemlich häftig finde ist das Paint des einzelnen Partikels. Dort musst du für jede kleine Koordinate extra eine Berechnung anwerfen. Ich würde versuchen das so einfach wie möglich zu gestalten. So viel wie möglich vorberechnen etc. Denn solche Berechnungen finden auf der FPU statt und eine zu starke vermischung zwischen FPU und CPU bringt Delphi etwas aus dem Tritt. Also so etwas sind stellen die immer gut Zeit benötigen.

Evtl könnte es auch einiges bringen zuvor die Punkte in ein VBO zu schreiben und dann dieses zu rendern. Evtl geht es schneller, da du derzeit bei jedem Quad warten musst bist die Grafikkarte fertig ist und so würdest du es in einen Speicher packen und anschließend nur sagen zeichnen. Wärend die Grafikkarte dann die Punkte zeichnet könntest du schon wieder andere Sachen machen, da das ganze ja asynchron abläuft.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Okt 26, 2007 16:05 
Offline
DGL Member

Registriert: Di Okt 23, 2007 10:20
Beiträge: 84
unwichtig


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


Wer ist online?

Mitglieder in diesem Forum: Bing [Bot] und 6 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.016s | 16 Queries | GZIP : On ]