C2Materials.pas
上传用户:yj_qiu
上传日期:2022-08-08
资源大小:23636k
文件大小:52k
源码类别:

游戏引擎

开发平台:

Delphi

  1. (*
  2.  @Abstract(CAST II Engine materials unit)
  3.  (C) 2006 George "Mirage" Bakhtadze. <a href="http://www.casteng.com">www.casteng.com</a> <br>
  4.  The source code may be used under either MPL 1.1 or LGPL 2.1 license. See included license.txt file <br>
  5.  Unit contains material base class
  6. *)
  7. {$Include GDefines.inc}
  8. {$Include C2Defines.inc}
  9. unit C2Materials;
  10. interface
  11. uses
  12.   TextFile,
  13.   BaseTypes, Basics, BaseMsg, Props, OTypes, BaseClasses, Resources, ItemMsg,
  14.   C2Types, CAST2, C2Res, C2Msg;
  15. const
  16.   // Color mask
  17.   cmAlpha = 1; cmRed = 2; cmGreen = 4; cmBlue = 8;
  18.     // Texture index special values
  19.   // Texture unresolved yet or its resolution failed
  20.   tivUnresolved   = -1;
  21.   // No texture specified for the given stage
  22.   tivNull         = -2;
  23.   // Texture is a render target
  24.   tivRenderTarget = -16;
  25.     // Shader index special values
  26.   // Shader unresolved yet or its resolution failed
  27.   sivUnresolved   = -1;
  28.   // No Shader specified for the given render pass
  29.   sivNull         = -2;
  30.   // Texture matrix type enumeration string
  31.   TextureMatrixTypesEnum = 'None' + StringDelimiter +
  32.                            'Camera inverse' + StringDelimiter + 'Mirror' + StringDelimiter + 'Shadow map' + StringDelimiter +
  33.                            'Scale' + StringDelimiter +
  34.                            'Custom';
  35.   // Pass running conditions enumeration string
  36.   TPassConditionsEnum = 'Once' + StringDelimiter + 'For each light';
  37. type
  38.   // Pass running conditions enumeration
  39.   TPassCondition = (// Run the pass once for an item
  40.                     pcOnce,
  41.                     // Run the pass for each light affecting the currently rendering item   
  42.                     pcEachLight);
  43.   TBlendingState = record
  44.     Enabled: Boolean;
  45.     CRC, AlphaRef, ATestFunc, SrcBlend, DestBlend, Operation: Integer;
  46.   end;
  47.   TZBufferState = record
  48.     CRC, ZTestFunc, ZBias: Integer;
  49.     ZWrite: Boolean;
  50.   end;
  51.   TFillShadeMode = record
  52.     CRC, FillMode, ShadeMode, CullMode: Integer;
  53.     ColorMask: Cardinal;
  54.   end;
  55.   TStencilState = record
  56.     CRC, SFailOp, ZFailOp, PassOp, STestFunc: Integer;
  57.   end;
  58.   TTWrapCoordSet = array[0..MaxTextureCoordSets-1] of Cardinal;
  59.   TTextureWrap = record
  60.     CRC: Cardinal;
  61.     CoordSet: TTWrapCoordSet;
  62.   end;
  63.   TLightingState = record
  64.     CRC: Integer;
  65.     GlobalAmbient: BaseTypes.TColor;
  66.     SpecularMode: SmallInt;
  67.     NormalizeNormals, Enabled: Boolean;
  68.   end;
  69.   TPointEdgeState = record
  70.     CRC: Integer;
  71.     PointSprite, PointScale, EdgeAntialias: Boolean;
  72.   end;
  73.   // Texture matrix setting
  74.   TTextureMatrixType = (// No texture matrix
  75.                         tmNone,
  76.                         // Inverse camera view matrix
  77.                         tmCameraInverse,
  78.                         { Predefined texture matrix for a mirror implementation
  79.                         }
  80.                         tmMirror,
  81.                         { Predefined texture matrix for shadow maps implementation
  82.                         }
  83.                         tmShadowMap,
  84.                         // Scale matrix by <b>TextureMatrixBias</b>
  85.                         tmScale,
  86.                         // Texture matrix for the given coordinate set will be retrieved from the item currently drawn with the @Link(RetrieveTextureMatrix) delegate
  87.                         tmCustom);
  88.   TStage = record
  89.     TextureIndex: Integer;                          // can be tivUnresolved, tivNull, tivRenderTarget
  90.     ColorArg0, AlphaArg0: Longword;
  91.     ColorOp, ColorArg1, ColorArg2: Longword; InvertColorArg1, InvertColorArg2: Boolean;
  92.     AlphaOp, AlphaArg1, AlphaArg2: Longword; InvertAlphaArg1, InvertAlphaArg2: Boolean;
  93.     TAddressing: Longword; StoreToTemp: Boolean;
  94.     MipLODBias: Single;
  95.     MaxMipLevel, MaxAnisotropy, Filtering: Longword;
  96.     UVSource, TTransform: Longword;                 // Texture coordinates source, transform and wrapping
  97.     TextureBorder: BaseTypes.TColor;
  98.     TextureMatrixType: TTextureMatrixType;
  99.     TextureMatrixBias: Single;
  100.     Camera: TCamera;
  101.   end;
  102.   TRenderPass = class(TItem)
  103.   public
  104.     // SortBias is added to any sorted item's SortValue 
  105.     SortBias: Single;
  106.     Group: TPassGroup;
  107.     BlendingState: TBlendingState;
  108.     FillShadeMode: TFillShadeMode;
  109.     ZBufferState : TZBufferState;
  110.     StencilState : TStencilState;
  111.     StencilRef, StencilMask, StencilWriteMask: Integer;
  112.     TextureFactor: BaseTypes.TColor;    
  113.     TextureWrap  : TTextureWrap;
  114.     Ambient, Diffuse, Specular, Emissive: BaseTypes.TColor4S;
  115.     Power: Single;
  116.     LightingState: TLightingState;
  117.     Stages: array of TStage;
  118.     FogKind: Integer;
  119.     FogStart, FogEnd, FogDensity: Single;
  120.     FogColor: BaseTypes.TColor;
  121.     PointSize, MinPointSize, MaxPointSize: Single;
  122.     PointScaleA, PointScaleB, PointScaleC: Single;
  123.     PointEdgeState: TPointEdgeState;
  124.     LinePattern: Longword;
  125.     VertexShaderIndex, PixelShaderIndex: Integer;   /// can be sivUnresolved, sivNull
  126.     VertexDeclaration: TVertexDeclaration;
  127.     ApplyCondition: TPassCondition;
  128.     Items: TItems; TotalItems: Integer;                               // Items using this pass
  129.     constructor Create(AManager: TItemsManager); override;
  130.     destructor Destroy; override;
  131.     procedure AddProperties(const Result: Props.TProperties); override;
  132.     procedure SetProperties(Properties: Props.TProperties); override;
  133.     /// For internal use only.
  134.     function AddItem(const Item: TItem): Integer;
  135.     /// For internal use only.
  136.     function RemoveItem(const Index: Integer): Boolean;
  137.     /// Called from TRenderer.ResolveTexture. For internal use only.
  138.     function ResolveTexture(const Index: Integer; out Texture: Resources.TImageResource): Boolean;
  139.     function ResolveVertexShader(var Shader: C2Res.TShaderResource): Boolean;
  140.     function ResolvePixelShader(var Shader: C2Res.TShaderResource): Boolean;
  141.   private
  142.       ResolvedTexture: Resources.TImageResource;  // Obsolete?
  143.     ResolvedVertexShader, ResolvedPixelShader: C2Res.TShaderResource;
  144.     FOrder: Integer;
  145.     FTotalVertexStreams, FStream0Elements: Integer;
  146.     FVertexShaderConstants, FPixelShaderConstants: TAnsiStringArray;
  147.     FCompiledVertexShaderConstants, FCompiledPixelShaderConstants: array of OTypes.TRTData;
  148.     function GetTotalStages: Integer;
  149.     procedure SetTotalStages(const Value: Integer);
  150.     function GetItemIndex(const Item: TItem): Integer;
  151.     procedure SetOrder(const Value: Integer);
  152.     function GetTotalPixelShaderConstants: Integer;
  153.     function GetTotalVertexShaderConstants: Integer;
  154.     procedure SetTotalPixelShaderConstants(const Value: Integer);
  155.     procedure SetTotalVertexShaderConstants(const Value: Integer);
  156.     function GetPixelShaderConstant(Index: Integer): string;
  157.     function GetVertexShaderConstant(Index: Integer): string;
  158.     procedure SetPixelShaderConstant(Index: Integer; const Value: string);
  159.     procedure SetVertexShaderConstant(Index: Integer; const Value: string);
  160.     function GetCompiledPixelShaderConstants(Index: Integer): OTypes.TRTData;
  161.     function GetCompiledVertexShaderConstants(Index: Integer): OTypes.TRTData;
  162.   public
  163.     procedure HandleMessage(const Msg: TMessage); override;
  164.     procedure RequestValidation;
  165.     property TotalStages: Integer read GetTotalStages write SetTotalStages;
  166.     property Order: Integer read FOrder write SetOrder;
  167.     property TotalVertexShaderConstants: Integer read GetTotalVertexShaderConstants write SetTotalVertexShaderConstants;
  168.     property TotalPixelShaderConstants: Integer read GetTotalPixelShaderConstants write SetTotalPixelShaderConstants;
  169.     property VertexShaderConstant[Index: Integer]: string read GetVertexShaderConstant write SetVertexShaderConstant;
  170.     property PixelShaderConstant[Index: Integer]: string read GetPixelShaderConstant write SetPixelShaderConstant;
  171.     property CompiledVertexShaderConstants[Index: Integer]: OTypes.TRTData read GetCompiledVertexShaderConstants;
  172.     property CompiledPixelShaderConstants[Index: Integer]:  OTypes.TRTData read GetCompiledPixelShaderConstants;
  173.   end;
  174.   TTechnique = class(TItem)
  175.   private
  176.     FTotalPasses: Integer;
  177.     PassesCache: array of TRenderPass;
  178.     FValid: Boolean;
  179.     procedure SetTotalPasses(const Value: Integer);
  180.     function GetPass(Index: Integer): TRenderPass;
  181.     procedure SetPass(Index: Integer; const Value: TRenderPass);
  182.   protected
  183.     procedure SetState(const Value: TItemFlags); override;
  184.   public
  185.     LOD: Integer;
  186.     constructor Create(AManager: TItemsManager); override;
  187.     procedure AddProperties(const Result: Props.TProperties); override;
  188.     procedure SetProperties(Properties: Props.TProperties); override;
  189.     property TotalPasses: Integer read FTotalPasses write SetTotalPasses;
  190.     property Passes[Index: Integer]: TRenderPass read GetPass write SetPass; default;
  191.     property Valid: Boolean read FValid write FValid;
  192.   end;
  193.   TMaterial = class(TItem)
  194.     procedure AddProperties(const Result: Props.TProperties); override;
  195.     procedure SetProperties(Properties: Props.TProperties); override;
  196.     function GetTechniqueByLOD(Lod: Single): TTechnique;
  197.   private
  198.     FTotalTechniques: Integer;
  199.     function GetTechnique(Index: Integer): TTechnique;
  200.     procedure SetTechnique(Index: Integer; const Value: TTechnique);
  201.     procedure SetTotalTechniques(const Value: Integer);
  202.     function PassBelongs(AItem: TItem): Boolean;
  203.   public
  204.     procedure OnSceneLoaded; override;
  205.     procedure HandleMessage(const Msg: TMessage); override;
  206.     property TotalTechniques: Integer read FTotalTechniques write SetTotalTechniques;
  207.     property Technique[Index: Integer]: TTechnique read GetTechnique write SetTechnique; default;
  208.   end;
  209.   function GetPointEdgeState(PointSprite, PointScale, EdgeAntialias: Boolean): TPointEdgeState;
  210.   function GetBlendingState(Enabled: Boolean; SrcBlend, DestBlend, AlphaRef, ATestFunc, Operation: Integer): TBlendingState;
  211.   function GetZBufferState(ZWrite: Boolean; ZTestFunc, ZBias: Integer): TZBufferState;
  212.   function GetFillShadeMode(FillMode, ShadeMode, CullMode: Integer; ColorMask: Cardinal): TFillShadeMode;
  213.   function GetStencilstate(SFailOp, ZFailOp, PassOp, STestFunc: Integer): TStencilState;
  214.   function GetTextureWrap(Set0, Set1, Set2, Set3, Set4, Set5, Set6, Set7: Cardinal): TTextureWrap;
  215.   function GetLightingState(SpecularMode: Integer; NormalizeNormals, Enabled: Boolean; GlobalAmbient: BaseTypes.TColor): TLightingState;
  216. implementation
  217. uses SysUtils;
  218. function GetPointEdgeState(PointSprite, PointScale, EdgeAntialias: Boolean): TPointEdgeState;
  219. begin
  220.   Result.PointSprite   := PointSprite;
  221.   Result.PointScale    := PointScale;
  222.   Result.EdgeAntialias := EdgeAntialias;
  223.   Result.CRC           := Ord(EdgeAntialias) shl 2 + Ord(PointScale) shl 1 + Ord(PointSprite);
  224. end;
  225. function GetBlendingState(Enabled: Boolean; SrcBlend, DestBlend, AlphaRef, ATestFunc, Operation: Integer): TBlendingState;
  226. begin
  227.   Result.Enabled   := Enabled;
  228.   Result.SrcBlend  := SrcBlend;
  229.   Result.DestBlend := DestBlend;
  230.   Result.AlphaRef  := AlphaRef;
  231.   Result.ATestFunc := ATestFunc;
  232.   Result.Operation := Operation;
  233.   Result.CRC       := AlphaRef shl 24 + Ord(Enabled) shl 23 + Operation shl 18 + ATestFunc shl 12 + SrcBlend shl 6 + DestBlend;
  234. end;
  235. function GetZBufferState(ZWrite: Boolean; ZTestFunc, ZBias: Integer): TZBufferState;
  236. begin
  237.   Result.ZWrite    := ZWrite;
  238.   Result.ZTestFunc := ZTestFunc;
  239.   Result.ZBias     := ZBias;
  240.   Result.CRC       := Ord(ZWrite) shl 15 + ZTestFunc shl 8 + ZBias;
  241. end;
  242. function GetFillShadeMode(FillMode, ShadeMode, CullMode: Integer; ColorMask: Cardinal): TFillShadeMode;
  243. begin
  244.   Result.FillMode  := FillMode;
  245.   Result.ShadeMode := ShadeMode;
  246.   Result.CullMode  := CullMode;
  247.   Result.ColorMask := ColorMask;
  248.   Result.CRC       := Integer(ColorMask shl 16) + CullMode shl 12 + ShadeMode shl 4 + FillMode;
  249. end;
  250. function GetStencilstate(SFailOp, ZFailOp, PassOp, STestFunc: Integer): TStencilState;
  251. begin
  252.   Result.SFailOp   := SFailOp;
  253.   Result.ZFailOp   := ZFailOp;
  254.   Result.PassOp    := PassOp;
  255.   Result.STestFunc := STestFunc;
  256.   Result.CRC       := STestFunc shl 24 + PassOp shl 16 + ZFailOp shl 8 + SFailOp;
  257. end;
  258. function GetTextureWrap(Set0, Set1, Set2, Set3, Set4, Set5, Set6, Set7: Cardinal): TTextureWrap;
  259. begin
  260.   Result.CoordSet[0] := Set0;
  261.   Result.CoordSet[1] := Set1;
  262.   Result.CoordSet[2] := Set2;
  263.   Result.CoordSet[3] := Set3;
  264.   Result.CoordSet[4] := Set4;
  265.   Result.CoordSet[5] := Set5;
  266.   Result.CoordSet[6] := Set6;
  267.   Result.CoordSet[7] := Set7;
  268.   Result.CRC  := Set7 shl 28 + Set6 shl 24 + Set5 shl 20 + Set4 shl 16 + Set3 shl 12 + Set2 shl 8 + Set1 shl 4 + Set0;
  269. end;
  270. function GetLightingState(SpecularMode: Integer; NormalizeNormals, Enabled: Boolean; GlobalAmbient: BaseTypes.TColor): TLightingState;
  271. begin
  272.   Result.SpecularMode     := SpecularMode;
  273.   Result.NormalizeNormals := NormalizeNormals;
  274.   Result.Enabled          := Enabled;
  275.   Result.GlobalAmbient    := GlobalAmbient;
  276.   Result.CRC              := Ord(SpecularMode) shl 2 + Ord(NormalizeNormals) shl 1 + Ord(Enabled);
  277. end;
  278. { TRenderPass }
  279. constructor TRenderPass.Create(AManager: TItemsManager);
  280. begin
  281.   inherited;
  282.   FOrder           := poNormal;
  283.   SortBias         := 0;
  284.   BlendingState    := GetBlendingState(False, bmONE, bmZERO, 0, tfALWAYS, boADD);
  285.   FillShadeMode    := GetFillShadeMode(fmDEFAULT, smGOURAUD, cmCAMERADEFAULT, $FFFFFFFF);
  286.   ZBufferState     := GetZBufferState(True, tfLESSEQUAL, 0);
  287.   StencilState     := GetStencilstate(soKEEP, soKEEP, soKEEP, tfALWAYS);
  288.   StencilRef       := 0;
  289.   StencilMask      := -1;
  290.   StencilWriteMask := -1;
  291.   TextureFactor.C   := $00000000;
  292.   TextureWrap       := GetTextureWrap(0, 0, 0, 0, 0, 0, 0, 0);
  293.   Ambient          := GetColor4S(0.5, 0.5, 0.5, 0.5);
  294.   Diffuse          := GetColor4S(0.5, 0.5, 0.5, 0.5);
  295.   Specular         := GetColor4S(0.0, 0.0, 0.0, 0.0);
  296.   Power            := 0;
  297.   LightingState    := GetLightingState(slACCURATE, False, True, GetColor($40404040));
  298.   Group           := 0;
  299.   FogKind         := fkVertex;
  300.   FogStart        := 0;
  301.   FogEnd          := 10000;
  302.   FogDensity      := 1;
  303.   FogColor.C      := $808080FF;
  304.   PointSize       := 1;
  305.   LinePattern     := 0;
  306.   MinPointSize    := 0;
  307.   MaxPointSize    := 10000;
  308.   PointScaleA     := 1;
  309.   PointScaleB     := 0;
  310.   PointScaleC     := 0;
  311.   PointEdgeState  := GetPointEdgeState(False, False, False);
  312.   VertexShaderIndex := sivNull;
  313.   PixelShaderIndex  := sivNull;
  314.   FTotalVertexStreams := 1;
  315.   FStream0Elements    := 0;
  316.   TotalStages := 1;
  317. end;
  318. destructor TRenderPass.Destroy;
  319. var i: Integer;
  320. begin
  321.   VertexDeclaration := nil;
  322.   Items             := nil;
  323.   for i := 0 to High(FVertexShaderConstants) do FVertexShaderConstants[i] := '';
  324.   FVertexShaderConstants := nil;
  325.   for i := 0 to High(FPixelShaderConstants) do  FPixelShaderConstants[i]  := '';
  326.   FPixelShaderConstants := nil;
  327.   for i := 0 to High(FCompiledVertexShaderConstants) do FreeAndNil(FCompiledVertexShaderConstants[i]);
  328.   FCompiledVertexShaderConstants := nil;
  329.   for i := 0 to High(FCompiledPixelShaderConstants) do FreeAndNil(FCompiledPixelShaderConstants[i]);
  330.   FCompiledPixelShaderConstants := nil;
  331.   inherited;
  332. end;
  333. procedure TRenderPass.AddProperties(const Result: Props.TProperties);
  334. var j, k: Integer; LevelStr: string[50];
  335. begin
  336.   inherited;
  337.   if Assigned(Result) then begin
  338.     Result.AddEnumerated('Group', [], Group, PassGroupsEnum);
  339.     Result.AddEnumerated('RenderOrder',             [], Order, PassOrdersEnum);
  340.     Result.Add('RenderSort bias',        vtSingle,  [], FloatToStr(SortBias), '');
  341.     Result.AddEnumerated('RenderFace culling',      [], FillShadeMode.CullMode,  CullModesEnum);
  342.     Result.Add('RenderColor write mask', vtColor,   [], '#' + IntToHex(FillShadeMode.ColorMask, 8), '');
  343.     Result.Add('Blend',                    vtBoolean, [], OnOffStr[BlendingState.Enabled], '');
  344.     Result.AddEnumerated('BlendOperation',           [], BlendingState.Operation, BlendOpsEnum);
  345.     Result.AddEnumerated('BlendSource',              [], BlendingState.SrcBlend,  BlendArgumentsEnum);
  346.     Result.AddEnumerated('BlendDestination',         [], BlendingState.DestBlend, BlendArgumentsEnum);
  347.     Result.AddEnumerated('BlendAlpha test function', [], BlendingState.ATestFunc, TestFuncsEnum);
  348.     Result.Add('BlendAlpha reference',     vtInt,    [], IntToStr(BlendingState.AlphaRef), '0-255');
  349.     Result.AddEnumerated('RenderFill mode',         [], FillShadeMode.FillMode,  FillModesEnum);
  350.     Result.AddEnumerated('RenderShade mode',        [], FillShadeMode.ShadeMode, ShadeModesEnum);
  351.     Result.AddEnumerated('Z bufferTest function',  [], ZBufferState.ZTestFunc, TestFuncsEnum);
  352.     Result.Add('Z bufferBias',          vtInt,     [], IntToStr(ZBufferState.ZBias),  '');
  353.     Result.Add('Z bufferWrite',         vtBoolean, [], OnOffStr[ZBufferState.ZWrite], '');
  354.     Result.AddEnumerated('StencilOn stencil fail', [], StencilState.SFailOp,   StencilOpsEnum);
  355.     Result.AddEnumerated('StencilOn Z fail',       [], StencilState.ZFailOp,   StencilOpsEnum);
  356.     Result.AddEnumerated('StencilOn pass',         [], StencilState.PassOp,    StencilOpsEnum);
  357.     Result.AddEnumerated('StencilTest function',   [], StencilState.STestFunc, TestFuncsEnum);
  358.     Result.Add('StencilReference',  vtInt, [], IntToStr(StencilRef),       '0-255');
  359.     Result.Add('StencilMask',       vtInt, [], IntToStr(StencilMask),      '');
  360.     Result.Add('StencilWrite mask', vtInt, [], IntToStr(StencilWriteMask), '');
  361.     AddColor4sProperty(Result, 'TextureFactor', ColorTo4S(TextureFactor));
  362.     for j := 0 to MaxTextureCoordSets-1 do begin
  363.       LevelStr := 'TextureCoord set ' + IntToStr(j) + '';
  364.       Result.Add(LevelStr + 'Wrap U',  vtBoolean, [], OnOffStr[TextureWrap.CoordSet[j] and twUCoord > 0],   '');
  365.       Result.Add(LevelStr + 'Wrap V',  vtBoolean, [], OnOffStr[TextureWrap.CoordSet[j] and twVCoord > 0],   '');
  366.       Result.Add(LevelStr + 'Wrap W',  vtBoolean, [], OnOffStr[TextureWrap.CoordSet[j] and twWCoord > 0],   '');
  367.       Result.Add(LevelStr + 'Wrap W2', vtBoolean, [], OnOffStr[TextureWrap.CoordSet[j] and twW2Coord > 0],  '');
  368.     end;
  369.     Result.Add('Lighting', vtBoolean, [], OnOffStr[LightingState.Enabled], '');
  370.     AddColor4sProperty(Result, 'LightingAmbient',  Ambient);
  371.     AddColor4sProperty(Result, 'LightingDiffuse',  Diffuse);
  372.     AddColor4sProperty(Result, 'LightingSpecular', Specular);
  373.     AddColor4sProperty(Result, 'LightingEmissive', Emissive);
  374.     Result.Add('LightingSpecularPower', vtSingle, [], FloatToStr(Power), '0-100');
  375.     Result.AddEnumerated('LightingSpecularMode',         [], LightingState.SpecularMode, SpecularEnum);
  376.     Result.Add('LightingNormalize normals',    vtBoolean, [], OnOffStr[LightingState.NormalizeNormals], '');
  377.     AddColor4sProperty(Result, 'Global ambient', ColorTo4S(LightingState.GlobalAmbient));
  378.     AddColor4sProperty(Result, 'FogColor', ColorTo4S(FogColor));
  379.     Result.AddEnumerated('FogType', [], FogKind, FogKindsEnum);
  380.     Result.Add('FogStart',   vtSingle,  [], FloatToStr(FogStart),   '0.1-100');
  381.     Result.Add('FogEnd',     vtSingle,  [], FloatToStr(FogEnd),     '50-1000');
  382.     Result.Add('FogDensity', vtSingle,  [], FloatToStr(FogDensity), '1-10');
  383.     Result.Add('PointSprites', vtBoolean, [], OnOffStr[PointEdgeState.PointSprite], '');
  384.     Result.Add('PointScaling', vtBoolean, [], OnOffStr[PointEdgeState.PointScale], '');
  385.     Result.Add('PointSize',     vtSingle, [], FloatToStr(PointSize),    '0.01-10');
  386.     Result.Add('PointSize min', vtSingle, [], FloatToStr(MinPointSize), '0.01-10');
  387.     Result.Add('PointSize max', vtSingle, [], FloatToStr(MaxPointSize), '0.01-10');
  388.     Result.Add('PointScale A', vtSingle, [], FloatToStr(PointScaleA), '0.01-10');
  389.     Result.Add('PointScale B', vtSingle, [], FloatToStr(PointScaleB), '0.01-10');
  390.     Result.Add('PointScale C', vtSingle, [], FloatToStr(PointScaleC), '0.01-10');
  391.     Result.Add('Line pattern', vtNat, [], IntToStr(LinePattern), '');
  392.     Result.Add('Edge antialiasing', vtBoolean, [], OnOffStr[PointEdgeState.EdgeAntialias], '');
  393.     Result.Add('Total stages', vtNat, [], IntToStr(TotalStages), '');
  394.     Result.Add('ShadersVertexDeclarationTotal streams', vtInt, [], IntToStr(FTotalVertexStreams), '');
  395.     for j := 0 to FTotalVertexStreams-1 do begin
  396.       LevelStr := 'ShadersVertexDeclarationStream #' + IntToStr(j) + '';
  397.       Result.Add(LevelStr + 'Total elements', vtInt, [], IntToStr(FStream0Elements), '');
  398.       for k := 0 to FStream0Elements-1 do Result.AddEnumerated(LevelStr + '#' + IntToStr(k) + 'Data type', [], Ord(VertexDeclaration[k]), VertexDataTypesEnum);
  399.     end;
  400.     Result.Add('ShadersVertexTotal constants', vtInt, [], IntToStr(TotalVertexShaderConstants), '');
  401.     Result.Add('ShadersPixelTotal constants',  vtInt, [], IntToStr(TotalPixelShaderConstants), '');
  402.     for j := 0 to TotalVertexShaderConstants-1 do
  403.       Result.Add('ShadersVertexConstants#' + IntToStr(j), vtString, [], FVertexShaderConstants[j], '');
  404.     for j := 0 to TotalPixelShaderConstants-1 do
  405.       Result.Add('ShadersPixelConstants#' + IntToStr(j), vtString, [], FPixelShaderConstants[j], '');
  406.   end;
  407.   AddItemLink(Result, 'ShadersVertex', [], 'TShaderResource');
  408.   AddItemLink(Result, 'ShadersPixel',  [], 'TShaderResource');
  409.   for j := 0 to TotalStages-1 do begin
  410.     LevelStr := 'Stage #' + IntToStr(j) + '';
  411.     AddItemLink(Result, LevelStr + 'Texture', [], 'TItem');
  412.     if Assigned(Result) then begin
  413.       Result.AddEnumerated(LevelStr + 'ColorOperation',  [], Stages[j].ColorOp,   ColorOpsEnum);
  414.       Result.AddEnumerated(LevelStr + 'ColorArgument 0', [], Stages[j].ColorArg0, ColorArgsEnum);
  415.       Result.AddEnumerated(LevelStr + 'ColorArgument 1', [], Stages[j].ColorArg1, ColorArgsEnum);
  416.       Result.AddEnumerated(LevelStr + 'ColorArgument 2', [], Stages[j].ColorArg2, ColorArgsEnum);
  417.       Result.Add(LevelStr + 'ColorInvert Arg1', vtBoolean, [], OnOffStr[Stages[j].InvertColorArg1], '');
  418.       Result.Add(LevelStr + 'ColorInvert Arg2', vtBoolean, [], OnOffStr[Stages[j].InvertColorArg2], '');
  419.       Result.AddEnumerated(LevelStr + 'AlphaOperation',  [], Stages[j].AlphaOp,   AlphaOpsEnum);
  420.       Result.AddEnumerated(LevelStr + 'AlphaArgument 0', [], Stages[j].AlphaArg0, AlphaArgsEnum);
  421.       Result.AddEnumerated(LevelStr + 'AlphaArgument 1', [], Stages[j].AlphaArg1, AlphaArgsEnum);
  422.       Result.AddEnumerated(LevelStr + 'AlphaArgument 2', [], Stages[j].AlphaArg2, AlphaArgsEnum);
  423.       Result.Add(LevelStr + 'AlphaInvert Arg1', vtBoolean, [], OnOffStr[Stages[j].InvertColorArg1], '');
  424.       Result.Add(LevelStr + 'AlphaInvert Arg2', vtBoolean, [], OnOffStr[Stages[j].InvertColorArg2], '');
  425.       Result.AddEnumerated(LevelStr + 'AdressingU', [],  Stages[j].TAddressing and $00F,        TexAdrsEnum);
  426.       Result.AddEnumerated(LevelStr + 'AdressingV', [], (Stages[j].TAddressing and $0F0) shr 4, TexAdrsEnum);
  427.       Result.AddEnumerated(LevelStr + 'AdressingW', [], (Stages[j].TAddressing and $F00) shr 8, TexAdrsEnum);
  428.       Result.Add(LevelStr + 'Store in Temp register', vtBoolean, [], OnOffStr[Stages[j].StoreToTemp], '');
  429.       Result.AddEnumerated(LevelStr + 'FilteringMin', [],  Stages[j].Filtering and $00F,        TexFiltersEnum);
  430.       Result.AddEnumerated(LevelStr + 'FilteringMax', [], (Stages[j].Filtering and $0F0) shr 4, TexFiltersEnum);
  431.       Result.AddEnumerated(LevelStr + 'FilteringMip', [], (Stages[j].Filtering and $F00) shr 8, TexFiltersEnum);
  432.       Result.Add(LevelStr + 'FilteringMip LOD bias',   vtSingle, [], FloatToStr(Stages[j].MipLODBias),  '');
  433.       Result.Add(LevelStr + 'FilteringMax mip level',  vtInt,    [], IntToStr(Stages[j].MaxMipLevel),   '');
  434.       Result.Add(LevelStr + 'FilteringMax anisotropy', vtInt,    [], IntToStr(Stages[j].MaxAnisotropy), '');
  435.       AddColor4sProperty(Result, LevelStr + 'Texture border', ColorTo4S(Stages[j].TextureBorder));
  436.       Result.Add(LevelStr + 'Texture coordsSet', vtNat, [], IntToStr(Stages[j].UVSource and $F), '');
  437.       Result.AddEnumerated(LevelStr + 'Texture coordsGeneration',  [], Stages[j].UVSource shr 4, TexCoordsGenEnum);
  438.       Result.AddEnumerated(LevelStr + 'Texture coordsTransform',   [], Stages[j].TTransform and $F, 'None&U&U, V&U, V, W, &U, V, W, W2');
  439.       Result.AddEnumerated(LevelStr + 'Texture coordsMatrix type', [], Ord(Stages[j].TextureMatrixType), TextureMatrixTypesEnum);
  440.       Result.Add(LevelStr + 'Texture coordsMatrix bias', vtSingle, [], FloatToStr(Stages[j].TextureMatrixBias), '-1-1');
  441.       Result.Add(LevelStr + 'Texture coordsProjected', vtBoolean, [], OnOffStr[Stages[j].TTransform and $80 > 0], '');
  442.     end;
  443.   end;
  444. end;
  445. procedure TRenderPass.SetProperties(Properties: Props.TProperties);
  446. var j, k: Integer; LevelStr: string[50];
  447. begin
  448.   inherited;
  449.   if Properties.Valid('Group') then Group := Properties.GetAsInteger('Group');
  450.   if Properties.Valid('RenderOrder')            then Order    := Properties.GetAsInteger('RenderOrder');
  451.   if Properties.Valid('RenderSort bias')        then SortBias := StrToFloatDef(Properties['RenderSort bias'], 0);
  452.   if Properties.Valid('RenderFace culling')     then FillShadeMode.CullMode  :=          Properties.GetAsInteger('RenderFace culling');
  453.   if Properties.Valid('RenderColor write mask') then FillShadeMode.ColorMask := Longword(Properties.GetAsInteger('RenderColor write mask'));
  454.   if Properties.Valid('Blend')                     then BlendingState.Enabled   := Properties.GetAsInteger('Blend') > 0;
  455.   if Properties.Valid('BlendOperation')           then BlendingState.Operation := Properties.GetAsInteger('BlendOperation');
  456.   if Properties.Valid('BlendSource')              then BlendingState.SrcBlend  := Properties.GetAsInteger('BlendSource');
  457.   if Properties.Valid('BlendDestination')         then BlendingState.DestBlend := Properties.GetAsInteger('BlendDestination');
  458.   if Properties.Valid('BlendAlpha test function') then BlendingState.ATestFunc := Properties.GetAsInteger('BlendAlpha test function');
  459.   if Properties.Valid('BlendAlpha reference')     then BlendingState.AlphaRef  := StrToIntDef(Properties[ 'BlendAlpha reference'], 0);
  460.   BlendingState := GetBlendingState(BlendingState.Enabled, BlendingState.SrcBlend, BlendingState.DestBlend, BlendingState.AlphaRef, BlendingState.ATestFunc, BlendingState.Operation);
  461.   if Properties.Valid('RenderFill mode')  then FillShadeMode.FillMode  := Properties.GetAsInteger('RenderFill mode');
  462.   if Properties.Valid('RenderShade mode') then FillShadeMode.ShadeMode := Properties.GetAsInteger('RenderShade mode');
  463.   FillShadeMode := GetFillShadeMode(FillShadeMode.FillMode, FillShadeMode.ShadeMode, FillShadeMode.CullMode, FillShadeMode.ColorMask);
  464.   if Properties.Valid('Z bufferTest function') then ZBufferState.ZTestFunc := Properties.GetAsInteger('Z bufferTest function');
  465.   if Properties.Valid('Z bufferBias')          then ZBufferState.ZBias     := StrToIntDef(Properties[ 'Z bufferBias'], 0);
  466.   if Properties.Valid('Z bufferWrite')         then ZBufferState.ZWrite    := Properties.GetAsInteger('Z bufferWrite') > 0;
  467.   ZBufferState := GetZBufferState(ZBufferState.ZWrite, ZBufferState.ZTestFunc, ZBufferState.ZBias);
  468.   if Properties.Valid('StencilOn stencil fail') then StencilState.SFailOp   := Properties.GetAsInteger('StencilOn stencil fail');
  469.   if Properties.Valid('StencilOn Z fail')       then StencilState.ZFailOp   := Properties.GetAsInteger('StencilOn Z fail');
  470.   if Properties.Valid('StencilOn pass')         then StencilState.PassOp    := Properties.GetAsInteger('StencilOn pass');
  471.   if Properties.Valid('StencilTest function')   then StencilState.STestFunc := Properties.GetAsInteger('StencilTest function');
  472.   StencilState := GetStencilstate(StencilState.SFailOp, StencilState.ZFailOp, StencilState.PassOp, StencilState.STestFunc);
  473.   if Properties.Valid('StencilReference')  then StencilRef       := StrToIntDef(Properties['StencilReference'], 0);
  474.   if Properties.Valid('StencilMask')       then StencilMask      := StrToIntDef(Properties['StencilMask'], -1);
  475.   if Properties.Valid('StencilWrite mask') then StencilWriteMask := StrToIntDef(Properties['StencilWrite mask'], -1);
  476.   SetColorProperty(Properties, 'TextureFactor', TextureFactor);
  477.   for j := 0 to MaxTextureCoordSets-1 do begin
  478.     LevelStr := 'TextureCoord set ' + IntToStr(j) + '';
  479.     if Properties.Valid(LevelStr + 'Wrap U') then
  480.      if Properties.GetAsInteger(LevelStr + 'Wrap U') > 0 then
  481.       TextureWrap.CoordSet[j] := TextureWrap.CoordSet[j] or twUCoord else
  482.        TextureWrap.CoordSet[j] := TextureWrap.CoordSet[j] and not twUCoord;
  483.     if Properties.Valid(LevelStr + 'Wrap V') then
  484.      if Properties.GetAsInteger(LevelStr + 'Wrap V') > 0 then
  485.       TextureWrap.CoordSet[j] := TextureWrap.CoordSet[j] or twVCoord else
  486.        TextureWrap.CoordSet[j] := TextureWrap.CoordSet[j] and not twVCoord;
  487.     if Properties.Valid(LevelStr + 'Wrap W') then
  488.      if Properties.GetAsInteger(LevelStr + 'Wrap W') > 0 then
  489.       TextureWrap.CoordSet[j] := TextureWrap.CoordSet[j] or twWCoord else
  490.        TextureWrap.CoordSet[j] := TextureWrap.CoordSet[j] and not twWCoord;
  491.     if Properties.Valid(LevelStr + 'Wrap W2') then
  492.      if Properties.GetAsInteger(LevelStr + 'Wrap W2') > 0 then
  493.       TextureWrap.CoordSet[j] := TextureWrap.CoordSet[j] or twW2Coord else
  494.        TextureWrap.CoordSet[j] := TextureWrap.CoordSet[j] and not twW2Coord;
  495.   end;
  496.   TextureWrap := GetTextureWrap(TextureWrap.CoordSet[0], TextureWrap.CoordSet[1], TextureWrap.CoordSet[2], TextureWrap.CoordSet[3],
  497.                                 TextureWrap.CoordSet[4], TextureWrap.CoordSet[5], TextureWrap.CoordSet[6], TextureWrap.CoordSet[7]);
  498.   SetColor4sProperty(Properties, 'LightingAmbient',  Ambient);
  499.   SetColor4sProperty(Properties, 'LightingDiffuse',  Diffuse);
  500.   SetColor4sProperty(Properties, 'LightingSpecular', Specular);
  501.   SetColor4sProperty(Properties, 'LightingEmissive', Emissive);
  502.   if Properties.Valid('Lighting')                   then LightingState.Enabled          := Properties.GetAsInteger('Lighting') > 0;
  503.   if Properties.Valid('LightingSpecularPower') then Power := StrToFloatDef(Properties['LightingSpecularPower'], 0);
  504.   if Properties.Valid('LightingSpecularMode')     then LightingState.SpecularMode     := Properties.GetAsInteger('LightingSpecularMode');
  505.   if Properties.Valid('LightingNormalize normals') then LightingState.NormalizeNormals := Properties.GetAsInteger('LightingNormalize normals') > 0;
  506.   SetColorProperty(Properties, 'Global ambient', LightingState.GlobalAmbient);
  507.   LightingState := GetLightingState(LightingState.SpecularMode, LightingState.NormalizeNormals, LightingState.Enabled, LightingState.GlobalAmbient);
  508.   SetColorProperty(Properties, 'FogColor', FogColor);
  509.   if Properties.Valid('FogType')    then FogKind    := Properties.GetAsInteger('FogType');
  510.   if Properties.Valid('FogStart')   then FogStart   := StrToFloatDef(Properties['FogStart'],   0);
  511.   if Properties.Valid('FogEnd')     then FogEnd     := StrToFloatDef(Properties['FogEnd'],     10000);
  512.   if Properties.Valid('FogDensity') then FogDensity := StrToFloatDef(Properties['FogDensity'], 1);
  513.   if Properties.Valid('PointSprites') then PointEdgeState.PointSprite := Properties.GetAsInteger('PointSprites') > 0;
  514.   if Properties.Valid('PointScaling') then PointEdgeState.PointScale  := Properties.GetAsInteger('PointScaling') > 0;
  515.   if Properties.Valid('PointSize')     then PointSize    := StrToFloatDef(Properties['PointSize'],   1);
  516.   if Properties.Valid('PointSize min') then MinPointSize := StrToFloatDef(Properties['PointSize min'], 0);
  517.   if Properties.Valid('PointSize max') then MaxPointSize := StrToFloatDef(Properties['PointSize max'], 1000);
  518.   if Properties.Valid('PointScale A') then PointScaleA := StrToFloatDef(Properties['PointScale A'], 1);
  519.   if Properties.Valid('PointScale B') then PointScaleB := StrToFloatDef(Properties['PointScale B'], 0);
  520.   if Properties.Valid('PointScale C') then PointScaleC := StrToFloatDef(Properties['PointScale C'], 0);
  521.   if Properties.Valid('Line pattern') then LinePattern := StrToIntDef(Properties['Line pattern'], 0);
  522.   if Properties.Valid('Edge antialiasing') then PointEdgeState.EdgeAntialias := Properties.GetAsInteger('Edge antialiasing') > 0;
  523.   PointEdgeState := GetPointEdgeState(PointEdgeState.PointSprite, PointEdgeState.PointScale, PointEdgeState.EdgeAntialias);
  524.   // Shaders
  525.   LevelStr := 'ShadersVertexDeclarationTotal streams';
  526.   if Properties.Valid(LevelStr) then FTotalVertexStreams := Properties.GetAsInteger(LevelStr);
  527.   for j := 0 to FTotalVertexStreams-1 do begin
  528.     LevelStr := 'ShadersVertexDeclarationStream #' + IntToStr(j) + '';
  529.     if Properties.Valid(LevelStr + 'Total elements') then begin
  530.       FStream0Elements := Properties.GetAsInteger(LevelStr + 'Total elements');
  531.       SetLength(VertexDeclaration, FStream0Elements);
  532.     end;
  533.     for k := 0 to FStream0Elements-1 do
  534.       if Properties.Valid(LevelStr + '#' + IntToStr(k) + 'Data type') then VertexDeclaration[k] := TVertexDataType(Properties.GetAsInteger(LevelStr + '#' + IntToStr(k) + 'Data type'));
  535.   end;
  536.   LevelStr := 'ShadersVertexTotal constants';
  537.   if Properties.Valid(LevelStr) then TotalVertexShaderConstants := Properties.GetAsInteger(LevelStr);
  538.   LevelStr := 'ShadersPixelTotal constants';
  539.   if Properties.Valid(LevelStr) then TotalPixelShaderConstants := Properties.GetAsInteger(LevelStr);
  540.   for j := 0 to TotalVertexShaderConstants-1 do begin
  541.     LevelStr := 'ShadersVertexConstants#' + IntToStr(j);
  542.     if Properties.Valid(LevelStr) then
  543.       VertexShaderConstant[j] := Properties[LevelStr];
  544.   end;
  545.   for j := 0 to TotalPixelShaderConstants-1 do begin
  546.     LevelStr := 'ShadersPixelConstants#' + IntToStr(j);
  547.     if Properties.Valid(LevelStr) then
  548.       PixelShaderConstant[j] := Properties[LevelStr];
  549.   end;
  550.   
  551.   if Properties.Valid('ShadersVertex') then begin
  552.     if SetLinkProperty('ShadersVertex', Properties['ShadersVertex']) then
  553.       VertexShaderIndex := sivUnresolved;
  554.     if (Properties['ShadersVertex'] = '') then VertexShaderIndex := sivNull;
  555.   end;
  556.         
  557.   if Properties.Valid('ShadersPixel')  then begin
  558.     if SetLinkProperty('ShadersPixel', Properties['ShadersPixel']) then
  559.       PixelShaderIndex := sivUnresolved;
  560.     if (Properties['ShadersPixel'] = '') then PixelShaderIndex := sivNull;
  561.   end;
  562.   // Texture stages        
  563.   if Properties.Valid('Total stages') then TotalStages := Properties.GetAsInteger('Total stages');
  564.   for j := 0 to TotalStages-1 do begin
  565.     LevelStr := 'Stage #' + IntToStr(j) + '';
  566.     if Properties.Valid(LevelStr + 'Texture') then
  567.       if (Properties[LevelStr + 'Texture'] = '') then begin
  568.         Stages[j].TextureIndex := tivNull;
  569.         SetLinkProperty(LevelStr + 'Texture', '');
  570.       end else if SetLinkProperty(LevelStr + 'Texture', Properties[LevelStr + 'Texture']) then
  571.         Stages[j].TextureIndex := tivUnresolved;
  572.     if Properties.Valid(LevelStr + 'ColorOperation')   then Stages[j].ColorOp         := Properties.GetAsInteger(LevelStr + 'ColorOperation');
  573.     if Properties.Valid(LevelStr + 'ColorArgument 0')  then Stages[j].ColorArg0       := Properties.GetAsInteger(LevelStr + 'ColorArgument 0');
  574.     if Properties.Valid(LevelStr + 'ColorArgument 1')  then Stages[j].ColorArg1       := Properties.GetAsInteger(LevelStr + 'ColorArgument 1');
  575.     if Properties.Valid(LevelStr + 'ColorArgument 2')  then Stages[j].ColorArg2       := Properties.GetAsInteger(LevelStr + 'ColorArgument 2');
  576.     if Properties.Valid(LevelStr + 'ColorInvert Arg1') then Stages[j].InvertColorArg1 := Properties.GetAsInteger(LevelStr + 'ColorInvert Arg1') > 0;
  577.     if Properties.Valid(LevelStr + 'ColorInvert Arg2') then Stages[j].InvertColorArg2 := Properties.GetAsInteger(LevelStr + 'ColorInvert Arg2') > 0;
  578.     if Properties.Valid(LevelStr + 'AlphaOperation')   then Stages[j].AlphaOp         := Properties.GetAsInteger(LevelStr + 'AlphaOperation');
  579.     if Properties.Valid(LevelStr + 'AlphaArgument 0')  then Stages[j].AlphaArg0       := Properties.GetAsInteger(LevelStr + 'AlphaArgument 0');
  580.     if Properties.Valid(LevelStr + 'AlphaArgument 1')  then Stages[j].AlphaArg1       := Properties.GetAsInteger(LevelStr + 'AlphaArgument 1');
  581.     if Properties.Valid(LevelStr + 'AlphaArgument 2')  then Stages[j].AlphaArg2       := Properties.GetAsInteger(LevelStr + 'AlphaArgument 2');
  582.     if Properties.Valid(LevelStr + 'AlphaInvert Arg1') then Stages[j].InvertAlphaArg1 := Properties.GetAsInteger(LevelStr + 'AlphaInvert Arg1') > 0;
  583.     if Properties.Valid(LevelStr + 'AlphaInvert Arg2') then Stages[j].InvertAlphaArg2 := Properties.GetAsInteger(LevelStr + 'AlphaInvert Arg2') > 0;
  584.     if Properties.Valid(LevelStr + 'AdressingU') then Stages[j].TAddressing := (Stages[j].TAddressing and not $00F) or Cardinal(Properties.GetAsInteger(LevelStr + 'AdressingU'));
  585.     if Properties.Valid(LevelStr + 'AdressingV') then Stages[j].TAddressing := (Stages[j].TAddressing and not $0F0) or Cardinal(Properties.GetAsInteger(LevelStr + 'AdressingV')) shl 4;
  586.     if Properties.Valid(LevelStr + 'AdressingW') then Stages[j].TAddressing := (Stages[j].TAddressing and not $F00) or Cardinal(Properties.GetAsInteger(LevelStr + 'AdressingW')) shl 8;
  587.     if Properties.Valid(LevelStr + 'Store in Temp register') then Stages[j].StoreToTemp := Properties.GetAsInteger(LevelStr + 'Store in Temp register') > 0;
  588.     if Properties.Valid(LevelStr + 'FilteringMin') then Stages[j].Filtering := (Stages[j].Filtering and not $00F) or Cardinal(Properties.GetAsInteger(LevelStr + 'FilteringMin'));
  589.     if Properties.Valid(LevelStr + 'FilteringMax') then Stages[j].Filtering := (Stages[j].Filtering and not $0F0) or Cardinal(Properties.GetAsInteger(LevelStr + 'FilteringMax')) shl 4;
  590.     if Properties.Valid(LevelStr + 'FilteringMip') then Stages[j].Filtering := (Stages[j].Filtering and not $F00) or Cardinal(Properties.GetAsInteger(LevelStr + 'FilteringMip')) shl 8;
  591.     if Properties.Valid(LevelStr + 'FilteringMip LOD bias')   then Stages[j].MipLODBias  := StrToFloatDef(Properties[LevelStr + 'FilteringMip LOD bias'], 0);
  592.     if Properties.Valid(LevelStr + 'FilteringMax mip level')  then Stages[j].MaxMipLevel := Properties.GetAsInteger(LevelStr + 'FilteringMax mip level');
  593.     if Properties.Valid(LevelStr + 'FilteringMax anisotropy') then Stages[j].MaxAnisotropy := Properties.GetAsInteger(LevelStr + 'FilteringMax anisotropy');
  594.     SetColorProperty(Properties, LevelStr + 'Texture border', Stages[j].TextureBorder);
  595.     if Properties.Valid(LevelStr + 'Texture coordsSet')        then Stages[j].UVSource := (Stages[j].UVSource and not $0F) or Cardinal(Properties.GetAsInteger(LevelStr + 'Texture coordsSet'));
  596.     if Properties.Valid(LevelStr + 'Texture coordsGeneration') then Stages[j].UVSource := (Stages[j].UVSource and not $F0) or Cardinal(Properties.GetAsInteger(LevelStr + 'Texture coordsGeneration')) shl 4;
  597.     if Properties.Valid(LevelStr + 'Texture coordsTransform')   then Stages[j].TTransform        := (Stages[j].TTransform and not $0F) or Cardinal(Properties.GetAsInteger(LevelStr + 'Texture coordsTransform'));
  598.     if Properties.Valid(LevelStr + 'Texture coordsMatrix type') then Stages[j].TextureMatrixType := TTextureMatrixType(Properties.GetAsInteger(LevelStr + 'Texture coordsMatrix type'));
  599.     if Properties.Valid(LevelStr + 'Texture coordsMatrix bias') then Stages[j].TextureMatrixBias := StrToFloatDef(Properties[LevelStr + 'Texture coordsMatrix bias'], 0);
  600.     if Properties.Valid(LevelStr + 'Texture coordsProjected')   then Stages[j].TTransform        := (Stages[j].TTransform and not $80) or Cardinal(Properties.GetAsInteger(LevelStr + 'Texture coordsProjected')) shl 7;
  601.   end;
  602.   RequestValidation;
  603. end;
  604. function TRenderPass.GetTotalStages: Integer;
  605. begin
  606.   Result := Length(Stages);
  607. end;
  608. procedure TRenderPass.SetTotalStages(const Value: Integer);
  609. var i: Integer; OldTotalStages: Integer;
  610. begin
  611.   OldTotalStages := TotalStages;
  612.   SetLength(Stages, Value);
  613.   for i := OldTotalStages to Value-1 do begin
  614.     Stages[i].TextureIndex      := tivNull;
  615.     Stages[i].ColorOp           := toMODULATE;
  616.     Stages[i].ColorArg1         := taTexture;
  617.     Stages[i].ColorArg2         := taDiffuse;
  618.     Stages[i].InvertColorArg1   := False;
  619.     Stages[i].InvertColorArg2   := False;
  620.     Stages[i].AlphaOp           := toDISABLE;
  621.     Stages[i].AlphaArg1         := taTexture;
  622.     Stages[i].AlphaArg2         := taDiffuse;
  623.     Stages[i].InvertAlphaArg1   := False;
  624.     Stages[i].InvertAlphaArg2   := False;
  625.     Stages[i].TAddressing       := 0;
  626.     Stages[i].StoreToTemp       := False;
  627.     Stages[i].Filtering         := $222;
  628.     Stages[i].UVSource          := 0;
  629.     Stages[i].TTransform        := 2;
  630.     Stages[i].TextureMatrixType := tmNone;
  631.     Stages[i].TextureMatrixBias := 0;
  632.   end;
  633.   BuildItemLinks;
  634. end;
  635. function TRenderPass.AddItem(const Item: TItem): Integer;
  636. begin
  637.   Assert(GetItemIndex(Item) = -1, ClassName + '.AddItem: Item already exists');
  638.   if TotalItems = 0 then (FManager as CAST2.TBaseCore).AddPass(Self);
  639.   Inc(TotalItems);
  640.   if Length(Items) < TotalItems then SetLength(Items, Length(Items) + ItemsCapacityStep);
  641.   Items[TotalItems-1] := Item;
  642.   Result := TotalItems-1;
  643. end;
  644. function TRenderPass.RemoveItem(const Index: Integer): Boolean;
  645. // Returns true if item relocation in Items array occured
  646. begin
  647.   Assert((Index >= 0) and (Index < TotalItems), ClassName + '.RemoveItem: Invalid index "' + IntToStr(Index) + '"');
  648.   Dec(TotalItems);
  649.   Items[Index] := Items[TotalItems];
  650.   Result := Index <> TotalItems;
  651.   if TotalItems = 0 then (FManager as CAST2.TBaseCore).RemovePass(Self);
  652. end;
  653. function TRenderPass.ResolveTexture(const Index: Integer; out Texture: Resources.TImageResource): Boolean;
  654. var Item: TItem;
  655. begin
  656.   Result := ResolveLink('Stage #' + IntToStr(Index) + 'Texture', Item);
  657.   if Item is TImageResource then begin
  658.     Texture := Item as Resources.TImageResource;
  659.     Stages[Index].Camera := nil;
  660.     ResolvedTexture := Texture;
  661.   end else if Item is TCamera then begin
  662.     Stages[Index].TextureIndex := tivRenderTarget;
  663.     Stages[Index].Camera := Item as TCamera;
  664.   end;
  665. end;
  666. function TRenderPass.ResolveVertexShader(var Shader: TShaderResource): Boolean;
  667. var Item: TItem;
  668. begin
  669.   Result := ResolveLink('ShadersVertex', Item);
  670.   Shader := Item as TShaderResource;
  671.   ResolvedVertexShader := Shader;
  672. end;
  673. function TRenderPass.ResolvePixelShader(var Shader: TShaderResource): Boolean;
  674. var Item: TItem;
  675. begin
  676.   Result := ResolveLink('ShadersPixel', Item);
  677.   Shader := Item as TShaderResource;
  678.   ResolvedPixelShader := Shader;
  679. end;
  680. function TRenderPass.GetItemIndex(const Item: TItem): Integer;
  681. begin
  682.   Result := 0;
  683.   while Result < TotalItems do begin
  684.     if Items[Result] = Item then Exit;
  685.     Inc(Result);
  686.   end;
  687.   Result := -1;
  688. end;
  689. procedure TRenderPass.SetOrder(const Value: Integer);
  690. begin
  691.   if Value = FOrder then Exit;
  692.   FOrder := Value;
  693.   if (TotalItems > 0) and (FManager <> nil) then begin                 // For pass reordering in core
  694.     (FManager as CAST2.TBaseCore).RemovePass(Self);
  695.     (FManager as CAST2.TBaseCore).AddPass(Self);
  696.   end;
  697. end;
  698. function TRenderPass.GetTotalPixelShaderConstants: Integer;
  699. begin
  700.   Result := Length(FPixelShaderConstants);
  701. end;
  702. function TRenderPass.GetTotalVertexShaderConstants: Integer;
  703. begin
  704.   Result := Length(FVertexShaderConstants);
  705. end;
  706. procedure TRenderPass.SetTotalPixelShaderConstants(const Value: Integer);
  707. begin
  708.   SetLength(FPixelShaderConstants, Value);
  709.   SetLength(FCompiledPixelShaderConstants, Value);
  710.   RequestValidation;
  711. end;
  712. procedure TRenderPass.SetTotalVertexShaderConstants(const Value: Integer);
  713. begin
  714.   SetLength(FVertexShaderConstants, Value);
  715.   SetLength(FCompiledVertexShaderConstants, Value);
  716.   RequestValidation;
  717. end;
  718. function TRenderPass.GetPixelShaderConstant(Index: Integer): string;
  719. begin
  720.   Result := FPixelShaderConstants[Index];
  721. end;
  722. function TRenderPass.GetVertexShaderConstant(Index: Integer): string;
  723. begin
  724.   Result := FVertexShaderConstants[Index];
  725. end;
  726. procedure TRenderPass.SetVertexShaderConstant(Index: Integer; const Value: string);
  727. begin
  728.   if (Index >= 0) or (Index < TotalVertexShaderConstants) then begin
  729.     FVertexShaderConstants[Index] := Value;
  730.     FCompiledVertexShaderConstants[Index] := FManager.Compiler.Compile(Value);
  731.   end else Log.Log(Format('%S.%S: Invalid index', [ClassName, 'SetVertexShaderConstant']), lkError);
  732. end;
  733. procedure TRenderPass.SetPixelShaderConstant(Index: Integer; const Value: string);
  734. begin
  735.   if (Index >= 0) or (Index < TotalPixelShaderConstants) then begin
  736.     FPixelShaderConstants[Index] := Value;
  737.     FCompiledPixelShaderConstants[Index] := FManager.Compiler.Compile(Value);
  738.   end else Log.Log(Format('%S.%S: Invalid index', [ClassName, 'SetPixelShaderConstant']), lkError);
  739. end;
  740. function TRenderPass.GetCompiledVertexShaderConstants(Index: Integer): OTypes.TRTData;
  741. begin
  742.   Result := FCompiledVertexShaderConstants[Index];
  743. end;
  744. function TRenderPass.GetCompiledPixelShaderConstants(Index: Integer): OTypes.TRTData;
  745. begin
  746.   Result := FCompiledPixelShaderConstants[Index];
  747. end;
  748. procedure TRenderPass.HandleMessage(const Msg: TMessage);
  749. var i: Integer;
  750. begin
  751.   inherited;
  752.   if Msg.ClassType = TDataModifyMsg then begin
  753.     if TDataModifyMsg(Msg).Data = Pointer(ResolvedVertexShader) then VertexShaderIndex := sivUnresolved;
  754.     if TDataModifyMsg(Msg).Data = Pointer(ResolvedPixelShader) then  PixelShaderIndex  := sivUnresolved;
  755. //    if TDataModifyMsg(Msg).Data = ResolvedTexture     then  texVertexShaderIndex := sivUnresolved;
  756.   end else if Msg.ClassType = TRemoveFromSceneMsg then with TRemoveFromSceneMsg(Msg) do
  757.     for i := 0 to TotalStages-1 do
  758.       if (Item = Stages[i].Camera) and (Item is TCamera) then begin
  759.         Stages[i].TextureIndex := tivUnresolved;
  760.         SetLinkProperty('Stage #' + IntToStr(i) + 'Texture', Stages[i].Camera.GetFullName);
  761.         Stages[i].Camera       := nil;
  762.       end;
  763. end;
  764. procedure TRenderPass.RequestValidation;
  765. begin
  766.   if not FManager.IsSceneLoading and Assigned(FManager.Root) then
  767.     SendMessage(TRenderPassModifiedMsg.Create(Self), nil, [mfBroadcast]);
  768. end;
  769. { TTechnique }
  770. procedure TTechnique.SetState(const Value: TItemFlags);
  771. var Modified: Boolean;
  772. begin
  773.   Modified := (isVisible in State) and not (isVisible in Value) or
  774.               not (isVisible in State) and (isVisible in Value);
  775.   inherited;
  776.   if Modified and not FManager.IsSceneLoading and Assigned(FManager.Root) then
  777.     SendMessage(TRenderPassModifiedMsg.Create(Passes[0]), nil, [mfBroadcast]);
  778. end;
  779. constructor TTechnique.Create(AManager: TItemsManager);
  780. begin
  781.   inherited;
  782.   TotalPasses := 0;
  783.   LOD         := 0;
  784.   Valid       := False;
  785.   Include(FState, isVisible);
  786. end;
  787. procedure TTechnique.AddProperties(const Result: Props.TProperties);
  788. var i: Integer;
  789. begin
  790.   inherited;
  791.   if Assigned(Result) then begin
  792.     Result.Add('Total passes', vtInt, [], IntToStr(TotalPasses),  '');
  793.     Result.Add('LOD',  vtInt,    [], IntToStr(LOD),  '');
  794.   end;  
  795.   for i := 0 to TotalPasses-1 do
  796.     AddItemLink(Result, Format('Pass #%D', [i]), [], 'TRenderPass');
  797. end;
  798. procedure TTechnique.SetProperties(Properties: Props.TProperties);
  799. var ItemProps: Props.TProperties;
  800.   function GetPassIndex(const Name: string): Integer;
  801.   begin
  802.     Result := TotalPasses-1;
  803.     while (Result >= 0) and (ItemProps[Format('Pass #%D', [Result])] <> Name) do Dec(Result);
  804.   end;
  805. var i, Ind: Integer; PropName: string;
  806. begin
  807.   inherited;
  808. //  Include(FState, isVisible);
  809.   if Properties.Valid('Total passes') then TotalPasses := StrToIntDef(Properties['Total passes'], TotalPasses);
  810.   ItemProps := Props.TProperties.Create;
  811.   AddProperties(ItemProps);
  812.   for i := 0 to TotalPasses-1 do if Properties.Valid(Format('Pass #%D', [i])) then begin
  813.     PropName := Format('Pass #%D', [i]);
  814.     Ind := GetPassIndex(Properties[PropName]);
  815.     if (Ind = -1) or (Ind = i) then
  816.       SetLinkProperty(PropName, Properties[PropName])
  817.     else Log.Log('TTechnique.SetProperties: Duplicate pass in technique: "' + Properties[PropName], lkError);
  818.   end;
  819.   FreeAndNil(ItemProps);
  820.   if Properties.Valid('LOD') then LOD := StrToIntDef(Properties['LOD'], 0);
  821. end;
  822. procedure TTechnique.SetTotalPasses(const Value: Integer);
  823. begin
  824.   if not FManager.IsSceneLoading and Assigned(FManager.Root) then
  825.     SendMessage(TTechniqueModificationBeginMsg.Create(Self), nil, [mfBroadcast]);
  826.   FTotalPasses := Value;
  827.   SetLength(PassesCache, FTotalPasses);
  828.   BuildItemLinks;
  829.   if not FManager.IsSceneLoading and Assigned(FManager.Root) then
  830.     SendMessage(TTechniqueModificationEndMsg.Create(Self), nil, [mfBroadcast]);
  831. end;
  832. function TTechnique.GetPass(Index: Integer): TRenderPass;
  833. var Item: TItem;
  834. begin
  835.   if PassesCache[Index] <> nil then
  836.     Result := PassesCache[Index] else begin
  837.       ResolveLink(Format('Pass #%D', [Index]), Item);
  838.       PassesCache[Index] := Item as TRenderPass;
  839.       Result := PassesCache[Index]
  840.     end;
  841. end;
  842. procedure TTechnique.SetPass(Index: Integer; const Value: TRenderPass);
  843. begin
  844.   if not FManager.IsSceneLoading and Assigned(FManager.Root) then
  845.     SendMessage(TTechniqueModificationBeginMsg.Create(Self), nil, [mfBroadcast]);
  846.   SetLinkedObject(Format('Pass #%D', [Index]), Value);
  847.   if not FManager.IsSceneLoading and Assigned(FManager.Root) then
  848.     SendMessage(TTechniqueModificationEndMsg.Create(Self), nil, [mfBroadcast]);
  849. end;
  850. { TMaterial }
  851. procedure TMaterial.AddProperties(const Result: Props.TProperties);
  852. var i: Integer;
  853. begin
  854.   inherited;
  855.   if Assigned(Result) then Result.Add('Total techniques', vtInt, [], IntToStr(TotalTechniques),  '');
  856.   for i := 0 to TotalTechniques-1 do
  857.     AddItemLink(Result, Format('Technique #%D', [i]), [], 'TTechnique');
  858. end;
  859. procedure TMaterial.SetProperties(Properties: Props.TProperties);
  860. var i: Integer;
  861. begin
  862.   inherited;
  863.   if Properties.Valid('Total techniques') then
  864.     TotalTechniques := StrToIntDef(Properties['Total techniques'], TotalTechniques);
  865.   for i := 0 to TotalTechniques-1 do if Properties.Valid(Format('Technique #%D', [i])) then
  866.     SetLinkProperty(Format('Technique #%D', [i]), Properties[Format('Technique #%D', [i])]);
  867. end;
  868. function TMaterial.GetTechniqueByLOD(Lod: Single): TTechnique;
  869. var i: Integer;
  870. begin
  871.   Result := nil;
  872.   i := 0;
  873.   while (i < TotalTechniques) and
  874.         ( not (isVisible in Technique[i].State) or not Technique[i].Valid or (Technique[i].LOD <> Round(Lod)) ) do Inc(i);
  875.   if i < TotalTechniques then Result := Technique[i];
  876. end;
  877. function TMaterial.GetTechnique(Index: Integer): TTechnique;
  878. var Item: TItem;
  879. begin
  880.   ResolveLink(Format('Technique #%D', [Index]), Item);
  881.   Result := Item as TTechnique;
  882. end;
  883. procedure TMaterial.SetTechnique(Index: Integer; const Value: TTechnique);
  884. begin
  885.   SetLinkedObject(Format('Technique #%D', [Index]), Value);
  886. end;
  887. procedure TMaterial.SetTotalTechniques(const Value: Integer);
  888. begin
  889.   FTotalTechniques := Value;
  890.   BuildItemLinks;
  891. end;
  892. function TMaterial.PassBelongs(AItem: TItem): Boolean;
  893.   function BelongsToTechnique(Tech: TTechnique): Boolean;
  894.   var i: Integer;
  895.   begin
  896.     Result := False;
  897.     if not Assigned(Tech) then Exit;
  898.     i := Tech.TotalPasses-1;
  899.     while (i >= 0) and (Tech.Passes[i] <> AItem) do Dec(i);
  900.     Result := i >= 0;
  901.   end;
  902. var i: Integer;
  903. begin
  904.   i := TotalTechniques-1;
  905.   while (i >= 0) and not BelongsToTechnique(Technique[i]) do Dec(i);
  906.   Result := i >= 0;
  907. end;
  908. procedure TMaterial.HandleMessage(const Msg: TMessage);
  909. begin
  910.   inherited;
  911.   if (Msg.ClassType = TRenderReinitMsg) or
  912.     ((Msg.ClassType = TRenderPassModifiedMsg) and PassBelongs(TRenderPassModifiedMsg(Msg).Item)) then
  913.     SendMessage(TRequestValidationMsg.Create(Self), nil, [mfCore]);
  914. end;
  915. procedure TMaterial.OnSceneLoaded;
  916. begin
  917.   inherited;
  918.   SendMessage(TRequestValidationMsg.Create(Self), nil, [mfCore]);
  919. end;
  920. end.