GLSL.ShaderLattice.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. unit GLSL.ShaderLattice;
  5. (*
  6. Lattice shader that simulate Lattice.
  7. At this time only one light source is supported
  8. *)
  9. interface
  10. {$I GLScene.inc}
  11. uses
  12. System.Classes,
  13. OpenGLTokens,
  14. GLScene,
  15. GLBaseClasses,
  16. GLState,
  17. GLContext,
  18. GLRenderContextInfo,
  19. GLVectorGeometry,
  20. GLCoordinates,
  21. GLTextureFormat,
  22. GLColor,
  23. GLTexture,
  24. GLMaterial,
  25. GLSL.Shader,
  26. GLS.ShaderCustom;
  27. (* Custom class for GLSLSimpleLatticeShader.
  28. A shader that simulate Lattice *)
  29. type
  30. TGLCustomGLSLSimpleLatticeShader = class(TGLCustomGLSLShader)
  31. private
  32. FLatticeScale: TGLCoordinates2;
  33. FLatticeThreshold: TGLCoordinates2;
  34. procedure SetLatticeScale(const Value: TGLCoordinates2);
  35. procedure SetLatticeThreshold(const Value: TGLCoordinates2);
  36. protected
  37. procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
  38. function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
  39. public
  40. constructor Create(AOwner : TComponent); override;
  41. destructor Destroy; override;
  42. property LatticeScale: TGLCoordinates2 read FLatticeScale write SetLatticeScale;
  43. property LatticeThreshold: TGLCoordinates2 read FLatticeThreshold write SetLatticeThreshold;
  44. end;
  45. (* Custom class for GLSLLatticeShader.
  46. A shader that simulate Lattice with Diffuse/Specular and support Texture *)
  47. TGLCustomGLSLLatticeShader = class(TGLCustomGLSLSimpleLatticeShader)
  48. private
  49. FAmbientColor: TGLColor;
  50. FDiffuseColor: TGLColor;
  51. FSpecularColor: TGLColor;
  52. FMaterialLibrary: TGLAbstractMaterialLibrary;
  53. FMainTexture: TGLTexture;
  54. FMainTexName : TGLLibMaterialName;
  55. FSpecularPower: Single;
  56. FLightPower: Single;
  57. function GetMaterialLibrary: TGLAbstractMaterialLibrary;
  58. procedure SetMainTexTexture(const Value: TGLTexture);
  59. function GetMainTexName: TGLLibMaterialName;
  60. procedure SetMainTexName(const Value: TGLLibMaterialName);
  61. procedure SetDiffuseColor(AValue: TGLColor);
  62. procedure SetAmbientColor(AValue: TGLColor);
  63. procedure SetSpecularColor(AValue: TGLColor);
  64. protected
  65. procedure DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject); override;
  66. procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
  67. procedure SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary); virtual;
  68. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  69. public
  70. constructor Create(AOwner : TComponent); override;
  71. destructor Destroy; override;
  72. property DiffuseColor : TGLColor read FDiffuseColor Write setDiffuseColor;
  73. property SpecularColor : TGLColor Read FSpecularColor Write setSpecularColor;
  74. property AmbientColor : TGLColor Read FAmbientColor Write setAmbientColor;
  75. property MaterialLibrary: TGLAbstractMaterialLibrary read getMaterialLibrary write SetMaterialLibrary;
  76. property MainTexture: TGLTexture read FMainTexture write SetMainTexTexture;
  77. property MainTextureName: TGLLibMaterialName read GetMainTexName write SetMainTexName;
  78. property SpecularPower: Single read FSpecularPower write FSpecularPower;
  79. property LightPower: Single read FLightPower write FLightPower;
  80. end;
  81. TGLSLSimpleLatticeShader = class(TGLCustomGLSLSimpleLatticeShader)
  82. published
  83. property LatticeScale;
  84. property LatticeThreshold;
  85. end;
  86. TGLSLLatticeShader = class(TGLCustomGLSLLatticeShader)
  87. published
  88. property LatticeScale;
  89. property LatticeThreshold;
  90. property AmbientColor;
  91. property DiffuseColor;
  92. property SpecularColor;
  93. property MainTexture;
  94. property SpecularPower;
  95. property LightPower;
  96. end;
  97. //------------------------------------------------------
  98. implementation
  99. //------------------------------------------------------
  100. //------------------------------------------------------
  101. // TGLCustomGLSLSimpleLatticeShader
  102. //------------------------------------------------------
  103. constructor TGLCustomGLSLSimpleLatticeShader.Create(AOwner: TComponent);
  104. begin
  105. inherited;
  106. with FragmentProgram.Code do
  107. begin
  108. Clear;
  109. Add(' uniform vec2 Scale; ');
  110. Add(' uniform vec2 Threshold; ');
  111. Add(' ');
  112. Add(' void main (void) ');
  113. Add('{ ');
  114. Add(' float ss = fract(gl_TexCoord[0].s * Scale.s); ');
  115. Add(' float tt = fract(gl_TexCoord[0].t * Scale.t); ');
  116. Add(' ');
  117. Add(' if ((ss > Threshold.s) && (tt > Threshold.t)) discard; ');
  118. Add(' gl_FragColor = gl_Color;');
  119. Add('} ');
  120. end;
  121. // Initial stuff.
  122. FLatticeScale := TGLCoordinates2.Create(Self);
  123. FLatticeThreshold := TGLCoordinates2.Create(Self);
  124. FLatticeScale.SetPoint2D(10, 40);
  125. FLatticeThreshold.SetPoint2D(0.15, 0.3);
  126. end;
  127. destructor TGLCustomGLSLSimpleLatticeShader.Destroy;
  128. begin
  129. FLatticeScale.Destroy;
  130. FLatticeThreshold.Destroy;
  131. inherited;
  132. end;
  133. procedure TGLCustomGLSLSimpleLatticeShader.DoApply(var rci: TGLRenderContextInfo;Sender: TObject);
  134. begin
  135. GetGLSLProg.UseProgramObject;
  136. Param['Scale'].AsVector2f := FLatticeScale.AsPoint2D;
  137. Param['Threshold'].AsVector2f := FLatticeThreshold.AsPoint2D;
  138. end;
  139. function TGLCustomGLSLSimpleLatticeShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
  140. begin
  141. Result := False;
  142. //gl.ActiveTexture(GL_TEXTURE0_ARB);
  143. GetGLSLProg.EndUseProgramObject;
  144. end;
  145. procedure TGLCustomGLSLSimpleLatticeShader.SetLatticeScale(
  146. const Value: TGLCoordinates2);
  147. begin
  148. FLatticeScale.Assign(Value);
  149. end;
  150. procedure TGLCustomGLSLSimpleLatticeShader.SetLatticeThreshold(
  151. const Value: TGLCoordinates2);
  152. begin
  153. FLatticeThreshold.Assign(Value);
  154. end;
  155. { TGLCustomGLSLLatticeShader }
  156. constructor TGLCustomGLSLLatticeShader.Create(
  157. AOwner: TComponent);
  158. begin
  159. inherited;
  160. FAmbientColor := TGLColor.Create(Self);
  161. FDiffuseColor := TGLColor.Create(Self);
  162. FSpecularColor := TGLColor.Create(Self);
  163. //setup initial parameters
  164. FAmbientColor.SetColor(0.15, 0.15, 0.15, 1);
  165. FDiffuseColor.SetColor(1, 1, 1, 1);
  166. FSpecularColor.SetColor(1, 1, 1, 1);
  167. FSpecularPower := 8; //6
  168. FLightPower := 1;
  169. end;
  170. destructor TGLCustomGLSLLatticeShader.Destroy;
  171. begin
  172. FAmbientColor.Destroy;
  173. FDiffuseColor.Destroy;
  174. FSpecularColor.Destroy;
  175. inherited;
  176. end;
  177. procedure TGLCustomGLSLLatticeShader.DoApply(var rci: TGLRenderContextInfo; Sender: TObject);
  178. begin
  179. inherited;
  180. Param['AmbientColor'].AsVector4f := FAmbientColor.Color;
  181. Param['DiffuseColor'].AsVector4f := FDiffuseColor.Color;
  182. Param['SpecularColor'].AsVector4f := FSpecularColor.Color;
  183. Param['SpecPower'].AsVector1f := FSpecularPower;
  184. Param['LightIntensity'].AsVector1f := FLightPower;
  185. Param['MainTexture'].AsTexture2D[0] := FMainTexture;
  186. end;
  187. procedure TGLCustomGLSLLatticeShader.DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject);
  188. begin
  189. with VertexProgram.Code do
  190. begin
  191. Clear;
  192. Add('varying vec3 Normal; ');
  193. Add('varying vec3 LightVector; ');
  194. Add('varying vec3 CameraVector; ');
  195. Add('varying vec2 Texcoord; ');
  196. Add(' ');
  197. Add(' ');
  198. Add('void main(void) ');
  199. Add('{ ');
  200. Add(' gl_Position = ftransform(); ');
  201. Add(' Texcoord = gl_MultiTexCoord0.xy; ');
  202. Add(' Normal = normalize(gl_NormalMatrix * gl_Normal); ');
  203. Add(' vec3 p = (gl_ModelViewMatrix * gl_Vertex).xyz; ');
  204. Add(' LightVector = normalize(gl_LightSource[0].position.xyz - p); ');
  205. Add(' CameraVector = normalize(p); ');
  206. Add('} ');
  207. end;
  208. with FragmentProgram.Code do
  209. begin
  210. Clear;
  211. Add(' uniform vec2 Scale; ');
  212. Add(' uniform vec2 Threshold; ');
  213. Add(' ');
  214. Add('uniform vec4 AmbientColor; ');
  215. Add('uniform vec4 DiffuseColor; ');
  216. Add('uniform vec4 SpecularColor; ');
  217. Add(' ');
  218. Add('uniform float LightIntensity; ');
  219. Add('uniform float SpecPower; ');
  220. Add('uniform sampler2D MainTexture; ');
  221. Add(' ');
  222. Add('varying vec3 Normal; ');
  223. Add('varying vec3 LightVector; ');
  224. Add('varying vec3 CameraVector; ');
  225. Add('varying vec2 Texcoord; ');
  226. Add(' ');
  227. Add('void main(void) ');
  228. Add('{ ');
  229. Add(' float ss = fract(Texcoord[0] * Scale.s); ');
  230. Add(' float tt = fract(Texcoord[1] * Scale.t); ');
  231. Add(' ');
  232. Add(' if ((ss > Threshold.s) && (tt > Threshold.t)) discard; ');
  233. Add(' ');
  234. Add(' vec4 TextureContrib = texture2D(MainTexture, Texcoord); ');
  235. Add(' vec4 DiffuseContrib = clamp(DiffuseColor * dot(LightVector, Normal), 0.0, 1.0); ');
  236. Add(' ');
  237. Add(' vec3 reflect_vec = reflect(CameraVector, -Normal); ');
  238. Add(' float Temp = dot(reflect_vec, LightVector); ');
  239. Add(' vec4 SpecContrib = SpecularColor * clamp(pow(Temp, SpecPower), 0.0, 0.95); ');
  240. Add(' ');
  241. Add(' gl_FragColor = TextureContrib * LightIntensity * (AmbientColor + DiffuseContrib) + LightIntensity * SpecContrib; ');
  242. Add('} ');
  243. end;
  244. inherited;
  245. end;
  246. function TGLCustomGLSLLatticeShader.GetMaterialLibrary: TGLAbstractMaterialLibrary;
  247. begin
  248. Result := FMaterialLibrary;
  249. end;
  250. procedure TGLCustomGLSLLatticeShader.SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary);
  251. begin
  252. if FMaterialLibrary <> nil then FMaterialLibrary.RemoveFreeNotification(Self);
  253. FMaterialLibrary := Value;
  254. if (FMaterialLibrary <> nil)
  255. and (FMaterialLibrary is TGLAbstractMaterialLibrary) then
  256. FMaterialLibrary.FreeNotification(Self);
  257. end;
  258. procedure TGLCustomGLSLLatticeShader.SetMainTexTexture(const Value: TGLTexture);
  259. begin
  260. if FMainTexture = Value then Exit;
  261. FMainTexture := Value;
  262. NotifyChange(Self)
  263. end;
  264. function TGLCustomGLSLLatticeShader.GetMainTexName: TGLLibMaterialName;
  265. begin
  266. Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FMainTexture);
  267. if Result = '' then Result := FMainTexName;
  268. end;
  269. procedure TGLCustomGLSLLatticeShader.SetMainTexName(const Value: TGLLibMaterialName);
  270. begin
  271. // Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
  272. if FMainTexName = Value then Exit;
  273. FMainTexName := Value;
  274. FMainTexture := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FMainTexName);
  275. NotifyChange(Self);
  276. end;
  277. procedure TGLCustomGLSLLatticeShader.SetDiffuseColor(AValue: TGLColor);
  278. begin
  279. FDiffuseColor.DirectColor := AValue.Color;
  280. end;
  281. procedure TGLCustomGLSLLatticeShader.SetAmbientColor(AValue: TGLColor);
  282. begin
  283. FAmbientColor.DirectColor := AValue.Color;
  284. end;
  285. procedure TGLCustomGLSLLatticeShader.SetSpecularColor(AValue: TGLColor);
  286. begin
  287. FSpecularColor.DirectColor := AValue.Color;
  288. end;
  289. procedure TGLCustomGLSLLatticeShader.Notification(AComponent: TComponent; Operation: TOperation);
  290. var
  291. Index: Integer;
  292. begin
  293. inherited;
  294. if Operation = opRemove then
  295. if AComponent = FMaterialLibrary then
  296. if FMaterialLibrary <> nil then
  297. begin
  298. if FMainTexture <> nil then
  299. begin
  300. Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FMainTexture);
  301. if Index <> -1 then
  302. SetMainTexTexture(nil);
  303. end;
  304. FMaterialLibrary := nil;
  305. end;
  306. end;
  307. end.