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

Aktuelle Zeit: So Jul 06, 2025 23:31

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



Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Fr Mai 29, 2009 08:59 
Offline
DGL Member

Registriert: Mo Mai 25, 2009 21:29
Beiträge: 30
Hi,

mein Projekt läuft mit 30 FPS SEHR langsam, zumal es ja noch nicht viel machen muss.
Ich wollte daher herausfinden woran es liegt. Da ich gelesen habe das glbindTexture() langsam ist, habe ich es einfach mal ausgeklammert.
(Natürlich hatte dann alles die selbe Textur - war halt n experiment)
Ich sparte mir in dem Fall 89 bindtexture.
Danach kam ich auf 60FPS.
Was mich allerdings sehr stutzig machte, war, als ich nachmas, wo ich wie viel Zeit einsparte:
Zum aufbau meines OnIdle:
1) Die Zeitmessung und Berechnung, wie viel ich in den Hauptberechnung vorangehen muss.
2) Die Hauptberechnungen (Bewegung, usw)
3) Kamera (besser: was ich alles Zeichnen muss)
4) Das Zeichnen
5) Done := false;

Hierzu die Durchschnitts-Werte mit glbindtexture()
Zeitberechnungen: 5,86666741164031E-6
Hauptberechnungen: 0,000349555599943568
Kamera: 3,42222265679018E-6
Zeichnen: 7,35428664816338E-5
Neuer Aufruf von Idle: 0,0331958391359796 //Zeit direkt vor done:=false bis zum beginn des neuen onidle-Aufrufs

Ohne glBindTexture:
Zeitberechnungen: 5,7968261329303E-6
Hauptberechnungen: 0,000367015919621069
Kamera: 3,42222265679018E-6
Zeichnen:0,000257015905652813
Neuer Aufruf von Idle: 0,0157169416783418

Das Zeichnen ist also schneller geworden, aber vor allem gab es eine wahnsinnige Zeiteinsparung bis zum nächsten OnIdle-Aufruf oO.
Wenn OnIdle sofort gewesen wäre, würde ich in ersterem Fall auf 2.7k in letzterem auf 1k FPS kommen.
Wohaer kommt a) Der Zeitgewinn im OnIdle-Aufruf, wenn ich das bindtexture weglasse?
Das sollte meiner Meinung doch unabhängig sein.
b) Wieso braucht das überhaupt so lange?
Ich habe es mal in einer leeren Anwendung getestet, dort betrug es nur um die 8E-6 Sekunden.
und natürlich c) Was kann ich dagegen machen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 29, 2009 09:51 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 29, 2003 00:11
Beiträge: 436
Erstmal möglichst nach Texturen sortiert zeichnen, so dass du dir das Binding oft sparst. Alle Objekte in einem Rutsch zeichnen, die TexturA benutzen, dann alle, die TexturB benutzen. So musst du hier nur 2x eine Textur binden.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 29, 2009 10:21 
Offline
DGL Member

Registriert: Mo Mai 25, 2009 21:29
Beiträge: 30
Das weis ich, aber dennoch wird es zu vielen Texturen kommen.
Meine Frage war eher, wieso das OnIdle Event so beeinflusst wird, was meiner Meinung nach nicht möglich sein sollte.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 29, 2009 10:30 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Ich habe deine Angaben mal einheitlich in Millisekunden umgerechnet. Bei diesen Exponenten kann man die doch gar nicht vergleichen.
Also nach deinen Zeitangaben geht das rendern mit glBindTexture schneller und zwar um den Faktor 3. Ich vermute mal entweder bei deiner Zeitmessung ist der Wurm drin oder du hast dich irgendwo vertippt.
Sollten deine Zahlen stimmen: Die meiste Zeit geht außerhalb deines Programms verloren! Es hilft nichts dein Programm zu optimieren, da läuft irgendeine andere Anwendung die viel Leistung zieht.

Zitat:
Hierzu die Durchschnitts-Werte mit glbindtexture()
Zeitberechnungen: 0,005866667ms
Hauptberechnungen: 0,3495556ms
Kamera: 0,003422223ms
Zeichnen: 0,073542866ms
Neuer Aufruf von Idle: 33,195839136ms //Zeit direkt vor done:=false bis zum beginn des neuen onidle-Aufrufs

Ohne glBindTexture:
Zeitberechnungen: 0,005796826ms
Hauptberechnungen: 0,36701592ms
Kamera: 0,003422223ms
Zeichnen:0,257015906ms
Neuer Aufruf von Idle: 15,716941678ms

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 29, 2009 10:44 
Offline
DGL Member

Registriert: Mo Mai 25, 2009 21:29
Beiträge: 30
Hmm, also vertippt habe ich mich nicht:
Ich poste grad mal mein OnIdle:
Code:
  1.  
  2. procedure TFrmPlay.IdleHandler(Sender: TObject; var Done: Boolean);
  3. var AktuelleZeit: Int64;
  4. begin
  5. If FrmErstellen.FormShowState = ShowFrmPlay then
  6.     begin
  7.     QueryPerformanceCounter(percount1);
  8.     LOG.Add('Neuer Aufruf von Idle: '+ floattostr((percount1-percount2)/frequency));
  9.     AktuelleZeit := GetTickCount;
  10.     AktuellerFrame := (AktuelleZeit-GameStartTime) div (1000 div Const_FPS);
  11.     inc(FPS);
  12.     If ((aktuelleZeit - LastFPS) > 1000) then
  13.         begin
  14.         LastFPS := aktuellezeit;
  15.         LOG.Add('FPS: ' + inttostr(FPS));
  16.         FPS := 0;
  17.         end;
  18.     QueryPerformanceCounter(percount2);
  19.     LOG.Add('Zeitberechnungen: '+ floattostr((percount2-percount1)/frequency));
  20.     While AktuellerFrame > VerarbeiteterFrame do
  21.         begin
  22.         inc(VerarbeiteterFrame);
  23.         TimedAllActions;
  24.         If Spielerliste.Spieler[0] = Localplayer then
  25.             TimedHostActions
  26.         else
  27.             TimedClientActions;
  28.         end;
  29.     QueryPerformanceCounter(percount1);
  30.     LOG.Add('Hauptberechnungen: '+ floattostr((percount1-percount2)/frequency));
  31.     //ZEICHNEN
  32.     GetCameraPosition;
  33.     QueryPerformanceCounter(percount2);
  34.     LOG.Add('Kamera: '+ floattostr((percount2-percount1)/frequency));
  35.     Render;
  36.     QueryPerformanceCounter(percount1);
  37.     LOG.Add('Zeichnen: '+ floattostr((percount1-percount2)/frequency));
  38.     percount2 := percount1;
  39.     //sleep(AktuelleZeit+(1000 div Const_FPSMAX) - GetTickCount);
  40.     Done:= false;
  41.     end
  42. else
  43. Done := true;
  44. end;


Ich sehe da auch nicht den Fehler, falls ich einen habe.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 29, 2009 10:55 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Schreibt deine Log-Klasse vielleicht ohne Puffer auf die Festplatte? Dann musst du dich nicht wundern wenn das so lahm ist.

Edit: Allerdings geht deine Zeitmessung ja auch darüber....hm...

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 29, 2009 11:01 
Offline
DGL Member

Registriert: Mo Mai 25, 2009 21:29
Beiträge: 30
LOG ist eine TStringlist die im Ondestroy auf eine Textfile geschrieben wird.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 29, 2009 12:02 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Ich würde vom OnIdle Event ganz absehen, da dessen Aufruf durch diverse Dinge behindert werden kann. In meinen Augen ist dieser Callback daher für eine Hauptrenderschleife total unbrauchbar und man sollte eine eigene Renderschleife implementieren, so wie ich das in allen meinen Projekten auch tue. Beim Programmstart also z.B. einen Timer loslaufen lassen (10ms) und von dort aus einen eigenen Mainloop starten und den Timer wieder deaktivieren.

P.S. : Wenn deine Awendung nie mehr als 60fps schafft, solltest du prüfen ob die vertikale Synchronisation deiner Grafikkarte aktiviert ist. Wenn ja, dann kann eine 3D-Anwendung nicht schneller laufen als die eingestellte Bildwiederholfrequenz. Also testweise im Treibermenü deaktivieren oder im Programm selbst mit wglSwapIntervalEXT.

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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 29, 2009 12:52 
Offline
DGL Member

Registriert: Mo Mai 25, 2009 21:29
Beiträge: 30
Wie sähe so eine Renderschleife aus?
Bsp:
Code:
  1.  
  2. While ProgrammSollZeichnen do
  3. begin
  4. application.processmessages
  5. //Rest wie im bisherigen  OnIdle
  6. end;
  7.  

So in etwa?

Vertikale Synchronisation ist aktiviert, allerdings war ja mit 30 FPS die Anwendung unter dem Maximum mit dem Texturbinden.
Ich muss also schauen, dass ich die zusammenpacke.
Allerdings scheint sich dass in einem längeren OnIdle niederzuschlagen (Das war ja am meisten länger geworden wenn ich bindtextur ausgeklammert habe).
Mir ist aber etwas anderes aufgefallen- der Grund weshalb ich eigentlich erst auf FPS-Störungen gekommen bin:
Mein Bild ist doppelt. (Also immer der frame davor so wackelig dabei)
Dadurch sieht das ganze bei Bewegung verschmiert, ruckelig aus.
(Sowohl mit als auch ohne VSync)
Kann man das beheben?


Zuletzt geändert von Mortal-Shadow am Fr Mai 29, 2009 12:54, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 29, 2009 12:52 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Ich würde sogar das ganze TForm weg lassen und selber das Fenster erstellen, da du so noch die ganze Mechanik von VCL mit durchnudeln lässt.
Es müssen ja noch Events abgerufen, verarbeitet, weiter geleitet werden und wer weiß, was die VCL noch alles tut, bevor es dein Idle Event auslöst.
Allerdings macht mich was anderes sehr stutzig, unzwar, dass (15ms idle + ~1ms für rest)*60Frames=960ms und somit verdammt nah an die Vertikale Synchronisierung liegt.
Ich kann mir gut vorstellen, dass dort der Grafiktreiber eingreift.
Da vorher bei einer FPS<60 dein Idle ja auch weniger Zeit gebraucht hat und VSync wegem weniger als 60FPS nicht greift.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 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 | 14 Queries | GZIP : On ]