Frameunabhängigkeit klappt nicht
Übersicht

MeikBetreff: Frameunabhängigkeit klappt nicht |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Moin ![]() Zuerst: Wer das Pröglein testen mag braucht die Plot.png. Muss im selben Verzeichnis wie das Programm liegen. (Ist keine leere Seite. Das Bild ist nur 16 x 16 px Groß und ist ein weißer Kreis ^^) http://img215.imageshack.us/img215/9704/plot.png Achso und ich hab Draw3D V3.2 mit eingebaut. Letztens kam das ps3 3.0 Update raus. Diese Version hat den standard Hintergrund "aufbereitet" und mit so "Glühwürmchen" versehen (Particle die kurz aufleuchten und dann wieder schwächer werden). Da dacht ich mir "Boah, sieht das cool aus. Das muss ich mal nachprogrammieren." Gesagt getahn! Der Code funktioniert so wie er ist einwandfrei für mein verständnis ![]() Code: Code: [AUSKLAPPEN] Global SW% = 800, SH% = 600
Graphics3D SW%, SH%, 32, 1 SetBuffer( BackBuffer() ) SeedRnd( MilliSecs() ) Local frametimer% = CreateTimer( 60 ) Local Camera% = CreateCamera() Include "Includes\Draw3D.bb" DrawInit3D( Camera% ) Origin3D( SW%, SH% ) Global Font = LoadFont3D( "Fonts\Standard.png" ) SetFont3D( 0.5, 1.0, 0.0, 0.0 ) ;Global Background% = LoadImage3D( "Background.bmp" ) Global ParticleTimer% = MilliSecs() Global ParticleDelay% = ParticleTimer% + 50 Global NumParticle% = 0 Global NumParticlePerFrame% = 1 Global MaxParticle% = 200 Global FPSC# = 0 ;C = Counter Global FPS# = 0 Global FPSF# = MilliSecs() + 1000 ;F = Finish Global ms# = MilliSecs() Global mse# = 0.0 Global dif# = 0.0 Global dot% = LoadImage3D( "Plot.png" ) Type TParticle Field img% Field dir% Field x#, y# Field mx#, my# Field r%, g%, b%, a# Field life% Field hlife% Field scale# Field scaleperframe# End Type While Not KeyDown( 1 ) ms# = MilliSecs() FPSC# = FPSC# + 1 If( ms# > FPSF# ) FPS# = FPSC# FPSC# = 0 FPSF# = ms# + 1000 EndIf ;ParticleTimer% = MilliSecs() ;If( ParticleTimer% > ParticleDelay% ) For i = 1 To NumParticlePerFrame% If( NumParticle% < MaxParticle% ) Then CreateParticle() Next ;ParticleDelay% = ParticleTimer% + 50 ;EndIf ColorG3D( 255, 255, 255, 1 ) ;DrawImage3D( Background%, 0, 0 ) UpdateParticle() Text3D( Font, -SW% / 2, 0, "FPS: " + FPS# ) Text3D( Font, -SW% / 2, -12, "FPS Counter: " + FPSC# ) Text3D( Font, -SW% / 2, -24, "FPS Finish: " + FPSF# ) Text3D( Font, -SW% / 2, -36, "ms: " + ms# ) Text3D( Font, -SW% / 2, -48, "mse: " + mse# ) Text3D( Font, -SW% / 2, -60, "dif: " + dif# ) mse# = MilliSecs() dif# = mse# - ms# WaitTimer( frametimer% ) RenderWorld() Clear3D() Flip 0 Wend End Function CreateParticle() NumParticle% = NumParticle% + 1 Local p.TParticle = New TParticle ;p\img% = GrabImage3D( dot%, 0, 0, 1, 1, 1, 1 ) p\img% = LoadImage3D( "Plot.png" ) p\x# = Rand( -(SW% / 2), SW% / 2 ) p\y# = Rand( -(SH% / 2), SH% / 2 ) p\dir% = Rand( 360 ) p\mx# = Cos( p\dir% ) * Rnd( 0.1, 0.5 ) p\my# = Sin( p\dir% ) * Rnd( 0.1, 0.5 ) p\r% = 200 p\g% = 200 p\b% = 200 p\a# = Rnd( 0.3, 1.0 ) p\life% = Rand( 20, 80 ) p\hlife% = p\life% / 2 p\scale# = 0 p\scaleperframe# = Rnd( 0.005, 0.01 ) End Function Function UpdateParticle() For p.TParticle = Each TParticle p\x# = p\x# + p\mx# p\y# = p\y# + p\my# ;p\x# = p\x# + p\mx# / FPS# ;p\y# = p\y# + p\my# / FPS# ;p\x# = p\x# + p\mx# * dif# ;p\y# = p\y# + p\my# * dif# p\life% = p\life% - 1 If( p\life% > p\hlife% ) p\scale# = p\scale# + p\scaleperframe# Else p\scale# = p\scale# - p\scaleperframe# EndIf ColorG3D( p\r%, p\g%, p\b%, p\a# ) DrawImage3D( p\img%, p\x#, p\y#, 0, 0, p\scale#, 0 ) If( p\life% <= 0 ) p\x# = Rand( -(SW% / 2), SW% / 2 ) p\y# = Rand( -(SH% / 2), SH% / 2 ) p\dir% = Rand( 360 ) p\mx# = Cos( p\dir% ) * Rnd( 0.1, 0.5 ) p\my# = Sin( p\dir% ) * Rnd( 0.1, 0.5 ) p\r% = 200 p\g% = 200 p\b% = 200 p\a# = Rnd( 0.3, 1.0 ) p\life% = Rand( 20, 80 ) p\hlife% = p\life% / 2 p\scale# = 0 p\scaleperframe# = Rnd( 0.005, 0.02 ) ;NumParticle% = NumParticle% - 1 EndIf Next End Function die FPS zu mässen (oder messen? weiss ich grad nicht ^^, zu zählen ) hab ich hinbekommen. Aus einem meiner alten Bücher über c++ und DirectX hab ich das Beispiel: Code: [AUSKLAPPEN] p\x# = p\x# + p\mx# / FPS#
p\y# = p\y# + p\my# / FPS# So wird die Frameunabhängigkeit aber nur einmal pro Sekunde aktualisiert da sich die FPS nur einmal pro Sekunde ändern. Jetzt hab ich hier mal im Forum gelesen die Zeitdifferenz vom Anfang der Schleife zum Ende der Schleife zur Berechnung zu benutzen. Hab ich auch probiert. Ergebnis: Code: [AUSKLAPPEN] [...]
Global ms# = MilliSecs() Global mse# = 0.0 ;Millisekunden am Ende der Schleife Global dif# = 0.0 [...] While Not KeyDown( 1 ) ms# = MilliSecs() [...] mse# = MilliSecs() dif# = mse# - ms# Wend End Function UpdateParticle() For p.TParticle = Each TParticle p\x# = p\x# + p\mx# * dif# p\y# = p\y# + p\my# * dif# [...] Next End Function Und jetzt nach langer Erklärung das eigendliche Problem: dif# wechselt sich immer zwischen 0.0 und 4.0. Warum ist das so? Was hab ich in meinem Code anders gemacht als es hier in den vielen Beispielen beschrieben ist? Meine rechenkünste sind zu bescheiden um von den dif# auf Frames umzurechnen aber rein logisch gesehen müsste bei ca 60 FPS dif# höher sein als 4.0. Hoffe ihr habt mich (mal wieder ^^) verstanden wo mein Problem liegt ![]() Ich will euch nur nicht auf den Zeiger gehen mit meinem Pipi Progrämmchen und meinen Ellenlangen Texterklärungen ![]() Edit: Habe bei 500 Glühwürmchen 11 FPS und eine Millisekundendifferenz von 2? wie geht das? :O Zählt mein Rechner schneller als er die Bilder aufbauen kann? hmm... |
||
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich hab dein Code nicht gleich sofort verstanden, dann neu angefangen dir das Frameunabhängige mal zu erklären. Dazu habe ich ein kleines Testprogramm geschrieben:
Code: [AUSKLAPPEN] Graphics 800,100,0,2
SetBuffer BackBuffer() Local Timer=CreateTimer(60) Local Warten Local MSNeu=MilliSecs() Local MSAlt Local MSDiff# Local XPos#=100 Local XSpeed#=5 While Not KeyHit(1) MSAlt=MSNeu MSNeu=MilliSecs() MSDiff=(MSNeu-MSAlt)/16.666 ; Entspricht (1000MS/Sek)/60FPS Text 20,14,"Langsamen Rechner simulieren mit [SPACE]" Text 20,34,"Ist gerade Aktiv = "+Warten If KeyHit(57) Then Warten=1-Warten If Warten=1 Then Delay 40 If KeyDown(203) Then XSpeed=XSpeed-0.1*MSDiff If KeyDown(205) Then XSpeed=XSpeed+0.1*MSDiff Rect XPos,54,10,10,1 XPos=XPos+XSpeed*MSDiff If XPos>800 Then XPos=-10 If XPos<-10 Then XPos=800 Text 20,74,"DifferenzMultiplikator: "+MSDiff WaitTimer Timer Flip 0 Cls Wend End Im großem und ganzem brauchst du nicht unzählige MilliSecs() aufrufe pro Schleifendurchlauf. Es reicht erstmal nur einer. Auch eine FPS-Berehnung brauchst du nicht. Was dur brauchst ist einfach nur die Differenzzeit de sletzten Schleifendurchlaufs. Und dieser errechnet sich aus den folgenden drei Zeilen: Code: [AUSKLAPPEN] MSAlt=MSNeu
MSNeu=MilliSecs() MSDiff=(MSNeu-MSAlt)/16.666 Im Idealfall (das wäre, das Programm läuft mit 60 FPS was 1000/60 = 16.6666 entspricht) läuft die Berechnung auf den Wert 1.0 zu. Läuft dein Programm zum Beispiel nur mit 30 FPS, dann wird MSDiff zu 2.0 etc... Diesen Wert mußt du dann zu jeder Geschwindigkeitsvariable (auch bei der Beschleunigung!!!) mit einberechnen. Also Multiplizieren. Fertig ist das ganze. Edit1: Zitat: Edit: Habe bei 500 Glühwürmchen 11 FPS und eine Millisekundendifferenz von 2? wie geht das? :O Zählt mein Rechner schneller als er die Bilder aufbauen kann? hmm...
Wenn deine Grafikkarte sehr leistungsschwach ist, kann es passieren, dass der Rechner tatsächlich Bilder im vorraus berechnet und die Grafikkarte bis zu einer Sekunde hinterher hinkt, bis es dann den Speicher frei gibt und das Aufbauen der Verzögerung wieder von neuen beginnt. zumindest habe ich das Problem bei meiner abgespeckten und ur-alten ATI, wenn zuviele 3D-Sachen berechnet werden, der Prozessor sich aber langweilt. |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
![]() |
Nicdel |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zu beachten:
Code: [AUSKLAPPEN] CreateTimer(60)
begrenzt nicht auf 60 sondern auf 62.5 FPS. |
||
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7 |
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Jo, das stimmt wohl. Habe es zwar auch schon seit einiger Zeit feststellen müssen, habe mir aber nicht die Mühe gemacht die tatsächliche Zeit zu messen.
Aber eben mal ausprobiert, statt: MSDiff=(MSNeu-MSAlt)/16.666 dann MSDiff=(MSNeu-MSAlt)/16 zu nehmen, macht das ganze noch unruhiger wie ich finde. Auch wenn /16 dann genau 1000/62.5 entsprechen. |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
Meik |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Erstmal herzlichen Dank ![]() Ich hab hier tatsächlich eine uralt mühle die WIRKLICH uralt ist. Die Grafikkarte ist auch schon vor dem ersten Weltkrieg alt gewesen ^^. Vielleicht packt der Rechner das ja wirklich nicht und ich muss das mal auf einem anderen Rechner Probieren ![]() Ich werd mal mein kleines Glühwürmchen Projekt in dein Frameunabhängiges Programm "einbauen" und schauen ob ich nicht vielleicht doch was retten kann ![]() Danke euch beiden für die Hilfe und die Infos ![]() btw: Sobald man Draw3D erwähnt kommt hectic irgendwie immer dazu ^^ Ist nicht böse gemeint aber das ist sowas wie das "Batman" symbol am Himmel *g* MFG ![]() Edit: Geil, jetzt klappt es dank deiner Formel, hectic! Ich weiss noch nicht was an meinem Code so blöd lief aber ich werd den nicht löschen. Mein alter Code ist ein hervorragendes Übungsobjekt für mich ^^. Wie schön ich mir immer selbst Steine in den Weg lege um mich dann zu freuen sie wieder weg zu räumen xD *glücklich ist* ^^ Edit 2: Die Framezählung hab ich nur eingebaut weil ich testen wollte ob ich das überhaupt kann. Sie hat keinen wirklich Sinn ausser zu exestieren ^^ |
||
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ja, immer wenn die Draw3D mit im Spiel ist schalte ich mich ein. Das liegt u.a. auch daran, dass ich immer noch auf der Suche nach möglichen Fehlern der Draw3D bin. Möchte vermeiden, dass sich Leute den Kopf zerbrechen, nur weil ich eventuell Fehler gemacht habe. So konnten auch in der V.3.2 zu älteren noch zwei solcher Fehler behoben werden.
Das waren, falls es überhaupt jemand interessiert: Einmal beeinfluste ein eingestellter Fog mit die Draw3D-Darstellung. Und zum anderem gab es Probleme, wenn jemand eine sehr große Auflösung eingestellt hat, dann war das standard voreingestellte CameraRange nicht mehr im Sichtbereich der Draw3D gewesen. Beide Fehler habe ich behoben, auf welche ich nicht gekommen wäre, da ich zum einen nicht mit FogRange arbeite noch große Auflösungen in Projekten einstelle. ![]() Für Hobbyentwickler soll programmieren ja Spaß machen. Und jeder hat da seine eigenen Vorlieben. Im übrigen finde ich deine Glühwürmchen sehr gut umgesetzt. Ich probier das gleich mal zu Testzwecken auf meinem SED (SpriteEDitor) der automatisch Animationen für die Draw3D2 machen kann. |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
Meik |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Vielen dank für das Lob ![]() Übrigends: Das ist das mein erstes Prjekt mit Draw3D und hatte keine Probleme mit dem 0 Punkt *g* find ich Klasse so! Draw3D ansich ist Super! |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group