glClear() not obeying scissor region [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm drawing Open GL content (direct Win32 - not using GLUT, FreeGLUT, GLFW, etc) using double buffering in an arbitrary Windows 7 window which is already open, for example, a Windows Notepad window. I have the window handle and can draw the content I want as expected, but I am seeing strange behavior with the glClear() function.
It is my understanding that the glClear() function should only affect pixels on the screen which are INSIDE the region defined by the glScissor() function. I have defined the scissor region with glScissor() and then enabled the scissor function using glEnable(GL_SCISSOR_TEST). glClearColor is set to white (0,0,0,1). I'm clearing both color and depth buffers with the glClear() command.
When the SwapBuffers() command is executed in order to render on the screen, my selected clear color of white is painted inside the scissor region as I requested, but the rest of the window OUTSIDE the scissor region is painted black, rather than leaving these pixels untouched as I expected.
As shown in the image, the scissor region (white) and the object (3D cube) are drawn correctly, but the rest of the notepad window's pixels are set to black, and anything previously painted in that Notepad window is covered over.
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // white background
glViewport(0, 0, 300, 300);
glScissor(0, 0, 250, 400);
glEnable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//... draw cube inside glBegin()/glEnd()...
SwapBuffers(hDC);

If I get your description correctly, glClear works as intended.
You must not assume that only because you see something on the screen, it is also present in the back buffer. The contents of the Notepad window that you see is either the front buffer, or a copy of the front buffer that was blitted into DWM's own secret render buffer (depending on whether you have compositing or not). Or, something else, a GDI buffer that was blitted to DWM's buffer, or such. Most likely the latter, since it's using GDI to render.
When you flip buffers, the back buffer is displayed over anything that's on-screen in that regin, and what you get is an all-black buffer (actually uninitialized, but presumably the driver was so kind as to zero the memory) except for the area that you cleared to white.
Which is exactly what you should expect -- your glClear affected only a subregion, and the rest is undefined, it happened to be zero (black).
Incidentially, if no compositing is enabled what you can see on-screen can be copied from the front buffer to the back buffer on most graphic cards, so you would be able to still see the original contents of the Notepad window if you wished to have it that way. You will however never have the contents of a GDI window in your back buffer magically (nor will this work with DWM, nor is it something that is guaranteed to work, it only works incidentially most of the time).
The clean solution, if you want the window's original contents, would be to BitBlt from the DC to memory, create a texture, and draw (or blit) that one into the back buffer.

Related

How to render in the title bar with D3D11 in Windows 7?

I have a program that renders to a D3D11 swapchain created with IDXGIFactory2::CreateSwapChainForHwnd. It clears the swap chain to a particular color, specifically green, and draws a textured rectangle. Following the guide at https://learn.microsoft.com/en-us/windows/desktop/dwm/customframe, I extended the window caption downward using DwmExtendFrameIntoClientArea and I extended the client area to the entire window by handling the WM_NCCALCSIZE message. When the swap chain is presented, the contents of the swap chain buffer is drawn on top of the window, completely covering the DWM-drawn glass frame and caption buttons. How can I leave regions of the glass frame and caption buttons to be drawn by DWM while still drawing in the window frame using D3D11?
I have already tried to clear the RenderTargetView to a color of {0.0f, 0.0f, 0.0f, 0.0f} with ID3D11DeviceContext::ClearRenderTargetView but the alpha component appears to be ignored. I've tried to specify DXGI_ALPHA_MODE_STRAIGHT and DXGI_ALPHA_MODE_PREMULTIPLIED in the AlphaMode member of the DXGI_SWAP_CHAIN_DESC1 used to create the swap chain, but it crashes because alpha-blended swapchains must be created by CreateSwapChainForComposition or CreateSwapChainForCoreWindow. Those functions are not viable since I would like to support Windows 7.
Another thing I've tried is creating a blend state and making parts of the texture transparent. All this does is blend the transparent parts of texture with the clear color. Nothing is getting rendered by DWM though.

Draw OpenGL to an offscreen bitmap

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.

SDL resetting glViewport

I'm testing supporting multiple resolutions in an application using SDL2 with OpenGL. To create my "letterbox" functionality I set my glViewport to an appropriate value and everything works perfectly.
However, if I create my window with the SDL_WINDOW_ALLOW_HIGHDPI flag set, whenever I move my window (after receiving the SDL_WINDOWEVENT_MOVED event) SDL modifies the viewport to the full size of the window, which can be verified by calling SDL_GL_GetDrawableSize during the event.
If I do not set SDL_WINDOW_ALLOW_HIGHDPI when creating the window, the viewport is not reset. I do believe this to be a bug, but cannot find anything through the SDL bugzilla so I thought to ask if anyone has seen similar behavior.
You may need to have a retina MacBook Pro to experience this behavior.
Just do what you should be doing anyway: Always re-/set the viewport at the beginning of drawing each frame. As soon as you want to implement a HUD, use framebuffer objects or similar things you'll have to set the viewport (several times) for drawing each frame.

Drawing a line with open GL

I am a newbie with OpenGL. I need to draw a line with it. I browsed the web and found this code:
glBegin(GL_LINES);
glVertex2f(.25,0.25);
glVertex2f(.75,.75);
glEnd();
However, I don't see any line. The consoler appears only for some milliseconds. I need a program that will draw a line and at least visible for some moments.
Thanks in advance.
Bevor you can draw something, you first need some canvas to draw upon. That's be a window with a pixel framebuffer; without doing extra effort you don't have such.
So first step is to create a window which you can draw into, that gives you the canvas.
Next you need the actual pens to draw with. That would be a OpenGL context you have to create and connect with the window.
Only after you did that you can actually ask OpenGL to draw some line. If you just call the drawing commands, there's nothing going to happen, because you neither have the canvas to draw to, nor the pen to draw with.

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.