Shatter Glass desktop Win32 effect for windows? - c++

I would like a win32 program that takes the desktop and acts like it is shattering glass and in the end would put the pieces back together is there way reference on Doing this kind of effect with C++?

I wrote a program (unfortunately now lost) to do something like this a few years ago.
The desktop image can be retrieved by creating a DC for the screen, creating a compatible bitmap, then using BitBlt to copy the screen contents into the bitmap. Then use GetDIBits to get the pixels from this bitmap in a known format.
This link doesn't do exactly that, but it demonstrates the principle, albeit using MFC. I couldn't find a Win32-specific example:
http://www.flounder.com/screencapture.htm
For the shattering effect, best to use Direct3D or OpenGL. (Further details are up to you.) Create a texture using the bitmap data saved earlier.
By way of window for associating with OpenGL or D3D, create a borderless window that fills the entire screen and doesn't do painting or background erasing. This will prevent any flicker when switching from the desktop image to the copy of the desktop image being used to draw.
(If using D3D, you'll also find GetMonitorInfo useful in conjunction with IDirect3D9::GetAdapterMonitor and friends, as you'll need to create a separate device for each monitor and you'll therefore need to know which portion of the desktop corresponds to that device.)

Related

How do I render a win32 window to an opengl texture?

I want to be able to render a win32 control inside an OpenGL texture. In order to be able to 3d transform it. Specifically I want to embed Internet explorer to show webpages and video inside a 3D transformed window.
How do I render a win32 window to a texture in a fast enough way (I need to keep 60 fps)?
There are a few ways you can go about it. In all cases, you will need to fetch a device context (DC) from the target window (GetDC, GetDCEx).
Then, you can either read the pixels directly (GetPixel); or blit the contents into your own DC (BitBlt) and then access that (e.g. GetDIBits).
Since you want to "embed" Internet Explorer, and by that you probably mean keeping its window hidden; you will want to consider how to make the above work on windows that are not visible, partially visible, etc. Consider as well your Windows version and/or whether the DWM might be disabled (and therefore the content of a window may not be available). Take a look at PrintWindow to force a WM_PAINT/WM_PRINT.
One small MSDN guide that can introduce you to all this and has a full example is: Capturing an Image.
In any case, you can always go for an alternative solution by embedding some other browser/engine as a library (e.g. Chromium Embedded Framework (CEF), Qt's WebEngine, Electron...).

Creating a program that creates a full screen overlay

I want to write a program that would create a transparent overlay filling the entire screen in Windows 7, preferably with C++ and OpenGL. Though, if there is an API written in another language that makes this super easy, I would be more than willing to use that too. In general, I assume I would have to be able to read the pixels that are already on the screen somehow.
Using the same method screen capture software uses to get the pixels from the screen and then redrawing them would work initially, but the problem would then be if the screen updates. My program would then have to minimize/close and reappear in order for me to be able to read the underlying pixels.
Windows Vista introduced a new flag into the PIXELFORMATDESCRIPTOR: PFD_SUPPORT_COMPOSITION. If the OpenGL context is created with an alpha channel, i.e. AlphaBits of the PFD is nonzero, the alpha channel of the OpenGL framebuffer is respected by the Windows compositor.
Then by creating a full screen, borderless, undecorated window you get this exakt kind of overlay you desire. However this window will still receive all input events, so you'll have to do some grunt work and pass on all input events to the underlying windows manually.

Draw OpenGL on the windows desktop without a window

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...

Screen capture of MDI app with OpenGL graphics using MFC

In our MDI application - which is written in MFC - we have a function to save a screenshot of the MDI client area to file. We are currently doing a BitBlt from the screen into a bitmap, which is then saved. The problem is that some of the MDI child windows have their content rendered by OpenGL, and in the destination bitmap these areas show up as blank or garbled.
I have considered some alternatives:
- Extract the OpenGL content directly (using glReadPixels), and draw this to the relevant portions of the screen bitmap.
- Simulate an ALT+PrtScr, since doing this manually seems to get the content just fine. This will trash the clipboard content, though.
- Try working with the DWM. Appart from Vista and Win7, this also needs to work on Win2000 and XP, so this probably isn't the way to go.
Any input will be appreciated!
The best way to get a bitmap from an OpenGL window is to draw the content to a bitmap 'window'. See PFD_DRAW_TO_BITMAP for more information on how to do this.
If you want to go with the Alt+PrtScr way, you have to consider that many users have their own print screen tool installed which reacts on that very same hotkey. So you can't be sure that this hotkey will copy the content to the clipboard. It may just open the window of the installed print screen tool/utility.
Use the glReadPixels() approach. This question is asked quite often, here, on the gamedev.net forums and on other places, so google should show you code samples easily, but the glReadPixels() approach is the generally recommended approach.
Simulating keypresses is a recipe for disaster, I would stay away from that.

GDI+ Dithering Problem

I have a C++ application that uses the Win32 API for Windows, and I'm having a problem with GDI+ dithering, when I don't know why it should be.
I have a custom control (custom window). When I receive the WM_PAINT message, I draw some Polygons using FillPolygon on a Graphics device. This Graphics device was created using the HDC from BeginPaint.
When the polygons appear on the screen, though, they are dithered instead of transparent, and only seem to show few colors (maybe 256?) When I do the same thing in C# using the .NET interface into GDI+, it works fine, which is leaving me wondering what's going on.
I'm not doing anything special, this is a simple example that should work fine, as far as I know. Am I doing something wrong?
Edit: Nevermind. It only happens over Remote Desktop, even though the C# example doesnt Dither over remote desktop. Remote Desktop is set at 32-bit color, so I don't know what's up with that.
Hmm... The filling capabilities are determined by the target device. When working over remote desktop, AFAIK Windows substitutes the display driver, so that can change the supported features of the display.
when drawing on wm_paint, you actually draw directly on the screen surface, while .net usually uses double buffering (draws to in memory bitmap and then blits the entire bitmap)
there are some settings in gdi+ that affect the drawing quality. maybe there are different defaults for on-screen, off-screen and remote painting?
It only happens over Remote Desktop
Many remoting applications will reduce colour depth in order to reduce bandwidth requirements. While I haven't used Remote Desktop, the same happens on certain VNC connections. I'd check your RD server and client settings.