Copy image of an opengl window to a window gdi dc - windows

I have to copy the image of a windows application (form based, not full screen) that is rendered with opengl to a region(panel) of the window of an other application (using GDI functions).
The opengl window is rendered on one monitor with the first graphic card of the system and the destination panel is rendered on an an other monitor, that is controlled by an other graphic card.
Both applications are "third party application". The only information I have are the window handles of both, the opengl application and the destination panel.
I did some tests with Delphi using the "dglOpenGL" unit - but without success. "glReadPixels" always results in an empty data array.
I do not understand how I can get access to an existing rendering context that was created by an other application.
My project is written in Delphi - but if there are hints, code snippets, in C# or C++, that will be helpful, too.

Related

Is it possible to keep the Windows' compositor working normally when using a fullscreen OpenGL application?

Under Windows, when the DWM composition is active, there's a somehow "special path" for fullscreened OpenGL applications that prevents all other subwindows (popups, menus, tooltips) to be correctly layered on top of the fullscreened OpenGL window.
While this is useful for games and such, it's totally a pain for other fullscreen OpenGL applications (CAD, 3d editors, etc.). This problem is causing endless troubles for Qt users, see here, here, or here.
Is there a way to tell Windows not to enable the special path for a given application / fullscreen window? Either in the manifest, or via DWM APIs, I don't care.
Yes, this can be done by tricking Windows into thinking that the Window should be composited with transparency. For this you call DwmEnableBlurBehindWindow on the window. In case of a fullscreen WS_POPUP window this makes the window fully transparent (instead of the glass effect) and you can use the window's alpha channel to control the opacity; for a regular window with a title area and border you get the glassy effect then.
Now if you configure the pixelformat without an alpha channel or set the alpha channel to all 1 (full opacity) the compositor still has to assume some transparency may be present and goes through full composition.
Small update
Although WinXP and Win2k are beyond their EOL, it may be undesireable to hardlink the dwmapi.dll to the executable, e.g. if you have to support legacy systems with your software for some reason. For that I wrote a small wrapper library dwm_load that dynamically loads the dwmapi.dll if available or falls back to failsafe implementation of the DWM functions.

Access every window's rendering area

What is the best way to access the rendering area of every single window in Microsoft Windows, so I can render them myself in 3D? I know the Desktop Window Manager (dwm) gives every window a rendertarget and renders them alltogether on the screen.
There are tons of 3D window managers out there, but finding some code or other information is hard for me, so I'm asking you.
I would like to do it in OpenGL, but I can imagine it's just possible in DirectX, but that's fine too.
Thanks in advance!
You have to use the operaring system / graphics system specific API dedicated for that task. OpenGL is operating and graphics system agnostic and has no notion of "windows".
In Windows the API you must use is the DWM API. For Windows versions predating the DWM API (XP and earlier) some "dirty" hacks have to be employed to get the contents of the windows (essentially hooking the WM_PAINT and WM_ERASEBACKGROUND messages, and the BeginPaint and EndPaint functions of the GDI to copy the windows' contents into a DIBSECTION that can be used for updating a texture).
In X11 the API to use is XComposite + the GLX_ARB_texture_from_pixmap extension

MS Windows - Capture windows' gpu bitmaps

I presume dwm holds bitmap data of each rendered window in the GPU. Can I access this data? I want to use it as a texture in D3D (or preferably OpenGL). Screenshotting each window to RAM and back to GPU is too slow.
Ive seen other posts like : obtaining full desktop screenshot from the GPU
so Im doubtful, but maybe something has changed in the last 3 years.
Edit
So do all applications use Direct3D to draw all components? Would, say, this chrome browser's content, or file explorer's, or anything exist as an image in the graphics card or are only borders and such rendered through Direct3D/2D? Want to make sure before pursuing. BTW: my idea is a desktop for the Rift without running an alternate shell.

Can you make a Winform draw on top of full screen DirectX layer?

I have a native C++ application that is rendering 3D using DirectX.
The app can switch between windowed and fullscreen using IDXGISwapChain::SetFullscreenState().
However some of my UI is in a .Net Winform in a managed dll.
In windowed mode I just call into the .Net dll and that opens the secondary Winform, so two windows, the main native MFC/DirectX and .Net Winform control.
But when the DirectX is in full screen, can I get the Winform to be show above the Direct X layer?
Is it even possible?
Merely setting the Winform property
this.TopMost = true;
is not sufficient. The winform is under the Direct X layer.
I just want "my" WinForm over the full screen.
You could copy your WinForm's DC onto bitmap in memory and copy that onto a DirectX rendering surface and pass messages back to the WinForm. It might be slow thow though, if you try to do very much.

modal window with non square borders

How do I make modal windows with non square borders, for instance a modal window which has a corner to indicate it's coming (sorta being shout) from a text.
Create your modal dialog window as you would normally and then call SetWindowRgn API to set the non-rectangular region you want to achieve.
Note that this will not allow you to do semi-transparent effects, it works only for opaque windows. If you want alpha blending, your window has to be top-level (alpha transparency is not supported for child windows) and you should be usign different APIs.
Also, this works for C++ clients using the native Win32 API. If you are writing C#/VB.Net code, you need to specify if you are using WinForms or WPF, as the solution is different for these.

Resources