123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818 |
- //
- // The graphics engine GLXEngine. The unit of GXScene for Delphi
- //
- unit GXSL.DiffuseSpecularShader;
- (*
- This is a collection of GLSL Diffuse Specular shaders, comes in these variaties
- (to know what these suffixes and prefixes mean see GXS.CustomShader.pas):
- - TgxSLDiffuseSpecularShader
- - TgxSLDiffuseSpecularShaderMT
- - TgxSLMLDiffuseSpecularShader
- - TgxSLMLDiffuseSpecularShaderMT
- Notes:
- 1) TgxSLDiffuseSpecularShader takes all Material parameters directly
- from OpenGL (that includes TgxMaterial's)
- 2) TgxSLDiffuseSpecularShader takes all Light parameters directly
- from OpenGL (that includes TgxLightSource's)
- *)
- interface
- {$I Stage.Defines.inc}
- uses
- System.Classes,
- System.SysUtils,
- GXS.PersistentClasses,
- Stage.VectorGeometry,
- GXS.Color,
- Stage.Strings,
- GXS.Scene,
- GXSL.CustomShader,
- GXSL.Shader,
- GXS.Texture,
- GXS.RenderContextInfo,
- GXS.Material;
- type
- EgxslDiffuseSpecularShaderException = class(EgxslShaderException);
- // Abstract class.
- TgxBaseCustomGLSLDiffuseSpecular = class(TgxslCustomShader)
- private
- FLightPower: Single;
- FRealisticSpecular: Boolean;
- FFogSupport: TgxShaderFogSupport;
- procedure SetRealisticSpecular(const Value: Boolean);
- procedure SetFogSupport(const Value: TgxShaderFogSupport);
- protected
- procedure DoApply(var rci : TgxRenderContextInfo; Sender : TObject); override;
- function DoUnApply(var rci: TgxRenderContextInfo): Boolean; override;
- public
- constructor Create(AOwner : TComponent); override;
- property LightPower: Single read FLightPower write FLightPower;
- property RealisticSpecular: Boolean read FRealisticSpecular write SetRealisticSpecular;
- // User can disable fog support and save some FPS if he doesn't need it.
- property FogSupport: TgxShaderFogSupport read FFogSupport write SetFogSupport default sfsAuto;
- end;
- // Abstract class.
- TgxBaseGLSLDiffuseSpecularShaderMT = class(TgxBaseCustomGLSLDiffuseSpecular, IgxMaterialLibrarySupported)
- private
- FMaterialLibrary: TgxMaterialLibrary;
- FMainTexture: TgxTexture;
- FMainTextureName: TgxLibMaterialName;
- function GetMainTextureName: TgxLibMaterialName;
- procedure SetMainTextureName(const Value: TgxLibMaterialName);
- // Implementing IGLMaterialLibrarySupported.
- function GetMaterialLibrary: TgxAbstractMaterialLibrary;
- protected
- procedure SetMaterialLibrary(const Value: TgxMaterialLibrary); virtual;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- procedure DoApply(var rci : TgxRenderContextInfo; Sender : TObject); override;
- public
- property MainTexture: TgxTexture read FMainTexture write FMainTexture;
- property MainTextureName: TgxLibMaterialName read GetMainTextureName write SetMainTextureName;
- property MaterialLibrary: TgxMaterialLibrary read FMaterialLibrary write SetMaterialLibrary;
- end;
- {******** Single Light ************}
- TgxCustomGLSLDiffuseSpecularShader = class(TgxBaseCustomGLSLDiffuseSpecular)
- protected
- procedure DoInitialize(var rci: TgxRenderContextInfo; Sender: TObject); override;
- procedure DoApply(var rci : TgxRenderContextInfo; Sender : TObject); override;
- end;
- TgxCustomGLSLDiffuseSpecularShaderMT = class(TgxBaseGLSLDiffuseSpecularShaderMT)
- protected
- procedure DoInitialize(var rci: TgxRenderContextInfo; Sender: TObject); override;
- end;
- //******* Multi Light *********
- TLightRecord = record
- Enabled: Boolean;
- Style: TgxLightStyle;
- end;
- // Note: probably LightCount should be replaced by LightSources, like in GLSLBumpShader.pas
- TgxCustomGLSLMLDiffuseSpecularShader = class(TgxBaseCustomGLSLDiffuseSpecular)
- private
- FLightTrace: array[0..7] of TLightRecord;
- protected
- procedure DoInitialize(var rci: TgxRenderContextInfo; Sender: TObject); override;
- procedure DoApply(var rci: TgxRenderContextInfo; Sender: TObject); override;
- public
- constructor Create(AOwner : TComponent); override;
- end;
- TgxCustomGLSLMLDiffuseSpecularShaderMT = class(TgxBaseGLSLDiffuseSpecularShaderMT)
- private
- FLightTrace: array[0..7] of TLightRecord;
- protected
- procedure DoInitialize(var rci: TgxRenderContextInfo; Sender: TObject); override;
- procedure DoApply(var rci: TgxRenderContextInfo; Sender: TObject); override;
- public
- constructor Create(AOwner : TComponent); override;
- end;
- {******** Published Stuff ************}
- TgxSLDiffuseSpecularShaderMT = class(TgxCustomGLSLDiffuseSpecularShaderMT)
- published
- property MainTextureName;
- property LightPower;
- property FogSupport;
- end;
- TgxSLDiffuseSpecularShader = class(TgxCustomGLSLDiffuseSpecularShader)
- published
- property LightPower;
- property FogSupport;
- end;
- TgxSLMLDiffuseSpecularShaderMT = class(TgxCustomGLSLMLDiffuseSpecularShaderMT)
- published
- property MainTextureName;
- property LightPower;
- property FogSupport;
- end;
- TgxSLMLDiffuseSpecularShader = class(TgxCustomGLSLMLDiffuseSpecularShader)
- published
- property LightPower;
- property FogSupport;
- end;
- implementation //--------------------------------------------------------------
- procedure GetVertexProgramCode(const Code: TStrings;
- AFogSupport: Boolean; var rci: TgxRenderContextInfo);
- begin
- with Code do
- begin
- Clear;
- Add('varying vec3 Normal; ');
- Add('varying vec4 Position; ');
- if AFogSupport then
- begin
- Add('varying float fogFactor; ');
- end;
- Add(' ');
- Add(' ');
- Add('void main(void) ');
- Add('{ ');
- Add(' gl_Position = ftransform(); ');
- Add(' gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; ');
- Add(' Normal = normalize(gl_NormalMatrix * gl_Normal); ');
- Add(' Position = gl_ModelViewMatrix * gl_Vertex; ');
- if AFogSupport then
- begin
- Add(' const float LOG2 = 1.442695; ');
- Add(' gl_FogFragCoord = length(Position.xyz); ');
- case TgxSceneBuffer(rci.buffer).FogEnvironment.FogMode of
- fmLinear:
- Add(' fogFactor = (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale; ');
- fmExp, // Yep, I don't know about this type, so I use fmExp2.
- fmExp2:
- begin
- Add(' fogFactor = exp2( -gl_Fog.density * ');
- Add(' gl_Fog.density * ');
- Add(' gl_FogFragCoord * ');
- Add(' gl_FogFragCoord * ');
- Add(' LOG2 ); ');
- end;
- else
- Assert(False, strUnknownType);
- end;
- Add(' fogFactor = clamp(fogFactor, 0.0, 1.0); ');
- end;
- Add('} ');
- end;
- end;
- procedure AddLightSub(const Code: TStrings);
- begin
- with Code do
- begin
- Add('void pointLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3)');
- Add('{');
- Add(' float nDotVP; // normal . light direction');
- Add(' float nDotHV; // normal . light half vector');
- Add(' float pf; // power factor');
- Add(' float attenuation; // computed attenuation factor');
- Add(' float d; // distance from surface to light source');
- Add(' vec3 VP; // direction from surface to light position');
- Add(' vec3 halfVector; // direction of maximum highlights');
- Add(' ');
- Add(' // Compute vector from surface to light position');
- Add(' VP = vec3 (gl_LightSource[i].position) - ecPosition3;');
- Add(' ');
- Add(' // Compute distance between surface and light position');
- Add(' d = length(VP);');
- Add(' ');
- Add(' // Normalize the vector from surface to light position');
- Add(' VP = normalize(VP);');
- Add(' ');
- Add(' // Compute attenuation');
- Add(' attenuation = 1.0 / (gl_LightSource[i].constantAttenuation +');
- Add(' gl_LightSource[i].linearAttenuation * d +');
- Add(' gl_LightSource[i].quadraticAttenuation * d * d);');
- Add(' ');
- Add(' halfVector = normalize(VP + eye);');
- Add(' ');
- Add(' nDotVP = max(0.0, dot(normal, VP));');
- Add(' nDotHV = max(0.0, dot(normal, halfVector));');
- Add(' ');
- Add(' if (nDotVP == 0.0)');
- Add(' {');
- Add(' pf = 0.0;');
- Add(' }');
- Add(' else');
- Add(' {');
- Add(' pf = pow(nDotHV, gl_FrontMaterial.shininess);');
- Add(' ');
- Add(' }');
- Add(' Ambient += gl_LightSource[i].ambient * attenuation;');
- Add(' Diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation;');
- Add(' Specular += gl_LightSource[i].specular * pf * attenuation;');
- Add('}');
- Add(' ');
- Add('void directionalLight(in int i, in vec3 normal)');
- Add('{');
- Add(' float nDotVP; // normal . light direction');
- Add(' float nDotHV; // normal . light half vector');
- Add(' float pf; // power factor');
- Add(' ');
- Add(' nDotVP = max(0.0, dot(normal, normalize(vec3 (gl_LightSource[i].position))));');
- Add(' nDotHV = max(0.0, dot(normal, vec3 (gl_LightSource[i].halfVector)));');
- Add(' ');
- Add(' if (nDotVP == 0.0)');
- Add(' {');
- Add(' pf = 0.0;');
- Add(' }');
- Add(' else');
- Add(' {');
- Add(' pf = pow(nDotHV, gl_FrontMaterial.shininess);');
- Add(' ');
- Add(' }');
- Add(' Ambient += gl_LightSource[i].ambient;');
- Add(' Diffuse += gl_LightSource[i].diffuse * nDotVP;');
- Add(' Specular += gl_LightSource[i].specular * pf;');
- Add('}');
- Add('void spotLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3)');
- Add('{');
- Add(' float nDotVP; // normal . light direction');
- Add(' float nDotHV; // normal . light half vector');
- Add(' float pf; // power factor');
- Add(' float spotDot; // cosine of angle between spotlight');
- Add(' float spotAttenuation; // spotlight attenuation factor');
- Add(' float attenuation; // computed attenuation factor');
- Add(' float d; // distance from surface to light source');
- Add(' vec3 VP; // direction from surface to light position');
- Add(' vec3 halfVector; // direction of maximum highlights');
- Add(' ');
- Add(' // Compute vector from surface to light position');
- Add(' VP = vec3 (gl_LightSource[i].position) - ecPosition3;');
- Add(' ');
- Add(' // Compute distance between surface and light position');
- Add(' d = length(VP);');
- Add(' ');
- Add(' // Normalize the vector from surface to light position');
- Add(' VP = normalize(VP);');
- Add(' ');
- Add(' // Compute attenuation');
- Add(' attenuation = 1.0 / (gl_LightSource[i].constantAttenuation +');
- Add(' gl_LightSource[i].linearAttenuation * d +');
- Add(' gl_LightSource[i].quadraticAttenuation * d * d);');
- Add(' ');
- Add(' // See if point on surface is inside cone of illumination');
- Add(' spotDot = dot(-VP, normalize(gl_LightSource[i].spotDirection));');
- Add(' ');
- Add(' if (spotDot < gl_LightSource[i].spotCosCutoff)');
- Add(' {');
- Add(' spotAttenuation = 0.0; // light adds no contribution');
- Add(' }');
- Add(' else');
- Add(' {');
- Add(' spotAttenuation = pow(spotDot, gl_LightSource[i].spotExponent);');
- Add(' ');
- Add(' }');
- Add(' // Combine the spotlight and distance attenuation.');
- Add(' attenuation *= spotAttenuation;');
- Add(' ');
- Add(' halfVector = normalize(VP + eye);');
- Add(' ');
- Add(' nDotVP = max(0.0, dot(normal, VP));');
- Add(' nDotHV = max(0.0, dot(normal, halfVector));');
- Add(' ');
- Add(' if (nDotVP == 0.0)');
- Add(' {');
- Add(' pf = 0.0;');
- Add(' }');
- Add(' else');
- Add(' {');
- Add(' pf = pow(nDotHV, gl_FrontMaterial.shininess);');
- Add(' ');
- Add(' }');
- Add(' Ambient += gl_LightSource[i].ambient * attenuation;');
- Add(' Diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation;');
- Add(' Specular += gl_LightSource[i].specular * pf * attenuation;');
- Add(' ');
- Add('}');
- Add('void infiniteSpotLight(in int i, in vec3 normal)');
- Add('{');
- Add(' float nDotVP; // normal . light direction');
- Add(' float nDotHV; // normal . light half vector');
- Add(' float pf; // power factor');
- Add(' float spotAttenuation;');
- Add(' vec3 Ppli;');
- Add(' vec3 Sdli;');
- Add(' ');
- Add(' nDotVP = max(0.0, dot(normal, normalize(vec3 (gl_LightSource[i].position))));');
- Add(' nDotHV = max(0.0, dot(normal, vec3 (gl_LightSource[i].halfVector)));');
- Add(' ');
- Add(' Ppli = -normalize(vec3(gl_LightSource[i].position));');
- Add(' Sdli = normalize(vec3(gl_LightSource[i].spotDirection));');
- Add(' ');
- Add(' spotAttenuation = pow(dot(Ppli, Sdli), gl_LightSource[i].spotExponent);');
- Add(' if (nDotVP == 0.0)');
- Add(' {');
- Add(' pf = 0.0;');
- Add(' }');
- Add(' else');
- Add(' {');
- Add(' pf = pow(nDotHV, gl_FrontMaterial.shininess);');
- Add(' ');
- Add(' }');
- Add(' Ambient += gl_LightSource[i].ambient * spotAttenuation;');
- Add(' Diffuse += gl_LightSource[i].diffuse * nDotVP * spotAttenuation;');
- Add(' Specular += gl_LightSource[i].specular * pf * spotAttenuation;');
- Add('}');
- end;
- end;
- procedure GetMLFragmentProgramCodeMid(const Code: TStrings;
- const CurrentLight: Integer; AStyle: TgxLightStyle);
- begin
- with Code do
- begin
- case AStyle of
- lsOmni: Add(Format(' pointLight(%d, N, eye, Pos); ', [CurrentLight]));
- lsSpot: Add(Format(' spotLight(%d, N, eye, Pos); ', [CurrentLight]));
- lsParallel: Add(Format(' directionalLight(%d, N); ', [CurrentLight]));
- lsParallelSpot: Add(Format(' infiniteSpotLight(%d, N); ', [CurrentLight]));
- end;
- end;
- end;
- procedure GetFragmentProgramCode(const Code: TStrings;
- const ARealisticSpecular: Boolean; const AFogSupport: Boolean;
- aRci: TgxRenderContextInfo);
- var
- scene: TgxScene;
- begin
- with Code do
- begin
- Clear;
- Add('uniform float LightIntensity; ');
- Add('uniform sampler2D MainTexture; ');
- Add(' ');
- Add('varying vec3 Normal; ');
- Add('varying vec4 Position; ');
- if AFogSupport then
- begin
- Add('varying float fogFactor; ');
- end;
- Add('vec4 Ambient;');
- Add('vec4 Diffuse;');
- Add('vec4 Specular;');
- AddLightSub(Code);
- Add('void main(void) ');
- Add('{ ');
- Add(' vec4 TextureContrib = texture2D(MainTexture, gl_TexCoord[0].xy); ');
- Add(' vec3 eye = vec3(0.0, 0.0, 1.0); ');
- Add(' Diffuse = vec4(0.0); ');
- Add(' Specular = vec4(0.0); ');
- Add(' Ambient = vec4(0.0); ');
- Add(' vec3 Pos = Position.xyz; ');
- Add(' vec3 N = normalize(Normal); ');
- scene := TgxScene(ARci.scene);
- if (scene.Lights.Count > 0) then
- GetMLFragmentProgramCodeMid(Code, 0,
- TgxLightSource(scene.Lights[0]).LightStyle);
- if ARealisticSpecular then
- Add(' gl_FragColor = LightIntensity * (TextureContrib * (gl_FrontLightModelProduct.sceneColor + Ambient * gl_FrontMaterial.ambient + Diffuse * gl_FrontMaterial.diffuse) + Specular * gl_FrontMaterial.specular); ')
- else
- Add(' gl_FragColor = LightIntensity * TextureContrib * (gl_FrontLightModelProduct.sceneColor + Ambient * gl_FrontMaterial.ambient + Diffuse * gl_FrontMaterial.diffuse + Specular * gl_FrontMaterial.specular); ');
- if AFogSupport then
- Add(' gl_FragColor = mix(gl_Fog.color, gl_FragColor, fogFactor);');
- Add(' gl_FragColor.a = TextureContrib.a; ');
- Add('} ');
- end;
- end;
- procedure GetMLFragmentProgramCodeBeg(const Code: TStrings;
- const AFogSupport: Boolean);
- begin
- with Code do
- begin
- Clear;
- Add('uniform sampler2D MainTexture;');
- Add('uniform float LightIntensity; ');
- Add('uniform float SpecPower; ');
- Add('varying vec3 Normal;');
- Add('varying vec4 Position;');
- if AFogSupport then
- begin
- Add('varying float fogFactor;');
- end;
- Add('vec4 Ambient;');
- Add('vec4 Diffuse;');
- Add('vec4 Specular;');
- AddLightSub(Code);
- Add('void main(void) ');
- Add('{ ');
- Add(' vec4 TextureContrib = texture2D(MainTexture, gl_TexCoord[0].st); ');
- Add(' vec3 eye = vec3(0.0, 0.0, 1.0); ');
- Add(' Diffuse = vec4(0.0); ');
- Add(' Specular = vec4(0.0); ');
- Add(' Ambient = vec4(0.0); ');
- Add(' vec3 Pos = Position.xyz; ');
- Add(' vec3 N = normalize(Normal); ');
- end;
- end;
- procedure GetMLFragmentProgramCodeEnd(const Code: TStrings;
- const ARealisticSpecular: Boolean;
- AFogSupport: Boolean);
- begin
- with Code do
- begin
- if ARealisticSpecular then
- Add(' gl_FragColor = LightIntensity * (TextureContrib * (gl_FrontLightModelProduct.sceneColor + Ambient * gl_FrontMaterial.ambient + Diffuse * gl_FrontMaterial.diffuse) + Specular * gl_FrontMaterial.specular); ')
- else
- Add(' gl_FragColor = LightIntensity * TextureContrib * (gl_FrontLightModelProduct.sceneColor + Ambient * gl_FrontMaterial.ambient + Diffuse * gl_FrontMaterial.diffuse + Specular * gl_FrontMaterial.specular); ');
- if AFogSupport then
- Add(' gl_FragColor = mix(gl_Fog.color, gl_FragColor, fogFactor);');
- Add(' gl_FragColor.a = TextureContrib.a; ');
- Add('} ');
- end;
- end;
- { TgxBaseCustomGLSLDiffuseSpecular }
- constructor TgxBaseCustomGLSLDiffuseSpecular.Create(
- AOwner: TComponent);
- begin
- inherited;
- FLightPower := 1;
- FFogSupport := sfsAuto;
- TStringList(VertexProgram.Code).OnChange := nil;
- TStringList(FragmentProgram.Code).OnChange := nil;
- VertexProgram.Enabled := true;
- FragmentProgram.Enabled := true;
- end;
- procedure TgxBaseCustomGLSLDiffuseSpecular.DoApply(
- var rci: TgxRenderContextInfo; Sender: TObject);
- begin
- GetGXSLProg.UseProgramObject;
- Param['LightIntensity'].AsVector1f := FLightPower;
- end;
- function TgxBaseCustomGLSLDiffuseSpecular.DoUnApply(
- var rci: TgxRenderContextInfo): Boolean;
- begin
- Result := False;
- GetGXSLProg.EndUseProgramObject;
- end;
- procedure TgxBaseCustomGLSLDiffuseSpecular.SetFogSupport(
- const Value: TgxShaderFogSupport);
- begin
- if FFogSupport <> Value then
- begin
- FFogSupport := Value;
- Self.FinalizeShader;
- end;
- end;
- procedure TgxBaseCustomGLSLDiffuseSpecular.SetRealisticSpecular(
- const Value: Boolean);
- begin
- if FRealisticSpecular <> Value then
- begin
- FRealisticSpecular := Value;
- Self.FinalizeShader;
- end;
- end;
- { TgxBaseGLSLDiffuseSpecularShaderMT }
- procedure TgxBaseGLSLDiffuseSpecularShaderMT.DoApply(
- var rci: TgxRenderContextInfo; Sender: TObject);
- begin
- inherited;
- Param['MainTexture'].AsTexture2D[0] := FMainTexture;
- end;
- function TgxBaseGLSLDiffuseSpecularShaderMT.GetMainTextureName: TgxLibMaterialName;
- begin
- Result := FMaterialLibrary.GetNameOfTexture(FMainTexture);
- end;
- function TgxBaseGLSLDiffuseSpecularShaderMT.GetMaterialLibrary: TgxAbstractMaterialLibrary;
- begin
- Result := FMaterialLibrary;
- end;
- procedure TgxBaseGLSLDiffuseSpecularShaderMT.Notification(
- AComponent: TComponent; Operation: TOperation);
- var
- Index: Integer;
- begin
- inherited;
- if Operation = opRemove then
- if AComponent = FMaterialLibrary then
- if FMaterialLibrary <> nil then
- begin
- //need to nil the textures that were ownned by it
- if FMainTexture <> nil then
- begin
- Index := FMaterialLibrary.Materials.GetTextureIndex(FMainTexture);
- if Index <> -1 then
- FMainTexture := nil;
- end;
- FMaterialLibrary := nil;
- end;
- end;
- procedure TgxBaseGLSLDiffuseSpecularShaderMT.SetMainTextureName(
- const Value: TgxLibMaterialName);
- begin
- if FMaterialLibrary = nil then
- begin
- FMainTextureName := Value;
- if not (csLoading in ComponentState) then
- raise EgxslDiffuseSpecularShaderException.Create(strErrorEx + strMatLibNotDefined);
- end
- else
- begin
- FMainTexture := FMaterialLibrary.TextureByName(Value);
- FMainTextureName := '';
- end;
- end;
- procedure TgxBaseGLSLDiffuseSpecularShaderMT.SetMaterialLibrary(
- const Value: TgxMaterialLibrary);
- begin
- if FMaterialLibrary <> nil then
- FMaterialLibrary.RemoveFreeNotification(Self);
- FMaterialLibrary := Value;
- if FMaterialLibrary <> nil then
- begin
- FMaterialLibrary.FreeNotification(Self);
- if FMainTextureName <> '' then
- SetMainTextureName(FMainTextureName);
- end
- else
- FMainTextureName := '';
- end;
- { TgxCustomGLSLDiffuseSpecularShaderMT }
- procedure TgxCustomGLSLDiffuseSpecularShaderMT.DoInitialize(var rci: TgxRenderContextInfo; Sender: TObject);
- begin
- GetVertexProgramCode(VertexProgram.Code, IsFogEnabled(FFogSupport, rci), rci);
- GetFragmentProgramCode(FragmentProgram.Code, FRealisticSpecular, IsFogEnabled(FFogSupport, rci), rci);
- VertexProgram.Enabled := True;
- FragmentProgram.Enabled := True;
- inherited;
- end;
- { TgxCustomGLSLDiffuseSpecularShader }
- procedure TgxCustomGLSLDiffuseSpecularShader.DoApply(
- var rci: TgxRenderContextInfo; Sender: TObject);
- begin
- inherited;
- Param['MainTexture'].AsVector1i := 0; // Use the current texture.
- end;
- procedure TgxCustomGLSLDiffuseSpecularShader.DoInitialize(var rci: TgxRenderContextInfo; Sender: TObject);
- begin
- GetVertexProgramCode(VertexProgram.Code, IsFogEnabled(FFogSupport, rci), rci);
- GetFragmentProgramCode(FragmentProgram.Code, FRealisticSpecular, IsFogEnabled(FFogSupport, rci), rci);
- VertexProgram.Enabled := True;
- FragmentProgram.Enabled := True;
- inherited;
- end;
- { TgxCustomGLSLMLDiffuseSpecularShader }
- constructor TgxCustomGLSLMLDiffuseSpecularShader.Create(
- AOwner: TComponent);
- begin
- inherited;
- end;
- procedure TgxCustomGLSLMLDiffuseSpecularShader.DoApply(var rci: TgxRenderContextInfo; Sender: TObject);
- var
- I: Integer;
- scene: TgxScene;
- needRecompile: Boolean;
- begin
- scene := TgxScene(rci.scene);
- needRecompile := False;
- for I := 0 to scene.Lights.Count - 1 do
- begin
- if Assigned(scene.Lights[I]) then
- begin
- if FLightTrace[I].Enabled <> TgxLightSource(scene.Lights[I]).Shining then
- begin
- needRecompile := True;
- break;
- end;
- if FLightTrace[I].Style <> TgxLightSource(scene.Lights[I]).LightStyle then
- begin
- needRecompile := True;
- break;
- end;
- end
- else
- if FLightTrace[I].Enabled then
- begin
- needRecompile := True;
- break;
- end;
- end;
- if needRecompile then
- begin
- FinalizeShader;
- InitializeShader(rci, Sender);
- end;
- inherited;
- Param['MainTexture'].AsVector1i := 0; // Use the current texture.
- end;
- procedure TgxCustomGLSLMLDiffuseSpecularShader.DoInitialize(var rci: TgxRenderContextInfo; Sender: TObject);
- var
- I: Integer;
- scene: TgxScene;
- begin
- GetVertexProgramCode(VertexProgram.Code, IsFogEnabled(FFogSupport, rci), rci);
- with FragmentProgram.Code do
- begin
- GetMLFragmentProgramCodeBeg(FragmentProgram.Code, IsFogEnabled(FFogSupport, rci));
- // Repeat for all lights.
- scene := TgxScene(rci.scene);
- for I := 0 to scene.Lights.Count - 1 do
- begin
- if Assigned(scene.Lights[I]) then
- begin
- FLightTrace[I].Enabled := TgxLightSource(scene.Lights[I]).Shining;
- FLightTrace[I].Style := TgxLightSource(scene.Lights[I]).LightStyle;
- if FLightTrace[I].Enabled then
- GetMLFragmentProgramCodeMid(FragmentProgram.Code, I, FLightTrace[I].Style);
- end
- else
- FLightTrace[I].Enabled := False;
- end;
- GetMLFragmentProgramCodeEnd(FragmentProgram.Code,
- FRealisticSpecular, IsFogEnabled(FFogSupport, rci));
- end;
- VertexProgram.Enabled := True;
- FragmentProgram.Enabled := True;
- inherited DoInitialize(rci, Sender);
- end;
- { TgxCustomGLSLMLDiffuseSpecularShaderMT }
- constructor TgxCustomGLSLMLDiffuseSpecularShaderMT.Create(
- AOwner: TComponent);
- begin
- inherited;
- end;
- procedure TgxCustomGLSLMLDiffuseSpecularShaderMT.DoApply(
- var rci: TgxRenderContextInfo; Sender: TObject);
- var
- I: Integer;
- scene: TgxScene;
- needRecompile: Boolean;
- begin
- scene := TgxScene(rci.scene);
- needRecompile := False;
- for I := 0 to scene.Lights.Count - 1 do
- begin
- if Assigned(scene.Lights[I]) then
- begin
- if FLightTrace[I].Enabled <> TgxLightSource(scene.Lights[I]).Shining then
- begin
- needRecompile := True;
- break;
- end;
- if FLightTrace[I].Style <> TgxLightSource(scene.Lights[I]).LightStyle then
- begin
- needRecompile := True;
- break;
- end;
- end
- else
- if FLightTrace[I].Enabled then
- begin
- needRecompile := True;
- break;
- end;
- end;
- if needRecompile then
- begin
- FinalizeShader;
- InitializeShader(rci, Sender);
- end;
- inherited;
- end;
- procedure TgxCustomGLSLMLDiffuseSpecularShaderMT.DoInitialize(var rci: TgxRenderContextInfo; Sender: TObject);
- var
- I: Integer;
- scene: TgxScene;
- begin
- GetVertexProgramCode(VertexProgram.Code, IsFogEnabled(FFogSupport, rci), rci);
- with FragmentProgram.Code do
- begin
- GetMLFragmentProgramCodeBeg(FragmentProgram.Code, IsFogEnabled(FFogSupport, rci));
- // Repeat for all lights.
- scene := TgxScene(rci.scene);
- for I := 0 to scene.Lights.Count - 1 do
- begin
- if Assigned(scene.Lights[I]) then
- begin
- FLightTrace[I].Enabled := TgxLightSource(scene.Lights[I]).Shining;
- FLightTrace[I].Style := TgxLightSource(scene.Lights[I]).LightStyle;
- if FLightTrace[I].Enabled then
- GetMLFragmentProgramCodeMid(FragmentProgram.Code, I, FLightTrace[I].Style);
- end
- else
- FLightTrace[I].Enabled := False;
- end;
- GetMLFragmentProgramCodeEnd(FragmentProgram.Code,
- FRealisticSpecular, IsFogEnabled(FFogSupport, rci));
- end;
- VertexProgram.Enabled := True;
- FragmentProgram.Enabled := True;
- inherited;
- end;
- initialization
- RegisterClasses([
- TgxCustomGLSLDiffuseSpecularShader,
- TgxCustomGLSLDiffuseSpecularShaderMT,
- TgxCustomGLSLMLDiffuseSpecularShader,
- TgxCustomGLSLMLDiffuseSpecularShaderMT,
- TgxSLDiffuseSpecularShader,
- TgxSLDiffuseSpecularShaderMT,
- TgxSLMLDiffuseSpecularShader,
- TgxSLMLDiffuseSpecularShaderMT
- ]);
- end.
|