Затем мы вызываем функцию DirectDraw CreateSurface(). В качестве первого аргумента передается указатель на структуру с описанием поверхности; если вызов окажется успешным, указатель surfбудет ссылаться на созданную поверхность.
При успешном создании поверхности макрос MFC TRACE()выводит отладочное сообщение, а вы получаете указатель surf. Тем не менее раз мы явно указали, что поверхность должна находиться в видеопамяти, при нехватке последней вызов CreateSurface()может закончиться неудачно. В этом случае мы изменяем поле dwCaps, заносим в него флаг DDSCAPS_SYSTEMMEMORYи снова вызываем функцию CreateSurface(). Скорее всего, вторая попытка окажется успешной; если и на этот раз поверхность не будет создана, функция возвратит 0.
Но давайте вернемся к списку функций DirectDrawWinдля работы с поверхностями. Функция LoadSurface()загружает содержимое BMP-файла в существующую поверхность. Эта функция будет часто упоминаться, когда речь пойдет о восстановлении потерянных поверхностей. Функция LoadSurface()похожа на первую версию CreateSurface()(с загрузкой BMP-файла).
Функции ClearSurface()могут использоваться для частичного заполнения поверхностей. Первая версия ClearSurface()заполняет поверхность величиной, передаваемой в качестве второго параметра. Необязательный аргумент rectопределяет заполняемую прямоугольную область (если он не задан, заполняется вся поверхность). Вторая версия ClearSurface()получает в качестве аргументов RGB-составляющие и на их основании вычисляет значение, присваиваемое каждому пикселю поверхности. Из-за дополнительной работы, затрачиваемой на интерпретацию цветов, вторая версия работает медленнее первой. Первая функция ClearSurface()реализована так:
BOOL DirectDrawWin::ClearSurface(LPDIRECTDRAWSURFACE surf, DWORD clr, RECT* rect) {
if (surf==0) return FALSE;
DDBLTFX bltfx;
ZeroMemory(&bltfx, sizeof(bltfx));
bltfx.dwSize = sizeof(bltfx);
bltfx.dwFillColor = clr;
HRESULT r;
r=surf->Blt(rect, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx);
return r==DD_OK;
}
Функция ClearSurface()получает три аргумента: указатель на заполняемую поверхность; величину, присваиваемую каждому пикселю; и необязательную структуру RECT, которая определяет заполняемую область поверхности.
После проверки указателя мы подготавливаем экземпляр структуры DDBLTFX. Полю dwFillColorприсваивается величина, используемая для заполнения, а сама операция осуществляется функцией Blt()интерфейса DirectDrawSurface. Флаг DDBLT_COLORFILLсообщает Blt()о том, что вместо блиттинга выполняется цветовое заполнение.
Получившаяся функция удобна, но ей не хватает универсальности. Дело в том, что величина, применяемая для заполнения поверхности, может иметь различный смысл. Например, для палитровых поверхностей она представляет собой индекс в палитре. Без предварительной проверки палитры невозможно предсказать, какой цвет будет использоваться для заполнения. Аналогичные проблемы возникают и для беспалитровых поверхностей, поскольку конкретное значение пикселя зависит от глубины и формата пикселей. Форматы пикселей особенно часто различаются в режимах High Color, поэтому заполнение поверхности конкретным цветом превращается в нетривиальную задачу.
Вторая версия ClearSurface()получает в качестве аргументов RGB-составляющие и рассчитывает по ним конкретную величину, присваиваемую пикселям поверхности. В таком варианте функция становится более универсальной, но и работает медленнее; быстродействие особенно сильно снижается для палитровых поверхностей, потому что нужный цвет приходится искать в палитре. Код этой функции будет рассмотрен в главе 5.
Нам остается рассмотреть лишь функцию GetSurfaceDimensions(), которая получает указатель на поверхность и возвращает ее ширину и высоту. Код этой функции выглядит так:
BOOL DirectDrawWin::GetSurfaceDimensions(LPDIRECTDRAWSURFACE surf, DWORD& w, DWORD& h) {
if (surf==0) return FALSE;
DDSURFACEDESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.dwSize=sizeof(desc);
desc.dwFlags=DDSD_WIDTH | DDSD_HEIGHT;
if (surf->GetSurfaceDesc(&desc)!=DD_OK) return FALSE;
w=desc.dwWidth;
h=desc.dwHeight;
return TRUE;
}
После проверки указателя мы подготавливаем экземпляр структуры DDSURFACEDESC. Нас интересуют ширина и высота поверхности, поэтому в поле dwFlagsзаносятся флаги DDSD_WIDTHи DDSD_HEIGHT.
Затем мы вызываем функцию GetSurfaceDesc()интерфейса DirectDrawSurfaceи передаем ей указатель на структуру с описанием поверхности. Функция GetSurfaceDesc()сохраняет размеры поверхности в полях dwWidthи dwHeight. Они присваиваются переданным по ссылке переменным wи hтипа DWORD, после чего функция завершается.
Читать дальше