GLS.CgPostTransformationShader.pas 4.5 KB

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