Draw OpenGL to an offscreen bitmap - c++

I've inherited a project which renders a 3D scene directly to the window using OpenGL. The code works fine, but we're now drawing an icon onto the 3D view to "Exit 3D view mode". This also works fine, but results in a lot of flickering as the view is rapidly rotated.
I'd like to be able to draw to an off-screen bitmap (ie. without a HWND), then draw my icon to the bitmap, then finally StretchBlt the bitmap to the window using double-buffering. We do this in other contexts (such as zooming into an image which does not need OpenGL) and it works great. My problem is that I am an OpenGL novice and all attempts at starting with the DC of the off-screen bitmap and creating a HWND from this DC fail, usually because of selecting a pixel format for the DC.
There are a few questions asking similar things here on StackOverflow (eg. this question without an accepted answer. Is this possible ? If so is there a relatively straightforward tutorial describing the procedure? If the process is extremely complex requiring detailed OpenGL knowledge, then I may just have to leave it and live with the flickering because it is a rarely used mode in our software.

Just draw the Icon using OpenGL using a textured quad.
All this draw to a bitmap copy to DC StretchBlt involves several roundtrips from and to graphics memory (wastes bandwidth) and StretchBlt will likely not be GPU accelerated. All in all what you want to do is inefficient and may even reduce quality.
I presume you have the icon stored in your executable as a resource. The most simple way to go about it is to create a memory DC (CreateCompatibleDC) with a DIBSECTION (CreateDIBSection), draw the icon to that and load the DIBSECTION data into a OpenGL texture. Then to draw the icon use glViewport to select the destination rectangle in window coordinates, use an identity transform to draw a rectangle covering the whole viewport (position values (-1,1)→(1,1), texture coordinate values (0,0)→(1,1) gives you the right outcome).
Important side fix: In case your program does silly things like setting viewport and the fixed function pipeline GL_PROJECTION matrix in a window resize handler you should clean up that anti pattern and move this to where it belongs: In the drawing code.

Related

Draw semi transparent shadow around Window

I'm trying to do something like what Auslogics Disk Defrag does with its custom window:
As can be seen, the blurred semi transparent shadow surrounding the window is much darker than the standard one, so the program must be drawing it by itself. The problem is, I can't find a way to paint anything transparent around a window.
In an answer to a similiar question, someone suggested creating a slightly bigger transparent window (using WS_EX_LAYERED + SetLayeredWindowAttributes()) behind the actual application window, and then do the translucent drawing on the transparent one. Not only does it sound like an ugly hack, it doesn't actually work. If, for example, one tries to draw a semi transparent black rectangle on a transparent window via GDI+, alpha blending is applied to the shape's color over the window background color (which would also be the transparency color) and then the shape is drawn with the calculated color, which obviously is not the window transparency, resulting in an opaque rectangle.
The semi transparent shadow is actually done by Gaussian Blur of the black square.
You can use this effect to create glows and drop shadows and use the
composite effect to apply the result to the original image. It is
useful in photo processing for filters like highlights and shadows.
You can use the output of this effect for input into lighting effects,
like the Specular Lighting or Diffuse Lighting effects, because the
alpha channel is blurred, too and lighting effects use the alpha
channel to determine surface geometry as a height map.
This effect is used by the built-in Shadow effect.
Refer: Gaussian blur effect
Then remove the standard frame, the entire window is your client area, so you can draw shadow in the extended frame.
Refer: Drawing in the Extended Frame Window
I think I've found a solution that works for me. I was hoping I wouldn't have to create an extra window just for the shadow, but every method I could find or think of would require me to draw all the controls by myself and/or somehow correct their alpha values.
So, I'm using a layered window with per pixel alpha. I paint over it with Direct2D, or, alternatively, I use some PNGs with transparency for the edges and corners of the shadow and copy them on a memory DC. Either way I simply recreate the shadow with the right dimensions when the window is resized, and call UpdateLayeredWindowIndirect. Both methods seem to be working well on Windows 7 and 10, and so far I haven't found any glitches.
Preventing it from showing on the taskbar was a bit tricky. All the ways I know have drawbacks. What worked best for me was making the layered window owned by the main one. At least that way it will only be visible on the desktop where the program is actually running, unlike other alternatives which would force it to show on every virtual desktop. Finally, because I disable that window, I interact with it by processing WM_SETCURSOR.

How to avoid pixel fighting when drawing on display with SetPixel?

I am using SetPixel(GetDC(0),x,y,color) to write on the screen but as I do that, some other program updates it's screen and overwrites my drawn pixel thus the image drawn on screen appear to sparkle.
How Can I avoid this and draw something on the screen without the fear that it will be overwritten?
The screen is a shared resource. If you want something that is exclusively yours, create a window and draw into that.

Draw GDI+ graphics objects using multi-threading

I have an application in which i am drawing thousands of rectangles of different size. Now here i am giving on user selection of those rectangle i am just drawing rotating border on that particular rectangle...(marching ant animation on rectangle selection).
Now if user selects few rectangles than it won't create such trouble but once user selects all or many at a time then redrawing showing flickering effect which doesn't look good and not even acceptable.
i want make it parallelization of it so i can gain the performance out of it.
I suggest you to use double buffering: create a memory DC, draw on it and then perform BitBlt on a real DC. You can find a lot of examples about this technique in the Internet.
Also you may refer to this msdn article: Flicker-Free Displays Using an Off-Screen DC

New to OpenGL, working on "paint" program

I'm taking a computer graphics course this semester at college and our first assignment is to build a program that works much like Microsoft paint. We need to set options for drawing with shapes of different colors, sizes, and transparency parameters.
I'm having trouble finding information on how to program the ability to draw with a given shape on mouse drag. I'm not asking for the solution in code, but guidance on where to study functions that might accomplish this.
I'm completely new to OpenGL (but not C++) & I own "Computer Graphics with OpenGL" 4th ed. by Hearn & Baker. None of the topics suggest this capability.
What's probably asked from you is creating a single bufferd window, or switching to draw on the front buffer, and draw some shape at the mouse pointers location, when a button is pressed (and dragged), without clearing the frontbuffer inbetween. For added robustness draw to a Frame Buffer Object attached texture, so that dragging some window will not coorupt the user's drawing.
Keywords: Set Viewport to Window size. Ortho projection to window bounds, do not use glClear (except for resetting the picture).

Drawing without flickering

I have a win32 application which was developed in c++. The application draws some stuff on the window using basic shapes (rectangles). The windows is repainted every 20ms (50hz) using InvalidateRect. All works well but the drawing is flickering. How can i prevent the flickering? In c# i normally use a double buffered component (such as pictureBox), how could i get rid of this in c++ using win32?
You can create an in-memory device context, draw those shapes to it (just like you would to the window's device context) and then blit from it to window's device context when the window is invalidated.
You also need to disable background clearing (handle WM_ERASEBKGND window message appropriately) before the draw happens.
Edit: I stumbled upon a pretty exhaustive tutorial on flicker-free drawing in GDI, which explains all aspects of drawing in Windows and comes with examples.
You can easily implement double buffering in Win32 as well. Assuming you are doing your painting directly on the Window using its device context, do this instead:
Create a "memory" device context and do all your drawing on that device context, then copy the invalidated portions of the window to the actual device context when appropriate, using the BitBlt() function
There's a pretty good (albeit high level) overview here.
You can double buffer in C++, too.
When you get the DC to paint to, you create an offscreen bitmap (CreateCompatibleBitmap) and a memory DC (CreateCompatibleDC). Do all your painting to that DC. At the end, do a BitBlt from the memory DC to the actual DC.
For performance, you might want to cache the offscreen bitmap and DC, but remember to recreate them when the window size changes.
Here's the greatest tutorial i've found yet:
https://msdn.microsoft.com/en-us/library/ms969905.aspx
In short - yes, you have to implement the double-buffering. It's done through creating the in-memory DC and then drawing everything you want to an in-memory bitmap using that DC, only afterwards commiting this bitmap to an actual DC.