-
!!! (19.05.11 13:32) [20]Когда-то использовал следующую функцию загрузки bmpшек на поверхность directx7 ...
у меня тоже не получалось правильно загрузить, но на этом форуме помогли.// ================================================================================ ====
// структура для хранения спрайта
typedef struct
{
int xsize;
int ysize;
LPDIRECTDRAWSURFACE7 Surf;
}spriteTag;
// ================================================================================ ====
// Загружает спрайт из архива
spriteTag* Pak_LoadSprite (packfile_t *pf, char *filename, int r, int g, int b)
{
char *buf_data; // Буфер данных
// Грузим данные в буффер, используя функцию из библиотеки
/*
unpak.c Copyright (C) 1998-2000 Vitaly Ovtchinnikov
and Damir Sagidullin */
int filesize = PackFileGet (pf, filename, &buf_data);
if (!filesize || !(*buf_data)) // Если ничего не загрузилось
{
free (buf_data);
return NULL;
}
// Копируем заголовок
BITMAPFILEHEADER bmpHEAD;
memcpy (&bmpHEAD, buf_data, sizeof(bmpHEAD));
// Проверяем, действительно ли это БМП файл
char *bmpType = (char*)&bmpHEAD.bfType;
if (*bmpType != 'B' || *++bmpType != 'M') // Если нет
{
free (buf_data);
return NULL;
}
// Копируем второй - информацинный заголовок
BITMAPINFOHEADER bmpINFO;
memcpy (&bmpINFO, buf_data + sizeof(bmpHEAD), sizeof(bmpINFO));
if (bmpINFO.biCompression != BI_RGB) // Не сжатое ли изображение
{
free (buf_data);
return NULL;
}
// Устраивают ли нас пиксели
if (bmpINFO.biBitCount != 24)
{
free (buf_data);
return NULL;
}
// Выделяем место под спрайт
spriteTag *newSprite = new spriteTag;
// Если не удалось выделеть место
if (!newSprite)
{
free (buf_data);
return NULL;
}
// сохраним в спрайте размеры картинки
newSprite->xsize = bmpINFO.biWidth;
newSprite->ysize = bmpINFO.biHeight;
// Создаем поверхность
if (DirectDraw7_CreateSurface (&(newSprite->Surf), newSprite->xsize, newSprite->ysize))
{
free (buf_data);
delete newSprite;
return NULL;
}
// Установим прозрачный цвет для поверхности
DirectDraw7_SetColorKey (newSprite->Surf, r, g, b);
// Вычисляем размер изображения, если нужно
int ImageSize = bmpINFO.biSizeImage;
if (!ImageSize)
ImageSize = ((bmpINFO.biWidth*(bmpINFO.biBitCount/8)+3 & ~3)*bmpINFO.biHeight);
// Теперь займемся копированием точек на поверхность
BYTE *bmpbuf = (BYTE*)(buf_data + sizeof(bmpHEAD) + bmpINFO.biSize);
DDSURFACEDESC2 desc;
ZeroMemory (&desc, sizeof (desc));
desc.dwSize = sizeof (desc);
// Залочим поверхность чтобы с ней можно было работать
HRESULT res = newSprite->Surf->Lock( 0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0 );
// Если не получилось, то на выход
if (res != DD_OK)
{
free (buf_data);
delete newSprite;
return false;
}
int BytesRequired = bmpINFO.biWidth * 3;
int BytesGiven = (BytesRequired + 3) & ~3;
BYTE *surfBits = (BYTE*)desc.lpSurface;
BYTE *imageBits = (BYTE*)(&bmpbuf[(bmpINFO.biHeight-1)*BytesGiven]);
for (int i=0; i<bmpINFO.biHeight; i++)
{
WORD *pixptr = (WORD*)surfBits;
RGBTRIPLE *triple = (RGBTRIPLE*)imageBits;
for (int p=0; p<bmpINFO.biWidth; p++)
{
BYTE rf = triple->rgbtRed >> 3;
BYTE gf = triple->rgbtGreen >> 2;
BYTE bf = triple->rgbtBlue >> 3;
*pixptr = (WORD)(bf | (gf << 5) | (rf << 11));
triple++;
pixptr++;
}
surfBits += desc.lPitch;
imageBits -= BytesGiven;
}
// Разлочим поверхность
newSprite->Surf->Unlock (NULL);
// вернем готовый спрайт
return newSprite;
} -
eXAAAXe (20.05.11 11:49) [21]
> CrytoGen (18.05.11 21:20) [18]
Выравнял по 4 байта, для не кратных 2-ке, всё осталось также как на картинке.
> Попробуйте так. И поищите ответ сами, что ли :)
У меня плохо гуглится. :)
>Sapersky (19.05.11 00:43) [19]
Спасибо.
>!!! (19.05.11 13:32) [20]
Посмотрел код, вроде тоже самое: выравнивание, RGB-структура. -
CrytoGen (20.05.11 12:37) [22]Для всех надо выравнивать.For Y:= H - 1 downto 0 do
begin
P:= Pointer(Integer(pScr)+((Y*3+3)*W div 4)*4);//выровняли по 4 байта
For X:= 0 to W - 1 do
with P^ do
begin
PDWORD(DWORD(LRect.pBits) + Y * LRect.Pitch + X * 4)^:= D3DCOLOR_XRGB(B, G, R);
Inc(P);
end;
end;
Ну так попробуйте. И вообще если у вас проблемы отладить такую вещь, то используйте более стандартные подходы. Если бы взяли TBitmap.Scanline, вообще такой проблемы не было бы. -
CrytoGen (20.05.11 13:23) [23]Лучше конечно такие вещи с дельфёй проверять.For Y:= H - 1 downto 0 do
begin
P:= Pointer(Integer(pScr)+((Y*3+3) div 4)*4*W);//выровняли по 4 байта
For X:= 0 to W - 1 do
with P^ do
begin
PDWORD(DWORD(LRect.pBits) + Y * LRect.Pitch + X * 4)^:= D3DCOLOR_XRGB(B, G, R);
Inc(P);
end;
end; -
eXAAAXe (20.05.11 16:11) [24]
> CrytoGen
> Sapersky
Большое спасибо, что терпели меня. =)
Сделал как в ScanLine у TBitmap.