| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928 |
- //
- // The graphics engine GLScene https://github.com/glscene
- //
- unit GLSL.BumpShaders;
- (*
- A GLSL shader that applies bump mapping.
- This is a collection of GLSL Bump shaders, comes in these variaties
- (to know what these abriviations mean, see GLCustomShader.pas):
- - TGLSLBumpShader
- - TGLSLBumpShaderMT
- - TGLSLBumpShaderAM
- - TGLSLMLBumpShader
- - TGLSLMLBumpShaderMT
- Notes:
- 1) Alpha is a synthetic property, in real life your should set each
- color's Alpha individualy
- 2) TGLSLMLBumpShader takes all Light parameters directly
- from OpenGL (that includes TGLLightSource's)
- TODO:
- 1) Implement IGLShaderDescription in all shaders.
- *)
- interface
- uses
- Winapi.OpenGL,
- Winapi.OpenGLext,
- System.Classes,
- System.SysUtils,
- GLScene.OpenGLTokens,
- GLScene.VectorTypes,
- GLScene.VectorGeometry,
- GLS.Material,
- GLS.Graphics,
- GLScene.VectorLists,
- GLS.Color,
- GLS.RenderContextInfo,
- GLS.State,
- GLScene.TextureFormat,
- GLS.Texture,
- GLS.Scene,
- GLS.Context,
- GLS.Cadencer,
- GLScene.Strings,
- GLSL.Shader,
- GLSL.CustomShader,
- GLScene.Utils;
- type
- TBumpMethod = (bmDot3TexCombiner, bmBasicARBFP);
- TBumpSpace = (bsObject, bsTangentExternal, bsTangentQuaternion);
- TBumpOption = (boDiffuseTexture2, // Use secondary texture as diffuse
- boSpecularTexture3, // Use tertiary texture as specular
- boUseSecondaryTexCoords, // Pass through secondary texcoords
- boLightAttenuation, // Use light attenuation
- boParallaxMapping // Enable parallax offset mapping
- );
- TBumpOptions = set of TBumpOption;
- TSpecularMode = (smOff, smBlinn, smPhong);
- EGLSLBumpShaderException = class(EGLSLShaderException);
- // An abstract class.
- TGLBaseCustomGLSLBumpShader = class(TGLCustomGLSLShader, IGLMaterialLibrarySupported)
- private
- FBumpHeight: Single;
- FBumpSmoothness: Integer;
- FSpecularPower: Single;
- FSpecularSpread: Single;
- FLightPower: Single;
- FMaterialLibrary: TGLMaterialLibrary;
- FNormalTexture: TGLTexture;
- FSpecularTexture: TGLTexture;
- FNormalTextureName: TGLLibMaterialName;
- FSpecularTextureName: TGLLibMaterialName;
- function GetNormalTextureName: TGLLibMaterialName;
- function GetSpecularTextureName: TGLLibMaterialName;
- procedure SetNormalTextureName(const Value: TGLLibMaterialName);
- procedure SetSpecularTextureName(const Value: TGLLibMaterialName);
- procedure SetSpecularTexture(const Value: TGLTexture);
- procedure SetNormalTexture(const Value: TGLTexture);
- // Implementing IGLMaterialLibrarySupported.
- function GetMaterialLibrary: TGLAbstractMaterialLibrary;
- protected
- procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
- function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
- procedure SetMaterialLibrary(const Value: TGLMaterialLibrary); virtual;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- public
- constructor Create(AOwner : TComponent); override;
- property BumpHeight: Single read FBumpHeight write FBumpHeight;
- property BumpSmoothness: Integer read FBumpSmoothness write FBumpSmoothness;
- property SpecularPower: Single read FSpecularPower write FSpecularPower;
- property SpecularSpread: Single read FSpecularSpread write FSpecularSpread;
- property LightPower: Single read FLightPower write FLightPower;
- property NormalTexture: TGLTexture read FNormalTexture write SetNormalTexture;
- property SpecularTexture: TGLTexture read FSpecularTexture write SetSpecularTexture;
- property NormalTextureName: TGLLibMaterialName read GetNormalTextureName write SetNormalTextureName;
- property SpecularTextureName: TGLLibMaterialName read GetSpecularTextureName write SetSpecularTextureName;
- property MaterialLibrary: TGLMaterialLibrary read FMaterialLibrary write SetMaterialLibrary;
- end;
- // An abstract class.
- TGLBaseCustomGLSLBumpShaderMT = class(TGLBaseCustomGLSLBumpShader)
- private
- FMainTexture: TGLTexture;
- FMainTextureName: TGLLibMaterialName;
- function GetMainTextureName: string;
- procedure SetMainTextureName(const Value: string);
- protected
- procedure SetMaterialLibrary(const Value: TGLMaterialLibrary); override;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- public
- property MainTexture: TGLTexture read FMainTexture write FMainTexture;
- property MainTextureName: TGLLibMaterialName read GetMainTextureName write SetMainTextureName;
- end;
- // One Light shaders.
- TGLCustomGLSLBumpShaderAM = class(TGLBaseCustomGLSLBumpShaderMT)
- private
- FAmbientColor: TGLColor;
- FDiffuseColor: TGLColor;
- FSpecularColor: TGLColor;
- function GetAlpha: Single;
- procedure SetAlpha(const Value: Single);
- protected
- procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
- procedure DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject); override;
- public
- constructor Create(AOwner : TComponent); override;
- destructor Destroy; override;
- property AmbientColor: TGLColor read FAmbientColor;
- property DiffuseColor: TGLColor read FDiffuseColor;
- property SpecularColor: TGLColor read FSpecularColor;
- property Alpha: Single read GetAlpha write SetAlpha;
- end;
- TGLCustomGLSLBumpShaderMT = class(TGLBaseCustomGLSLBumpShaderMT)
- protected
- procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
- procedure DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject); override;
- end;
- TGLCustomGLSLBumpShader = class(TGLBaseCustomGLSLBumpShader, IGLShaderDescription)
- private
- // Implementing IGLShaderDescription.
- procedure SetShaderTextures(const Textures: array of TGLTexture);
- procedure GetShaderTextures(var Textures: array of TGLTexture);
- procedure SetShaderColorParams(const AAmbientColor, ADiffuseColor, ASpecularcolor: TVector4f);
- procedure GetShaderColorParams(var AAmbientColor, ADiffuseColor, ASpecularcolor: TVector4f);
- procedure SetShaderMiscParameters(const ACadencer: TGLCadencer; const AMatLib: TGLMaterialLibrary; const ALightSources: TGLLightSourceSet);
- procedure GetShaderMiscParameters(var ACadencer: TGLCadencer; var AMatLib: TGLMaterialLibrary; var ALightSources: TGLLightSourceSet);
- function GetShaderAlpha: Single;
- procedure SetShaderAlpha(const Value: Single);
- function GetShaderDescription: string;
- protected
- procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
- procedure DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject); override;
- end;
- // MultiLight shaders.
- TGLCustomGLSLMLBumpShader = class(TGLBaseCustomGLSLBumpShader, IGLShaderDescription)
- private
- FLightSources: TGLLightSourceSet;
- FLightCompensation: Single;
- procedure SetLightSources(const Value: TGLLightSourceSet);
- procedure SetLightCompensation(const Value: Single);
- // Implementing IGLShaderDescription.
- procedure SetShaderTextures(const Textures: array of TGLTexture);
- procedure GetShaderTextures(var Textures: array of TGLTexture);
- procedure SetShaderColorParams(const AAmbientColor, ADiffuseColor, ASpecularcolor: TVector4f);
- procedure GetShaderColorParams(var AAmbientColor, ADiffuseColor, ASpecularcolor: TVector4f);
- procedure SetShaderMiscParameters(const ACadencer: TGLCadencer; const AMatLib: TGLMaterialLibrary; const ALightSources: TGLLightSourceSet);
- procedure GetShaderMiscParameters(var ACadencer: TGLCadencer; var AMatLib: TGLMaterialLibrary; var ALightSources: TGLLightSourceSet);
- function GetShaderAlpha: Single;
- procedure SetShaderAlpha(const Value: Single);
- function GetShaderDescription: string;
- protected
- procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
- procedure DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject); override;
- public
- constructor Create(AOwner : TComponent); override;
- property LightSources: TGLLightSourceSet read FLightSources write SetLightSources default [1];
- {Setting LightCompensation to a value less than 1 decreeses individual
- light intensity when using multiple lights }
- property LightCompensation: Single read FLightCompensation write SetLightCompensation;
- end;
- TGLCustomGLSLMLBumpShaderMT = class(TGLBaseCustomGLSLBumpShaderMT)
- private
- FLightSources: TGLLightSourceSet;
- FLightCompensation: Single;
- procedure SetLightSources(const Value: TGLLightSourceSet);
- procedure SetLightCompensation(const Value: Single);
- protected
- procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
- procedure DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject); override;
- public
- constructor Create(AOwner : TComponent); override;
- property LightSources: TGLLightSourceSet read FLightSources write SetLightSources default [1];
- (* Setting LightCompensation to a value less than 1 decreeses individual
- light intensity when using multiple lights *)
- property LightCompensation: Single read FLightCompensation write SetLightCompensation;
- end;
- {************** Published **************}
- // One light shaders.
- TGLSLBumpShaderMT = class(TGLCustomGLSLBumpShaderMT)
- published
- property MainTextureName;
- property NormalTextureName;
- property SpecularTextureName;
- property MaterialLibrary;
- property BumpHeight;
- property BumpSmoothness;
- property SpecularPower;
- property SpecularSpread;
- property LightPower;
- end;
- TGLSLBumpShader = class(TGLCustomGLSLBumpShader)
- published
- property NormalTextureName;
- property SpecularTextureName;
- property MaterialLibrary;
- property BumpHeight;
- property BumpSmoothness;
- property SpecularPower;
- property SpecularSpread;
- property LightPower;
- end;
- TGLSLBumpShaderAM = class(TGLCustomGLSLBumpShaderAM)
- published
- property AmbientColor;
- property DiffuseColor;
- property SpecularColor;
- property Alpha stored False;
- property MainTextureName;
- property NormalTextureName;
- property SpecularTextureName;
- property MaterialLibrary;
- property BumpHeight;
- property BumpSmoothness;
- property SpecularPower;
- property SpecularSpread;
- property LightPower;
- end;
- // Multi light shaders.
- TGLSLMLBumpShader = class(TGLCustomGLSLMLBumpShader)
- published
- property NormalTextureName;
- property SpecularTextureName;
- property MaterialLibrary;
- property BumpHeight;
- property BumpSmoothness;
- property SpecularPower;
- property SpecularSpread;
- property LightPower;
- property LightSources;
- property LightCompensation;
- end;
- TGLSLMLBumpShaderMT = class(TGLCustomGLSLMLBumpShaderMT)
- published
- property MainTextureName;
- property NormalTextureName;
- property SpecularTextureName;
- property MaterialLibrary;
- property BumpHeight;
- property BumpSmoothness;
- property SpecularPower;
- property SpecularSpread;
- property LightPower;
- property LightSources;
- property LightCompensation;
- end;
- (*
- A shader that applies bump mapping.
- Notes:
- The normal map is expected to be the primary texture.
- The secondary texture is used for the diffuse texture,
- to enable set boDiffuseTexture2 in the BumpOptions property.
- The tertiary texture is used for the specular texture,
- to enable set boSpecularTexture3 in the BumpOptions property.
- The SpecularMode determines the specular highlight calculation
- (Blinn or Phong), smOff disables specular highlights in the
- shader.
- External tangent bump space expects tangent data under
- GL_TEXTURE1_ARB and binormal data under GL_TEXTURE2_ARB.
- The boUseSecondaryTexCoords bump option tells the shader to use
- the secondary texture coordinates for the diffuse and specular
- texture lookups.
- *)
- // A generic bump shader.
- TGLBumpShader = class(TGLShader)
- private
- FVertexProgramHandle: TGLARBVertexProgramHandle;
- FFragmentProgramHandle: TGLARBFragmentProgramHandle;
- FLightIDs: TGIntegerList;
- FLightsEnabled: Integer;
- FBumpMethod: TBumpMethod;
- FBumpSpace: TBumpSpace;
- FBumpOptions: TBumpOptions;
- FSpecularMode: TSpecularMode;
- FDesignTimeEnabled: Boolean;
- FAmbientPass: Boolean;
- FDiffusePass: Boolean;
- FVertexProgram: TStringList;
- FFragmentProgram: TStringList;
- FParallaxOffset: Single;
- function GenerateVertexProgram: string;
- function GenerateFragmentProgram: string;
- procedure DoLightPass(var rci: TGLRenderContextInfo; lightID: Cardinal);
- protected
- procedure SetBumpMethod(const Value: TBumpMethod);
- procedure SetBumpSpace(const Value: TBumpSpace);
- procedure SetBumpOptions(const Value: TBumpOptions);
- procedure SetSpecularMode(const Value: TSpecularMode);
- procedure SetDesignTimeEnabled(const Value: Boolean);
- procedure SetParallaxOffset(const Value: Single);
- procedure Loaded; override;
- procedure DeleteVertexPrograms;
- procedure DeleteFragmentPrograms;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
- function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
- published
- property BumpMethod: TBumpMethod read FBumpMethod write SetBumpMethod;
- property BumpSpace: TBumpSpace read FBumpSpace write SetBumpSpace;
- property BumpOptions: TBumpOptions read FBumpOptions write SetBumpOptions;
- property SpecularMode: TSpecularMode read FSpecularMode write
- SetSpecularMode;
- property DesignTimeEnabled: Boolean read FDesignTimeEnabled write
- SetDesignTimeEnabled;
- property ParallaxOffset: Single read FParallaxOffset write
- SetParallaxOffset;
- end;
- //--------------------------------------------------------------
- implementation
- //--------------------------------------------------------------
- procedure GetVertexProgramCode(const Code: TStrings);
- begin
- with Code do
- begin
- Clear;
- Add('varying vec2 Texcoord; ');
- Add('varying vec3 ViewDirection; ');
- Add('varying vec3 LightDirection; ');
- Add(' ');
- Add('void main( void ) ');
- Add('{ ');
- Add(' gl_Position = ftransform(); ');
- Add(' Texcoord = gl_MultiTexCoord0.xy; ');
- Add(' ');
- Add(' vec3 fvViewDirection = (gl_ModelViewMatrix * gl_Vertex).xyz; ');
- Add(' vec3 fvLightDirection = gl_LightSource[0].position.xyz - fvViewDirection; ');
- Add(' ');
- Add(' vec3 fvNormal = gl_NormalMatrix * gl_Normal; ');
- Add(' vec3 fvBinormal = gl_NormalMatrix * gl_MultiTexCoord2.xyz; ');
- Add(' vec3 fvTangent = gl_NormalMatrix * gl_MultiTexCoord1.xyz; ');
- Add(' ');
- Add(' ViewDirection.x = dot( fvTangent, fvViewDirection ); ');
- Add(' ViewDirection.y = dot( fvBinormal, fvViewDirection ); ');
- Add(' ViewDirection.z = dot( fvNormal, fvViewDirection ); ');
- Add(' ');
- Add(' LightDirection.x = dot( fvTangent, fvLightDirection ); ');
- Add(' LightDirection.y = dot( fvBinormal, fvLightDirection ); ');
- Add(' LightDirection.z = dot( fvNormal, fvLightDirection ); ');
- Add(' ');
- Add(' LightDirection = normalize(LightDirection); ');
- Add(' ViewDirection = normalize(ViewDirection); ');
- Add('} ');
- end;
- end;
- procedure GetFragmentProgramCodeMP(const Code: TStrings; const UseSpecularMap: Boolean; const UseNormalMap: Boolean);
- begin
- with Code do
- begin
- Clear;
- Add('uniform vec4 fvAmbient; ');
- Add('uniform vec4 fvSpecular; ');
- Add('uniform vec4 fvDiffuse; ');
- Add(' ');
- Add('uniform float fLightPower; ');
- Add('uniform float fSpecularPower; ');
- Add('uniform float fSpecularSpread; ');
- if UseNormalMap then
- begin
- Add('uniform sampler2D bumpMap; ');
- Add('uniform float fBumpHeight; ');
- Add('uniform float fBumpSmoothness; ');
- end;
- Add(' ');
- Add('uniform sampler2D baseMap; ');
- if UseSpecularMap then
- Add('uniform sampler2D specMap; ');
- Add(' ');
- Add('varying vec2 Texcoord; ');
- Add('varying vec3 ViewDirection; ');
- Add('varying vec3 LightDirection; ');
- Add(' ');
- Add('void main( void ) ');
- Add('{ ');
- if UseNormalMap then
- Add(' vec3 fvNormal = normalize( ( texture2D( bumpMap, Texcoord ).xyz * fBumpSmoothness) - fBumpHeight * fBumpSmoothness); ')
- else
- Add(' vec3 fvNormal = vec3(0.0, 0.0, 1);');
- Add(' ');
- Add(' float fNDotL = dot( fvNormal, LightDirection ); ');
- Add(' vec3 fvReflection = normalize( ( (fSpecularSpread * fvNormal ) * fNDotL ) - LightDirection ); ');
- Add(' ');
- Add(' float fRDotV = max( dot( fvReflection, -ViewDirection ), 0.0 ); ');
- Add(' ');
- Add(' vec4 fvBaseColor = texture2D( baseMap, Texcoord ); ');
- if UseSpecularMap then
- Add(' vec4 fvSpecColor = texture2D( specMap, Texcoord ) * fvSpecular; ')
- else
- Add(' vec4 fvSpecColor = fvSpecular; ');
- Add(' ');
- Add(' vec4 fvTotalDiffuse = clamp(fvDiffuse * fNDotL, 0.0, 1.0); ');
- Add(' ');
- Add(' // (fvTotalDiffuse + 0.2) / 1.2 is used for removing artefacts on the non-lit side ');
- Add(' vec4 fvTotalSpecular = clamp((pow(fRDotV, fSpecularPower ) ) * (fvTotalDiffuse + 0.2) / 1.2 * fvSpecColor, 0.0, 1.0); ');
- Add(' ');
- Add(' gl_FragColor = fLightPower * (fvBaseColor * ( fvAmbient + fvTotalDiffuse ) + fvTotalSpecular); ');
- Add('} ');
- end;
- end;
- procedure GetFragmentProgramCode(const Code: TStrings; const UseSpecularMap: Boolean; const UseNormalMap: Boolean);
- begin
- with Code do
- begin
- Clear;
- Add('uniform float fLightPower; ');
- Add('uniform float fSpecularPower; ');
- Add('uniform float fSpecularSpread; ');
- if UseNormalMap then
- begin
- Add('uniform sampler2D bumpMap; ');
- Add('uniform float fBumpHeight; ');
- Add('uniform float fBumpSmoothness; ');
- end;
- Add(' ');
- Add('uniform sampler2D baseMap; ');
- if UseSpecularMap then
- Add('uniform sampler2D specMap; ');
- Add(' ');
- Add('varying vec2 Texcoord; ');
- Add('varying vec3 ViewDirection; ');
- Add('varying vec3 LightDirection; ');
- Add(' ');
- Add('void main( void ) ');
- Add('{ ');
- if UseNormalMap then
- Add(' vec3 fvNormal = normalize( ( texture2D( bumpMap, Texcoord ).xyz * fBumpSmoothness) - fBumpHeight * fBumpSmoothness); ')
- else
- Add(' vec3 fvNormal = vec3(0.0, 0.0, 1.0);');
- Add(' ');
- Add(' float fNDotL = dot( fvNormal, LightDirection ); ');
- Add(' vec3 fvReflection = normalize( ( (fSpecularSpread * fvNormal ) * fNDotL ) - LightDirection ); ');
- Add(' ');
- Add(' float fRDotV = max(dot( fvReflection, -ViewDirection ), 0.0); ');
- Add(' ');
- Add(' vec4 fvBaseColor = texture2D( baseMap, Texcoord ); ');
- if UseSpecularMap then
- Add(' vec4 fvSpecColor = texture2D( specMap, Texcoord ) * gl_LightSource[0].specular; ')
- else
- Add(' vec4 fvSpecColor = gl_LightSource[0].specular; ');
- Add(' ');
- Add(' vec4 fvTotalDiffuse = clamp(gl_LightSource[0].diffuse * fNDotL, 0.0, 1.0); ');
- Add(' ');
- Add(' // (fvTotalDiffuse + 0.2) / 1.2 is used for removing artefacts on the non-lit side ');
- Add(' vec4 fvTotalSpecular = clamp((pow(fRDotV, fSpecularPower ) ) * (fvTotalDiffuse + 0.2) / 1.2 * fvSpecColor, 0.0, 1.0); ');
- Add(' ');
- Add(' gl_FragColor = fLightPower * (fvBaseColor * ( gl_LightSource[0].ambient + fvTotalDiffuse ) + fvTotalSpecular); ');
- Add('} ');
- end;
- end;
- procedure GetMLVertexProgramCode(const Code: TStrings);
- begin
- with Code do
- begin
- Clear;
- Add('varying vec2 Texcoord; ');
- Add('varying vec3 ViewDirection; ');
- Add(' ');
- Add('varying vec3 fvViewDirection; ');
- Add('varying vec3 fvNormal; ');
- Add('varying vec3 fvBinormal; ');
- Add('varying vec3 fvTangent; ');
- Add(' ');
- Add('void main( void ) ');
- Add('{ ');
- Add(' gl_Position = ftransform(); ');
- Add(' Texcoord = gl_MultiTexCoord0.xy; ');
- Add(' ');
- Add(' fvViewDirection = (gl_ModelViewMatrix * gl_Vertex).xyz; ');
- Add(' ');
- Add(' fvNormal = gl_NormalMatrix * gl_Normal; ');
- Add(' fvBinormal = gl_NormalMatrix * gl_MultiTexCoord2.xyz; ');
- Add(' fvTangent = gl_NormalMatrix * gl_MultiTexCoord1.xyz; ');
- Add(' ');
- Add(' ViewDirection.x = dot( fvTangent, fvViewDirection ); ');
- Add(' ViewDirection.y = dot( fvBinormal, fvViewDirection ); ');
- Add(' ViewDirection.z = dot( fvNormal, fvViewDirection ); ');
- Add(' ');
- Add(' ViewDirection = normalize(ViewDirection); ');
- Add('} ');
- end;
- end;
- procedure GetMLFragmentProgramCodeBeg(const Code: TStrings; const UseSpecularMap: Boolean; const UseNormalMap: Boolean);
- begin
- with Code do
- begin
- Clear;
- Add('uniform float fLightPower; ');
- Add('uniform float fSpecularPower; ');
- Add('uniform float fSpecularSpread; ');
- if UseNormalMap then
- begin
- Add('uniform sampler2D bumpMap; ');
- Add('uniform float fBumpHeight; ');
- Add('uniform float fBumpSmoothness; ');
- end;
- Add(' ');
- Add('uniform sampler2D baseMap; ');
- if UseSpecularMap then
- Add('uniform sampler2D specMap; ');
- Add(' ');
- Add('varying vec2 Texcoord; ');
- Add('varying vec3 ViewDirection; ');
- Add(' ');
- Add('varying vec3 fvViewDirection; ');
- Add('varying vec3 fvNormal; ');
- Add('varying vec3 fvBinormal; ');
- Add('varying vec3 fvTangent; ');
- Add(' ');
- Add('void main( void ) ');
- Add('{ ');
- Add(' vec3 LightDirection;');
- Add(' vec3 fvLightDirection; ');
- Add(' ');
- if UseNormalMap then
- Add(' vec3 fvBumpNormal = normalize( ( texture2D( bumpMap, Texcoord ).xyz * fBumpSmoothness) - fBumpHeight * fBumpSmoothness); ')
- else
- Add(' vec3 fvBumpNormal = vec3(0.0, 0.0, 1);');
- Add(' ');
- Add(' float fNDotL ; ');
- Add(' vec3 fvReflection ; ');
- Add(' float fRDotV ; ');
- Add(' vec4 fvBaseColor = texture2D( baseMap, Texcoord ); ');
- if UseSpecularMap then
- Add(' vec4 fvSpecColor = texture2D( specMap, Texcoord ); ')
- else
- Add(' vec4 fvSpecColor = vec4(1.0, 1.0, 1.0, 1.0); ');
- Add(' vec4 fvNewDiffuse ; ');
- Add(' vec4 fvTotalDiffuse = vec4(0, 0, 0, 0); ');
- Add(' vec4 fvTotalAmbient = vec4(0, 0, 0, 0); ');
- Add(' vec4 fvTotalSpecular = vec4(0, 0, 0, 0); ');
- end;
- end;
- procedure GetMLFragmentProgramCodeMid(const Code: TStrings; const CurrentLight: Integer);
- begin
- with Code do
- begin
- Add(' fvLightDirection = gl_LightSource[' + IntToStr(CurrentLight) + '].position.xyz - fvViewDirection; ');
- Add(' ');
- Add(' LightDirection.x = dot( fvTangent, fvLightDirection ); ');
- Add(' LightDirection.y = dot( fvBinormal, fvLightDirection ); ');
- Add(' LightDirection.z = dot( fvNormal, fvLightDirection ); ');
- Add(' LightDirection = normalize(LightDirection); ');
- Add(' ');
- Add(' fNDotL = dot( fvBumpNormal, LightDirection ); ');
- Add(' fvReflection = normalize( ( (fSpecularSpread * fvBumpNormal ) * fNDotL ) - LightDirection ); ');
- Add(' fRDotV = max( dot( fvReflection, -ViewDirection ), 0.0 ); ');
- Add(' fvNewDiffuse = clamp(gl_LightSource[' + IntToStr(CurrentLight) + '].diffuse * fNDotL, 0.0, 1.0); ');
- Add(' fvTotalDiffuse = min(fvTotalDiffuse + fvNewDiffuse, 1.0); ');
- Add(' fvTotalSpecular = min(fvTotalSpecular + clamp((pow(fRDotV, fSpecularPower ) ) * (fvNewDiffuse + 0.2) / 1.2 * (fvSpecColor * gl_LightSource[' + IntToStr(CurrentLight) + '].specular), 0.0, 1.0), 1.0); ');
- Add(' fvTotalAmbient = fvTotalAmbient + gl_LightSource[' + IntToStr(CurrentLight) + '].ambient; ');
- end;
- end;
- procedure GetMLFragmentProgramCodeEnd(const Code: TStrings; const FLightCount: Integer; const FLightCompensation: Single);
- var
- Temp: AnsiString;
- begin
- with Code do
- begin
- Str((1 + (FLightCount - 1) * FLightCompensation) / FLightCount :1 :1, Temp);
- if (FLightCount = 1) or (FLightCompensation = 1) then
- Add(' gl_FragColor = fLightPower * (fvBaseColor * ( fvTotalAmbient + fvTotalDiffuse ) + fvTotalSpecular); ')
- else
- Add(' gl_FragColor = fLightPower * (fvBaseColor * ( fvTotalAmbient + fvTotalDiffuse ) + fvTotalSpecular) * ' + string(Temp) + '; ');
- Add('} ');
- end;
- end;
- { TGLBaseCustomGLSLBumpShader }
- constructor TGLBaseCustomGLSLBumpShader.Create(AOwner: TComponent);
- begin
- inherited;
- FSpecularPower := 6;
- FSpecularSpread := 1.5;
- FLightPower := 1;
- FBumpHeight := 0.5;
- FBumpSmoothness := 300;
- TStringList(VertexProgram.Code).OnChange := nil;
- TStringList(FragmentProgram.Code).OnChange := nil;
- VertexProgram.Enabled := True;
- FragmentProgram.Enabled := True;
- end;
- procedure TGLBaseCustomGLSLBumpShader.DoApply(
- var rci: TGLRenderContextInfo; Sender: TObject);
- begin
- // Don't inherit not to call the event.
- GetGLSLProg.UseProgramObject;
- Param['fSpecularPower'].AsVector1f := FSpecularPower;
- Param['fSpecularSpread'].AsVector1f := FSpecularSpread;
- Param['fLightPower'].AsVector1f := FLightPower;
- if FSpecularTexture <> nil then
- Param['specMap'].AsTexture2D[2] := FSpecularTexture;
- {$IFNDEF USE_OPTIMIZATIONS}
- if FNormalTexture <> nil then
- {$ENDIF}
- begin
- Param['bumpMap'].AsTexture2D[1] := FNormalTexture;
- Param['fBumpHeight'].AsVector1f := FBumpHeight;
- Param['fBumpSmoothness'].AsVector1f := FBumpSmoothness;
- end;
- end;
- function TGLBaseCustomGLSLBumpShader.DoUnApply(
- var rci: TGLRenderContextInfo): Boolean;
- begin
- //don't inherit not to call the event
- Result := False;
- GetGLSLProg.EndUseProgramObject;
- end;
- function TGLBaseCustomGLSLBumpShader.GetMaterialLibrary: TGLAbstractMaterialLibrary;
- begin
- Result := FMaterialLibrary;
- end;
- function TGLBaseCustomGLSLBumpShader.GetNormalTextureName: TGLLibMaterialName;
- begin
- Result := FMaterialLibrary.GetNameOfTexture(FNormalTexture);
- if Result = '' then Result := FNormalTextureName;
- end;
- function TGLBaseCustomGLSLBumpShader.GetSpecularTextureName: TGLLibMaterialName;
- begin
- Result := FMaterialLibrary.GetNameOfTexture(FSpecularTexture);
- if Result = '' then Result := FSpecularTextureName;
- end;
- procedure TGLBaseCustomGLSLBumpShader.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 FNormalTexture <> nil then
- begin
- Index := FMaterialLibrary.Materials.GetTextureIndex(FNormalTexture);
- if Index <> -1 then
- SetNormalTexture(nil);
- end;
- if FSpecularTexture <> nil then
- begin
- Index := FMaterialLibrary.Materials.GetTextureIndex(FSpecularTexture);
- if Index <> -1 then
- SetSpecularTexture(nil);
- end;
- FMaterialLibrary := nil;
- end;
- end;
- procedure TGLBaseCustomGLSLBumpShader.SetMaterialLibrary(
- const Value: TGLMaterialLibrary);
- begin
- if FMaterialLibrary <> nil then
- FMaterialLibrary.RemoveFreeNotification(Self);
- FMaterialLibrary := Value;
- if FMaterialLibrary <> nil then
- begin
- FMaterialLibrary.FreeNotification(Self);
- if FNormalTextureName <> '' then
- SetNormalTextureName(FNormalTextureName);
- if FSpecularTextureName <> '' then
- SetSpecularTextureName(FSpecularTextureName);
- end
- else
- begin
- FNormalTextureName := '';
- FSpecularTextureName := '';
- end;
- end;
- procedure TGLBaseCustomGLSLBumpShader.SetNormalTexture(
- const Value: TGLTexture);
- begin
- FNormalTexture := Value;
- FinalizeShader;
- end;
- procedure TGLBaseCustomGLSLBumpShader.SetNormalTextureName(
- const Value: TGLLibMaterialName);
- begin
- if FMaterialLibrary = nil then
- begin
- FNormalTextureName := Value;
- if not (csLoading in ComponentState) then
- raise EGLSLBumpShaderException.Create(strErrorEx + strMatLibNotDefined);
- end
- else
- begin
- SetNormalTexture(FMaterialLibrary.TextureByName(Value));
- FNormalTextureName := '';
- end;
- end;
- procedure TGLBaseCustomGLSLBumpShader.SetSpecularTexture(
- const Value: TGLTexture);
- begin
- FSpecularTexture := Value;
- FinalizeShader;
- end;
- procedure TGLBaseCustomGLSLBumpShader.SetSpecularTextureName(
- const Value: TGLLibMaterialName);
- begin
- if FMaterialLibrary = nil then
- begin
- FSpecularTextureName := Value;
- if not (csLoading in ComponentState) then
- raise EGLSLBumpShaderException.Create(strErrorEx + strMatLibNotDefined);
- end
- else
- begin
- SetSpecularTexture(FMaterialLibrary.TextureByName(Value));
- FSpecularTextureName := '';
- end;
- end;
- { TGLBaseCustomGLSLBumpShaderMT }
- function TGLBaseCustomGLSLBumpShaderMT.GetMainTextureName: TGLLibMaterialName;
- begin
- Result := FMaterialLibrary.GetNameOfTexture(FMainTexture);
- if Result = '' then Result := FMainTextureName;
- end;
- procedure TGLBaseCustomGLSLBumpShaderMT.Notification(
- AComponent: TComponent; Operation: TOperation);
- var
- Index: Integer;
- begin
- 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;
- end;
- inherited;
- end;
- procedure TGLBaseCustomGLSLBumpShaderMT.SetMainTextureName(
- const Value: TGLLibMaterialName);
- begin
- if FMaterialLibrary = nil then
- begin
- FMainTextureName := Value;
- if not (csLoading in ComponentState) then
- raise EGLSLBumpShaderException.Create(strErrorEx + strMatLibNotDefined);
- end
- else
- begin
- FMainTexture := FMaterialLibrary.TextureByName(Value);
- FMainTextureName := '';
- end;
- end;
- procedure TGLBaseCustomGLSLBumpShaderMT.SetMaterialLibrary(
- const Value: TGLMaterialLibrary);
- begin
- inherited;
- if FMaterialLibrary <> nil then
- begin
- if FMainTextureName <> '' then
- SetMainTextureName(FMainTextureName);
- end
- else
- FMainTextureName := '';
- end;
- { TGLCustomGLSLBumpShaderAM }
- constructor TGLCustomGLSLBumpShaderAM.Create(AOwner: TComponent);
- begin
- inherited;
- FAmbientColor := TGLColor.Create(Self);
- FDiffuseColor := TGLColor.Create(Self);
- FSpecularColor := TGLColor.Create(Self);
- // Setup initial parameters.
- FAmbientColor.SetColor(0.15, 0.15, 0.15, 1);
- FDiffuseColor.SetColor(1, 1, 1, 1);
- FSpecularColor.SetColor(1, 1, 1, 1);
- end;
- destructor TGLCustomGLSLBumpShaderAM.Destroy;
- begin
- FAmbientColor.Destroy;
- FDiffuseColor.Destroy;
- FSpecularColor.Destroy;
- inherited;
- end;
- procedure TGLCustomGLSLBumpShaderAM.DoApply(var rci: TGLRenderContextInfo;
- Sender: TObject);
- begin
- inherited;
- Param['fvAmbient'].AsVector4f := FAmbientColor.Color;
- Param['fvDiffuse'].AsVector4f := FDiffuseColor.Color;
- Param['fvSpecular'].AsVector4f := FSpecularColor.Color;
- Param['baseMap'].AsTexture2D[0] := FMainTexture;
- end;
- procedure TGLCustomGLSLBumpShaderAM.DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject);
- begin
- GetVertexProgramCode(VertexProgram.Code);
- GetFragmentProgramCodeMP(FragmentProgram.Code, FSpecularTexture <> nil, FNormalTexture <> nil);
- VertexProgram.Enabled := True;
- FragmentProgram.Enabled := True;
- inherited;
- end;
- function TGLCustomGLSLBumpShaderAM.GetAlpha: Single;
- begin
- Result := (FAmbientColor.Alpha + FDiffuseColor.Alpha + FSpecularColor.Alpha) / 3;
- end;
- procedure TGLCustomGLSLBumpShaderAM.SetAlpha(const Value: Single);
- begin
- FAmbientColor.Alpha := Value;
- FDiffuseColor.Alpha := Value;
- FSpecularColor.Alpha := Value;
- end;
- { TGLCustomGLSLMLBumpShaderMT }
- constructor TGLCustomGLSLMLBumpShaderMT.Create(AOwner: TComponent);
- begin
- inherited;
- FLightSources := [1];
- FLightCompensation := 1;
- end;
- procedure TGLCustomGLSLMLBumpShaderMT.DoApply(var rci: TGLRenderContextInfo;
- Sender: TObject);
- begin
- inherited;
- Param['baseMap'].AsTexture2D[0] := FMainTexture;
- end;
- procedure TGLCustomGLSLMLBumpShaderMT.DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject);
- var
- I: Integer;
- lLightCount: Integer;
- begin
- GetMLVertexProgramCode(VertexProgram.Code);
-
- with FragmentProgram.Code do
- begin
- GetMLFragmentProgramCodeBeg(FragmentProgram.Code, FSpecularTexture <> nil, FNormalTexture <> nil);
- lLightCount := 0;
- // Repeat for all lights.
- for I := 0 to glsShaderMaxLightSources - 1 do
- if I + 1 in FLightSources then
- begin
- GetMLFragmentProgramCodeMid(FragmentProgram.Code, I);
- Inc(lLightCount);
- end;
- GetMLFragmentProgramCodeEnd(FragmentProgram.Code, lLightCount, FLightCompensation);
- end;
- VertexProgram.Enabled := True;
- FragmentProgram.Enabled := True;
- inherited;
- end;
- procedure TGLCustomGLSLMLBumpShaderMT.SetLightCompensation(
- const Value: Single);
- begin
- FLightCompensation := Value;
- FinalizeShader;
- end;
- procedure TGLCustomGLSLMLBumpShaderMT.SetLightSources(
- const Value: TGLLightSourceSet);
- begin
- Assert(Value <> [], strErrorEx + strShaderNeedsAtLeastOneLightSource);
- FLightSources := Value;
- FinalizeShader;
- end;
- { TGLCustomGLSLBumpShaderMT }
- procedure TGLCustomGLSLBumpShaderMT.DoApply(
- var rci: TGLRenderContextInfo; Sender: TObject);
- begin
- inherited;
- Param['baseMap'].AsTexture2D[0] := FMainTexture;
- end;
- procedure TGLCustomGLSLBumpShaderMT.DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject);
- begin
- GetVertexProgramCode(VertexProgram.Code);
- GetFragmentProgramCode(FragmentProgram.Code, FSpecularTexture <> nil, FNormalTexture <> nil);
- inherited;
- end;
- { TGLCustomGLSLBumpShader }
- procedure TGLCustomGLSLBumpShader.DoApply(var rci: TGLRenderContextInfo;
- Sender: TObject);
- begin
- inherited;
- Param['baseMap'].AsVector1i := 0; // Use the current texture.
- end;
- procedure TGLCustomGLSLBumpShader.DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject);
- begin
- GetVertexProgramCode(VertexProgram.Code);
- GetFragmentProgramCode(FragmentProgram.Code, FSpecularTexture <> nil, FNormalTexture <> nil);
- VertexProgram.Enabled := True;
- FragmentProgram.Enabled := True;
- inherited;
- end;
- function TGLCustomGLSLBumpShader.GetShaderAlpha: Single;
- begin
- //ignore
- Result := -1;
- end;
- procedure TGLCustomGLSLBumpShader.GetShaderColorParams(var AAmbientColor,
- ADiffuseColor, ASpecularcolor: TVector4f);
- begin
- //ignore
- AAmbientColor := NullHmgVector;
- ADiffuseColor := NullHmgVector;
- ASpecularcolor := NullHmgVector;
- end;
- procedure TGLCustomGLSLBumpShader.GetShaderTextures(
- var Textures: array of TGLTexture);
- begin
- Textures[0] := FNormalTexture;
- Textures[1] := FSpecularTexture;
- end;
- procedure TGLCustomGLSLBumpShader.GetShaderMiscParameters(var ACadencer: TGLCadencer;
- var AMatLib: TGLMaterialLibrary; var ALightSources: TGLLightSourceSet);
- begin
- ACadencer := nil;
- AMatLib := FMaterialLibrary;
- ALightSources := [0];
- end;
- procedure TGLCustomGLSLBumpShader.SetShaderAlpha(const Value: Single);
- begin
- //ignore
- end;
- procedure TGLCustomGLSLBumpShader.SetShaderColorParams(const AAmbientColor,
- ADiffuseColor, ASpecularcolor: TVector4f);
- begin
- //ignore
- end;
- procedure TGLCustomGLSLBumpShader.SetShaderMiscParameters(
- const ACadencer: TGLCadencer; const AMatLib: TGLMaterialLibrary;
- const ALightSources: TGLLightSourceSet);
- begin
- SetMaterialLibrary(AMatLib);
- end;
- procedure TGLCustomGLSLBumpShader.SetShaderTextures(
- const Textures: array of TGLTexture);
- begin
- SetNormalTexture(Textures[0]);
- SetSpecularTexture(Textures[1]);
- end;
- function TGLCustomGLSLBumpShader.GetShaderDescription: string;
- begin
- Result := 'ShaderTexture1 is NormalMap, ShaderTexture2 is SpecularMap'
- end;
- { TGLCustomGLSLMLBumpShader }
- constructor TGLCustomGLSLMLBumpShader.Create(AOwner: TComponent);
- begin
- inherited;
- FLightSources := [1];
- FLightCompensation := 1;
- end;
- procedure TGLCustomGLSLMLBumpShader.DoApply(var rci: TGLRenderContextInfo;
- Sender: TObject);
- begin
- inherited;
- Param['baseMap'].AsVector1i := 0; // Use the current texture.
- end;
- procedure TGLCustomGLSLMLBumpShader.DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject);
- var
- I: Integer;
- lLightCount: Integer;
- begin
- GetMLVertexProgramCode(VertexProgram.Code);
-
- with FragmentProgram.Code do
- begin
- GetMLFragmentProgramCodeBeg(FragmentProgram.Code, FSpecularTexture <> nil, FNormalTexture <> nil);
- lLightCount := 0;
- // Repeat for all lights.
- for I := 0 to glsShaderMaxLightSources - 1 do
- if I + 1 in FLightSources then
- begin
- GetMLFragmentProgramCodeMid(FragmentProgram.Code, I);
- Inc(lLightCount);
- end;
- GetMLFragmentProgramCodeEnd(FragmentProgram.Code, lLightCount, FLightCompensation);
- end;
- VertexProgram.Enabled := True;
- FragmentProgram.Enabled := True;
- inherited;
- end;
- procedure TGLCustomGLSLMLBumpShader.SetLightCompensation(
- const Value: Single);
- begin
- FLightCompensation := Value;
- FinalizeShader;
- end;
- procedure TGLCustomGLSLMLBumpShader.SetLightSources(
- const Value: TGLLightSourceSet);
- begin
- Assert(Value <> [], strErrorEx + strShaderNeedsAtLeastOneLightSource);
- FLightSources := Value;
- FinalizeShader;
- end;
- function TGLCustomGLSLMLBumpShader.GetShaderAlpha: Single;
- begin
- //ignore
- Result := -1;
- end;
- procedure TGLCustomGLSLMLBumpShader.GetShaderColorParams(var AAmbientColor,
- ADiffuseColor, ASpecularcolor: TVector4f);
- begin
- //ignore
- AAmbientColor := NullHmgVector;
- ADiffuseColor := NullHmgVector;
- ASpecularcolor := NullHmgVector;
- end;
- function TGLCustomGLSLMLBumpShader.GetShaderDescription: string;
- begin
- Result := 'ShaderTexture1 is NormalMap, ShaderTexture2 is SpecularMap';
- end;
- procedure TGLCustomGLSLMLBumpShader.GetShaderMiscParameters(
- var ACadencer: TGLCadencer; var AMatLib: TGLMaterialLibrary;
- var ALightSources: TGLLightSourceSet);
- begin
- ACadencer := nil;
- AMatLib := FMaterialLibrary;
- ALightSources := FLightSources;
- end;
- procedure TGLCustomGLSLMLBumpShader.GetShaderTextures(
- var Textures: array of TGLTexture);
- begin
- Textures[0] := FNormalTexture;
- Textures[1] := FSpecularTexture;
- end;
- procedure TGLCustomGLSLMLBumpShader.SetShaderAlpha(const Value: Single);
- begin
- //ignore
- end;
- procedure TGLCustomGLSLMLBumpShader.SetShaderColorParams(const AAmbientColor,
- ADiffuseColor, ASpecularcolor: TVector4f);
- begin
- //ignore
- end;
- procedure TGLCustomGLSLMLBumpShader.SetShaderMiscParameters(
- const ACadencer: TGLCadencer; const AMatLib: TGLMaterialLibrary;
- const ALightSources: TGLLightSourceSet);
- begin
- SetMaterialLibrary(AMatLib);
- SetLightSources(ALightSources);
- end;
- procedure TGLCustomGLSLMLBumpShader.SetShaderTextures(
- const Textures: array of TGLTexture);
- begin
- SetNormalTexture(Textures[0]);
- SetSpecularTexture(Textures[1]);
- end;
- // ------------------
- // ------------------ TGLBumpShader ------------------
- // ------------------
- constructor TGLBumpShader.Create(AOwner: TComponent);
- begin
- inherited;
- FLightIDs := TGIntegerList.Create;
- FBumpMethod := bmDot3TexCombiner;
- FBumpSpace := bsObject;
- FBumpOptions := [];
- FSpecularMode := smOff;
- ShaderStyle := ssLowLevel;
- FParallaxOffset := 0.04;
- FVertexProgram := TStringList.Create;
- FFragmentProgram := TStringList.Create;
- end;
- destructor TGLBumpShader.Destroy;
- begin
- DeleteVertexPrograms;
- DeleteFragmentPrograms;
- FLightIDs.Free;
- FVertexProgram.Free;
- FFragmentProgram.Free;
- inherited;
- end;
- procedure TGLBumpShader.Loaded;
- begin
- inherited;
- end;
- function TGLBumpShader.GenerateVertexProgram: string;
- var
- VP: TStringList;
- DoTangent, DoSpecular, DoParallaxOffset: Boolean;
- texcoord: Integer;
- begin
- DoSpecular := (BumpMethod = bmBasicARBFP) and not (SpecularMode = smOff);
- DoTangent := (BumpSpace = bsTangentExternal) or (BumpSpace =
- bsTangentQuaternion);
- DoParallaxOffset := (BumpMethod = bmBasicARBFP) and (boParallaxMapping in
- BumpOptions) and DoTangent;
- VP := TStringList.Create;
- VP.Add('!!ARBvp1.0');
- VP.Add('OPTION ARB_position_invariant;');
- VP.Add('PARAM mv[4] = { state.matrix.modelview };');
- VP.Add('PARAM mvinv[4] = { state.matrix.modelview.inverse };');
- VP.Add('PARAM mvit[4] = { state.matrix.modelview.invtrans };');
- VP.Add('PARAM tex[4] = { state.matrix.texture[0] };');
- if boUseSecondaryTexCoords in BumpOptions then
- VP.Add('PARAM tex2[4] = { state.matrix.texture[1] };');
- VP.Add('PARAM lightPos = program.local[0];');
- VP.Add('PARAM lightAtten = program.local[1];');
- if BumpSpace = bsTangentExternal then
- begin
- VP.Add('ATTRIB tangent = vertex.texcoord[1];');
- VP.Add('ATTRIB binormal = vertex.texcoord[2];');
- VP.Add('ATTRIB normal = vertex.normal;');
- end;
- VP.Add('TEMP temp, temp2, light, eye, atten;');
- if (boLightAttenuation in BumpOptions) then
- begin
- VP.Add(' DP4 temp.x, mv[0], vertex.position;');
- VP.Add(' DP4 temp.y, mv[1], vertex.position;');
- VP.Add(' DP4 temp.z, mv[2], vertex.position;');
- VP.Add(' ADD light, lightPos, -temp;');
- VP.Add(' DP3 atten.y, light, light;');
- VP.Add(' RSQ atten.y, atten.y;');
- if BumpMethod = bmDot3TexCombiner then
- begin
- VP.Add(' RCP atten.y, atten.y;');
- VP.Add(' MUL atten.z, atten.y, atten.y;');
- VP.Add(' MAD atten.x, lightAtten.y, atten.y, lightAtten.x;');
- VP.Add(' MAD atten.x, lightAtten.z, atten.z, atten.x;');
- VP.Add(' RCP atten.x, atten.x;');
- end
- else if BumpMethod = bmBasicARBFP then
- begin
- // Store the distance in atten.x for ARBFP,
- // fragment program will calculate attenutation
- VP.Add(' RCP atten.x, atten.y;');
- end;
- VP.Add(' DP3 temp.x, mvinv[0], light;');
- VP.Add(' DP3 temp.y, mvinv[1], light;');
- VP.Add(' DP3 temp.z, mvinv[2], light;');
- VP.Add(' MOV light, temp;');
- end
- else
- begin
- VP.Add(' DP4 light.x, mvinv[0], lightPos;');
- VP.Add(' DP4 light.y, mvinv[1], lightPos;');
- VP.Add(' DP4 light.z, mvinv[2], lightPos;');
- VP.Add(' ADD light, light, -vertex.position;');
- end;
- if DoSpecular or DoParallaxOffset then
- VP.Add(' ADD eye, mvit[3], -vertex.position;');
- if DoTangent then
- begin
- if BumpSpace = bsTangentExternal then
- begin
- VP.Add(' DP3 temp.x, light, tangent;');
- VP.Add(' DP3 temp.y, light, binormal;');
- VP.Add(' DP3 temp.z, light, normal;');
- VP.Add(' MOV light, temp;');
- if DoSpecular or DoParallaxOffset then
- begin
- VP.Add(' DP3 temp.x, eye, tangent;');
- VP.Add(' DP3 temp.y, eye, binormal;');
- VP.Add(' DP3 temp.z, eye, normal;');
- VP.Add(' MOV eye, temp;');
- end;
- end
- else if BumpSpace = bsTangentQuaternion then
- begin
- VP.Add(' DP3 temp.x, light, light;');
- VP.Add(' RSQ temp.x, temp.x;');
- VP.Add(' MUL light, temp.x, light;');
- VP.Add(' MOV temp2.x, vertex.normal.y;');
- VP.Add(' ADD temp2.y, 0.0, -vertex.normal.x;');
- VP.Add(' MOV temp2.z, 0.0;');
- VP.Add(' DP3 temp.x, temp2, light;');
- VP.Add(' MUL temp.x, temp2.y, light.z;');
- VP.Add(' MAD temp.y, vertex.normal.z, light.x, temp.x;');
- VP.Add(' MUL temp.x, vertex.normal.y, light.z;');
- VP.Add(' MAD temp.z, vertex.normal.z, light.y, -temp.x;');
- VP.Add(' MUL temp.x, vertex.normal.y, light.y;');
- VP.Add(' MAD temp.x, vertex.normal.z, light.z, temp.x;');
- VP.Add(' MAD temp.w, -temp2.y, light.x, temp.x;');
- VP.Add(' MOV light, temp.yzwy;');
- if DoSpecular or DoParallaxOffset then
- begin
- VP.Add(' DP3 temp.x, temp2, eye;');
- VP.Add(' MUL temp.x, temp2.y, eye.z;');
- VP.Add(' MAD temp.y, vertex.normal.z, eye.x, temp.x;');
- VP.Add(' MUL temp.x, vertex.normal.y, eye.z;');
- VP.Add(' MAD temp.z, vertex.normal.z, eye.y, -temp.x;');
- VP.Add(' MUL temp.x, vertex.normal.y, eye.y;');
- VP.Add(' MAD temp.x, vertex.normal.z, eye.z, temp.x;');
- VP.Add(' MAD temp.w, -temp2.y, eye.x, temp.x;');
- VP.Add(' MOV eye, temp.yzwy;');
- end;
- end;
- end;
- if BumpMethod = bmDot3TexCombiner then
- begin
- if BumpSpace <> bsTangentQuaternion then
- begin
- VP.Add(' DP3 temp.x, light, light;');
- VP.Add(' RSQ temp, temp.x;');
- VP.Add(' MUL light, temp.x, light;');
- end;
- if boLightAttenuation in BumpOptions then
- VP.Add(' MUL light, atten.x, light;');
- VP.Add(' MAD result.color, light, 0.5, 0.5;');
- VP.Add(' MOV result.color.w, 1.0;');
- end
- else if BumpMethod = bmBasicARBFP then
- begin
- if boLightAttenuation in BumpOptions then
- VP.Add(' MOV light.w, atten.x;')
- else
- VP.Add(' MOV light.w, 0.0;');
- if DoSpecular or DoParallaxOffset then
- VP.Add(' MOV eye.w, 0.0;');
- end;
- texcoord := 0;
- VP.Add(' DP4 temp.x, vertex.texcoord[0], tex[0];');
- VP.Add(' DP4 temp.y, vertex.texcoord[0], tex[1];');
- VP.Add(' DP4 temp.z, vertex.texcoord[0], tex[2];');
- VP.Add(' DP4 temp.w, vertex.texcoord[0], tex[3];');
- VP.Add(' MOV result.texcoord[' + IntToStr(texcoord) + '], temp;');
- Inc(texcoord);
- if boUseSecondaryTexCoords in BumpOptions then
- begin
- VP.Add(' DP4 temp.x, vertex.texcoord[1], tex2[0];');
- VP.Add(' DP4 temp.y, vertex.texcoord[1], tex2[1];');
- VP.Add(' DP4 temp.z, vertex.texcoord[1], tex2[2];');
- VP.Add(' DP4 temp.w, vertex.texcoord[1], tex2[3];');
- VP.Add(' MOV result.texcoord[' + IntToStr(texcoord) + '], temp;');
- Inc(texcoord);
- end;
- if BumpMethod = bmDot3TexCombiner then
- begin
- if (boDiffuseTexture2 in BumpOptions)
- and not (boUseSecondaryTexCoords in BumpOptions) then
- VP.Add(' MOV result.texcoord[' + IntToStr(texcoord) + '], temp;');
- end
- else
- begin
- VP.Add(' MOV result.texcoord[' + IntToStr(texcoord) + '], light;');
- Inc(texcoord);
- if DoSpecular then
- VP.Add(' MOV result.texcoord[' + IntToStr(texcoord) + '], eye;');
- end;
- VP.Add('END');
- FVertexProgram.Assign(VP);
- Result := VP.Text;
- VP.Free;
- end;
- function TGLBumpShader.GenerateFragmentProgram: string;
- var
- FP: TStringList;
- DoSpecular,
- DoTangent,
- DoParallaxOffset: Boolean;
- texcoord,
- normalTexCoords,
- diffTexCoords,
- specTexCoords,
- lightTexCoords,
- eyeTexCoords: Integer;
- begin
- DoSpecular := not (SpecularMode = smOff);
- DoTangent := (BumpSpace = bsTangentExternal) or (BumpSpace =
- bsTangentQuaternion);
- DoParallaxOffset := (boParallaxMapping in BumpOptions) and DoTangent;
- texcoord := 0;
- normalTexCoords := texcoord;
- if boUseSecondaryTexCoords in BumpOptions then
- Inc(texcoord);
- diffTexCoords := texcoord;
- specTexCoords := texcoord;
- Inc(texcoord);
- lightTexCoords := texcoord;
- Inc(texcoord);
- eyeTexCoords := texcoord;
- FP := TStringList.Create;
- FP.Add('!!ARBfp1.0');
- FP.Add('PARAM lightDiffuse = program.local[0];');
- FP.Add('PARAM lightSpecular = program.local[1];');
- FP.Add('PARAM lightAtten = program.local[2];');
- FP.Add('PARAM materialDiffuse = state.material.diffuse;');
- FP.Add('PARAM materialSpecular = state.material.specular;');
- FP.Add('PARAM shininess = state.material.shininess;');
- FP.Add('TEMP temp, tex, light, eye, normal, col, diff, spec;');
- FP.Add('TEMP textureColor, reflect, atten, offset, texcoord;');
- if DoSpecular or DoParallaxOffset then
- begin
- // Get the eye vector
- FP.Add(' DP3 eye, fragment.texcoord[' + IntToStr(eyeTexCoords) +
- '], fragment.texcoord[' + IntToStr(eyeTexCoords) + '];');
- FP.Add(' RSQ eye, eye.x;');
- FP.Add(' MUL eye, fragment.texcoord[' + IntToStr(eyeTexCoords) +
- '], eye.x;');
- end;
- if DoParallaxOffset then
- begin
- // Get the parallax offset
- FP.Add(' TEX textureColor, fragment.texcoord[' + IntToStr(normalTexCoords)
- + '], texture[0], 2D;');
- FP.Add(Format(' MAD offset.x, textureColor.a, %f, %f;', [FParallaxOffset,
- -0.5 * FParallaxOffset]));
- FP.Add(' MUL offset, eye, offset.x;');
- FP.Add(' ADD texcoord, fragment.texcoord[' + IntToStr(normalTexCoords) +
- '], offset;');
- end
- else
- FP.Add(' MOV texcoord, fragment.texcoord[' + IntToStr(normalTexCoords) +
- '];');
- // Get the normalized normal vector
- FP.Add(' TEX textureColor, texcoord, texture[0], 2D;');
- FP.Add(' ADD normal, textureColor, -0.5;');
- FP.Add(' DP3 temp, normal, normal;');
- FP.Add(' RSQ temp, temp.x;');
- FP.Add(' MUL normal, normal, temp.x;');
- // Get the normalized light vector
- FP.Add(' MOV light, fragment.texcoord[' + IntToStr(lightTexCoords) + '];');
- if boLightAttenuation in BumpOptions then
- FP.Add(' MOV atten.x, light.w;');
- FP.Add(' DP3 light, light, light;');
- FP.Add(' RSQ light, light.x;');
- FP.Add(' MUL light, fragment.texcoord[' + IntToStr(lightTexCoords) +
- '], light.x;');
- // Calculate the diffuse color
- FP.Add(' DP3 diff, normal, light;');
- FP.Add(' MUL diff, diff, lightDiffuse;');
- FP.Add(' MUL diff, diff, materialDiffuse;');
- if boDiffuseTexture2 in BumpOptions then
- begin
- if DoParallaxOffset then
- begin
- FP.Add(' ADD temp, fragment.texcoord[' + IntToStr(diffTexCoords) +
- '], offset;');
- FP.Add(' TEX textureColor, temp, texture[1], 2D;');
- end
- else
- FP.Add(' TEX textureColor, fragment.texcoord[' + IntToStr(diffTexCoords)
- + '], texture[1], 2D;');
- FP.Add(' MUL diff, diff, textureColor;');
- end;
- if DoSpecular then
- begin
- case SpecularMode of
- smBlinn:
- begin
- FP.Add(' ADD eye, eye, light;');
- FP.Add(' DP3 temp, eye, eye;');
- FP.Add(' RSQ temp, temp.x;');
- FP.Add(' MUL eye, eye, temp.x;');
- FP.Add(' DP3_SAT spec, normal, eye;');
- end;
- smPhong:
- begin
- FP.Add(' DP3 reflect, normal, light;');
- FP.Add(' MUL reflect, reflect.x, normal;');
- FP.Add(' MUL reflect, 2.0, reflect;');
- FP.Add(' ADD reflect, reflect, -light;');
- FP.Add(' DP3_SAT spec, reflect, eye;');
- end;
- else
- Assert(False, 'Invalid specular mode!');
- end;
- FP.Add(' POW spec, spec.x, shininess.x;');
- FP.Add(' MUL spec, spec, materialSpecular;');
- FP.Add(' MUL spec, spec, lightSpecular;');
- if boSpecularTexture3 in BumpOptions then
- begin
- if DoParallaxOffset then
- begin
- FP.Add(' ADD temp, fragment.texcoord[' + IntToStr(specTexCoords) +
- '], offset;');
- FP.Add(' TEX textureColor, temp, texture[2], 2D;');
- end
- else
- FP.Add(' TEX textureColor, fragment.texcoord[' +
- IntToStr(specTexCoords) + '], texture[2], 2D;');
- FP.Add(' MUL spec, spec, textureColor;');
- end;
- end;
- // Output
- if DoSpecular then
- FP.Add(' ADD temp, diff, spec;')
- else
- FP.Add(' MOV temp, diff;');
- if boLightAttenuation in BumpOptions then
- begin
- FP.Add(' MUL atten.y, atten.x, atten.x;');
- FP.Add(' MAD atten.x, lightAtten.y, atten.x, lightAtten.x;');
- FP.Add(' MAD atten.x, lightAtten.z, atten.y, atten.x;');
- FP.Add(' RCP atten.x, atten.x;');
- FP.Add(' MUL temp, temp, atten.x;');
- end;
- FP.Add(' MOV_SAT result.color, temp;');
- FP.Add(' MOV result.color.w, 1.0;');
- FP.Add('END');
- FFragmentProgram.Assign(FP);
- Result := FP.Text;
- FP.Free;
- end;
- // DoLightPass
- //
- procedure TGLBumpShader.DoLightPass(var rci: TGLRenderContextInfo;
- lightID: Cardinal);
- var
- dummyHandle, tempHandle: Integer;
- lightPos, lightAtten,
- materialDiffuse, lightDiffuse, lightSpecular: TGLVector;
- begin
- FVertexProgramHandle.Enable;
- FVertexProgramHandle.Bind;
- // Set the light position to program.local[0]
- gl.GetLightfv(GL_LIGHT0 + FLightIDs[0], GL_POSITION, @lightPos.X);
- gl.ProgramLocalParameter4fv(GL_VERTEX_PROGRAM_ARB, 0, @lightPos.X);
- // Set the light attenutation to program.local[1]
- lightAtten.X := rci.GLStates.LightConstantAtten[FLightIDs[0]];
- lightAtten.Y := rci.GLStates.LightLinearAtten[FLightIDs[0]];
- lightAtten.Z := rci.GLStates.LightQuadraticAtten[FLightIDs[0]];
- gl.ProgramLocalParameter4fv(GL_VERTEX_PROGRAM_ARB, 1, @lightAtten.X);
- case FBumpMethod of
- bmDot3TexCombiner:
- begin
- rci.GLStates.ActiveTexture := 0;
- dummyHandle := rci.GLStates.TextureBinding[0, ttTexture2D];
- gl.TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
- gl.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB);
- gl.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE0_ARB);
- gl.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB);
- rci.GLStates.ActiveTexture := 1;
- rci.GLStates.ActiveTextureEnabled[ttTexture2D] := True;
- tempHandle := rci.GLStates.TextureBinding[1, ttTexture2D];
- if tempHandle = 0 then
- rci.GLStates.TextureBinding[1, ttTexture2D] := dummyHandle;
- lightDiffuse := rci.GLStates.LightDiffuse[FLightIDs[0]];
- gl.GetMaterialfv(GL_FRONT, GL_DIFFUSE, @materialDiffuse);
- lightDiffuse.X := lightDiffuse.X * materialDiffuse.X;
- lightDiffuse.Y := lightDiffuse.Y * materialDiffuse.Y;
- lightDiffuse.Z := lightDiffuse.Z * materialDiffuse.Z;
- lightDiffuse.W := lightDiffuse.W * materialDiffuse.W;
- gl.TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, @lightDiffuse);
- gl.TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
- gl.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
- gl.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
- gl.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT_COLOR_EXT);
- with rci.GLStates do
- begin
- ActiveTexture := 2;
- ActiveTextureEnabled[ttTexture2D] := False;
- ActiveTexture := 0;
- end;
- end;
- bmBasicARBFP:
- begin
- FFragmentProgramHandle.Enable;
- FFragmentProgramHandle.Bind;
- lightDiffuse := rci.GLStates.LightDiffuse[FLightIDs[0]];
- lightSpecular := rci.GLStates.LightSpecular[FLightIDs[0]];
- lightAtten.X := rci.GLStates.LightConstantAtten[FLightIDs[0]];
- gl.ProgramLocalParameter4fv(GL_FRAGMENT_PROGRAM_ARB, 0,
- @lightDiffuse.X);
- gl.ProgramLocalParameter4fv(GL_FRAGMENT_PROGRAM_ARB, 1,
- @lightSpecular.X);
- gl.ProgramLocalParameter4fv(GL_FRAGMENT_PROGRAM_ARB, 2,
- @lightAtten.X);
- end;
- else
- Assert(False, 'Invalid bump method!');
- end;
- end;
- procedure TGLBumpShader.DoApply(var rci: TGLRenderContextInfo; Sender: TObject);
- var
- maxTextures, i: Integer;
- ambient, LMaterialAmbient: TGLColorVector;
- success: Boolean;
- begin
- if (csDesigning in ComponentState) and not DesignTimeEnabled then
- exit;
- if not Enabled then
- exit;
- gl.GetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, @maxTextures);
- success := False;
- try
- if not gl.ARB_multitexture then
- raise Exception.Create('This shader requires GL_ARB_multitexture.');
- if (maxTextures < 3)
- and ((BumpMethod <> bmDot3TexCombiner) or (BumpSpace = bsTangentExternal)) then
- raise
- Exception.Create('The current shader settings require 3 or more texture units.');
- if (maxTextures < 4)
- and (BumpMethod <> bmDot3TexCombiner)
- and (boUseSecondaryTexCoords in BumpOptions)
- and (SpecularMode <> smOff) then
- raise
- Exception.Create('The current shader settings require 4 or more texture units.');
- if not Assigned(FVertexProgramHandle) then
- begin
- FVertexProgramHandle := TGLARBVertexProgramHandle.CreateAndAllocate;
- FVertexProgramHandle.LoadARBProgram(GenerateVertexProgram);
- end;
- if not Assigned(FFragmentProgramHandle) then
- if FBumpMethod = bmBasicARBFP then
- begin
- FFragmentProgramHandle := TGLARBFragmentProgramHandle.CreateAndAllocate;
- FFragmentProgramHandle.LoadARBProgram(GenerateFragmentProgram);
- end;
- success := True;
- finally
- if not success then
- begin
- Enabled := False;
- DesignTimeEnabled := False;
- end;
- end;
- FLightIDs.Clear;
- rci.GLStates.ActiveTexture := 0;
- if rci.GLStates.ActiveTextureEnabled[ttTexture2D] then
- for i := 0 to rci.GLStates.MaxLights - 1 do
- begin
- if rci.GLStates.LightEnabling[i] then
- FLightIDs.Add(i);
- end;
- FLightsEnabled := FLightIDs.Count;
- FAmbientPass := False;
- FDiffusePass := False;
- if FLightIDs.Count > 0 then
- begin
- rci.GLStates.DepthFunc := cfLEqual;
- rci.GLStates.Disable(stBlend);
- DoLightPass(rci, FLightIDs[0]);
- FLightIDs.Delete(0);
- end
- else
- with rci.GLStates do
- begin
- Disable(stLighting);
- ActiveTexture := 0;
- ActiveTextureEnabled[ttTexture2D] := False;
- ActiveTexture := 1;
- ActiveTextureEnabled[ttTexture2D] := False;
- ActiveTexture := 2;
- ActiveTextureEnabled[ttTexture2D] := False;
- ActiveTexture := 0;
- gl.GetFloatv(GL_LIGHT_MODEL_AMBIENT, @ambient);
- gl.GetMaterialfv(GL_FRONT, GL_AMBIENT, @LMaterialAmbient);
- ambient.X := ambient.X * LMaterialAmbient.X;
- ambient.Y := ambient.Y * LMaterialAmbient.Y;
- ambient.Z := ambient.Z * LMaterialAmbient.Z;
- gl.Color3fv(@ambient);
- FAmbientPass := True;
- end;
- end;
- function TGLBumpShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
- var
- ambient, LMaterialAmbient: TGLVector;
- begin
- Result := False;
- if (csDesigning in ComponentState) and not DesignTimeEnabled then
- exit;
- if not Enabled then
- exit;
- if FLightIDs.Count > 0 then
- with rci.GLStates do
- begin
- DepthFunc := cfLEqual;
- Enable(stBlend);
- SetBlendFunc(bfOne, bfOne);
- DoLightPass(rci, FLightIDs[0]);
- FLightIDs.Delete(0);
- Result := True;
- Exit;
- end
- else if not FDiffusePass and (FLightsEnabled <> 0)
- and (boDiffuseTexture2 in BumpOptions)
- and (BumpMethod = bmDot3TexCombiner) then
- with rci.GLStates do
- begin
- Enable(stBlend);
- SetBlendFunc(bfDstColor, bfZero);
- ActiveTexture := 0;
- ActiveTextureEnabled[ttTexture2D] := False;
- ActiveTexture := 1;
- ActiveTextureEnabled[ttTexture2D] := True;
- gl.TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- ActiveTexture := 2;
- ActiveTextureEnabled[ttTexture2D] := False;
- ActiveTexture := 0;
- FDiffusePass := True;
- Result := True;
- Exit;
- end
- else if not FAmbientPass then
- with rci.GLStates do
- begin
- FVertexProgramHandle.Disable;
- if BumpMethod = bmBasicARBFP then
- FFragmentProgramHandle.Disable;
- Disable(stLighting);
- ActiveTexture := 0;
- ActiveTextureEnabled[ttTexture2D] := False;
- ActiveTexture := 1;
- ActiveTextureEnabled[ttTexture2D] := False;
- ActiveTexture := 2;
- ActiveTextureEnabled[ttTexture2D] := False;
- ActiveTexture := 0;
- DepthFunc := cfLEqual;
- Enable(stBlend);
- SetBlendFunc(bfOne, bfOne);
- gl.GetFloatv(GL_LIGHT_MODEL_AMBIENT, @ambient);
- gl.GetMaterialfv(GL_FRONT, GL_AMBIENT, @LMaterialAmbient);
- ambient.X := ambient.X * LMaterialAmbient.X;
- ambient.Y := ambient.Y * LMaterialAmbient.Y;
- ambient.Z := ambient.Z * LMaterialAmbient.Z;
- gl.Color3fv(@ambient);
- FAmbientPass := True;
- Result := True;
- Exit;
- end;
- FVertexProgramHandle.Disable;
- if BumpMethod = bmBasicARBFP then
- FFragmentProgramHandle.Disable;
- end;
- procedure TGLBumpShader.DeleteVertexPrograms;
- begin
- FVertexProgramHandle.Free;
- FVertexProgramHandle := nil;
- FVertexProgram.Clear;
- end;
- procedure TGLBumpShader.DeleteFragmentPrograms;
- begin
- FFragmentProgramHandle.Free;
- FFragmentProgramHandle := nil;
- FFragmentProgram.Clear;
- end;
- procedure TGLBumpShader.SetBumpMethod(const Value: TBumpMethod);
- begin
- if Value <> FBumpMethod then
- begin
- FBumpMethod := Value;
- DeleteVertexPrograms;
- DeleteFragmentPrograms;
- NotifyChange(Self);
- end;
- end;
- procedure TGLBumpShader.SetBumpSpace(const Value: TBumpSpace);
- begin
- if Value <> FBumpSpace then
- begin
- FBumpSpace := Value;
- DeleteVertexPrograms;
- DeleteFragmentPrograms;
- NotifyChange(Self);
- end;
- end;
- procedure TGLBumpShader.SetBumpOptions(const Value: TBumpOptions);
- begin
- if Value <> FBumpOptions then
- begin
- FBumpOptions := Value;
- DeleteVertexPrograms;
- DeleteFragmentPrograms;
- NotifyChange(Self);
- end;
- end;
- procedure TGLBumpShader.SetSpecularMode(const Value: TSpecularMode);
- begin
- if Value <> FSpecularMode then
- begin
- FSpecularMode := Value;
- DeleteVertexPrograms;
- DeleteFragmentPrograms;
- NotifyChange(Self);
- end;
- end;
- procedure TGLBumpShader.SetDesignTimeEnabled(const Value: Boolean);
- begin
- if Value <> FDesignTimeEnabled then
- begin
- FDesignTimeEnabled := Value;
- NotifyChange(Self);
- end;
- end;
- procedure TGLBumpShader.SetParallaxOffset(const Value: Single);
- begin
- if Value <> FParallaxOffset then
- begin
- FParallaxOffset := Value;
- DeleteVertexPrograms;
- DeleteFragmentPrograms;
- NotifyChange(Self);
- end;
- end;
- //-----------------------------------------------
- initialization
- //-----------------------------------------------
- RegisterClasses([TGLSLBumpShaderMT, TGLSLBumpShader, TGLSLBumpShaderAM,
- TGLSLMLBumpShader, TGLSLMLBumpShaderMT]);
- end.
|