123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873 |
- //
- // The graphics engine GXScene https://github.com/glscene
- //
- unit GXSL.TextureShaders;
- (*
- This shader allows to apply multiple textures, gathering them from existing materials.
- This allows saving resources, since you can reference the textures of any material in
- any materialLibrary.
- Note that actually the component references a Material (not a texture) but
- it uses that material's texture. The referenced material settings will be ignored,
- but the texture's settings (like TextureMode, ImageGamma, ImageBrightness) will be used.
- Instead the local material settings (listed in the collection) will be used.
- *)
- interface
- uses
- Winapi.OpenGL,
- Winapi.OpenGLext,
- System.Classes,
- System.SysUtils,
- GXS.Scene,
- GXS.Context,
- GXS.Texture,
- Stage.VectorTypes,
- GXS.XOpenGL,
- Stage.VectorGeometry,
- GXS.Color,
- GXS.Material,
- Stage.Strings,
- GXS.VectorFileObjects,
- GXS.State,
- GXS.PersistentClasses,
- GXS.Coordinates,
- GXS.TextureCombiners,
- GXS.RenderContextInfo,
- GXS.ImageUtils;
- type
- TgxShaderTextureSharing = class;
- TgxShaderTextureSharingMaterial = class(TgxInterfacedCollectionItem, IgxMaterialLibrarySupported)
- private
- FTextureMatrix: TMatrix4f;
- FNeedToUpdateTextureMatrix: Boolean;
- FTextureMatrixIsUnitary: Boolean;
- FLibMaterial: TgxLibMaterial;
- FTexOffset: TgxCoordinates2;
- FTexScale: TgxCoordinates2;
- FBlendingMode: TgxBlendingMode;
- FSpecular: TgxColor;
- FAmbient: TgxColor;
- FDiffuse: TgxColor;
- FEmission: TgxColor;
- FShininess: TgxShininess;
- FMaterialLibrary: TgxMaterialLibrary;
- FLibMaterialName: TgxLibMaterialName;
- procedure SetAmbient(const Value: TgxColor);
- procedure SetDiffuse(const Value: TgxColor);
- procedure SetEmission(const Value: TgxColor);
- procedure SetShininess(const Value: TgxShininess);
- procedure SetSpecular(const Value: TgxColor);
- procedure SetMaterialLibrary(const Value: TgxMaterialLibrary);
- procedure SetLibMaterialName(const Value: TgxLibMaterialName);
- procedure SetBlendingMode(const Value: TgxBlendingMode);
- procedure SetLibMaterial(const Value: TgxLibMaterial);
- procedure SetTexOffset(const Value: TgxCoordinates2);
- procedure SetTexScale(const Value: TgxCoordinates2);
- function GetTextureMatrix: TMatrix4f;
- function GetTextureMatrixIsUnitary: Boolean;
- protected
- procedure coordNotifychange(Sender: TObject);
- procedure OtherNotifychange(Sender: TObject);
- function GetDisplayName: string; override;
- function GetTextureSharingShader: TgxShaderTextureSharing;
- // Implementing IgxMaterialLibrarySupported.
- function GetMaterialLibrary: TgxAbstractMaterialLibrary; virtual;
- public
- procedure Apply(var rci: TgxRenderContextInfo);
- procedure UnApply(var rci: TgxRenderContextInfo);
- constructor Create(Collection: TCollection); override;
- destructor Destroy; override;
- property LibMaterial: TgxLibMaterial read FLibMaterial write SetLibMaterial;
- property TextureMatrix: TMatrix4f read GetTextureMatrix;
- property TextureMatrixIsUnitary: Boolean read GetTextureMatrixIsUnitary;
- published
- property TexOffset: TgxCoordinates2 read FTexOffset write SetTexOffset;
- property TexScale: TgxCoordinates2 read FTexScale write SetTexScale;
- property BlendingMode: TgxBlendingMode read FBlendingMode write SetBlendingMode;
- property Emission: TgxColor read FEmission write SetEmission;
- property Ambient: TgxColor read FAmbient write SetAmbient;
- property Diffuse: TgxColor read FDiffuse write SetDiffuse;
- property Specular: TgxColor read FSpecular write SetSpecular;
- property Shininess: TgxShininess read FShininess write SetShininess;
- property MaterialLibrary: TgxMaterialLibrary read FMaterialLibrary write SetMaterialLibrary;
- property LibMaterialName: TgxLibMaterialName read FLibMaterialName write SetLibMaterialName;
- end;
- TgxShaderTextureSharingMaterials = class(TOwnedCollection)
- protected
- function GetItems(const AIndex: Integer): TgxShaderTextureSharingMaterial;
- procedure SetItems(const AIndex: Integer; const Value: TgxShaderTextureSharingMaterial);
- function GetParent: TgxShaderTextureSharing;
- public
- function Add: TgxShaderTextureSharingMaterial;
- constructor Create(AOwner: TgxShaderTextureSharing);
- property Items[const AIndex: Integer]: TgxShaderTextureSharingMaterial read GetItems write SetItems; default;
- end;
- TgxShaderTextureSharing = class(TgxShader)
- private
- FMaterials: TgxShaderTextureSharingMaterials;
- FCurrentPass: Integer;
- procedure SetMaterials(const Value: TgxShaderTextureSharingMaterials);
- protected
- procedure DoApply(var rci: TgxRenderContextInfo; Sender: TObject); override;
- function DoUnApply(var rci: TgxRenderContextInfo): Boolean; override;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- function AddLibMaterial(const ALibMaterial: TgxLibMaterial): TgxShaderTextureSharingMaterial;
- function FindLibMaterial(const ALibMaterial: TgxLibMaterial): TgxShaderTextureSharingMaterial;
- published
- property Materials: TgxShaderTextureSharingMaterials read FMaterials write SetMaterials;
- end;
- // A shader that can setup the texture combiner.
- TgxTexCombineShader = class(TgxShader)
- private
- FCombiners: TStringList;
- FCommandCache: TgxCombinerCache;
- FCombinerIsValid: Boolean; // to avoid reparsing invalid stuff
- FDesignTimeEnabled: Boolean;
- FMaterialLibrary: TgxMaterialLibrary;
- FLibMaterial3Name: TgxLibMaterialName;
- CurrentLibMaterial3: TgxLibMaterial;
- FLibMaterial4Name: TgxLibMaterialName;
- CurrentLibMaterial4: TgxLibMaterial;
- FApplied3, FApplied4: Boolean;
- protected
- procedure SetCombiners(const val: TStringList);
- procedure SetDesignTimeEnabled(const val: Boolean);
- procedure SetMaterialLibrary(const val: TgxMaterialLibrary);
- procedure SetLibMaterial3Name(const val: TgxLibMaterialName);
- procedure SetLibMaterial4Name(const val: TgxLibMaterialName);
- procedure NotifyLibMaterial3Destruction;
- procedure NotifyLibMaterial4Destruction;
- procedure DoInitialize(var rci: TgxRenderContextInfo; Sender: TObject); override;
- procedure DoApply(var rci: TgxRenderContextInfo; Sender: TObject); override;
- function DoUnApply(var rci: TgxRenderContextInfo): Boolean; override;
- procedure DoFinalize; override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- procedure NotifyChange(Sender: TObject); override;
- published
- property Combiners: TStringList read FCombiners write SetCombiners;
- property DesignTimeEnabled: Boolean read FDesignTimeEnabled write SetDesignTimeEnabled;
- property MaterialLibrary: TgxMaterialLibrary read FMaterialLibrary write SetMaterialLibrary;
- property LibMaterial3Name: TgxLibMaterialName read FLibMaterial3Name write SetLibMaterial3Name;
- property LibMaterial4Name: TgxLibMaterialName read FLibMaterial4Name write SetLibMaterial4Name;
- end;
- //=======================================================================
- implementation
- //=======================================================================
- //----------------------------------------------------------------------------
- // TgxShaderTextureSharingMaterial
- //----------------------------------------------------------------------------
- procedure TgxShaderTextureSharingMaterial.Apply(var rci: TgxRenderContextInfo);
- begin
- if not Assigned(FLibMaterial) then
- Exit;
- xglBeginUpdate;
- if Assigned(FLibMaterial.Shader) then
- begin
- case FLibMaterial.Shader.ShaderStyle of
- ssHighLevel: FLibMaterial.Shader.Apply(rci, FLibMaterial);
- ssReplace:
- begin
- FLibMaterial.Shader.Apply(rci, FLibMaterial);
- Exit;
- end;
- end;
- end;
- if not FLibMaterial.Material.Texture.Disabled then
- begin
- if not (GetTextureMatrixIsUnitary) then
- begin
- rci.gxStates.SetTextureMatrix(TextureMatrix);
- end;
- end;
- if moNoLighting in FLibMaterial.Material.MaterialOptions then
- rci.gxStates.Disable(stLighting);
- if stLighting in rci.gxStates.States then
- begin
- rci.gxStates.SetMaterialColors(cmFront,
- Emission.Color, Ambient.Color, Diffuse.Color, Specular.Color, Shininess);
- rci.gxStates.PolygonMode :=FLibMaterial.Material.PolygonMode;
- end
- else
- FLibMaterial.Material.FrontProperties.ApplyNoLighting(rci, cmFront);
- if (stCullFace in rci.gxStates.States) then
- begin
- case FLibMaterial.Material.FaceCulling of
- fcBufferDefault: if not rci.bufferFaceCull then
- begin
- rci.gxStates.Disable(stCullFace);
- FLibMaterial.Material.BackProperties.Apply(rci, cmBack);
- end;
- fcCull: ; // nothing to do
- fcNoCull:
- begin
- rci.gxStates.Disable(stCullFace);
- FLibMaterial.Material.BackProperties.Apply(rci, cmBack);
- end;
- else
- Assert(False);
- end;
- end
- else
- begin
- // currently NOT culling
- case FLibMaterial.Material.FaceCulling of
- fcBufferDefault:
- begin
- if rci.bufferFaceCull then
- rci.gxStates.Enable(stCullFace)
- else
- FLibMaterial.Material.BackProperties.Apply(rci, cmBack);
- end;
- fcCull: rci.gxStates.Enable(stCullFace);
- fcNoCull: FLibMaterial.Material.BackProperties.Apply(rci, cmBack);
- else
- Assert(False);
- end;
- end;
- // Apply Blending mode
- if not rci.ignoreBlendingRequests then
- case BlendingMode of
- bmOpaque:
- begin
- rci.gxStates.Disable(stBlend);
- rci.gxStates.Disable(stAlphaTest);
- end;
- bmTransparency:
- begin
- rci.gxStates.Enable(stBlend);
- rci.gxStates.Enable(stAlphaTest);
- rci.gxStates.SetBlendFunc(bfSrcAlpha, bfOneMinusSrcAlpha);
- end;
- bmAdditive:
- begin
- rci.gxStates.Enable(stBlend);
- rci.gxStates.Enable(stAlphaTest);
- rci.gxStates.SetBlendFunc(bfSrcAlpha, bfOne);
- end;
- bmAlphaTest50:
- begin
- rci.gxStates.Disable(stBlend);
- rci.gxStates.Enable(stAlphaTest);
- rci.gxStates.SetAlphaFunction(cfGEqual, 0.5);
- end;
- bmAlphaTest100:
- begin
- rci.gxStates.Disable(stBlend);
- rci.gxStates.Enable(stAlphaTest);
- rci.gxStates.SetAlphaFunction(cfGEqual, 1.0);
- end;
- bmModulate:
- begin
- rci.gxStates.Enable(stBlend);
- rci.gxStates.Enable(stAlphaTest);
- rci.gxStates.SetBlendFunc(bfDstColor, bfZero);
- end;
- else
- Assert(False);
- end;
- // Fog switch
- if moIgnoreFog in FLibMaterial.Material.MaterialOptions then
- begin
- if stFog in rci.gxStates.States then
- begin
- rci.gxStates.Disable(stFog);
- Inc(rci.fogDisabledCounter);
- end;
- end;
- if not Assigned(FLibMaterial.Material.TextureEx) then
- begin
- if Assigned(FLibMaterial.Material.Texture) then
- FLibMaterial.Material.Texture.Apply(rci);
- end
- else
- begin
- if Assigned(FLibMaterial.Material.Texture) and not FLibMaterial.Material.TextureEx.IsTextureEnabled(0) then
- FLibMaterial.Material.Texture.Apply(rci)
- else
- if FLibMaterial.Material.TextureEx.Count > 0 then
- FLibMaterial.Material.TextureEx.Apply(rci);
- end;
- if Assigned(FLibMaterial.Shader) then
- begin
- case FLibMaterial.Shader.ShaderStyle of
- ssLowLevel: FLibMaterial.Shader.Apply(rci, FLibMaterial);
- end;
- end;
- xglEndUpdate;
- end;
- procedure TgxShaderTextureSharingMaterial.coordNotifychange(Sender: TObject);
- begin
- FNeedToUpdateTextureMatrix := True;
- GetTextureSharingShader.NotifyChange(Self);
- end;
- constructor TgxShaderTextureSharingMaterial.Create(Collection: TCollection);
- begin
- inherited;
- FSpecular := TgxColor.Create(Self);
- FSpecular.OnNotifyChange := OtherNotifychange;
- FAmbient := TgxColor.Create(Self);
- FAmbient.OnNotifyChange := OtherNotifychange;
- FDiffuse := TgxColor.Create(Self);
- FDiffuse.OnNotifyChange := OtherNotifychange;
- FEmission := TgxColor.Create(Self);
- FEmission.OnNotifyChange := OtherNotifychange;
- FTexOffset := TgxCoordinates2.CreateInitialized(Self, NullHmgVector, csPoint2d);
- FTexOffset.OnNotifyChange := coordNotifychange;
- FTexScale := TgxCoordinates2.CreateInitialized(Self, XYZHmgVector, csPoint2d);
- FTexScale.OnNotifyChange := coordNotifychange;
- FNeedToUpdateTextureMatrix := True;
- end;
- destructor TgxShaderTextureSharingMaterial.Destroy;
- begin
- FSpecular.Free;
- FAmbient.Free;
- FDiffuse.Free;
- FEmission.Free;
- FTexOffset.Free;
- FTexScale.Free;
- inherited;
- end;
- function TgxShaderTextureSharingMaterial.GetDisplayName: string;
- var
- st: string;
- begin
- if Assigned(MaterialLibrary) then
- st := MaterialLibrary.Name
- else
- st := '';
- Result := '[' + st + '.' + Self.LibMaterialName + ']';
- end;
- function TgxShaderTextureSharingMaterial.GetMaterialLibrary: TgxAbstractMaterialLibrary;
- begin
- Result := FMaterialLibrary;
- end;
- function TgxShaderTextureSharingMaterial.GetTextureMatrix: TMatrix4f;
- begin
- if FNeedToUpdateTextureMatrix then
- begin
- if not (TexOffset.Equals(NullHmgVector) and TexScale.Equals(XYZHmgVector)) then
- begin
- FTextureMatrixIsUnitary := False;
- FTextureMatrix := CreateScaleAndTranslationMatrix(TexScale.AsVector, TexOffset.AsVector)
- end
- else
- FTextureMatrixIsUnitary := True;
- FNeedToUpdateTextureMatrix := False;
- end;
- Result := FTextureMatrix;
- end;
- function TgxShaderTextureSharingMaterial.GetTextureMatrixIsUnitary: Boolean;
- begin
- if FNeedToUpdateTextureMatrix then
- GetTextureMatrix;
- Result := FTextureMatrixIsUnitary;
- end;
- function TgxShaderTextureSharingMaterial.GetTextureSharingShader: TgxShaderTextureSharing;
- begin
- if Collection is TgxShaderTextureSharingMaterials then
- Result := TgxShaderTextureSharingMaterials(Collection).GetParent
- else
- Result := nil;
- end;
- procedure TgxShaderTextureSharingMaterial.OtherNotifychange(Sender: TObject);
- begin
- GetTextureSharingShader.NotifyChange(Self);
- end;
- procedure TgxShaderTextureSharingMaterial.SetAmbient(const Value: TgxColor);
- begin
- FAmbient.Assign(Value);
- end;
- procedure TgxShaderTextureSharingMaterial.SetBlendingMode(const Value: TgxBlendingMode);
- begin
- FBlendingMode := Value;
- end;
- procedure TgxShaderTextureSharingMaterial.SetDiffuse(const Value: TgxColor);
- begin
- FDiffuse.Assign(Value);
- end;
- procedure TgxShaderTextureSharingMaterial.SetEmission(const Value: TgxColor);
- begin
- FEmission.Assign(Value);
- end;
- procedure TgxShaderTextureSharingMaterial.SetLibMaterialName(const Value: TgxLibMaterialName);
- begin
- FLibMaterialName := Value;
- if (FLibMaterialName = '') or (FMaterialLibrary = nil) then
- FLibMaterial := nil
- else
- SetLibMaterial(FMaterialLibrary.LibMaterialByName(FLibMaterialName));
- end;
- procedure TgxShaderTextureSharingMaterial.SetLibMaterial(const Value: TgxLibMaterial);
- begin
- FLibMaterial := Value;
- if FLibMaterial <> nil then
- begin
- FLibMaterialName := FLibMaterial.DisplayName;
- FMaterialLibrary := TgxMaterialLibrary(TgxLibMaterials(Value.Collection).Owner);
- if not (csloading in GetTextureSharingShader.ComponentState) then
- begin
- FTexOffset.Assign(FLibMaterial.TextureOffset);
- FTexScale.Assign(FLibMaterial.TextureScale);
- FBlendingMode := FLibMaterial.Material.BlendingMode;
- fEmission.Assign(FLibMaterial.Material.FrontProperties.Emission);
- fAmbient.Assign(FLibMaterial.Material.FrontProperties.Ambient);
- fDiffuse.Assign(FLibMaterial.Material.FrontProperties.Diffuse);
- fSpecular.Assign(FLibMaterial.Material.FrontProperties.Specular);
- fShininess := FLibMaterial.Material.FrontProperties.Shininess;
- end;
- end;
- end;
- procedure TgxShaderTextureSharingMaterial.SetMaterialLibrary(const Value: TgxMaterialLibrary);
- begin
- FMaterialLibrary := Value;
- if (FLibMaterialName = '') or (FMaterialLibrary = nil) then
- FLibMaterial := nil
- else
- SetLibMaterial(FMaterialLibrary.LibMaterialByName(FLibMaterialName));
- end;
- procedure TgxShaderTextureSharingMaterial.SetShininess(const Value: TgxShininess);
- begin
- FShininess := Value;
- end;
- procedure TgxShaderTextureSharingMaterial.SetSpecular(const Value: TgxColor);
- begin
- FSpecular.Assign(Value);
- end;
- procedure TgxShaderTextureSharingMaterial.SetTexOffset(const Value: TgxCoordinates2);
- begin
- FTexOffset.Assign(Value);
- FNeedToUpdateTextureMatrix := True;
- end;
- procedure TgxShaderTextureSharingMaterial.SetTexScale(const Value: TgxCoordinates2);
- begin
- FTexScale.Assign(Value);
- FNeedToUpdateTextureMatrix := True;
- end;
- procedure TgxShaderTextureSharingMaterial.UnApply(var rci: TgxRenderContextInfo);
- begin
- if not Assigned(FLibMaterial) then
- Exit;
- if Assigned(FLibMaterial.Shader) then
- begin
- case FLibMaterial.Shader.ShaderStyle of
- ssLowLevel: FLibMaterial.Shader.UnApply(rci);
- ssReplace:
- begin
- FLibMaterial.Shader.UnApply(rci);
- Exit;
- end;
- end;
- end;
- FLibMaterial.Material.UnApply(rci);
- if not FLibMaterial.Material.Texture.Disabled then
- if not (GetTextureMatrixIsUnitary) then
- begin
- rci.gxStates.ResetTextureMatrix;
- end;
- if Assigned(FLibMaterial.Shader) then
- begin
- case FLibMaterial.Shader.ShaderStyle of
- ssHighLevel: FLibMaterial.Shader.UnApply(rci);
- end;
- end;
- end;
- //----------------------------
- // TgxShaderTextureSharing
- //----------------------------
- function TgxShaderTextureSharing.AddLibMaterial(const ALibMaterial: TgxLibMaterial): TgxShaderTextureSharingMaterial;
- begin
- Result := FMaterials.Add;
- Result.SetLibMaterial(ALibMaterial);
- end;
- constructor TgxShaderTextureSharing.Create(AOwner: TComponent);
- begin
- inherited;
- FMaterials := TgxShaderTextureSharingMaterials.Create(Self);
- ShaderStyle := ssReplace;
- end;
- destructor TgxShaderTextureSharing.Destroy;
- begin
- FMaterials.Free;
- inherited;
- end;
- procedure TgxShaderTextureSharing.DoApply(var rci: TgxRenderContextInfo; Sender: TObject);
- begin
- if Materials.Count > 0 then
- begin
- rci.gxStates.Enable(stDepthTest);
- rci.gxStates.DepthFunc := cfLEqual;
- Materials[0].Apply(rci);
- FCurrentPass := 1;
- end;
- end;
- function TgxShaderTextureSharing.DoUnApply(var rci: TgxRenderContextInfo): Boolean;
- begin
- Result := False;
- if Materials.Count > 0 then
- begin
- Materials[FCurrentPass - 1].UnApply(rci);
- if FCurrentPass < Materials.Count then
- begin
- Materials[FCurrentPass].Apply(rci);
- Inc(FCurrentPass);
- Result := True;
- end
- else
- begin
- rci.gxStates.DepthFunc := cfLess;
- rci.gxStates.Disable(stBlend);
- rci.gxStates.Disable(stAlphaTest);
- FCurrentPass := 0;
- end;
- end;
- end;
- function TgxShaderTextureSharing.FindLibMaterial(const ALibMaterial: TgxLibMaterial): TgxShaderTextureSharingMaterial;
- var
- I: Integer;
- begin
- Result := nil;
- for I := 0 to FMaterials.Count - 1 do
- if FMaterials[I].FLibMaterial = ALibMaterial then
- begin
- Result := FMaterials[I];
- Break;
- end;
- end;
- procedure TgxShaderTextureSharing.Notification(AComponent: TComponent; Operation: TOperation);
- var
- I: Integer;
- begin
- inherited;
- if Operation = opRemove then
- begin
- if AComponent is TgxMaterialLibrary then
- begin
- for I := 0 to Materials.Count - 1 do
- begin
- if Materials.Items[I].MaterialLibrary = AComponent then
- Materials.Items[I].MaterialLibrary := nil;
- end;
- end;
- end;
- end;
- procedure TgxShaderTextureSharing.SetMaterials(const Value: TgxShaderTextureSharingMaterials);
- begin
- FMaterials.Assign(Value);
- end;
- //----------------------------------------
- // TgxShaderTextureSharingMaterials
- //----------------------------------------
- function TgxShaderTextureSharingMaterials.Add: TgxShaderTextureSharingMaterial;
- begin
- Result := (inherited Add) as TgxShaderTextureSharingMaterial;
- end;
- constructor TgxShaderTextureSharingMaterials.Create(AOwner: TgxShaderTextureSharing);
- begin
- inherited Create(AOwner, TgxShaderTextureSharingMaterial);
- end;
- function TgxShaderTextureSharingMaterials.GetItems(const AIndex: Integer): TgxShaderTextureSharingMaterial;
- begin
- Result := (inherited Items[AIndex]) as TgxShaderTextureSharingMaterial;
- end;
- function TgxShaderTextureSharingMaterials.GetParent: TgxShaderTextureSharing;
- begin
- Result := TgxShaderTextureSharing(GetOwner);
- end;
- procedure TgxShaderTextureSharingMaterials.SetItems(const AIndex: Integer; const Value: TgxShaderTextureSharingMaterial);
- begin
- inherited Items[AIndex] := Value;
- end;
- // ------------------
- // ------------------ TgxTexCombineShader ------------------
- // ------------------
- constructor TgxTexCombineShader.Create(AOwner: TComponent);
- begin
- inherited;
- ShaderStyle := ssLowLevel;
- FCombiners := TStringList.Create;
- TStringList(FCombiners).OnChange := NotifyChange;
- FCombinerIsValid := True;
- FCommandCache := nil;
- end;
- destructor TgxTexCombineShader.Destroy;
- begin
- if Assigned(currentLibMaterial3) then
- currentLibMaterial3.UnregisterUser(Self);
- if Assigned(currentLibMaterial4) then
- currentLibMaterial4.UnregisterUser(Self);
- inherited;
- FCombiners.Free;
- end;
- procedure TgxTexCombineShader.Notification(AComponent: TComponent; Operation: TOperation);
- begin
- if (FMaterialLibrary = AComponent) and (Operation = opRemove) then
- begin
- NotifyLibMaterial3Destruction;
- NotifyLibMaterial4Destruction;
- FMaterialLibrary := nil;
- end;
- inherited;
- end;
- procedure TgxTexCombineShader.NotifyChange(Sender: TObject);
- begin
- FCombinerIsValid := True;
- FCommandCache := nil;
- inherited NotifyChange(Sender);
- end;
- procedure TgxTexCombineShader.NotifyLibMaterial3Destruction;
- begin
- FLibMaterial3Name := '';
- currentLibMaterial3 := nil;
- end;
- procedure TgxTexCombineShader.NotifyLibMaterial4Destruction;
- begin
- FLibMaterial4Name := '';
- currentLibMaterial4 := nil;
- end;
- procedure TgxTexCombineShader.SetMaterialLibrary(const val: TgxMaterialLibrary);
- begin
- FMaterialLibrary := val;
- SetLibMaterial3Name(LibMaterial3Name);
- SetLibMaterial4Name(LibMaterial4Name);
- end;
- procedure TgxTexCombineShader.SetLibMaterial3Name(const val: TgxLibMaterialName);
- var
- newLibMaterial: TgxLibMaterial;
- begin
- // locate new libmaterial
- if Assigned(FMaterialLibrary) then
- newLibMaterial := MaterialLibrary.Materials.GetLibMaterialByName(val)
- else
- newLibMaterial := nil;
- FLibMaterial3Name := val;
- // unregister if required
- if newLibMaterial <> currentLibMaterial3 then
- begin
- // unregister from old
- if Assigned(currentLibMaterial3) then
- currentLibMaterial3.UnregisterUser(Self);
- currentLibMaterial3 := newLibMaterial;
- // register with new
- if Assigned(currentLibMaterial3) then
- currentLibMaterial3.RegisterUser(Self);
- NotifyChange(Self);
- end;
- end;
- procedure TgxTexCombineShader.SetLibMaterial4Name(const val: TgxLibMaterialName);
- var
- newLibMaterial: TgxLibMaterial;
- begin
- // locate new libmaterial
- if Assigned(FMaterialLibrary) then
- newLibMaterial := MaterialLibrary.Materials.GetLibMaterialByName(val)
- else
- newLibMaterial := nil;
- FLibMaterial4Name := val;
- // unregister if required
- if newLibMaterial <> currentLibMaterial4 then
- begin
- // unregister from old
- if Assigned(currentLibMaterial4) then
- currentLibMaterial4.UnregisterUser(Self);
- currentLibMaterial4 := newLibMaterial;
- // register with new
- if Assigned(currentLibMaterial4) then
- currentLibMaterial4.RegisterUser(Self);
- NotifyChange(Self);
- end;
- end;
- procedure TgxTexCombineShader.DoInitialize(var rci: TgxRenderContextInfo; Sender: TObject);
- begin
- end;
- procedure TgxTexCombineShader.DoApply(var rci: TgxRenderContextInfo; Sender: TObject);
- var
- n, units: Integer;
- begin
- // if not GL_ARB_multitexture then Exit;
- FApplied3 := False;
- FApplied4 := False;
- if FCombinerIsValid and (FDesignTimeEnabled or (not (csDesigning in ComponentState))) then
- begin
- try
- if Assigned(currentLibMaterial3) or Assigned(currentLibMaterial4) then
- begin
- glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, @n);
- units := 0;
- if Assigned(currentLibMaterial3) and (n >= 3) then
- begin
- with currentLibMaterial3.Material.Texture do
- begin
- if Enabled then
- begin
- if currentLibMaterial3.TextureMatrixIsIdentity then
- ApplyAsTextureN(3, rci)
- else
- ApplyAsTextureN(3, rci, @currentLibMaterial3.TextureMatrix.X.X);
- // ApplyAsTextureN(3, rci, currentLibMaterial3);
- Inc(units, 4);
- FApplied3 := True;
- end;
- end;
- end;
- if Assigned(currentLibMaterial4) and (n >= 4) then
- begin
- with currentLibMaterial4.Material.Texture do
- begin
- if Enabled then
- begin
- if currentLibMaterial4.TextureMatrixIsIdentity then
- ApplyAsTextureN(4, rci)
- else
- ApplyAsTextureN(4, rci, @currentLibMaterial4.TextureMatrix.X.X);
- // ApplyAsTextureN(4, rci, currentLibMaterial4);
- Inc(units, 8);
- FApplied4 := True;
- end;
- end;
- end;
- if units > 0 then
- xglMapTexCoordToArbitraryAdd(units);
- end;
- if Length(FCommandCache) = 0 then
- FCommandCache := GetTextureCombiners(FCombiners);
- for n := 0 to High(FCommandCache) do
- begin
- rci.gxStates.ActiveTexture := FCommandCache[n].ActiveUnit;
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
- glTexEnvi(GL_TEXTURE_ENV, FCommandCache[n].Arg1, FCommandCache[n].Arg2);
- end;
- rci.gxStates.ActiveTexture := 0;
- except
- on E: Exception do
- begin
- FCombinerIsValid := False;
- InformationDlg(E.ClassName + ': ' + E.Message);
- end;
- end;
- end;
- end;
- function TgxTexCombineShader.DoUnApply(var rci: TgxRenderContextInfo): Boolean;
- begin
- if FApplied3 then
- with currentLibMaterial3.Material.Texture do
- UnApplyAsTextureN(3, rci, (not currentLibMaterial3.TextureMatrixIsIdentity));
- if FApplied4 then
- with currentLibMaterial4.Material.Texture do
- UnApplyAsTextureN(4, rci, (not currentLibMaterial4.TextureMatrixIsIdentity));
- Result := False;
- end;
- procedure TgxTexCombineShader.DoFinalize;
- begin
- end;
- procedure TgxTexCombineShader.SetCombiners(const val: TStringList);
- begin
- if val <> FCombiners then
- begin
- FCombiners.Assign(val);
- NotifyChange(Self);
- end;
- end;
- procedure TgxTexCombineShader.SetDesignTimeEnabled(const val: Boolean);
- begin
- if val <> FDesignTimeEnabled then
- begin
- FDesignTimeEnabled := val;
- NotifyChange(Self);
- end;
- end;
- //----------------------------------------------------------------------------
- initialization
- //----------------------------------------------------------------------------
- RegisterClasses([TgxShaderTextureSharing, TgxShaderTextureSharingMaterials,
- TgxShaderTextureSharingMaterial]);
- end.
|