gpt4 book ai didi

具有 16 位颜色深度的 C++ Direct3D9 GetFrontBufferData

转载 作者:太空宇宙 更新时间:2023-11-04 13:46:23 27 4
gpt4 key购买 nike

我目前正在开发一个小的屏幕截图应用程序,它将我屏幕的两个桌面记录在一个文件中。我正在使用 GetFrontBufferData() 函数,它运行良好。

不幸的是,当将屏幕颜色深度从 32 位更改为 16 位(以执行一些测试)时,我的图像很差(分辨率更改后的紫色图像)并且录制的屏幕截图质量非常差:

enter image description here

有人知道是否有办法在 16 位屏幕上使用 GetFrontBufferData() 吗?

编辑:

我的初始化 direct3D:

    ZeroMemory(&d3dPresentationParameters,sizeof(D3DPRESENT_PARAMETERS));//Fills a block of memory with zeros.
d3dPresentationParameters.Windowed = TRUE;
d3dPresentationParameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
d3dPresentationParameters.BackBufferFormat = d3dFormat;//d3dDisplayMode.Format;//D3DFMT_A8R8G8B8;
d3dPresentationParameters.BackBufferCount = 1;
d3dPresentationParameters.BackBufferHeight = gScreenRect.bottom = uiHeight;
d3dPresentationParameters.BackBufferWidth = gScreenRect.right = uiWidth;
d3dPresentationParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dPresentationParameters.MultiSampleQuality = 0;
d3dPresentationParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dPresentationParameters.hDeviceWindow = hWnd;
d3dPresentationParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
d3dPresentationParameters.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;

我用来截图的线程:

    CreateOffscreenPlainSurface(uiWidth, uiHeight, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, pBackBuffer, NULL)) != D3D_OK )
{
DBG("Error: CreateOffscreenPlainSurface failed = 0x%x", iRes);
break;
}

GetFrontBufferData(0, pCaptureSurface)) != D3D_OK)
{
DBG("Error: GetFrontBufferData failed = 0x%x", iRes);
break;
}

//D3DXSaveSurfaceToFile("Desktop.bmp", D3DXIFF_BMP, pBackBuffer,NULL, NULL); //Test purposes

ZeroMemory(lockedRect, sizeof(D3DLOCKED_RECT));
LockRect(lockedRect, NULL, D3DLOCK_READONLY)) != D3D_OK )
{
DBG("Error: LockRect failed = 0x%x", iRes);
break;
}

if( (iRes = UnlockRect()) != D3D_OK )
{
DBG("Error: UnlockRect failed = 0x%x", iRes);
break;
}
/**/
  • 此代码可以完美地处理 32 位色深,但不能处理 16 位色深。
  • 在创 build 备时,我为两个屏幕创建了 2 个设备 (iScreenNber)。这也适用于 32 位(不是 16 位)。
  • 将捕获的屏幕截图保存到 2 个 bmp 文件以进行测试(16 位)时,我有一个屏幕完美地代表主显示屏,而另一个屏幕是黑色的。
  • 当使用 memcpy 来使用 pData 时,我有上面的紫色屏幕截图,分辨率很差

编辑2:

我注意到以下几点:

  • 将屏幕外表面保存到 BMP 文件时,我得到了主显示(在 1.bmp 上),它每帧都刷新一次(因此工作正常)。对于第二个显示,我只得到第一帧,仅此而已。
  • 引用 MSDN 的 GetFrontBufferData pDestSurface 指向的缓冲区将填充前端缓冲区的表示,转换为标准的每像素 32 位格式 D3DFMT_A8R8G8B8。” 我猜这是 16 位色深的问题。
  • 第一个问题来自 memcpy,它不能正确处理 16 位颜色深度,我仍然不知道为什么 ----> 为此需要帮助!!
  • 第二个问题是第二个显示器不工作,我也不知道为什么

我在这里做错了什么?我刚刚在我的桌面 N°xx.bmp 文件上看到一个黑色图像

非常感谢您的帮助。

最佳答案

这就是我创建表面来捕获屏幕截图的方式:

IDirect3DSurface9* pCaptureSurface = NULL;
HRESULT hr = pD3DDevice->CreateOffscreenPlainSurface(
D3DPresentParams.BackBufferWidth,
D3DPresentParams.BackBufferHeight,
D3DPresentParams.BackBufferFormat,
D3DPOOL_SYSTEMMEM,
&pCaptureSurface,
NULL);
pD3DDevice->GetFrontBufferData(0, pCaptureSurface);

如果您没有在任何地方存储 D3DPresentParams,您可以使用 IDirect3DDevice9::GetDisplayMode 获取交换链的宽度、高度和格式。捕获前缓冲区后可以执行的所有调整大小和格式转换操作。另外,据我所知,显示格式不支持 alpha channel ,因此它通常是 D3DFMT_X8R8G8B8,而不是 D3DFMT_A8R8G8B8

更新:实际上,您尝试使用 d3d 设备捕获整个屏幕,而不渲染任何内容。 d3d/opengl 的一个目的是创建或处理图像并进行 GPU 加速。截屏只是复制一些显存,并没有使用所有的 GPU 能力。因此,使用任何 GPU API 都不会带来显着的 yield 。此外,当您捕获不是由您自己渲染的前端缓冲区时,您会看到奇怪的事情发生。要扩展您的应用程序,您可以通过 GDI 捕获图像,然后将其加载到纹理中并进行任何 GPU 后处理。

关于具有 16 位颜色深度的 C++ Direct3D9 GetFrontBufferData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25765371/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com