fFurShaderD.pas 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. unit fFurShaderD;
  2. interface
  3. uses
  4. Winapi.Windows,
  5. Winapi.Messages,
  6. Winapi.OpenGL,
  7. Winapi.OpenGLext,
  8. System.SysUtils,
  9. System.Variants,
  10. System.Classes,
  11. System.Math,
  12. Vcl.Graphics,
  13. Vcl.Controls,
  14. Vcl.Forms,
  15. Vcl.Dialogs,
  16. Vcl.ExtCtrls,
  17. Vcl.StdCtrls,
  18. Vcl.Imaging.jpeg,
  19. GLS.Texture,
  20. GLS.FileTGA,
  21. GLS.VectorLists,
  22. VectorTypes,
  23. Stage.Utils,
  24. GLS.Context,
  25. GLS.FileOBJ,
  26. Stage.VectorGeometry,
  27. Stage.TextureFormat
  28. GLS.XOpenGL,
  29. GLS.Graphics,
  30. GLS.BaseClasses,
  31. GLS.RenderContextInfo,
  32. GLS.Material,
  33. GLS.Cadencer,
  34. GLS.Scene,
  35. GLS.VectorFileObjects,
  36. GLS.Objects,
  37. GLS.Coordinates,
  38. GLS.SceneViewer;
  39. type
  40. TFormFur = class(TForm)
  41. GLScene1: TGLScene;
  42. GLViewer: TGLSceneViewer;
  43. GLCadencer1: TGLCadencer;
  44. Camera: TGLCamera;
  45. Scene: TGLDummyCube;
  46. Timer1: TTimer;
  47. CamBox: TGLDummyCube;
  48. MatLib: TGLMaterialLibrary;
  49. RenderDirectGL: TGLDirectOpenGL;
  50. GLLightSource1: TGLLightSource;
  51. SceneMesh: TGLFreeForm;
  52. procedure FormCreate(Sender: TObject);
  53. procedure GLCadencer1Progress(Sender: TObject; const deltaTime, newTime: Double);
  54. procedure GLViewerMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
  55. X, Y: Integer);
  56. procedure GLViewerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  57. procedure Timer1Timer(Sender: TObject);
  58. procedure FormClose(Sender: TObject; var Action: TCloseAction);
  59. procedure FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer;
  60. MousePos: TPoint; var Handled: Boolean);
  61. procedure RenderDirectGLRender(Sender: TObject; var rci: TGLRenderContextInfo);
  62. private
  63. Path: TFileName;
  64. mx, my: Integer;
  65. InitDGL: Boolean;
  66. AltDGL: Boolean;
  67. GLSLProg: TGLProgramHandle;
  68. procedure PrepareTextures;
  69. procedure DummyRender(dummy: TGLDummyCube; rci: TGLRenderContextInfo);
  70. public
  71. end;
  72. var
  73. FormFur: TFormFur;
  74. implementation
  75. {$R *.dfm}
  76. procedure TFormFur.PrepareTextures;
  77. begin
  78. SetCurrentDir(Path + '\texture');
  79. with MatLib.LibMaterialByName('Fur').Material.Texture do
  80. begin
  81. Image.LoadFromFile('fur.tga');
  82. end;
  83. with MatLib.LibMaterialByName('FurColor').Material.Texture do
  84. begin
  85. Image.LoadFromFile('rainbowfilm_smooth.jpg');
  86. end;
  87. end;
  88. procedure TFormFur.FormCreate(Sender: TObject);
  89. begin
  90. Path := GetCurrentAssetPath();
  91. SetCurrentDir(Path + '\model');
  92. InitDGL := False;
  93. AltDGL := False;
  94. GLViewer.Buffer.FaceCulling := False;
  95. SceneMesh.LoadFromFile('Torus.obj');
  96. GLCadencer1.Enabled := True;
  97. Timer1.Enabled := True;
  98. end;
  99. procedure TFormFur.DummyRender(dummy: TGLDummyCube; rci: TGLRenderContextInfo);
  100. var
  101. i: Integer;
  102. begin
  103. if (dummy.Count > 0) then
  104. begin
  105. for i := 0 to dummy.Count - 1 do
  106. begin
  107. if TGLSceneObject(dummy.Children[i]).Tag <> 1 then
  108. begin
  109. if dummy.Children[i].Visible then
  110. dummy.Children[i].Visible := False;
  111. gl.PushMatrix();
  112. gl.MultMatrixf(PGLFloat(TGLSceneObject(dummy.Children[i]).AbsoluteMatrixAsAddress));
  113. if dummy.Children[i].Count > 0 then
  114. dummy.Children[i].DoRender(rci, True, True)
  115. else
  116. dummy.Children[i].DoRender(rci, True, False);
  117. gl.PopMatrix;
  118. end;
  119. end;
  120. end;
  121. end;
  122. procedure TFormFur.GLCadencer1Progress(Sender: TObject; const deltaTime, newTime: Double);
  123. begin
  124. SceneMesh.Pitch(0.5);
  125. GLViewer.Invalidate;
  126. end;
  127. procedure TFormFur.GLViewerMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
  128. X, Y: Integer);
  129. begin
  130. mx := X;
  131. my := Y;
  132. end;
  133. procedure TFormFur.GLViewerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  134. begin
  135. if (ssright in Shift) then
  136. Camera.MoveAroundTarget(my - Y, mx - X);
  137. mx := X;
  138. my := Y;
  139. end;
  140. procedure TFormFur.Timer1Timer(Sender: TObject);
  141. begin
  142. Caption := Format('Fur Shader. [%.2f] FPS', [GLViewer.FramesPerSecond]);
  143. GLViewer.ResetPerformanceMonitor;
  144. end;
  145. procedure TFormFur.FormClose(Sender: TObject; var Action: TCloseAction);
  146. begin
  147. AltDGL := True;
  148. InitDGL := False;
  149. GLCadencer1.Enabled := False;
  150. Timer1.Enabled := False;
  151. GLSLProg.Free;
  152. end;
  153. procedure TFormFur.FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer;
  154. MousePos: TPoint; var Handled: Boolean);
  155. begin
  156. Camera.AdjustDistanceToTarget(Power(1.1, WheelDelta / 120));
  157. end;
  158. procedure TFormFur.RenderDirectGLRender(Sender: TObject; var rci: TGLRenderContextInfo);
  159. var
  160. v: TVector4f;
  161. begin
  162. if (not InitDGL) then
  163. begin
  164. (*
  165. if (not(GL_ARB_shader_objects and GL_ARB_vertex_program and GL_ARB_vertex_shader and
  166. GL_ARB_fragment_shader)) then
  167. begin
  168. ShowMessage('Your hardware/driver doesn''t support GLSL and can''t execute this demo!');
  169. Halt;
  170. end;
  171. *)
  172. SetCurrentDir(Path + '\shader');
  173. GLSLProg := TGLProgramHandle.CreateAndAllocate;
  174. GLSLProg.AddShader(TGLVertexShaderHandle, LoadAnsiStringFromFile('Fur_vp.glsl'));
  175. GLSLProg.AddShader(TGLFragmentShaderHandle,
  176. LoadAnsiStringFromFile('Fur_fp.glsl'));
  177. if (not GLSLProg.LinkProgram) then
  178. raise Exception.Create(GLSLProg.InfoLog);
  179. if (not GLSLProg.ValidateProgram) then
  180. raise Exception.Create(GLSLProg.InfoLog);
  181. gl.CheckError;
  182. PrepareTextures;
  183. InitDGL := True;
  184. end;
  185. v.X := 0.2196;
  186. v.Y := 0.2202;
  187. v.Z := 0.2202;
  188. v.W := 1.0000;
  189. if (InitDGL) and (not AltDGL) then
  190. begin
  191. with GLSLProg do
  192. begin
  193. UseProgramObject;
  194. gl.ActiveTexture(GL_TEXTURE0_ARB);
  195. gl.BindTexture(GL_TEXTURE_2D, MatLib.Materials[0].Material.Texture.Handle);
  196. gl.ActiveTexture(GL_TEXTURE1_ARB);
  197. gl.BindTexture(GL_TEXTURE_2D, MatLib.Materials[1].Material.Texture.Handle);
  198. Uniform1f['shell_distance'] := 0.30000;
  199. Uniform1f['pass_index'] := 0;
  200. Uniform4f['furColorScale'] := v;
  201. Uniform1i['FurColor'] := 1;
  202. Uniform1i['Fur'] := 0;
  203. DummyRender(Scene, rci);
  204. gl.Enable(GL_BLEND);
  205. gl.BlendFunc(GL_SRC_ALPHA, GL_ONE);
  206. gl.BlendFunc(GL_DST_ALPHA, GL_ONE);
  207. Uniform1f['pass_index'] := 1;
  208. DummyRender(Scene, rci);
  209. Uniform1f['pass_index'] := 2;
  210. DummyRender(Scene, rci);
  211. Uniform1f['pass_index'] := 3;
  212. DummyRender(Scene, rci);
  213. Uniform1f['pass_index'] := 4;
  214. DummyRender(Scene, rci);
  215. Uniform1f['pass_index'] := 5;
  216. DummyRender(Scene, rci);
  217. Uniform1f['pass_index'] := 6;
  218. DummyRender(Scene, rci);
  219. Uniform1f['pass_index'] := 7;
  220. DummyRender(Scene, rci);
  221. Uniform1f['pass_index'] := 8;
  222. DummyRender(Scene, rci);
  223. Uniform1f['pass_index'] := 9;
  224. DummyRender(Scene, rci);
  225. Uniform1f['pass_index'] := 10;
  226. DummyRender(Scene, rci);
  227. Uniform1f['pass_index'] := 11;
  228. DummyRender(Scene, rci);
  229. Uniform1f['pass_index'] := 12;
  230. DummyRender(Scene, rci);
  231. Uniform1f['pass_index'] := 13;
  232. DummyRender(Scene, rci);
  233. Uniform1f['pass_index'] := 14;
  234. DummyRender(Scene, rci);
  235. Uniform1f['pass_index'] := 15;
  236. DummyRender(Scene, rci);
  237. EndUseProgramObject;
  238. end;
  239. end;
  240. end;
  241. end.