2
votes

I've got an OpenGL application with win32 api without glut etc...and I run into a problem with screen tearing in fullscreen. Basicly I have set WS_POPUP as a window style and resolution of my monitor as window size. I'm running on AMD radeon HD 7770 and I see terrible tearing! When I put WS_POPUPWINDOW style instead of WS_POPUP, the tearing is gone, however I have unwanted border around my scene. Another thing I noticed is fact, that the tearing disappears when the resolution is NOT native. So when I pass my_screen_resolution + 1 as size parameter, the tearing is gone.

RESx = 1920;
RESy = 1080;
hwnd = CreateWindowEx(NULL, NAME, NAME, WS_POPUP, 0, 0, RESx, RESy, NULL, NULL, hInstance, NULL);
SetWindowPos(hwnd, 0, -1, -1, RESx + 1, RESy + 1, 0); // With this function call, the tearing disappears!

What can I do to get rid of the tearing without having to run on not native resolution?

EDIT: (Hint: It's not V-sync)

2
I don't think you can avoid vsync to get rid of the tearing. There are plenty of potential solutions to limit input lag on the other hand. Like for example, run your app logic at 300 fps but only draw it at 60fps. Try to Google it for more details (or maybe ask another question here).Jerem
I'm updating things on 60FPS and drawing on maximum as possible (I get around 600FPS). I know, I can avoid tearing since the last function (SetWindowPos(hwnd, 0, -1, -1, RESx + 1, RESy + 1, 0);) in my post does this. However I think this is not a proper solution.ProXicT
"Hint: It's not V-sync"... well, thanks for the hint, but it actually is V-sync. The entire purpose of V-sync is to prevent tearing. That's all it does. V-sync does not have any other purpose.Dietrich Epp
@DietrichEpp no, it's only a solution to a quirky problem. just because vsync is meant to prevent tearing, and tearing is his issue, doesn't NECESSARILY mean it's because you need vsync to fix it. because i can solve this just by using width+1 and there's no tearing. i can set the viewport with width and no issue at all. no need for vsync. why only when it maps the exact screen does it tear? an actual reason (answer) perhaps would be that it runs even faster mapped to the exact resolution? and hence vsync is perhaps the only way to solve that?Puddle
@Puddle: With width+1 you may be going through the compositor, and maybe that will give you v-sync.Dietrich Epp

2 Answers

2
votes

What can I do to get rid of the tearing without having to run on not native resolution?

EDIT: (Hint: It's not V-sync)

Yes it is V-Sync.

When you make a fullscreen window, it will bypass the DWM compositor.

If the window is not covering the full screen its contents are going through the DWM compositor. The DWM compositor itself makes itself a copy of the window's contents whenever something indicates, that it is done drawing (return from WM_PAINT handler, EndPaint or SwapBuffers called). The composition itself happens V-synced.

Thanks for your advice, but I want to aviod the tearing without vsync. With vsync I have terrible input lag.

Then you're doing something wrong in your input processing. Most likely your event loop only processes one input event at a time then does a redraw. If that's the case and your scene complexity goes up, then you're getting lag, that's proportional to your scene's drawing complexity. You don't want this to happen.

What you should do is accumulate all the input events that piled up between redraws and coalesce them into a single new drawing state. Ideally input events are collected until only just before the scene is set up for drawing to reflect the most recent state. If you want to get fancy you my add a Kalman filter to predict the input state at the moment the frame gets shown to the user and use that for drawing the scene.

1
votes

To remove OpenGL tearing, you should have "enable" vsync. Follow this link for details: how to enable vertical sync in opengl?