Archived

This topic is now archived and is closed to further replies.

Some Observations on the Window

This topic is 4996 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I think this should apply to all programs developed with the basecode. It is kind of a coincidence actually that I found it: if you move the screen off the screen a little, minimize and restore it, the graphics will stop updating unless you drag the window back off the edge. Also you can''t use MoveWindow to resize the window to a smaller size. Otherwise there is some repaint error in the region where the original window should be. Any ideas for improvements? Cheers Singulab

Share this post


Link to post
Share on other sites
This is an OS limitation - Windows does automatic clipping of surfaces that aren''t visible. Pretty straightforward - how else would you imagine it''d be possible to have 10+, 100+ windows open at a time.

AFAIK, process execution is suspended as far as OpenGL drawback goes while the window is being dragged. Here''s the technical explanation: for any generic window, Windows does the drawing internally (through GDI), which guarantees that up to n times a second each window that is physically visible is redrawn. However, user-drawn windows only update:

1) when the WM_PAINT and its relatives (WM_NCPAINT, etc) messages are handled
2) when the process is running and something causes the window to be periodically updated (generic OpenGL, DirectX, your own API-based, or a similar GDI-based application)

If you drag an OpenGL window, you''ll notice that the frame of the window as well as the non-client area (the caption bar as well as any buttons on it) are redrawn as you move the window in and out of the visible area (off-screen or behind another, say an always-on-top window). This happens because Windows manages this stuff internally and guarantees that, if an application is functioning properly, its user interface will be drawn whenever needed - not constantly, but whenever needed.

If you did a little test and handled the WM_PAINT message as well in your OpenGL application, you''d notice that it only is called when some (any) kind of clipping is done on the client area of the window (the area in which your GL scene is rendered). If you were to respond to this message and draw the non-clipped portion of the screen every time WM_PAINT is sent, you''d not have this weird effect. That could, however, potentially cause your computer to stall as tens upon tens of these insignificant messages are sent to your application every second and you try to respond to them.

In other words, it''s easier to ignore this little detail.




TCP - Transmission by Carrier Pigeons

Share this post


Link to post
Share on other sites
snisarenko -

It is Lesson01.


Crispy -

It is pretty much of a curiosity because it does not matter which side you go out of - even by only one pixel. And even if you just let the window lie there. Implication: position your windows really carefully (either you or the user), or the user will be completely bewildered as to why your program does not update.

The strange point is that interception is done every loop, events are properly handled and SwapBuffers() follows. Windows should force-update it should it not?

I am not sure if WM_PAINT should be used instead. If you look at Celestia (also in OpenGL), WM_PAINT is handled instead. Still if you try to move it off a bit, press the up arrow, and you see no change. Move it back, the camera is rotated (so it really intercept messages). Weird.

Share this post


Link to post
Share on other sites
I''m not following you - if the window does not update while partially concealed and not being dragged, then the code sucks - that is, unless the code doesn''t update the frame buffer while the window is not active and the window also happens to be inactive (don''t know if this is the case for lesson 1).

The moral of the story: graphics API''s perform 20% better and with 20% less hassle in fullscreen. Period.




TCP - Transmission by Carrier Pigeons

Share this post


Link to post
Share on other sites
- singulab
I think you modified something in lesson 1 windows code, because I am not getting any of the symptoms you are describing when running lesson 1. Besides lesson 1 is old. Try one of the basecodes that you can download on the left menu of his main page


- crispy
About the WM_PAINT. I don't think windows continuously sends thousands of these messages to the window(program). It only sends the WM_PAINT when the window has been moved or resized. And when the window is not moving or being resized the messeage is not sent. I think the whole point of WM_PAINT is to let the window know that it needs to refresh after there have been modifications to the window either position or size and let the programmer decide what to do at that moment.

[edited by - snisarenko on April 6, 2004 6:20:00 PM]

[edited by - snisarenko on April 6, 2004 6:20:48 PM]

Share this post


Link to post
Share on other sites
Two points to note: first, not just partially concealed. It continues to update behind other windows but not beyond the edges. (Again, try it out and you will see.) Second, Celestia receives WM_PAINT as often as you could figure out . But there is no performance problem.

snisarenko -
I don''t know if it is just the problem of my Windows 98. At least it affects all OpenGL programs. I haven''t tried out DirectX yet.

Share this post


Link to post
Share on other sites
quote:
Original post by snisarenko
- crispy
About the WM_PAINT. I don''t think windows continuously sends thousands of these messages to the window(program). It only sends the WM_PAINT when the window has been moved or resized. And when the window is not moving or being resized the messeage is not sent. I think the whole point of WM_PAINT is to let the window know that it needs to refresh after there have been modifications to the window either position or size and let the programmer decide what to do at that moment.



You think correctly. However, this is also what I said. I never said windows polls the WM_PAINT or any other messages (well, except maybe for WM_TIMER) periodically - the problem arises when you slowly move the window concealing parts of the client area, in which case Windows will do its best to keep that portion of the window updated, perhaps sending you 80-100 WM_PAINT''s a second. With >10-15 ms/frame you''ll create quite a jumpy effect as you''re not capable of updating the window as often.

>> It continues to update behind other windows but not beyond the edges.

That''s because Windows does the clipping, not OpenGL - I think I said this before. That''s why you''re effectively using a device context to manage rendering to a window, rather than a direct buffer.

>> Second, Celestia receives WM_PAINT as often as you could figure out . But there is no performance problem.

1) What the heck is Celestia (yes, I understand it''s a basecode of some sort, in which case, if it''s open-source, why don''t you just have a look at it)?
2) The first sentence doesn''t make any sense without more background information. You can force-update a window (or portions of it) by calling InvalidateRect() with appropriate arguments. The reason there is no performance problem is most probably due to a framerate normalizer (or limiter, depending on how you look at it) - a new frame is drawn only as often as physically feasible. This requires some heuristics, but can be implemented quite easily.






TCP - Transmission by Carrier Pigeons

Share this post


Link to post
Share on other sites
quote:
Original post by Crispy
That's because Windows does the clipping, not OpenGL - I think I said this before. That's why you're effectively using a device context to manage rendering to a window, rather than a direct buffer.


I mean part of it is not concealed and yet it does not update. One don't expect to enter text in Notepad slightly off the edge and receives nothing visible at all in the non-hidden area. That is why it is strange - and can be dangerous if your game is really serious (Diablo players even fear the Windows key).

quote:

1) What the heck is Celestia (yes, I understand it's a basecode of some sort, in which case, if it's open-source, why don't you just have a look at it)?


Oh my goodness it is not a basecode. It is a great space program at www.shatters.net/celestia/. Open source.

quote:

2) The first sentence doesn't make any sense without more background information. You can force-update a window (or portions of it) by calling InvalidateRect() with appropriate arguments. The reason there is no performance problem is most probably due to a framerate normalizer (or limiter, depending on how you look at it) - a new frame is drawn only as often as physically feasible. This requires some heuristics, but can be implemented quite easily.


Well I kind of "Spy++"ed on it and you find WM_PAINT flooding. In one minute, it gives me 699 WM_PAINT P WM_PAINT hdc:00000000. If I keep it busy by pressing a key it gives ~1730 messages. On the other hand Lesson01 has no WM_PAINT at all.

EDIT: 1730 messages include WM_KEYUP and such.

Managed a test on Baldur's Gate I too: no such mentioned problem. What's more: it does not receive WM_PAINT.

[edited by - singulab on April 7, 2004 8:55:26 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by snisarenko
- singulab
I think you modified something in lesson 1 windows code, because I am not getting any of the symptoms you are describing when running lesson 1. Besides lesson 1 is old. Try one of the basecodes that you can download on the left menu of his main page


Tried out nehegl latest and the rotating triangle-something just stopped to do so once the window is slightly off screen.

EDIT: BTW I can't figure out much difference between Lesson01 anyway. Logic and principles remain the same.

[edited by - singulab on April 7, 2004 9:09:21 AM]

Share this post


Link to post
Share on other sites
Well since I am running win2k and lesson 1 is not showing the symptoms you describe, I am gonna have to assume its something to do with win98

Try to run the same programs you are runing on you win98 on a win2k.

P.S. I guess there were quite a lot of revision in the GUI since win98

Share this post


Link to post
Share on other sites