fShadowFBOD.pas 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. unit fShadowFBOD;
  2. interface
  3. uses
  4. Winapi.OpenGL,
  5. Winapi.OpenGLext,
  6. System.SysUtils,
  7. System.Variants,
  8. System.Classes,
  9. Vcl.Graphics,
  10. Vcl.Controls,
  11. Vcl.Forms,
  12. Vcl.Dialogs,
  13. Vcl.StdCtrls,
  14. Vcl.ExtCtrls,
  15. Vcl.Imaging.Jpeg,
  16. GLScene.TextureFormat,
  17. GLS.Scene,
  18. GLScene.VectorTypes,
  19. GLS.Context,
  20. GLS.Objects,
  21. GLS.HUDObjects,
  22. GLS.Material,
  23. GLS.Texture,
  24. GLS.SceneViewer,
  25. GLS.GeomObjects,
  26. GLS.FBORenderer,
  27. GLS.Cadencer,
  28. GLSL.CustomShader,
  29. GLSL.Shader,
  30. GLScene.VectorGeometry,
  31. GLScene.Coordinates,
  32. GLScene.BaseClasses,
  33. GLS.RenderContextInfo,
  34. GLS.SimpleNavigation,
  35. GLS.VectorFileObjects,
  36. GLS.PipelineTransformation,
  37. GLS.FileMD2,
  38. Formats.DDSImage,
  39. GLS.FileOBJ,
  40. GLS.Graphics,
  41. GLS.State,
  42. GLScene.Utils;
  43. type
  44. TFormShadowFBO = class(TForm)
  45. GLSceneViewer1: TGLSceneViewer;
  46. GLScene1: TGLScene;
  47. GLSphere1: TGLSphere;
  48. GLMaterialLibrary1: TGLMaterialLibrary;
  49. GLCamera1: TGLCamera;
  50. SceneRoot: TGLDummyCube;
  51. GLPlane1: TGLPlane;
  52. GLTorus1: TGLTorus;
  53. GLLightSource1: TGLLightSource;
  54. GLCadencer1: TGLCadencer;
  55. Timer1: TTimer;
  56. GLShadowTextureSprite: TGLHUDSprite;
  57. GLCamera2: TGLCamera;
  58. GLCylinder1: TGLCylinder;
  59. GLSLShader1: TGLSLShader;
  60. GLSLShader2: TGLSLShader;
  61. PrepareShadowMapping: TGLDirectOpenGL;
  62. GLNavigation: TGLSimpleNavigation;
  63. GLFreeForm1: TGLFreeForm;
  64. LightFBORenderer: TGLFBORenderer;
  65. procedure GLSLShader2Initialize(Shader: TGLCustomGLSLShader);
  66. procedure GLSLShader1UnApply(Shader: TGLCustomGLSLShader; var ThereAreMorePasses: Boolean);
  67. procedure FormResize(Sender: TObject);
  68. procedure PrepareShadowMappingRender(Sender: TObject; var rci: TGLRenderContextInfo);
  69. procedure GLSLShader2Apply(Shader: TGLCustomGLSLShader);
  70. procedure GLSLShader1Apply(Shader: TGLCustomGLSLShader);
  71. procedure FormCreate(Sender: TObject);
  72. procedure GLCadencer1Progress(Sender: TObject; const deltaTime,
  73. newTime: Double);
  74. procedure LightFBORendererBeforeRender(Sender: TObject; var rci: TGLRenderContextInfo);
  75. procedure LightFBORendererAfterRender(Sender: TObject; var rci: TGLRenderContextInfo);
  76. procedure GLSceneViewer1BeforeRender(Sender: TObject);
  77. private
  78. FBiasMatrix: TGLMatrix;
  79. FLightModelViewMatrix: TGLMatrix;
  80. FLightProjMatrix: TGLMatrix;
  81. FInvCameraMatrix: TGLMatrix;
  82. FEyeToLightMatrix: TGLMatrix;
  83. public
  84. end;
  85. var
  86. FormShadowFBO: TFormShadowFBO;
  87. implementation
  88. {$R *.dfm}
  89. procedure TFormShadowFBO.PrepareShadowMappingRender(Sender: TObject; var rci: TGLRenderContextInfo);
  90. begin
  91. // prepare shadow mapping matrix
  92. FInvCameraMatrix := rci.PipelineTransformation.InvModelViewMatrix^;
  93. // go from eye space to light's "eye" space
  94. FEyeToLightMatrix := MatrixMultiply(FInvCameraMatrix, FLightModelViewMatrix);
  95. // then to clip space
  96. FEyeToLightMatrix := MatrixMultiply(FEyeToLightMatrix, FLightProjMatrix);
  97. // and finally make the [-1..1] coordinates into [0..1]
  98. FEyeToLightMatrix := MatrixMultiply(FEyeToLightMatrix, FBiasMatrix);
  99. end;
  100. procedure TFormShadowFBO.FormCreate(Sender: TObject);
  101. begin
  102. var Path: TFileName := GetCurrentAssetPath();
  103. // Loading textures
  104. SetCurrentDir(Path + '\texture');
  105. with GLMaterialLibrary1 do
  106. begin
  107. TextureByName('Chekers').Image.LoadFromFile('marbletiles.jpg');
  108. TextureByName('Chekers').Disabled := false;
  109. TextureByName('Chekers2').Image.LoadFromFile('Concrete.jpg');
  110. TextureByName('Chekers2').Disabled := false;
  111. TextureByName('Lightspot').Image.LoadFromFile('Flare1.bmp');
  112. TextureByName('Lightspot').Disabled := false;
  113. // Loading cubemap
  114. SetCurrentDir(Path + '\cubemap');
  115. TextureByName('mask').Image.LoadFromFile('Masks.dds');
  116. TextureByName('mask').Disabled := false;
  117. end;
  118. // Loading skeletal models with skin texture
  119. SetCurrentDir(Path + '\modelext');
  120. GLFreeForm1.LoadFromFile('waste.md2');
  121. GLFreeForm1.Scale.Scale(0.05);
  122. GLFreeForm1.Position.Y := GLPlane1.Position.Y + 0.6;
  123. GLMaterialLibrary1.TextureByName('bark').Image.LoadFromFile('waste.jpg');
  124. GLMaterialLibrary1.TextureByName('bark').Disabled := false;
  125. FBiasMatrix := CreateScaleAndTranslationMatrix(VectorMake(0.5, 0.5, 0.5), VectorMake(0.5, 0.5, 0.5));
  126. // Loading shaders
  127. SetCurrentDir(Path +'\shader');
  128. GLSLShader1.VertexProgram.LoadFromFile('shadowmap_vp.glsl');
  129. GLSLShader1.FragmentProgram.LoadFromFile('shadowmapvis_fp.glsl');
  130. GLSLShader1.Enabled := true;
  131. GLSLShader2.VertexProgram.LoadFromFile('shadowmap_vp.glsl');
  132. GLSLShader2.FragmentProgram.LoadFromFile('shadowmap_fp.glsl');
  133. GLSLShader2.Enabled := true;
  134. end;
  135. procedure TFormShadowFBO.FormResize(Sender: TObject);
  136. begin
  137. GLSceneViewer1.Camera.SceneScale := GLSceneViewer1.ClientWidth / 400;
  138. end;
  139. procedure TFormShadowFBO.GLCadencer1Progress(Sender: TObject; const deltaTime,
  140. newTime: Double);
  141. begin
  142. GLTorus1.Turn(deltaTime * 25);
  143. GLCylinder1.turn(deltaTime * 50);
  144. GLCamera2.Position.Rotate(VectorMake(0, 1, 0), deltaTime * 0.1);
  145. end;
  146. procedure TFormShadowFBO.GLSceneViewer1BeforeRender(Sender: TObject);
  147. begin
  148. if not (GLSceneViewer1.Buffer.RenderingContext.gl.EXT_framebuffer_object) then
  149. begin
  150. ShowMessage('Sorry, this demo requires GL_EXT_framebuffer_object and either');
  151. Close;
  152. end;
  153. end;
  154. procedure TFormShadowFBO.GLSLShader1Apply(Shader: TGLCustomGLSLShader);
  155. begin
  156. Shader.Param['ShadowMap'].AsTexture2D[0] := GLMaterialLibrary1.TextureByName(LightFBORenderer.DepthTextureName);
  157. // set compare to none so we can read off the depth value directly
  158. gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
  159. end;
  160. procedure TFormShadowFBO.GLSLShader1UnApply(Shader: TGLCustomGLSLShader; var ThereAreMorePasses: Boolean);
  161. begin
  162. // reset the compare mode to default
  163. gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
  164. end;
  165. procedure TFormShadowFBO.GLSLShader2Apply(Shader: TGLCustomGLSLShader);
  166. begin
  167. with Shader, GLMaterialLibrary1 do
  168. begin
  169. Param['ShadowMap'].AsTexture2D[1] := TextureByName(LightFBORenderer.DepthTextureName);
  170. Param['LightspotMap'].AsTexture2D[2] := TextureByName('Lightspot');
  171. Param['Scale'].AsFloat := 16.0;
  172. Param['Softly'].AsInteger := 1;
  173. Param['EyeToLightMatrix'].AsMatrix4f := FEyeToLightMatrix;
  174. end;
  175. end;
  176. procedure TFormShadowFBO.GLSLShader2Initialize(Shader: TGLCustomGLSLShader);
  177. begin
  178. with Shader, GLMaterialLibrary1 do
  179. begin
  180. Param['TextureMap'].AsTexture2D[0] := TextureByName('Chekers2');
  181. Param['ShadowMap'].AsTexture2D[1] := TextureByName(LightFBORenderer.DepthTextureName);
  182. Param['LightspotMap'].AsTexture2D[2] := TextureByName('Lightspot');
  183. end;
  184. end;
  185. procedure TFormShadowFBO.LightFBORendererBeforeRender(Sender: TObject; var rci: TGLRenderContextInfo);
  186. begin
  187. // get the modelview and projection matrices from the light's "camera"
  188. with rci.PipelineTransformation do
  189. begin
  190. FLightModelViewMatrix := ModelViewMatrix^;
  191. FLightProjMatrix := ProjectionMatrix^;
  192. end;
  193. // push geometry back a bit, prevents false self-shadowing
  194. with rci.GLStates do
  195. begin
  196. Enable(stPolygonOffsetFill);
  197. PolygonOffsetFactor := 2;
  198. PolygonOffsetUnits := 2;
  199. end;
  200. end;
  201. procedure TFormShadowFBO.LightFBORendererAfterRender(Sender: TObject; var rci: TGLRenderContextInfo);
  202. begin
  203. rci.GLStates.Disable(stPolygonOffsetFill);
  204. end;
  205. end.