C++ CreateDIBSection为同一图像返回不一致的位图位值

C++ CreateDIBSection为同一图像返回不一致的位图位值,c++,winapi,bitmap,direct3d,createdibsection,C++,Winapi,Bitmap,Direct3d,Createdibsection,这是一个扩展的问题 使用Direct3D绘制相同图像的位图位值,验证Direct3D渲染的一致性,即只要每次运行程序(绘制同一图像)时得到相同的位图位值,则考虑Direct3D渲染通过。 然而,奇怪的是,在运行程序的前4次(绘制相同的图像)中,我只能获得相同的位图位值(如下面代码中所示的“图像”),在第5次之后,位图位值的结果将开始略有变化(只更改了少量字节,其余大部分字节仍然相同),并且从未返回与前4次相同的位图位值 但是,一旦我重新启动计算机并再次开始运行我的程序,我会得到相同的模式:我在运

这是一个扩展的问题

使用Direct3D绘制相同图像的位图位值,验证Direct3D渲染的一致性,即只要每次运行程序(绘制同一图像)时得到相同的位图位值,则考虑Direct3D渲染通过。 然而,奇怪的是,在运行程序的前4次(绘制相同的图像)中,我只能获得相同的位图位值(如下面代码中所示的“图像”),在第5次之后,位图位值的结果将开始略有变化(只更改了少量字节,其余大部分字节仍然相同),并且从未返回与前4次相同的位图位值

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

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

  • 在GPU的渲染中有一些轻微的不一致,这意味着GPU可能包含一些缺陷,但我不是GPU专家,所以我没有信心以这种方式得出结论

  • 我知道CreateDIBSection将自行处理内存分配,是否可能在调用DeleteObject后内存未正确清理,并影响位图位值中的某些位?(我遵循了本文中的释放内存步骤,但这无助于获得相同图像的一致位图位值。)

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

    谢谢

    代码:

    #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;
    }
    
    #包括
    #包括
    HWND m_HWND;
    void GetBitMapInfo(常量int和x_坐标、常量int和y_坐标、常量int和iWidth、常量int和iHeight)
    {
    DWORD imageSize=iWidth*iHeight*4;
    //获取显示窗口
    HDC displayWindow=GetDC(m_hwnd);
    HDC HDC=CreateCompatibleDC(显示窗口);
    //填写位图信息
    BITMAPINFO-bmpInfo;
    零内存(&bmpInfo,sizeof(BITMAPINFO));
    bmpInfo.bmiHeader.biSize=sizeof(BitMapInfo头文件);
    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.biclrued=0;
    bmpInfo.bmiHeader.biClrImportant=0;
    //为像素信息创建存储
    uint8_t*image=nullptr;
    //使用BMP像素信息填充存储器
    HBITMAP HBITMAP=CreateDIBSection(hdc,&bmpInfo,DIB_RGB_颜色,(void**)(&image),nullptr,NULL);
    HGDIOBJ save=SelectObject(hdc、hBitmap);
    BitBlt(hdc、x_坐标、y_坐标、iWidth、iHeight、displayWindow、0、SRCCOPY);
    DeleteObject(SelectObject(hdc,save));
    DeleteDC(hdc);
    DeleteDC(显示窗口);
    删除对象(hBitmap);
    返回;
    }
    int main()
    {
    GetBitMapInfo(0、0、1920、1080);
    返回0;
    }
    
    我最终找到了问题的根本原因,这与CreateDBSection()无关,而是由于旋转角度,我将其传递给DirectX::XMMatrixRotationY以控制三维对象渲染的旋转(在教程的GraphicsClass::Frame()下,下面的链接)

    实际上,设置它的方式是,它将无限循环通过3D对象渲染(并旋转),直到用户按escape键退出,因此它使旋转角度变量为静态

    但是我只希望3D对象有一个完整的旋转。因为角度是一个静态变量,所以我修改的程序的逻辑出错,它只进行了一个完整的旋转。因此,静态角度是从上一次运行中建立起来的(我在验证期间多次循环修改过的测试)这导致在接下来的重复测试中,开始旋转角度不同,因为角度在增加,直到它自身重置为0度,然后重新开始

    由于这个微小的偏移,最终渲染帧将在不同的部分停止。CreateDBSection()返回的位图位值(我使用它进行CRC检查,以验证3D对象渲染的一致性),它基于渲染完成后和窗口被破坏前最后显示的帧,当然会不同于开始运行,因此会使我的CRC(循环冗余校验)不断变化

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

    摘要:

  • CealDeBeScess()对于返回的位图位值没有问题(我是一个不清楚Direct3D渲染和我的差C++的问题,我会改进自己))< /LI>
  • 我已经尝试了图形驱动程序更新(通过检查驱动程序状态),虽然这对我的情况没有帮助,因为检查后,我的图形驱动程序是最新的,但在某些情况下,这是一个有用的调试步骤

  • 感谢所有人的帮助。

    我们不知道你是如何比较你的值的。也许你只是做错了。1)我有可能。GPU硬件有故障,驱动程序有故障,等等。请尝试先更新GPU驱动程序。然后尝试排除问题实际上不在创建映像的程序中。2)可能性不大。您正在使用
    BitBlt
    完全覆盖DIB部分内存,因此它以前的内容是什么并不重要。您是否只抓住了您关心的窗口?上面的代码捕获主监视器的桌面窗口(高达1920x1080)。