GLSL.CustomShader.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. //
  2. // The graphics engine GLScene
  3. //
  4. unit GLSL.CustomShader;
  5. (*
  6. A collection of pure abstract classes - descendants of TGLShader, which are
  7. used for purpose of not having to write the same stuff all over and over
  8. again in your own shader classes.
  9. It also contains a procedures and function that can be used in all shaders.
  10. The whole history is logged in a former GLS version of the unit.
  11. *)
  12. interface
  13. uses
  14. Winapi.OpenGL,
  15. Winapi.OpenGLext,
  16. System.Classes,
  17. System.SysUtils,
  18. Stage.VectorGeometry,
  19. Stage.VectorTypes,
  20. Stage.OpenGLTokens,
  21. Stage.TextureFormat,
  22. Stage.Strings,
  23. GLS.Texture,
  24. GLS.Cadencer,
  25. GLS.Scene,
  26. GLS.Context,
  27. GLS.RenderContextInfo,
  28. GLS.Material,
  29. GLS.VectorLists,
  30. GLSL.ShaderParameter;
  31. const
  32. glsShaderMaxLightSources = 8;
  33. type
  34. TGLShaderFogSupport = (sfsEnabled, sfsDisabled, sfsAuto);
  35. TGLTransformFeedBackMode = (tfbmInterleaved, tfbmSeparate);
  36. EGLCustomShaderException = class(EGLShaderException);
  37. TGLCustomShader = class;
  38. TGLVertexProgram = class;
  39. TGLFragmentProgram = class;
  40. TGLGeometryProgram = class;
  41. TGLShaderEvent = procedure(Shader: TGLCustomShader) of object;
  42. TGLShaderUnAplyEvent = procedure(Shader: TGLCustomShader; var ThereAreMorePasses: Boolean) of object;
  43. TGLLightSourceEnum = 1..glsShaderMaxLightSources;
  44. TGLLightSourceSet = set of TGLLightSourceEnum;
  45. (* This interface describes user shaders, in order to be able to access them
  46. via a unified interface. If user shader does not support some option, don't
  47. raise an axception, just ignore it. *)
  48. IGLShaderDescription = interface
  49. ['{04089C64-60C2-43F5-AC9C-38ED46264812}']
  50. procedure SetShaderTextures(const Textures: array of TGLTexture);
  51. procedure GetShaderTextures(var Textures: array of TGLTexture);
  52. procedure SetShaderColorParams(const AAmbientColor, ADiffuseColor, ASpecularcolor: TVector4f);
  53. procedure GetShaderColorParams(var AAmbientColor, ADiffuseColor, ASpecularcolor: TVector4f);
  54. procedure SetShaderMiscParameters(const ACadencer: TGLCadencer; const AMatLib: TGLMaterialLibrary; const ALightSources: TGLLightSourceSet);
  55. procedure GetShaderMiscParameters(var ACadencer: TGLCadencer; var AMatLib: TGLMaterialLibrary; var ALightSources: TGLLightSourceSet);
  56. function GetShaderAlpha: Single;
  57. procedure SetShaderAlpha(const Value: Single);
  58. function GetShaderDescription: string;
  59. end;
  60. // Used in the TGLPostShaderHolder component.
  61. IGLPostShader = interface
  62. ['{68A62362-AF0A-4CE8-A9E1-714FE02AFA4A}']
  63. // Called on every pass.
  64. procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;
  65. TextureTarget: TGLTextureTarget);
  66. // Called to determine if it is compatible.
  67. function GetTextureTarget: TGLTextureTarget;
  68. end;
  69. // A pure abstract class, must be overriden.
  70. TGLCustomShader = class(TGLShader)
  71. private
  72. FFragmentProgram: TGLFragmentProgram;
  73. FVertexProgram: TGLVertexProgram;
  74. FGeometryProgram: TGLGeometryProgram;
  75. FTagObject: TObject;
  76. procedure SetFragmentProgram(const Value: TGLFragmentProgram);
  77. procedure SetGeometryProgram(const Value: TGLGeometryProgram);
  78. procedure SetVertexProgram(const Value: TGLVertexProgram);
  79. function StoreFragmentProgram: Boolean;
  80. function StoreGeometryProgram: Boolean;
  81. function StoreVertexProgram: Boolean;
  82. protected
  83. FDebugMode: Boolean;
  84. procedure SetDebugMode(const Value: Boolean); virtual;
  85. property FragmentProgram: TGLFragmentProgram read FFragmentProgram write SetFragmentProgram stored StoreFragmentProgram;
  86. property VertexProgram: TGLVertexProgram read FVertexProgram write SetVertexProgram stored StoreVertexProgram;
  87. property GeometryProgram: TGLGeometryProgram read FGeometryProgram write SetGeometryProgram stored StoreGeometryProgram;
  88. (* Treats warnings as errors and displays this error,
  89. instead of a general shader-not-supported message. *)
  90. property DebugMode: Boolean read FDebugMode write SetDebugMode default False;
  91. property TagObject: TObject read FTagObject write FTagObject default nil;
  92. public
  93. constructor Create(AOwner: TComponent); override;
  94. destructor Destroy; override;
  95. procedure Assign(Source: TPersistent); override;
  96. procedure LoadShaderPrograms(const VPFilename, FPFilename: string; const GPFilename: string = '');
  97. end;
  98. // A custom shader program.
  99. TGLShaderProgram = class(TPersistent)
  100. private
  101. FParent: TGLCustomShader;
  102. FEnabled: Boolean;
  103. FCode: TStrings;
  104. procedure SetCode(const Value: TStrings);
  105. procedure SetEnabled(const Value: Boolean);
  106. procedure OnChangeCode(Sender: TObject);
  107. protected
  108. function GetOwner: TPersistent; override;
  109. public
  110. procedure LoadFromFile(const AFileName: string);
  111. procedure Apply; virtual;
  112. constructor Create(const AParent: TGLCustomShader); virtual;
  113. destructor Destroy; override;
  114. procedure Assign(Source: TPersistent); override;
  115. published
  116. property Code: TStrings read FCode write SetCode;
  117. property Enabled: Boolean read FEnabled write SetEnabled default False;
  118. end;
  119. TGLVertexProgram = class(TGLShaderProgram)
  120. published
  121. property Code;
  122. property Enabled;
  123. end;
  124. TGLFragmentProgram = class(TGLShaderProgram)
  125. published
  126. property Code;
  127. property Enabled;
  128. end;
  129. TGLGeometryProgram = class(TGLShaderProgram)
  130. private
  131. FInputPrimitiveType: TGLgsInTypes;
  132. FOutputPrimitiveType: TGLgsOutTypes;
  133. FVerticesOut: TGLint;
  134. procedure SetInputPrimitiveType(const Value: TGLgsInTypes);
  135. procedure SetOutputPrimitiveType(const Value: TGLgsOutTypes);
  136. procedure SetVerticesOut(const Value: TGLint);
  137. public
  138. constructor Create(const AParent: TGLCustomShader); override;
  139. published
  140. property Code;
  141. property Enabled;
  142. property InputPrimitiveType: TGLgsInTypes read FInputPrimitiveType write SetInputPrimitiveType default gsInPoints;
  143. property OutputPrimitiveType: TGLgsOutTypes read FOutputPrimitiveType write SetOutputPrimitiveType default gsOutPoints;
  144. property VerticesOut: TGLint read FVerticesOut write SetVerticesOut default 0;
  145. end;
  146. // Wrapper around a parameter of the main program.
  147. TGLCustomShaderParameter = class(TObject)
  148. private
  149. protected
  150. function GetAsVector1f: Single; virtual; abstract;
  151. function GetAsVector2f: TVector2f; virtual; abstract;
  152. function GetAsVector3f: TVector3f; virtual; abstract;
  153. function GetAsVector4f: TGLVector; virtual; abstract;
  154. function GetAsVector1i: Integer; virtual; abstract;
  155. function GetAsVector2i: TVector2i; virtual; abstract;
  156. function GetAsVector3i: TVector3i; virtual; abstract;
  157. function GetAsVector4i: TVector4i; virtual; abstract;
  158. function GetAsVector1ui: Cardinal; virtual; abstract;
  159. function GetAsVector2ui: TVector2ui; virtual; abstract;
  160. function GetAsVector3ui: TVector3ui; virtual; abstract;
  161. function GetAsVector4ui: TVector4ui; virtual; abstract;
  162. procedure SetAsVector1f(const Value: Single); virtual; abstract;
  163. procedure SetAsVector2f(const Value: TVector2f); virtual; abstract;
  164. procedure SetAsVector3f(const Value: TVector3f); virtual; abstract;
  165. procedure SetAsVector4f(const Value: TVector4f); virtual; abstract;
  166. procedure SetAsVector1i(const Value: Integer); virtual; abstract;
  167. procedure SetAsVector2i(const Value: TVector2i); virtual; abstract;
  168. procedure SetAsVector3i(const Value: TVector3i); virtual; abstract;
  169. procedure SetAsVector4i(const Value: TVector4i); virtual; abstract;
  170. procedure SetAsVector1ui(const Value: Cardinal); virtual; abstract;
  171. procedure SetAsVector2ui(const Value: TVector2ui); virtual; abstract;
  172. procedure SetAsVector3ui(const Value: TVector3ui); virtual; abstract;
  173. procedure SetAsVector4ui(const Value: TVector4ui); virtual; abstract;
  174. function GetAsMatrix2f: TMatrix2f; virtual; abstract;
  175. function GetAsMatrix3f: TMatrix3f; virtual; abstract;
  176. function GetAsMatrix4f: TMatrix4f; virtual; abstract;
  177. procedure SetAsMatrix2f(const Value: TMatrix2f); virtual; abstract;
  178. procedure SetAsMatrix3f(const Value: TMatrix3f); virtual; abstract;
  179. procedure SetAsMatrix4f(const Value: TMatrix4f); virtual; abstract;
  180. procedure SetAsTexture(const TextureIndex: Integer;
  181. const Value: TGLTexture);
  182. procedure SetAsTexture1D(const TextureIndex: Integer;
  183. const Value: TGLTexture);
  184. procedure SetAsTexture2D(const TextureIndex: Integer;
  185. const Value: TGLTexture);
  186. procedure SetAsTexture3D(const TextureIndex: Integer;
  187. const Value: TGLTexture);
  188. procedure SetAsTextureCube(const TextureIndex: Integer;
  189. const Value: TGLTexture);
  190. procedure SetAsTextureRect(const TextureIndex: Integer;
  191. const Value: TGLTexture);
  192. function GetAsCustomTexture(const TextureIndex: Integer;
  193. TextureTarget: TGLTextureTarget): Cardinal; virtual; abstract;
  194. procedure SetAsCustomTexture(const TextureIndex: Integer;
  195. TextureTarget: TGLTextureTarget; const Value: Cardinal); virtual; abstract;
  196. function GetAsUniformBuffer: Cardinal; virtual; abstract;
  197. procedure SetAsUniformBuffer(UBO: Cardinal); virtual; abstract;
  198. public
  199. (* This overloaded SetAsVector accepts open array as input. e.g.
  200. SetAsVectorF([0.1, 0.2]). Array length must between 1-4. *)
  201. procedure SetAsVectorF(const Values: array of Single); overload;
  202. procedure SetAsVectorI(const Values: array of Integer); overload;
  203. // SetToTextureOf determines texture type on-the-fly.
  204. procedure SetToTextureOf(const LibMaterial: TGLLibMaterial; const TextureIndex: Integer); overload;
  205. procedure SetToTextureOf(const Texture: TGLTexture; const TextureIndex: Integer); overload;
  206. // GLScene-friendly properties.
  207. property AsVector: TGLVector read GetAsVector4f write SetAsVector4f;
  208. property AsAffineVector: TAffineVector read GetAsVector3f write SetAsVector3f;
  209. // Standard types.
  210. property AsFloat: Single read GetAsVector1f write SetAsVector1f;
  211. property AsInteger: Integer read GetAsVector1i write SetAsVector1i;
  212. // Float vector types.
  213. property AsVector1f: Single read GetAsVector1f write SetAsVector1f;
  214. property AsVector2f: TVector2f read GetAsVector2f write SetAsVector2f;
  215. property AsVector3f: TVector3f read GetAsVector3f write SetAsVector3f;
  216. property AsVector4f: TVector4f read GetAsVector4f write SetAsVector4f;
  217. // Integer vector types.
  218. property AsVector1i: Integer read GetAsVector1i write SetAsVector1i;
  219. property AsVector2i: TVector2i read GetAsVector2i write SetAsVector2i;
  220. property AsVector3i: TVector3i read GetAsVector3i write SetAsVector3i;
  221. property AsVector4i: TVector4i read GetAsVector4i write SetAsVector4i;
  222. // Unsigned integer vector types.
  223. property AsVector1ui: Cardinal read GetAsVector1ui write SetAsVector1ui;
  224. property AsVector2ui: TVector2ui read GetAsVector2ui write SetAsVector2ui;
  225. property AsVector3ui: TVector3ui read GetAsVector3ui write SetAsVector3ui;
  226. property AsVector4ui: TVector4ui read GetAsVector4ui write SetAsVector4ui;
  227. // Matrix Types.
  228. property AsMatrix2f: TMatrix2f read GetAsMatrix2f write SetAsMatrix2f;
  229. property AsMatrix3f: TMatrix3f read GetAsMatrix3f write SetAsMatrix3f;
  230. property AsMatrix4f: TMatrix4f read GetAsMatrix4f write SetAsMatrix4f;
  231. // Texture Types.
  232. property AsTexture [const TextureIndex: Integer]: TGLTexture write SetAsTexture;
  233. property AsTexture1D [const TextureIndex: Integer]: TGLTexture write SetAsTexture1D;
  234. property AsTexture2D [const TextureIndex: Integer]: TGLTexture write SetAsTexture2D;
  235. property AsTexture3D [const TextureIndex: Integer]: TGLTexture write SetAsTexture3D;
  236. property AsTextureRect[const TextureIndex: Integer]: TGLTexture write SetAsTextureRect;
  237. property AsTextureCube[const TextureIndex: Integer]: TGLTexture write SetAsTextureCube;
  238. property AsCustomTexture[const TextureIndex: Integer; TextureTarget: TGLTextureTarget]: Cardinal read GetAsCustomTexture write SetAsCustomTexture;
  239. property AsUniformBuffer: Cardinal read GetAsUniformBuffer write SetAsUniformBuffer;
  240. end;
  241. (* Adds two more blending modes to standard ones.
  242. Not sure how to name them or if they should be included in TBlending mode,
  243. so I created a new type here. *)
  244. TGLBlendingModeEx = (bmxOpaque, bmxTransparency, bmxAdditive,
  245. bmxAlphaTest50, bmxAlphaTest100, bmxModulate,
  246. bmxDestColorOne, bmxDestAlphaOne);
  247. // Exported procedures.
  248. procedure ApplyBlendingModeEx(const BlendingMode: TGLBlendingModeEx);
  249. procedure UnApplyBlendingModeEx;
  250. procedure InitTexture(
  251. const TextureHandle: Cardinal;
  252. const TextureSize: TGLSize;
  253. const TextureTarget: TGLTextureTarget = ttTexture2D);
  254. // Probably need to give them proper names, instead of numbers...
  255. procedure DrawTexturedScreenQuad;
  256. procedure DrawTexturedScreenQuad2(const ViewPortSize: TGLSize);
  257. procedure DrawTexturedScreenQuad3;
  258. procedure DrawTexturedScreenQuad4(const ViewPortSize: TGLSize);
  259. procedure DrawTexturedScreenQuad5(const ViewPortSize: TGLSize);
  260. procedure DrawTexturedScreenQuad6(const ViewPortSize: TGLSize);
  261. procedure CopyScreentoTexture(const ViewPortSize: TGLSize; const TextureTarget: Word = GL_TEXTURE_2D);
  262. procedure CopyScreentoTexture2(const ViewPortSize: TGLSize; const TextureTarget: Word = GL_TEXTURE_2D);
  263. function IsFogEnabled(const AFogSupportMode: TGLShaderFogSupport; var rci: TGLRenderContextInfo): Boolean;
  264. procedure GetActiveLightsList(const ALightIDs: TGLIntegerList);
  265. //------------------------------------------
  266. implementation
  267. //------------------------------------------
  268. uses
  269. GLS.State;
  270. procedure GetActiveLightsList(const ALightIDs: TGLIntegerList);
  271. var
  272. I: Integer;
  273. begin
  274. ALightIDs.Clear;
  275. with CurrentGLContext.GLStates do
  276. begin
  277. for I := 0 to MaxLights - 1 do
  278. begin
  279. if LightEnabling[I] then
  280. ALightIDs.Add(I);
  281. end;
  282. end;
  283. end;
  284. function IsFogEnabled(const AFogSupportMode: TGLShaderFogSupport; var rci: TGLRenderContextInfo): Boolean;
  285. begin
  286. case AFogSupportMode of
  287. sfsEnabled: Result := True;
  288. sfsDisabled: Result := False;
  289. sfsAuto: Result := TGLSceneBuffer(rci.buffer).FogEnable;
  290. else
  291. Result := False;
  292. Assert(False, strUnknownType);
  293. end;
  294. end;
  295. procedure CopyScreentoTexture(const ViewPortSize: TGLSize; const TextureTarget: Word = GL_TEXTURE_2D);
  296. begin
  297. gl.CopyTexSubImage2D(TextureTarget, 0, 0, 0, 0, 0, ViewPortSize.cx, ViewPortSize.cy);
  298. end;
  299. procedure CopyScreentoTexture2(const ViewPortSize: TGLSize; const TextureTarget: Word = GL_TEXTURE_2D);
  300. begin
  301. gl.CopyTexImage2D(TextureTarget, 0, GL_RGB, 0, 0, ViewPortSize.cx, ViewPortSize.cy, 0);
  302. end;
  303. procedure ApplyBlendingModeEx(const BlendingMode: TGLBlendingModeEx);
  304. begin
  305. with CurrentGLContext.GLStates do
  306. begin
  307. Enable(stBlend);
  308. case BlendingMode of
  309. bmxOpaque: SetBlendFunc(bfSRCALPHA, bfONE);
  310. bmxTransparency: SetBlendFunc(bfSRCALPHA, bfONEMINUSSRCALPHA);
  311. bmxAdditive: SetBlendFunc(bfSRCALPHA, bfONE);
  312. bmxAlphaTest50: SetGLAlphaFunction(cfGEQUAL, 0.5);
  313. bmxAlphaTest100: SetGLAlphaFunction(cfGEQUAL, 1.0);
  314. bmxModulate: SetBlendFunc(bfDSTCOLOR, bfZERO);
  315. bmxDestColorOne: SetBlendFunc(bfDSTCOLOR, bfONE);
  316. bmxDestAlphaOne: SetBlendFunc(bfDSTALPHA, bfONE);
  317. else
  318. Assert(False, strErrorEx + strUnknownType);
  319. end;
  320. end;
  321. end;
  322. procedure UnApplyBlendingModeEx;
  323. begin
  324. end;
  325. procedure DrawTexturedScreenQuad;
  326. begin
  327. gl.MatrixMode(GL_MODELVIEW);
  328. gl.PushMatrix;
  329. gl.LoadIdentity;
  330. gl.MatrixMode(GL_PROJECTION);
  331. gl.PushMatrix;
  332. gl.LoadIdentity;
  333. // drawing rectangle over screen
  334. gl.Disable(GL_DEPTH_TEST);
  335. DrawTexturedScreenQuad3;
  336. gl.Enable(GL_DEPTH_TEST);
  337. gl.PopMatrix;
  338. gl.MatrixMode(GL_MODELVIEW);
  339. gl.PopMatrix;
  340. end;
  341. procedure DrawTexturedScreenQuad2(const ViewPortSize: TGLSize);
  342. begin
  343. gl.PushMatrix;
  344. gl.MatrixMode(GL_PROJECTION);
  345. gl.PushMatrix;
  346. gl.LoadIdentity;
  347. gl.Ortho(0, ViewPortSize.cx, ViewPortSize.cy, 0, 0, 1);
  348. gl.Disable(GL_DEPTH_TEST);
  349. gl.DepthMask(False);
  350. gl.Begin_(GL_QUADS);
  351. gl.TexCoord2f(0.0, ViewPortSize.cy); gl.Vertex2f(0, 0);
  352. gl.TexCoord2f(0.0, 0.0); gl.Vertex2f(0, ViewPortSize.cy);
  353. gl.TexCoord2f(ViewPortSize.cx, 0.0); gl.Vertex2f(ViewPortSize.cx, ViewPortSize.cy);
  354. gl.TexCoord2f(ViewPortSize.cx, ViewPortSize.cy); gl.Vertex2f(ViewPortSize.cx, 0);
  355. gl.End_;
  356. gl.DepthMask(True);
  357. gl.Enable(GL_DEPTH_TEST);
  358. gl.MatrixMode(GL_PROJECTION);
  359. gl.PopMatrix;
  360. gl.MatrixMode(GL_MODELVIEW);
  361. gl.PopMatrix;
  362. end;
  363. procedure DrawTexturedScreenQuad4(const ViewPortSize: TGLSize);
  364. begin
  365. gl.Begin_(GL_QUADS);
  366. gl.TexCoord2f(0, 0); gl.Vertex2f(-1, -1);
  367. gl.TexCoord2f(ViewPortSize.cx, 0); gl.Vertex2f( 1, -1);
  368. gl.TexCoord2f(ViewPortSize.cx, ViewPortSize.cy); gl.Vertex2f( 1, 1);
  369. gl.TexCoord2f(0, ViewPortSize.cy); gl.Vertex2f(-1, 1);
  370. gl.End_;
  371. end;
  372. procedure DrawTexturedScreenQuad5(const ViewPortSize: TGLSize);
  373. begin
  374. gl.MatrixMode( GL_PROJECTION );
  375. gl.PushMatrix;
  376. gl.LoadIdentity;
  377. gl.Ortho( 0, ViewPortSize.cx, ViewPortSize.cy, 0, 0, 1 );
  378. gl.MatrixMode(GL_MODELVIEW);
  379. gl.PushMatrix;
  380. gl.LoadIdentity;
  381. gl.Disable(GL_DEPTH_TEST);
  382. gl.DepthMask( FALSE );
  383. DrawTexturedScreenQuad3;
  384. gl.DepthMask( TRUE );
  385. gl.Enable(GL_DEPTH_TEST);
  386. gl.PopMatrix;
  387. gl.MatrixMode( GL_PROJECTION );
  388. gl.PopMatrix;
  389. gl.MatrixMode( GL_MODELVIEW );
  390. end;
  391. procedure DrawTexturedScreenQuad6(const ViewPortSize: TGLSize);
  392. begin
  393. gl.MatrixMode( GL_PROJECTION );
  394. gl.PushMatrix;
  395. gl.LoadIdentity;
  396. gl.Ortho( 0, ViewPortSize.cx, ViewPortSize.cy, 0, 0, 1 );
  397. gl.MatrixMode(GL_MODELVIEW);
  398. gl.PushMatrix;
  399. gl.LoadIdentity;
  400. gl.Disable(GL_DEPTH_TEST);
  401. gl.DepthMask( FALSE );
  402. DrawTexturedScreenQuad4(ViewPortSize);;
  403. gl.DepthMask( TRUE );
  404. gl.Enable(GL_DEPTH_TEST);
  405. gl.PopMatrix;
  406. gl.MatrixMode( GL_PROJECTION );
  407. gl.PopMatrix;
  408. gl.MatrixMode( GL_MODELVIEW );
  409. end;
  410. procedure DrawTexturedScreenQuad3;
  411. begin
  412. gl.Begin_(GL_QUADS);
  413. gl.TexCoord2f(0, 0); gl.Vertex2f(-1, -1);
  414. gl.TexCoord2f(1, 0); gl.Vertex2f(1, -1);
  415. gl.TexCoord2f(1, 1); gl.Vertex2f(1, 1);
  416. gl.TexCoord2f(0, 1); gl.Vertex2f(-1, 1);
  417. gl.End_;
  418. end;
  419. procedure InitTexture(
  420. const TextureHandle: Cardinal;
  421. const TextureSize: TGLSize;
  422. const TextureTarget: TGLTextureTarget = ttTexture2D);
  423. var
  424. glTarget: Cardinal;
  425. begin
  426. with CurrentGLContext.GLStates do
  427. begin
  428. TextureBinding[ActiveTexture, TextureTarget] := TextureHandle;
  429. end;
  430. glTarget := DecodeTextureTarget(TextureTarget);
  431. gl.TexParameteri(glTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  432. gl.TexParameteri(glTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  433. gl.TexParameteri(glTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  434. gl.TexParameteri(glTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  435. gl.CopyTexImage2D(glTarget, 0, GL_RGBA8, 0, 0, TextureSize.cx, TextureSize.cy, 0);
  436. end;
  437. //---------------------------------------------
  438. // TGLShaderProgram
  439. //---------------------------------------------
  440. procedure TGLShaderProgram.Apply;
  441. begin
  442. FParent.FinalizeShader;
  443. end;
  444. procedure TGLShaderProgram.Assign(Source: TPersistent);
  445. begin
  446. if Source = nil then
  447. Exit;
  448. if (Source is TGLShaderProgram) then
  449. begin
  450. FEnabled := TGLShaderProgram(Source).FEnabled;
  451. FCode.Assign(TGLShaderProgram(Source).FCode);
  452. end
  453. else
  454. inherited; //die, die, die!!!
  455. end;
  456. constructor TGLShaderProgram.Create(const AParent: TGLCustomShader);
  457. begin
  458. FParent := AParent;
  459. FCode := TStringList.Create;
  460. TStringList(FCode).OnChange := OnChangeCode;
  461. FEnabled := False;
  462. end;
  463. destructor TGLShaderProgram.Destroy;
  464. begin
  465. FCode.Destroy;
  466. end;
  467. function TGLShaderProgram.GetOwner: TPersistent;
  468. begin
  469. Result := FParent;
  470. end;
  471. procedure TGLShaderProgram.LoadFromFile(const AFileName: string);
  472. begin
  473. FCode.LoadFromFile(AFileName);
  474. FEnabled := True;
  475. end;
  476. procedure TGLShaderProgram.OnChangeCode(Sender: TObject);
  477. begin
  478. FEnabled := True;
  479. FParent.NotifyChange(self);
  480. end;
  481. procedure TGLShaderProgram.SetCode(const Value: TStrings);
  482. begin
  483. FCode.Assign(Value);
  484. FParent.NotifyChange(self);
  485. end;
  486. procedure TGLShaderProgram.SetEnabled(const Value: Boolean);
  487. begin
  488. if Value = FEnabled then
  489. Exit;
  490. FEnabled := Value;
  491. if FEnabled then
  492. FParent.FinalizeShader;
  493. end;
  494. //---------------------------------------------
  495. // TGLCustomShader
  496. //---------------------------------------------
  497. procedure TGLCustomShader.Assign(Source: TPersistent);
  498. begin
  499. if Source is TGLCustomShader then
  500. begin
  501. FFragmentProgram.Assign(TGLCustomShader(Source).FFragmentProgram);
  502. FVertexProgram.Assign(TGLCustomShader(Source).FVertexProgram);
  503. FGeometryProgram.Assign(TGLCustomShader(Source).FGeometryProgram);
  504. FTagObject := TGLCustomShader(Source).FTagObject;
  505. end;
  506. inherited;
  507. end;
  508. constructor TGLCustomShader.Create(AOwner: TComponent);
  509. begin
  510. inherited Create(AOwner);
  511. FDebugMode := False;
  512. FFragmentProgram := TGLFragmentProgram.Create(Self);
  513. FVertexProgram := TGLVertexProgram.Create(Self);
  514. FGeometryProgram := TGLGeometryProgram.Create(Self);
  515. end;
  516. destructor TGLCustomShader.Destroy;
  517. begin
  518. FFragmentProgram.Destroy;
  519. FVertexProgram.Destroy;
  520. FGeometryProgram.Destroy;
  521. inherited;
  522. end;
  523. procedure TGLCustomShader.LoadShaderPrograms(const VPFilename, FPFilename: string; const GPFilename: string = '');
  524. begin
  525. If VPFilename <> '' then VertexProgram.LoadFromFile(VPFilename);
  526. If FPFilename <> '' then FragmentProgram.LoadFromFile(FPFilename);
  527. If GPFilename <> '' then GeometryProgram.LoadFromFile(GPFilename);
  528. end;
  529. procedure TGLCustomShader.SetDebugMode(const Value: Boolean);
  530. begin
  531. if FDebugMode <> Value then
  532. begin
  533. FDebugMode := Value;
  534. if FDebugMode then
  535. FailedInitAction := fiaReRaiseException
  536. else
  537. FailedInitAction := fiaRaiseStandardException;
  538. end;
  539. end;
  540. procedure TGLCustomShader.SetFragmentProgram(const Value: TGLFragmentProgram);
  541. begin
  542. FFragmentProgram.Assign(Value);
  543. end;
  544. procedure TGLCustomShader.SetGeometryProgram(const Value: TGLGeometryProgram);
  545. begin
  546. FGeometryProgram.Assign(Value);
  547. end;
  548. procedure TGLCustomShader.SetVertexProgram(const Value: TGLVertexProgram);
  549. begin
  550. FVertexProgram.Assign(Value);
  551. end;
  552. function TGLCustomShader.StoreFragmentProgram: Boolean;
  553. begin
  554. Result := FFragmentProgram.Enabled or (FFragmentProgram.Code.Text <> '')
  555. end;
  556. function TGLCustomShader.StoreGeometryProgram: Boolean;
  557. begin
  558. Result := FGeometryProgram.Enabled or (FGeometryProgram.Code.Text <> '')
  559. end;
  560. function TGLCustomShader.StoreVertexProgram: Boolean;
  561. begin
  562. Result := FVertexProgram.Enabled or (FVertexProgram.Code.Text <> '')
  563. end;
  564. //---------------------------------------------
  565. // TGLCustomShaderParameter
  566. //---------------------------------------------
  567. procedure TGLCustomShaderParameter.SetAsTexture(
  568. const TextureIndex: Integer; const Value: TGLTexture);
  569. begin
  570. SetAsCustomTexture(TextureIndex, Value.TextureHandle.Target, Value.Handle);
  571. end;
  572. procedure TGLCustomShaderParameter.SetAsTexture1D(
  573. const TextureIndex: Integer; const Value: TGLTexture);
  574. begin
  575. SetAsCustomTexture(TextureIndex, ttTexture1D, Value.Handle);
  576. end;
  577. procedure TGLCustomShaderParameter.SetAsTexture2D(
  578. const TextureIndex: Integer; const Value: TGLTexture);
  579. begin
  580. SetAsCustomTexture(TextureIndex, ttTexture2D, Value.Handle);
  581. end;
  582. procedure TGLCustomShaderParameter.SetAsTexture3D(
  583. const TextureIndex: Integer; const Value: TGLTexture);
  584. begin
  585. SetAsCustomTexture(TextureIndex, ttTexture3D, Value.Handle);
  586. end;
  587. procedure TGLCustomShaderParameter.SetAsTextureCube(
  588. const TextureIndex: Integer; const Value: TGLTexture);
  589. begin
  590. SetAsCustomTexture(TextureIndex, ttTextureCube, Value.Handle);
  591. end;
  592. procedure TGLCustomShaderParameter.SetAsTextureRect(
  593. const TextureIndex: Integer; const Value: TGLTexture);
  594. begin
  595. SetAsCustomTexture(TextureIndex, ttTextureRect, Value.Handle);
  596. end;
  597. procedure TGLCustomShaderParameter.SetAsVectorF(const Values: array of Single);
  598. begin
  599. case Length(Values) of
  600. 1: SetAsVector1f(Values[0]);
  601. 2: SetAsVector2f(Vector2fMake(Values[0], Values[1]));
  602. 3: SetAsVector3f(Vector3fMake(Values[0], Values[1], Values[2]));
  603. 4: SetAsVector4f(Vector4fMake(Values[0], Values[1], Values[2], Values[3]));
  604. else
  605. Assert(False, 'Vector length must be between 1 to 4');
  606. end;
  607. end;
  608. procedure TGLCustomShaderParameter.SetAsVectorI(const Values: array of Integer);
  609. begin
  610. case Length(Values) of
  611. 1: SetAsVector1i(Values[0]);
  612. 2: SetAsVector2i(Vector2iMake(Values[0], Values[1]));
  613. 3: SetAsVector3i(Vector3iMake(Values[0], Values[1], Values[2]));
  614. 4: SetAsVector4i(Vector4iMake(Values[0], Values[1], Values[2], Values[3]));
  615. else
  616. Assert(False, 'Vector length must be between 1 to 4');
  617. end;
  618. end;
  619. procedure TGLCustomShaderParameter.SetToTextureOf(
  620. const LibMaterial: TGLLibMaterial; const TextureIndex: Integer);
  621. begin
  622. SetToTextureOf(LibMaterial.Material.Texture, TextureIndex);
  623. end;
  624. procedure TGLCustomShaderParameter.SetToTextureOf(
  625. const Texture: TGLTexture; const TextureIndex: Integer);
  626. begin
  627. SetAsCustomTexture(TextureIndex, Texture.Image.NativeTextureTarget, Texture.Handle);
  628. end;
  629. constructor TGLGeometryProgram.Create(const AParent: TGLCustomShader);
  630. begin
  631. inherited Create(AParent);
  632. FInputPrimitiveType := gsInPoints;
  633. FOutputPrimitiveType := gsOutPoints;
  634. FVerticesOut := 0;
  635. end;
  636. procedure TGLGeometryProgram.SetInputPrimitiveType(const Value: TGLgsInTypes);
  637. begin
  638. if Value <> FInputPrimitiveType then
  639. begin
  640. FInputPrimitiveType := Value;
  641. FParent.NotifyChange(Self);
  642. end;
  643. end;
  644. procedure TGLGeometryProgram.SetOutputPrimitiveType(const Value: TGLgsOutTypes);
  645. begin
  646. if Value<>FOutputPrimitiveType then
  647. begin
  648. FOutputPrimitiveType := Value;
  649. FParent.NotifyChange(Self);
  650. end;
  651. end;
  652. procedure TGLGeometryProgram.SetVerticesOut(const Value: TGLint);
  653. begin
  654. if Value<>FVerticesOut then
  655. begin
  656. FVerticesOut := Value;
  657. FParent.NotifyChange(Self);
  658. end;
  659. end;
  660. //---------------------------------------------
  661. initialization
  662. //---------------------------------------------
  663. RegisterClasses([TGLCustomShader, TGLShaderProgram,
  664. TGLVertexProgram, TGLFragmentProgram, TGLGeometryProgram]);
  665. end.