Графика для Windows библиотека программиста средствами DirectDraw
bda5893f

Битные поверхности



Мы рассмотрели доступ к 16-битным поверхностям, и все самое сложное осталось позади. Для 24- и 32-битных поверхностей сокращение цветов уже не требуется, поэтому вычислить значение пикселя оказывается проще. В основном нам нужно лишь извлечь цветовые составляющие и сдвинуть их в позицию, определяемую расположением и форматом пикселя. Для 24-битных поверхностей процесс можно оптимизировать, если формат пикселей поверхности совпадает с форматом пикселей BMP-файла. 24-битные поверхности обрабатываются функцией Copy_Bmp24_Surface24() (см. листинг 5.3).
Листинг 5.3. Функция Copy_Bmp24_Surface24()

BOOL DirectDrawWin::Copy_Bmp24_Surface24( LPDIRECTDRAWSURFACE surf, BYTE* bmpbuf, int w, int h ) { if (surf==0 || bmpbuf==0) return FALSE; DDSURFACEDESC desc; ZeroMemory( &desc, sizeof(desc) ); desc.dwSize = sizeof(desc); HRESULT r=surf->Lock( 0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0 ); if (r!=DD_OK) { TRACE("Copy_Bmp24_Surface24: Lock() failed\n"); return FALSE; } int bytesrequired=w*3; int bytesgiven=(bytesrequired+3) & ~3; BYTE* surfbits = (BYTE*)desc.lpSurface; BYTE* imagebits = (BYTE*)(&bmpbuf[(h-1)*bytesgiven]); // Проверить, совпадает ли формат файла с форматом поверхности // Если совпадает, пересылку можно ускорить функцией memcpy() if (loREDbit==16 && loGREENbit==8 && loBLUEbit==0) { TRACE("using optimized code...\n"); for (int i=0;i<h;i++) { memcpy( surfbits, imagebits, bytesrequired ); surfbits += desc.lPitch; imagebits -= bytesgiven; } } else { TRACE("not using optimated code...\n"); for(int i=0; i<h; i++ ) { RGBTRIPLE* surf=(RGBTRIPLE*)surfbits; RGBTRIPLE* image=(RGBTRIPLE*)imagebits; for (int p=0;p<w;p++) { DWORD r=image->rgbtRed << loREDbit; DWORD g=image->rgbtGreen << loGREENbit; DWORD b=image->rgbtBlue << loBLUEbit; DWORD* data=(DWORD*)surf; *data = r|g|b; surf++; image++; } surfbits += desc.lPitch; imagebits -= bytesgiven; } } surf->Unlock( 0 ); return TRUE; }

Функция Copy_Bmp24_Surface24() учитывает две возможные ситуации. Если формат пикселей поверхности совпадает с форматом графических данных, целые строки пикселей копируются в цикле функцией memcpy() без всяких изменений. В противном случае используется второй цикл.
Неоптимизированный цикл похож на тот, что применялся для 16-битных поверхностей, но на этот раз нам не нужно выполнять сокращение цветов. Для доступа к поверхности и графическим данным используются два указателя, surf и image. Оба являются указателями на 24-битный тип RGBTRIPLE, что упрощает перебор 24-битных пикселей.
Каждая цветовая составляющая извлекается из буфера графических данных и сдвигается в соответствии со значением переменных loREDbit, loGREENbit и loBLUEbit. Затем компоненты объединяются и заносятся в память поверхности. Наконец, инкрементирование указателей surf и image перемещает их к следующему пикселю.


Содержание раздела