GXSL.CustomShader.pas 25 KB

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