Discussion:
Problem with wxMemoryDC in wxCocoa and wxGTK
Fulvio Senore
2014-05-27 15:16:54 UTC
Permalink
I have a program that works correctly under Windows but not under OS
X/Cocoa and Linux.

The program is a panoramic viewer (something like Google Street View).
It draws many frames, as quickly as possible, to the screen when the
user "looks around".

The program creates each frame in a wxBitmap, then it draws it to the
screen with the following code:

wxClientDC dc( this );
dc.DrawBitmap( m_ViewerBitmap, 0, 0 );

This works well with all the operating systems.

Sometimes I need to draw a small image in certain locations of each
frame. Those are hotspots: clicking them the user can load another
image. The image is contained in a wxBitmap with an alpha channel.

In this situation I create each frame as usual, then I draw the hotspost
in the wxBitmap that contains the frame, then I draw the frame to the
screen. The only difference is that I draw the hotspots immediately
before drawing the bitmap to the screen.

To draw the hotspots I use code similar to the following:

wxMemoryDC mdc;
mdc.SelectObject( bmp );
mdc.DrawBitmap( m_HotspotBitmap, x, y, true );
mdc.SelectObject( wxNullBitmap );

This code works only under Windows. Under OS X the screen becomes gray
and I only see the hotspots. If I "move around" the hotspots draw lines
on the screen and I can see the image through those lines. It looks like
calling wxMemoryDC::SelectObject() creates a gray layer that hides the
underlying image, and that layer is erased by calling DrawBitmap() to
draw hotspots.

I have commented out some code to see what happens and I discovered that
it is enough to call
mdc.SelectObject( bmp );
to make the screen gray.

Under Linux things are similar, but instead of a gray screen I see the
last image created without drawing hotspost.

I feel like I am missing something obvious, but I cannot understand
where is the error.

May anybody tell me the correct way to do what I want?

Thanks in advance.

Fulvio Senore
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Stefan Csomor
2014-05-27 19:17:36 UTC
Permalink
Hi Fulvio

if possible you should only draw during a paint event, using wxPaintDCs
and if things have to be redrawn, invalidate the respective rectangle.
Have all information in the view's state, so that it can redraw itself
correctly and completely.

Best,

Stefan

-----Ursprüngliche Nachricht-----
Von: Fulvio Senore <***@fsoft.it>
Antworten an: "wx-***@googlegroups.com" <wx-***@googlegroups.com>
Datum: Dienstag, 27. Mai 2014 17:16
An: "wx-***@googlegroups.com" <wx-***@googlegroups.com>
Betreff: Problem with wxMemoryDC in wxCocoa and wxGTK
Post by Fulvio Senore
I have a program that works correctly under Windows but not under OS
X/Cocoa and Linux.
The program is a panoramic viewer (something like Google Street View).
It draws many frames, as quickly as possible, to the screen when the
user "looks around".
The program creates each frame in a wxBitmap, then it draws it to the
wxClientDC dc( this );
dc.DrawBitmap( m_ViewerBitmap, 0, 0 );
This works well with all the operating systems.
Sometimes I need to draw a small image in certain locations of each
frame. Those are hotspots: clicking them the user can load another
image. The image is contained in a wxBitmap with an alpha channel.
In this situation I create each frame as usual, then I draw the hotspost
in the wxBitmap that contains the frame, then I draw the frame to the
screen. The only difference is that I draw the hotspots immediately
before drawing the bitmap to the screen.
wxMemoryDC mdc;
mdc.SelectObject( bmp );
mdc.DrawBitmap( m_HotspotBitmap, x, y, true );
mdc.SelectObject( wxNullBitmap );
This code works only under Windows. Under OS X the screen becomes gray
and I only see the hotspots. If I "move around" the hotspots draw lines
on the screen and I can see the image through those lines. It looks like
calling wxMemoryDC::SelectObject() creates a gray layer that hides the
underlying image, and that layer is erased by calling DrawBitmap() to
draw hotspots.
I have commented out some code to see what happens and I discovered that
it is enough to call
mdc.SelectObject( bmp );
to make the screen gray.
Under Linux things are similar, but instead of a gray screen I see the
last image created without drawing hotspost.
I feel like I am missing something obvious, but I cannot understand
where is the error.
May anybody tell me the correct way to do what I want?
Thanks in advance.
Fulvio Senore
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.
or visit http://groups.google.com/group/wx-users
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Fulvio Senore
2014-05-27 20:01:23 UTC
Permalink
Post by Stefan Csomor
Hi Fulvio
if possible you should only draw during a paint event, using wxPaintDCs
and if things have to be redrawn, invalidate the respective rectangle.
Have all information in the view's state, so that it can redraw itself
correctly and completely.
Best,
Stefan
Hi Stefan,

thank you for the hint. At the moment I am mainly drawing in idle events
handling. My program works in a way similar to a video player: it has to
draw as many frames as possible to yield a smooth movement.
I thought that drawing during idle events, requesting more of them as
needed, was a good solution.
This happens while the user drags the mouse. Do you think that
constantly refreshing and updating the screen would be fast?

Anyway, I have discovered that just putting these two lines before
drawing the bitmap to the client DC:

wxMemoryDC mdc;
mdc.SelectObject( bmp );

is enough to get a gray window instead of the original content of the
bitmap. Do you think that this problem can be solved by drawing to a
paint DC?

Thank you.

Fulvio
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Vadim Zeitlin
2014-05-27 20:14:45 UTC
Permalink
On Tue, 27 May 2014 22:01:23 +0200 Fulvio Senore wrote:

FS> thank you for the hint. At the moment I am mainly drawing in idle events
FS> handling. My program works in a way similar to a video player: it has to
FS> draw as many frames as possible to yield a smooth movement.
FS> I thought that drawing during idle events, requesting more of them as
FS> needed, was a good solution.

It really isn't. You really need to call Refresh() and paint in your
EVT_PAINT handlers instead.

FS> This happens while the user drags the mouse. Do you think that
FS> constantly refreshing and updating the screen would be fast?

Yes.

Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
Fulvio Senore
2014-05-28 14:14:42 UTC
Permalink
Post by Vadim Zeitlin
FS> thank you for the hint. At the moment I am mainly drawing in idle events
FS> handling. My program works in a way similar to a video player: it has to
FS> draw as many frames as possible to yield a smooth movement.
FS> I thought that drawing during idle events, requesting more of them as
FS> needed, was a good solution.
It really isn't. You really need to call Refresh() and paint in your
EVT_PAINT handlers instead.
FS> This happens while the user drags the mouse. Do you think that
FS> constantly refreshing and updating the screen would be fast?
Yes.
I have changed my code and now I always draw to the screen inside an
EVT_PAINT handler. The program speed did not change in a noticeable way
so it is OK for me.

Unfortunately my problem is not solved. I still get a gray screen if I do

wxMemoryDC mdc;
mdc.SelectObject( bmp );

just before drawing bmp to the screen. Everything works fine if I do not
use those lines of code. This happens under Mac and Linux, Windows works
correctly.

How can those lines cause such an effect?

Fulvio
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Fulvio Senore
2014-05-30 20:14:38 UTC
Permalink
Post by Fulvio Senore
I have changed my code and now I always draw to the screen inside an
EVT_PAINT handler. The program speed did not change in a noticeable way
so it is OK for me.
Unfortunately my problem is not solved. I still get a gray screen if I do
wxMemoryDC mdc;
mdc.SelectObject( bmp );
just before drawing bmp to the screen. Everything works fine if I do not
use those lines of code. This happens under Mac and Linux, Windows works
correctly.
How can those lines cause such an effect?
I have been to reproduce the problem with a small change to the minimal
sample. I create a small bitmap filled with green color and I write it
to the screen.
Testing in OS X Mountain Lion if I select the bitmap in a wxMemoryDC the
bitmap is not shown any more.

Should I make the patch available somewhere or should I create a Trac
ticket?

Fulvio
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Stefan Csomor
2014-05-31 12:11:05 UTC
Permalink
Hi
Post by Fulvio Senore
Should I make the patch available somewhere or should I create a Trac
ticket?
please create a Trac ticket, attach the patch and assign it to me

Thanks,

Stefan
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Fulvio Senore
2014-05-31 15:00:45 UTC
Permalink
Post by Stefan Csomor
Hi
Post by Fulvio Senore
Should I make the patch available somewhere or should I create a Trac
ticket?
please create a Trac ticket, attach the patch and assign it to me
I created the ticket but I dad not find a way to assign it to you, sorry.

Thank you

Fulvio
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Loading...