AsphyreTextures.pas
上传用户:ctlcnc
上传日期:2021-12-10
资源大小:4933k
文件大小:21k
源码类别:

2D图形编程

开发平台:

Delphi

  1. unit AsphyreTextures;
  2. //---------------------------------------------------------------------------
  3. // AsphyreTextures.pas                                  Modified: 24-Jan-2006
  4. // Basic wrappers for Direct3D textures                           Version 1.0
  5. //---------------------------------------------------------------------------
  6. // Important Notice:
  7. //
  8. // If you modify/use this code or one of its parts either in original or
  9. // modified form, you must comply with Mozilla Public License v1.1,
  10. // specifically section 3, "Distribution Obligations". Failure to do so will
  11. // result in the license breach, which will be resolved in the court.
  12. // Remember that violating author's rights is considered a serious crime in
  13. // many countries. Thank you!
  14. //
  15. // !! Please *read* Mozilla Public License 1.1 document located at:
  16. //  http://www.mozilla.org/MPL/
  17. //
  18. // If you require any clarifications about the license, feel free to contact
  19. // us or post your question on our forums at: http://www.afterwarp.net
  20. //---------------------------------------------------------------------------
  21. // The contents of this file are subject to the Mozilla Public License
  22. // Version 1.1 (the "License"); you may not use this file except in
  23. // compliance with the License. You may obtain a copy of the License at
  24. // http://www.mozilla.org/MPL/
  25. //
  26. // Software distributed under the License is distributed on an "AS IS"
  27. // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  28. // License for the specific language governing rights and limitations
  29. // under the License.
  30. //
  31. // The Original Code is AsphyreTextures.pas.
  32. //
  33. // The Initial Developer of the Original Code is M. Sc. Yuriy Kotsarenko.
  34. // Portions created by M. Sc. Yuriy Kotsarenko are Copyright (C) 2007,
  35. // Afterwarp Interactive. All Rights Reserved.
  36. //---------------------------------------------------------------------------
  37. interface
  38. //---------------------------------------------------------------------------
  39. uses
  40.  Windows, Direct3D9, D3DX9, Types, Classes, SysUtils, Vectors2px,
  41.  AsphyreAsserts, MediaUtils, AsphyreArchives, Vectors2, AsphyreTypes 
  42.  {$IFDEF DebugMode}, AsphyreDebug{$ENDIF};
  43. //---------------------------------------------------------------------------
  44. type
  45.  TAsphyreTextureType = (attManaged, attDynamic, attRenderTarget);
  46. //---------------------------------------------------------------------------
  47.  TAsphyreCustomTexture = class
  48.  private
  49.   FDevice   : TObject;
  50.   FFormat   : TD3DFormat;
  51.   FMipLevels: Cardinal;
  52.   FSize     : TPoint;
  53.  protected
  54.   FTex9       : IDirect3DTexture9;
  55.   FTextureType: TAsphyreTextureType;
  56.   FInitialized: Boolean;
  57.   procedure FindUsagePool(out Usage: Cardinal; out Pool: TD3DPool);
  58.  public
  59.   // The particular device this texture is bound to.
  60.   property Device: TObject read FDevice;
  61.   // Interface to Direct3D texture.
  62.   property Tex9: IDirect3DTexture9 read FTex9;
  63.   // Indicates whether the texture has been initialized successfully.
  64.   property Initialized: Boolean read FInitialized;
  65.   // The specific type of texture.
  66.   property TextureType: TAsphyreTextureType read FTextureType;
  67.   // The current size of the texture.
  68.   property Size: TPoint read FSize write FSize;
  69.   // The format of texture pixels; may differ after initialization.
  70.   property Format: TD3DFormat read FFormat write FFormat;
  71.   // Number of mip levels to be created.
  72.   property MipLevels: Cardinal read FMipLevels write FMipLevels;
  73.   function Initialize(): Boolean; virtual; abstract;
  74.   procedure Finalize(); virtual; abstract;
  75.   // Binds this texture to the specific stage.
  76.   procedure Activate(Stage: Cardinal);
  77.   // Converts pixel coordinates to logical coordinates [0..1].
  78.   function CoordToLogical(const Coord: TPoint2px): TPoint2; virtual;
  79.   // Converts logical coordinates [0..1] to pixel coordinates.
  80.   function LogicalToCoord(const Coord: TPoint2): TPoint2px; virtual;
  81.   // Converts an array of four texture coordinates in pixels to logical
  82.   // values of [0..1].
  83.   function CoordToLogical4(const Points: TPoint4px): TPoint4;
  84.   constructor Create(ADevice: TObject); virtual;
  85.   destructor Destroy(); override;
  86.  end;
  87. //---------------------------------------------------------------------------
  88.  TAsphyrePlainTexture = class(TAsphyreCustomTexture)
  89.  private
  90.   FOrigSize   : TPoint2px;
  91.   FPatternSize: TPoint2px;
  92.   FPadding    : TPoint2px;
  93.  protected
  94.   function RefreshInfo(): Boolean;
  95.  public
  96.   // The original texture size, which stays unchanged.
  97.   property OrigSize: TPoint2px read FOrigSize write FOrigSize;
  98.   // The size of individual sub-images inside the texture.
  99.   property PatternSize: TPoint2px read FPatternSize write FPatternSize;
  100.   // The padding of individual patterns
  101.   property Padding: TPoint2px read FPadding write FPadding;
  102.   // initialize texture using SrcSize, Format and MipLevel config
  103.   function Initialize(): Boolean; override;
  104.   function InitializeEx(const Source: string; ColorKey: Cardinal): Boolean;
  105.   procedure Finalize(); override;
  106.   // These functions are overriden because pixel coordinates are given
  107.   // in terms of "OrigSize" and not the actual texture size.
  108.   function CoordToLogical(const Coord: TPoint2px): TPoint2; override;
  109.   function LogicalToCoord(const Coord: TPoint2): TPoint2px; override;
  110.   constructor Create(ADevice: TObject); override;
  111.  end;
  112. //---------------------------------------------------------------------------
  113.  TAsphyreRenderTarget = class(TAsphyreCustomTexture)
  114.  private
  115.   FUseDepthStencil: Boolean;
  116.   DepthStencil : IDirect3DSurface9;
  117.   SavedSurface : IDirect3DSurface9;
  118.   SavedDepthBuf: IDirect3DSurface9;
  119.  protected
  120.   function RefreshInfo(): Boolean;
  121.  public
  122.   // Determines whether to use depth/stencil buffers, assuming that the device
  123.   // has depth/stencil buffer support enabled as well. The depth/stencil format
  124.   // will match the one provided in the related TAsphyreDevice.
  125.   property UseDepthStencil: Boolean read FUseDepthStencil write FUseDepthStencil;
  126.   // initialize texture using SrcSize, Format and MipLevel config
  127.   function Initialize(): Boolean; override;
  128.   procedure Finalize(); override;
  129.   // Start rendering on this render target.
  130.   function BeginDraw(): Boolean;
  131.   // End rendering on this render target.
  132.   procedure EndDraw();
  133.   constructor Create(ADevice: TObject); override;
  134.  end;
  135. //---------------------------------------------------------------------------
  136.  TAsphyreDynamicTexture = class(TAsphyreCustomTexture)
  137.  protected
  138.   function RefreshInfo(): Boolean;
  139.  public
  140.   // initialize texture using SrcSize, Format and MipLevel config
  141.   function Initialize(): Boolean; override;
  142.   function InitializeEx(const Source: string; ColorKey: Cardinal): Boolean;
  143.   procedure Finalize(); override;
  144.   function Lock(out Bits: Pointer; out Pitch: Integer): Boolean;
  145.   procedure Unlock();
  146.   constructor Create(ADevice: TObject); override;
  147.  end;
  148. //---------------------------------------------------------------------------
  149. implementation
  150. //---------------------------------------------------------------------------
  151. uses
  152.  AsphyreDevices;
  153. //---------------------------------------------------------------------------
  154. constructor TAsphyreCustomTexture.Create(ADevice: TObject);
  155. begin
  156.  inherited Create();
  157.  FDevice:= ADevice;
  158.  Assert((FDevice <> nil)and(FDevice is TAsphyreDevice),
  159.   msgDeviceUnspecified);
  160.  FInitialized:= False;
  161.  FTextureType:= attManaged;
  162.  FFormat     := D3DFMT_UNKNOWN;
  163.  FMipLevels  := D3DX_DEFAULT;
  164. end;
  165. //---------------------------------------------------------------------------
  166. destructor TAsphyreCustomTexture.Destroy();
  167. begin
  168.  if (FInitialized) then Finalize();
  169.  inherited;
  170. end;
  171. //---------------------------------------------------------------------------
  172. procedure TAsphyreCustomTexture.FindUsagePool(out Usage: Cardinal;
  173.  out Pool: TD3DPool);
  174. begin
  175.  Usage:= 0;
  176.  Pool := D3DPOOL_MANAGED;
  177.  case TextureType of
  178.   attDynamic:
  179.    begin
  180.     Usage:= D3DUSAGE_DYNAMIC;
  181.     Pool := D3DPOOL_DEFAULT;
  182.    end;
  183.   attRenderTarget:
  184.    begin
  185.     Usage:= D3DUSAGE_RENDERTARGET;
  186.     Pool := D3DPOOL_DEFAULT;
  187.    end;
  188.  end;
  189. end;
  190. //---------------------------------------------------------------------------
  191. function TAsphyreCustomTexture.LogicalToCoord(const Coord: TPoint2): TPoint2px;
  192. begin
  193.  Result.X:= Round(Coord.x * FSize.X);
  194.  Result.Y:= Round(Coord.y * FSize.Y);
  195. end;
  196. //---------------------------------------------------------------------------
  197. function TAsphyreCustomTexture.CoordToLogical(const Coord: TPoint2px): TPoint2;
  198. begin
  199.  if (FSize.X > 0) then Result.x:= Coord.X / FSize.X else Result.x:= 0.0;
  200.  if (FSize.Y > 0) then Result.y:= Coord.Y / FSize.Y else Result.y:= 0.0;
  201. end;
  202. //---------------------------------------------------------------------------
  203. procedure TAsphyreCustomTexture.Activate(Stage: Cardinal);
  204. begin
  205.  if (FDevice <> nil)and(FTex9 <> nil) then
  206.   TAsphyreDevice(Device).Dev9.SetTexture(Stage, FTex9);
  207. end;
  208. //---------------------------------------------------------------------------
  209. function TAsphyreCustomTexture.CoordToLogical4(
  210.  const Points: TPoint4px): TPoint4;
  211. var
  212.  i: Integer;
  213. begin
  214.  for i:= 0 to 3 do
  215.   Result[i]:= CoordToLogical(Points[i]);
  216. end;
  217. //---------------------------------------------------------------------------
  218. constructor TAsphyrePlainTexture.Create(ADevice: TObject);
  219. begin
  220.  inherited;
  221.  FTextureType:= attManaged;
  222.  Format      := D3DFMT_UNKNOWN;
  223.  MipLevels   := D3DX_DEFAULT;
  224. end;
  225. //---------------------------------------------------------------------------
  226. function TAsphyrePlainTexture.RefreshInfo(): Boolean;
  227. var
  228.  Desc: TD3DSurfaceDesc;
  229. begin
  230.  Result:= (FTex9 <> nil);
  231.  if (not Result) then Exit;
  232.  Result:= Succeeded(FTex9.GetLevelDesc(0, Desc));
  233.  if (Result) then
  234.   begin
  235.    FSize.X:= Desc.Width;
  236.    FSize.Y:= Desc.Height;
  237.    FFormat:= Desc.Format;
  238.   end;
  239. end;
  240. //---------------------------------------------------------------------------
  241. function TAsphyrePlainTexture.Initialize(): Boolean;
  242. var
  243.  Usage: Cardinal;
  244.  Pool : TD3DPool;
  245. begin
  246.  Assert(not FInitialized, msgAlreadyInitialized);
  247.  FindUsagePool(Usage, Pool);
  248.  Result:= Succeeded(D3DXCreateTexture(TAsphyreDevice(Device).Dev9,
  249.   FOrigSize.X, FOrigSize.Y, FMipLevels, Usage, FFormat, Pool, FTex9));
  250.  if (not Result)or(not RefreshInfo()) then
  251.   begin
  252.    FTex9 := nil;
  253.    Result:= False;
  254.   end;
  255.  FInitialized:= Result;
  256. end;
  257. //---------------------------------------------------------------------------
  258. function TAsphyrePlainTexture.InitializeEx(const Source: string;
  259.  ColorKey: Cardinal): Boolean;
  260. var
  261.  Usage: Cardinal;
  262.  Pool : TD3DPool;
  263.  Info : TD3DXImageInfo;
  264.  TempPath, TempFile: string;
  265.  MemStream: TMemoryStream;
  266. begin
  267.  FindUsagePool(Usage, Pool);
  268.  if (IsArchiveLink(Source)) then
  269.   begin
  270.    if (ArchiveManager.ShouldUseDisk(Source)) then
  271.     begin // archive is to be extracted to disk first
  272.      {$IFDEF DebugMode}
  273.      DebugLog(' + Extracting texture ' + ExtractArchiveKey(Source) + ' from ' +
  274.       ExtractFileName(ExtractArchiveName(Source)) + ' to disk.');
  275.      {$ENDIF}
  276.      // find some temporary path to save file to
  277.      TempPath:= GetTempPath();
  278.      // extract the item from archive to temporary path
  279.      Result:= ArchiveManager.ExtractToDisk(Source, TempPath);
  280.      if (Result) then
  281.       begin
  282.        // find the name of the extracted file
  283.        TempFile:= MakeValidPath(TempPath) +
  284.         MakeValidFileName(ExtractArchiveKey(Source));
  285.        {$IFDEF DebugMode}
  286.        DebugLog(' ++ Loading texture from: ' + TempFile);
  287.        {$ENDIF}
  288.        // load the extracted file
  289.        Result:= Succeeded(D3DXCreateTextureFromFileEx(TAsphyreDevice(Device).Dev9,
  290.         PChar(TempFile),
  291.         D3DX_DEFAULT {width}, D3DX_DEFAULT {height}, FMipLevels, Usage, FFormat,
  292.         Pool, D3DX_DEFAULT {filter}, D3DX_DEFAULT {mip filter}, ColorKey, @Info,
  293.         nil, FTex9));
  294.        // remove the extracted file to avoid trash
  295.        DeleteFile(TempFile);
  296.       end;
  297.     end else
  298.     begin // can load the bitmap directly from memory
  299.      {$IFDEF DebugMode}
  300.      DebugLog(' + Extracting texture ' + ExtractArchiveKey(Source) + ' from ' +
  301.       ExtractFileName(ExtractArchiveName(Source)) + ' to memory.');
  302.      {$ENDIF}
  303.      // create a temporary memory stream
  304.      MemStream:= TMemoryStream.Create();
  305.      // extract archive directly to memory
  306.      Result:= ArchiveManager.ExtractToStream(Source, MemStream);
  307.      if (Result) then
  308.       begin
  309.        {$IFDEF DebugMode}
  310.        DebugLog(' +++ Loading texture from memory.');
  311.        {$ENDIF}
  312.        Result:= Succeeded(D3DXCreateTextureFromFileInMemoryEx(TAsphyreDevice(Device).Dev9,
  313.         MemStream.Memory, MemStream.Size, D3DX_DEFAULT {width},
  314.         D3DX_DEFAULT {height}, FMipLevels, Usage, FFormat, Pool,
  315.         D3DX_DEFAULT {filter}, D3DX_DEFAULT {mip filter}, ColorKey, @Info, nil,
  316.         FTex9));
  317.       end;
  318.      // release the memory stream
  319.      MemStream.Free();
  320.     end;
  321.   end else
  322.   begin // load image
  323.    {$IFDEF DebugMode}
  324.    DebugLog('Loading texture from disk: ' + {Source}ExtractArchiveName(Source));
  325.    {$ENDIF}
  326.    Result:= Succeeded(D3DXCreateTextureFromFileEx(TAsphyreDevice(Device).Dev9,
  327.     PChar(ExtractArchiveName(Source)), D3DX_DEFAULT {width}, D3DX_DEFAULT {height},
  328.     FMipLevels, Usage, FFormat, Pool, D3DX_DEFAULT {filter},
  329.     D3DX_DEFAULT {mip filter}, ColorKey, @Info, nil, FTex9));
  330.   end;
  331.  if (not Result)or(not RefreshInfo()) then
  332.   begin
  333.    FTex9 := nil;
  334.    Result:= False;
  335.   end else
  336.   begin
  337.    FOrigSize.X:= Info.Width;
  338.    FOrigSize.Y:= Info.Height;
  339.    FInitialized:= True;
  340.   end;
  341. end;
  342. //---------------------------------------------------------------------------
  343. procedure TAsphyrePlainTexture.Finalize();
  344. begin
  345.  if (FTex9 <> nil) then FTex9:= nil;
  346.  FInitialized:= False;
  347. end;
  348. //---------------------------------------------------------------------------
  349. function TAsphyrePlainTexture.LogicalToCoord(const Coord: TPoint2): TPoint2px;
  350. begin
  351.  Result.X:= Round(Coord.x * FOrigSize.X);
  352.  Result.Y:= Round(Coord.y * FOrigSize.Y);
  353. end;
  354. //---------------------------------------------------------------------------
  355. function TAsphyrePlainTexture.CoordToLogical(const Coord: TPoint2px): TPoint2;
  356. begin
  357.  if (FOrigSize.X > 0) then Result.x:= Coord.X / FOrigSize.X
  358.   else Result.x:= 0.0;
  359.  if (FOrigSize.Y > 0) then Result.y:= Coord.Y / FOrigSize.Y
  360.   else Result.y:= 0.0;
  361. end;
  362. //---------------------------------------------------------------------------
  363. constructor TAsphyreRenderTarget.Create(ADevice: TObject);
  364. begin
  365.  inherited;
  366.  FTextureType:= attRenderTarget;
  367.  Format      := D3DFMT_A8R8G8B8;
  368.  MipLevels   := 1;
  369.  FUseDepthStencil:= False;
  370.  DepthStencil := nil;
  371.  SavedSurface := nil;
  372.  SavedDepthBuf:= nil;
  373. end;
  374. //---------------------------------------------------------------------------
  375. function TAsphyreRenderTarget.RefreshInfo(): Boolean;
  376. var
  377.  Desc: TD3DSurfaceDesc;
  378. begin
  379.  Result:= (FTex9 <> nil);
  380.  if (not Result) then Exit;
  381.  Result:= Succeeded(FTex9.GetLevelDesc(0, Desc));
  382.  if (Result) then
  383.   begin
  384.    FSize.X:= Desc.Width;
  385.    FSize.Y:= Desc.Height;
  386.    FFormat:= Desc.Format;
  387.   end;
  388. end;
  389. //---------------------------------------------------------------------------
  390. function TAsphyreRenderTarget.Initialize(): Boolean;
  391. var
  392.  Usage: Cardinal;
  393.  Pool : TD3DPool;
  394. begin
  395.  Assert(not FInitialized, msgAlreadyInitialized);
  396.  FindUsagePool(Usage, Pool);
  397.  Result:= Succeeded(D3DXCreateTexture(TAsphyreDevice(Device).Dev9,
  398.   FSize.X, FSize.Y, FMipLevels, Usage, FFormat, Pool, FTex9));
  399.  if (not Result)or(not RefreshInfo()) then
  400.   begin
  401.    FTex9 := nil;
  402.    Result:= False;
  403.   end;
  404.  if (Result)and(FUseDepthStencil) then
  405.   with TAsphyreDevice(Device) do
  406.    begin
  407.     Result:= Succeeded(Dev9.CreateDepthStencilSurface(FSize.X, FSize.Y,
  408.      Params.AutoDepthStencilFormat, D3DMULTISAMPLE_NONE, 0, True, DepthStencil,
  409.      nil));
  410.     if (not Result) then FTex9:= nil;
  411.    end;
  412.  if (not Result)or(not RefreshInfo()) then
  413.   begin
  414.    FTex9 := nil;
  415.    Result:= False;
  416.   end;
  417.  FInitialized:= Result;
  418. end;
  419. //---------------------------------------------------------------------------
  420. procedure TAsphyreRenderTarget.Finalize();
  421. begin
  422.  if (SavedDepthBuf <> nil) then SavedDepthBuf:= nil;
  423.  if (SavedSurface <> nil) then SavedSurface:= nil;
  424.  if (DepthStencil <> nil) then DepthStencil:= nil;
  425.  if (FTex9 <> nil) then FTex9:= nil;
  426.  FInitialized:= False;
  427. end;
  428. //---------------------------------------------------------------------------
  429. function TAsphyreRenderTarget.BeginDraw(): Boolean;
  430. var
  431.  MySurface: IDirect3DSurface9;
  432. begin
  433.  Assert(FInitialized, msgNotInitialized);
  434.  // (1) Retreive my own surface for setting it as a render target.
  435.  Result:= Succeeded(FTex9.GetSurfaceLevel(0, MySurface));
  436.  if (not Result) then
  437.   begin
  438.    {$IFDEF DebugMode}
  439.    DebugLog('!! Failed retreiving my render target surface.');
  440.    {$ENDIF}
  441.    Exit;
  442.   end;
  443.  with TAsphyreDevice(Device).Dev9 do
  444.   begin
  445.    // (2) Retreive the render surface that was previously active.
  446.    Result:= Succeeded(GetRenderTarget(0, SavedSurface));
  447.    if (not Result) then
  448.     begin
  449.      {$IFDEF DebugMode}
  450.      DebugLog('!! Failed retreiving currently active rendering surface.');
  451.      {$ENDIF}
  452.      Exit;
  453.     end;
  454.    // (3) Retreive the depth/stencil that was previously active.
  455.    if (FUseDepthStencil) then
  456.     begin
  457.      Result:= Succeeded(GetDepthStencilSurface(SavedDepthBuf));
  458.      if (not Result) then
  459.       begin
  460.        {$IFDEF DebugMode}
  461.        DebugLog('!! Failed retreiving currently active depth/stencil buffer.');
  462.        {$ENDIF}
  463.        Exit;
  464.       end;
  465.     end;
  466.    // (4) Set my surface to be the new render target.
  467.    Result:= Succeeded(SetRenderTarget(0, MySurface));
  468.    if (not Result) then
  469.     begin
  470.      {$IFDEF DebugMode}
  471.      DebugLog('!! Failed setting my surface as a new rendering target.');
  472.      {$ENDIF}
  473.      Exit;
  474.     end;
  475.    // (5) Set my own buffer as a new depth/stencil buffer.
  476.    if (FUseDepthStencil) then
  477.     begin
  478.      Result:= Succeeded(SetDepthStencilSurface(DepthStencil));
  479.      if (not Result) then
  480.       begin
  481.        {$IFDEF DebugMode}
  482.        DebugLog('!! Failed setting my buffer as a new depth/stencil buffer.');
  483.        {$ENDIF}
  484.        Exit;
  485.       end;
  486.     end;
  487.    // (6) Release the surface instance previously retreived.
  488.    MySurface:= nil;
  489.   end;
  490. end;
  491. //---------------------------------------------------------------------------
  492. procedure TAsphyreRenderTarget.EndDraw();
  493. begin
  494.  with TAsphyreDevice(Device).Dev9 do
  495.   begin
  496.    // Restore previously used depth/stencil buffer. 
  497.    if (SavedDepthBuf <> nil) then
  498.     begin
  499.      SetDepthStencilSurface(SavedDepthBuf);
  500.      SavedDepthBuf:= nil;
  501.     end;
  502.    // Restore previously used surface as a render target.
  503.    if (SavedSurface <> nil) then
  504.     begin
  505.      SetRenderTarget(0, SavedSurface);
  506.      SavedSurface:= nil;
  507.     end;
  508.   end;
  509. end;
  510. //---------------------------------------------------------------------------
  511. constructor TAsphyreDynamicTexture.Create(ADevice: TObject);
  512. begin
  513.  inherited;
  514.  FTextureType:= attDynamic;
  515.  Format      := D3DFMT_A8R8G8B8;
  516.  MipLevels   := 1;
  517. end;
  518. //---------------------------------------------------------------------------
  519. function TAsphyreDynamicTexture.RefreshInfo(): Boolean;
  520. var
  521.  Desc: TD3DSurfaceDesc;
  522. begin
  523.  Result:= (FTex9 <> nil);
  524.  if (not Result) then Exit;
  525.  Result:= Succeeded(FTex9.GetLevelDesc(0, Desc));
  526.  if (Result) then
  527.   begin
  528.    FSize.X:= Desc.Width;
  529.    FSize.Y:= Desc.Height;
  530.    FFormat:= Desc.Format;
  531.   end;
  532. end;
  533. //---------------------------------------------------------------------------
  534. function TAsphyreDynamicTexture.Initialize(): Boolean;
  535. var
  536.  Usage: Cardinal;
  537.  Pool : TD3DPool;
  538. begin
  539.  Assert(not FInitialized, msgAlreadyInitialized);
  540.  FindUsagePool(Usage, Pool);
  541.  Result:= Succeeded(D3DXCreateTexture(TAsphyreDevice(Device).Dev9,
  542.   FSize.X, FSize.Y, FMipLevels, Usage, FFormat, Pool, FTex9));
  543.  if (not Result)or(not RefreshInfo()) then
  544.   begin
  545.    FTex9 := nil;
  546.    Result:= False;
  547.   end;
  548.  FInitialized:= Result;
  549. end;
  550. //---------------------------------------------------------------------------
  551. function TAsphyreDynamicTexture.InitializeEx(const Source: string;
  552.  ColorKey: Cardinal): Boolean;
  553. var
  554.  Usage: Cardinal;
  555.  Pool : TD3DPool;
  556. begin
  557.  Assert(not FInitialized, msgAlreadyInitialized);
  558.  FindUsagePool(Usage, Pool);
  559.  Result:= Succeeded(D3DXCreateTexture(TAsphyreDevice(Device).Dev9,
  560.   FSize.X, FSize.Y, FMipLevels, Usage, FFormat, Pool, FTex9));
  561.  if (not Result)or(not RefreshInfo()) then
  562.   begin
  563.    FTex9 := nil;
  564.    Result:= False;
  565.   end;
  566.  if (not Result)or(not RefreshInfo()) then
  567.   begin
  568.    FTex9 := nil;
  569.    Result:= False;
  570.   end;
  571.  FInitialized:= Result;  
  572. end;
  573. //---------------------------------------------------------------------------
  574. procedure TAsphyreDynamicTexture.Finalize();
  575. begin
  576.  if (FTex9 <> nil) then FTex9:= nil;
  577.  FInitialized:= False;
  578. end;
  579. //---------------------------------------------------------------------------
  580. function TAsphyreDynamicTexture.Lock(out Bits: Pointer;
  581.  out Pitch: Integer): Boolean;
  582. var
  583.  LockedRect: TD3DLockedRect;
  584. begin
  585.  Assert(FTex9 <> nil);
  586.  Result:= Succeeded(FTex9.LockRect(0, LockedRect, nil, D3DLOCK_DISCARD));
  587.  Bits := LockedRect.pBits;
  588.  Pitch:= LockedRect.Pitch;
  589. end;
  590. //---------------------------------------------------------------------------
  591. procedure TAsphyreDynamicTexture.Unlock();
  592. begin
  593.  Assert(FTex9 <> nil);
  594.  FTex9.UnlockRect(0);
  595. end;
  596. //---------------------------------------------------------------------------
  597. end.