//DJXRender v1.3
unit DJXRender;

interface

uses
  Windows,
  Classes,
  SysUtils,
  DJXClasses,
  DJXTextures,
  DJXShaders,
  DJXUtils,
  Direct3D9,
  D3DX9;

type
  TDJXShaders = class;

  TDJXRender = class(TObject)
  private
    m_DanJetX: Pointer;
    m_VB2D: TDJXVB2D;
    m_VB3D: TDJXVB3D;
    m_Shaders: TDJXShaders;
    m_matWorld, m_matView, m_matProj, m_matTex: TD3DMatrix;
  protected
    function GetMatWorld: PD3DXMatrix;
    function GetMatView: PD3DXMatrix;
    function GetMatProj: PD3DXMatrix;
    function GetMatTex: PD3DXMatrix;
  public
    constructor Create(DanJetX: Pointer);
    destructor Destroy; override;
    property DanJetX: Pointer read m_DanJetX write m_DanJetX;
    property MatWorld: PD3DXMatrix read GetMatWorld;
    property MatView: PD3DXMatrix read GetMatView;
    property MatProj: PD3DXMatrix read GetMatProj;
    property MatTex: PD3DXMatrix read GetMatTex;
    property Shaders: TDJXShaders read m_Shaders write m_Shaders;
    procedure Init;
    procedure UnInit;
    procedure DrawTexture2D(
      x1,y1,x2,y2,x3,y3,x4,y4: single;
      col1,col2,col3,col4: TDJXColor;
      CenterX,CenterY,Rotation,ScaleX,ScaleY:single;
      Texture: TDJXTexture;
      FlipTopBottom: boolean = false;
      FlipLeftRight: boolean = false;
      ImageIndex: integer=0;
      TileWidth: integer=0; TileHeight: integer=0
    );
    procedure DrawBillboard(
      x,y,z: single;
      x1,y1,x2,y2,x3,y3,x4,y4: single;
      col1,col2,col3,col4: TDJXColor;
      Rotation, ScaleX, ScaleY: single;
      Texture: TDJXTexture;
      ImageIndex: integer;
      TileWidth: integer=0; TileHeight: integer=0
    );
    procedure DrawBillboardCyl(
      p1x,p1y,p1z: single;
      p2x,p2y,p2z: single;
      x1,y1,x2,y2,x3,y3,x4,y4: single;
      col1,col2,col3,col4: TDJXColor;
      Scale: single;
      Texture: TDJXTexture;
      ImageIndex: integer;
      TileWidth: integer=0; TileHeight: integer=0
    );
    procedure Prs2DTransformVertices(
      CenterX,CenterY: single;
      Rotation: single;
      Texture: TDJXTexture = nil;
      TileWidth: integer = 0;
      TileHeight: integer = 0;
      ScaleX: single = 1;
      ScaleY: single = 1
    );
    procedure Prs3DClearWorldMatrix;
    procedure Prs3DApplyWorldMatrix;
    procedure Prs3DInverseWorldTo(SrcMatrix: TD3DMatrix);
    procedure Prs3DScaleWorld(X, Y, Z: single);
    procedure Prs3DRotateWorldAroundVector(X, Y, Z: single; angle: single);
    procedure Prs3DRotateWorld(Xangle, Yangle, Zangle: single);
    procedure Prs3DRotateWorldX(Angle: single);
    procedure Prs3DRotateWorldY(Angle: single);
    procedure Prs3DRotateWorldZ(Angle: single);
    procedure Prs3DMoveWorld(X, Y, Z: double);
    procedure Prs3DMultiplyWorld(m: TD3DXMatrix);
    procedure Prs3DPreScaleWorld(X, Y, Z: single);
    procedure Prs3DPreRotateWorldAroundVector(X, Y, Z: single; angle: single);
    procedure Prs3DPreRotateWorld(Xangle, Yangle, Zangle: single);
    procedure Prs3DPreRotateWorldX(Angle: single);
    procedure Prs3DPreRotateWorldY(Angle: single);
    procedure Prs3DPreRotateWorldZ(Angle: single);
    procedure Prs3DPreMoveWorld(X, Y, Z: double);
    procedure Prs3DPreMultiplyWorld(m: TD3DXMatrix);
    procedure PrsTexClearTexMatrix;
    procedure PrsTexApplyTexMatrix(Stage: byte);
    procedure PrsTexScaleTex(X, Y, Z: single);
    procedure PrsTexRotateTexAroundVector(X, Y, Z: single; angle: single);
    procedure PrsTexRotateTex(Xangle, Yangle, Zangle: single);
    procedure PrsTexRotateTexX(Angle: single);
    procedure PrsTexRotateTexY(Angle: single);
    procedure PrsTexRotateTexZ(Angle: single);
    procedure PrsTexMoveTex(X, Y, Z: double);
    procedure Prs3DSetView(eyePtX, eyePtY, eyePtZ: single; LookAtX, LookAtY, LookAtZ: single; upVecX, upVecY, upVecZ: single); overload;
    procedure Prs3DSetView(eyePt, LookAt, upVec: TD3DXVector3); overload;
    procedure Prs3DSetPerspective(Aspect, ZNear, ZFar: single; FOV: single = defFOV); overload;
    procedure Prs3DSetPerspective; overload;
    procedure Prs3DSetPerspectiveORT(Width, Height, ZNear, ZFar: single); overload;
    procedure Prs3DSetPerspectiveORT; overload;
  end;

  TDJXShaders = class
  private
    m_DanJetX: Pointer;
    m_Shaders: TList;
  protected
    function getItem(Index: integer): TDJXShader;
    procedure setItem(Index: integer; Value: TDJXShader);
    procedure LoadShaders;
    procedure UnLoadShaders;
  public
    property Shader[Index: integer]: TDJXShader read getItem write setItem;
  published
    constructor Create(DanJetX: Pointer);
    destructor Destroy; override;
    function Find(name: string): TDJXShader;
    function Add(Shader: TDJXShader): TDJXShader;
    function LoadVertexShaderFromMemory(Ptr: Pointer; Size: DWORD; NameInList: string): TDJXVertexShader;
    function LoadPixelShaderFromMemory(Ptr: Pointer; Size: DWORD; NameInList: string): TDJXPixelShader;
    procedure OnLostDevice;
    procedure OnResetDevice;
  end;

  TDJXFrustumPlane = record
    normal: TD3DXVector3;
    distance: single;
  end;
  TDJXFrustum = class(TObject)
  private
    m_Planes: array[0..5] of TDJXFrustumPlane;
    function GetPlane(Index: integer): TDJXFrustumPlane;
  public
    property Planes[Index: integer]: TDJXFrustumPlane read GetPlane;
    procedure Normalize;
    function DistanceToPoint(PlaneIndex: integer; Pt: TD3DXVector3): single;
  end;
  
  TDJXCamera = class(TObject)
  private
    m_DanJetX: Pointer;
    m_eyePtX,m_eyePtY,m_eyePtZ: single;
    m_LookAtX,m_LookAtY,m_LookAtZ: single;
    m_upVecX,m_upVecY,m_upVecZ: single;
  protected
    procedure SetEyePtX(Value: single);
    procedure SetEyePtY(Value: single);
    procedure SetEyePtZ(Value: single);
    procedure SetLookAtX(Value: single);
    procedure SetLookAtY(Value: single);
    procedure SetLookAtZ(Value: single);
    procedure SetUpVecX(Value: single);
    procedure SetUpVecY(Value: single);
    procedure SetUpVecZ(Value: single);
  public
    property EyePtX: single read m_eyePtX write SetEyePtX;
    property EyePtY: single read m_eyePtY write SetEyePtY;
    property EyePtZ: single read m_eyePtZ write SetEyePtZ;
    property LookAtX: single read m_LookAtX write SetLookAtX;
    property LookAtY: single read m_LookAtY write SetLookAtY;
    property LookAtZ: single read m_LookAtZ write SetLookAtZ;
    property UpVecX: single read m_upVecX write SetUpVecX;
    property UpVecY: single read m_upVecY write SetUpVecY;
    property UpVecZ: single read m_upVecZ write SetUpVecZ;
    procedure SetView(
      NewEyePtX, NewEyePtY, NewEyePtZ: single;
      NewLookAtX, NewLookAtY, NewLookAtZ: single;
      NewupVecX, NewupVecY, NewupVecZ: single
    ); overload;
    procedure SetView(NewEyePt, NewLookAt, NewupVec: TD3DXVector3); overload;
    procedure SetPerspective; overload;
    procedure SetPerspective(Aspect, ZNear, ZFar: single; FOV: single = defFOV); overload;
    procedure SetPerspectiveORT; overload;
    procedure SetPerspectiveORT(Width,Height,ZNear, ZFar: single); overload;
    procedure Reset;
    procedure Update;
    procedure rotateView(const x,y: single; sensitivity: single=0.005);
    procedure rotateEye(const x,y: single; distance: single=1; sensitivity: single=0.005);
    function GenerateFrustum: TDJXFrustum;
    function PointInFrustum(Pt: TD3DXVector3; Frustum: TDJXFrustum = nil): boolean;
    function BoxInFrustum(MinBounds, MaxBounds: TD3DXVector3; Frustum: TDJXFrustum = nil): boolean;
    function SphereInFrustum(Center: TD3DXVector3; Radius: single; Frustum: TDJXFrustum = nil): boolean;
    procedure MousePosToVector(var RayOrigin,RayDir: TD3DXVector3);
    function PickTriangle(
      Vec1,Vec2,Vec3: TD3DXVector3;
      var dist: single;
      var HitPos: TD3DXVector3
    ): boolean;
    function GetViewMatrix: TD3DXMatrix;
    function GetProjectionMatrix: TD3DXMatrix;
    function GetCombinedViewProjection: TD3DXMatrix;
    function GetCombinedTransposedViewProjection: TD3DXMatrix;
    function GetViewVector3: TD3DXVector3;
    function GetViewVector4: TD3DXVector4;
    function GetCamPosVector3: TD3DXVector3;
    function GetCamPosVector4: TD3DXVector4;
    constructor Create(DanJetX: Pointer);
    destructor Destroy; override;
  end;

  TDJXMatrices = class(TObject)
  private
    m_DanJetX: Pointer;
  protected
    procedure SetW(m: TD3DXMatrix);
    function GetW: TD3DXMatrix;
    procedure SetV(m: TD3DXMatrix);
    function GetV: TD3DXMatrix;
    procedure SetP(m: TD3DXMatrix);
    function GetP: TD3DXMatrix;
    function GetWV: TD3DXMatrix;
    function GetVP: TD3DXMatrix;
    function GetWVP: TD3DXMatrix;
    function GetWt: TD3DXMatrix;
    function GetVt: TD3DXMatrix;
    function GetPt: TD3DXMatrix;
    function GetWVt: TD3DXMatrix;
    function GetVPt: TD3DXMatrix;
    function GetWVPt: TD3DXMatrix;
    function GetWi: TD3DXMatrix;
    function GetVi: TD3DXMatrix;
    function GetPi: TD3DXMatrix;
    function GetWVi: TD3DXMatrix;
    function GetVPi: TD3DXMatrix;
    function GetWVPi: TD3DXMatrix;
  published
    constructor Create(DanJetX: Pointer);
    destructor Destroy; override;
  public
    property W: TD3DXMatrix read GetW write SetW;
    property V: TD3DXMatrix read GetV write SetV;
    property P: TD3DXMatrix read GetP write SetP;
    property WV: TD3DXMatrix read GetWV;
    property VP: TD3DXMatrix read GetVP;
    property WVP: TD3DXMatrix read GetWVP;
    property Wt: TD3DXMatrix read GetWt;
    property Vt: TD3DXMatrix read GetVt;
    property Pt: TD3DXMatrix read GetPt;
    property WVt: TD3DXMatrix read GetWVt;
    property VPt: TD3DXMatrix read GetVPt;
    property WVPt: TD3DXMatrix read GetWVPt;
    property Wi: TD3DXMatrix read GetWi;
    property Vi: TD3DXMatrix read GetVi;
    property Pi: TD3DXMatrix read GetPi;
    property WVi: TD3DXMatrix read GetWVi;
    property VPi: TD3DXMatrix read GetVPi;
    property WVPi: TD3DXMatrix read GetWVPi;
  end;

  TDJXMatrices3D = class(TObject)
  private
    m_DanJetX: Pointer;
    m_WorldMatrixStack: array of TD3DXMatrix;
  public
    constructor Create(DanJetX: Pointer);
    destructor Destroy; override;
    procedure ClearWorldMatrix;
    procedure ApplyWorldMatrix;
    procedure TransformWorld(
      moveX, moveY, moveZ,
      rotateX, rotateY, rotateZ,
      scaleX, scaleY, scaleZ: single
    ); overload;
    procedure TransformWorld(m: TD3DXMatrix); overload;
    procedure ScaleWorld(X, Y, Z: single);
    procedure RotateWorldAroundVector(X, Y, Z: single; Angle: single);
    procedure RotateWorld(Xangle, Yangle, Zangle: single);
    procedure RotateWorldX(Angle: single);
    procedure RotateWorldY(Angle: single);
    procedure RotateWorldZ(Angle: single);
    procedure MoveWorld(X, Y, Z: double);
    procedure MultiplyWorld(m: TD3DXMatrix);
    procedure Billboard;
    procedure PreTransformWorld(
      moveX, moveY, moveZ,
      rotateX, rotateY, rotateZ,
      scaleX, scaleY, scaleZ: single
    ); overload;
    procedure PreTransformWorld(m: TD3DXMatrix); overload;
    procedure PreScaleWorld(X, Y, Z: single);
    procedure PreRotateWorldAroundVector(X, Y, Z: single; Angle: single);
    procedure PreRotateWorld(Xangle, Yangle, Zangle: single);
    procedure PreRotateWorldX(Angle: single);
    procedure PreRotateWorldY(Angle: single);
    procedure PreRotateWorldZ(Angle: single);
    procedure PreMoveWorld(X, Y, Z: double);
    procedure PreMultiplyWorld(m: TD3DXMatrix);
    procedure PushWorldMatrix;
    procedure PopWorldMatrix;
    function GetCombinedTransposedMatrix: TD3DXMatrix;
    function GetCombinedMatrix: TD3DXMatrix;
    function GetWorldMatrix: TD3DXMatrix;
    function GetInverseWorldMatrix: TD3DXMatrix;
    function GetTransposeWorldMatrix: TD3DXMatrix;
  end;

  TDJXMatricesTex = class(TObject)
  private
    m_DanJetX: Pointer;
  public
    procedure ClearTexMatrix;
    procedure ApplyTexMatrix(Stage: byte);
    procedure TransformTex(
      moveX, moveY, moveZ,
      rotateX, rotateY, rotateZ,
      scaleX, scaleY, scaleZ: single
    );
    procedure ScaleTex(X,Y,Z: single);
    procedure RotateTexAroundVector(X, Y, Z: single; Angle: single);
    procedure RotateTex(Xangle,Yangle,Zangle: single);
    procedure RotateTexX(angle: single);
    procedure RotateTexY(angle: single);
    procedure RotateTexZ(angle: single);
    procedure MoveTex(X,Y,Z: double);
    constructor Create(DanJetX: Pointer);
    destructor Destroy; override;
  end;

  TDJXVertexProcessing = (
    vpSoftware,
    vpHardware,
    vpMixed
  );
  TDJXDeviceType = (
    dtHAL,
    dtREF,
    dtSW
  );
  TDJXBBFormat = (
    bbA8R8G8B8,
    bbX8R8G8B8,
    bbR5G6B5
  );
  TDJXDSFormat = (
    dsD16,
    dsD24S8
  );
  TDJXAntialias = (
    aaNone,
    aaNonMaskable,
    aa2_Samples,
    aa4_Samples,
    aa6_Samples
  );
  TDJXInitialization = class(TPersistent)
  private
    m_DeviceType: TDJXDeviceType;
    m_BBFormat: TDJXBBFormat;
    m_DepthStencil: TDJXDSFormat;
    m_AntiAlias: TDJXAntialias;
    m_AAQuality: byte;
    m_VertexProcessing: TDJXVertexProcessing;
  protected
    procedure setAAQuality(Value: byte);
    procedure setAntialias(Value: TDJXAntialias);
  public
    constructor Create;
    destructor Destroy; override;
  published
    property DeviceType: TDJXDeviceType read m_DeviceType write m_DeviceType default dtHAL;
    property BBufferFormat: TDJXBBFormat read m_BBFormat write m_BBFormat default bbR5G6B5;
    property DepthStencil: TDJXDSFormat read m_DepthStencil write m_DepthStencil default dsD16;
    property VertexProcessing: TDJXVertexProcessing read m_VertexProcessing write m_VertexProcessing default vpSoftware;
    property Antialiasing: TDJXAntialias read m_Antialias write setAntialias default aaNone;
    property AAQuality: byte read m_AAQuality write setAAQuality;
  end;

  TBlendStage = packed record
    ColorOp: DWORD;
    ColorArg1: DWORD;
    ColorArg2: DWORD;
    ColorArg0: DWORD;
    AlphaOp: DWORD;
    AlphaArg1: DWORD;
    AlphaArg2: DWORD;
    AlphaArg0: DWORD;
    Result: DWORD;
  end;
  TBlendPack = packed record
    Stages: array[0..3] of TBlendStage;
  end;
  TDJXMultiTexBlend = class(TObject)
  private
    m_DanJetX: Pointer;
    m_Name: string;
    m_BlendStages: TBlendPack;
  public
    constructor Create(DanJetX: Pointer);
    destructor Destroy; override;
    property Name: string read m_Name write m_Name;
    procedure LoadFromFile(f: string);
    procedure SetToDevice;
  end;
  TDJXMultiTexBlendList = class(TObject)
  private
    m_DanJetX: Pointer;
    m_Blends: TList;
    procedure SetBlend(Index: integer; Blend: TDJXMultiTexBlend);
    function GetBlend(Index: integer): TDJXMultiTexBlend;
  public
    constructor Create(DanJetX: Pointer);
    destructor Destroy; override;
    function CreateBlendFromFile(f: string; Name: string): TDJXMultiTexBlend;
    property Blends[Index: integer]: TDJXMultiTexBlend read GetBlend write SetBlend;
    function Find(BlendName: string): TDJXMultiTexBlend;
    procedure Add(Blend: TDJXMultiTexBlend);
    procedure Delete(Index: integer);
    procedure Remove(Blend: TDJXMultiTexBlend);
    procedure FreeBlends;
  end;

  TDJXRenderStates = class;
  TDJXSamplerStates = class;
  TDJXTextureStageStates = class;
  TDJXStates = class(TPersistent)
  private
    m_DanJetX: Pointer;
    m_RenderStates: TDJXRenderStates;
    m_SamplerStates: TDJXSamplerStates;
    m_TextureStageStates: TDJXTextureStageStates;
  public
    property DanJetX: Pointer read m_DanJetX write m_DanJetX;
    procedure SetDefaults;
    procedure SetFromMemory;
  published
    property RenderStates: TDJXRenderStates read m_RenderStates write m_RenderStates;
    property SamplerStates: TDJXSamplerStates read m_SamplerStates write m_SamplerStates;
    property TextureStageStates: TDJXTextureStageStates read m_TextureStageStates write m_TextureStageStates;
  end;
  
  TDJXRenderStates = class(TPersistent)
  private
    m_States: TDJXStates;
    m_ZEnable: DWORD;
    m_ZWriteEnable: boolean;
    m_ZFunc: DWORD;
    m_AlphaBlendEnable: boolean;
    m_AlphaTestEnable: boolean;
    m_AlphaRef: DWORD;
    m_AlphaFunc: DWORD;
    m_SrcBlend: DWORD;
    m_DestBlend: DWORD;
    m_SeparateAlphaBlendEnable: boolean;
    m_SrcBlendAlpha: DWORD;
    m_DestBlendAlpha: DWORD;
    m_DiffuseMaterialSource: DWORD;
    m_SpecularMaterialSource: DWORD;
    m_AmbientMaterialSource: DWORD;
    m_EmissiveMaterialSource: DWORD;
    m_ColorVertex: boolean;
    m_StencilEnable: boolean;
    m_StencilFunc: DWORD;
    m_StencilRef: DWORD;
    m_StencilFail: DWORD;
    m_StencilZFail: DWORD;
    m_StencilPass: DWORD;
    m_StencilMask: DWORD;
    m_StencilWriteMask: DWORD;
    m_TwoSidedStencilMode: boolean;
    m_CCW_StencilFail: DWORD;
    m_CCW_StencilZFail: DWORD;
    m_CCW_StencilPass: DWORD;
    m_CCW_StencilFunc: DWORD;
    m_FogEnable: boolean;
    m_FogColor: D3DCOLOR;
    m_FogTableMode: DWORD;
    m_FogVertexMode: DWORD;
    m_FogStart: single;
    m_FogEnd: single;
    m_FogDensity: single;
    m_RangeFogEnable: boolean;
    m_FillMode: DWORD;
    m_ShadeMode: DWORD;
    m_CullMode: DWORD;
    m_DitherEnable: boolean;
    m_SpecularEnable: boolean;
    m_Lighting: boolean;
    m_Ambient: D3DCOLOR;
    m_DepthBias: single;
    m_SlopeScaleDepthBias: single;
    m_NormalizeNormals: boolean;
    m_MultiSampleAntialias: boolean;
    m_MultiSampleMask: DWORD;
    m_ScissorTestEnable: boolean;
    m_ClipPlaneEnable: boolean;
    m_AntialiasedLineEnable: boolean;
  protected
    procedure SetZEnable(Value: DWORD);
    function GetZEnable: DWORD;
    procedure SetZWriteEnable(Value: boolean);
    function GetZWriteEnable: boolean;
    procedure setZFunc(Value: DWORD);
    function getZFunc: DWORD;
    procedure setAlphaBlendEnable(Value: boolean);
    function getAlphaBlendEnable: boolean;
    procedure setAlphaTestEnable(Value: boolean);
    function getAlphaTestEnable: boolean;
    procedure setAlphaRef(Value: DWORD);
    function getAlphaRef: DWORD;
    procedure setAlphaFunc(Value: DWORD);
    function getAlphaFunc: DWORD;
    procedure setSrcBlend(Value: DWORD);
    function getSrcBlend: DWORD;
    procedure setDestBlend(Value: DWORD);
    function getDestBlend: DWORD;
    procedure setSeparateAlphaBlendEnable(Value: boolean);
    function getSeparateAlphaBlendEnable: boolean;
    procedure setSrcBlendAlpha(Value: DWORD);
    function getSrcBlendAlpha: DWORD;
    procedure setDestBlendAlpha(Value: DWORD);
    function getDestBlendAlpha: DWORD;
    procedure setDiffuseMaterialSource(Value: DWORD);
    function getDiffuseMaterialSource: DWORD;
    procedure setSpecularMaterialSource(Value: DWORD);
    function getSpecularMaterialSource: DWORD;
    procedure setAmbientMaterialSource(Value: DWORD);
    function getAmbientMaterialSource: DWORD;
    procedure setEmissiveMaterialSource(Value: DWORD);
    function getEmissiveMaterialSource: DWORD;
    procedure setColorVertex(Value: boolean);
    function getColorVertex: boolean;
    procedure setStencilEnable(Value: boolean);
    function getStencilEnable: boolean;
    procedure setStencilFunc(Value: DWORD);
    function getStencilFunc: DWORD;
    procedure setStencilRef(Value: DWORD);
    function getStencilRef: DWORD;
    procedure setStencilFail(Value: DWORD);
    function getStencilFail: DWORD;
    procedure setStencilZFail(Value: DWORD);
    function getStencilZFail: DWORD;
    procedure setStencilPass(Value: DWORD);
    function getStencilPass: DWORD;
    procedure setStencilMask(Value: DWORD);
    function getStencilMask: DWORD;
    procedure setStencilWriteMask(Value: DWORD);
    function getStencilWriteMask: DWORD;
    procedure setTwoSidedStencilMode(Value: boolean);
    function getTwoSidedStencilMode: boolean;
    procedure setCCW_StencilFail(Value: DWORD);
    function getCCW_StencilFail: DWORD;
    procedure setCCW_StencilZFail(Value: DWORD);
    function getCCW_StencilZFail: DWORD;
    procedure setCCW_StencilPass(Value: DWORD);
    function getCCW_StencilPass: DWORD;
    procedure setCCW_StencilFunc(Value: DWORD);
    function getCCW_StencilFunc: DWORD;
    procedure setFogEnable(Value: boolean);
    function getFogEnable: boolean;
    procedure setFogColor(Value: D3DCOLOR);
    function getFogColor: D3DCOLOR;
    procedure setFogTableMode(Value: DWORD);
    function getFogTableMode: DWORD;
    procedure setFogVertexMode(Value: DWORD);
    function getFogVertexMode: DWORD;
    procedure setFogStart(Value: single);
    function getFogStart: single;
    procedure setFogEnd(Value: single);
    function getFogEnd: single;
    procedure setFogDensity(Value: single);
    function getFogDensity: single;
    procedure setRangeFogEnable(Value: boolean);
    function getRangeFogEnable: boolean;
    procedure setFillMode(Value: DWORD);
    function getFillMode: DWORD;
    procedure setShadeMode(Value: DWORD);
    function getShadeMode: DWORD;
    procedure setCullMode(Value: DWORD);
    function getCullMode: DWORD;
    procedure setDitherEnable(Value: boolean);
    function getDitherEnable: boolean;
    procedure setSpecularEnable(Value: boolean);
    function getSpecularEnable: boolean;
    procedure setLighting(Value: boolean);
    function getLighting: boolean;
    procedure setAmbient(Value: D3DCOLOR);
    function getAmbient: D3DCOLOR;
    procedure setDepthBias(Value: single);
    function getDepthBias: single;
    procedure setSlopeScaleDepthBias(Value: single);
    function getSlopeScaleDepthBias: single;
    procedure setNormalizeNormals(Value: boolean);
    function getNormalizeNormals: boolean;
    procedure setMultiSampleAntialias(Value: boolean);
    function getMultiSampleAntialias: boolean;
    procedure setMultiSampleMask(Value: DWORD);
    function getMultiSampleMask: DWORD;
    procedure setScissorTestEnable(Value: boolean);
    function getScissorTestEnable: boolean;
    procedure setClipPlaneEnable(Value: boolean);
    function getClipPlaneEnable: boolean;
    procedure setAntialiasedLineEnable(Value: boolean);
    function getAntialiasedLineEnable: boolean;
  public
    property States: TDJXStates read m_States write m_States;
    procedure SetDefaults;
    procedure SetFromMemory;
  published
    property ZEnable: DWORD read getZEnable write setZEnable;
    property ZWriteEnable: boolean read getZWriteEnable write setZWriteEnable;
    property ZFunc: DWORD read getZFunc write setZFunc;
    property AlphaBlendEnable: boolean read getAlphaBlendEnable write setAlphaBlendEnable;
    property AlphaTestEnable: boolean read getAlphaTestEnable write setAlphaTestEnable;
    property AlphaRef: DWORD read getAlphaRef write setAlphaRef;
    property AlphaFunc: DWORD read getAlphaFunc write setAlphaFunc;
    property SrcBlend: DWORD read getSrcBlend write setSrcBlend;
    property DestBlend: DWORD read getDestBlend write setDestBlend;
    property SeparateAlphaBlendEnable: boolean read getSeparateAlphaBlendEnable write setSeparateAlphaBlendEnable;
    property SrcBlendAlpha: DWORD read getSrcBlendAlpha write setSrcBlendAlpha;
    property DestBlendAlpha: DWORD read getDestBlendAlpha write setDestBlendAlpha;
    property DiffuseMaterialSource: DWORD read getDiffuseMaterialSource write setDiffuseMaterialSource;
    property AmbientMaterialSource: DWORD read getAmbientMaterialSource write setAmbientMaterialSource;
    property SpecularMaterialSource: DWORD read getSpecularMaterialSource write setSpecularMaterialSource;
    property EmissiveMaterialSource: DWORD read getEmissiveMaterialSource write setEmissiveMaterialSource;
    property ColorVertex: boolean read getColorVertex write setColorVertex;
    property StencilEnable: boolean read getStencilEnable write setStencilEnable;
    property StencilFunc: DWORD read getStencilFunc write setStencilFunc;
    property StencilRef: DWORD read getStencilRef write setStencilRef;
    property StencilFail: DWORD read getStencilFail write setStencilFail;
    property StencilZFail: DWORD read getStencilZFail write setStencilZFail;
    property StencilPass: DWORD read getStencilPass write setStencilPass;
    property StencilMask: DWORD read getStencilMask write setStencilMask;
    property StencilWriteMask: DWORD read getStencilWriteMask write setStencilWriteMask;
    property TwoSidedStencilMode: boolean read getTwoSidedStencilMode write setTwoSidedStencilMode;
    property CCW_StencilFail: DWORD read getCCW_StencilFail write setCCW_StencilFail;
    property CCW_StencilZFail: DWORD read getCCW_StencilZFail write setCCW_StencilZFail;
    property CCW_StencilPass: DWORD read getCCW_StencilPass write setCCW_StencilPass;
    property CCW_StencilFunc: DWORD read getCCW_StencilFunc write setCCW_StencilFunc;
    property FogEnable: boolean read getFogEnable write setFogEnable;
    property FogColor: D3DCOLOR read getFogColor write setFogColor;
    property FogTableMode: DWORD read getFogTableMode write setFogTableMode;
    property FogVertexMode: DWORD read getFogVertexMode write setFogVertexMode;
    property FogStart: single read getFogStart write setFogStart;
    property FogEnd: single read getFogEnd write setFogEnd;
    property FogDensity: single read getFogDensity write setFogDensity;
    property RangeFogEnable: boolean read getRangeFogEnable write setRangeFogEnable;
    property FillMode: DWORD read getFillMode write setFillMode;
    property ShadeMode: DWORD read getShadeMode write setShadeMode;
    property CullMode: DWORD read getCullMode write setCullMode;
    property DitherEnable: boolean read getDitherEnable write setDitherEnable;
    property SpecularEnable: boolean read getSpecularEnable write setSpecularEnable;
    property Lighting: boolean read getLighting write setLighting;
    property Ambient: D3DCOLOR read getAmbient write setAmbient;
    property DepthBias: single read getDepthBias write setDepthBias;
    property SlopeScaleDepthBias: single read getSlopeScaleDepthBias write setSlopeScaleDepthBias;
    property NormalizeNormals: boolean read getNormalizeNormals write setNormalizeNormals;
    property MultiSampleAntialias: boolean read getMultiSampleAntialias write setMultiSampleAntialias;
    property MultiSampleMask: DWORD read getMultiSampleMask write setMultiSampleMask;
    property ScissorTestEnable: boolean read getScissorTestEnable write setScissorTestEnable;
    property ClipPlaneEnbale: boolean read getClipPlaneEnable write setClipPlaneEnable;
    property AntialiasedLineEnable: boolean read getAntialiasedLineEnable write setAntialiasedLineEnable;
  end;

  TDJXSamplerStates = class(TPersistent)
  private
    m_States: TDJXStates;
    m_AddressU: array[0..7] of DWORD;
    m_AddressV: array[0..7] of DWORD;
    m_AddressW: array[0..7] of DWORD;
    m_MagFilter: array[0..7] of DWORD;
    m_MinFilter: array[0..7] of DWORD;
    m_MipFilter: array[0..7] of DWORD;
    m_BorderColor: array[0..7] of DWORD;
  protected
    procedure setAddressU(Sampler: byte; Value: DWORD);
    function getAddressU(Sampler: byte): DWORD;
    procedure setAddressV(Sampler: byte; Value: DWORD);
    function getAddressV(Sampler: byte): DWORD;
    procedure setAddressW(Sampler: byte; Value: DWORD);
    function getAddressW(Sampler: byte): DWORD;
    procedure setMagFilter(Sampler: byte; Value: DWORD);
    function getMagFilter(Sampler: byte): DWORD;
    procedure setMinFilter(Sampler: byte; Value: DWORD);
    function getMinFilter(Sampler: byte): DWORD;
    procedure setMipFilter(Sampler: byte; Value: DWORD);
    function getMipFilter(Sampler: byte): DWORD;
    procedure setBorderColor(Sampler: byte; Value: DWORD);
    function getBorderColor(Sampler: byte): DWORD;
  public
    property States: TDJXStates read m_States write m_States;
    procedure SetDefaults;
    procedure SetFromMemory;
    property AddressU[Sampler: byte]: DWORD read getAddressU write setAddressU;
    property AddressV[Sampler: byte]: DWORD read getAddressV write setAddressV;
    property AddressW[Sampler: byte]: DWORD read getAddressW write setAddressW;
    property MagFilter[Sampler: byte]: DWORD read getMagFilter write setMagFilter;
    property MinFilter[Sampler: byte]: DWORD read getMinFilter write setMinFilter;
    property MipFilter[Sampler: byte]: DWORD read getMipFilter write setMipFilter;
    property BorderColor[Sampler: byte]: DWORD read GetBorderColor write SetBorderColor;
  end;

  TDJXTextureStageStates = class(TPersistent)
  private
    m_States: TDJXStates;
    m_ColorOp: array[0..7] of DWORD;
    m_ColorArg0: array[0..7] of DWORD;
    m_ColorArg1: array[0..7] of DWORD;
    m_ColorArg2: array[0..7] of DWORD;
    m_AlphaOp: array[0..7] of DWORD;
    m_AlphaArg0: array[0..7] of DWORD;
    m_AlphaArg1: array[0..7] of DWORD;
    m_AlphaArg2: array[0..7] of DWORD;
    m_ResultArg: array[0..7] of DWORD;
    m_Constant: array[0..7] of DWORD;
    m_TexCoordIndex: array[0..7] of DWORD;
    m_TextureTransformFlags: array[0..7] of DWORD;
    m_BumpEnvMat00: array[0..7] of single;
    m_BumpEnvMat01: array[0..7] of single;
    m_BumpEnvMat10: array[0..7] of single;
    m_BumpEnvMat11: array[0..7] of single;
    m_BumpEnvLScale: array[0..7] of single;
    m_BumpEnvLOffset: array[0..7] of single;
  protected
    procedure setColorOp(Stage: byte; Value: DWORD);
    function getColorOp(Stage: byte): DWORD;
    procedure setColorArg0(Stage: byte; Value: DWORD);
    function getColorArg0(Stage: byte): DWORD;
    procedure setColorArg1(Stage: byte; Value: DWORD);
    function getColorArg1(Stage: byte): DWORD;
    procedure setColorArg2(Stage: byte; Value: DWORD);
    function getColorArg2(Stage: byte): DWORD;
    procedure setAlphaOp(Stage: byte; Value: DWORD);
    function getAlphaOp(Stage: byte): DWORD;
    procedure setAlphaArg0(Stage: byte; Value: DWORD);
    function getAlphaArg0(Stage: byte): DWORD;
    procedure setAlphaArg1(Stage: byte; Value: DWORD);
    function getAlphaArg1(Stage: byte): DWORD;
    procedure setAlphaArg2(Stage: byte; Value: DWORD);
    function getAlphaArg2(Stage: byte): DWORD;
    procedure setResultArg(Stage: byte; Value: DWORD);
    function getResultArg(Stage: byte): DWORD;
    procedure setConstant(Stage: byte; Value: DWORD);
    function getConstant(Stage: byte): DWORD;
    procedure setTexCoordIndex(Stage: byte; Value: DWORD);
    function getTexCoordIndex(Stage: byte): DWORD;
    procedure setTextureTransformFlags(Stage: byte; Value: DWORD);
    function getTextureTransformFlags(Stage: byte): DWORD;
    procedure setBumpEnvMat00(Stage: byte; Value: single);
    function getBumpEnvMat00(Stage: byte): single;
    procedure setBumpEnvMat01(Stage: byte; Value: single);
    function getBumpEnvMat01(Stage: byte): single;
    procedure setBumpEnvMat10(Stage: byte; Value: single);
    function getBumpEnvMat10(Stage: byte): single;
    procedure setBumpEnvMat11(Stage: byte; Value: single);
    function getBumpEnvMat11(Stage: byte): single;
    procedure setBumpEnvLScale(Stage: byte; Value: single);
    function getBumpEnvLScale(Stage: byte): single;
    procedure setBumpEnvLOffset(Stage: byte; Value: single);
    function getBumpEnvLOffset(Stage: byte): single;
  public
    property States: TDJXStates read m_States write m_States;
    procedure SetDefaults;
    procedure SetFromMemory;
    property ColorOp[Stage: byte]: DWORD read getColorOp write setColorOp;
    property ColorArg0[Stage: byte]: DWORD read getColorArg0 write setColorArg0;
    property ColorArg1[Stage: byte]: DWORD read getColorArg1 write setColorArg1;
    property ColorArg2[Stage: byte]: DWORD read getColorArg2 write setColorArg2;
    property AlphaOp[Stage: byte]: DWORD read getAlphaOp write setAlphaOp;
    property AlphaArg0[Stage: byte]: DWORD read getAlphaArg0 write setAlphaArg0;
    property AlphaArg1[Stage: byte]: DWORD read getAlphaArg1 write setAlphaArg1;
    property AlphaArg2[Stage: byte]: DWORD read getAlphaArg2 write setAlphaArg2;
    property ResultArg[Stage: byte]: DWORD read getResultArg write setResultArg;
    property Constant[Stage: byte]: DWORD read getConstant write setConstant;
    property TexCoordIndex[Stage: byte]: DWORD read getTexCoordIndex write setTexCoordIndex;
    property TextureTransformFlags[Stage: byte]: DWORD read getTextureTransformFlags write setTextureTransformFlags;
    property BumpEnvMat00[Stage: byte]: single read GetBumpEnvMat00 write SetBumpEnvMat00;
    property BumpEnvMat01[Stage: byte]: single read GetBumpEnvMat01 write SetBumpEnvMat01;
    property BumpEnvMat10[Stage: byte]: single read GetBumpEnvMat10 write SetBumpEnvMat10;
    property BumpEnvMat11[Stage: byte]: single read GetBumpEnvMat11 write SetBumpEnvMat11;
    property BumpEnvLScale[Stage: byte]: single read GetBumpEnvLScale write SetBumpEnvLScale;
    property BumpEnvLOffset[Stage: byte]: single read GetBumpEnvLOffset write SetBumpEnvLOffset;
  end;

implementation

uses
  DJX, Types;


//TDJXMultiTexBlend BEGIN
constructor TDJXMultiTexBlend.Create(DanJetX: Pointer);
begin
  m_DanJetX := DanJetX;
end;
destructor TDJXMultiTexBlend.Destroy;
begin
  inherited Destroy;
end;
procedure TDJXMultiTexBlend.LoadFromFile(f: string);
begin
  if not fileExists(f) then exit;
  with TFileStream.Create(f,fmOpenRead) do
  begin
    ReadBuffer(m_BlendStages,sizeof(m_BlendStages));
    free;
  end;
end;
procedure TDJXMultiTexBlend.SetToDevice;
var
  i: integer;
begin
  for i := 0 to 3 do
  begin
    TDanJetX(m_DanJetX).States.TextureStageStates.ColorOp[i]:=m_BlendStages.Stages[i].ColorOp;
    TDanJetX(m_DanJetX).States.TextureStageStates.ColorArg1[i]:=m_BlendStages.Stages[i].ColorArg1;
    TDanJetX(m_DanJetX).States.TextureStageStates.ColorArg2[i]:=m_BlendStages.Stages[i].ColorArg2;
    TDanJetX(m_DanJetX).States.TextureStageStates.ColorArg0[i]:=m_BlendStages.Stages[i].ColorArg0;
    TDanJetX(m_DanJetX).States.TextureStageStates.AlphaOp[i]:=m_BlendStages.Stages[i].AlphaOp;
    TDanJetX(m_DanJetX).States.TextureStageStates.AlphaArg1[i]:=m_BlendStages.Stages[i].AlphaArg1;
    TDanJetX(m_DanJetX).States.TextureStageStates.AlphaArg2[i]:=m_BlendStages.Stages[i].AlphaArg2;
    TDanJetX(m_DanJetX).States.TextureStageStates.AlphaArg0[i]:=m_BlendStages.Stages[i].AlphaArg0;
    TDanJetX(m_DanJetX).States.TextureStageStates.ResultArg[i]:=m_BlendStages.Stages[i].Result;
  end;
end;
//TDJXMultiTexBlend END
//TDJXMultiTexBlendList BEGIN
constructor TDJXMultiTexBlendList.Create(DanJetX: Pointer);
begin
  m_DanJetX := DanJetX;
  m_Blends := TList.Create;
end;
destructor TDJXMultiTexBlendList.Destroy;
begin
  FreeBlends;
  m_Blends.Free;
  inherited Destroy;
end;

procedure TDJXMultiTexBlendList.SetBlend(Index: integer; Blend: TDJXMultiTexBlend);
begin
  m_Blends.Items[Index] := Blend;
end;
function TDJXMultiTexBlendList.GetBlend(Index: integer): TDJXMultiTexBlend;
begin
  result := TDJXMultiTexBlend(m_Blends.Items[Index]);
end;

function TDJXMultiTexBlendList.CreateBlendFromFile(f: string; Name: string): TDJXMultiTexBlend;
var
  Blend: TDJXMultiTexBlend;
begin
  result := nil;
  if not fileExists(f) then exit;
  Blend := TDJXMultiTexBlend.Create(m_DanJetX);
  Blend.Name := Name;
  Blend.LoadFromFile(f);
  Add(Blend);
  result := Blend;
end;
function TDJXMultiTexBlendList.Find(BlendName: string): TDJXMultiTexBlend;
var
  i: integer;
begin
  result := nil;
  for i := 0 to m_Blends.Count - 1 do
  if TDJXMultiTexBlend(m_Blends.Items[i]).Name = BlendName then
  begin
    result := TDJXMultiTexBlend(m_Blends.Items[i]);
    break;
  end;
end;
procedure TDJXMultiTexBlendList.Add(Blend: TDJXMultiTexBlend);
begin
  m_Blends.Add(Blend);
end;
procedure TDJXMultiTexBlendList.Delete(Index: integer);
begin
  TDJXMultiTexBlend(m_Blends.Items[Index]).Free;
  m_Blends.Delete(Index);
end;
procedure TDJXMultiTexBlendList.Remove(Blend: TDJXMultiTexBlend);
begin
  m_Blends.Remove(Blend);
  Blend.Free;
end;
procedure TDJXMultiTexBlendList.FreeBlends;
begin
  while m_Blends.Count > 0 do
  begin
    Blends[0].Free;
    m_Blends.Delete(0);
  end;
end;
//TDJXMultiTexBlendList END

//TDJXInitialization BEGIN
constructor TDJXInitialization.Create;
begin
  inherited Create;
  m_AAQuality := 0;
end;
destructor TDJXInitialization.Destroy;
begin
  inherited Destroy;
end;
procedure TDJXInitialization.setAAQuality(Value: byte);
begin
  if m_AntiAlias <> aaNonMaskable then
  begin
    m_AAQuality := 0;
    exit;
  end;
  if Value > 2 then m_AAQuality := 2
  else
  m_AAQuality := Value;
end;
procedure TDJXInitialization.setAntialias(Value: TDJXAntialias);
begin
  m_Antialias := Value;
  if m_AntiAlias <> aaNonMaskable then AAQuality := 0;
end;
//TDJXInitialization END

//DJXStates BEGIN
procedure TDJXStates.SetDefaults;
begin
  if m_RenderStates <> nil then
  m_RenderStates.SetDefaults;
  if m_SamplerStates <> nil then
  m_SamplerStates.SetDefaults;
  if m_TextureStageStates <> nil then
  m_TextureStageStates.SetDefaults;
end;
procedure TDJXStates.SetFromMemory;
begin
  if m_RenderStates <> nil then
  m_RenderStates.SetFromMemory;
  if m_SamplerStates <> nil then
  m_SamplerStates.SetFromMemory;
  if m_TextureStageStates <> nil then
  m_TextureStageStates.SetFromMemory;
end;
//DJXStates END

//DJXTextureStageStates BEGIN
procedure TDJXTextureStageStates.SetDefaults;
var
  i: integer;
begin
  for i := 0 to 3 do
  begin
    if i = 0 then
    begin
      ColorOp[i] := D3DTOP_MODULATE;
      ColorArg0[i] := D3DTA_CURRENT;
      ColorArg1[i] := D3DTA_TEXTURE;
      ColorArg2[i] := D3DTA_CURRENT;
      AlphaOp[i] := D3DTOP_MODULATE;
      AlphaArg0[i] := D3DTA_CURRENT;
      AlphaArg1[i] := D3DTA_TEXTURE;
      AlphaArg2[i] := D3DTA_CURRENT;
      ResultArg[i] := D3DTA_CURRENT;
    end
    else
    begin
      ColorOp[i] := D3DTOP_DISABLE;
      ColorArg0[i] := D3DTA_DIFFUSE;
      ColorArg1[i] := D3DTA_DIFFUSE;
      ColorArg2[i] := D3DTA_DIFFUSE;
      AlphaOp[i] := D3DTOP_DISABLE;
      AlphaArg0[i] := D3DTA_DIFFUSE;
      AlphaArg1[i] := D3DTA_DIFFUSE;
      AlphaArg2[i] := D3DTA_DIFFUSE;
      ResultArg[i] := D3DTA_CURRENT;
    end;
    Constant[i] := 0;
    TexCoordIndex[i] := i;
    TextureTransformFlags[i] := D3DTTFF_DISABLE;
    BumpEnvMat00[i] := 0.0;
    BumpEnvMat01[i] := 0.0;
    BumpEnvMat10[i] := 0.0;
    BumpEnvMat11[i] := 0.0;
    BumpEnvLScale[i] := 0.0;
    BumpEnvLOffset[i] := 0.0;
  end;
end;
procedure TDJXTextureStageStates.SetFromMemory;
var
  i: integer;
begin
  for i := 0 to 3 do
  begin
    ColorOp[i] := m_ColorOp[i];
    ColorArg0[i] := m_ColorArg0[i];
    ColorArg1[i] := m_ColorArg1[i];
    ColorArg2[i] := m_ColorArg2[i];
    AlphaOp[i] := m_AlphaOp[i];
    AlphaArg0[i] := m_AlphaArg0[i];
    AlphaArg1[i] := m_AlphaArg1[i];
    AlphaArg2[i] := m_AlphaArg2[i];
    ResultArg[i] := m_ResultArg[i];
    Constant[i] := m_Constant[i];
    TexCoordIndex[i] := m_TexCoordIndex[i];
    TextureTransformFlags[i] := m_TextureTransformFlags[i];
    BumpEnvMat00[i] := m_BumpEnvMat00[i];
    BumpEnvMat01[i] := m_BumpEnvMat01[i];
    BumpEnvMat10[i] := m_BumpEnvMat10[i];
    BumpEnvMat11[i] := m_BumpEnvMat11[i];
    BumpEnvLScale[i] := m_BumpEnvLScale[i];
    BumpEnvLOffset[i] := m_BumpEnvLOffset[i];
  end;
end;
procedure TDJXTextureStageStates.setColorOp(Stage: byte; Value: DWORD);
begin
  m_ColorOp[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_COLOROP, Value);
end;
function TDJXTextureStageStates.getColorOp(Stage: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_ColorOp[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_COLOROP, Result);
end;
procedure TDJXTextureStageStates.setColorArg0(Stage: byte; Value: DWORD);
begin
  m_ColorArg0[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_COLORARG0, Value);
end;
function TDJXTextureStageStates.getColorArg0(Stage: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_ColorArg0[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_COLORARG0, Result);
end;
procedure TDJXTextureStageStates.setColorArg1(Stage: byte; Value: DWORD);
begin
  m_ColorArg1[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_COLORARG1, Value);
end;
function TDJXTextureStageStates.getColorArg1(Stage: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_ColorArg1[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_COLORARG1, Result);
end;
procedure TDJXTextureStageStates.setColorArg2(Stage: byte; Value: DWORD);
begin
  m_ColorArg2[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_COLORARG2, Value);
end;
function TDJXTextureStageStates.getColorArg2(Stage: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_ColorArg2[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_COLORARG2, Result);
end;
procedure TDJXTextureStageStates.setAlphaOp(Stage: byte; Value: DWORD);
begin
  m_AlphaOp[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_ALPHAOP, Value);
end;
function TDJXTextureStageStates.getAlphaOp(Stage: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_AlphaOp[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_ALPHAOP, Result);
end;
procedure TDJXTextureStageStates.setAlphaArg0(Stage: byte; Value: DWORD);
begin
  m_AlphaArg0[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_ALPHAARG0, Value);
end;
function TDJXTextureStageStates.getAlphaArg0(Stage: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_AlphaArg0[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_ALPHAARG0, Result);
end;
procedure TDJXTextureStageStates.setAlphaArg1(Stage: byte; Value: DWORD);
begin
  m_AlphaArg1[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_ALPHAARG1, Value);
end;
function TDJXTextureStageStates.getAlphaArg1(Stage: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_AlphaArg1[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_ALPHAARG1, Result);
end;
procedure TDJXTextureStageStates.setAlphaArg2(Stage: byte; Value: DWORD);
begin
  m_AlphaArg2[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_ALPHAARG2, Value);
end;
function TDJXTextureStageStates.getAlphaArg2(Stage: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_AlphaArg2[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_ALPHAARG2, Result);
end;
procedure TDJXTextureStageStates.setResultArg(Stage: byte; Value: DWORD);
begin
  m_ResultArg[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_RESULTARG, Value);
end;
function TDJXTextureStageStates.getResultArg(Stage: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_ResultArg[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_RESULTARG, Result);
end;
procedure TDJXTextureStageStates.setConstant(Stage: byte; Value: DWORD);
begin
  m_Constant[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_CONSTANT, Value);
end;
function TDJXTextureStageStates.getConstant(Stage: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_Constant[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_CONSTANT, Result);
end;
procedure TDJXTextureStageStates.setTexCoordIndex(Stage: byte; Value: DWORD);
begin
  m_TexCoordIndex[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_TEXCOORDINDEX, Value);
end;
function TDJXTextureStageStates.getTexCoordIndex(Stage: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_TexCoordIndex[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_TEXCOORDINDEX, Result);
end;
procedure TDJXTextureStageStates.setTextureTransformFlags(Stage: byte; Value: DWORD);    
begin
  m_TextureTransformFlags[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_TEXTURETRANSFORMFLAGS, Value);
end;
function TDJXTextureStageStates.getTextureTransformFlags(Stage: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_TextureTransformFlags[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_TEXTURETRANSFORMFLAGS, Result);
end;
procedure TDJXTextureStageStates.setBumpEnvMat00(Stage: byte; Value: single);
begin
  m_BumpEnvMat00[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_BUMPENVMAT00, PDWORD(@Value)^);
end;
function TDJXTextureStageStates.getBumpEnvMat00(Stage: byte): single;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_BumpEnvMat00[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_BUMPENVMAT00, PDWORD(@Result)^);
end;
procedure TDJXTextureStageStates.setBumpEnvMat01(Stage: byte; Value: single);
begin
  m_BumpEnvMat01[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_BUMPENVMAT01, PDWORD(@Value)^);
end;
function TDJXTextureStageStates.getBumpEnvMat01(Stage: byte): single;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_BumpEnvMat01[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_BUMPENVMAT01, PDWORD(@Result)^);
end;
procedure TDJXTextureStageStates.setBumpEnvMat10(Stage: byte; Value: single);
begin
  m_BumpEnvMat10[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_BUMPENVMAT10, PDWORD(@Value)^);
end;
function TDJXTextureStageStates.getBumpEnvMat10(Stage: byte): single;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_BumpEnvMat10[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_BUMPENVMAT10, PDWORD(@Result)^);
end;
procedure TDJXTextureStageStates.setBumpEnvMat11(Stage: byte; Value: single);
begin
  m_BumpEnvMat11[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_BUMPENVMAT11, PDWORD(@Value)^);
end;
function TDJXTextureStageStates.getBumpEnvMat11(Stage: byte): single;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_BumpEnvMat11[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_BUMPENVMAT11, PDWORD(@Result)^);
end;
procedure TDJXTextureStageStates.setBumpEnvLScale(Stage: byte; Value: single);
begin
  m_BumpEnvLScale[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_BUMPENVLSCALE, PDWORD(@Value)^);
end;
function TDJXTextureStageStates.getBumpEnvLScale(Stage: byte): single;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_BumpEnvLScale[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_BUMPENVLSCALE, PDWORD(@Result)^);
end;
procedure TDJXTextureStageStates.setBumpEnvLOffset(Stage: byte; Value: single);
begin
  m_BumpEnvLOffset[Stage] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetTextureStageState(Stage, D3DTSS_BUMPENVLOFFSET, PDWORD(@Value)^);
end;
function TDJXTextureStageStates.getBumpEnvLOffset(Stage: byte): single;      
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_BumpEnvLOffset[Stage];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetTextureStageState(Stage, D3DTSS_BUMPENVLOFFSET, PDWORD(@Result)^);
end;
//DJXTextureStageStates END

//DJXSamplerStates BEGIN
procedure TDJXSamplerStates.SetFromMemory;
var
  i: integer;
begin
  for i := 0 to 7 do
  begin
    AddressU[i] := m_AddressU[i];
    AddressV[i] := m_AddressV[i];
    AddressW[i] := m_AddressW[i];
    MagFilter[i] := m_MagFilter[i];
    MinFilter[i] := m_MinFilter[i];
    MipFilter[i] := m_MipFilter[i];
  end;
end;
procedure TDJXSamplerStates.SetDefaults;
var
  i: integer;
begin
  for i := 0 to 7 do
  begin
    AddressU[i] := D3DTADDRESS_WRAP;
    AddressV[i] := D3DTADDRESS_WRAP;
    AddressW[i] := D3DTADDRESS_WRAP;
    MagFilter[i] := D3DTEXF_POINT;
    MinFilter[i] := D3DTEXF_POINT;
    MipFilter[i] := D3DTEXF_NONE;
  end;
end;
procedure TDJXSamplerStates.setAddressU(Sampler: byte; Value: DWORD);
begin
  m_AddressU[Sampler] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetSamplerState(Sampler, D3DSAMP_ADDRESSU, Value);
end;
function TDJXSamplerStates.getAddressU(Sampler: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_AddressU[Sampler];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetSamplerState(Sampler, D3DSAMP_ADDRESSU, Result);
end;
procedure TDJXSamplerStates.setAddressV(Sampler: byte; Value: DWORD);
begin
  m_AddressV[Sampler] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetSamplerState(Sampler, D3DSAMP_ADDRESSV, Value);
end;
function TDJXSamplerStates.getAddressV(Sampler: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_AddressV[Sampler];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetSamplerState(Sampler, D3DSAMP_ADDRESSV, Result);
end;
procedure TDJXSamplerStates.setAddressW(Sampler: byte; Value: DWORD);
begin
  m_AddressW[Sampler] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetSamplerState(Sampler, D3DSAMP_ADDRESSW, Value);
end;
function TDJXSamplerStates.getAddressW(Sampler: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_AddressW[Sampler];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetSamplerState(Sampler, D3DSAMP_ADDRESSW, Result);
end;
procedure TDJXSamplerStates.setMagFilter(Sampler: byte; Value: DWORD);
begin
  m_MagFilter[Sampler] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetSamplerState(Sampler, D3DSAMP_MAGFILTER, Value);
end;
function TDJXSamplerStates.getMagFilter(Sampler: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_MagFilter[Sampler];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetSamplerState(Sampler, D3DSAMP_MAGFILTER, Result);
end;
procedure TDJXSamplerStates.setMinFilter(Sampler: byte; Value: DWORD);
begin
  m_MinFilter[Sampler] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetSamplerState(Sampler, D3DSAMP_MINFILTER, Value);
end;
function TDJXSamplerStates.getMinFilter(Sampler: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_MinFilter[Sampler];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetSamplerState(Sampler, D3DSAMP_MINFILTER, Result);
end;
procedure TDJXSamplerStates.setMipFilter(Sampler: byte; Value: DWORD);
begin
  m_MipFilter[Sampler] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetSamplerState(Sampler, D3DSAMP_MIPFILTER, Value);
end;
function TDJXSamplerStates.getMipFilter(Sampler: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_MipFilter[Sampler];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetSamplerState(Sampler, D3DSAMP_MIPFILTER, Result);
end;
procedure TDJXSamplerStates.setBorderColor(Sampler: byte; Value: DWORD);
begin
  m_BorderColor[Sampler] := Value;
  if m_States = nil then
  exit;
  if not TDanJetX(m_States.m_DanJetX).Initialized then
  exit;
  TDanJetX(m_States.m_DanJetX).Device.SetSamplerState(Sampler, D3DSAMP_BORDERCOLOR, Value);
end;
function TDJXSamplerStates.getBorderColor(Sampler: byte): DWORD;
begin
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.m_DanJetX).Initialized)) then
  begin
    Result := m_BorderColor[Sampler];
    exit;
  end;
  TDanJetX(m_States.m_DanJetX).Device.GetSamplerState(Sampler, D3DSAMP_BORDERCOLOR, Result);
end;
//DJXSamplerStates END

//DJXRenderStates BEGIN
procedure TDJXRenderStates.SetDefaults;
begin
  ZEnable := D3DZB_FALSE;
  ZWriteEnable := true;
  ZFunc := D3DCMP_LESSEQUAL;
  AlphaBlendEnable := true;
  AlphaTestEnable := true;
  AlphaRef := 1;
  AlphaFunc := D3DCMP_GREATEREQUAL;
  SrcBlend := D3DBLEND_ONE;
  DestBlend := D3DBLEND_ZERO;
  SeparateAlphaBlendEnable := false;
  SrcBlendAlpha := D3DBLEND_ONE;
  DestBlendAlpha := D3DBLEND_ZERO;
  DiffuseMaterialSource := D3DMCS_COLOR1;
  AmbientMaterialSource := D3DMCS_MATERIAL;
  SpecularMaterialSource := D3DMCS_COLOR2;
  EmissiveMaterialSource := D3DMCS_MATERIAL;
  ColorVertex := false;
  StencilEnable := false;
  StencilFunc := D3DCMP_ALWAYS;
  StencilRef := 0;
  StencilFail := D3DSTENCILOP_KEEP;
  StencilZFail := D3DSTENCILOP_KEEP;
  StencilPass := D3DSTENCILOP_KEEP;
  StencilMask := $ffffffff;
  StencilWriteMask := $ffffffff;
  TwoSidedStencilMode := false;
  CCW_StencilFail := D3DSTENCILOP_KEEP;
  CCW_StencilZFail := D3DSTENCILOP_KEEP;
  CCW_StencilPass := D3DSTENCILOP_KEEP;
  CCW_StencilFunc := D3DCMP_ALWAYS;
  FogEnable := false;
  FogColor := D3DCOLOR_XRGB(0,0,0);
  FogTableMode := D3DFOG_NONE;
  FogVertexMode := D3DFOG_NONE;
  FogStart := 0;
  FogEnd := 1;
  RangeFogEnable := false;
  FillMode := D3DFILL_SOLID;
  ShadeMode := D3DSHADE_GOURAUD;
  CullMode := D3DCULL_CCW;
  DitherEnable := false;
  SpecularEnable := false;
  Lighting := false;
  Ambient := D3DCOLOR_XRGB(0,0,0);
  DepthBias := 0;
  SlopeScaleDepthBias := 0;
  NormalizeNormals := true;
  MultiSampleAntialias := true;
  MultiSampleMask := $ffffffff;
  ScissorTestEnable := false;
  AntialiasedLineEnable := false;
end;
procedure TDJXRenderStates.SetFromMemory;
begin
  ZEnable := m_ZEnable;
  ZWriteEnable := m_ZWriteEnable;
  ZFunc := m_ZFunc;              
  AlphaBlendEnable := m_AlphaBlendEnable;
  AlphaTestEnable := m_AlphaTestEnable;
  AlphaRef := m_AlphaRef;
  AlphaFunc := m_AlphaFunc;
  SrcBlend := m_SrcBlend;
  DestBlend := m_DestBlend;
  SeparateAlphaBlendEnable := m_SeparateAlphaBlendEnable;
  SrcBlendAlpha := m_SrcBlendAlpha;
  DestBlendAlpha := m_DestBlendAlpha;
  DiffuseMaterialSource := m_DiffuseMaterialSource;
  AmbientMaterialSource := m_AmbientMaterialSource;
  SpecularMaterialSource := m_SpecularMaterialSource;
  EmissiveMaterialSource := m_EmissiveMaterialSource;
  ColorVertex := m_ColorVertex;
  StencilEnable := m_StencilEnable;
  StencilFunc := m_StencilFunc;
  StencilRef := m_StencilRef;
  StencilFail := m_StencilFail;
  StencilZFail := m_StencilZFail;
  StencilPass := m_StencilPass;
  StencilMask := m_StencilMask;
  StencilWriteMask := m_StencilWriteMask;
  TwoSidedStencilMode := m_TwoSidedStencilMode;
  CCW_StencilFail := m_CCW_StencilFail;
  CCW_StencilZFail := m_CCW_StencilZFail;
  CCW_StencilPass := m_CCW_StencilPass;
  CCW_StencilFunc := m_CCW_StencilFunc;
  FogEnable := m_FogEnable;
  FogColor := m_FogColor;
  FogTableMode := m_FogTableMode;
  FogVertexMode := m_FogVertexMode;
  FogStart := m_FogStart;
  FogEnd := m_FogEnd;
  RangeFogEnable := m_RangeFogEnable;
  FillMode := m_FillMode;
  ShadeMode := m_ShadeMode;
  CullMode := m_CullMode;
  DitherEnable := m_DitherEnable;
  SpecularEnable := m_SpecularEnable;
  Lighting := m_Lighting;
  Ambient := m_Ambient;
  DepthBias := m_DepthBias;
  SlopeScaleDepthBias := m_SlopeScaleDepthBias;
  NormalizeNormals := m_NormalizeNormals;
  MultiSampleAntialias := m_MultiSampleAntialias;
  MultiSampleMask := m_MultiSampleMask;
  AntialiasedLineEnable := m_AntialiasedLineEnable;
end;
procedure TDJXRenderStates.SetZEnable(Value: DWORD);
begin
  m_ZEnable := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_ZENABLE, Value);
end;
function TDJXRenderStates.GetZEnable: DWORD;
begin
  if (m_States = nil) then
  begin
    result := m_ZEnable;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_ZEnable;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_ZENABLE, Result);
end;
procedure TDJXRenderStates.SetZWriteEnable(Value: boolean);
begin
  m_ZWriteEnable := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  if Value then
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_ZWRITEENABLE, ITrue)
  else
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_ZWRITEENABLE, IFalse);
end;
function TDJXRenderStates.GetZWriteEnable: boolean;
var
  DWD: DWORD;      
begin
  if (m_States = nil) then
  begin
    result := m_ZWriteEnable;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_ZWriteEnable;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_ZWRITEENABLE, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setZFunc(Value: DWORD);   
begin
  m_ZFunc := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_ZFUNC, Value);
end;
function TDJXRenderStates.getZFunc: DWORD;           
begin
  if (m_States = nil) then
  begin
    result := m_ZFunc;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_ZFunc;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_ZFUNC, Result);
end;
procedure TDJXRenderStates.setAlphaBlendEnable(Value: boolean);  
begin
  m_AlphaBlendEnable := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  if Value then
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_ALPHABLENDENABLE, ITrue)
  else
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_ALPHABLENDENABLE, IFalse);
end;
function TDJXRenderStates.getAlphaBlendEnable: boolean;    
var
  DWD: DWORD;      
begin
  if (m_States = nil) then
  begin
    result := m_AlphaBlendEnable;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_AlphaBlendEnable;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_ALPHABLENDENABLE, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setAlphaTestEnable(Value: boolean);
begin
  m_AlphaTestEnable := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  if Value then
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_ALPHATESTENABLE, ITrue)
  else
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_ALPHATESTENABLE, IFalse);
end;
function TDJXRenderStates.getAlphaTestEnable: boolean;   
var
  DWD: DWORD;      
begin
  if (m_States = nil) then
  begin
    result := m_AlphaTestEnable;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_AlphaTestEnable;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_ALPHATESTENABLE, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setAlphaRef(Value: DWORD);    
begin
  m_AlphaRef := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_ALPHAREF, Value);
end;
function TDJXRenderStates.getAlphaRef: DWORD;            
begin
  if (m_States = nil) then
  begin
    result := m_AlphaRef;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_AlphaRef;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_ALPHAREF, Result);
end;
procedure TDJXRenderStates.setAlphaFunc(Value: DWORD); 
begin
  m_AlphaFunc := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_ALPHAFUNC, Value);
end;
function TDJXRenderStates.getAlphaFunc: DWORD;         
begin
  if (m_States = nil) then
  begin
    result := m_AlphaFunc;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_AlphaFunc;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_ALPHAFUNC, Result);
end;
procedure TDJXRenderStates.setSrcBlend(Value: DWORD);   
begin
  m_SrcBlend := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_SRCBLEND, Value);
end;
function TDJXRenderStates.getSrcBlend: DWORD;           
begin
  if (m_States = nil) then
  begin
    result := m_SrcBlend;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_SrcBlend;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_SRCBLEND, Result);
end;
procedure TDJXRenderStates.setDestBlend(Value: DWORD);   
begin
  m_DestBlend := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_DESTBLEND, Value);
end;
function TDJXRenderStates.getDestBlend: DWORD;         
begin
  if (m_States = nil) then
  begin
    result := m_DestBlend;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_DestBlend;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_DESTBLEND, Result);
end;
procedure TDJXRenderStates.setSeparateAlphaBlendEnable(Value: boolean);   
begin
  m_SeparateAlphaBlendEnable := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  if Value then
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, ITrue)
  else
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, IFalse);
end;
function TDJXRenderStates.getSeparateAlphaBlendEnable: boolean;   
var
  DWD: DWORD;      
begin
  if (m_States = nil) then
  begin
    result := m_SeparateAlphaBlendEnable;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_SeparateAlphaBlendEnable;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setSrcBlendAlpha(Value: DWORD);   
begin
  m_SrcBlendAlpha := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_SRCBLENDALPHA, Value);
end;
function TDJXRenderStates.getSrcBlendAlpha: DWORD;           
begin
  if (m_States = nil) then
  begin
    result := m_SrcBlendAlpha;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_SrcBlendAlpha;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_SRCBLENDALPHA, Result);
end;
procedure TDJXRenderStates.setDestBlendAlpha(Value: DWORD);  
begin
  m_DestBlendAlpha := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_DESTBLENDALPHA, Value);
end;
function TDJXRenderStates.getDestBlendAlpha: DWORD;         
begin
  if (m_States = nil) then
  begin
    result := m_DestBlendAlpha;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_DestBlendAlpha;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_DESTBLENDALPHA, Result);
end;
procedure TDJXRenderStates.setDiffuseMaterialSource(Value: DWORD);  
begin
  m_DiffuseMaterialSource := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, Value);
end;
function TDJXRenderStates.getDiffuseMaterialSource: DWORD;         
begin
  if (m_States = nil) then
  begin
    result := m_DiffuseMaterialSource;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_DiffuseMaterialSource;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, Result);
end;
procedure TDJXRenderStates.setSpecularMaterialSource(Value: DWORD);  
begin
  m_SpecularMaterialSource := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_SPECULARMATERIALSOURCE, Value);
end;
function TDJXRenderStates.getSpecularMaterialSource: DWORD;
begin
  if (m_States = nil) then
  begin
    result := m_SpecularMaterialSource;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_SpecularMaterialSource;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_SPECULARMATERIALSOURCE, Result);
end;
procedure TDJXRenderStates.setAmbientMaterialSource(Value: DWORD);
begin
  m_AmbientMaterialSource := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, Value);
end;
function TDJXRenderStates.getAmbientMaterialSource: DWORD;
begin
  if (m_States = nil) then
  begin
    result := m_AmbientMaterialSource;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_AmbientMaterialSource;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_AMBIENTMATERIALSOURCE, Result);
end;
procedure TDJXRenderStates.setEmissiveMaterialSource(Value: DWORD);
begin
  m_EmissiveMaterialSource := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, Value);
end;
function TDJXRenderStates.getEmissiveMaterialSource: DWORD;
begin
  if (m_States = nil) then
  begin
    result := m_EmissiveMaterialSource;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_EmissiveMaterialSource;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, Result);
end;
procedure TDJXRenderStates.setColorVertex(Value: boolean);
begin
  m_ColorVertex := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  if Value then
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_COLORVERTEX, ITrue)
  else
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_COLORVERTEX, IFalse);
end;
function TDJXRenderStates.getColorVertex: boolean;
var
  DWD: DWORD;
begin
  if (m_States = nil) then
  begin
    result := m_ColorVertex;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_ColorVertex;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_COLORVERTEX, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setStencilEnable(Value: boolean);  
begin
  m_StencilEnable := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  if Value then
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_STENCILENABLE, ITrue)
  else
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_STENCILENABLE, IFalse);
end;
function TDJXRenderStates.getStencilEnable: boolean;        
var
  DWD: DWORD;      
begin
  if (m_States = nil) then
  begin
    result := m_StencilEnable;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_StencilEnable;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_STENCILENABLE, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setStencilFunc(Value: DWORD);   
begin
  m_StencilFunc := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_STENCILFUNC, Value);
end;
function TDJXRenderStates.getStencilFunc: DWORD;         
begin
  if (m_States = nil) then
  begin
    result := m_StencilFunc;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_StencilFunc;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_STENCILFUNC, Result);
end;
procedure TDJXRenderStates.setStencilRef(Value: DWORD);    
begin
  m_StencilRef := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_STENCILREF, Value);
end;
function TDJXRenderStates.getStencilRef: DWORD;            
begin
  if (m_States = nil) then
  begin
    result := m_StencilRef;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_StencilRef;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_STENCILREF, Result);
end;
procedure TDJXRenderStates.setStencilFail(Value: DWORD);  
begin
  m_StencilFail := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_STENCILFAIL, Value);
end;
function TDJXRenderStates.getStencilFail: DWORD;          
begin
  if (m_States = nil) then
  begin
    result := m_StencilFail;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_StencilFail;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_STENCILFAIL, Result);
end;
procedure TDJXRenderStates.setStencilZFail(Value: DWORD); 
begin
  m_StencilZFail := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_STENCILZFAIL, Value);
end;
function TDJXRenderStates.getStencilZFail: DWORD;         
begin
  if (m_States = nil) then
  begin
    result := m_StencilZFail;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_StencilZFail;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_STENCILZFAIL, Result);
end;
procedure TDJXRenderStates.setStencilPass(Value: DWORD);  
begin
  m_StencilPass := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_STENCILPASS, Value);
end;
function TDJXRenderStates.getStencilPass: DWORD;         
begin
  if (m_States = nil) then
  begin
    result := m_StencilPass;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_StencilPass;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_STENCILPASS, Result);
end;
procedure TDJXRenderStates.setStencilMask(Value: DWORD);    
begin
  m_StencilMask := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_STENCILMASK, Value);
end;
function TDJXRenderStates.getStencilMask: DWORD;           
begin
  if (m_States = nil) then
  begin
    result := m_StencilMask;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_StencilMask;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_STENCILMASK, Result);
end;
procedure TDJXRenderStates.setStencilWriteMask(Value: DWORD);  
begin
  m_StencilWriteMask := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_STENCILWRITEMASK, Value);
end;
function TDJXRenderStates.getStencilWriteMask: DWORD;          
begin
  if (m_States = nil) then
  begin
    result := m_StencilWriteMask;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_StencilWriteMask;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_STENCILWRITEMASK, Result);
end;
procedure TDJXRenderStates.setTwoSidedStencilMode(Value: boolean);
begin
  m_TwoSidedStencilMode := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  if Value then
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, ITrue)
  else
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, IFalse);
end;
function TDJXRenderStates.getTwoSidedStencilMode: boolean;
var
  DWD: DWORD;      
begin
  if (m_States = nil) then
  begin
    result := m_TwoSidedStencilMode;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_TwoSidedStencilMode;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_TWOSIDEDSTENCILMODE, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setCCW_StencilFail(Value: DWORD);
begin
  m_CCW_StencilFail := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_CCW_STENCILFAIL, Value);
end;
function TDJXRenderStates.getCCW_StencilFail: DWORD;
begin
  if (m_States = nil) then
  begin
    result := m_CCW_StencilFail;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_CCW_StencilFail;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_CCW_STENCILFAIL, Result);
end;
procedure TDJXRenderStates.setCCW_StencilZFail(Value: DWORD);
begin
  m_CCW_StencilZFail := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_CCW_STENCILZFAIL, Value);
end;
function TDJXRenderStates.getCCW_StencilZFail: DWORD;
begin
  if (m_States = nil) then
  begin
    result := m_CCW_StencilZFail;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_CCW_StencilZFail;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_CCW_STENCILZFAIL, Result);
end;
procedure TDJXRenderStates.setCCW_StencilPass(Value: DWORD);
begin
  m_CCW_StencilPass := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_CCW_STENCILPASS, Value);
end;
function TDJXRenderStates.getCCW_StencilPass: DWORD;
begin
  if (m_States = nil) then
  begin
    result := m_CCW_StencilPass;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_CCW_StencilPass;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_CCW_STENCILPASS, Result);
end;
procedure TDJXRenderStates.setCCW_StencilFunc(Value: DWORD);
begin
  m_CCW_StencilFunc := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_CCW_STENCILFUNC, Value);
end;
function TDJXRenderStates.getCCW_StencilFunc: DWORD;   
begin
  if (m_States = nil) then
  begin
    result := m_CCW_StencilFunc;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_CCW_StencilFunc;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_CCW_STENCILFUNC, Result);
end;
procedure TDJXRenderStates.setFogEnable(Value: boolean);    
begin
  m_FogEnable := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  if Value then
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_FOGENABLE, ITrue)
  else
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_FOGENABLE, IFalse);
end;
function TDJXRenderStates.getFogEnable: boolean;             
var
  DWD: DWORD;      
begin
  if (m_States = nil) then
  begin
    result := m_FogEnable;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_FogEnable;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_FOGENABLE, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setFogColor(Value: D3DCOLOR);   
begin
  m_FogColor := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_FOGCOLOR, Value);
end;
function TDJXRenderStates.getFogColor: D3DCOLOR;             
begin
  if (m_States = nil) then
  begin
    result := m_FogColor;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_FogColor;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_FOGCOLOR, DWORD(Result));
end;
procedure TDJXRenderStates.setFogTableMode(Value: DWORD);    
begin
  m_FogTableMode := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_FOGTABLEMODE, Value);
end;
function TDJXRenderStates.getFogTableMode: DWORD;            
begin
  if (m_States = nil) then
  begin
    result := m_FogTableMode;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_FogTableMode;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_FOGTABLEMODE, Result);
end;
procedure TDJXRenderStates.setFogVertexMode(Value: DWORD);    
begin
  m_FogVertexMode := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_FOGVERTEXMODE, Value);
end;
function TDJXRenderStates.getFogVertexMode: DWORD;            
begin
  if (m_States = nil) then
  begin
    result := m_FogVertexMode;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_FogVertexMode;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_FOGVERTEXMODE, Result);
end;
procedure TDJXRenderStates.setFogStart(Value: single);
begin
  m_FogStart := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_FOGSTART, PDWORD(@Value)^);
end;
function TDJXRenderStates.getFogStart: single;                
begin
  if (m_States = nil) then
  begin
    result := m_FogStart;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_FogStart;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_FOGSTART, PDWORD(@Result)^);
end;
procedure TDJXRenderStates.setFogEnd(Value: single);
begin
  m_FogEnd := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_FOGEND, PDWORD(@Value)^);
end;
function TDJXRenderStates.getFogEnd: single;                  
begin
  if (m_States = nil) then
  begin
    result := m_FogEnd;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_FogEnd;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_FOGEND, PDWORD(@Result)^);
end;
procedure TDJXRenderStates.setRangeFogEnable(Value: boolean); 
begin
  m_RangeFogEnable := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  if Value then
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_RANGEFOGENABLE, ITrue)
  else
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_RANGEFOGENABLE, IFalse);
end;
procedure TDJXRenderStates.setFogDensity(Value: single);          
begin
  m_FogDensity := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_FOGDENSITY, PDWORD(@Value)^);
end;
function TDJXRenderStates.getFogDensity: single;                  
begin
  if (m_States = nil) then
  begin
    result := m_FogDensity;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_FogDensity;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_FOGDENSITY, PDWORD(@Result)^);
end;
function TDJXRenderStates.getRangeFogEnable: boolean;
var
  DWD: DWORD;      
begin
  if (m_States = nil) then
  begin
    result := m_RangeFogEnable;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_RangeFogEnable;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_RANGEFOGENABLE, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setFillMode(Value: DWORD);        
begin
  m_FillMode := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_FILLMODE, Value);
end;
function TDJXRenderStates.getFillMode: DWORD;               
begin
  if (m_States = nil) then
  begin
    result := m_FillMode;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_FillMode;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_FILLMODE, Result);
end;
procedure TDJXRenderStates.setShadeMode(Value: DWORD);      
begin
  m_ShadeMode := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_SHADEMODE, Value);
end;
function TDJXRenderStates.getShadeMode: DWORD;           
begin
  if (m_States = nil) then
  begin
    result := m_ShadeMode;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_ShadeMode;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_SHADEMODE, Result);
end;
procedure TDJXRenderStates.setCullMode(Value: DWORD);   
begin
  m_CullMode := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_CULLMODE, Value);
end;
function TDJXRenderStates.getCullMode: DWORD;            
begin
  if (m_States = nil) then
  begin
    result := m_CullMode;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_CullMode;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_CULLMODE, Result);
end;
procedure TDJXRenderStates.setDitherEnable(Value: boolean);  
begin
  m_DitherEnable := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  if Value then
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_DITHERENABLE, ITrue)
  else
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_DITHERENABLE, IFalse);
end;
function TDJXRenderStates.getDitherEnable: boolean;         
var
  DWD: DWORD;      
begin
  if (m_States = nil) then
  begin
    result := m_DitherEnable;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_DitherEnable;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_DITHERENABLE, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setSpecularEnable(Value: boolean);  
begin
  m_SpecularEnable := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  if Value then
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_SPECULARENABLE, ITrue)
  else
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_SPECULARENABLE, IFalse);
end;
function TDJXRenderStates.getSpecularEnable: boolean;         
var
  DWD: DWORD;      
begin
  if (m_States = nil) then
  begin
    result := m_SpecularEnable;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_SpecularEnable;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_SPECULARENABLE, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setLighting(Value: boolean);      
begin
  m_Lighting := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  if Value then
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_LIGHTING, ITrue)
  else
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_LIGHTING, IFalse);
end;
function TDJXRenderStates.getLighting: boolean;             
var
  DWD: DWORD;      
begin
  if (m_States = nil) then
  begin
    result := m_Lighting;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_Lighting;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_LIGHTING, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setAmbient(Value: D3DCOLOR);     
begin
  m_Ambient := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_AMBIENT, Value);
end;
function TDJXRenderStates.getAmbient: D3DCOLOR;            
begin
  if (m_States = nil) then
  begin
    result := m_Ambient;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_Ambient;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_AMBIENT, DWORD(Result));
end;
procedure TDJXRenderStates.setDepthBias(Value: single);     
begin
  m_DepthBias := Value;
  if (m_States=nil)or((m_States<>nil)and(not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_DEPTHBIAS, PDWORD(@Value)^);
end;
function TDJXRenderStates.getDepthBias: single;             
begin
  if (m_States = nil) then
  begin
    result := m_DepthBias;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_DepthBias;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_DEPTHBIAS, PDWORD(@Result)^);
end;
procedure TDJXRenderStates.setSlopeScaleDepthBias(Value: single);
begin
  m_SlopeScaleDepthBias := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, PDWORD(@Value)^);
end;
function TDJXRenderStates.getSlopeScaleDepthBias: single;
begin
  if (m_States = nil) then
  begin
    result := m_SlopeScaleDepthBias;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_SlopeScaleDepthBias;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, PDWORD(@Result)^);
end;
procedure TDJXRenderStates.setNormalizeNormals(Value: boolean);
begin
  m_NormalizeNormals := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  if Value then
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_NORMALIZENORMALS, ITrue)
  else
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_NORMALIZENORMALS, IFalse);
end;
function TDJXRenderStates.getNormalizeNormals: boolean;      
var
  DWD: DWORD;      
begin
  if (m_States = nil) then
  begin
    result := m_NormalizeNormals;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_NormalizeNormals;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_NORMALIZENORMALS, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setMultiSampleAntialias(Value: boolean);
begin
  m_MultiSampleAntialias := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, DWORD(Value));
end;
function TDJXRenderStates.getMultiSampleAntialias: boolean;
var
  DWD: DWORD;      
begin
  if (m_States = nil) then
  begin
    result := m_MultiSampleAntialias;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_MultiSampleAntialias;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_MULTISAMPLEANTIALIAS, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setMultiSampleMask(Value: DWORD);
begin
  m_MultiSampleMask := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_MULTISAMPLEMASK, Value);
end;
function TDJXRenderStates.getMultiSampleMask: DWORD;        
begin
  if (m_States = nil) then
  begin
    result := m_MultiSampleMask;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_MultiSampleMask;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_MULTISAMPLEMASK, Result);
end;
procedure TDJXRenderStates.setScissorTestEnable(Value: boolean);
begin
  m_ScissorTestEnable := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_SCISSORTESTENABLE, DWORD(Value));
end;
function TDJXRenderStates.getScissorTestEnable: boolean;
var
  DWD: DWORD;
begin
  if (m_States = nil) then
  begin
    result := m_ScissorTestEnable;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_ScissorTestEnable;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_SCISSORTESTENABLE, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setClipPlaneEnable(Value: boolean);
begin
  m_ClipPlaneEnable := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_CLIPPLANEENABLE, DWORD(Value));
end;
function TDJXRenderStates.getClipPlaneEnable: boolean;
var
  DWD: DWORD;
begin
  if (m_States = nil) then
  begin
    result := m_ClipPlaneEnable;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_ClipPlaneEnable;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_CLIPPLANEENABLE, DWD);
  result := (DWD = ITrue);
end;
procedure TDJXRenderStates.setAntialiasedLineEnable(Value: boolean);
begin
  m_AntialiasedLineEnable := Value;
  if (m_States = nil) or ((m_States <> nil) and (not TDanJetX(m_States.DanJetX).Initialized)) then
  Exit;
  TDanJetX(m_States.DanJetX).Device.SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, DWORD(Value));
end;
function TDJXRenderStates.getAntialiasedLineEnable: boolean;
var
  DWD: DWORD;
begin
  if (m_States = nil) then
  begin
    result := m_AntialiasedLineEnable;
    Exit;
  end;
  if (not TDanJetX(m_States.DanJetX).Initialized) then
  begin
    Result := m_AntialiasedLineEnable;
    Exit;
  end;
  TDanJetX(m_States.DanJetX).Device.GetRenderState(D3DRS_ANTIALIASEDLINEENABLE, DWD);
  result := (DWD = ITrue);
end;
//DJXRenderStates END

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

procedure TDJXMatrices.SetW(m: TD3DXMatrix);
begin
  move(m, TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld, sizeof(TD3DXMatrix));
  TDanJetX(m_DanJetX).Device.SetTransform(D3DTS_WORLD, m);
end;
function TDJXMatrices.GetW: TD3DXMatrix;    
begin
  result := TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld;
end;
procedure TDJXMatrices.SetV(m: TD3DXMatrix);
begin
  move(m, TDJXRender(TDanJetX(m_DanJetX).Render).m_matView, sizeof(TD3DXMatrix));
  TDanJetX(m_DanJetX).Device.SetTransform(D3DTS_VIEW, m);
end;
function TDJXMatrices.GetV: TD3DXMatrix;    
begin
  result := TDJXRender(TDanJetX(m_DanJetX).Render).m_matView;
end;
procedure TDJXMatrices.SetP(m: TD3DXMatrix); 
begin
  move(m, TDJXRender(TDanJetX(m_DanJetX).Render).m_matProj, sizeof(TD3DXMatrix));
  TDanJetX(m_DanJetX).Device.SetTransform(D3DTS_PROJECTION, m);
end;
function TDJXMatrices.GetP: TD3DXMatrix;  
begin
  result := TDJXRender(TDanJetX(m_DanJetX).Render).m_matProj;
end;
function TDJXMatrices.GetWV: TD3DXMatrix;
begin
  D3DXMatrixMultiply(result, GetW, GetV);
end;
function TDJXMatrices.GetVP: TD3DXMatrix;
begin
  D3DXMatrixMultiply(result, GetV, GetP);
end;
function TDJXMatrices.GetWVP: TD3DXMatrix;
begin
  D3DXMatrixMultiply(result, GetWV, GetP);
end;
function TDJXMatrices.GetWt: TD3DXMatrix;
begin
  D3DXMatrixTranspose(result, GetW);
end;
function TDJXMatrices.GetVt: TD3DXMatrix;
begin
  D3DXMatrixTranspose(result, GetV);
end;
function TDJXMatrices.GetPt: TD3DXMatrix;
begin
  D3DXMatrixTranspose(result, GetP);
end;
function TDJXMatrices.GetWVt: TD3DXMatrix;
begin
  D3DXMatrixTranspose(result, GetWV);
end;
function TDJXMatrices.GetVPt: TD3DXMatrix;
begin
  D3DXMatrixTranspose(result, GetVP);
end;
function TDJXMatrices.GetWVPt: TD3DXMatrix;
begin
  D3DXMatrixTranspose(result, GetWVP);
end;
function TDJXMatrices.GetWi: TD3DXMatrix;
begin
  D3DXMatrixInverse(result, nil, GetW);
end;
function TDJXMatrices.GetVi: TD3DXMatrix;
begin
  D3DXMatrixInverse(result, nil, GetV);
end;
function TDJXMatrices.GetPi: TD3DXMatrix;
begin
  D3DXMatrixInverse(result, nil, GetP);
end;
function TDJXMatrices.GetWVi: TD3DXMatrix;
begin
  D3DXMatrixInverse(result, nil, GetWV);
end;
function TDJXMatrices.GetVPi: TD3DXMatrix;
begin
  D3DXMatrixInverse(result, nil, GetVP);
end;
function TDJXMatrices.GetWVPi: TD3DXMatrix;  
begin
  D3DXMatrixInverse(result, nil, GetWVP);
end;
//TDJXMatrices END

//TDJXMatrices3D BEGIN
constructor TDJXMatrices3D.Create(DanJetX: Pointer);
begin
  inherited Create;
  m_DanJetX := DanJetX;
end;
destructor TDJXMatrices3D.Destroy;
begin
  inherited Destroy;
end;
procedure TDJXMatrices3D.ClearWorldMatrix;
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DClearWorldMatrix;
end;
procedure TDJXMatrices3D.ApplyWorldMatrix;
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DApplyWorldMatrix;
end;
procedure TDJXMatrices3D.TransformWorld(
  moveX, moveY, moveZ,
  rotateX, rotateY, rotateZ,
  scaleX, scaleY, scaleZ: single
);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DScaleWorld(scaleX, scaleY, scaleZ);
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DRotateWorld(rotateX, rotateY, rotateZ);
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DMoveWorld(moveX, moveY, moveY);
end;
procedure TDJXMatrices3D.TransformWorld(m: TD3DXMatrix);
begin
  D3DXMatrixMultiply(
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld,
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld,
    m
  );
end;
procedure TDJXMatrices3D.ScaleWorld(X, Y, Z: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DScaleWorld(X, Y, Z);
end;
procedure TDJXMatrices3D.RotateWorldAroundVector(X, Y, Z: single; Angle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DRotateWorldAroundVector(X, Y, Z, Angle);
end;
procedure TDJXMatrices3D.RotateWorld(Xangle, Yangle, Zangle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DRotateWorld(Xangle, Yangle, Zangle);
end;
procedure TDJXMatrices3D.RotateWorldX(Angle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DRotateWorldX(Angle);
end;
procedure TDJXMatrices3D.RotateWorldY(Angle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DRotateWorldY(Angle);
end;
procedure TDJXMatrices3D.RotateWorldZ(Angle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DRotateWorldZ(Angle);
end;
procedure TDJXMatrices3D.MoveWorld(X, Y, Z: double);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DMoveWorld(X, Y, Z);
end;
procedure TDJXMatrices3D.MultiplyWorld(m: TD3DXMatrix);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DMultiplyWorld(m);
end;
procedure TDJXMatrices3D.Billboard;
var
  PrevX, PrevY, PrevZ: single;
begin
  PrevX := TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld._41;
  PrevY := TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld._42;
  PrevZ := TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld._43;
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DInverseWorldTo(
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matView
  );
  TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld._41 := PrevX;
  TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld._42 := PrevY;
  TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld._43 := PrevZ;
end;
procedure TDJXMatrices3D.PreTransformWorld(
      moveX, moveY, moveZ,
      rotateX, rotateY, rotateZ,
      scaleX, scaleY, scaleZ: single
    );
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DPreMoveWorld(moveX, moveY, moveY);
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DPreRotateWorld(rotateX, rotateY, rotateZ);
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DPreScaleWorld(scaleX, scaleY, scaleZ);
end;
procedure TDJXMatrices3D.PreTransformWorld(m: TD3DXMatrix); 
begin
  D3DXMatrixMultiply(
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld,
    m,
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld
  );
end;
procedure TDJXMatrices3D.PreScaleWorld(X, Y, Z: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DPreScaleWorld(X, Y, Z);
end;
procedure TDJXMatrices3D.PreRotateWorldAroundVector(X, Y, Z: single; Angle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DPreRotateWorldAroundVector(X, Y, Z, Angle);
end;
procedure TDJXMatrices3D.PreRotateWorld(Xangle, Yangle, Zangle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DPreRotateWorld(Xangle, Yangle, Zangle);
end;
procedure TDJXMatrices3D.PreRotateWorldX(Angle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DPreRotateWorldX(Angle);
end;
procedure TDJXMatrices3D.PreRotateWorldY(Angle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DPreRotateWorldY(Angle);
end;
procedure TDJXMatrices3D.PreRotateWorldZ(Angle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DPreRotateWorldZ(Angle);
end;
procedure TDJXMatrices3D.PreMoveWorld(X, Y, Z: double);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DPreMoveWorld(X, Y, Z);
end;
procedure TDJXMatrices3D.PreMultiplyWorld(m: TD3DXMatrix);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DPreMultiplyWorld(m);
end;
procedure TDJXMatrices3D.PushWorldMatrix;
var
  h: integer;
begin
  h := Length(m_WorldMatrixStack);
  SetLength(m_WorldMatrixStack, h + 1);
  Move(
    TDJXRender(TDanJetX(m_DanJetX).Render).m_MatWorld,
    m_WorldMatrixStack[h],
    SizeOf(TD3DXMatrix)
  );
end;
procedure TDJXMatrices3D.PopWorldMatrix;
var
  h: integer;
begin
  h := High(m_WorldMatrixStack);
  if h < 0 then Exit;
  Move(
    m_WorldMatrixStack[h],
    TDJXRender(TDanJetX(m_DanJetX).Render).m_MatWorld,
    SizeOf(TD3DXMatrix)
  );
  SetLength(m_WorldMatrixStack, h);
end;
function TDJXMatrices3D.GetCombinedTransposedMatrix: TD3DXMatrix;
var
  TransformMatrix: TD3DXMatrix;
begin
  D3DXMatrixMultiply(
    TransformMatrix,
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld,
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matView
  );
  D3DXMatrixMultiply(
    TransformMatrix,
    TransformMatrix,
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matProj
  );
  D3DXMatrixTranspose(result, TransformMatrix);
end;
function TDJXMatrices3D.GetCombinedMatrix: TD3DXMatrix;
begin
  D3DXMatrixMultiply(
    result,
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld,
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matView
  );
  D3DXMatrixMultiply(
    result,
    result,
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matProj
  );
end;
function TDJXMatrices3D.GetWorldMatrix: TD3DXMatrix;
begin
  result := TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld;
end;
function TDJXMatrices3D.GetInverseWorldMatrix: TD3DXMatrix;
begin
  D3DXMatrixInverse(result, nil, TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld);
end;
function TDJXMatrices3D.GetTransposeWorldMatrix: TD3DXMatrix;
begin
  D3DXMatrixTranspose(result, TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld);
end;
//TDJXMatrices3D END

//DJXMatricesTex BEGIN
constructor TDJXMatricesTex.Create(DanJetX: Pointer);
begin
  inherited Create;
  m_DanJetX := DanJetX;
end;
destructor TDJXMatricesTex.Destroy;
begin
  inherited Destroy;
end;
procedure TDJXMatricesTex.ClearTexMatrix;
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).PrsTexClearTexMatrix;
end;
procedure TDJXMatricesTex.ApplyTexMatrix(Stage: byte);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).PrsTexApplyTexMatrix(Stage);
end;
procedure TDJXMatricesTex.TransformTex(
  moveX, moveY, moveZ,
  rotateX, rotateY, rotateZ,
  scaleX, scaleY, scaleZ: single
);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).PrsTexScaleTex(scaleX, scaleY, scaleZ);
  TDJXRender(TDanJetX(m_DanJetX).Render).PrsTexRotateTex(rotateX, rotateY, rotateZ);
  TDJXRender(TDanJetX(m_DanJetX).Render).PrsTexMoveTex(moveX, moveY, moveY);
end;
procedure TDJXMatricesTex.ScaleTex(X, Y, Z: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).PrsTexScaleTex(X, Y, Z);
end;
procedure TDJXMatricesTex.RotateTexAroundVector(X,Y,Z: single; Angle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).PrsTexRotateTexAroundVector(X, Y, Z, Angle);
end;
procedure TDJXMatricesTex.RotateTex(Xangle, Yangle, Zangle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).PrsTexRotateTex(Xangle, Yangle, Zangle);
end;
procedure TDJXMatricesTex.RotateTexX(Angle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).PrsTexRotateTexX(Angle);
end;
procedure TDJXMatricesTex.RotateTexY(Angle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).PrsTexRotateTexY(Angle);
end;
procedure TDJXMatricesTex.RotateTexZ(Angle: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).PrsTexRotateTexZ(Angle);
end;
procedure TDJXMatricesTex.MoveTex(X, Y, Z: double);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).PrsTexMoveTex(X, Y, Z);
end;
//DJXMatricesTex END

//TDJXCamera BEGIN
constructor TDJXCamera.Create(DanJetX: Pointer);
begin
  inherited Create;
  m_DanJetX := DanJetX;
end;
destructor TDJXCamera.Destroy;
begin
  inherited Destroy;
end;
procedure TDJXCamera.Reset;
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetView(
    m_eyePtX, m_eyePtY, m_eyePtZ,
    m_LookAtX, m_LookAtY, m_LookAtZ,
    m_upVecX, m_upVecY, m_upVecZ
  );
end;
procedure TDJXCamera.Update;
begin
  TDanJetX(m_DanJetX).Device.GetTransform(
    D3DTS_PROJECTION, TDJXRender(TDanJetX(m_DanJetX).Render).m_matProj
  );
  TDanJetX(m_DanJetX).Device.GetTransform(
    D3DTS_VIEW, TDJXRender(TDanJetX(m_DanJetX).Render).m_matView
  );
end;
procedure TDJXCamera.SetPerspectiveORT;
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetPerspectiveORT;
end;
procedure TDJXCamera.SetPerspectiveORT(Width, Height, ZNear, ZFar: single);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetPerspectiveORT(Width, Height, ZNear, ZFar);
end;
procedure TDJXCamera.SetPerspective;
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetPerspective;
end;
procedure TDJXCamera.SetPerspective(Aspect, ZNear, ZFar: single; FOV: single = defFOV);
begin
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetPerspective(Aspect, ZNear, ZFar, FOV);
end;
procedure TDJXCamera.SetView(
  NewEyePtX, NewEyePtY, NewEyePtZ: single;
  NewLookAtX, NewLookAtY, NewLookAtZ: single;
  NewupVecX, NewupVecY, NewupVecZ: single
);
begin
  m_EyePtX := NewEyePtX;
  m_EyePtY := NewEyePtY;
  m_EyePtZ := NewEyePtZ;
  m_LookAtX := NewLookAtX;
  m_LookAtY := NewLookAtY;
  m_LookAtZ := NewLookAtZ;
  m_UpVecX := NewUpVecX;
  m_UpVecY := NewUpVecY;
  m_UpVecZ := NewUpVecZ;
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetView(
    eyePtX,eyePtY, eyePtZ,
    LookAtX, LookAtY, LookAtZ,
    upVecX, upVecY, upVecZ
  );
end;
procedure TDJXCamera.SetView(NewEyePt, NewLookAt, NewupVec: TD3DXVector3);
begin
  m_EyePtX := NewEyePt.x;
  m_EyePtY := NewEyePt.Y;
  m_EyePtZ := NewEyePt.Z;
  m_LookAtX := NewLookAt.X;
  m_LookAtY := NewLookAt.Y;
  m_LookAtZ := NewLookAt.Z;
  m_UpVecX := NewUpVec.X;
  m_UpVecY := NewUpVec.Y;
  m_UpVecZ := NewUpVec.Z;
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetView(NewEyePt, NewLookAt, NewupVec);
end;
procedure TDJXCamera.SetEyePtX(Value: single);
begin
  m_EyePtX := Value;
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetView(
    m_EyePtX, m_EyePtY, m_EyePtZ,
    m_LookAtX, m_LookAtY, m_LookAtZ,
    m_upVecX, m_upVecY, m_upVecZ
  );
end;
procedure TDJXCamera.SetEyePtY(Value: single);
begin
  m_EyePtY := Value;
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetView(
    m_EyePtX, m_EyePtY, m_EyePtZ,
    m_LookAtX, m_LookAtY, m_LookAtZ,
    m_upVecX, m_upVecY, m_upVecZ
  );
end;
procedure TDJXCamera.SetEyePtZ(Value: single);
begin
  m_EyePtZ := Value;
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetView(
    m_EyePtX, m_EyePtY, m_EyePtZ,
    m_LookAtX, m_LookAtY, m_LookAtZ,
    m_upVecX, m_upVecY, m_upVecZ
  );
end;
procedure TDJXCamera.SetLookAtX(Value: single);
begin
  m_LookAtX := Value;
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetView(
    m_EyePtX, m_EyePtY, m_EyePtZ,
    m_LookAtX, m_LookAtY, m_LookAtZ,
    m_upVecX, m_upVecY, m_upVecZ
  );
end;
procedure TDJXCamera.SetLookAtY(Value: single);
begin
  m_LookAtY := Value;
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetView(
    m_EyePtX, m_EyePtY, m_EyePtZ,
    m_LookAtX, m_LookAtY, m_LookAtZ,
    m_upVecX, m_upVecY, m_upVecZ
  );
end;
procedure TDJXCamera.SetLookAtZ(Value: single);
begin
  m_LookAtZ := Value;
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetView(
    m_EyePtX, m_EyePtY, m_EyePtZ,
    m_LookAtX, m_LookAtY, m_LookAtZ,
    m_upVecX, m_upVecY, m_upVecZ
  );
end;
procedure TDJXCamera.SetUpVecX(Value: single);
begin
  m_upVecX := Value;
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetView(
    m_EyePtX, m_EyePtY, m_EyePtZ,
    m_LookAtX, m_LookAtY, m_LookAtZ,
    m_upVecX, m_upVecY, m_upVecZ
  );
end;
procedure TDJXCamera.SetUpVecY(Value: single);
begin
  m_upVecY := Value;
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetView(
    m_EyePtX, m_EyePtY, m_EyePtZ,
    m_LookAtX, m_LookAtY, m_LookAtZ,
    m_upVecX, m_upVecY, m_upVecZ
  );
end;
procedure TDJXCamera.SetUpVecZ(Value: single);
begin
  m_upVecZ := Value;
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetView(
    m_EyePtX, m_EyePtY, m_EyePtZ,
    m_LookAtX, m_LookAtY, m_LookAtZ,
    m_upVecX, m_upVecY, m_upVecZ
  );
end;
procedure TDJXCamera.rotateEye(const x, y: single; distance: single = 1; sensitivity: single = 0.005);
var
  hang: single;
  VecPl: TD3DXVector3;
begin
  VecPl.Y := (m_EyePtY - m_LookAtY) / distance;
  VecPl.X := m_EyePtX - m_LookAtX;
  VecPl.Z := m_EyePtZ - m_LookAtZ;
  VecPl.Y := limit_dbl(VecPl.Y - y * sensitivity, -0.99, 0.99);
  hang := (getAngRad(0, 0, VecPl.X, VecPl.Z)) - x * sensitivity;
  VecPl.X := Cos(hang) * (1 - Abs(VecPl.Y));
  VecPl.Z := Sin(hang) * (1 - Abs(VecPl.Y));
  m_EyePtY := m_LookAtY + VecPl.Y * distance;
  m_EyePtX := m_LookAtX + VecPl.X * distance;
  m_EyePtZ := m_LookAtZ + VecPl.Z * distance;
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetView(
    m_EyePtX, m_EyePtY, m_EyePtZ,
    m_LookAtX, m_LookAtY, m_LookAtZ,
    m_upVecX, m_upVecY, m_upVecZ
  );
end;
procedure TDJXCamera.rotateView(const x, y: single; sensitivity: single = 0.005);
var
  hang: single;
  VecPl: TD3DXVector3;
begin
  VecPl.Y := m_LookAtY - m_EyePtY;
  VecPl.X := m_LookAtX - m_EyePtX;
  VecPl.Z := m_LookAtZ - m_EyePtZ;
  VecPl.Y := limit_dbl(VecPl.Y - y * sensitivity, -0.99, 0.99);
  hang := (getAngRad(0, 0, VecPl.X, VecPl.Z)) - x * sensitivity;
  VecPl.X := Cos(hang) * ( 1 - Abs(VecPl.Y));
  VecPl.Z := Sin(hang) * (1 - Abs(VecPl.Y));
  m_LookAtY := m_EyePtY + VecPl.Y;
  m_LookAtX := m_EyePtX + VecPl.X;
  m_LookAtZ := m_EyePtZ + VecPl.Z;
  TDJXRender(TDanJetX(m_DanJetX).Render).Prs3DSetView(
    m_EyePtX, m_EyePtY, m_EyePtZ,
    m_LookAtX, m_LookAtY, m_LookAtZ,
    m_upVecX, m_upVecY, m_upVecZ
  );
end;
function TDJXCamera.GenerateFrustum: TDJXFrustum;
var
  frustum: TDJXFrustum;
  matComb: TD3DXMatrixA16;
begin
  frustum := TDJXFrustum.Create;
  D3DXMatrixMultiply(
    matComb,
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matView,
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matProj
  );
  //Left plane
  frustum.m_Planes[0].normal.x := matComb._14 + matComb._11;
  frustum.m_Planes[0].normal.y := matComb._24 + matComb._21;
  frustum.m_Planes[0].normal.z := matComb._34 + matComb._31;
  frustum.m_Planes[0].distance := matComb._44 + matComb._41;

  //Right plane
  frustum.m_Planes[1].normal.x := matComb._14 - matComb._11;
  frustum.m_Planes[1].normal.y := matComb._24 - matComb._21;
  frustum.m_Planes[1].normal.z := matComb._34 - matComb._31;
  frustum.m_Planes[1].distance := matComb._44 - matComb._41;

  //Top plane
  frustum.m_Planes[2].normal.x := matComb._14 - matComb._12;
  frustum.m_Planes[2].normal.y := matComb._24 - matComb._22;
  frustum.m_Planes[2].normal.z := matComb._34 - matComb._32;
  frustum.m_Planes[2].distance := matComb._44 - matComb._42;

  //Bottom plane
  frustum.m_Planes[3].normal.x := matComb._14 + matComb._12;
  frustum.m_Planes[3].normal.y := matComb._24 + matComb._22;
  frustum.m_Planes[3].normal.z := matComb._34 + matComb._32;
  frustum.m_Planes[3].distance := matComb._44 + matComb._42;

  //Near plane
  frustum.m_Planes[4].normal.x := matComb._13;
  frustum.m_Planes[4].normal.y := matComb._23;
  frustum.m_Planes[4].normal.z := matComb._33;
  frustum.m_Planes[4].distance := matComb._43;

  //Near plane
  frustum.m_Planes[5].normal.x := matComb._14 - matComb._13;
  frustum.m_Planes[5].normal.y := matComb._24 - matComb._23;
  frustum.m_Planes[5].normal.z := matComb._34 - matComb._33;
  frustum.m_Planes[5].distance := matComb._44 - matComb._43;

  result := frustum;
end;
function TDJXCamera.PointInFrustum(Pt: TD3DXVector3; frustum: TDJXFrustum = nil): boolean;
var
  i: integer;
  frust: TDJXFrustum;
  dist: single;
begin
  result := true;
  if frustum = nil then
  frust := GenerateFrustum
  else
  frust := frustum;
  for i := 0 to 5 do
  begin
    dist := frust.DistanceToPoint(i, Pt);
    if dist <= 0 then
    begin
      result := false;
      break;
    end;
  end;
  if frustum = nil then
  frust.Free;
end;
function TDJXCamera.BoxInFrustum(MinBounds, MaxBounds: TD3DXVector3; Frustum: TDJXFrustum = nil): boolean;
var
  i: integer;
  Frust: TDJXFrustum;
  MinPoint, MaxPoint: TD3DXVector3;
begin
  if Frustum = nil then
  Frust := TDanJetX(m_DanJetX).Camera.GenerateFrustum
  else
  Frust := Frustum;
  result := true;
  for i := 0 to 5 do
  begin
    if Frust.Planes[i].normal.x <= 0 then
    begin
      MinPoint.x := MinBounds.x;
      MaxPoint.x := MaxBounds.x;
    end
    else
    begin
      MinPoint.x := MaxBounds.x;
      MaxPoint.x := MinBounds.x;
    end;
    if Frust.Planes[i].normal.y <= 0 then
    begin
      MinPoint.y := MinBounds.y;
      MaxPoint.y := MaxBounds.y;
    end
    else
    begin
      MinPoint.y := MaxBounds.y;
      MaxPoint.y := MinBounds.y;
    end;
    if Frust.Planes[i].normal.z <= 0 then
    begin
      MinPoint.z := MinBounds.z;
      MaxPoint.z := MaxBounds.z;
    end
    else
    begin
      MinPoint.z := MaxBounds.z;
      MaxPoint.z := MinBounds.z;
    end;
    if Frust.DistanceToPoint(i, MinPoint) < 0 then
    begin
      result := false;
      break;
    end;
  end;
  if Frustum = nil then Frust.Free;
end;
function TDJXCamera.SphereInFrustum(Center: TD3DXVector3; Radius: single; Frustum: TDJXFrustum = nil): boolean;
var
  i: integer;
  Frust: TDJXFrustum;
begin
  if Frustum = nil then
  Frust := TDanJetX(m_DanJetX).Camera.GenerateFrustum
  else
  Frust := Frustum;
  result := true;
  for i := 0 to 5 do
  if (
    Frust.Planes[i].normal.x * Center.x +
    Frust.Planes[i].normal.y * Center.y +
    Frust.Planes[i].normal.z * Center.z +
    Frust.Planes[i].distance <= -Radius
  ) then
  begin
    result := false;
    break;
  end;
  if Frustum = nil then Frust.Free;
end;
procedure TDJXCamera.MousePosToVector(var RayOrigin, RayDir: TD3DXVector3);
var
  Vec: TD3DXVector3;
  mc: TPoint;
  w, h: integer;
  ViewInverseMat: TD3DXMatrix;
begin
  mc := TDanJetX(m_DanJetX).MousePos;
  w := TDanJetX(m_DanJetX).ViewPort.Width;
  h := TDanJetX(m_DanJetX).ViewPort.Height;
  Vec.x := (((mc.X * 2) / w) - 1) / TDJXRender(TDanJetX(m_DanJetX).Render).m_MatProj._11;
  Vec.y := -(((mc.Y * 2) / h) - 1) / TDJXRender(TDanJetX(m_DanJetX).Render).m_MatProj._22;
  Vec.z := 1;
  D3DXMatrixInverse(
    ViewInverseMat,
    nil,
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matView
  );
  RayDir.x := Vec.x * ViewInverseMat._11 + Vec.y * ViewInverseMat._21 + Vec.z * ViewInverseMat._31;
  RayDir.y := Vec.x * ViewInverseMat._12 + Vec.y * ViewInverseMat._22 + Vec.z * ViewInverseMat._32;
  RayDir.z := Vec.x * ViewInverseMat._13 + Vec.y * ViewInverseMat._23 + Vec.z * ViewInverseMat._33;
  RayOrigin.x := ViewInverseMat._41;
  RayOrigin.y := ViewInverseMat._42;
  RayOrigin.z := ViewInverseMat._43;
end;
function TDJXCamera.PickTriangle(
      Vec1, Vec2, Vec3: TD3DXVector3;
      var dist: single;
      var HitPos: TD3DXVector3
    ): boolean;
var
  Orig, Dir: TD3DXVector3;
  matInverse: TD3DXMatrix;
  hit: boolean;
  u, v: single;
begin
  D3DXMatrixInverse(matInverse, nil, TDJXRender(TDanJetX(m_DanJetX).Render).m_matWorld);

  TDanJetX(m_DanJetX).Camera.MousePosToVector(Orig, Dir);

  D3DXVec3TransformCoord(Orig, Orig, matInverse);
  D3DXVec3TransformNormal(Dir, Dir, matInverse);
  D3DXVec3Normalize(Dir, Dir);

  hit:=D3DXIntersectTri(
    Vec1, Vec2, Vec3,
    Orig,
    Dir,
    u,v,
    dist
  );

  if hit then
  HitPos := D3DXVector3(Orig.x + Dir.x * dist, Orig.y + Dir.y * dist, Orig.z + Dir.z * dist)
  else
  HitPos := D3DXVector3(0, 0, 0);
  
  result := hit;
end;
function TDJXCamera.GetViewMatrix: TD3DXMatrix;
begin
  result := TDJXRender(TDanJetX(m_DanJetX).Render).m_matView;
end;
function TDJXCamera.GetProjectionMatrix: TD3DXMatrix;
begin
  result := TDJXRender(TDanJetX(m_DanJetX).Render).m_matProj;
end;
function TDJXCamera.GetCombinedViewProjection: TD3DXMatrix;
begin
  D3DXMatrixMultiply(
    result,
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matView,
    TDJXRender(TDanJetX(m_DanJetX).Render).m_matProj
  );
end;
function TDJXCamera.GetCombinedTransposedViewProjection: TD3DXMatrix;
begin
  result := GetCombinedViewProjection;
  D3DXMatrixTranspose(result, result);
end;
function TDJXCamera.GetViewVector3: TD3DXVector3;
begin
  D3DXVec3Subtract(
    result,
    D3DXVector3(m_LookAtX, m_LookAtY, m_LookAtZ),
    D3DXVector3(m_EyePtX, m_EyePtY, m_EyePtZ)
  );
  D3DXVec3Normalize(result, result);
end;
function TDJXCamera.GetViewVector4: TD3DXVector4;
var
  v3: TD3DXVector3;
begin
  v3 := GetViewVector3;
  result := D3DXVector4(v3, 0);
end;
function TDJXCamera.GetCamPosVector3: TD3DXVector3;
begin
  result := D3DXVector3(
    m_EyePtX, m_EyePtY, m_EyePtZ
  );
end;
function TDJXCamera.GetCamPosVector4: TD3DXVector4;
var
  v3: TD3DXVector3;
begin
  v3 := GetCamPosVector3;
  result := D3DXVector4(v3, 1);
end;
//TDJXCamera END

//TDJXFrustum BEGIN
function TDJXFrustum.GetPlane(Index: integer): TDJXFrustumPlane;
begin
  if (Index < 0) or (Index > 5) then exit;
  result := m_planes[Index];
end;
procedure TDJXFrustum.Normalize;
var
  i: integer;
  grad: single;
begin
  for i := 0 to 5 do
  begin
    grad := 1 / sqrt(
      sqr(m_planes[i].normal.x) +
      sqr(m_planes[i].normal.y) +
      sqr(m_planes[i].normal.z)
    );
    m_planes[i].normal.x := m_planes[i].normal.x * grad;
    m_planes[i].normal.y := m_planes[i].normal.y * grad;
    m_planes[i].normal.z := m_planes[i].normal.z * grad;
    m_planes[i].distance := m_planes[i].distance * grad;
  end;
end;
function TDJXFrustum.DistanceToPoint(PlaneIndex: integer; Pt: TD3DXVector3): single;
begin
  result := D3DXVec3Dot(m_planes[PlaneIndex].normal,Pt) + m_planes[PlaneIndex].distance;
end;
//TDJXFrustum END

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

function TDJXRender.GetMatWorld: PD3DXMatrix;
begin
  Result := PD3DXMatrix(@m_MatWorld);
end;
function TDJXRender.GetMatView: PD3DXMatrix;
begin
  Result := PD3DXMatrix(@m_MatView);
end;
function TDJXRender.GetMatProj: PD3DXMatrix;
begin
  Result := PD3DXMatrix(@m_MatProj);
end;
function TDJXRender.GetMatTex: PD3DXMatrix;
begin
  Result := PD3DXMatrix(@m_MatTex);
end;

procedure TDJXRender.Init;
begin
  m_VB2D := TDJXVB2D.Create(m_DanJetX);
  m_VB2D.initVB(4);

  m_VB3D := TDJXVB3D.Create(m_DanJetX);
  m_VB3D.initVB(4);

  m_Shaders := TDJXShaders.Create(m_DanJetX);
end;
procedure TDJXRender.UnInit;
begin
  if m_VB2D <> nil then m_VB2D.Free;
  if m_VB3D <> nil then m_VB3D.Free;
  if m_Shaders <> nil then m_Shaders.Free;
end;
procedure TDJXRender.Prs3DClearWorldMatrix;
begin
  D3DXMatrixIdentity(m_MatWorld);
end;
procedure TDJXRender.Prs3DApplyWorldMatrix;
begin
  TDanJetX(m_DanJetX).Device.SetTransform(D3DTS_WORLD, m_matWorld);
end;
procedure TDJXRender.Prs3DScaleWorld(X, Y, Z: single);
var
  MatrixScale: TD3DXMatrix;
begin
  D3DXMatrixScaling(MatrixScale, X, Y, Z);
  D3DXMatrixMultiply(m_matWorld, m_matWorld, MatrixScale);
end;
procedure TDJXRender.Prs3DInverseWorldTo(SrcMatrix: TD3DMatrix);
var
  MatrixInverse: TD3DXMatrix;
begin
  D3DXMatrixInverse(MatrixInverse, nil, SrcMatrix);
  D3DXMatrixMultiply(m_matWorld, m_matWorld, MatrixInverse);
end;
procedure TDJXRender.Prs3DMoveWorld(X, Y, Z: double);
var
  MatrixMove: TD3DXMatrix;
begin
  D3DXMatrixTranslation(MatrixMove, x, y, z);
  D3DXMatrixMultiply(m_matWorld, m_matWorld, MatrixMove);
end;
procedure TDJXRender.Prs3DMultiplyWorld(m: TD3DXMatrix);
begin
  D3DXMatrixMultiply(m_matWorld, m_matWorld, m);
end;
procedure TDJXRender.Prs3DRotateWorldAroundVector(X, Y, Z: single; angle: single);
var
  MatrixRotate: TD3DXMatrix;
begin
  D3DXMatrixRotationAxis(MatrixRotate, D3DXVector3(X, Y, Z), angle);
  D3DXMatrixMultiply(m_matWorld, m_matWorld, MatrixRotate);
end;
procedure TDJXRender.Prs3DRotateWorldX(Angle: single);
var
  MatrX: TD3DMatrix;
begin
  D3DXMatrixRotationX(MatrX, Angle);
  D3DXMatrixMultiply(m_matWorld, m_MatWorld, MatrX);
end;
procedure TDJXRender.Prs3DRotateWorldY(Angle: single);
var
  MatrY: TD3DMatrix;
begin
  D3DXMatrixRotationY(MatrY, Angle);
  D3DXMatrixMultiply(m_matWorld, m_MatWorld, MatrY);
end;
procedure TDJXRender.Prs3DRotateWorldZ(Angle: single);
var
  MatrZ: TD3DMatrix;
begin
  D3DXMatrixRotationZ(MatrZ, Angle);
  D3DXMatrixMultiply(m_matWorld, m_MatWorld, MatrZ);
end;
procedure TDJXRender.Prs3DRotateWorld(Xangle, Yangle, Zangle: single);
var
  MatrX, MatrY, MatrZ: TD3DMatrix;
begin
  D3DXMatrixRotationX(MatrX, Xangle);
  D3DXMatrixRotationY(MatrY, Yangle);
  D3DXMatrixRotationZ(MatrZ, Zangle);
  D3DXMatrixMultiply(m_matWorld, m_matWorld, MatrX);
  D3DXMatrixMultiply(m_matWorld, m_matWorld, MatrY);
  D3DXMatrixMultiply(m_matWorld, m_matWorld, MatrZ);
end;
procedure TDJXRender.Prs3DPreScaleWorld(X, Y, Z: single);
var
  MatrixScale: TD3DXMatrix;
begin
  D3DXMatrixScaling(MatrixScale, X, Y, Z);
  D3DXMatrixMultiply(m_MatWorld, MatrixScale, m_MatWorld);
end;
procedure TDJXRender.Prs3DPreRotateWorldAroundVector(X, Y, Z: single; angle: single);
var
  MatrixRotation: TD3DXMatrix;
begin
  D3DXMatrixRotationAxis(MatrixRotation, D3DXVector3(X, Y, Z), angle);
  D3DXMatrixMultiply(m_MatWorld, MatrixRotation, m_MatWorld);
end;
procedure TDJXRender.Prs3DPreRotateWorld(Xangle, Yangle, Zangle: single);
var
  MatrX, MatrY, MatrZ: TD3DMatrix;
begin
  D3DXMatrixRotationX(MatrX, Xangle);
  D3DXMatrixRotationY(MatrY, Yangle);
  D3DXMatrixRotationZ(MatrZ, Zangle);
  D3DXMatrixMultiply(m_MatWorld, MatrX, m_MatWorld);
  D3DXMatrixMultiply(m_MatWorld, MatrY, m_MatWorld);
  D3DXMatrixMultiply(m_MatWorld, MatrZ, m_MatWorld);
end;
procedure TDJXRender.Prs3DPreRotateWorldX(Angle: single);
var
  MatrX: TD3DMatrix;
begin
  D3DXMatrixRotationX(MatrX, Angle);
  D3DXMatrixMultiply(m_MatWorld, MatrX, m_MatWorld);
end;
procedure TDJXRender.Prs3DPreRotateWorldY(Angle: single);
var
  MatrY: TD3DMatrix;
begin
  D3DXMatrixRotationY(MatrY, Angle);
  D3DXMatrixMultiply(m_MatWorld, MatrY, m_MatWorld);
end;
procedure TDJXRender.Prs3DPreRotateWorldZ(Angle: single);
var
  MatrZ: TD3DMatrix;
begin
  D3DXMatrixRotationZ(MatrZ, Angle);
  D3DXMatrixMultiply(m_MatWorld, MatrZ, m_MatWorld);
end;
procedure TDJXRender.Prs3DPreMoveWorld(X, Y, Z: double);   
var
  MatrixMove: TD3DXMatrix;
begin
  D3DXMatrixTranslation(MatrixMove, x, y, z);
  D3DXMatrixMultiply(m_MatWorld, MatrixMove, m_MatWorld);
end;
procedure TDJXRender.Prs3DPreMultiplyWorld(m: TD3DXMatrix);
begin
  D3DXMatrixMultiply(m_MatWorld, m, m_MatWorld);
end;
procedure TDJXRender.PrsTexClearTexMatrix;
begin
  D3DXMatrixIdentity(m_MatTex);
end;
procedure TDJXRender.PrsTexApplyTexMatrix(Stage: byte);
var
  TransformStage: _D3DTRANSFORMSTATETYPE;
begin
  case Stage of
    0: TransformStage := D3DTS_TEXTURE0;
    1: TransformStage := D3DTS_TEXTURE1;
    2: TransformStage := D3DTS_TEXTURE2;
    3: TransformStage := D3DTS_TEXTURE3;
    4: TransformStage := D3DTS_TEXTURE4;
    5: TransformStage := D3DTS_TEXTURE5;
    6: TransformStage := D3DTS_TEXTURE6;
    7: TransformStage := D3DTS_TEXTURE7;
    else
    TransformStage := D3DTS_TEXTURE0;
  end;
  TDanJetX(m_DanJetX).Device.SetTransform(TransformStage, m_matTex);
end;
procedure TDJXRender.PrsTexScaleTex(X, Y, Z: single);
var
  MatrixScale: TD3DXMatrix;
begin
  D3DXMatrixScaling(MatrixScale, X, Y, Z);
  D3DXMatrixMultiply(m_matTex, m_matTex, MatrixScale);
end;
procedure TDJXRender.PrsTexMoveTex(X, Y, Z: double);
var
  MatrixMove: TD3DXMatrix;
begin
  D3DXMatrixIdentity(MatrixMove);
  MatrixMove._31 := x;
  MatrixMove._32 := y;
  MatrixMove._33 := z;
  D3DXMatrixMultiply(m_matTex, m_matTex, MatrixMove);
end;
procedure TDJXRender.PrsTexRotateTexAroundVector(X, Y, Z: single; Angle: single);
var
  MatrixRotate: TD3DXMatrix;
begin
  D3DXMatrixRotationAxis(MatrixRotate, D3DXVector3(X, Y, Z), angle);
  D3DXMatrixMultiply(m_matTex, m_matTex, MatrixRotate);
end;
procedure TDJXRender.PrsTexRotateTexX(Angle: single);
var
  MatrX: TD3DMatrix;
begin
  D3DXMatrixRotationX(MatrX, Angle);
  D3DXMatrixMultiply(m_matTex, m_matTex, MatrX);
end;
procedure TDJXRender.PrsTexRotateTexY(Angle: single);
var
  MatrY: TD3DMatrix;
begin
  D3DXMatrixRotationY(MatrY, Angle);
  D3DXMatrixMultiply(m_matTex, m_matTex, MatrY);
end;
procedure TDJXRender.PrsTexRotateTexZ(Angle: single);
var
  MatrZ: TD3DMatrix;
begin
  D3DXMatrixRotationZ(MatrZ, Angle);
  D3DXMatrixMultiply(m_matTex, m_matTex, MatrZ);
end;
procedure TDJXRender.PrsTexRotateTex(Xangle, Yangle, Zangle: single);
var
  MatrX, MatrY, MatrZ: TD3DMatrix;
begin
  D3DXMatrixRotationX(MatrX, Xangle);
  D3DXMatrixRotationY(MatrY, Yangle);
  D3DXMatrixRotationZ(MatrZ, Zangle);
  D3DXMatrixMultiply(m_matTex, m_matTex, MatrX);
  D3DXMatrixMultiply(m_matTex, m_matTex, MatrY);
  D3DXMatrixMultiply(m_matTex, m_matTex, MatrZ);
end;
procedure TDJXRender.Prs3DSetPerspective(Aspect, ZNear, ZFar: single; FOV: single = DefFOV);
begin
  D3DXMatrixPerspectiveFovLH(m_matProj, FOV, Aspect, ZNear, ZFar);
  TDanJetX(m_DanJetX).Device.SetTransform(D3DTS_PROJECTION, m_matProj);
end;
procedure TDJXRender.Prs3DSetPerspective;
begin
  D3DXMatrixPerspectiveFovLH(
    m_matProj,
    DefFOV,
    TDanJetX(m_DanJetX).Width/TDanJetX(m_DanJetX).Height,
    1, 100
  );
  TDanJetX(m_DanJetX).Device.SetTransform(D3DTS_PROJECTION, m_matProj);
end;
procedure TDJXRender.Prs3DSetPerspectiveORT(Width, Height, ZNear, ZFar: single);
begin
  D3DXMatrixOrthoLH(
    m_matProj,
    Width,
    Height,
    ZNear, ZFar
  );
  TDanJetX(m_DanJetX).Device.SetTransform(D3DTS_PROJECTION, m_matProj);
end;
procedure TDJXRender.Prs3DSetPerspectiveORT;
begin
  D3DXMatrixOrthoLH(
    m_matProj,
    TDanJetX(m_DanJetX).Width,
    TDanJetX(m_DanJetX).Height,
    1, 100
  );
  TDanJetX(m_DanJetX).Device.SetTransform(D3DTS_PROJECTION, m_matProj);
end;
procedure TDJXRender.Prs3DSetView(eyePt, LookAt, upVec: TD3DXVector3);
begin
  D3DXMatrixLookAtLH(m_matView, EyePt, Lookat, UpVec);
  TDanJetX(m_DanJetX).Device.SetTransform(D3DTS_VIEW, m_matView);
end;
procedure TDJXRender.Prs3DSetView(
  eyePtX,eyePtY, eyePtZ: single;
  LookAtX, LookAtY, LookAtZ: single;
  upVecX, upVecY, upVecZ: single
);
begin
  Prs3DSetView(
    D3DXVector3(eyePtX, eyePtY, eyePtZ),
    D3DXVector3(lookAtX, lookAtY, lookAtZ),
    D3DXVector3(upVecX, upVecY, upVecZ)
  );
end;
procedure TDJXRender.Prs2DTransformVertices(
      CenterX,CenterY: single;
      Rotation: single;
      Texture: TDJXTexture = nil;
      TileWidth: integer = 0;
      TileHeight: integer = 0;
      ScaleX: single = 1;
      ScaleY: single = 1
    );{$IFDEF SUPPORTS_INLINE} inline; {$ENDIF}
var
  i: integer;
  q, s1, s2, s3, s4: single;
  tw, th, cx, cy: double;
  minX, minY, maxX, maxY: single;
  totalX, totalY: single;
begin
  totalX := 0;
  totalY := 0;
  for i := 0 to 3 do
  begin
    totalX := totalX + m_VB2D.Vertices[i].x;
    totalY := totalY + m_VB2D.Vertices[i].y;
  end;
  minX := totalX/4;
  minY := totalY/4;
  maxX := minX;
  maxY := minY;
  for i := 0 to 3 do
  begin
    if m_VB2D.Vertices[i].x < minX then minX := m_VB2D.Vertices[i].x;
    if m_VB2D.Vertices[i].y < minY then minY := m_VB2D.Vertices[i].y;
    if m_VB2D.Vertices[i].x > maxX then maxX := m_VB2D.Vertices[i].x;
    if m_VB2D.Vertices[i].y > maxY then maxY := m_VB2D.Vertices[i].y;
  end;
  tw := maxX - minX;
  th := maxY - minY;
  cx := m_VB2D.Vertices[0].x + CenterX * tw;
  cy := m_VB2D.Vertices[0].y + CenterY * th;
  q := Rotation;
  s1 := ScaleX * cos(q);
  s2 := ScaleX * sin(q);
  s3 := -ScaleY * sin(q);
  s4 := ScaleY * cos(q);
  for i := 0 to 3 do
  with m_VB2D.Vertices[i] do
  begin
    q := s1 * x + s3 * y + CX - CX * s1 - CY * s3;
    y := s2 * x + s4 * y + CY - CX * s2 - CY * s4;
    x := q;
  end;
end;

procedure TDJXRender.DrawTexture2D(
  x1, y1, x2, y2, x3, y3, x4, y4: single;
  col1, col2, col3, col4: TDJXColor;
  CenterX, CenterY, Rotation, ScaleX, ScaleY: single;
  Texture: TDJXTexture;
  FlipTopBottom: boolean = false;
  FlipLeftRight: boolean = false;
  ImageIndex: integer=0;
  TileWidth: integer=0; TileHeight: integer=0
); {$IFDEF SUPPORTS_INLINE} inline; {$ENDIF}
begin
  m_VB2D.Vertices[0] := DJXVertex2D(x1, y1, col1);
  m_VB2D.Vertices[1] := DJXVertex2D(x2, y2, col2);
  m_VB2D.Vertices[2] := DJXVertex2D(x3, y3, col3);
  m_VB2D.Vertices[3] := DJXVertex2D(x4, y4, col4);
  SetTextureToVertices(
    m_VB2D.Vertices[0],
    m_VB2D.Vertices[1],
    m_VB2D.Vertices[2],
    m_VB2D.Vertices[3],
    Texture,
    FlipTopBottom,
    FlipLeftRight,
    ImageIndex,
    TileWidth,
    TileHeight,
    TDanJetX(m_DanJetX).TruncatePixel
  );

  
  if (Rotation <> 0) or (ScaleX <> 1) or (ScaleY <> 1) then
  Prs2DTransformVertices(
    CenterX, CenterY,
    Rotation, Texture,
    TileWidth, TileHeight,
    ScaleX, ScaleY
  );

  Texture.SetToDevice(0);

  m_VB2D.setVertices(0, 4);
  m_VB2D.DrawTriangleFan(0, 2);
end;

procedure TDJXRender.DrawBillboard(
  x, y, z: single;
  x1, y1, x2, y2, x3, y3, x4, y4: single;
  col1, col2, col3, col4: TDJXColor;
  Rotation, ScaleX, ScaleY: single;
  Texture: TDJXTexture;
  ImageIndex: integer;
  TileWidth: integer = 0; TileHeight: integer = 0
);
var
  Norm: TD3DXVector3;
begin
  if Texture = nil then exit;
  Texture.SetToDevice(0);
  m_VB3D.Vertices[0] := DJXVertex3D(x1, y1, 0, col1);
  m_VB3D.Vertices[1] := DJXVertex3D(x2, y2, 0, col2);
  m_VB3D.Vertices[2] := DJXVertex3D(x3, y3, 0, col3);
  m_VB3D.Vertices[3] := DJXVertex3D(x4, y4, 0, col4);

  SetTextureToVertices(
    m_VB3D.Vertices[0],
    m_VB3D.Vertices[1],
    m_VB3D.Vertices[2],
    m_VB3D.Vertices[3],
    Texture,
    false,
    false,
    ImageIndex,
    TileWidth,
    TileHeight,
    TDanJetX(m_DanJetX).TruncatePixel
  );

  Norm := GetTriangleNormal(
    D3DXVector3(x1, y1, 0),
    D3DXVector3(x2, y2, 0),
    D3DXVector3(x3, y3, 0)
  );
  m_VB3D.Vertices[0].nx := Norm.x; m_VB3D.Vertices[0].ny := Norm.y; m_VB3D.Vertices[0].nz := Norm.z;
  m_VB3D.Vertices[1].nx := Norm.x; m_VB3D.Vertices[1].ny := Norm.y; m_VB3D.Vertices[1].nz := Norm.z;
  m_VB3D.Vertices[2].nx := Norm.x; m_VB3D.Vertices[2].ny := Norm.y; m_VB3D.Vertices[2].nz := Norm.z;
  m_VB3D.Vertices[3].nx := Norm.x; m_VB3D.Vertices[3].ny := Norm.y; m_VB3D.Vertices[3].nz := Norm.z;

  Prs3DClearWorldMatrix;
  Prs3DScaleWorld(ScaleX, ScaleY, 1);
  Prs3DRotateWorld(0, 0, Rotation);
  Prs3DInverseWorldTo(m_matView);
  m_matWorld._41 := 0;
  m_matWorld._42 := 0;
  m_matWorld._43 := 0;
  Prs3DMoveWorld(x, y, z);
  Prs3DApplyWorldMatrix;

  m_VB3D.setVertices(0, 4);
  m_VB3D.DrawTriangleFan(0, 2);
end;

procedure TDJXRender.DrawBillboardCyl(
  p1x, p1y, p1z: single;
  p2x, p2y, p2z: single;
  x1, y1, x2, y2, x3, y3, x4, y4: single;
  col1, col2, col3, col4: TDJXColor;
  Scale: single;
  Texture: TDJXTexture;
  ImageIndex: integer;
  TileWidth: integer = 0; TileHeight: integer = 0
);
var
  WorldVec: TD3DXVector3;
  ProjVec1, ProjVec2: TD3DXvector3;
  Ang: single;
begin
  if Texture = nil then exit;
  Texture.SetToDevice(0);
  m_VB3D.Vertices[0] := DJXVertex3D(x1, y1, 0, col1, 0, 0, 0, 0, -1);
  m_VB3D.Vertices[1] := DJXVertex3D(x2, y2, 0, col2, 0, 0, 0, 0, -1);
  m_VB3D.Vertices[2] := DJXVertex3D(x3, y3, 0, col3, 0, 0, 0, 0, -1);
  m_VB3D.Vertices[3] := DJXVertex3D(x4, y4, 0, col4, 0, 0, 0, 0, -1);

  SetTextureToVertices(
    m_VB3D.Vertices[0],
    m_VB3D.Vertices[1],
    m_VB3D.Vertices[2],
    m_VB3D.Vertices[3],
    Texture,
    false,
    false,
    ImageIndex,
    TileWidth,
    TileHeight,
    TDanJetX(m_DanJetX).TruncatePixel
  );

  Prs3DClearWorldMatrix;
  Prs3DScaleWorld(Scale, 1, 1);
  D3DXVec3Project(
    ProjVec1,
    D3DXVector3(p1x, p1y, p1z),
    TDanJetX(m_DanJetX).ViewPort,
    m_matProj,
    m_matView,
    m_matWorld
  );
  Prs3DClearWorldMatrix;
  Prs3DScaleWorld(Scale, 1, 1);
  D3DXVec3Project(
    ProjVec2,
    D3DXVector3(p2x, p2y, p2z),
    TDanJetX(m_DanJetX).ViewPort,
    m_matProj,
    m_matView,
    m_matWorld
  );

  Ang := pi / 2 - GetAngRad(ProjVec1.x, ProjVec1.y, ProjVec2.x, ProjVec2.y);

  Prs3DClearWorldMatrix;
  Prs3DScaleWorld(Scale, 1, 1);
  Prs3DRotateWorld(0, 0, Ang);
  Prs3DInverseWorldTo(m_matView);
  m_matWorld._41 := 0;
  m_matWorld._42 := 0;
  m_matWorld._43 := 0;
  Prs3DMoveWorld(p1x, p1y, p1z);
  Prs3DApplyWorldMatrix;
  D3DXVec3TransformCoord(
    WorldVec,
    D3DXVector3(m_VB3D.Vertices[0].x, m_VB3D.Vertices[0].y, m_VB3D.Vertices[0].z),
    m_matWorld
  );
  m_VB3D.Vertices[0].x := WorldVec.x;
  m_VB3D.Vertices[0].y := WorldVec.y;
  m_VB3D.Vertices[0].z := WorldVec.z;
  D3DXVec3TransformCoord(
    WorldVec,
    D3DXVector3(m_VB3D.Vertices[1].x, m_VB3D.Vertices[1].y, m_VB3D.Vertices[1].z),
    m_matWorld
  );
  m_VB3D.Vertices[1].x := WorldVec.x;
  m_VB3D.Vertices[1].y := WorldVec.y;
  m_VB3D.Vertices[1].z := WorldVec.z;

  Prs3DClearWorldMatrix;
  Prs3DScaleWorld(Scale, 1, 1);
  Prs3DRotateWorld(0, 0, Ang);
  Prs3DInverseWorldTo(m_matView);
  m_matWorld._41 := 0;
  m_matWorld._42 := 0;
  m_matWorld._43 := 0;
  Prs3DMoveWorld(p2x, p2y, p2z);
  Prs3DApplyWorldMatrix;
  D3DXVec3TransformCoord(
    WorldVec,
    D3DXVector3(m_VB3D.Vertices[2].x, m_VB3D.Vertices[2].y, m_VB3D.Vertices[2].z),
    m_matWorld
  );
  m_VB3D.Vertices[2].x := WorldVec.x;
  m_VB3D.Vertices[2].y := WorldVec.y;
  m_VB3D.Vertices[2].z := WorldVec.z;
  D3DXVec3TransformCoord(
    WorldVec,
    D3DXVector3(m_VB3D.Vertices[3].x, m_VB3D.Vertices[3].y, m_VB3D.Vertices[3].z),
    m_matWorld
  );
  m_VB3D.Vertices[3].x := WorldVec.x;
  m_VB3D.Vertices[3].y := WorldVec.y;
  m_VB3D.Vertices[3].z := WorldVec.z;

  Prs3DClearWorldMatrix;
  Prs3DApplyWorldMatrix;

  m_VB3D.setVertices(0, 4);
  m_VB3D.DrawTriangleFan(0, 2);
end;
//TDJXRender END

//TDJXShaders BEGIN
constructor TDJXShaders.Create(DanJetX: Pointer);
begin
  inherited Create;
  m_DanJetX := DanJetX;
  m_Shaders := TList.Create;
  LoadShaders;
end;
destructor TDJXShaders.Destroy;
begin
  UnLoadShaders;
  m_Shaders.Free;
  inherited Destroy;
end;

function TDJXShaders.getItem(Index: integer): TDJXShader;
begin
  result := TDJXShader(m_Shaders.items[Index]);
end;
procedure TDJXShaders.setItem(Index: integer; Value: TDJXShader);
begin
  m_Shaders.items[Index] := Value;
end;
procedure TDJXShaders.LoadShaders;
const
  //Vertex Shaders
  {$include Shaders\DJXBasic_VS.cvs}
  {$include Shaders\DJXNoPSLight_VS.cvs}
  {$include Shaders\DJXNoPSLightSmooth_VS.cvs}
  {$include Shaders\DJXLight_VS.cvs}
  {$include Shaders\DJXLightSpec_VS.cvs}
  {$include Shaders\DJXBump_VS.cvs}
  {$include Shaders\DJXBumpSpec_VS.cvs}
  {$include Shaders\DJXBumpSpecRef_VS.cvs}
  {$include Shaders\DJXParalaxBump_VS.cvs}
  {$include Shaders\DJXParalaxBumpSpec_VS.cvs}
  {$include Shaders\DJXParalaxBumpSpecRef_VS.cvs}
  {$include Shaders\DJXToon_VS.cvs}
  {$include Shaders\DJXToonLight_VS.cvs}
  {$include Shaders\DJXToonLightSpec_VS.cvs}
  {$include Shaders\DJXToonBump_VS.cvs}
  {$include Shaders\DJXToonBumpSpec_VS.cvs}
  {$include Shaders\DJXShadow_VS.cvs}
  //Pixel Shaders
  {$include Shaders\DJXLight_PS.cps}
  {$include Shaders\DJXLightSpec_PS.cps}
  {$include Shaders\DJXBump_PS.cps}
  {$include Shaders\DJXBumpSpec_PS.cps}
  {$include Shaders\DJXBumpSpecRef_PS.cps}
  {$include Shaders\DJXParalaxBump_PS.cps}
  {$include Shaders\DJXParalaxBumpSpec_PS.cps}
  {$include Shaders\DJXParalaxBumpSpecRef_PS.cps}
  {$include Shaders\DJXToon_PS.cps}
  {$include Shaders\DJXToonLight_PS.cps}
  {$include Shaders\DJXToonLightSpec_PS.cps}
  {$include Shaders\DJXToonBump_PS.cps}
  {$include Shaders\DJXToonBumpSpec_PS.cps}
begin
  //Vertex Shaders
  LoadVertexShaderFromMemory(
    @DJXBasic_VS[0], length(DJXBasic_VS), 'DJXBasic_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXNoPSLight_VS[0], length(DJXNoPSLight_VS), 'DJXNoPSLight_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXNoPSLightSmooth_VS[0], length(DJXNoPSLightSmooth_VS), 'DJXNoPSLightSmooth_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXLight_VS[0], length(DJXLight_VS), 'DJXLight_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXLightSpec_VS[0], length(DJXLightSpec_VS), 'DJXLightSpec_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXBump_VS[0], length(DJXBump_VS), 'DJXBump_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXBumpSpec_VS[0], length(DJXBumpSpec_VS), 'DJXBumpSpec_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXBumpSpecRef_VS[0], length(DJXBumpSpecRef_VS), 'DJXBumpSpecRef_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXParalaxBump_VS[0], length(DJXParalaxBump_VS), 'DJXParalaxBump_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXParalaxBumpSpec_VS[0], length(DJXParalaxBumpSpec_VS), 'DJXParalaxBumpSpec_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXParalaxBumpSpecRef_VS[0], length(DJXParalaxBumpSpecRef_VS), 'DJXParalaxBumpSpecRef_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXToon_VS[0], length(DJXToon_VS), 'DJXToon_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXToonLight_VS[0], length(DJXToonLight_VS), 'DJXToonLight_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXToonLightSpec_VS[0], length(DJXToonLightSpec_VS), 'DJXToonLightSpec_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXToonBump_VS[0], length(DJXToonBump_VS), 'DJXToonBump_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXToonBumpSpec_VS[0], length(DJXToonBumpSpec_VS), 'DJXToonBumpSpec_VS'
  );
  LoadVertexShaderFromMemory(
    @DJXShadow_VS[0], length(DJXShadow_VS), 'DJXShadow_VS'
  );
  //Pixel Shaders
  LoadPixelShaderFromMemory(
    @DJXLight_PS[0], length(DJXLight_PS), 'DJXLight_PS'
  );
  LoadPixelShaderFromMemory(
    @DJXLightSpec_PS[0], length(DJXLightSpec_PS), 'DJXLightSpec_PS'
  );
  LoadPixelShaderFromMemory(
    @DJXBump_PS[0], length(DJXBump_PS), 'DJXBump_PS'
  );
  LoadPixelShaderFromMemory(
    @DJXBumpSpec_PS[0], length(DJXBumpSpec_PS), 'DJXBumpSpec_PS'
  );
  LoadPixelShaderFromMemory(
    @DJXBumpSpecRef_PS[0], length(DJXBumpSpecRef_PS), 'DJXBumpSpecRef_PS'
  );
  LoadPixelShaderFromMemory(
    @DJXParalaxBump_PS[0], length(DJXParalaxBump_PS), 'DJXParalaxBump_PS'
  );
  LoadPixelShaderFromMemory(
    @DJXParalaxBumpSpec_PS[0], length(DJXParalaxBumpSpec_PS), 'DJXParalaxBumpSpec_PS'
  );
  LoadPixelShaderFromMemory(
    @DJXParalaxBumpSpecRef_PS[0], length(DJXParalaxBumpSpecRef_PS), 'DJXParalaxBumpSpecRef_PS'
  );
  LoadPixelShaderFromMemory(
    @DJXToon_PS[0], length(DJXToon_PS), 'DJXToon_PS'
  );
  LoadPixelShaderFromMemory(
    @DJXToonLight_PS[0], length(DJXToonLight_PS), 'DJXToonLight_PS'
  );
  LoadPixelShaderFromMemory(
    @DJXToonLightSpec_PS[0], length(DJXToonLightSpec_PS), 'DJXToonLightSpec_PS'
  );
  LoadPixelShaderFromMemory(
    @DJXToonBump_PS[0], length(DJXToonBump_PS), 'DJXToonBump_PS'
  );
  LoadPixelShaderFromMemory(
    @DJXToonBumpSpec_PS[0], length(DJXToonBumpSpec_PS), 'DJXToonBumpSpec_PS'
  );
end;
procedure TDJXShaders.UnLoadShaders;
begin
  while m_Shaders.Count > 0 do
  begin
    TDJXShader(m_Shaders.Items[0]).Free;
    m_Shaders.Delete(0);
  end;
end;

function TDJXShaders.Find(name: string): TDJXShader;
var
  i: integer;
begin
  for i := 0 to m_Shaders.Count - 1 do
  if TDJXShader(m_Shaders.Items[i]).Name = name then
  begin
    result := TDJXShader(m_Shaders.Items[i]);
    exit;
  end;
  result := nil;
end;
function TDJXShaders.Add(Shader: TDJXShader): TDJXShader;
begin
  m_Shaders.Add(Shader);
  result := Shader;
end;
function TDJXShaders.LoadVertexShaderFromMemory(Ptr: Pointer; Size: DWORD; NameInList: string): TDJXVertexShader;
var
  shader: TDJXVertexShader;
begin
  shader := TDJXVertexShader.Create;
  shader.DanJetX := m_DanJetX;
  shader.LoadFromMemory(Ptr, Size);
  if length(shader.Errors) > 0 then
  begin
    shader.Free;
    exit;
  end;
  shader.Name := NameInList;
  result := TDJXVertexShader(Add(shader));
end;
function TDJXShaders.LoadPixelShaderFromMemory(Ptr: Pointer; Size: DWORD; NameInList: string): TDJXPixelShader;
var
  shader: TDJXPixelShader;
begin
  shader := TDJXPixelShader.Create;
  shader.DanJetX := m_DanJetX;
  shader.LoadFromMemory(Ptr, Size);
  if length(shader.Errors) > 0 then
  begin
    shader.Free;
    exit;
  end;
  shader.Name := NameInList;
  result := TDJXPixelShader(Add(shader));
end;
procedure TDJXShaders.OnLostDevice;
var
  i: integer;
begin
  for i := 0 to m_Shaders.Count - 1 do
  begin
    TDJXShader(m_Shaders.Items[i]).OnLostDevice;
  end;
end;
procedure TDJXShaders.OnResetDevice;
var
  i: integer;
begin
  for i := 0 to m_Shaders.Count - 1 do
  begin
    TDJXShader(m_Shaders.Items[i]).OnResetDevice;
  end;
end;
//TDJXShaders END

end.
