PDA

View Full Version : D3DTexture write to and from a stream...



NecroDOME
19-01-2006, 08:31 PM
Hello,

is it posible to read and write a IDirect3DTexture9 directly to or from a TFileStream of TMemoryStream?

LP
19-01-2006, 09:22 PM
Yes, use LockRect (http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/directx9_c_summer_03/directx/graphics/reference/d3d/interfaces/idirect3dtexture9/lockrect.asp) and UnlockRect (http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c_Summer_04/directx/graphics/reference/d3d/interfaces/idirect3dtexture9/UnlockRect.asp) methods to get direct access to texture's pixels.

NecroDOME
19-01-2006, 09:26 PM
Yes I know, but is there a way to do it with LoadFromMemory ?

LP
19-01-2006, 10:12 PM
Do you mean something like this:


var
i: Integer;
LRect: TD3DLocked_Rect;
Stream: TStream;
MemAddr: Pointer;
begin
Texture.LockRect(0, LRect, nil, 0);

for i:= 0 to TextureHeight - 1 do
begin
// point to location of specific scanline
MemAddr:= Pointer(Integer(LRect.Bits) + (LRect.Pitch * i));

// read pixel data from stream
Stream.ReadBuffer(MemAddr^, TextureWidth * BytesPerPixel);
end;

Texture.UnlockRect(0);
end;

Clootie
20-01-2006, 07:27 PM
Lifepower advice is good if you are confident in texture format.
Another (easier) method could be (if you read real texture with header etc.:


procedure Load(..., out Texture: IDirect3DTexture9);
var
Stream: TStream;
MemAddr: Pointer;
begin
MemAddr := nil;
Stream := TFileStream.Create(...); // or TAnyStream.Create...
try
GetMem(MemAddr, Stream.Size);
Stream.ReadBuffer(MemAddr^, Stream.Size); // read pixel data from stream
if FAILED(D3DXCreateTextureFromFileInMemory(d3dDevice , MemAddr, Stream.Size, Texture)) then
begin
// error while creating texture - handle me!
end;
finally
FreeMem(MemAddr);
Stream.Free;
end;
end;

// Edit: fixed code (added missing GetMem() call) //

LP
20-01-2006, 09:10 PM
Notice that in Clootie's code the memory for MemAddr is not allocated. You should add "GetMem(MemAddr, Stream.Size)" before reading. Also, there is no possibility to save the texture to stream this way.

As for texture format, you can use GetLevelDesc to retreive information about the texture and its format. Of course, to support multiple texture formats you'll have to write the necessary conversion functions.

NecroDOME
20-01-2006, 10:20 PM
thanks for your repleys

Both are interesting, but it's main use is to write lightmaps someware to a file and read them when a level loads.

So I think I go with option A (from Lifepower)