4. Загрузка изображений в видеопамять (bitmap)
Следующим шагом является загрузка изображений в видеопамять. Идеальным является случай, когда в видеопамяти достаточно места для того чтобы там ужились все необходимые Вам для разработки изображения. Если ее не хватает , тоже особенно беспокоится не о чем, CreateSurface
создаст поверхности в обычной памяти (правда, это чуть замедлит).
Пример кода загрузки изображений в DirectDraw
/* * Функция DDLoadBitmap(IDirectDraw *pdd, LPCSTR szBitmap) создает поверхность * и загружает файл с диска. Параметр szBitmap имя файла изображения. */ IDirectDrawSurface * DDLoadBitmap(IDirectDraw *pdd, LPCSTR szBitmap) { HBITMAP hbm; BITMAP bm; IDirectDrawSurface *pdds; // загрузим с диска hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION); if (hbm == NULL) return NULL; GetObject(hbm, sizeof(bm), &bm); // получим размер //создадим поверхность для данного изображения pdds = CreateOffScreenSurface(pdd, bm.bmWidth, bm.bmHeight); if (pdds) { DDCopyBitmap(pdds, hbm, bm.bmWidth, bm.bmHeight); } DeleteObject(hbm); return pdds; } /* * Функция создания поверхности для изображения заданного размера * Эта поверхность окажется в видеопамяти, если ее еще достаточно, * в противном случае - в системной памяти */ IDirectDrawSurface * CreateOffScreenSurface(IDirectDraw *pdd, int dx, int dy) { DDSURFACEDESC ddsd; IDirectDrawSurface *pdds; // // Создание поверхности // ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH; // имеет значение высота и ширина ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; // это заэкранная поверхность ddsd.dwWidth = dx; ddsd.dwHeight = dy; if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK) { return NULL; } else { return pdds; } } /* * Функция копирования ранее загруженного изображения в видео поверхность * (Используется обычный GDI интерфейс) * Это, конечно, не самый быстрый способ - но зато надежный * A в данный момент спешить некуда. Если у Вас происходит динамическая подгрузка * изображений в процессе то лучше эту функцию переписать аккуратнее */ HRESULT DDCopyBitmap(IDirectDrawSurface *pdds, HBITMAP hbm, int dx, int dy) { HDC hdcImage; HDC hdc; HRESULT hr; HBITMAP hbmOld; // // привяжем контекст изображения (DC) к загруженному изображению // hdcImage = CreateCompatibleDC(NULL); hbmOld = (HBITMAP)SelectObject(hdcImage, hbm); if ((hr = pdds->GetDC(&hdc)) == DD_OK) { BitBlt(hdc, 0, 0, dx, dy, hdcImage, 0, 0, SRCCOPY); pdds->ReleaseDC(hdc); } SelectObject(hdcImage, hbmOld); DeleteDC(hdcImage); return hr; } |