使用SwapBuffers截取绘制OpenGL覆盖



我正在尝试制作一个库,通过拦截对SwapBuffers函数的调用,可以在使用OpenGL的游戏窗口的内容上绘制覆盖图。对于拦截,我使用Microsoft Detours。

BOOL WINAPI __SwapBuffers(HDC hDC)
{
HGLRC oldContext = wglGetCurrentContext();
if (!context) // Global variable
{
context = wglCreateContext(hDC);
}
wglMakeCurrent(hDC, context);
// Drawing
glRectf(0.1F, 0.5F, 0.2F, 0.6F);
wglMakeCurrent(hDC, oldContext);
return _SwapBuffers(hDC); // Call the original SwapBuffers
}

这段代码很有效,但偶尔,当我移动鼠标时,我的覆盖会闪烁。为什么?一些论坛表示,这样的实现可以显著降低FPS。还有更好的选择吗?如何将正常位置正确转换为OpenGL位置?例如,宽度=1366。结果是1366=1,0=-1。如何获得738的值?身高呢?

要将屏幕坐标转换为法线坐标,您需要知道屏幕宽度和屏幕高度,从[0],screenwidth]到[-1,1]/[0],screenheith]到[1,1]的线性映射。它简单如下:

int screenwidth, screenheight;
//...
screenwidth = 1366;
screenheight = 738;
//...
float screenx, screeny;
float x = (screenx/(float)screenwidth)*2-1;
float y = (screeny/(float)screenheight)*2-1;

问题z=0:glRect渲染为z=0,这是一个问题,因为平面将无限接近。因为opengl仍然考虑渲染到世界空间。屏幕空间位于非变换世界空间中的(x,y,1(处。OpenGL几乎总是使用三维坐标。

有两种方法可以解决这个问题:

  1. 您应该更喜欢使用带有z组件的函数,因为opengl在z=0时无法正确渲染。z=1对应于标准化屏幕空间

  2. 或者添加一个glTranslatef(0,0,1);以获得标准化屏幕空间

在屏幕空间上渲染2D并重置模型视图矩阵时,请记住禁用深度测试。

最新更新