Real Software Forums

The forum for Real Studio and other Real Software products.
[ REAL Software Website | Board Index ]
It is currently Tue Oct 17, 2017 9:12 pm
xojo

All times are UTC - 5 hours




Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 6:24 am 
Offline

Joined: Wed Nov 30, 2005 8:22 pm
Posts: 227
Location: L.I., New York
I have 6 canvases in an array (0-5) and I want to properly draw to them without using the Backdrop property as I am told that it is not to proper way to draw to the canvas.

One of the canvases (number 2 in the array) will be animated to display randomly blinking eyes. I already have the needed images to display that but I would like some code example on how to properly do this using the DoubleBuffer property of the canvas.

I know the EraseBackground should be set to false, but as I understand you have to keep telling the canvas to turn off the EraseBackground as it defaults to true when you call the Refresh method of the canvas.

I would appreciate some example code for the paint event and how to change the animated image when it gets changed keeping in mind that I have the DoubleBuffer property of the canvas set to true.

Thanks.

EDIT: I forgot to mention that the images I am working with are 256 x 256.


Top
 Profile  
Reply with quote  
 Post subject: Re: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 8:07 am 
Offline
User avatar

Joined: Sun Aug 05, 2007 10:46 am
Posts: 4931
Location: San Diego, CA
What platform?

If you are using predefined images (as opposed to things like DRAWLINE, DRAWRECT).... just use DRAWPICTURE in the PAINT event (forget about the background)
If you are using discrete draw commands, then do it to another PICTURE object, and then still use DRAWPICTURE

On OSX this can be done at an acceptable framerate with no flickering at all... without using Doublebuffering yourself.

_________________
Dave Sisemore
iMac I7[2012], OSX Mountain Lion 10.8.3 RB2012r2.1
Note : I am not interested in any solutions that involve custom Plug-ins of any kind


Top
 Profile  
Reply with quote  
 Post subject: Re: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 9:08 am 
Offline

Joined: Wed Nov 30, 2005 8:22 pm
Posts: 227
Location: L.I., New York
DaveS wrote:
What platform?

If you are using predefined images (as opposed to things like DRAWLINE, DRAWRECT).... just use DRAWPICTURE in the PAINT event (forget about the background)
If you are using discrete draw commands, then do it to another PICTURE object, and then still use DRAWPICTURE

On OSX this can be done at an acceptable framerate with no flickering at all... without using Doublebuffering yourself.


Windows and Mac OS X.

What you stated is Greek to me.


Top
 Profile  
Reply with quote  
 Post subject: Re: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 9:59 am 
Offline

Joined: Wed May 20, 2009 11:02 am
Posts: 423
There are two possibilities for double buffering, the first one is given by RS and/or the OS, and then you can do the double buffering yourself.

What Dave meant is that if you are using pictures in your canvases (as opposed to drawing lines, ovals, ... into the canvases) you can directly use the DrawPicture function of the graphic object of the Paint event in each canvas. You will get good results on Mac and probably also on Windows, although there could be some flickering omn Windows (look for flickering in the forum). Set DoubleBuffer to true and RB and/or the OS will take care of it.

On the other hand, if what you are drawing to those canvases is composed of lines, ovals, pixels,... then you need to do extra double buffering to improve the outcome (in terms of flickering and visual glitches). Then, instead of directly drawing individually the lines, ovals, pixels,... to the graphic object of the paint event of the canvas, it is better to draw them to another picture, and once that picture contains all you want on your canvas, draw the content of that picture on the canvas using DrawPicture in the paint event.

Pixe

_________________
Using RS2011r4.3 on Windows7.


Top
 Profile  
Reply with quote  
 Post subject: Re: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 12:16 pm 
Offline

Joined: Wed Nov 30, 2005 8:22 pm
Posts: 227
Location: L.I., New York
pixe656 wrote:
There are two possibilities for double buffering, the first one is given by RS and/or the OS, and then you can do the double buffering yourself.

What Dave meant is that if you are using pictures in your canvases (as opposed to drawing lines, ovals, ... into the canvases) you can directly use the DrawPicture function of the graphic object of the Paint event in each canvas. You will get good results on Mac and probably also on Windows, although there could be some flickering omn Windows (look for flickering in the forum). Set DoubleBuffer to true and RB and/or the OS will take care of it.

On the other hand, if what you are drawing to those canvases is composed of lines, ovals, pixels,... then you need to do extra double buffering to improve the outcome (in terms of flickering and visual glitches). Then, instead of directly drawing individually the lines, ovals, pixels,... to the graphic object of the paint event of the canvas, it is better to draw them to another picture, and once that picture contains all you want on your canvas, draw the content of that picture on the canvas using DrawPicture in the paint event.

Pixe


I learn by example code.

I have pre-done images that I am using.

EDIT: There seems to be an issue in Windows. If the DoubleBuffer property is true, any image masks I am using get discarded and replaced with white.

EDIT2: I have partially figured out how to draw using the paint event but I can't figure out how to draw a new picture outside the paint event.


Top
 Profile  
Reply with quote  
 Post subject: Re: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 4:59 pm 
Offline

Joined: Wed May 20, 2009 11:02 am
Posts: 423
ccfman2004 wrote:
I learn by example code.

Search the forums ("canvas double buffer" should be ok, I guess) and you will find it. I don't have any code to post, I am just saying what I have read in several other threads.

ccfman2004 wrote:
I have pre-done images that I am using.

Then, probably you will not need to do any extra double buffering yourself. Just draw those pictures on the canvas in the paint event.

ccfman2004 wrote:
EDIT: There seems to be an issue in Windows. If the DoubleBuffer property is true, any image masks I am using get discarded and replaced with white.

Sorry, I can't help you with this.

ccfman2004 wrote:
I can't figure out how to draw a new picture outside the paint event.

You shouldn't need it because you are using already made pictures. However, if you would like to know how to do it:

Add a picture-property to the canvas (or window holding the canvas) and in the Open event instantiate it:
MyTempPic = new MyPicProperty(WidthOfTheCanvas, HeightOfTheCanvas, DepthOfTheCanvas)


Now you need to paint all the stuff (ovals, lines, text, pixels, ... whatever you want on the final canvas) on MyTempPic. Do this in any method of your code, but not in the Paint event. Once this is done "Refresh" the canvas. This will fire the Paint event of the canvas where you will draw that picture on the canvas:
g.DrawPicture MyTempPic, 0, 0

You just need that single line of code in the Paint event.

There might be mistakes in the "code", but that's the general idea. Again, search for other threads as this topic has been treated several times.

Pixe

_________________
Using RS2011r4.3 on Windows7.


Top
 Profile  
Reply with quote  
 Post subject: Re: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 5:42 pm 
Offline

Joined: Wed Nov 30, 2005 8:22 pm
Posts: 227
Location: L.I., New York
One of the canvases is going to have an animation as I said.

I don't understand how to change the picture at will.

Drawing the picture once at the start of the game is one thing, but changing it when I need it to change is another.


Top
 Profile  
Reply with quote  
 Post subject: Re: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 5:51 pm 
Offline

Joined: Wed May 20, 2009 11:02 am
Posts: 423
Use a Timer, in which you can draw the picture you are going to show next on MyTempPic and then call Canvas.Refresh.

Pixe

_________________
Using RS2011r4.3 on Windows7.


Top
 Profile  
Reply with quote  
 Post subject: Re: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 5:55 pm 
Offline

Joined: Wed Nov 30, 2005 8:22 pm
Posts: 227
Location: L.I., New York
The canvases I have are set up in an array. Does that complicate things?

I still have the problem in Windows with the DoubleBuffer property causing the picture to loose its mask.

EDIT: WOW does Windows suck. I have no issues in Mac OS X with drawing each image to may canvas array using the Paint event. Windows, on the other hand, is a mess. Even though I only call refresh to a specific canvas in the array, Windows simply draws the last image I used to all 6 canvases.


Last edited by ccfman2004 on Thu Aug 11, 2011 6:14 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 6:12 pm 
Offline

Joined: Wed May 20, 2009 11:02 am
Posts: 423
Quote:
The canvases I have are set up in an array. Does that complicate things?


Not at all, in the timer refer to the canvas you need to refresh only: MyCanvasArray(2).Refresh

_________________
Using RS2011r4.3 on Windows7.


Top
 Profile  
Reply with quote  
 Post subject: Re: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 6:14 pm 
Offline

Joined: Wed Nov 30, 2005 8:22 pm
Posts: 227
Location: L.I., New York
pixe656 wrote:
Quote:
The canvases I have are set up in an array. Does that complicate things?


Not at all, in the timer refer to the canvas you need to refresh only: MyCanvasArray(2).Refresh


Only problem is that Windows refreshes ALL canvases in the array for some reason and uses the last image in the imgTmp I set up


Top
 Profile  
Reply with quote  
 Post subject: Re: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 6:29 pm 
Offline

Joined: Wed May 20, 2009 11:02 am
Posts: 423
Quote:
Only problem is that Windows refreshes ALL canvases in the array for some reason and uses the last image in the imgTmp I set up


I just put together a test project with a canvas array and only one canvas is refreshed. Something is wrong in your code.

I am using RS2011r2 on Windows 7, by the way.

Pixe.

_________________
Using RS2011r4.3 on Windows7.


Top
 Profile  
Reply with quote  
 Post subject: Re: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 8:03 pm 
Offline

Joined: Wed Nov 30, 2005 8:22 pm
Posts: 227
Location: L.I., New York
pixe656 wrote:
Quote:
Only problem is that Windows refreshes ALL canvases in the array for some reason and uses the last image in the imgTmp I set up


I just put together a test project with a canvas array and only one canvas is refreshed. Something is wrong in your code.

I am using RS2011r2 on Windows 7, by the way.

Pixe.


Can I see your test code?

I am also using Windows 7 x64 with RS2011r2.

The strange thing is that the code works perfectly fine in Mac OS X 10.6.8.


Top
 Profile  
Reply with quote  
 Post subject: Re: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 10:01 pm 
Offline

Joined: Fri Jan 06, 2006 3:21 pm
Posts: 12388
Location: Portland, OR USA
pixe656 wrote:
Something is wrong in your code.

I agree completely.

ccfman2004 wrote:
The strange thing is that the code works perfectly fine in Mac OS X 10.6.8.

That's probably a fluke. Sometimes you get lucky and faulty code seems to work.

I've heard this same scenario several times, and each time it's been an error in the code.

You can call Refresh(false) to prevent the canvas from erasing its background.


Top
 Profile  
Reply with quote  
 Post subject: Re: Properly drawing to canvas with double buffering
PostPosted: Thu Aug 11, 2011 10:23 pm 
Offline

Joined: Wed Nov 30, 2005 8:22 pm
Posts: 227
Location: L.I., New York
timhare wrote:
pixe656 wrote:
Something is wrong in your code.

I agree completely.

ccfman2004 wrote:
The strange thing is that the code works perfectly fine in Mac OS X 10.6.8.

That's probably a fluke. Sometimes you get lucky and faulty code seems to work.

I've heard this same scenario several times, and each time it's been an error in the code.

You can call Refresh(false) to prevent the canvas from erasing its background.


That's part of my code. I already have Refresh(false).

I even changed the code slightly with the same results.

At first I was using a For Next loop to add the images to the canvases. Then I removed the For Next loop and did each canvas separately.

I still can't figure out why Windows disregards the mask I am using if I set the DoubleBuffer property to true.

p = PNGStringToPictureMBS(DecodeBase64(rs.Field("Pic0")),0)
imgTmp = p.HMirrorMBS
imgTmp.Mask = p.Mask.HMirrorMBS
imgCanvas(0).Refresh(False)

p = PNGStringToPictureMBS(DecodeBase64(rs.Field("Pic1")),0)
imgTmp = p.HMirrorMBS
imgTmp.Mask = p.Mask.HMirrorMBS
imgCanvas(1).Refresh(False)

p = PNGStringToPictureMBS(DecodeBase64(rs.Field("Pic2")),0)
imgTmp = p.HMirrorMBS
imgTmp.Mask = p.Mask.HMirrorMBS
imgCanvas(2).Refresh(False)

p = PNGStringToPictureMBS(DecodeBase64(rs.Field("Pic3")),0)
imgTmp = p.HMirrorMBS
imgTmp.Mask = p.Mask.HMirrorMBS
imgCanvas(3).Refresh(False)

p = PNGStringToPictureMBS(DecodeBase64(rs.Field("Pic4")),0)
imgTmp = p.HMirrorMBS
imgTmp.Mask = p.Mask.HMirrorMBS
imgCanvas(4).Refresh(False)

p = PNGStringToPictureMBS(DecodeBase64(rs.Field("Pic5")),0)
imgTmp = p.HMirrorMBS
imgTmp.Mask = p.Mask.HMirrorMBS
imgCanvas(5).Refresh(False)


I have the images stored in a database as a B64 encoded string.

This is the code in the Paint Event for the Canvas array.
g.DrawPicture imgTmp,0,0

What am I doing wrong?

EDIT: It appears the Windows handles the Paint event differently than Mac OS X. It seems even if I call refresh(false) to one specific canvas in the array, ALL canvases in the array get refreshed.

Another interesting issue. It seems that Windows constantly refreshes ALL canvases in the array, even if I don't call Refresh. The second I change the imgTmp, every canvas in the array get refreshed with that new image.

EDIT2: I am at a complete loss as to why Windows is refreshing the canvases whether I call Canvas.Refresh(False) or not.

EDIT3: There is definitely something funky going on in Windows. I set up a PushButton that erases imgTmp and refreshes one of the canvases. Guess what happened? NOTHING. The canvas did not refresh.

It works as expected in Mac OS X, but not in Windows.

EDIT4: If I put the DrawPicture code into a method and call the method with a PushButton, Windows properly draws the images to the canvases. If I call that Method using the Open event of the form, Windows draws the last image I used to all Canvases in the array. It makes no sense.

If anyone has any ideas as to what is going on, be my guest and help me out.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group