Flickering

Advanced game related topics
Krylar
User
User
Posts: 88
Joined: Thu Apr 15, 2004 3:17 pm

Flickering

Post by Krylar »

I've searched the boards and found a few suggestions for how to handle the flicker problem with using FlipBuffers, but I'm still not understanding what the best method is.

I tried the:

Code: Select all

StartDrawing(ScreenOutput()) 
Box (0,0,1204,768,0) 
StopDrawing()
Method instead of using ClearScreen(0,0,0). It does seem to curb the flickering a bit, but it still happens.

I also saw a couple of suggestions about controlling the refresh rate of the application, but I felt that this may cause potential problems with one's monitor. I did try using the SetFrameRate command, but I noticed no discernable difference with that either.

What I have noticed is that it only seems to flicker the top 30 or so pixels. The rest of the screen seems unaffected.

The code I'm using comes directly from the help file:

Code: Select all

  If InitSprite() And InitKeyboard() And OpenScreen(800,600,16,"") 
    Repeat 
      FlipBuffers() 
      ClearScreen(0, 0, 0) 
      
      ExamineKeyboard() 
      FullText$ + KeyboardInkey()  ; Add the new text to the current one (if any) 
      
      ; If we press the 'Back' key, delete the last character 
      ; 
      If KeyboardReleased(#PB_Key_Back)  
        FullText$ = Left(FullText$, Len(FullText$)-1) 
      EndIf 

      ; Display the result 
      ; 
      If StartDrawing(ScreenOutput()) 
        DrawingMode(1) 
        FrontColor(128, 255, 0) 
        Locate(20,20) : DrawText("Just type some text...:") 
        Locate(20,40) : DrawText(FullText$) 
        StopDrawing() 
      EndIf 
    Until KeyboardPushed(#PB_Key_Escape) 
  EndIf 
I'm using an ATI Radeon 9800 Pro with 256MB and the latest drivers (July 7th, 2004), and also using DirectX 9.0b.

I searched the boards pretty heavily but everything that I've tried has been met without success. Any ideas?

Thanks for any help you can provide!

-Krylar
MadMax
Enthusiast
Enthusiast
Posts: 237
Joined: Mon Oct 06, 2003 11:56 am

Post by MadMax »

This seems to be a common problem, with modern drivers and 2D. Sadly pure 2D is greatly despised nowadays.

I had a TNT2 when I bought Blitz3D (in a special offer with your book :D ) So I installed it all, and was horrified to see my screen flicker horribly in 2D mode. Luckily I thought of using my old gfx drivers (3.82) and it all worked well. Not only that but the card seemed to work faster in 3D as well. This has made me slightly suspicious of "latest drivers" fashion.

Of course your card is an ATI and not Nvidea, but solucion might be among the same lines.

One trouble is of course if you want to distribute your 2D games, chances are that the user's card will flicker in a bad way. Doesn't seem very feasible to me to be able to ask him to change his drivers. So one posible solution is to make a borderless invisible window, and open a windowed screen.

Here is your same code modified to do this:

Code: Select all

If InitSprite() And InitKeyboard()

sw = GetSystemMetrics_(#SM_CXSCREEN)
sh = GetSystemMetrics_(#SM_CYSCREEN)

   hWnd=OpenWindow(0,0,0,sw,sh,#PB_Window_BorderLess,"")

   X=OpenWindowedScreen(hWnd,0,0,800,600,1,0,0)
   ;SetFrameRate(60)

    Repeat
      FlipBuffers()
      ClearScreen(0, 0, 0)
     
      ExamineKeyboard()
      FullText$ + KeyboardInkey()  ; Add the new text to the current one (if any)
     
      ; If we press the 'Back' key, delete the last character
      ;
      If KeyboardReleased(#PB_Key_Back) 
        FullText$ = Left(FullText$, Len(FullText$)-1)
      EndIf

      ; Display the result
      ;
      If StartDrawing(ScreenOutput())
        DrawingMode(1)
        FrontColor(128, 255, 0)
        Locate(20,20) : DrawText("Just type some text...:")
        Locate(20,40) : DrawText(FullText$)
        StopDrawing()
      EndIf
      
      ;### Check for windows events   
      Eve= WindowEvent()  
      Select Eve
        Case #PB_Event_CloseWindow              
        End                                      
      EndSelect

    Until KeyboardPushed(#PB_Key_Escape)
  EndIf 
I would recomend having this as an option, in case the user screen flickers and he doesn't want to go around changing his drivers. Of course the pure 2D screen is far better in my opinion.

Hope this is of some help :D
Krylar
User
User
Posts: 88
Joined: Thu Apr 15, 2004 3:17 pm

Post by Krylar »

That does seem to work quite nicely. Do you notice a slowdown in speed with that method at all? Just curious.

All of the stuff that I still compile and use from my Blitz code has no flickering at all. Strange.

...EDIT: Note that I have 7 machines (I know that's sick) at home here, all with different video cards, nVidia, ATI, and then a couple of embedded laptop jobbies too. All of them seem to flicker with the original code. None flicker from my Blitz apps though. Maybe there's something more to this that we're missing that would help with this problem? Just a thought. END EDIT...

Ah well, thanks very much for the code!

-Krylar
Last edited by Krylar on Thu Jul 22, 2004 7:08 pm, edited 1 time in total.
Num3
PureBasic Expert
PureBasic Expert
Posts: 2812
Joined: Fri Apr 25, 2003 4:51 pm
Location: Portugal, Lisbon
Contact:

Post by Num3 »

The flickering can be because of 2 things

a) you've disabled Vsync on your video card driver (which is good for 3d, but kills 2d)

b) Bad coding, unlike the example in the manual you should make your rendering loop like this...

Code: Select all

Repeat

 ClearScreen(0,0,0) ; clear screen before rendering

 ; DRAW SPRITES

 FlipBuffers() ; This should always be the last thing

Forever
This way you ensure the screen is erased before any gfx are drawned and that every thing is on screen when it's flipped.
Krylar
User
User
Posts: 88
Joined: Thu Apr 15, 2004 3:17 pm

Post by Krylar »

I typically use the method of clearing at the top of the loop and flipping at the bottom, but I just wanted to cut-n-paste the code in. I did move the flip to the bottom as a test, but that didn't seem to help. Also I verified that my VSync is enabled.

Again, only seems to be a problem in things I'm creating with PB, at least that I can tell. Even some old C apps that I did when I was learning DirectX run without flicker, so it's gotta be some command I'm missing or improperly calling.

Thanks for the help!

-Krylar
Codemonger
Enthusiast
Enthusiast
Posts: 384
Joined: Sat May 24, 2003 8:02 pm
Location: Canada
Contact:

Post by Codemonger »

Damn I'm not home right now to find a solution this but a couple of things come to mind, and I'll check them out tonight:

One is Vsync disabled which will cause tearing effects, not screen flickering though. With Vsync disabled, and all images been drawn on the screen have not changed position or are static. You should not notice any odd visual defects such as flickering.

Another is that if you are clearing the front buffer (not back buffer) after flipping ?? this would definately cause a flicker ... when i get home tonight i'll test it. Basically you would be drawing the image then clearing it really quick .. quick enough to see a flickered image. Anyway I'll check it out tonight

Oh yeah to double check if Vsync is enabled you can use a FPS counter and that should be the same or similar to your refresh rate ... its a quick check to discount that theory. Also if your FPS is off the charts then your Vsync is disabled.
Last edited by Codemonger on Thu Jul 22, 2004 7:43 pm, edited 1 time in total.
<br>"I deliver Justice, not Mercy"

    - Codemonger, 2004 A.D.
MadMax
Enthusiast
Enthusiast
Posts: 237
Joined: Mon Oct 06, 2003 11:56 am

Post by MadMax »

@ Krylar: Your code works perfectly on my machine. Does this happen with all code samples? It all seems strange, as none of my usual testers has told me anything like this. Could some other program you normaly use intefere with PB?

I've taken the liberty of organizing your code in a different way (more to my liking :) ). Maybe, it'll work better?

Code: Select all

If InitSprite() And InitKeyboard() And OpenScreen(800,600,16,"")
    Repeat

      ClearScreen(0, 0, 0)
      
      If StartDrawing(ScreenOutput())
        DrawingMode(1)
        FrontColor(128, 255, 0)
        Locate(20,20) : DrawText("Just type some text...:")
        Locate(20,40) : DrawText(FullText$)
        StopDrawing()
      EndIf

      FlipBuffers()
     
      ExamineKeyboard()
      FullText$ + KeyboardInkey()  ; Add the new text to the current one (if any)
     
      ; If we press the 'Back' key, delete the last character
      ;
      If KeyboardReleased(#PB_Key_Back) 
        FullText$ = Left(FullText$, Len(FullText$)-1)
      EndIf

      ; Display the result
      ;
    Until KeyboardPushed(#PB_Key_Escape)
EndIf 
@ Num3: Yeah, I favour the way you propose too, but looking at the code, I can't see how it should realy change anything, except that there is a flip executed at the start of the code running. Could the fact that flipbuffers() is executed before or after the "jump" realy affect so much?
Codemonger
Enthusiast
Enthusiast
Posts: 384
Joined: Sat May 24, 2003 8:02 pm
Location: Canada
Contact:

Post by Codemonger »

I think Num3 was refering to good coding style ... Your Flip Buffers should be the last thing that happens because naturally it is the last you will do each frame (flip the frame). So its a simple sequence of events.

An example of simplifying the logic to see why FlipBuffers should be at the end, is to remove the loop. Then the code would make absolutely no sense having the flipbuffers at the beginning. It would flip nothing to the screen. But if we place it at the end and remove the loop .. it works. We have an image on the screen.
<br>"I deliver Justice, not Mercy"

    - Codemonger, 2004 A.D.
MadMax
Enthusiast
Enthusiast
Posts: 237
Joined: Mon Oct 06, 2003 11:56 am

Post by MadMax »

I think Num3 was refering to good coding style
Nothing to object then :D . I missunderstood the post.
Krylar
User
User
Posts: 88
Joined: Thu Apr 15, 2004 3:17 pm

Post by Krylar »

Heya,

I like that code layout better too. I snagged the code directly from the help file (look under "KeyboardInkey" to see it). Didn't help though :( Still flickers up top.

I quickly hacked in an FPS bit to the code and I'm running around 60fps.

Code: Select all

FPS_Timer = ElapsedMilliseconds()
FPS = 0
FPS_Counter = 0
FramesPerSecond.s = ""

If InitSprite() And InitKeyboard() And OpenScreen(800,600,16,"") 
    Repeat 

      ClearScreen(0, 0, 0) 
      
      If StartDrawing(ScreenOutput()) 
        DrawingMode(1) 
        FrontColor(128, 255, 0) 
        Locate(20,20) : DrawText("Just type some text...:") 
        Locate(20,40) : DrawText(FullText$) 
        FramesPerSecond = "FPS: " + Str(FPS)
        Locate(20,100) : DrawText(FramesPerSecond)
        StopDrawing() 
      EndIf 

      If ElapsedMilliseconds() > FPS_Timer + 1000
         FPS = FPS_Counter
         FPS_Counter = 0
         FPS_Timer = ElapsedMilliseconds()
      Else
         FPS_Counter = FPS_Counter + 1
      EndIf
      FlipBuffers() 
      
      ExamineKeyboard() 
      FullText$ + KeyboardInkey()  ; Add the new text to the current one (if any) 
      
      ; If we press the 'Back' key, delete the last character 
      ; 
      If KeyboardReleased(#PB_Key_Back) 
        FullText$ = Left(FullText$, Len(FullText$)-1) 
      EndIf 

      ; Display the result 
      ; 
    Until KeyboardPushed(#PB_Key_Escape) 
EndIf 
If my VSync was off I would be getting something monstrously higher than that, me thinks. :/

One thing that's certainly odd, though, if I put in a Delay(50) before the flip, there's no more flicker. Everything slows down, of course, but the flicker goes away.

-Krylar
Codemonger
Enthusiast
Enthusiast
Posts: 384
Joined: Sat May 24, 2003 8:02 pm
Location: Canada
Contact:

Post by Codemonger »

Hey thats funny i had 60fps in the last example i whipped up .. weird because my monitor refresh rate was set to 85 ... so if vsync was enabled my FPS should have been 85 .. I wonder if Fred implmented a frame cap to 60 FPS internally for compatibility reasons ... anyway i won't be home for another 3-4 hours ... this is gonna irritate me till then :?
<br>"I deliver Justice, not Mercy"

    - Codemonger, 2004 A.D.
Codemonger
Enthusiast
Enthusiast
Posts: 384
Joined: Sat May 24, 2003 8:02 pm
Location: Canada
Contact:

Post by Codemonger »

Hey wait .. looking at the code shouldnt your drawtext be after the Flip Buffers command ... because i believe drawtext is a GDI command and does not use the buffers .. simply draws on the DC directly.

Have a look at my post here, i have some code posted ...

viewtopic.php?t=11677
<br>"I deliver Justice, not Mercy"

    - Codemonger, 2004 A.D.
Krylar
User
User
Posts: 88
Joined: Thu Apr 15, 2004 3:17 pm

Post by Krylar »

Heya,

According to the help file on the DrawText setting: "The current output is set with StartDrawing()." And all the examples I've seen use DrawText inside the Starts/Stops.

For fun, I moved them out of the Start/Stop and just got a runtime error.

Good try though! :D

-Krylar
Codemonger
Enthusiast
Enthusiast
Posts: 384
Joined: Sat May 24, 2003 8:02 pm
Location: Canada
Contact:

Post by Codemonger »

The text should be in the
StartDrawing() and StopDrawing() ... what i was trying to say is that the drawtext (and the above commands for drawing the text) should be after FlipBuffers.

If the Drawtext draws to the DC or to the screen then the problem would look like this ...

Code: Select all


start loop 

clear back buffer screen 

draw text to the main screen (or the front buffer) 
' this text you would see appear on the mainscreen in realtime

FlipBuffers 

'this would flip the backbuffer (which you cleared) over the Front Buffer which has text but is now overwritten. You would catch a quick glimpse of the text

 
Anyway this is what might be happening .. so try placing all your text drawing code (make sure its only the text drawing stuff) after the flipbuffers.
<br>"I deliver Justice, not Mercy"

    - Codemonger, 2004 A.D.
Krylar
User
User
Posts: 88
Joined: Thu Apr 15, 2004 3:17 pm

Post by Krylar »

Gave that a shot, but it still happens.

Here's a descriptor of what I actually see:

The text doesn't flicker at all, but the top 30 pixels or so will show what looks like an application bar flicker in and out every so often. The rest of the screen seems to be fine, from what I can tell. But that top portion acts rather persnickety (yes, I said "persnickety").

So maybe it has something to do with the title bar specifically?

EDIT...note that I found this little bit from Fred in another thread:

"2) The VSync is always activated on PB."

I know some folks were thinking it may be VSync, but it looks like VSync is handled in PB.

...EDIT

Thanks for everyone's help here! :D

-Krylar
Last edited by Krylar on Mon Jul 26, 2004 4:34 pm, edited 1 time in total.
Post Reply