【问题标题】:C++ Drawing with BitBlt使用 BitBlt 进行 C++ 绘图
【发布时间】:2023-03-03 03:53:02
【问题描述】:

我有一个正在开发的游戏的功能:

void DrawMap()
{
BITMAP bm;
PAINTSTRUCT ps;
HBITMAP sprites = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_COLOR_SPRITES));
HDC hdc = BeginPaint(hWnd, &ps);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, sprites);
GetObject(sprites, sizeof(bm), &bm);

// Find x and y coordinate for the top left of the visible screen
int x = 4, y = 4, ypos = 0;

// Draw lower layer
for (int i = 0; i < 9; i++)
    for (int j = 0; j < 9; j++)
        BitBlt(hdc, (i * 32) + 36, (j * 32) + 36, 32, 32, hdcMem, game.get_pos(game.Layer_One[x + i][y + j], ypos), ypos, SRCCOPY);

// Draw upper layer
for (int i = 0; i < 9; i++)
    for (int j = 0; j < 9; j++)
        if (game.Layer_One[x + i][y + j] != 0)
            BitBlt(hdc, (i * 32) + 36, (j * 32) + 36, 32, 32, hdcMem, game.get_pos(game.Layer_One[x + i][y + j], ypos, true), ypos, SRCCOPY);

SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
EndPaint(hWnd, &ps);
}

变量“游戏”是我为保存所有游戏变量和函数而创建的一个类的实例。基本上,这两个分组的 for 循环应该做的是创建一个由 32 x 32 像素瓦片组成的双层 9 x 9 网格,这些瓦片是从将所有瓦片放在一个位置的图像中复制而来的。我已经测试了我的 get_pos() 函数,它为完整精灵位图中的部分位图返回正确的 x 和 y 位置。
get_pos() 的第二个参数是通过引用 - 所以它可以以这种方式给出一个 y 值并返回一个 x 值。 出于某种原因,我的功能,虽然对我来说似乎正确设置(并且肯定被调用)并没有在 hWnd 上产生任何绘图。我做错了什么?

【问题讨论】:

  • 另外,是行:GetObject(sprites, sizeof(bm), &bm);有必要吗?
  • 如果直接在窗口DC中选择位图,是否显示位图?如果是这样,如果你将它选择到内存DC并BitBlt所有它到窗口DC,它是否仍然显示?
  • 是从WM_PAINT 处理程序调用DrawMap(),还是在至少部分窗口无效的另一时刻?否则,BeginPaint() 构建的设备上下文会将其剪切区域设置为整个窗口,在其上绘制将不起作用。
  • 补充一点,如果您需要从其他地方在窗口上绘图,请使用GetDCReleaseDC 而不是BeginPaintEndPaint
  • Frédéric - 这一定是什么都没有显示的原因。它不是从 WM_PAINT 调用的。它实际上是从 InitInstance() 函数间接调用的。有没有办法暂时使窗口无效?在收到您或其他人的消息之前,我会寻找方法...

标签: c++ winapi bitmap draw


【解决方案1】:

它并没有直接回答你的问题,但是如果你不需要与非常旧的 Windows 版本兼容,为什么不使用 Direct2D? GDI 已被弃用(更不用说速度慢了)。

【讨论】:

  • -1:GDI 既不慢也不弃用。如果有的话,在执行BitBlts 的原始问题的上下文中,GDI 可能更快。这甚至还没有考虑到构建 Direct3D 设备的不小的成本。另外,GDI 是渲染像素完美图形的唯一方法(这也是 OP 显然所追求的)。 Direct2D 有其用途,主要用于将 2D 渲染与 Direct3D 混合。然而,这并不是 Direct2D 提供任何好处的情况之一。
  • 很明显,这个问题建议在游戏环境中使用,而不仅仅是将某些东西放到窗口中。 Direct2D 不需要任何与 Direct3D 相关的东西来做类似上面的事情。至于 GDI 和弃用——也许这有点太强了,但是:msdn.microsoft.com/en-us/library/windows/desktop/…
  • 不必对 Direct3D 感到厌烦,但是 Direct2D 必须这样做。并且构建 Direct3D 设备的成本不菲。至于您链接到的文章,查看所有宣传资料,您会发现以下内容:“BitBlt API 是硬件加速的”。至于“游戏风格”:我不会自动将“最先进的 3D 渲染以及所有的花里胡哨等等”读进去。
  • 还不错;我建议它只是为了阻止发布者在遗留 API 上投入太多时间(至少对于游戏而言)。 Direct2D 至少避免了像 opengl 或 Direct3D 这样的完全 3D api 的复杂性。我相信其声明的目的是或将要在新应用程序中取代 GDI 的使用。
猜你喜欢
  • 2012-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-29
  • 1970-01-01
  • 2012-05-15
相关资源
最近更新 更多