Hello!
I am using the Omega headers and I am also a member there.
This is a problem of Omega, but everybody with knowledge in DirectX could help, so I post it here, maybe someone has a good Idea.
Omega has his own OmegaImagelists (like in DelphiX) which can store images. My problem is I have 19 mb of huge imagelists and it takes a long time to load them all, too long for me.
A solution would be having all images standalone on the harddisc, but I don't like that solution, 600+ images.
The problem is the Init method takes too long, and I am sure there can be an easier and faster solution.
How it works (in my understanding)
1) Loadfromfile loads the imagelist in a stream.
2) Init calls no 3 for every item
3) Item.Init saves the TPicture to a stream, then creates the texture needed from the new stream.
This one is called first to load the imagelist.
Code:
procedure TImageListCollection.LoadFromFile(const Filename: string);
var
Stream: TMemoryStream;
begin
Stream := TMemoryStream.Create;
Stream.LoadFromFile(Filename);
self.LoadFromStream(Stream);
Stream.Free;
end;
Then the Init is called.
Code:
procedure TOmegaImageList.Init;
var
i: integer;
begin
if FOmegaScreen = nil then
exit;
FRenderer.OmegaScreen := FOmegaScreen;
FRenderer.Init;
if FOmegaScreen.Device = nil then
exit;
for i := 0 to ImageList.Count - 1 do
ImageList.Items[i].Init;
end;
This one is calling the init of each ImagelistItem then.
Code:
procedure TImageListItem.Init;
var
FD3DSurfaceDesc: TD3DSurface_DESC;
Stream: TMemoryStream;
sRealFilePath: string;
begin
//Load picture from filepath if present
FFilePath := Trim(FFilePath);
if Length(FFilepath) > 0 then
begin
//Make relative paths absolute
if (Pos(':', FFilepath) = 0) and (Pos('\\', FFilepath) = 0) then
begin
ChDir(ExtractFilePath(Application.ExeName));
sRealFilepath := ExpandFileName(FFilepath);
end
else
sRealFilepath := FFilepath;
if FileExists(sRealFilePath) then
FPicture.LoadFromFile(sRealFilepath);
end;
if (FPicture.Graphic = nil) then
exit;
FDevice :=
TOmegaImageList(TImageListCollection(Collection).GetOwner).FOmegaScreen.Device;
FRenderer :=
TOmegaImageList(TImageListCollection(Collection).GetOwner).FRenderer;
{
If (FDevice = nil) then
begin
MessageBox(0, pChar('Error: no device assigned!'), 'Error', MB_ICONERROR);
Application.Terminate;
end;
If (FRenderer = nil) then
begin
MessageBox(0, pChar('Error: no renderer assigned!'), 'Error', MB_ICONERROR);
Application.Terminate;
end;
}
Stream := TMemoryStream.Create;
try
FPicture.Graphic.SaveToStream(Stream);
if FTileHeight <= 0 then
FTileHeight := FPicture.Graphic.Height;
if FTileWidth <= 0 then
FTileWidth := FPicture.Graphic.Width;
if not assigned(self.FImage) then
if Self.Transparent = true then
begin
if failed(D3DXCreateTextureFromFileInMemoryEx(
FDevice, Stream.Memory, Stream.Size,
0, 0, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
D3DX_FILTER_NONE, D3DX_FILTER_NONE,
$FF000000 or Cardinal(TColor(OmegaColor(self.TransparentColor, 0))),
//Self.TransparentColor,
nil, nil, Self.FImage)) then
begin
MessageBox(0, pChar('Error creating texture ' + Self.FName), 'Error',
MB_ICONERROR);
Stream.Free;
Application.Terminate;
end;
end
else
begin
if failed(D3DXCreateTextureFromFileInMemoryEx(
FDevice, Stream.Memory, Stream.Size,
0, 0, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
D3DX_FILTER_NONE, D3DX_FILTER_NONE,
0, nil, nil, Self.FImage)) then
begin
MessageBox(0, pChar('Error creating texture ' + Self.FName), 'Error',
MB_ICONERROR);
Stream.Free;
Application.Terminate;
end;
end;
Self.FImage.GetLevelDesc(0, FD3DSurfaceDesc);
FRealWidth := FD3DSurfaceDesc.Width;
FRealHeight := FD3DSurfaceDesc.Height;
if FRealWidth < 2 then
FRealWidth := 2;
if FRealHeight < 2 then
FRealHeight := 2;
FHeight := FPicture.Height;
if FHeight = 0 then
FHeight := 1;
FWidth := FPicture.Width;
if FWidth = 0 then
FWidth := 1;
FNumOfRows := FHeight div FTileHeight;
FNumOfColumns := FWidth div FTileWidth;
finally
Stream.Free;
if Length(FFilePath) > 0 then
begin
FPicture.Free;
FPicture := TPicture.Create;
end;
end;
end;
So isn't it possible to make a new methode called 'LoadandInit' that loads all and makes the textures and works somehow faster, maybe without that TPicture and Savetostream etc?
How can I make it faster?
Thanks,
Firle[/code]
Bookmarks