I have an application with an OpenGL window as a child window of the main window.
When I display a dialog box above the OpenGL window, it doesn't get drawn. It's like it's not getting WM_PAINT messages. If I can guess the title bar position of the dialog box, I can drag it and it's still responsive.
I realise this might be a vague question, but I was wondering if anyone else has seen this sort of behaviour before and knew of a solution?
I wondered if the Pixel Format Descriptor would make a difference - I had PFD_DRAW_TO_WINDOW, but changing to PDF_DRAW_TO_BITMAP didn't make any difference. I'm not sure what else I should be looking at?
Bugger. Should have given all the details. I was running Windows in a virtual machine on Mac OS X using Parallels. I upgrade from Parallels 3 to 4 and now everything is working fine. I suspect a Parallels video driver issue.
Thanks to all those who answered with suggestions.
Is your opengl window constantly rendering. It is possible that the 3D hardware is simply rendering into an overlay that is overdrawing your dialog box. If you position the dialog box so it overlaps your main window, can you see some of it?
Try to pause rendering into the main display to see if it effects the results.
You will also need to make sure that your window style ensures the results are clipped...
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
You should check though all the items mentioned in this MSDN article, as it covers a lot of the basics for getting opengl rendering in a window correctly.
http://msdn.microsoft.com/en-us/library/ms970745.aspx
You may need to switch overlay off. It can be done via forcing back buffer presenting method to copy instead of swap.
Use wglChoosePixelFormatARB and one of parameters should be
WGL_SWAP_METHOD_ARB with value WGL_SWAP_COPY_ARB
This may seems stupid but are you sure your OpenGL window is not flagged "topmost" ?
Does the dialog box disappear also behind borders of your window or just behind the OpenGL rendering rectangle ?
Related
I have a wxWidgets application that has a number of child opengl windows. I'm using my own GL canvas class, not the wx one. The windows share their OpenGL context.
I don't think the fact it is wxwidgets is really relevant here.
The opengl windows are children of a windows that are siblings of one another, contained within a tab control. Kind of an MDI style interface, but it is not an MDI window.. Each one can be individually resized. All works lovely unless Aero is enabled and the DWM is active.
Resizing any window (not even the opengl ones) causes all of the opengl windows to flicker occasionally with a stale backing-store view that contains whatever rubbish has been on the screen at that point that is not opengl. This ONLY happens with Aero enabled.
I'm pretty certain that this is the DWM not actually having the opengl contents on its drawing surface backing store and the window not being repainted at the right moment.
I've tried so many things to get round this, I do have a solution but it is not very nice and involves reading the framebuffer with glReadPixels into a DIB and then blitting it to the paint DC in my onPaint routine. This workaround is only enabled if DWM is active but I'd rather not have to do this at all as it hurts performance slightly (but not too bad on a capable system - the scenes are relatively simple 3d graphs). Also mixing GDI and opengl is not recommended but this approach works, surprisingly. I can live with it for now but I'd rather not have to. I still have to do this in WM_PRINT if I want to take a screenshot of the child window anyway, I don't see a way around that.
Does anyone know of a better solution to this?
Before anyone asks I definitely do the following:
Window class has CS_OWNDC
WM_ERASEBACKGROUND does nothing and returns TRUE.
Double Buffering is enabled.
Windows have the WS_CLIPSIBLINGS and WS_CLIPCHILDREN window styles.
In my resize event handler I immediately repaint the window.
I've tried:
Setting PFD_SUPPORT_COMPOSITION in the pixel format descriptor.
Not using a wxPaintDC in the paint handler and calling
::ValidateRect(hwnd, NULL) instead.
Handling WM_NCPAINT and excluding the client area
Disabling NC paint via the DWM API
Excluding the client area in the paint event
Calling glFlush and/or glFinish before and after the buffer swap.
Invalidating the window at every paint event (as a test!) - still
flickers!
Not using a shared GL context.
Disabling double buffering.
Writing to GL_FRONT_AND_BACK
Disabling DWM is not an option.
And as far as I am aware this is even a problem if you are using Direct3D instead on OpenGL, though I have not tested this as it represents a lot of work.
This is a longshot, but I just solved exactly this same problem myself.
The longshot part comes in because we're doing owner draw of the outline of a captionless group box that surrounds our OpenGL window (i.e., to make a nice little border), and that may not describe your case.
What we found caused the problem was this:
We had been using a RoundRect() call (with a HOLLOW_BRUSH) to draw the outline of the group box. Changing it to a MoveToEx() and LineTo() calls to ensure JUST the lines are drawn and nothing gets done inside the group box kept the GDI from trying to unexpectedly repaint the whole content of the control. It's possible there's a difference in invalidation logic (or we had a bug somehow in loading the intended hollow brush). We're still investigating.
-Noel
My app has only a single OpenGL window (the main window) but I ran into some nasty DWM tearing issues on window resize and I wonder if one of the solutions may work for you.
First of all, I found that during window resize there are at least two different bad guys who want to "help" you by modifying your client area before you have a chance to update the window yourself, creating flicker.
The first bad guy dates back to a XP/Vista/7 BitBlt inside the SetWindowPos() that Windows does internally during window resize, and can be eliminated with a trick involving intercepting WM_NCCALCSIZE or another trick involving intercepting WM_WINDOWPOSCHANGING.
In Windows 8/10 we still have that problem but we have a new bad guy, the Aero DWM.exe window manager, who will do his own different kind of BitBlt when he thinks you are "behind" updating the screen.
I suspect that the rubbish pixels you are seeing might actually be an intentional and very very poor attempt by DWM to fill in something "acceptable" while it waits for you to draw. I discovered that DWM extends the edge pixels of old client area data when it blits the new client area, which is insane.
Unfortunately, I don't know of any 100% solution to prevent DWM from doing this, but I do have a timing hack that greatly reduces the frequency of it.
For source code to the WM_NCCALCSIZE/WM_WINDOWPOSCHANGING hack as well as the DWM timing hack, please see:
How to smooth ugly jitter/flicker/jumping when resizing windows, especially dragging left/top border (Win 7-10; bg, bitblt and DWM)?
Hmm, maybe you have ran into the same issue: if you are using "new" MFC
it will create and application with Tabs and Window Spliter.
The splitter has some logic (I am guessing somewhere around transparent window and drawing XOR
lines for the split) that causes this behavior. Remove the splitter to confirm it resolve
your issue. If you need split functionality -- put in a different splitter.
Also Tabs allow docking and again splitting the windows that has the same issue -- remove/replace.
Good luck,
Igor
When you make a window in glut using glutCreateWindow it puts a top to the window? What if I want to do some OpenGL rendering without a window top?
This probably doesn't make much sense without a picture:
Essentially I want to remove this from the window.
Use GLUT_BORDERLESS and GLUT_CAPTIONLESS as additional parameters to the glutInitDisplayMode() to get rid of window border and caption as follow:
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH|GLUT_BORDERLESS|GLUT_CAPTIONLESS);
At least it works pretty good with freeglut 2.8.1 on Windows.
The proper terminology for what you want is "undecorated window" or "borderless window". Unfortunately, I can't find any GLUT calls which let you control window decorations.
The closest I was able to find was glutFullScreen which, on X11 platforms, is often implemented by maximizing an undecorated window... but it'll re-decorate it if you un-maximize it.
This forum thread seems to confirm my conclusions.
I've seen things like this and I was wondering if this was possible, say I run my application
and it will show the render on whatever is below it.
So basically, rendering on the screen without a window.
Possible or a lie?
Note: Want to do this on windows and in c++.
It is possible to use your application to draw on other application's windows. Once you have found the window you want, you have it's HWND, you can then use it just like it was your own window for the purposes of drawing. But since that window doesn't know you have done this, it will probably mess up whatever you have drawn on it when it tries to redraw itself.
There are some very complicated ways of getting around this, some of them involve using windows "hooks" to intercept drawing messages to that window so you know when it has redrawn so that you can do your redrawing as well.
Another option is to use clipping regions on a window. This can allow you to give your window an unusual shape, and have everything behind it still look correct.
There are also ways to take over drawing of the desktop background window, and you can actually run an application that draws animations and stuff on the desktop background (while the desktop is still usable). At least, this was possible up through XP, not sure if it has changed in Vista/Win7.
Unfortunately, all of these options are too very complex to go in depth without more information on what you are trying to do.
You can use GetDesktopWindow(), to get the HWND of the desktop. But as a previous answer says (SoapBox), be careful, you may mess up the desktop because the OS expects that it owns it.
I wrote an open source project a few years ago to achieve this on the desktop background. It's called Uberdash. If you follow the window hierarchy, the desktop is just a window in a sort of "background" container. Then there is a main container and a front container. The front container is how windows become full screen or "always on top." You may be able to use Aero composition to render a window with alpha in the front container, but you will need to pass events on to the lower windows. It won't be pretty.
Also, there's a technology in some video cards called overlays/underlays. You used to be able to render directly to an overlay. Your GPU would apply it directly, with no interference to main memory. So even if you took a screen capture, your overlay/underlay would not show up in the screen cap. Unfortunately MS banned that technology in Vista...
I'm coding a short game in C++ and Win32, and I want to be able to make it in fullscreen with a fixed size. I also want the user to be able to switch focus between the game window and other windows as much as he/she wants without any weird screen glitches.
So far I know of the ChangeDisplaySettings function and creating the window with the WS_POPUP style at initialization to make it fullscreen. To detect the user switching focus to other windows by way of alt+tab or otherwise, what messages should I be handling on the window's WndProc or should I be using another function? When loss of focus is detected should I only call ChangeDisplaySettings(NULL, 0); or are there other functions I should call as well? And what method should I use to handle focus back into the window?
Also can anyone give me some info on how to make it work smoothly for different screen sizes?
Thanks for any help.
If you want an exclusive full screen window, use DirectX.
But I don't recommend it. Changing the display mode causes glitches, rearranges the users icons and so on. Whether done by you, or Direct X.
Rather create a normal window at your native res, and let the user maximize it if wanted.
You could also use the GDI+ library of Windows XP (and newer) to use hardware-accelerated stretching (draw in 640x480, let GDI+ resize it to the native resolution). Then you don't need exclusive mode of DirectDraw nor ChangeDisplaySettings.
Also drawing into a 640x480 big background buffer and bit blitting it on the drawing surface via StretchBlt can be a performant solution.
On Windows (Vista32), I want to display some simple graphics on top of a fullscreen flash window (an overlay of useful information while using the flash application). What's the fastest way to accomplish it?
I think I may be able to achieve it using DirectX with the DDSCAPS_OVERLAY flag but with the only example I've found I get an exception:
E_NOTIMPL
The function called is not supported at this time
on
m_direct_draw->CreateSurface(&ddsd, &m_overlay_surface, 0)
(full code here: http://nexe.gamedev.net/files/Overlay-2005-11-21.zip)
Something relevant to C/++ or Python would help me. I'm using the latest DirectX SDK.
Thank you
Just create a Layered Window and draw to it with an alpha channel - in WPF, this is as easy as setting the AllowsTransparency bit on the Window
While the transparent layered window is useful, it doesn't appear on top of the fullscreen flash with WS_EX_TOPMOST set.
Note sure how to reply to Paul sadly.
Overlaying on a 3D fullscreen application is very relevant but while it works and flash appears to load dx9, it doesn't show on flash.