Alpha not getting to 1
BlitzMax Forums/BlitzMax Beginners Area/Alpha not getting to 1
| ||
Can anyone ease my head and tell me when executing the code below why the 'Alpha' never (or only occasionaly) make it to 1.00000000?Strict Type TMyType Field Alpha:Float Field StartTime:Float Field ElapsedTime:Float Method ResetAlpha() Alpha = 0 End Method Method ResetTimers() StartTime = MilliSecs() ElapsedTime = 0 End Method Method CalculateElapsedTime() ElapsedTime = MilliSecs()-StartTime End Method Method Fade(FadeTimer:Int = 5000) ResetTimers() While ElapsedTime <= FadeTimer Alpha = ElapsedTime/FadeTimer Draw() CalculateElapsedTime() Wend DrawText "Done. Final Alpha: "+ Alpha , 0, 0 Flip End Method Method Draw() SetBlend ALPHABLEND SetAlpha Alpha SetColor 255, 255, 255 DrawText Alpha, 0, 0 DrawText "Working", 0, 10 Flip 1; Cls End Method End Type Local iRefreshRate:Int = GetDeviceCaps(GetDC(PrimaryDevice.hwnd), VREFRESH) SetGraphicsDriver GLMax2DDriver() Graphics 800, 600, 32, iRefreshRate ' And the code.. Local myScreen:TMyType = New TMyType myScreen.Fade() WaitKey If I change the screen refresh to 60 (instead of the current refresh rate) the 'Alpha' makes it to 1.00000000 If I change 'Flip 1' to 'Flip 0', again 'Alpha' makes it to 1.00000000 I am a little tierd, and cant seem to figure it out! Many thanks, |
| ||
at a guess, and without looking at the code, it's probably a floating point precision issue. You could check to see if it's close to 1.0 and if so, just set it. |
| ||
As a wild guess, I bet it only reaches 1.0 on screen refreshes that divide into 5000 ;) Its because somtimes the elapsed time is greater than the fade time While ElapsedTime <= FadeTimerIt will happen whenever (Milliseconds Per Frame) isnt a denominator of fadetimer EG 4980 + 60 Milli is grater then your 5000 Fadetimer, so it dosent run a cycle with it as one. To fix it make FadeTimer a multiple of the refresh rate (ie 5040 for 60Hz) |
| ||
H&K: I see what you are saying, but I don't think this is correct because why would it work okay (every time) when I set Flip to 0 (Flip 0) and the screen refresh is either 60 or my desktop (actually 75)? I am pretty sure that it wont matter what the refresh rate is if Flip is 0, it will always work. I am still stumped :( Just a thought.. If I change the following: Method Fade(FadeTimer:Int = 5000) ResetTimers() While ElapsedTime <= FadeTimer Alpha = ElapsedTime/FadeTimer Draw() CalculateElapsedTime() Wend DrawText "Done. Final Alpha: "+ Alpha , 0, 0 Flip End Method to Method Fade(FadeTimer:Int = 5000) ResetTimers() Repeat Alpha = ElapsedTime/FadeTimer Draw() CalculateElapsedTime() Until ElapsedTime >= FadeTimer DrawText "Done. Final Alpha: "+ Alpha , 0, 0 Flip End Method That might do it? (I cant try it now, I am still at work) |
| ||
Because with flip 0 it has no 60hz (it disables VSync unless it is enforced as always on in driver). With todays GPUs its most likely like 120 - 200 in which case its much more likely that it hits the right spot. Modifying the code a little should solve it: Method Fade(FadeTimer:Int = 5000) ResetTimers() While ElapsedTime <= FadeTimer Alpha = ElapsedTime/FadeTimer Draw() CalculateElapsedTime() Wend if Alpha < 1 Alpha = 1 Draw() CalculateElapsedTime() endif DrawText "Done. Final Alpha: "+ Alpha , 0, 0 Flip End Method |
| ||
If sync is 0, then the flip occurs as soon as possible. If sync is 1, then the flip occurs on the next vertical blank.Just change the 5000, to 5040. (for 60 hz) or5025 for 75 hrz. WHY, do you print the question, then say Naar your wrong, without even looking at the Anwser |
| ||
Yes! That will do it, thanks Dreamora!!! |
| ||
H&K, I didnt say you are wrong, because I dont know at this point. I said "I don't think this is correct", big difference. However, I didnt mean to offend you either way, so sorry :) |
| ||
Hang on, you mean you actually cut and pasted Dreams code, Yet couldnt be bothered to change 2 didits when I told you the anwser? Im sorry but yes I am annoyed at you. (I was alredy A bit annoyed when you reprinted your code without changing the 5000) |
| ||
H&K: I have not tried any of the code (still at work). I just mulled it over in my head, and Dreamora's made more sense. Although I got what you are aiming at. Thanks H&K for you reply! |
| ||
This is H&K's big brother. You've gone and made him cry Ok yep Dreams makes more sence. That because in anwser to your "Alpha doesnt reach 1" dream sudgests you just make it equal 1 The reason it wasnt equaling one is the reason I gave. I didnt mention the flip 0 not being synced the first time, because I (Incorrectly it seems), simply assumed you knew that. Whats happening when flip is 1, is that 1000/(Hertz frame rate) is being added to elapsedtime each flip. Now if 1000/(Hertz frame rate) doesnt divide without remainder into fadetime, then alpha will never reach 1. When Flip is 0, probally the flip time is as Dream said very very quick, so Frametime*x has more chance of being 5000 exactly |
| ||
Btw: you could use H&K suggestion as well but in an automatic way: Just calculate the difference from hertz to fadetimer: At the beginning of the function FadeTimer :+ (GraphicsHertz() - (FadeTimer mod GraphicsHertz()) ) That way the FadeTimer is always int divideable with Flip 1 and should reach alpha = 1 as well. I say should because I'm not sure that the GraphicsHertz() bug with DX has been fixed. |
| ||
@dream, I did think of presenting my first anwser like that, but decided to keep it simpler. However on my computer it sometimes drops from 60htz to 59htz unexpectedly. (Well not really unexpectidly, cos you can predict when its going to happen) When it does this, you need to just do what you have done and catch it ;) ie Your solution was the better one to use But thats because my answer was to show "Why alpha doesnt equal 1" by forceing u2o to look at what was specificaly wrong with his logic to make the while loop fail before it reached 1 (Edit: This makes me sound like a total git dosent it?) Which, given that I hate being given my sort of anwser, is probably not the way to do it. But I do think that there should be a fundimentaly different type of anwser depending on which thread, (begginer/programing) the post is in |
| ||
Thanks for the replies, much appreciated :) |