flickering stuff if you dont Cls

BlitzMax Forums/BlitzMax Beginners Area/flickering stuff if you dont Cls

Najdorf(Posted 2005) [#1]
I have this chain simulator, which uses the usual cls+flip routine to draw the chain. If I avoid the Cls, it should leave the trace of the chain of course. however it looks that if the chain is moving fast enough, it leavesa "flickering" trace. Do you know about this-how can I fix it?


Perturbatio(Posted 2005) [#2]
to guarantee removal, you would probably have to flip/draw/flip/draw then update.

*EDIT*
Not that I can see a reason why you would want to do this.


Beaker(Posted 2005) [#3]
You can avoid it by copying the backbuffer to the frontbuffer instead of Flipping (or just write to the frontbuffer only - no Flipping or Cls). Not sure if you can do this in Max tho.


Najdorf(Posted 2005) [#4]
no you probably misunderstood: try running this on MAX



as you can see Cls is commented (on purpose), and the stuff flickers. why is that? (after running this version, try uncommenting Cls, you'll see that I just draw a string)

PS: you can grab the string with the mouse


Perturbatio(Posted 2005) [#5]
I don't see any flicker with that code, runs as smooth as wet stuff off a smooth sloped thing.


Najdorf(Posted 2005) [#6]
then probably theres a bug, because on my computer, the lines drawn in the previous frames, that are still there since I have not called Cls, flicker a LOT.

This in the version where I DONT call Cls, while in the version where I call it, no problem


dangerdave(Posted 2005) [#7]
I get 'flicker' as well without CLS.
(with CLS, it works fine.)

So Pertubatio,
you don't see multiple lines when it runs?
(don't move the mouse and let the 'chain' fall down to the bottom of the screen.
You don't see mulitple lines on the entire screen without CLS?


Hmmmm, is it another nvidia vs ati thing?


Najdorf(Posted 2005) [#8]
I have ATI too


Perturbatio(Posted 2005) [#9]
Of course I see multiple lines (as in each render displays over the top of the previous which is to be expected when you don't clear the screen), I just don't see flicker.


Najdorf(Posted 2005) [#10]
yep the "multiple lines" flicker on my screen, which is wierd since they arent touched by the code


xlsior(Posted 2005) [#11]
Yup, *major* flickering -- as if only displayed every other frame (ATI Radeon 9600Pro).

It looks like the screen is in interlace mode or something, except the line that got added in the last update doesn't flicker.

Noticed the same thing with my own programs too -- unless I either do a CLS or redraw the entire screen each frame, things will flicker tremendously.

Is there any way around this and 'reuse' the scame screenbuffer without needed to redraw everything all over again, but not run into this flicker issue?

Is this a bug? If so, it would be extremely helpful if it can be remedied.

I was doing some timing tests last night, and unfortunately noticed that I don't have much 'spare' graphics power -- if I increase the number of drawing operations per frame to about twice as many as I'm using now in a game I'm working on (I'll need some more for other operations), my framerate drops from 75 to ~30 on my Athlon 2500+ (using onboard video)

I would love to be able to cut down on the number of redraws necesary by not having to update unchanged portions of the screen...


skidracer(Posted 2005) [#12]
I think there needs to be a single buffered full screen mode, I assume windowed mode is not affected?


xlsior(Posted 2005) [#13]
I assume windowed mode is not affected?


Correct. I just tried that, and in windowed mode there is no flickering, just fullscreen mode.

If I add a 'delay 100' after the flip command to see things in 'slow motion', windowed and non-windowed mode do behave differently. In windowed mode, the 'old' lines appear completely static. In full-screen mode, the background lines appear to be in continual motion, like a large color-cycled animation.

It appears that it is alternating between two different backbuffers, each of which gets copied to the front in turn.

If there is no delay, this causes flickering since 'old' information is only redrawn every second frame.

A good example is the following:

Graphics 800,600,32,60
test=LoadImage ("test.jpg")

DrawImage (test,0,0)
WaitKey()
Flip
WaitKey()
Flip
WaitKey()
Flip
WaitKey()
Flip
WaitKey()
Flip

In windowed mode, this code shows the image continuously. In full screen mode, the screen changes between the image and a blank screen each time I press a key.

Definitely different behaviour on windowed vs. fullscreen -- is this a bug, or by design?

Some people claimed not to see any flickering in the original sample -- do they see the image disappear in full screen mode when they run the example code above?


tonyg(Posted 2005) [#14]
After the first 'waitkey' the image is displayed constantly. This is my laptop with S3 SuperGraphics.
Running in both windowed and fullscreen shows the same.
The rope didn't flicker either. I have a PC with 9800 Pro which I can try later.


PowerPC603(Posted 2005) [#15]
Could it be that BMax is forced to use the FrontBuffer when using windowed mode?
Or that the gfx card doesn't allow double buffering while in windowed mode, so that the frontbuffer and the backbuffer are actually "merged".

Using the first code example:
In windowed mode, the vertical space between the red lines (that are drawn first) is small, while in fullscreen mode the spacing is much bigger (if you take one frame only).

In fullscreen mode, If I would take 2 successive frames and merge them in a paint program, I would get the same result as only 1 frame in windowed mode.

So it appears that the front and backbuffer are merged on my system somehow, when using windowed mode.
But I cannot tell if the fault lies within BMax, or my gfx card or windows.

I didn't check the entire code, but if you're drawing only one line per game loop, it appears that, while it keeps the current frontbuffer, you're drawing one line to the backbuffer and that "flip" pastes the backbuffer over the frontbuffer, ignoring the black color (background) when using windowed mode.
So that it just adds the last line to the frontbuffer, instead of overwriting the entire buffer.

I hope this makes any sense.


ImaginaryHuman(Posted 2005) [#16]
In windowed mode there is still double buffering, but as you say, so long as it is supported which isn't necessarily the case. One way to know is to draw several things to the backbuffer and if they show up without a Flip there is no double buffering.

Also I agree, in double-buffering, if you are going to leave permanent results you have to draw everything to both buffers.


Dreamora(Posted 2005) [#17]
Perhaps you have activated tripple buffering in your graphic drivers. But I don't think this should lead to this type of problems as DX supports flipchains with far more "backbuffers" than only one.

perhaps your gpu or their opengl drivers?


Najdorf(Posted 2005) [#18]
Yeah it looks that there is a triple buffering going on.

dont bother with my example its overly complex, stick with xlsior's, its much more to the point

I was doing some timing tests last night, and unfortunately noticed that I don't have much 'spare' graphics power -- if I increase the number of drawing operations per frame to about twice as many as I'm using now in a game I'm working on (I'll need some more for other operations), my framerate drops from 75 to ~30 on my Athlon 2500+ (using onboard video)

be sure you are not using any math operations, particularly avoid "^" (but you can use x*x and sqrt(x)), that slowed my chain code 15 times

PS: how do you call window mode (in the windows beta)?


PowerPC603(Posted 2005) [#19]
I used this code:
Graphics 800,600,0
test1 = LoadImage("test1.jpg")
test2 = LoadImage("test2.jpg")
test3 = LoadImage("test3.jpg")
test4 = LoadImage("test4.jpg")



DrawImage(test1, 0, 0)
DrawImage(test2, 100, 100)

WaitKey()
Flip

WaitKey()
DrawImage(test3, 200, 200)
WaitKey()
Flip
WaitKey()
DrawImage(test4, 300, 300)

WaitKey()
Flip

WaitKey()
Flip

WaitKey()
Flip

When the program halts on the first WaitKey(), it shows nothing.
Then a Flip comes (when I press a button), then it shows the first 2 images.
This is correct for now.

Now it waits execution on the second WaitKey().
After a button-press, it still shows the first 2 images.
At the next Flip (another button-press), the third picture (that was drawn to the backbuffer), is simply added to the frontbuffer, while keeping the first 2 images.

Now it takes another 2 button-presses to add the fourth image to the frontbuffer.

So it really appears that the backbuffer is pasted onto the frontbuffer when a Flip is executed, ignoring the background color.

Really weird.


Najdorf(Posted 2005) [#20]
I guess that's ok: you are using window mode, and that one works. (You are not calling cls, so all the images are still there)

try this:

Graphics 800,600
DrawOval 100, 100,30,30
Flip 
WaitKey() 
DrawOval 200, 200,30,30
Flip 
WaitKey() 
Flip 
WaitKey() 
Flip 
WaitKey() 


It shows that when you draw something, then flip, then draw something else, it uses a different backbuffer to draw on, and alternates in flipping the 2 backbuffers on the screen.


xlsior(Posted 2005) [#21]
It shows that when you draw something, then flip, then draw something else, it uses a different backbuffer to draw on, and alternates in flipping the 2 backbuffers on the screen.


Yup, same thing I'm seeing. One oval, jumping around.

Clearly does show that it alternates between two backbuffers... Of course the real question is whether or not this is something that can be fixed, especially it if only applies to 'some' video cards...

But definitely something that needs to be addressed or at least people should be aware of, of code that may 'look fine' on a developers PC might be an epileptic-inducing nightmare on someone elses machine.


tonyg(Posted 2005) [#22]
I've tried this on my ATI 9800 Pro @ 4.11 (6490) and there doesn't appear to be any flicker.


PowerPC603(Posted 2005) [#23]
In fullscreen mode, the 2 ovals are jumping around, but when using windowed mode (add ",0" to the graphics command), the first one stays into view.
The second one is just "added" to the frontbuffer.


tonyg(Posted 2005) [#24]
Graphics 800,600,0
DrawOval 100, 100,30,30
Flip 
WaitKey() 
DrawOval 200, 200,30,30
Flip 
WaitKey() 
Flip 
WaitKey() 
Flip 
WaitKey() 

results in...
the first oval being drawn,
press a key,
the second oval is drawn,
press a key,
both ovals drawn,
press a key,
both ovals are drawn.


Najdorf(Posted 2005) [#25]
yeah thats what it SHOULD do, the problems are in fullscreen mode.


tonyg(Posted 2005) [#26]
Blimey, this is like Groundhog Day...
Graphics 800,600
DrawOval 100, 100,30,30
Flip 
WaitKey() 
DrawOval 200, 200,30,30
Flip 
WaitKey() 
Flip 
WaitKey() 
Flip 
WaitKey() 

results in...
the first oval being drawn,
press a key,
the second oval is drawn,
press a key,
both ovals drawn,
press a key,
both ovals are drawn.
(i.e. the same results windowed or fullscreen)


Najdorf(Posted 2005) [#27]
Tony, we are saying that on SOME computers (e.g. mine and xlsior's) there is this problem in FULLSCREEN mode. On some others (like yours) theres no problem, and in both window mode and fullscreen mode the right thing happens (what you described).


marksibly(Posted 2005) [#28]
Hi,

Najdorf, what machine are you using?

(ps: It's very useful for this sort of thing for people to include their system configurations in their sigs).


Najdorf(Posted 2005) [#29]
• Sony Vaio PCG-K33
• Processor
Mobile Intel® Pentium® 4 Processor 532 (3.06GHz, 1MB L2 Cache)1
• Operating System
Microsoft® Windows® XP Professional Edition
• Front Side Bus Speed
533MHz
• Chipset
ATI Radeonâ„¢ IGP 345M
• Integrated Wireless LAN
IEEE 802.11b/g2
• LCD
15.4� WXGA with XBRITE™ technology (1280x800)3
• Hard Drive
60GB (4200rpm)4
• Memory
512MB5 PC-2100 266MHz DDR (256MB x 2)(Expandable to 1GB Maximum)
• Graphics
ATI Radeonâ„¢ IGP 345M 64MB Video RAM (shared w/ Main Memory)
• Graphics Interface
VGA out


A very brief review of what happens follows:

If I run this code

Graphics 800,600
DrawOval 100, 100,30,30
Flip 
WaitKey() 
DrawOval 200, 200,30,30
Flip 
WaitKey() 
Flip 
WaitKey() 
Flip 
WaitKey() 


it draws the first circle, then the second one but the first one disappears (although I didnt call Cls), then every time I "flip" one circle disappears and the other one reappears, as if it was drawing on 2 different backbuffers and displaying them alternatively.

Happens only in fullscreen mode.

Happens also to xlsior, PowerPC603 and (maybe) dangerdave


Emmett(Posted 2005) [#30]
Same results as Najdorf in fullscreen mode only.
1st flip - oval 1 only
2nd flip - oval 2 only
3rd flip - oval 1 only
4th flip - oval 2 only


PowerPC603(Posted 2005) [#31]
Try this code:
Graphics 800,600

DrawOval 100, 100,30,30
Flip 
WaitKey() 

DrawOval 200, 200,30,30
Flip 
WaitKey() 

DrawOval 300, 300,30,30
Flip 
WaitKey() 

Flip 
WaitKey() 

Flip 
WaitKey()

Flip 
WaitKey() 

The first time, you will see the first oval.
The second time you will see the second one.
The third time, you will see the first one and the third one.
The fourth time you will see the second one.

When using windowed mode, each time there's an oval added to the frontbuffer.

The fullscreen mode behaviour should be happening in both cases, to my opinion.

Before the first flip, you draw an oval to the first backbuffer, which flips into view at the first flip.
Then the second oval is drawn to the second backbuffer (which was previously the frontbuffer) and flips into view at the second flip.
Now the first backbuffer is used again to add the third oval to it.
Flip it into view, and you see the first and third oval.
Another flip will flip the second backbuffer into view, which had only the second oval drawn onto it.

This is what should be happening in both cases, AFAIK.


tonyg(Posted 2005) [#32]
Do people want to start adding their machine specs as Mark suggested?


{cYan|de}(Posted 2005) [#33]
thats not exactly the best way ive ever seen of drawing chain lol o_O


xlsior(Posted 2005) [#34]
Interesting --

As mentioned above, some video cards (including mine)appear to be alternating between *two* backbuffers instead of using just one, resulting in flickering on those systems if you draw some background items just once. (See the example of the moving ovals above)

Now, on my own computer I could address this flicker issue by drawing a (static) background twice, flipping after each draw, so both backbuffers ended up with a copy, and then leave it alone from that point forward -- the result was a stable picture, no flicker.

Now, theorethically this (drawing twice) should be stable on both systems using one, and two backbuffers...

Unfortunately I ran into another exception:

This ran OK on both my own system (which uses two backbuffers), my secondary computer (which seems to use one), but when I tested it on a 3rd machine (2.7 GHz E-Machine, some integrated onboard video controller) it was still flickering like crazy.

Now, this is very weird...

I'm not doing anything special on certain frames, each loop the exact same graphic draw functions are called. All pure blitz, no direct OpenGL stuff.

The only things I can think of:

- Maybe it uses two backbuffers, one of which automatically erases itself? (possibly a driver bug/feature?)

- Maybe it uses more than two backbuffers? (A bit unlikely I think, especially since the flickering looks like it drops every other frame. If it would draw 2/3 or so, it should appear less transparent, more 'solid'.

Hopefully I can figure out what video chipset it's using, that info that may lead to some more pointers... In the meantime, this is a bit of an unfortunate turn of events since it appears that I still can't count on graphics remaining on the screen even after drawing them twice...

It looks like I may have to look into adding a 'compatibility mode' to the game I'm working on: Give the choice betweeb drawing just twice (faster), or draw the full background each frame.

Unfortunately doing so gives me about 3/4 of the framerate I can get without redrawing the background, which can be significant on a mid range computer system

No idea how widespread of an issue this is though, maybe/hopefully it's just an isolated issue.

I also vaguely remember reading something about how some OpenGL cards never save the backbuffer information, en always require a full redraw... Is this true, or am I imagining things? :-)


Shambler(Posted 2005) [#35]
I've found this for those people with ATI (like me)

Right click desktop
Click Properties
>Advanced
>3D
>OpenGL
>Compatibility

from here you can enable/disable triplebuffering.

Disabled = flicker
Enabled = No flicker.


xlsior(Posted 2005) [#36]
Yup, confirmed the problem:

On the e-Machine, I need to draw and flip to the backbuffer three times for it to be stable, otherwise it will flicker. It appears to rotate through three seperate backbuffers. (Quad-buffering?) The video adapter in question identifies itself as an 'Intel(R) 82845G/GL/GE/PE/GV Graphics Controller'

So... That's 4 machines I've tested on so far, and those included a system with one backbuffer, 2 systems with two backbuffers, and a system with three backbuffers.

Is there any way for a program to find out in advance how many backbuffers a card is using, so I can use the appropriate drawing routines for the system in question?

Many of the blitzmax samples I've seen come by in the past all appear to assume the single backbuffer, which are bound to run into problems with flickering on many computer systems once they start hitting the big masses...


teamonkey(Posted 2005) [#37]
From another thread:

The contents of a backbuffer is undefined after a Flip. It might be black, it might be left untouched or it might be full of whatever temporary data the card's decided to store in it after the Flip. You can't assume that it will keep the contents of the last draw cycle.

This is standard OpenGL behaviour. your graphics card could use single buffering, double buffering, triple buffering or something completely off the wall. If you want to keep the previous frame you should copy it to an ofscreen buffer somewhere.


xlsior(Posted 2005) [#38]
The contents of a backbuffer is undefined after a Flip. It might be black, it might be left untouched or it might be full of whatever temporary data the card's decided to store in it after the Flip. You can't assume that it will keep the contents of the last draw cycle.


This is something that really should be in the docs, since it's pretty essential info and is far from obvious on many systems... And looking at many code examples posted on these forums over time, many people do assume that the contents will remain.

Anyway, that means I'll have to default to redrawing everything each frame then, if that's the only way to know for sure the contents will be there.

I guess I can build in some user-configurable settings where the user can turn off the full redraw to get a framerate boost, with a chance of it inducing flickering (or black background) on certain systems. Perhaps monitor the FPS, and only bring up the option if it looks like framerate might be an issue.


teamonkey(Posted 2005) [#39]
It's something that trips up loads of people coming from a software rendering background. I know it certainly tripped me up.

I can't quite remember how I got around it, but I think I used glCopyPixels, glDrawBuffer and glReadBuffer to copy the contents of one frame to an offscreen area of video memory and back.


xlsior(Posted 2005) [#40]
Well, in my current project the static background in question affects only about 20% of my screen, drawn as a border around a playing field...

So, considering the info above, I've made some changes to my drawing routines. I ended up just redrawing the border itself, after chopping up all four borders into several animimages sized in varying 'power-of-2' chunks as not to have too much overhead.

One strip of 64x64 pixel tiles on the top of the screen, another 32x32 pixel strip on top as well, and some 32x32 strips for the sides and bottom of the screen.

I did some tests, and found that it draws all those individual tiles in much less time than it would take to redraw the entire 800x600 background as a whole in one pass. I'll probably do some other tests to see if different subdivisions are more or less efficient.

As far as openGL textures/images are concerned: I read that internally it uses power-of-two sized textures to store them -- but does anyone know if these are stored as squares, or can they also be used as rectangles on all cards?
e.g. is 512x128 a valid size on all video cards, or would some of them store it as 512x512 internally?


teamonkey(Posted 2005) [#41]
As far as openGL textures/images are concerned: I read that internally it uses power-of-two sized textures to store them -- but does anyone know if these are stored as squares, or can they also be used as rectangles on all cards?

Rectangles are fine, so 512x128 is a valid texture size on any OpenGL card.


xlsior(Posted 2005) [#42]
Rectangles are fine, so 512x128 is a valid texture size on any OpenGL card.


Thanks, I ended up going with that rather than the smaller tiles for a convenience sake, although I didn't see any speed difference between using these larger textures and the tiny versions, as long as the dimensions were both in power-of-2 ranges.


McFox(Posted 2005) [#43]
Hmpf this problem is very annoying...
Can it be corrected (so, is it just a bug ?)
That's strange... windowed mode has no problem... why the buffers are managed differently in fullscreen ? :/