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

Aktuelle Zeit: Fr Jul 18, 2025 04:26

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Sa Mär 18, 2006 13:23 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jan 24, 2006 16:26
Beiträge: 25
hi,

ich möchte mein Programm vom Render/CPU Speed unabhängig machen und probiere TBM einzubauen.

Meine Fragen:
1. Wenn ich die Proceduren haben wie unten aufgeführt wo muss ich diese in meinem Programm plazieren?

2. Wo bekomme ich die Variablen Pos.x, Speed.x und Zeitfaktor her?

Code:
  1.  
  2. procedure TForm2.BeimStart;//Was hier drinnen steht sollte zum Start ausgeführt werden
  3. begin
  4.   BerechnungsZeit := GetTickCount();
  5. end;
  6.  
  7. procedure TForm2.BerechnungsCheck;//Alle nötigen Berechnungen durchführen
  8. const
  9.   Frequenz=1000;//Durch Windows festgelegt
  10. var
  11.   AktuelleZeit:LongWord;
  12. begin
  13.   AktuelleZeit := GetTickCount();
  14.   Berechne((AktuelleZeit - BerechnungsZeit) /Frequenz);
  15.   BerechnungsZeit := AktuelleZeit;
  16. end;
  17.  
  18. procedure TForm2.Berechne(ZeitFaktor:Double);
  19. begin
  20.   {Alle Berechnungen stehen hier }
  21.   //z.B
  22.   Pos.X := Pos.X + Speed.X*ZeitFaktor;
  23.   if Pos.X > 20 then Pos.X := 0;
  24. end;
  25.  


thx im Vorraus für die Antworten.

mfg juKx


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mär 18, 2006 18:04 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 26, 2002 22:12
Beiträge: 259
Wohnort: Dresden
Zuerst einmal solltest du für die Berechnung der Zeit kein GetTickCount nutzen. GetTickCount ist nicht sehr genau. Besser du nutzt QueryPerformanceCounter. Die Frequenz ist hier wesentlich höher.

Was die anderen beiden Fragen angeht, so werde ich nicht so richtig schlau daraus. Die Vorgehensweise ist folgende:
Im OnIdle-Ereignis oder wo auch immer du deine Szene aktualisierst startest du die Zeitmessung. Anschließend renderst und aktualisierst du deine Szene. Bist du damit fertig misst du die Zeit erneut und die Differenz ist logischerweise die vergangene Zeit, die du zum Aktualisieren deiner Szene benötigt hast. Das ist dann dein Zeitfaktor.

Pseudocode deiner Hauptrenderschleife:

QueryPerformanceCounter(End);
TimeFactor := (Start – End) / Frequency * ScaleFactor;
QueryPerformanceCounter(Start);
UpdateScene;
RenderScene;

Ich habe hierbei die Ermittlung von „End“ an den Anfang der Prozedur geschoben. Damit misst du automatisch auch noch die Zeit, die bis zum nächsten Aufruf deiner Renderprozedur vergeht. Du musst hierbei aber „Start“ vorinitialisieren (QueryPerformanceCounter(Start)), sonst erhältst du im ersten Frame einen sehr großen negativen Wert als Zeitfaktor.

_________________
Nichts auf der Welt ist so gerecht verteilt wie der Verstand. Denn jederman ist überzeugt, dass er genug davon habe.
Rene Descartes, frz. Mathematiker u. Philosoph, 1596-1650


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mär 18, 2006 18:30 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jan 24, 2006 16:26
Beiträge: 25
hi,

danke erstmal für deine Antwort! Sorry aber ich glaube ich bin zu dumm dazu:

1. Was ist der Scalefactor?

2. Wo muss ich dann den Zeitfaktor verwenden?

3. Sind die Sachen dort richtig in den Prozeduren?

Code:
  1.  
  2. var start,Ende : int64;
  3.  
  4. procedure TForm2.FormCreate(Sender: TObject);
  5. begin
  6.   DC:= GetDC(Handle);
  7.   if not InitOpenGL then Application.Terminate;
  8.   RC:= CreateRenderingContext( DC,
  9.                                [opDoubleBuffered],
  10.                                32,
  11.                                24,
  12.                                0,0,0,
  13.                                0);
  14.   ActivateRenderingContext(DC, RC);
  15.   SetupGL;
  16.   QueryPerformanceCounter(Start);
  17.   Application.OnIdle := IdleHandler;
  18. end;
  19.  
  20. procedure TForm2.Render;
  21. begin
  22.   //irgentwas
  23.  
  24.   TimeFactor := (Start – Ende) / Frequency * ScaleFactor;
  25.   SwapBuffers(DC);//um so mehr swapbuffers um so langsamer die bilder (fps)
  26. end;
  27.  
  28.  
  29. procedure TForm2.IdleHandler(Sender: TObject; var Done: Boolean);
  30. begin
  31.   QueryPerformanceCounter(Ende);
  32.   Render;
  33.   TimeFactor:=(Start–Ende)/Frequenz*ScaleFactor;
  34.   Done:= false;
  35. end;
  36.  


mfg juKx und thx für die Hilfe im Vorraus!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mär 18, 2006 20:17 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 26, 2002 22:12
Beiträge: 259
Wohnort: Dresden
ScaleFactor ist ein beliebiger Wert deiner Wahl. Der TimeFactor fließt immer in all deine Bewegungen (Beschleunigung, Geschwindigkeit) ein. Du kannst deine OpenGL-Welt theoretisch unendlich klein oder unendlich groß zeichnen. Weil TimeFactor als Produkt in alle Geschwindigkeiten einfließt erzeugt ein hoher TimeFactor auch hohe Geschwindigkeiten. Also passt du die Größe von TimeFactor mit Hilfe des ScaleFactors so an, dass du deinen bisherigen Code beibehalten kannst und ungefähr dasselbe Ergebnis erzielst (soweit ich weiß implementierst du Timebased Movement nachträglich).
Ansonsten müsstest du alle Geschwindigkeiten einzeln anpassen und das dauert länger ;).

FormCreate stimmt soweit. Du musst aber auch noch die Frequenz deines Counters ermitteln, denn die ist von Rechner zu Rechner unterschiedlich. Das machst du mittels QueryPerformanceFrequency (am besten auch im OnCreate). Damit hast du dann auch deinen Frequenzwert.

Der nächste Fehler ist, dass du im Moment „Start“ nur im OnCreate misst (das ist richtig wegen der Vorinitialisierung, die ich beschrieben habe). Du musst „Start“ aber zusätzlich jedes Frame neu ermitteln. Schleißlich willst du die vergangene Zeit für jedes Frame haben und nicht die vergangene Zeit seit Programmstart (OnCreate).

Ansonsten reicht es TimeFactor einmal zu berechnen ;).

Wirf am besten einen Blick ins Bombermantutorial. Der Sourcecode liegt soweit ich weiß offen und dann kannst du dir genau ansehen, wie es dort gemacht wird.

_________________
Nichts auf der Welt ist so gerecht verteilt wie der Verstand. Denn jederman ist überzeugt, dass er genug davon habe.
Rene Descartes, frz. Mathematiker u. Philosoph, 1596-1650


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 19, 2006 13:16 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jan 24, 2006 16:26
Beiträge: 25
Magellan hat geschrieben:
ScaleFactor ist ein beliebiger Wert deiner Wahl. Der TimeFactor fließt immer in all deine Bewegungen (Beschleunigung, Geschwindigkeit) ein. Du kannst deine OpenGL-Welt theoretisch unendlich klein oder unendlich groß zeichnen. Weil TimeFactor als Produkt in alle Geschwindigkeiten einfließt erzeugt ein hoher TimeFactor auch hohe Geschwindigkeiten. Also passt du die Größe von TimeFactor mit Hilfe des ScaleFactors so an, dass du deinen bisherigen Code beibehalten kannst und ungefähr dasselbe Ergebnis erzielst (soweit ich weiß implementierst du Timebased Movement nachträglich).
Ansonsten müsstest du alle Geschwindigkeiten einzeln anpassen und das dauert länger ;).


Das verstehe ich nicht. Ich habe jetzt den Timefactor berechnet und auch ein Blick ins Bomberman Tutorial geworfen aber ich weiss einfach nicht wo ich mein TimeFactor einbauen soll..In meiner Render Prozedur lasse ich einen Ball im Formular rumfliegen indem ich seine Mittelpunktskoordinaten in jedem Render Durchlauf um die Geschwindigkeit (vx,vy=1) veränder..muss da der timefactor mit einspielen alssen, weil im Bomberman Tutorial sieht man auch nicht wo der TimeFactor eingebaut wird....

Code:
  1. procedure TForm2.FormCreate(Sender: TObject);
  2. begin
  3.   DC:= GetDC(Handle);
  4.   if not InitOpenGL then Application.Terminate;
  5.   RC:= CreateRenderingContext( DC,
  6.                                [opDoubleBuffered],
  7.                                32,
  8.                                24,
  9.                                0,0,0,
  10.                                0);
  11.   ActivateRenderingContext(DC, RC);
  12.   SetupGL;
  13.   QueryPerformanceFrequency(Frequenz);
  14.   //QueryPerformanceCounter(Start);
  15.   Application.OnIdle := IdleHandler;
  16. end;
  17.  
  18. procedure TForm2.Render;
  19. begin
  20.   xm:=xm+vx; //Bewegung in die Sache bringen
  21.   ym:=ym+vy;
  22.  
  23.   SwapBuffers(DC);//um so mehr swapbuffers um so langsamer die bilder (fps)
  24. end;
  25.  
  26. procedure TForm2.IdleHandler(Sender: TObject; var Done: Boolean);
  27. var TimeFactor:real;
  28. begin
  29.   QueryPerformanceCounter(Start);
  30.   Render;
  31.   QueryPerformanceCounter(Ende);
  32.   TimeFactor:=((Start-Ende)/Frequenz)*100; //100 Scalefactor ist beliebig zu wählen
  33.  
  34.   Done:= false;
  35. end;


mfg juKx


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 19, 2006 14:38 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Na überall wo sich was bewegt. Der Timefactor ist eine float Zahl die du auf deine Geschwindigkeit multiplizierst. Ist der Factor größer 1 (also wenn das Rendern länger als normal dauert) dann fliegt die Kugel für den nächstenschritt etwas schneller. Ist der Factor kleiner ein (also wenn das Rendern schneller geht als "normal") dann fliegt die Kugel langsamer.

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 19, 2006 15:15 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jan 24, 2006 16:26
Beiträge: 25
ok danke erstmal....jetzt nur noch eine letzte Frage:

Dann müssen ja alle Bewegungsvaribalen vom Typ real sein odeR? Da meine aber integer sind geht das nicht...und noch ne Frage wie ist der Timefactor beim ersten durchlauf wenn er noch nicht berechnet ist?

mfg juKx


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 19, 2006 16:07 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 26, 2002 22:12
Beiträge: 259
Wohnort: Dresden
Du kannst den TimeFactor doch bei der Initialisierung auf 0 setzen. Damit vergeht im ersten Frame quasi gar keine Zeit.

Der Genauigkeit halber sollten alle „Bewegunsvariablen“ Fließkommatypen sein. Bei der Ausgabe hindert dich aber nichts daran die Werte zu runden.

_________________
Nichts auf der Welt ist so gerecht verteilt wie der Verstand. Denn jederman ist überzeugt, dass er genug davon habe.
Rene Descartes, frz. Mathematiker u. Philosoph, 1596-1650


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


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:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 15 Queries | GZIP : On ]