GXS.CgPostTransformationShader.pas 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //
  2. // The graphics engine GXScene
  3. //
  4. unit GXS.CgPostTransformationShader;
  5. (*
  6. A shader that uses a texture to distort the view by adjusting texture
  7. coordinates.
  8. Does not have any practical use, but is fun to play around with.
  9. *)
  10. interface
  11. uses
  12. System.Classes,
  13. System.SysUtils,
  14. GXS.Texture,
  15. GXS.Cadencer,
  16. GXS.Context,
  17. GXS.Scene,
  18. GXS.RenderContextInfo,
  19. Stage.TextureFormat,
  20. GXSL.CustomShader,
  21. Cg.GL,
  22. Cg.Import,
  23. GXS.CgShader;
  24. type
  25. TCGxCustomPostTransformationShader = class(TCGxCustomShader, IgxPostShader)
  26. private
  27. FTransformationPower: Single;
  28. FTransformationTexture: TgxTexture;
  29. protected
  30. procedure DoApply(var rci: TgxRenderContextInfo; Sender: TObject); override;
  31. // Implementing IPostShader.
  32. procedure DoUseTempTexture(const TempTexture: TgxTextureHandle; TextureTarget: TglTextureTarget);
  33. function GetTextureTarget: TglTextureTarget;
  34. public
  35. constructor Create(AOwner: TComponent); override;
  36. property TransformationPower: Single read FTransformationPower write FTransformationPower;
  37. property TransformationTexture: TgxTexture read FTransformationTexture write FTransformationTexture;
  38. end;
  39. TCGxPostTransformationShader = class(TCGxCustomPostTransformationShader)
  40. published
  41. property TransformationPower;
  42. property TransformationTexture;
  43. end;
  44. //------------------------------------------------------------------------
  45. implementation
  46. //------------------------------------------------------------------------
  47. //----------------------------------------
  48. // TCGxCustomPostTransformationShader
  49. //----------------------------------------
  50. constructor TCGxCustomPostTransformationShader.Create(AOwner: TComponent);
  51. begin
  52. inherited;
  53. with VertexProgram.Code do
  54. begin
  55. Add(' ');
  56. Add('void main( ');
  57. Add(' float4 iPos : POSITION, ');
  58. Add(' float2 iTex0 : TEXCOORD0, ');
  59. Add(' out float4 oPos : POSITION, ');
  60. Add(' out float2 oTex0 : TEXCOORD0 ');
  61. Add(' ) ');
  62. Add('{ ');
  63. Add(' oPos = iPos; ');
  64. Add(' oTex0 = iTex0; ');
  65. Add('} ');
  66. end;
  67. with FragmentProgram.Code do
  68. begin
  69. Add('void main( ');
  70. Add(' float2 iTex0 : TEXCOORD0, ');
  71. Add(' out float4 oCol : COLOR, ');
  72. Add(' ');
  73. Add(' uniform samplerRECT snapshotTex, ');
  74. Add(' uniform sampler2D transformTex, ');
  75. Add(' uniform float screenW, ');
  76. Add(' uniform float screenH, ');
  77. Add(' uniform float transformPower ');
  78. Add(' ) ');
  79. Add('{ ');
  80. Add(' ');
  81. Add(' /* Read the offset from the transformation texture ');
  82. Add(' x offset is in the red channel, ');
  83. Add(' y offset is in the green channel ');
  84. Add(' */ ');
  85. Add(' float2 offset = 2 * tex2D( transformTex, iTex0 ).rg -1; ');
  86. Add(' ');
  87. Add(' /* When using NPOT texture RECT, you need to scale up the texcoords with ');
  88. Add(' the screenSize */ ');
  89. Add(' iTex0.x *= screenW; ');
  90. Add(' iTex0.y *= screenH; ');
  91. Add(' ');
  92. Add(' /* Apply offset */ ');
  93. Add(' iTex0 += offset * transformPower; ');
  94. Add(' ');
  95. Add(' /* The result is the pixel from the snapshot, with offset */ ');
  96. Add(' oCol.rgb = texRECT( snapshotTex, iTex0 ).rgb; ');
  97. Add(' oCol.a = 1; ');
  98. Add('} ');
  99. end;
  100. VertexProgram.OnApply := OnApplyVP;
  101. FragmentProgram.OnApply := OnApplyFP;
  102. FragmentProgram.OnUnApply := OnUnApplyFP;
  103. FTransformationPower := 70;
  104. end;
  105. procedure TCGxCustomPostTransformationShader.DoApply(
  106. var rci: TgxRenderContextInfo; Sender: TObject);
  107. begin
  108. inherited;
  109. FragmentProgram.ParamByName('screenW').SetAsScalar(rci.viewPortSize.cx);
  110. FragmentProgram.ParamByName('screenH').SetAsScalar(rci.viewPortSize.cy);
  111. FragmentProgram.ParamByName('transformTex').SetAsTexture2D(FTransformationTexture.Handle);
  112. FragmentProgram.ParamByName('transformTex').EnableTexture;
  113. FragmentProgram.ParamByName('transformPower').SetAsScalar(FTransformationPower);
  114. end;
  115. procedure TCGxCustomPostTransformationShader.DoUseTempTexture(
  116. const TempTexture: TgxTextureHandle; TextureTarget: TglTextureTarget);
  117. begin
  118. FragmentProgram.ParamByName('snapshotTex').SetAsTextureRECT(TempTexture.Handle);
  119. FragmentProgram.ParamByName('snapshotTex').EnableTexture;
  120. end;
  121. function TCGxCustomPostTransformationShader.GetTextureTarget: TglTextureTarget;
  122. begin
  123. Result := ttTextureRect;
  124. end;
  125. end.