//DJXClasses v1.3
unit DJXClasses;

{$DEFINE SUPPORTS_INLINE}

interface

uses
  Windows,
  Graphics,
  Classes,
  Direct3D9,
  D3DX9;

type
  TDJXComponent = class (TComponent)
  protected
    m_DanJetX: Pointer;
  public
    property DanJetX: Pointer read m_DanJetX write m_DanJetX;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Init(DanJetX: Pointer); virtual;
    procedure OnLostDevice; virtual;
    procedure OnResetDevice; virtual;
  end;

  TDJXColor = DWORD;

  TDJXVertex2D = packed record
    x, y, z, rhw: Single;
    color: TDJXColor;
    tu,tv: single;
  end;
  TDJXVertex2DTex2 = packed record
    x, y, z, rhw: Single;
    color: TDJXColor;
    tu1,tv1: single;
    tu2,tv2: single;
  end;

  TDJXVertex3D = packed record
    x, y, z: Single;
    nx,ny,nz: Single;
    color: TDJXColor;
    tu,tv: single;
  end;
  TDJXVertex3DTex2 = packed record
    x, y, z: Single;
    nx,ny,nz: Single;
    color: TDJXColor;
    tu1,tv1: single;
    tu2,tv2: single;
  end;

  TDJXVertexFlex = packed record
    x, y, z, rhw: Single;
    nx,ny,nz: Single;
    color: TDJXColor;
    tu1,tv1: single;
    tu2,tv2: single;
    tu3,tv3: single;
    tu4,tv4: single;
    tu5,tv5: single;
    tu6,tv6: single;
    tu7,tv7: single;
    tu8,tv8: single;
  end;

  TDVertex3DArray = array of TDJXVertex3D;
  TDVertex3DTex2Array = array of TDJXVertex3DTex2;
  
  TDVertex2DArray = array of TDJXVertex2D;
  TDVertex2DTex2Array = array of TDJXVertex2DTex2;
  
  TDIndexArray = array of WORD;
  TDVertexArray = array of byte;
  TDVertexFlexArray = array of TDJXVertexFlex;

  PVector4Array = ^TVector4Array;
  TVector4Array = array of TD3DXVector4;

  TColorVector3 = record
    x, y, z: single;
    color: TDJXColor;
  end;
  PColorVector3Array = ^TColorVector3Array;
  TColorVector3Array = array of TColorVector3;

  TDJXMultisampleSpecs = record
    MultisampleNone: boolean;
    MultisampleNonMaskable: boolean;
    Multisample2X: boolean;
    Multisample3X: boolean;
    Multisample4X: boolean;
    Multisample5X: boolean;
    Multisample6X: boolean;
    Multisample7X: boolean;
    Multisample8X: boolean;
    Multisample9X: boolean;
    Multisample10X: boolean;
    Multisample11X: boolean;
    Multisample12X: boolean;
    Multisample13X: boolean;
    Multisample14X: boolean;
    Multisample15X: boolean;
    Multisample16X: boolean;
    MaxQuality: DWORD;
  end;

  TDJXAdapter = class(TObject)
  private
    m_DeviceCaps: TD3DCaps9;
    m_DisplayModes: array of PD3DDisplayMode;
    m_AdapterIdentifier: TD3DAdapterIdentifier9;
    m_CurrentDisplayMode: TD3DDisplayMode;
    m_MultisampleSpecs: TDJXMultisampleSpecs;
  protected
    function GetDisplayMode(Value: integer): PD3DDisplayMode;
    function GetDisplayModeCount: DWORD;
    procedure AddDisplayMode(Mode: TD3DDisplayMode);
  public
    property AdapterIdentifier: TD3DAdapterIdentifier9 read m_AdapterIdentifier;
    property CurrentDisplayMode: TD3DDisplayMode read m_CurrentDisplayMode;
    property DeviceCaps: TD3DCaps9 read m_DeviceCaps write m_DeviceCaps;
    property MultisampleSpecs: TDJXMultisampleSpecs read m_MultisampleSpecs;
    property DisplayModeCount: DWORD read GetDisplayModeCount;
    property DisplayModes[Index: integer]: PD3DDisplayMode read GetDisplayMode;

    constructor Create;
    destructor Destroy; override;
  end;

  TDJXSpecs = class(TObject)
  private
    m_Adapters: array of TDJXAdapter;
  protected
    function GetAdapter(Value: integer): TDJXAdapter;
    function GetAdapterCount: DWORD;
  public
    property AdapterCount: DWORD read GetAdapterCount;
    property Adapters[Index: integer]: TDJXAdapter read GetAdapter;

    constructor Create;
    destructor Destroy; override;

    procedure ClearSpecs;
    procedure CollectSpecs;
  end;

  TDJXVBRender = class(TObject)
  private
    m_DanJetX: Pointer;
  public
    constructor Create(DanJetX: Pointer);
    destructor Destroy; override;
    procedure DrawPointList(StartVertex, PrimitiveCount: LongWord);
    procedure DrawLineList(StartVertex, PrimitiveCount: LongWord);
    procedure DrawLineStrip(StartVertex, PrimitiveCount: LongWord);
    procedure DrawTriangleList(StartVertex, PrimitiveCount: LongWord);
    procedure DrawTriangleStrip(StartVertex, PrimitiveCount: LongWord);
    procedure DrawTriangleFan(StartVertex, PrimitiveCount: LongWord);
    procedure DrawIndexedLineList(BaseVertexIndex: Integer; MinVertexIndex, NumVertices, startIndex, primCount: LongWord);
    procedure DrawIndexedLineStrip(BaseVertexIndex: Integer; MinVertexIndex, NumVertices, startIndex, primCount: LongWord);
    procedure DrawIndexedTriangleList(BaseVertexIndex: Integer; MinVertexIndex, NumVertices, startIndex, primCount: LongWord);
    procedure DrawIndexedTriangleStrip(BaseVertexIndex: Integer; MinVertexIndex, NumVertices, startIndex, primCount: LongWord);
    procedure DrawIndexedTriangleFan(BaseVertexIndex: Integer; MinVertexIndex, NumVertices, startIndex, primCount: LongWord);
  end;

  TDJXVB = class(TObject)
  private
    m_DanJetX: Pointer;
    m_VB: IDirect3DVertexBuffer9;
    m_VArr: TDVertexArray;
    m_VF_Color: boolean;
    m_VF_Normals: boolean;
    m_VF_TexCount: byte;
    m_VF_2D: boolean;
    m_Size: cardinal;
    m_Count: cardinal;
    m_FVF: cardinal;
    m_Declaration: TFVFDeclaration;
  protected
    function getSize: Cardinal;
    procedure SetVertex(Index: integer; Value: TDJXVertexFlex);
    function GetVertex(Index: integer): TDJXVertexFlex;
    function GetVertexPointer: Pointer;
  public
    constructor Create(DanJetX: Pointer);
    destructor Destroy; override;
    property VF_Color: boolean read m_VF_Color write m_VF_Color;
    property VF_Normals: boolean read m_VF_Normals write m_VF_Normals;
    property VF_TexCount: byte read m_VF_TexCount write m_VF_TexCount;
    property VF_2D: boolean read m_VF_2D write m_VF_2D;
    property VertexPointer: Pointer read GetVertexPointer;
    property Vertices[Index: integer]: TDJXVertexFlex read GetVertex write SetVertex;
    property Count: cardinal read m_Count;
    function Init(size: longint; Usage: DWord = 0): boolean;
    procedure UnInit;
    procedure SetVertices(offset: longint; count: integer);
    procedure SetToDevice;
    function getFVF: Cardinal;
    function getDeclaration: TFVFDeclaration;
    function getVertexDeclaration: IDirect3DVertexDeclaration9;
  end;

  TDJXIB = class(TObject)
  private
    m_DanJetX: Pointer;
    m_Format: TD3DFormat;
    m_IB: IDirect3DIndexBuffer9;
    m_Indices: TDIndexArray;
    m_Count: cardinal;
  public
    constructor Create(DanJetX: Pointer);
    destructor Destroy; override;
    property Format: TD3DFormat read m_Format write m_Format;
    property Indices: TDIndexArray read m_Indices write m_Indices;
    property Count: cardinal read m_Count;
    function Init(size: longint; Usage: DWord = 0): boolean;
    procedure UnInit;
    procedure SetIndices(offset: longint; count: integer);
    procedure SetToDevice;
  end;

  TDJXVBbase = class(TObject)
  private
    m_DanJetX: Pointer;
    m_Indices: TDIndexArray;
    m_VB: IDirect3DVertexBuffer9;
    m_IB: IDirect3DIndexBuffer9;
    m_VerticesSet: longint;
    m_FVF: cardinal;
    m_Vsize: integer;
    m_Vpointer: Pointer;
    m_VertexCount: integer;
    m_IndexCount: integer;
    procedure SetSize(size: integer); virtual;
  public
    property VB: IDirect3DVertexBuffer9 read m_VB write m_VB;
    property IB: IDirect3DIndexBuffer9 read m_IB write m_IB;
    property Indices: TDIndexArray read m_Indices write m_Indices;
    property VertexCount: integer read m_VertexCount;
    property IndexCount: integer read m_IndexCount;
    function initVB(size: longint; Usage: DWord = 0): boolean;
    function initIB(size: longint; Usage: DWord = 0): boolean;
    procedure setVertices(offset: longint; count: integer);
    procedure setIndices(offset: longint; count: integer);
    procedure DrawPointList(firstVertex: integer; NumberOfPrimitives: integer);
    procedure DrawLineList(firstVertex: integer; NumberOfPrimitives: integer);
    procedure DrawIndexedLineList(firstIndex: integer; NumberOfPrimitives: integer);
    procedure DrawLineStrip(firstVertex: integer; NumberOfPrimitives: integer);
    procedure DrawIndexedLineStrip(firstIndex: integer; NumberOfPrimitives: integer);
    procedure DrawTriangleList(firstVertex: integer; NumberOfPrimitives: integer);
    procedure DrawIndexedTriangleList(firstIndex: integer; NumberOfPrimitives: integer);
    procedure DrawTriangleStrip(firstVertex: integer; NumberOfPrimitives: integer);
    procedure DrawIndexedTriangleStrip(firstIndex: integer; NumberOfPrimitives: integer);
    procedure DrawTriangleFan(firstVertex: integer; NumberOfPrimitives: integer);
    procedure DrawIndexedTriangleFan(firstIndex: integer; NumberOfPrimitives: integer);
    constructor Create(DanJetX: Pointer); virtual;
    destructor Destroy; override;
  end;

  TDJXVB3D = class(TDJXVBbase)
  private
    m_Vertices: TDVertex3DArray;
    procedure SetSize(size: longint); override;
  public
    property Vertices: TDVertex3DArray read m_Vertices write m_Vertices;
    constructor Create(DanJetX: Pointer); override;
    destructor Destroy; override;
  end;

  TDJXVB3DTex2 = class(TDJXVBbase)
  private
    m_Vertices: TDVertex3DTex2Array;
    procedure SetSize(size: longint); override;
  public
    property Vertices: TDVertex3DTex2Array read m_Vertices write m_Vertices;
    constructor Create(DanJetX: Pointer); override;
    destructor Destroy; override;
  end;

  TDJXVB2D = class(TDJXVBbase)
  private
    m_Vertices: TDVertex2DArray;
    procedure SetSize(size: longint); override;
  public
    property Vertices: TDVertex2DArray read m_Vertices write m_Vertices;
    constructor Create(DanJetX: Pointer); override;
    destructor Destroy; override;
  end;

  TDJXVB2DTex2 = class(TDJXVBbase)
  private
    m_Vertices: TDVertex2DTex2Array;
    procedure SetSize(size: longint); override;
  public
    property Vertices: TDVertex2DTex2Array read m_Vertices write m_Vertices;
    constructor Create(DanJetX: Pointer); override;
    destructor Destroy; override;
  end;

  TDJXVBFlex = class(TObject)
  private
    m_DanJetX: Pointer;
    m_Vertices: TDVertexFlexArray;
    m_VArr: TDVertexArray;
    m_Indices: TDIndexArray;
    m_VB: IDirect3DVertexBuffer9;
    m_IB: IDirect3DIndexBuffer9;
    m_VerticesSet: longint;
    m_Col: boolean;
    m_Norm: boolean;
    m_TexCount: byte;
    m_Pretransformed: boolean;
    m_SetFVF: DWORD;
  protected
    function GetFVF: Cardinal;
    function GetSize: Cardinal;
    function GetDeclaration: IDirect3DVertexDeclaration9;
  public
    property Vertices: TDVertexFlexArray read m_Vertices write m_Vertices;
    property Indices: TDIndexArray read m_Indices write m_Indices;
    property VF_Col: boolean read m_Col write m_Col default true;
    property VF_Norm: boolean read m_Norm write m_Norm default true;
    property VF_TexCount: byte read m_TexCount write m_TexCount;
    property VF_Pos2D: boolean read m_Pretransformed write m_Pretransformed default true;
    property FVF: DWORD read m_SetFVF;
    property Declaration: IDirect3DVertexDeclaration9 read GetDeclaration;
    function initVB(size: longint; Usage: DWord = 0): boolean;
    function initIB(size: longint; Usage: DWord = 0): boolean;
    procedure setVertices(offset: longint; count: integer);
    procedure setIndices(offset: longint; count: integer);
    property VB: IDirect3DVertexBuffer9 read m_VB write m_VB;
    property IB: IDirect3DIndexBuffer9 read m_IB write m_IB;
    procedure DrawPointList(firstVertex: integer; NumberOfPrimitives: integer);
    procedure DrawLineList(firstVertex: integer; NumberOfPrimitives: integer);
    procedure DrawIndexedLineList(firstIndex: integer; NumberOfPrimitives: integer);
    procedure DrawLineStrip(firstVertex: integer; NumberOfPrimitives: integer);
    procedure DrawIndexedLineStrip(firstIndex: integer; NumberOfPrimitives: integer);
    procedure DrawTriangleList(firstVertex: integer; NumberOfPrimitives: integer);
    procedure DrawIndexedTriangleList(firstIndex: integer; NumberOfPrimitives: integer);
    procedure DrawTriangleStrip(firstVertex: integer; NumberOfPrimitives: integer);
    procedure DrawIndexedTriangleStrip(firstIndex: integer; NumberOfPrimitives: integer);
    procedure DrawTriangleFan(firstVertex: integer; NumberOfPrimitives: integer);
    procedure DrawIndexedTriangleFan(firstIndex: integer; NumberOfPrimitives: integer);
    constructor Create(DanJetX: Pointer);
    destructor Destroy; override;
  end;

  PDJXMaterial9Array = ^TDJXMaterial9Array;
  TDJXMaterial9Array = array[0..0] of TD3DMaterial9;

  PDJXMaterialArray = ^TDJXMaterialArray;
  TDJXMaterialArray = array[0..0] of TD3DXMaterial;

  PDJXTexture9Array = ^IDJXTexture9Array;
  IDJXTexture9Array = array[0..0] of IDirect3DTexture9;

  PDJXMatrixPointerArray = ^TDJXMatrixPointerArray;
  TDJXMatrixPointerArray = array[0..MaxInt div SizeOf(Pointer) - 1] of PD3DXMatrix;

  PDJXMatrixArray = ^TDJXMatrixArray;
  TDJXMatrixArray = array[0..MaxInt div SizeOf(TD3DXMatrix) - 1] of TD3DXMatrix;

  PDJXAttributeRangeArray = ^TDJXAttributeRangeArray;
  TDJXAttributeRangeArray = array[0..MaxInt div SizeOf(TD3DXAttributeRange) - 1] of TD3DXAttributeRange;

  TDJXCullMode = (
    cullNone = D3DCULL_NONE,
    cullCW = D3DCULL_CW,
    cullCCW = D3DCULL_CCW
  );

  TDJXBlendMode = (
    bmNormal = 0,
    bmAdd = 1,
    bmSrcAdd = 2,
    bmSrcCol = 3,
    bmSrcColAdd = 4,
    bmMultiply = 5,
    bmMultiplyAlpha = 6,
    bmInvMultiply = 7,
    bmInvMultiplyAlpha = 8,
    bmInvert = 9,
    bmSrcBright = 10,
    bmDestBright = 11,
    bmInvSrcBright = 12,
    bmInvDestBright = 13,
    bmNoFrameRender = 14
  );

function DJXVertex3D(
           x,y,z: single;
           color: TDJXColor;
           tu,tv: single;
           nx,ny,nz: single
         ): TDJXVertex3D; overload;
function DJXVertex3D(
           x,y,z: single;
           color: TDJXColor;
           tu: single = 0; tv: single = 0
         ): TDJXVertex3D; overload;
function DJXVertex3DTex2(
           x,y,z: single;
           color: TDJXColor;
           tu1,tv1: single;
           tu2,tv2: single;
           nx,ny,nz: single
         ): TDJXVertex3DTex2;
function DJXVertex2D(
           x,y,z,rhw: single;
           color: TDJXColor;
           tu,tv: single
         ): TDJXVertex2D; overload;
function DJXVertex2D(
           x,y: single;
           color: TDJXColor;
           tu: single = 0; tv: single = 0
         ): TDJXVertex2D; overload;
function DJXVertex2DTex2(
           x,y: single;
           color: TDJXColor;
           tu1: single = 0; tv1: single = 0;
           tu2: single = 0; tv2: single = 0
         ): TDJXVertex2DTex2;
function DJXVertexFlex(
           x,y,z: single;
           nx: single = 0;
           ny: single = 0;
           nz: single = 0;
           color: TDJXColor = $ffffffff;
           tu1: single = 0; tv1: single = 0;
           tu2: single = 0; tv2: single = 0;
           tu3: single = 0; tv3: single = 0;
           tu4: single = 0; tv4: single = 0;
           tu5: single = 0; tv5: single = 0;
           tu6: single = 0; tv6: single = 0;
           tu7: single = 0; tv7: single = 0;
           tu8: single = 0; tv8: single = 0
         ): TDJXVertexFlex;
function DJXColor(r,g,b: byte;a:byte=255): TDJXColor; overload;
function DJXColor(Color: TColor; a: byte = 255): TDJXColor; overload;
function DJXColorR(Color: TDJXColor): byte;
function DJXColorG(Color: TDJXColor): byte;
function DJXColorB(Color: TDJXColor): byte;
function DJXColorA(Color: TDJXColor): byte;

const
  DJXFVF_VERTEX2D = (
    D3DFVF_XYZRHW or
    D3DFVF_DIFFUSE or
    D3DFVF_TEX1
  );
  DJXFVF_VERTEX2DTEX2 = (
    D3DFVF_XYZRHW or
    D3DFVF_DIFFUSE or
    D3DFVF_TEX2
  );
  DJXFVF_VERTEX3D = (
    D3DFVF_XYZ or
    D3DFVF_NORMAL or
    D3DFVF_DIFFUSE or
    D3DFVF_TEX1
  );
  DJXFVF_VERTEX3DTEX2 = (
    D3DFVF_XYZ or
    D3DFVF_NORMAL or
    D3DFVF_DIFFUSE or
    D3DFVF_TEX2
  );

  DegRad = pi / 180;
  RadDeg = 180 / pi;
  DefFOV = Pi / 4;

implementation

uses
  DJX, DJXRender, DJXUtils;

//TDJXComponent BEGIN
constructor TDJXComponent.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
end;
destructor TDJXComponent.Destroy;
begin
  inherited Destroy;
end;
procedure TDJXComponent.Init(DanJetX: Pointer);
begin
  m_DanJetX := DanJetX;
  TDanJetX(m_DanJetX).DJXComponentList.Add(self);
end;
procedure TDJXComponent.OnLostDevice;
begin

end;
procedure TDJXComponent.OnResetDevice;
begin

end;
//TDJXComponent END

//TDJXAdapter BEGIN
constructor TDJXAdapter.Create;
begin
  inherited Create;
end;
destructor TDJXAdapter.Destroy;
var
  i: integer;
begin
  for i := 0 to high(m_DisplayModes) do
  Dispose(m_DisplayModes[i]);
  SetLength(m_DisplayModes, 0);
  inherited Destroy;
end;

function TDJXAdapter.GetDisplayMode(Value: integer): PD3DDisplayMode;
begin
  if (Value >= 0) and (Value < Length(m_DisplayModes)) then
  Result := m_DisplayModes[Value];
end;
function TDJXAdapter.GetDisplayModeCount: DWORD;
begin
  Result := Length(m_DisplayModes);
end;
procedure TDJXAdapter.AddDisplayMode(Mode: TD3DDisplayMode);
begin
  SetLength(m_DisplayModes, Length(m_DisplayModes) + 1);
  New(m_DisplayModes[high(m_DisplayModes)]);
  move(Mode, m_DisplayModes[high(m_DisplayModes)]^, SizeOf(TD3DDisplayMode));
end;
//TDJXAdapter END

//TDJXSpecs BEGIN
constructor TDJXSpecs.Create;
begin
  inherited Create;
end;
destructor TDJXSpecs.Destroy;
begin
  ClearSpecs;
  inherited Destroy;
end;

function TDJXSpecs.GetAdapter(Value: integer): TDJXAdapter;
begin
  if (Value >= 0) and (Value < Length(m_Adapters)) then
  Result := m_Adapters[Value];
end;
function TDJXSpecs.GetAdapterCount: DWORD;
begin
  Result := Length(m_Adapters);
end;

procedure TDJXSpecs.ClearSpecs;
var
  i: integer;
begin
  for i := 0 to high(m_Adapters) do
  m_Adapters[i].Free;
  SetLength(m_Adapters, 0);
end;

procedure TDJXSpecs.CollectSpecs;
var
  D3D9: IDirect3D9;
  AdapterCount: DWORD;
  DisplayModeCount: DWORD;
  DisplayMode: TD3DDisplayMode;
  Format, i, j: integer;
const
  Formats: array [0..2] of TD3DFormat = (
    D3DFMT_A8R8G8B8,
    D3DFMT_X8R8G8B8,
    D3DFMT_R5G6B5
  );
begin
  ClearSpecs;

  D3D9 := Direct3DCreate9(D3D_SDK_VERSION);

  AdapterCount := D3D9.GetAdapterCount;

  SetLength(m_Adapters, AdapterCount);

  for i := 0 to AdapterCount - 1 do
  begin
    m_Adapters[i] := TDJXAdapter.Create;
    D3D9.GetAdapterIdentifier(i, 0, m_Adapters[i].m_AdapterIdentifier);
    D3D9.GetDeviceCaps(i, D3DDEVTYPE_HAL, m_Adapters[i].m_DeviceCaps);
    D3D9.GetAdapterDisplayMode(i, m_Adapters[i].m_CurrentDisplayMode);
    FillMemory(@m_Adapters[i].m_MultisampleSpecs, SizeOf(TDJXMultisampleSpecs), 1);
    m_Adapters[i].m_MultisampleSpecs.MaxQuality := 8;
    for Format := 0 to high(Formats) do
    begin
      m_Adapters[i].m_MultisampleSpecs.Multisample2X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample2X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_2_SAMPLES, nil
          )
        )
      );
      m_Adapters[i].m_MultisampleSpecs.Multisample3X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample3X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_3_SAMPLES, nil
          )
        )
      );
      m_Adapters[i].m_MultisampleSpecs.Multisample4X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample4X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_4_SAMPLES, nil
          )
        )
      );
      m_Adapters[i].m_MultisampleSpecs.Multisample5X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample5X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_5_SAMPLES, nil
          )
        )
      );
      m_Adapters[i].m_MultisampleSpecs.Multisample6X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample6X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_6_SAMPLES, nil
          )
        )
      );
      m_Adapters[i].m_MultisampleSpecs.Multisample7X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample7X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_7_SAMPLES, nil
          )
        )
      );
      m_Adapters[i].m_MultisampleSpecs.Multisample8X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample8X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_8_SAMPLES, nil
          )
        )
      );
      m_Adapters[i].m_MultisampleSpecs.Multisample9X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample9X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_9_SAMPLES, nil
          )
        )
      );
      m_Adapters[i].m_MultisampleSpecs.Multisample10X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample10X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_10_SAMPLES, nil
          )
        )
      );
      m_Adapters[i].m_MultisampleSpecs.Multisample11X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample11X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_11_SAMPLES, nil
          )
        )
      );
      m_Adapters[i].m_MultisampleSpecs.Multisample12X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample12X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_12_SAMPLES, nil
          )
        )
      );
      m_Adapters[i].m_MultisampleSpecs.Multisample13X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample13X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_13_SAMPLES, nil
          )
        )
      );
      m_Adapters[i].m_MultisampleSpecs.Multisample14X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample14X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_14_SAMPLES, nil
          )
        )
      );
      m_Adapters[i].m_MultisampleSpecs.Multisample15X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample15X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_15_SAMPLES, nil
          )
        )
      );
      m_Adapters[i].m_MultisampleSpecs.Multisample16X := (
        m_Adapters[i].m_MultisampleSpecs.Multisample16X and
        Succeeded(
          D3D9.CheckDeviceMultiSampleType(
            i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_16_SAMPLES, nil
          )
        )
      );
      while not Succeeded(
        D3D9.CheckDeviceMultiSampleType(
          i, D3DDEVTYPE_HAL, Formats[Format], false, D3DMULTISAMPLE_NONMASKABLE,
          @m_Adapters[i].m_MultisampleSpecs.MaxQuality
        )
      ) and (m_Adapters[i].m_MultisampleSpecs.MaxQuality > 0) do
      dec(m_Adapters[i].m_MultisampleSpecs.MaxQuality);

      DisplayModeCount := D3D9.GetAdapterModeCount(i, Formats[Format]);
      for j := 0 to DisplayModeCount - 1 do
      begin
        D3D9.EnumAdapterModes(i, Formats[Format], j, DisplayMode);
        m_Adapters[i].AddDisplayMode(DisplayMode);
      end;
    end;
    m_Adapters[i].m_MultisampleSpecs.MultisampleNonMaskable :=
    m_Adapters[i].m_MultisampleSpecs.MaxQuality > 0;

  end;

  safe_release(D3D9);
end;
//TDJXSpecs END

//TDJXVBRender BEGIN
constructor TDJXVBRender.Create(DanJetX: Pointer);
begin
  inherited Create;
  m_DanJetX := DanJetX;
end;
destructor TDJXVBRender.Destroy;
begin
  inherited Destroy;
end;

procedure TDJXVBRender.DrawPointList(StartVertex, PrimitiveCount: LongWord);
begin
  TDanJetX(m_DanJetX).Device.DrawPrimitive(D3DPT_POINTLIST,StartVertex,PrimitiveCount);
end;
procedure TDJXVBRender.DrawLineList(StartVertex, PrimitiveCount: LongWord);
begin
  TDanJetX(m_DanJetX).Device.DrawPrimitive(D3DPT_LINELIST,StartVertex,PrimitiveCount);
end;
procedure TDJXVBRender.DrawLineStrip(StartVertex, PrimitiveCount: LongWord);
begin
  TDanJetX(m_DanJetX).Device.DrawPrimitive(D3DPT_LINESTRIP,StartVertex,PrimitiveCount);
end;
procedure TDJXVBRender.DrawTriangleList(StartVertex, PrimitiveCount: LongWord);
begin
  TDanJetX(m_DanJetX).Device.DrawPrimitive(D3DPT_TRIANGLELIST,StartVertex,PrimitiveCount);
end;
procedure TDJXVBRender.DrawTriangleStrip(StartVertex, PrimitiveCount: LongWord);
begin
  TDanJetX(m_DanJetX).Device.DrawPrimitive(D3DPT_TRIANGLESTRIP,StartVertex,PrimitiveCount);
end;
procedure TDJXVBRender.DrawTriangleFan(StartVertex, PrimitiveCount: LongWord);
begin
  TDanJetX(m_DanJetX).Device.DrawPrimitive(D3DPT_TRIANGLEFAN,StartVertex,PrimitiveCount);
end;
procedure TDJXVBRender.DrawIndexedLineList(BaseVertexIndex: Integer; MinVertexIndex, NumVertices, startIndex, primCount: LongWord);
begin
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(D3DPT_LINELIST,BaseVertexIndex,MinVertexIndex,NumVertices,startIndex,primCount);
end;
procedure TDJXVBRender.DrawIndexedLineStrip(BaseVertexIndex: Integer; MinVertexIndex, NumVertices, startIndex, primCount: LongWord);
begin
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(D3DPT_LINESTRIP,BaseVertexIndex,MinVertexIndex,NumVertices,startIndex,primCount);
end;
procedure TDJXVBRender.DrawIndexedTriangleList(BaseVertexIndex: Integer; MinVertexIndex, NumVertices, startIndex, primCount: LongWord);
begin
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(D3DPT_TRIANGLELIST,BaseVertexIndex,MinVertexIndex,NumVertices,startIndex,primCount);
end;
procedure TDJXVBRender.DrawIndexedTriangleStrip(BaseVertexIndex: Integer; MinVertexIndex, NumVertices, startIndex, primCount: LongWord);
begin
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,BaseVertexIndex,MinVertexIndex,NumVertices,startIndex,primCount);
end;
procedure TDJXVBRender.DrawIndexedTriangleFan(BaseVertexIndex: Integer; MinVertexIndex, NumVertices, startIndex, primCount: LongWord);
begin
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(D3DPT_TRIANGLEFAN,BaseVertexIndex,MinVertexIndex,NumVertices,startIndex,primCount);
end;
//TDJXVBRender END

//TDJXVB BEGIN
constructor TDJXVB.Create(DanJetX: Pointer);
begin
  inherited Create;
  m_DanJetX := DanJetX;
end;
destructor TDJXVB.Destroy;
begin
  UnInit;
  inherited Destroy;
end;

function TDJXVB.getSize: Cardinal;
begin
  Result := 0;
  if m_VF_2D then
  Result := Result + sizeof(single) * 4
  else
  Result := Result + sizeof(single) * 3;
  if m_VF_Color then
  Result := Result + sizeof(TDJXColor);
  if m_VF_Normals then
  Result := Result + sizeof(single) * 3;
  Result := Result + sizeof(single) * 2 * m_VF_TexCount;
end;
procedure TDJXVB.SetVertex(Index: integer; Value: TDJXVertexFlex);
var
  VPointer: pbyte;
  VArrPos: cardinal;
begin
  VArrPos := Index * m_Size;
  VPointer := @Value;
  if m_VF_2D then
  begin
    move(VPointer^, m_VArr[VArrPos], 4 * sizeof(single));
    inc(VArrPos, 4 * sizeof(single));
  end
  else
  begin
    move(VPointer^, m_VArr[VArrPos], 3 * sizeof(single));
    inc(VArrPos, 3 * sizeof(single));
  end;
  inc(VPointer, 4 * sizeof(single));
  if m_VF_Normals then
  begin
    move(VPointer^, m_VArr[VArrPos], 3 * sizeof(single));
    inc(VArrPos, 3 * sizeof(single));
  end;
  inc(VPointer, 3 * sizeof(single));
  if m_VF_Color then
  begin
    move(VPointer^, m_VArr[VArrPos], sizeof(TDJXColor));
    inc(VArrPos, sizeof(TDJXColor));
  end;
  inc(VPointer, sizeof(TDJXColor));
  move(VPointer^, m_VArr[VArrPos], sizeof(single) * 2 * m_VF_TexCount);
end;
function TDJXVB.GetVertex(Index: integer): TDJXVertexFlex;
var
  VPointer: pbyte;
  VArrPos: cardinal;
begin
  VArrPos := Index * m_Size;
  ZeroMemory(@Result,sizeof(TDJXVertexFlex));
  VPointer := @Result;
  if m_VF_2D then
  begin
    move(m_VArr[VArrPos], VPointer^, 4 * sizeof(single));
    inc(VArrPos, 4 * sizeof(single));
  end
  else
  begin
    move(m_VArr[VArrPos], VPointer^, 3 * sizeof(single));
    inc(VArrPos, 3 * sizeof(single));
  end;
  inc(VPointer, 4 * sizeof(single));
  if m_VF_Normals then
  begin
    move(m_VArr[VArrPos], VPointer^, 3 * sizeof(single));
    inc(VArrPos, 3 * sizeof(single));
  end;
  inc(VPointer, 3 * sizeof(single));
  if m_VF_Color then
  begin
    move(m_VArr[VArrPos], VPointer^, sizeof(TDJXColor));
    inc(VArrPos, sizeof(TDJXColor));
  end;
  inc(VPointer, sizeof(TDJXColor));
  move(m_VArr[VArrPos], VPointer^, sizeof(single) * 2 * m_VF_TexCount);
end;
function TDJXVB.GetVertexPointer: Pointer;
begin
  Result := @m_VArr[0];
end;

function TDJXVB.Init(size: longint; Usage: DWord = 0): boolean;
begin
  result := false;
  if size <= 0 then exit;
  Safe_Release(m_VB);
  if FAILED(
    TDanJetX(m_DanJetX).Device.CreateVertexBuffer(
      size * getSize,
      Usage, getFVF,
      D3DPOOL_MANAGED, m_VB, nil
    )
  )
  then Exit;
  m_Size := getSize;
  m_FVF := getFVF;
  ZeroMemory(@m_Declaration,sizeof(m_Declaration));
  m_Declaration := getDeclaration;
  setLength(m_VArr,size * m_Size);
  m_Count := size;
  result := true;
end;
procedure TDJXVB.UnInit;
begin
  Safe_Release(m_VB);
end;
procedure TDJXVB.SetVertices(offset: longint; count: integer);
var
  pVertices: Pointer;
begin
  if FAILED(m_VB.Lock(offset, m_Size * count, pVertices, D3DLOCK_DISCARD))then Exit;
  CopyMemory(pVertices, @m_VArr[offset * m_Size], m_Size * count);
  m_VB.Unlock;
end;
procedure TDJXVB.SetToDevice;
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, m_Size);
  TDanJetX(m_DanJetX).Device.SetFVF(m_FVF);
end;
function TDJXVB.getFVF: Cardinal;
begin
  Result:=0;
  if m_VF_2D then
  Result:=Result or D3DFVF_XYZRHW
  else
  Result:=Result or D3DFVF_XYZ;
  if m_VF_Color then
  Result:=Result or D3DFVF_DIFFUSE;
  if m_VF_Normals then
  Result:=Result or D3DFVF_NORMAL;
  case m_VF_TexCount of
    1: Result:=Result or D3DFVF_TEX1;
    2: Result:=Result or D3DFVF_TEX2;
    3: Result:=Result or D3DFVF_TEX3;
    4: Result:=Result or D3DFVF_TEX4;
    5: Result:=Result or D3DFVF_TEX5;
    6: Result:=Result or D3DFVF_TEX6;
    7: Result:=Result or D3DFVF_TEX7;
    8: Result:=Result or D3DFVF_TEX8;
  end;
end;
function TDJXVB.getDeclaration: TFVFDeclaration;
begin
  D3DXDeclaratorFromFVF(m_FVF, result);
end;
function TDJXVB.getVertexDeclaration: IDirect3DVertexDeclaration9;
begin
  TDanJetX(m_DanJetX).Device.CreateVertexDeclaration(@m_Declaration[0], result);
end;
//TDJXVB END

//TDJXIB BEGIN
constructor TDJXIB.Create(DanJetX: Pointer);
begin
  inherited Create;
  m_DanJetX := DanJetX;
  m_Format := D3DFMT_INDEX16;
end;
destructor TDJXIB.Destroy;
begin
  UnInit;
  inherited Destroy;
end;

function TDJXIB.Init(size: longint; Usage: DWord = 0): boolean;
begin
  result := false;

  if size <= 0 then exit;

  Safe_Release(m_IB);

  if FAILED(
    TDanJetX(m_DanJetX).Device.CreateIndexBuffer(
      size * SizeOf(word),
      Usage, m_Format,
      D3DPOOL_MANAGED, m_IB, nil
    )
  )
  then Exit;

  setLength(m_Indices, size);
  m_Count := size;
  result := true;
end;
procedure TDJXIB.UnInit;
begin
  Safe_Release(m_IB);
end;
procedure TDJXIB.SetIndices(offset: longint; count: integer);
var
  pIndices: Pointer;
begin
  if FAILED(m_IB.Lock(offset, SizeOf(word) * count, pIndices, D3DLOCK_DISCARD))then Exit;
  CopyMemory(pIndices, @m_Indices[offset], SizeOf(word) * count);
  m_IB.Unlock;
end;
procedure TDJXIB.SetToDevice;                                
begin
  TDanJetX(m_DanJetX).Device.SetIndices(m_IB);
end;
//TDJXIB END

//TDJXVertexBuffer base class BEGIN
constructor TDJXVBbase.create(DanJetX: Pointer);
begin
  inherited create;
  m_DanJetX := DanJetX;
  m_VerticesSet := 0;
  m_FVF := DJXFVF_VERTEX2D;
  m_Vsize := sizeof(TDJXVertex2D);
end;
destructor TDJXVBbase.Destroy;
begin
  safe_release(m_VB);
  safe_release(m_IB);
  inherited Destroy;
end;
procedure TDJXVBbase.SetSize(size: integer);
begin

end;
function TDJXVBbase.initVB(size: longint; Usage: DWord = 0): boolean;
begin
  result := false;

  if size <= 0 then exit;

  safe_release(m_VB);

  if FAILED(
    TDanJetX(m_DanJetX).Device.CreateVertexBuffer(
      size * m_Vsize,
      Usage, m_FVF,
      D3DPOOL_MANAGED,
      m_VB, nil
    )
  )
  then Exit;

  SetSize(size);

  m_VertexCount := size;
  
  result := true;
end;
function TDJXVBbase.initIB(size: longint; Usage: DWord = 0): boolean;
begin
  result := false;

  if size <= 0 then exit;

  safe_release(m_IB);

  if FAILED(
    TDanJetX(m_DanJetX).Device.CreateIndexBuffer(
      size * SizeOf(word),
      Usage, D3DFMT_INDEX16,
      D3DPOOL_MANAGED, m_IB, nil
    )
  )
  then Exit;

  setLength(m_Indices, size);

  m_IndexCount := size;

  result := true;
end;
procedure TDJXVBbase.setVertices(offset: longint; count: integer);
var
  pVertices: Pointer;
begin
  m_VerticesSet := count;
  if FAILED(m_VB.Lock(offset, m_Vsize * count, pVertices, D3DLOCK_DISCARD))
  then Exit;
  CopyMemory(pVertices, m_Vpointer, m_Vsize * count);
  m_VB.Unlock;
end;
procedure TDJXVBbase.setIndices(offset: longint; count: integer);
var
  pIndices: Pointer;
begin
  if FAILED(m_IB.Lock(offset, SizeOf(word) * count, pIndices, D3DLOCK_DISCARD))
  then Exit;
  CopyMemory(pIndices, @m_Indices[offset], SizeOf(word) * count);
  m_IB.Unlock;
end;
procedure TDJXVBbase.DrawPointList(firstVertex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, m_Vsize);
  TDanJetX(m_DanJetX).Device.SetFVF(m_FVF);
  TDanJetX(m_DanJetX).Device.DrawPrimitive(
    D3DPT_POINTLIST, firstVertex, NumberOfPrimitives
  );
end;
procedure TDJXVBbase.DrawLineList(firstVertex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, m_Vsize);
  TDanJetX(m_DanJetX).Device.SetFVF(m_FVF);
  TDanJetX(m_DanJetX).Device.DrawPrimitive(
    D3DPT_LINELIST, firstVertex, NumberOfPrimitives
  );
end;
procedure TDJXVBbase.DrawIndexedLineList(firstIndex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, m_Vsize);
  TDanJetX(m_DanJetX).Device.SetIndices(m_IB);
  TDanJetX(m_DanJetX).Device.SetFVF(m_FVF);
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(
    D3DPT_LINELIST, 0, 0, m_VerticesSet, firstIndex, NumberOfPrimitives
  );
end;
procedure TDJXVBbase.DrawLineStrip(firstVertex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, m_Vsize);
  TDanJetX(m_DanJetX).Device.SetFVF(m_FVF);
  TDanJetX(m_DanJetX).Device.DrawPrimitive(
    D3DPT_LINESTRIP, firstVertex, NumberOfPrimitives
  );
end;
procedure TDJXVBbase.DrawIndexedLineStrip(firstIndex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, m_Vsize);
  TDanJetX(m_DanJetX).Device.SetIndices(m_IB);
  TDanJetX(m_DanJetX).Device.SetFVF(m_FVF);
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(
    D3DPT_LINESTRIP, 0, 0, m_VerticesSet, firstIndex, NumberOfPrimitives
  );
end;
procedure TDJXVBbase.DrawTriangleList(firstVertex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, m_Vsize);
  TDanJetX(m_DanJetX).Device.SetFVF(m_FVF);
  TDanJetX(m_DanJetX).Device.DrawPrimitive(
    D3DPT_TRIANGLELIST, firstVertex, NumberOfPrimitives
  );
end;
procedure TDJXVBbase.DrawIndexedTriangleList(firstIndex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, m_Vsize);
  TDanJetX(m_DanJetX).Device.SetIndices(m_IB);
  TDanJetX(m_DanJetX).Device.SetFVF(m_FVF);
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(
    D3DPT_TRIANGLELIST, 0, 0, m_VerticesSet, firstIndex, NumberOfPrimitives
  );
end;
procedure TDJXVBbase.DrawTriangleStrip(firstVertex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, m_Vsize);
  TDanJetX(m_DanJetX).Device.SetFVF(m_FVF);
  TDanJetX(m_DanJetX).Device.DrawPrimitive(
    D3DPT_TRIANGLESTRIP, firstVertex, NumberOfPrimitives
  );
end;
procedure TDJXVBbase.DrawIndexedTriangleStrip(firstIndex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, m_Vsize);
  TDanJetX(m_DanJetX).Device.SetIndices(m_IB);
  TDanJetX(m_DanJetX).Device.SetFVF(m_FVF);
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(
    D3DPT_TRIANGLESTRIP, 0, 0, m_VerticesSet, firstIndex, NumberOfPrimitives
  );
end;
procedure TDJXVBbase.DrawTriangleFan(firstVertex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, m_Vsize);
  TDanJetX(m_DanJetX).Device.SetFVF(m_FVF);
  TDanJetX(m_DanJetX).Device.DrawPrimitive(
    D3DPT_TRIANGLEFAN, firstVertex, NumberOfPrimitives
  );
end;
procedure TDJXVBbase.DrawIndexedTriangleFan(firstIndex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, m_Vsize);
  TDanJetX(m_DanJetX).Device.SetIndices(m_IB);
  TDanJetX(m_DanJetX).Device.SetFVF(m_FVF);
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(
    D3DPT_TRIANGLEFAN, 0, 0, m_VerticesSet, firstIndex, NumberOfPrimitives
  );
end;
//TDJXVertexBuffer base class END

//DJXVertexBuffer3D BEGIN
constructor TDJXVB3D.create(DanJetX: Pointer);
begin
  inherited create(DanJetX);
  m_Vsize := sizeof(TDJXVertex3D);
  m_FVF := DJXFVF_VERTEX3D;
end;
destructor TDJXVB3D.Destroy;
begin
  inherited Destroy;
end;
procedure TDJXVB3D.SetSize(size: longint);
begin
  SetLength(m_Vertices, size);
  m_VPointer := @m_Vertices[0];
end;
//DJXVertexBuffer3D END

//DJXVertexBuffer3DTex2 BEGIN
constructor TDJXVB3DTex2.create(DanJetX: Pointer);
begin
  inherited create(DanJetX);
  m_Vsize := sizeof(TDJXVertex3DTex2);
  m_FVF := DJXFVF_VERTEX3DTEX2;
end;
destructor TDJXVB3DTex2.Destroy;
begin
  inherited Destroy;
end;
procedure TDJXVB3DTex2.SetSize(size: longint);
begin
  SetLength(m_Vertices, size);
  m_VPointer := @m_Vertices[0];
end;
//DJXVertexBuffer3DTex2 END


//DJXVertexBuffer2D BEGIN
constructor TDJXVB2D.create(DanJetX: Pointer);
begin
  inherited create(DanJetX);
  m_Vsize := sizeof(TDJXVertex2D);
  m_FVF := DJXFVF_VERTEX2D;
end;
destructor TDJXVB2D.Destroy;
begin
  inherited Destroy;
end;                        
procedure TDJXVB2D.SetSize(size: longint);
begin
  SetLength(m_Vertices,size);
  m_VPointer := @m_Vertices[0];
end;
//DJXVertexBuffer2D END

//DJXVertexBuffer2DTex2 BEGIN
constructor TDJXVB2DTex2.create(DanJetX: Pointer);
begin
  inherited create(DanJetX);
  m_Vsize := sizeof(TDJXVertex2DTex2);
  m_FVF := DJXFVF_VERTEX2DTEX2;
end;
destructor TDJXVB2DTex2.Destroy;
begin
  inherited Destroy;
end;
procedure TDJXVB2DTex2.SetSize(size: longint);
begin
  SetLength(m_Vertices, size);
  m_VPointer := @m_Vertices[0];
end;
//DJXVertexBuffer2DTex2 END

//DJXVertexBufferFlex BEGIN
constructor TDJXVBFlex.create(DanJetX: Pointer);
begin
  inherited create;
  m_DanJetX := DanJetX;
  m_VerticesSet := 0;
  m_Col := true;
  m_Norm := true;
  m_Pretransformed := true;
  m_TexCount := 1;
  m_SetFVF := 0;
end;
destructor TDJXVBFlex.Destroy;
begin
  safe_release(m_VB);
  safe_release(m_IB);
  inherited Destroy;
end;
function TDJXVBFlex.getFVF: Cardinal;
begin
  Result := 0;
  if m_Pretransformed then
  Result := Result or D3DFVF_XYZRHW
  else
  Result := Result or D3DFVF_XYZ;
  if m_Col then
  Result := Result or D3DFVF_DIFFUSE;
  if m_Norm then
  Result := Result or D3DFVF_NORMAL;
  case m_TexCount of
    1: Result:=Result or D3DFVF_TEX1;
    2: Result:=Result or D3DFVF_TEX2;
    3: Result:=Result or D3DFVF_TEX3;
    4: Result:=Result or D3DFVF_TEX4;
    5: Result:=Result or D3DFVF_TEX5;
    6: Result:=Result or D3DFVF_TEX6;
    7: Result:=Result or D3DFVF_TEX7;
    8: Result:=Result or D3DFVF_TEX8;
  end;
end;
function TDJXVBFlex.getSize: Cardinal;
var
  i: integer;
begin
  Result := 0;
  if m_Pretransformed then
  Result := Result + sizeof(single) * 4
  else
  Result := Result + sizeof(single) * 3;
  if m_Col then
  Result := Result + sizeof(TDJXColor);
  if m_Norm then
  Result := Result + sizeof(single) * 3;
  for i := 0 to m_TexCount - 1 do
  Result := Result + sizeof(single) * 2;
end;
function TDJXVBFlex.GetDeclaration: IDirect3DVertexDeclaration9;
var
  Decl: TFVFDeclaration;
begin
  D3DXDeclaratorFromFVF(
    m_SetFVF,
    Decl
  );
  TDanJetX(m_DanJetX).Device.CreateVertexDeclaration(@Decl[0], Result);
end;
function TDJXVBFlex.initVB(size: longint; Usage: DWord = 0): boolean;
begin
  result := false;

  if size <= 0 then exit;

  safe_release(m_VB);

  m_SetFVF := getFVF;

  if FAILED(TDanJetX(m_DanJetX).Device.CreateVertexBuffer(
  size * getSize,
  Usage, m_SetFVF,
  D3DPOOL_MANAGED, m_VB, nil))
  then Exit;

  setLength(m_Vertices, size);
  setLength(m_VArr, size * getSize);
  
  result := true;
end;
function TDJXVBFlex.initIB(size: longint; Usage: DWord = 0): boolean;
begin
  result := false;

  if size <= 0 then exit;

  safe_release(m_IB);

  if FAILED(TDanJetX(m_DanJetX).Device.CreateIndexBuffer(
  size * SizeOf(word),
  Usage, D3DFMT_INDEX16,
  D3DPOOL_MANAGED, m_IB, nil))
  then Exit;

  setLength(m_Indices, size);

  result := true;
end;
procedure TDJXVBFlex.setVertices(offset: longint; count: integer);
var
  pVertices: Pointer;
  VPointer: pbyte;
  VArrPos: LongInt;
  i: integer;
begin
  VArrPos := 0;
  for i := offset to offset + count - 1 do
  begin
    VPointer := @m_Vertices[i];
    if m_Pretransformed then
    begin
      move(VPointer^, m_VArr[VArrPos], 4 * sizeof(single));
      inc(VArrPos, 4 * sizeof(single));
    end
    else
    begin
      move(VPointer^, m_VArr[VArrPos], 3 * sizeof(single));
      inc(VArrPos, 3 * sizeof(single));
    end;
    inc(VPointer, 4 * sizeof(single));
    if m_Norm then
    begin
      move(VPointer^, m_VArr[VArrPos], 3 * sizeof(single));
      inc(VArrPos, 3 * sizeof(single));
    end;
    inc(VPointer, 3 * sizeof(single));
    if m_Col then
    begin
      move(VPointer^, m_VArr[VArrPos], sizeof(TDJXColor));
      inc(VArrPos, sizeof(TDJXColor));
    end;
    inc(VPointer, sizeof(TDJXColor));
    move(VPointer^, m_VArr[VArrPos], sizeof(single) * 2 * m_TexCount);
    inc(VArrPos, sizeof(single) * 2 * m_TexCount);
  end;
  m_VerticesSet := count;
  if FAILED(m_VB.Lock(offset, getSize * count, pVertices, D3DLOCK_DISCARD))
  then Exit;
  CopyMemory(pVertices, @m_VArr[0], getSize * count);
  m_VB.Unlock;
end;
procedure TDJXVBFlex.setIndices(offset: longint; count: integer);
var
  pIndices: Pointer;
begin
  if FAILED(m_IB.Lock(offset, SizeOf(word) * count, pIndices, D3DLOCK_DISCARD))
  then Exit;
  CopyMemory(pIndices, @m_Indices[offset], SizeOf(word) * count);
  m_IB.Unlock;
end;
procedure TDJXVBFlex.DrawPointList(firstVertex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, getSize);
  TDanJetX(m_DanJetX).Device.SetFVF(getFVF);
  TDanJetX(m_DanJetX).Device.DrawPrimitive(
    D3DPT_POINTLIST, firstVertex, NumberOfPrimitives
  );
end;
procedure TDJXVBFlex.DrawLineList(firstVertex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, getSize);
  TDanJetX(m_DanJetX).Device.SetFVF(getFVF);
  TDanJetX(m_DanJetX).Device.DrawPrimitive(
    D3DPT_LINELIST, firstVertex, NumberOfPrimitives
  );
end;
procedure TDJXVBFlex.DrawIndexedLineList(firstIndex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, getSize);
  TDanJetX(m_DanJetX).Device.SetIndices(m_IB);
  TDanJetX(m_DanJetX).Device.SetFVF(getFVF);
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(
    D3DPT_LINELIST, 0, 0, m_VerticesSet, firstIndex, NumberOfPrimitives
  );
end;
procedure TDJXVBFlex.DrawLineStrip(firstVertex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, getSize);
  TDanJetX(m_DanJetX).Device.SetFVF(getFVF);
  TDanJetX(m_DanJetX).Device.DrawPrimitive(
    D3DPT_LINESTRIP, firstVertex, NumberOfPrimitives
  );
end;
procedure TDJXVBFlex.DrawIndexedLineStrip(firstIndex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, getSize);
  TDanJetX(m_DanJetX).Device.SetIndices(m_IB);
  TDanJetX(m_DanJetX).Device.SetFVF(getFVF);
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(
    D3DPT_LINESTRIP, 0, 0, m_VerticesSet, firstIndex, NumberOfPrimitives
  );
end;
procedure TDJXVBFlex.DrawTriangleList(firstVertex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, getSize);
  TDanJetX(m_DanJetX).Device.SetFVF(getFVF);
  TDanJetX(m_DanJetX).Device.DrawPrimitive(
    D3DPT_TRIANGLELIST, firstVertex, NumberOfPrimitives
  );
end;
procedure TDJXVBFlex.DrawIndexedTriangleList(firstIndex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, getSize);
  TDanJetX(m_DanJetX).Device.SetIndices(m_IB);
  TDanJetX(m_DanJetX).Device.SetFVF(getFVF);
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(
    D3DPT_TRIANGLELIST, 0, 0, m_VerticesSet, firstIndex, NumberOfPrimitives
  );
end;
procedure TDJXVBFlex.DrawTriangleStrip(firstVertex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, getSize);
  TDanJetX(m_DanJetX).Device.SetFVF(getFVF);
  TDanJetX(m_DanJetX).Device.DrawPrimitive(
    D3DPT_TRIANGLESTRIP, firstVertex, NumberOfPrimitives
  );
end;
procedure TDJXVBFlex.DrawIndexedTriangleStrip(firstIndex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, getSize);
  TDanJetX(m_DanJetX).Device.SetIndices(m_IB);
  TDanJetX(m_DanJetX).Device.SetFVF(getFVF);
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(
    D3DPT_TRIANGLESTRIP, 0, 0, m_VerticesSet, firstIndex, NumberOfPrimitives
  );
end;
procedure TDJXVBFlex.DrawTriangleFan(firstVertex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, getSize);
  TDanJetX(m_DanJetX).Device.SetFVF(getFVF);
  TDanJetX(m_DanJetX).Device.DrawPrimitive(
    D3DPT_TRIANGLEFAN, firstVertex, NumberOfPrimitives
  );
end;
procedure TDJXVBFlex.DrawIndexedTriangleFan(firstIndex: integer; NumberOfPrimitives: integer);
begin
  TDanJetX(m_DanJetX).Device.SetStreamSource(0, m_VB, 0, getSize);
  TDanJetX(m_DanJetX).Device.SetIndices(m_IB);
  TDanJetX(m_DanJetX).Device.SetFVF(getFVF);
  TDanJetX(m_DanJetX).Device.DrawIndexedPrimitive(
    D3DPT_TRIANGLEFAN, 0, 0, m_VerticesSet, firstIndex, NumberOfPrimitives
  );
end;
//DJXVertexBufferFlex END

//DJXColor BEGIN
function DJXColor(r,g,b: byte; a: byte = 255): TDJXColor;
begin
  result := (a shl 24) or (r shl 16) or (g shl 8) or b;
end;
function DJXColor(Color: TColor; a: byte = 255): TDJXColor;
var
  r,g,b: byte;
begin
  r := color and $ff;
  g := (color shr 8) and $ff;
  b := (color shr 16) and $ff;
  result := DJXColor(r,g,b,a)
end;
function DJXColorR(Color: TDJXColor): byte;
begin
  result := (Color shr 16) and $ff;
end;
function DJXColorG(Color: TDJXColor): byte;
begin
  result := (Color shr 8) and $ff;
end;
function DJXColorB(Color: TDJXColor): byte;
begin
  result := color and $ff;
end;
function DJXColorA(Color: TDJXColor): byte;
begin
  result := (color shr 24) and $ff;
end;
//DJXCOlor END

//DJXVertex2D BEGIN
function DJXVertex2D(
           x,y,z,rhw: single;
           color: TDJXColor;
           tu,tv: single
         ): TDJXVertex2D;
begin
  result.x := x;
  result.y := y;
  result.z := z;
  result.rhw := rhw;
  result.color := color;
  result.tu := tu;
  result.tv := tv;
end;
function DJXVertex2D(
           x,y: single;
           color: TDJXColor;
           tu: single = 0; tv: single = 0
         ): TDJXVertex2D;
begin
  result.x := x;
  result.y := y;
  result.z := 1;
  result.rhw := 1;
  result.color := color;
  result.tu := tu;
  result.tv := tv;
end;
function DJXVertex2DTex2(
           x,y: single;
           color: TDJXColor;
           tu1: single = 0; tv1: single = 0;
           tu2: single = 0; tv2: single = 0
         ): TDJXVertex2DTex2;
begin
  result.x := x;
  result.y := y;
  result.z := 1;
  result.rhw := 1;
  result.color := color;
  result.tu1 := tu1;
  result.tv1 := tv1;
  result.tu2 := tu2;
  result.tv2 := tv2;
end;
//DJXVertex2D END

//DJXVertex3D BEGIN
function DJXVertex3D(
           x,y,z: single;
           color: TDJXColor;
           tu: single = 0; tv: single = 0
         ): TDJXVertex3D;
begin
  result.x := x;
  result.y := y;
  result.z := z;
  result.nx := 0;
  result.ny := 0;
  result.nz := 0;
  result.color := color;
  result.tu := tu;
  result.tv := tv;
end;
function DJXVertex3D(
           x,y,z: single;
           color: TDJXColor;
           tu,tv: single;
           nx,ny,nz: single
         ): TDJXVertex3D;
begin
  result.x := x;
  result.y := y;
  result.z := z;
  result.nx := nx;
  result.ny := ny;
  result.nz := nz;
  result.color := color;
  result.tu := tu;
  result.tv := tv;
end;
function DJXVertex3DTex2(
           x,y,z: single;
           color: TDJXColor;
           tu1,tv1: single;
           tu2,tv2: single;
           nx,ny,nz: single
         ): TDJXVertex3DTex2;
begin
  result.x := x;
  result.y := y;
  result.z := z;
  result.nx := nx;
  result.ny := ny;
  result.nz := nz;
  result.color := color;
  result.tu1 := tu1;
  result.tv1 := tv1;
  result.tu2 := tu2;
  result.tv2 := tv2;
end;
//DJXVertex3D END

//DJXVertexFlex BEGIN
function DJXVertexFlex(
           x,y,z: single;
           nx: single = 0;
           ny: single = 0;
           nz: single = 0;
           color: TDJXColor = $ffffffff;
           tu1: single = 0; tv1: single = 0;
           tu2: single = 0; tv2: single = 0;
           tu3: single = 0; tv3: single = 0;
           tu4: single = 0; tv4: single = 0;
           tu5: single = 0; tv5: single = 0;
           tu6: single = 0; tv6: single = 0;
           tu7: single = 0; tv7: single = 0;
           tu8: single = 0; tv8: single = 0
         ): TDJXVertexFlex;
begin
  result.x := x;
  result.y := y;
  result.z := z;
  result.rhw := 1;
  result.nx := nx;
  result.ny := ny;
  result.nz := nz;
  result.color := color;
  result.tu1 := tu1;
  result.tv1 := tv1;
  result.tu2 := tu2;
  result.tv2 := tv2;
  result.tu3 := tu3;
  result.tv3 := tv3;
  result.tu4 := tu4;
  result.tv4 := tv4;
  result.tu5 := tu5;
  result.tv5 := tv5;
  result.tu6 := tu6;
  result.tv6 := tv6;
  result.tu7 := tu7;
  result.tv7 := tv7;
  result.tu8 := tu8;
  result.tv8 := tv8;
end;
//DJXVertexFlex END

end.
