-
Привет. Написал загрузку бмп. (Только 24 и 32 битных) 1) Но как залить им текстуру не понимаю. 2) Почему Device.FDevice.CreateTexture возвращает ИнвалидКал. function LoadTexture(const FileName: string; var W, H: LongWord; var Data: Pointer; var Format: TD3DFormat): boolean;
var
Bpp: LongWord;
begin
Result:= LoadBmp(FileName, W, H, Bpp, Data);
If Result then
Case Bpp of
24: Format:= D3DFMT_R8G8B8;
32: Format:= D3DFMT_X8B8G8R8;
end;
end;
function TTexture.Load(const FileName: string): boolean;
var
W, H : LongWord;
Format: TD3DFormat;
pScr : Pointer;
LRect : TD3DLockedRect;
begin
Result:= False;
If LoadTexture(FileName, W, H, pScr, Format) then
begin
If Check(Device.FDevice.CreateTexture(W, H, 0, 0, Format, D3DPOOL_MANAGED, FHandle, nil)) then
begin
If Check(FHandle.LockRect(0, LRect, nil, D3DLOCK_DISCARD)) then
try
finally
Result:= UnLock;
end;
end;
end;
end;
-
(Width,Height,1,0,D3DFMT_A8R8G8B8,D3DPOOL_MANAGED,d3dt,nil))
-
Спасибо. Инвалид калл исчез. Картинка (бмп24) загрузилась, но изображение серое и раздробленное. Ещё формат D3DFMT_R8G8B8 для бмп24 должен был подойти, но нет. Почему?
If Check(FHandle.LockRect(0, LRect, nil, D3DLOCK_DISCARD)) then
try
Move(pScr^, LRect.pBits^, W * H * 3);
finally
Result:= UnLock;
end;
-
Учтите LRect.pitch и чО в bmp выравнивание есть, точно не помню какое.
-
Да, точно. Решил для начала залить текстуру нужным цветом. На выходе получаю один мусор в текстуре.
For y:= 0 to H - 1 do
For x:= 0 to W - 1 do
begin
PDWORD(DWORD(LRect.pBits) + (Y * DWORD(LRect.Pitch)) + (X * 4))^:= D3DCOLOR_XRGB(255, 0, 0);
Inc(PDWORD(LRect.pBits)^);
end;
-
бред же написали :)
-
чтобы незапутаться попробуйте тупо FillChar
-
D3DFMT_R8G8B8 - Трёх байтовая структура, смещение по строкам у вас дважды получается и оба раза не верно.
-
Сделал вот так, работает:
function TTexture.Load(const FileName: string; Custom: boolean = False): boolean;
var
X, Y : LongWord;
W, H : LongWord;
P : PRGB;
pScr : Pointer;
LRect : TD3DLockedRect;
Format: TD3DFormat;
begin
If Custom then
begin
Result:= False;
If LoadTexture(FileName, W, H, pScr, Format) then
try
If not DXCheck(Device.FDevice.CreateTexture(W, H, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, FHandle, nil)) then Exit;
If DXCheck(FHandle.LockRect(0, LRect, nil, 0)) then
try
P:= pScr;
For Y:= H - 1 downto 0 do
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;
finally
Result:= DXCheck(FHandle.UnlockRect(0));
end;
finally
FreeMem(pScr);
end;
end else
Result:= DXCheck(D3DXCreateTextureFromFile(Device.GetHandle, XPChar(FileName), FHandle));
end;
Но есть вопросы: 1) Текстуры обязательно должны быть кратны 2-ке? 2) Работает только при D3DPOOL_MANAGED. 3) Перенос пикселей в 2-х циклах да и ещё с D3DCOLOR_XRGB - жирёт время. Как-то не оптимально получилось. Заранее благодарен. :)
-
1) вроде не обязательно 2) почитайте, сейчас на вскидку не подскажу 3) а вы часто текстуры загружаете? если нет, то какая разница - надёжность важнее
with P^ do
begin
PDWORD(DWORD(LRect.pBits) + Y * LRect.Pitch + X * 4)^:= D3DCOLOR_XRGB(B, G, R);
Inc(P);
end; чО за P? посмотрите типы RGBQuad и RGBTriple. чтобы не заморачиваться с альфой воспользуйтесь трёх байтной структурой.
-
1) Современные карты поддерживают некратные, но с ограничениями (мип-мэппинг с ними не работает и ещё что-то). Для 2D можно использовать, для 3D лучше не. 2) Да, так и было задумано MS'ом. К POOL_DEFAULT доступа через Lock нет. 3) Ничего там особенно не "жирёт". Инициализация DX больше времени займёт, чем загрузка текстур. Но если так уж хочется максимально "вылизать", убирай вызов функции, вычисление DWORD(LRect.pBits) + Y * LRect.Pitch на каждом шаге по X (оно же одинаковое остаётся).
-
> CrytoGen (17.05.11 10:26) [9] > чО за P?
type
PRGB = ^TRGB;
TRGB = record
R, G, B: byte;
end;
> Sapersky (17.05.11 11:41) [10]> 1) Современные карты поддерживают некратные, но с ограничениями > (мип-мэппинг с ними не работает и ещё что-то). Для 2D можно использовать, для 3D лучше не. Проверил капсы. Оказывается моя видеокарта не поддерживает такие текстуры. Всем спасибо. :)
-
-
у bmp выравнивание по 4 байта в строках
-
> CrytoGen (18.05.11 14:50) [13]
А как тогда сделать? Поменял так, но получается мусор:
type
PRGBA = ^TRGBA;
TRGBA = record
R, G, B, A: byte;
end;
Или Вы о чем?
-
For Y:= H - 1 downto 0 do
begin
P:= Pointer(Integer(pScr)+((Y*W*3+3) div 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;
у вас получаются данные из битмапа без разрыва, а они на каждой новой строке должны быть выровнены по 4-м байтам.
-
Правда с Pointer'ами и Interger'ами так лучше не делать, а переписать с промежуточным PByte
-
Для кратных 2-ке нормально, а для остальных нет.
-
For Y:= H - 1 downto 0 do
begin
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;
P:= Pointer(((Integer(P)+3) div 4)*4); end; Попробуйте так. И поищите ответ сами, что ли :)
-
Проще говоря, у битмапов как и у текстур есть Pitch, который не обязательно равен Width * BytesPerPixel. Посчитать его можно функцией BytesPerScanline из Graphics.pas.
-
Когда-то использовал следующую функцию загрузки bmpшек на поверхность directx7 ... у меня тоже не получалось правильно загрузить, но на этом форуме помогли.
typedef struct
spriteTag;
spriteTag* Pak_LoadSprite (packfile_t *pf, char *filename, int r, int g, int b)
&bmpHEAD.bfType;
if (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)
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++)
surfBits += desc.lPitch;
imageBits -= BytesGiven;
}
newSprite->Surf->Unlock (NULL);
return newSprite;
}
-
> CrytoGen (18.05.11 21:20) [18]
Выравнял по 4 байта, для не кратных 2-ке, всё осталось также как на картинке.
> Попробуйте так. И поищите ответ сами, что ли :)
У меня плохо гуглится. :)
>Sapersky (19.05.11 00:43) [19]
Спасибо.
>!!! (19.05.11 13:32) [20]
Посмотрел код, вроде тоже самое: выравнивание, RGB-структура.
-
Для всех надо выравнивать. For Y:= H - 1 downto 0 do
begin
P:= Pointer(Integer(pScr)+((Y*3+3)*W div 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, вообще такой проблемы не было бы.
-
Лучше конечно такие вещи с дельфёй проверять. For Y:= H - 1 downto 0 do
begin
P:= Pointer(Integer(pScr)+((Y*3+3) div 4)*4*W); 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;
-
> CrytoGen
> Sapersky
Большое спасибо, что терпели меня. =) Сделал как в ScanLine у TBitmap.
|