Note: The unit only returns the first texture at MipMap Level 0 even if the file is animated. It wouldn't be hard to modify the code below so it loads every frame instead of skipping them.
function LoadVTFImage(var TexData : TRawTexture; RawData : Pointer; Size : Int64; EXT : PWideChar) : Boolean; TexData stores the result. RawData is the actual VTF file loaded into a Pointer. Size is the size of the RawData. EXT is the Extention of the image, this check could be removed.
GL_BGRA is the default format that is returned in the TexData.Data.
Code:
unit Unit_VTF; { VTF - Valve Texture Format This unit is aimed at loading VTF files which are used by Source games (i.e HL2)
Its based on http://developer.valvesoftware.com/wiki/VTF
Composed by Stuart "Stucuk" Carey
This Unit uses parts of Martin Waldegger's DDS Unit for loading the actual textures }
interface
type TRawTexture = Record Data : Pointer; BPP, Padding : Byte; Width, Height : Word; end;
tagVTFHEADER = packed Record Signature : Array [0..3] of Char; // File signature ("VTF\0"). Version : Array [0..1] of Cardinal; // version[0].version[1] (currently 7.1). Headersize : Cardinal; // Size of the header struct (currently 64 bytes). Width, // Width of the largest mipmap in pixels. Must be a power of 2. Height : Word; // Height of the largest mipmap in pixels. Must be a power of 2. Flags : Cardinal; // VTF flags. Frames, // Number of frames, if animated (1 for no animation). FirstFrame : Word; // First frame in animation (0 based). Padding0 : Array [0..3] of Byte; // reflectivity padding (16 byte alignment). Reflectivity : Array [0..2] of Single; // reflectivity vector. Padding1 : Array [0..3] of Byte; // reflectivity padding (8 byte packing). BumpmapScale : Single; // Bumpmap scale. HighResFormat : Integer; // High resolution image format. MipmapCount : Byte; // Number of mipmaps. LowResFormat : integer; // Low resolution image format (always DXT1). LowResWidth, // Low resolution image width. LowResHeight : Byte; // Low resolution image height. B : Byte; // Added to make it 64 bytes long. end;
Procedure SwapY(Pixels: Pointer; xSize, ySize: Integer); var x, y: integer; P1, P2: ^Cardinal; Temp: Cardinal; begin for y:=0 to pred(ySize shr 1) do for x:=0 to pred(xSize) do begin P1 := Pointer(Cardinal(Pixels) + (y*xSize + x)*4); P2 := Pointer(Cardinal(Pixels) + ((ySize-y-1)*xSize + x)*4); Temp := P1^; P1^ := P2^; P2^ := Temp; end; end;
Procedure LoadTexture(Var Stream : TMemoryStream; Var Texture : Cardinal; Const Width,Height,CurrMipMap,MipMapCount,TextureType : Integer; Skip : Boolean); var li: ^TDDSLoadInfo; x,y,size : integer; data,pixels: PBytes; begin
case TextureType of IMAGE_FORMAT_DXT1 : li := @loadInfoDXT1; IMAGE_FORMAT_DXT3 : li := @loadInfoDXT3; IMAGE_FORMAT_DXT5 : li := @loadInfoDXT5; IMAGE_FORMAT_BGR888 : li := @loadInfoBGR8; IMAGE_FORMAT_BGR565 : li := @loadInfoBGR565; IMAGE_FORMAT_BGRA8888 : li := @loadInfoBGRA8; else Exit; end;
x := Width; y := Height;
if not Skip then GetMem(pixels, x*y*4);
if not Skip then begin glBindTexture(GL_TEXTURE_2D, Texture);
FreeMem(Data); end else Stream.Seek(Size,1); end else begin size := x * y * li.blockBytes;
if not Skip then begin GetMem(data, size); Stream.Read(Data^,Size);
if li.swap then glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); glTexImage2D(GL_TEXTURE_2D, CurrMipMap, li.internalFormat, x, y, 0, li.externalFormat, li.typ, data);
if li.swap then glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
Function GetHasAlpha(Format : Integer) : Boolean; begin case Format of 0,1,8,11, 12,13,14, 15,19,20, 21,24,25 : Result := True; else Result := False; end;
end;
//Note: While VTF's can be animated, for our purposes we just want the first image thats at MipMap 0 function LoadVTFImage(var TexData : TRawTexture; RawData : Pointer; Size : Int64; EXT : PWideChar) : Boolean; var x,y,curmip : integer; MS : TMemoryStream; Header : tagVTFHEADER; TempTexture : Cardinal; Faces : Integer; begin Result := False;
if not (Lowercase(WideString(EXT)) = '.vtf') then Exit;
MS := TMemoryStream.Create; glGenTextures(1, @TempTexture);
for curmip := Header.MipmapCount-1 downto 0 do begin
for x := 0 to Header.Frames-1 do for y := 0 to Faces-1 do begin LoadTexture(MS,TempTexture,Header.Width,Header.Height,curmip,Header.MipmapCount,Header.HighResFormat,not ((X = 0) and (Y = 0) and (curmip = 0)));
if (X = 0) and (Y = 0) and (curmip = 0) then begin TexData.Data := Nil; TexData.Width := Header.Width; TexData.Height := Header.Height; TexData.BPP := 4; GetMem(TexData.Data, Header.Width*Header.Height*4);
Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.