Изменение размера окна приводит к перезаписи растровых изображений - PullRequest
0 голосов
/ 04 октября 2019

Я возился с растровыми изображениями и рендерингом в Visual C ++ и столкнулся со странной проблемой.

Я пытаюсь изменить размер области рисования, когда пользователь изменяет размер окна. Прямо сейчас, расширение окна не только не увеличивает видимую область рисования (белые границы появляются за пределами того места, где были исходные границы окна), но изменение размера окна, кажется, мешает моим растровым изображениям.

Вот как выглядит игра при запуске:

enter image description here

После изменения ширины или высоты окна фиолетовый цветсимвол теперь заменен оранжевым.

enter image description here

И, наконец, все три становятся синими.

enter image description here

Если я продолжу, все символы будут перезаписаны растровым изображением фона зеленой травы.

enter image description here

Itпохоже, что происходит в обратном порядке, в котором отображаются растровые изображения. Добавление второго ряда символов подтвердило, что это не проблема в коде рендеринга - фактические растровые изображения в памяти каким-то образом меняются. Удаление кода изменения размера приводит к прекращению воспроизведения ошибки растрового изображения.

Это почти наверняка ошибка в моем коде изменения размера, когда я пытаюсь повторно инициализировать контекст устройства, но я не уверен, что это такое.

Вот соответствующий код настройки:

HBITMAP player_blue = (HBITMAP) LoadImage (NULL, L"Images/test_player_blue.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
HBITMAP player_orange = (HBITMAP) LoadImage (NULL, L"Images/test_player_orange.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
HBITMAP player_purple = (HBITMAP) LoadImage (NULL, L"Images/test_player_purple.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
HBITMAP background_bitmap = (HBITMAP) LoadImage (NULL, L"Images/test_background.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

  HDC hdc = GetDC (Window);
  HDC hdc_temp = CreateCompatibleDC (hdc);
  HBITMAP bitmap_buffer = CreateCompatibleBitmap (hdc, resize.screen_width, resize.screen_height);
  SelectObject (hdc, bitmap_buffer);

Основной цикл из wWinMain ():

  while (!Exit)
    {
    while (PeekMessage (&msg, nullptr, 0, 0, PM_REMOVE))
      {
      DispatchMessage(&msg);
      }
    Render ();
    }

Функция обратного вызова, в которой выполняется изменение размера:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  {
  switch (message)
    {
    case WM_SIZE:

      RECT window_rect;
      if (GetWindowRect (Window, &window_rect))
        {
        hdc = GetDC (Window);
        hdc_temp = CreateCompatibleDC (hdc);
        bitmap_buffer = CreateCompatibleBitmap (hdc, resize.screen_width, resize.screen_height);
        SelectObject (hdc, bitmap_buffer);

        screen_width = window_rect.right - window_rect.left;
        screen_height = window_rect.bottom - window_rect.top;
        }
      break;

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
    }
  return 0;
  }

Фактический рендеринг через BitBlt ():

void Render ()
  {
  SelectObject (hdc_temp, background_bitmap);
  BitBlt (hdc, 0, 0, 800, 600, hdc_temp, 0, 0, SRCCOPY);

  SelectObject (hdc_temp, player_blue);
  BitBlt (hdc, 0, 0, 126, 126, hdc_temp, 0, 0, SRCCOPY);
  SelectObject (hdc_temp, player_orange);
  BitBlt (hdc, 126, 0, 126, 126, hdc_temp, 0, 0, SRCCOPY);
  SelectObject (hdc_temp, player_purple);
  BitBlt (hdc, 252, 0, 126, 126, hdc_temp, 0, 0, SRCCOPY);
  }

1 Ответ

0 голосов
/ 04 октября 2019

Как прокомментировал Кен, вы теряете драгоценные ресурсы GDI. Еще несколько размеров, и ваше окно может стать черным:)

Пожалуйста, посмотрите https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createcompatibledc:

When you no longer need the memory DC, call the DeleteDC function. Возможно, вам не нужно создавать этот DC при каждом изменении размера.

То же самое касается CreateCompatibleBitmap.

...