else filename="tri24.bmp";
if (surf1) surf1->Release(), surf1=0;
surf1=CreateSurface(filename, TRUE);
if (surf1==0) {
FatalError("failed to load BMP");
return FALSE;
}
return TRUE;
}
В приложении Bounce используется одна вспомогательная поверхность, содержимое которой определяется одним из двух BMP-файлов: 8- или 24-битным. Функция использует 8-битный файл, если текущий видеорежим является 8-битным, и 24-битный файл — в противном случае. В принципе один и тот же BMP-файл можно использовать в обоих сценариях, но это неразумно. Поскольку 8-битные файлы могут состоять лишь из 256 цветов, не стоит использовать их в режимах High и True Color. В свою очередь 24-битные изображения не пользуются палитрами и могут содержать до 16 миллионов цветов. Генерация 256-цветной палитры для такого изображения становится нетривиальной задачей. Функция CreateCustomSurfaces()определяет глубину пикселей текущего видеорежима с помощью функции DirectDrawWin::GetCurDisplayDepth(). На основании полученного результата выбирается имя BMP-файла.
Затем мы проверяем указатель surf1. Если его значение отлично от нуля, поверхность освобождается, а указатель обнуляется. Это происходит из-за того, что функция CreateCustomSurfaces()может вызываться неоднократно. Функция ActivateDisplayMode()вызывает ее при активизации видеорежима, поэтому приложение, которое за время работы меняет несколько видеорежимов, несколько раз вызовет CreateCustomSurfaces(). Если поверхность создавалась ранее, приведенный код освобождает ее.
Затем мы вызываем функцию CreateSurface(), чтобы создать поверхность и загрузить в нее содержимое BMP-файла. Функция CreateSurface()есть в интерфейсе DirectDrawSurface, но в данном случае используется версия из класса DirectDrawWin. Функция CreateSurface()загружает BMP-файл и создает поверхность, размеры и содержимое которой определяются изображением, хранящимся в заданном BMP-файле. CreateSurface()возвращает указатель на созданную поверхность, если все прошло нормально, и ноль — в противном случае.
Обратите внимание на то, что функция CreateSurface()получает два аргумента. Первый из них представляет собой имя загружаемого BMP-файла. Второй аргумент показывает, нужно ли устанавливать палитру BMP-файла. Для 24-битных BMP-файлов этот аргумент игнорируется.
Функции для работы с поверхностями
Наше приложение Bounce является очень простым, поэтому функция CreateCustom Surfaces() делает не так уж много. Реальное приложение может создавать десятки и даже сотни поверхностей. Класс DirectDrawWinсодержит несколько служебных функций, которые могут пригодиться при работе с поверхностями, поэтому мы ненадолго отвлечемся от приложения Bounce и рассмотрим эти функции:
LPDIRECTDRAWSURFACE CreateSurface(LPCTSTR filename, BOOL installpalette=FALSE);
LPDIRECTDRAWSURFACE CreateSurface(DWORD w, DWORD h);
BOOL LoadSurface(LPDIRECTDRAWSURFACE surf, LPCTSTR filename);
BOOL ClearSurface(LPDIRECTDRAWSURFACE surf, DWORD clr, RECT* rect=0);
BOOL ClearSurface(LPDIRECTDRAWSURFACE surf, DWORD r, DWORD g, DWORD b, RECT* rect=0);
BOOL GetSurfaceDimensions(LPDIRECTDRAWSURFACE surf, DWORD& w, DWORD& h);
Первая функция нам уже знакома. Функция CreateSurface(), получая имя BMP-файла, создает новую поверхность на основании его содержимого. Кроме того, эта функция может извлекать палитру из 8-битных файлов и назначать ее поверхности. Реализация этой функции подробно рассматривается в главе 5.
Вторая функция — CreateSurface() — создает поверхность заданных размеров. Эта функция полезна в тех случаях, когда вам нужна новая поверхность, содержимое которой не связано с BMP-файлом. Данная версия CreateSurface()реализована так:
LPDIRECTDRAWSURFACE DirectDrawWin::CreateSurface(DWORD w, DWORD h) {
DWORD bytes=w*h*(displaydepth/8);
DDSURFACEDESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
desc.dwWidth = w;
desc.dwHeight = h;
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
LPDIRECTDRAWSURFACE surf;
HRESULT r=ddraw2->CreateSurface(&desc, &surf, 0);
if (r==DD_OK) {
TRACE("CreateSurface(%d,%d) created in video memory \n", w, h);
return surf;
}
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
r=ddraw2->CreateSurface(&desc, &surf, 0);
if (r==DD_OK) {
TRACE("CreateSurface(%d,%d) allocated in system memory \n", w, h);
return surf;
}
TRACE("CreateSurface(%d,%d) failed\n", w, h);
return 0;
}
Функция CreateSurface()с помощью структуры DDSURFACEDESCописывает поверхность, размеры которой равны передаваемым параметрам wи h. Поле dwFlagsпоказывает, какие поля структуры будут инициализироваться. Поля dwWidthи dwHeightопределяют размеры поверхности, а поле dwCaps — ее возможности. Обратите внимание на флаг DDSCAPS_VIDEOMEMORY, согласно которому создаваемая поверхность должна находиться в видеопамяти.
Читать дальше