CreateDIBSection returns 同一图像的位图位值不一致

CreateDIBSection returns inconsistent bitmap bit values for the same image

这是关于 的扩展问题。

我用它来获取同一张使用Direct3D绘制的图片的bitMap位值,验证其Direct3D渲染的一致性,即只要我每次获取相同的bitMap位值即可 运行程序(绘制相同的图像),然后我认为 Direct3D 渲染通过。

然而,奇怪的是我只能在 运行ning 程序的前 4 次获得相同的位图位值(来自 "image",如下面的代码所示) (绘制相同的图像),从第 5 次开始,位图位值的结果将开始轻微变化(只有少量字节发生变化,其余大部分字节仍然相同),并且永远不会恢复相同bitMap位值作为前4次。

但是,一旦我重新启动计算机并再次开始 运行 我的程序,我得到了相同的模式:我在前 4 次 运行ning 期间获得的位图位值该程序与第一次试用完全相同,但以下运行将导致不同的bitMap位值。

我能想到的两个可能的原因:

  1. GPU渲染略有不一致,GPU可能存在一些缺陷,但我不是GPU专家,所以我没有信心下定论这边走。

  2. 我知道 CreateDIBSection 会自行处理内存分配,是否有可能在调用 DeleteObject 后内存未正确清理并影响 bitMap 位值中的某些位? (我遵循了这个 discussion 中的释放内存步骤,但它并没有帮助我获得相同图像的一致位图位值。)

问题: 当我们从同一个图像中获取它时,我们如何每次都获得一致的位图位值(这可能吗?)?

谢谢。

代码:

#include <Windows.h>
#include <cstdint>
HWND m_hwnd;

void GetBitMapInfo(const int& x_Coordinate, const int& y_Coordinate, const int& iWidth, const int& iHeight)
{

DWORD imageSize = iWidth * iHeight * 4;

// Get the display window
HDC displayWindow = GetDC(m_hwnd);
HDC hdc = CreateCompatibleDC(displayWindow);

// Fill in the Bitmap information
BITMAPINFO bmpInfo;
ZeroMemory(&bmpInfo, sizeof(BITMAPINFO));
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = iWidth;
bmpInfo.bmiHeader.biHeight = iHeight;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 32;
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biSizeImage = 0;
bmpInfo.bmiHeader.biClrUsed = 0;
bmpInfo.bmiHeader.biClrImportant = 0;


// Create the storage for the pixel information
uint8_t* image = nullptr;

// Populate the storage with the BMP pixel information
HBITMAP hBitmap = CreateDIBSection(hdc, &bmpInfo, DIB_RGB_COLORS, (void**)(&image), nullptr, NULL);

HGDIOBJ save = SelectObject(hdc, hBitmap);
BitBlt(hdc, x_Coordinate, y_Coordinate, iWidth, iHeight, displayWindow, 0, 0, SRCCOPY);


DeleteObject(SelectObject(hdc, save));
DeleteDC(hdc);
DeleteDC(displayWindow);
DeleteObject(hBitmap);

return;
}

int main()
{
    GetBitMapInfo(0, 0, 1920, 1080);

    return 0;
}

我终于找到了问题的根源,这与 CreateDBSection() 无关,而是由于旋转角度,我将其传递给 DirectX::XMMatrixRotationY 以控制 3D 对象渲染的旋转(在教程的 GraphicsClass::Frame() 下,在下面的 link 下)。

original code实际上是这样设置的,它会无限循环渲染(和旋转)3D对象,直到用户按退出键退出,所以它使旋转角度变量静态.

但我只想让3D物体旋转一圈。由于角度是一个静态变量,我修改后的程序逻辑出错,它只完成了 1 个完整的旋转。因此,静态角度从之前的 运行 开始建立(我在验证期间多次循环修改后的测试),这导致开始旋转角度对于以下重复测试 运行 不同,因为角度一直在增加,直到它自身重置为 0 度并重新开始。

而且由于这个小小的偏移,最终的渲染帧会停在不同的部分。从 CreateDBSection() 返回的位图位值(我将其用于我自己的 CRC 校验目的,以验证 3D 对象渲染的一致性),它基于渲染完成后和 window 之前的最后显示帧被销毁,当然会不同于开始的运行s,因此会使我的CRC(循环冗余校验)不断变化。

我更正了我的代码,以便每次执行测试时,旋转始终从 0 度开始并以 360 度结束,然后退出测试。之后无论我重复多少次循环返回的位图位值都是一致的运行进行测试

总结:

  1. CreateDBSection()对于返回的位图位值没有问题(我是因为对Direct3D渲染理解不清晰和我的C++不好,我会改进自己;))
  2. 我已经尝试了图形驱动程序更新(通过 Intel Driver & Support Assistant 检查驱动程序状态,虽然这对我的情况没有帮助,因为检查后,我的图形驱动程序是最新的,它在某些情况下是一个有用的调试步骤。

感谢大家的帮助。