本文介绍了OpenGL具有全屏原始分辨率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有win32 api且没有glut等的OpenGL应用程序...我遇到了全屏屏幕撕裂的问题.基本上,我已经将WS_POPUP设置为窗口样式,并将显示器的分辨率设置为窗口大小.我在AMD radeon HD 7770上运行时,我看到了可怕的泪痕!当我放置WS_POPUPWINDOW样式而不是WS_POPUP时,撕裂消失了,但是我的场景周围没有多余的边框.我注意到的另一件事是事实,当分辨率不是本机分辨率时,撕裂消失了.因此,当我将my_screen_resolution + 1作为大小参数传递时,撕裂就消失了.

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?

(提示:这不是垂直同步)

推荐答案

(提示:这不是垂直同步)

是的,是V-Sync.

Yes it is V-Sync.

制作全屏窗口时,它将绕过DWM合成器.

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

如果窗口未覆盖全屏,则其内容将通过DWM合成器.只要有迹象表明,DWM合成器本身就会自己制作窗口内容的副本(从WM_PAINT处理程序,EndPaint或SwapBuffers返回).合成本身发生了V同步.

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.

然后,您在输入处理中做错了什么.您的事件循环很可能一次只处理一个输入事件,然后进行重绘.如果是这种情况,并且场景复杂度增加,那么您将变得滞后,这与场景的绘制复杂度成正比.您不希望这种情况发生.

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.

这篇关于OpenGL具有全屏原始分辨率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 13:29