fdMandelbrot.pas 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. unit fdMandelbrot;
  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. Vcl.Graphics,
  12. Vcl.Controls,
  13. Vcl.Forms,
  14. Vcl.Dialogs,
  15. Vcl.ExtCtrls,
  16. Vcl.StdCtrls,
  17. Vcl.Imaging.Jpeg,
  18. Stage.Keyboard,
  19. Stage.Utils,
  20. GLS.SceneViewer,
  21. GLS.Texture,
  22. GLS.Cadencer,
  23. GLS.Scene,
  24. GLS.Context,
  25. GLS.XCollection,
  26. GLS.FileTGA,
  27. GLS.HUDObjects,
  28. GLS.BitmapFont,
  29. GLS.WindowsFont,
  30. GLS.Material,
  31. GLS.Coordinates,
  32. GLS.RenderContextInfo,
  33. GLS.BaseClasses,
  34. GLSL.CustomShader,
  35. GLSL.Shader;
  36. type
  37. TFormMandelbrot = class(TForm)
  38. Scene: TGLScene;
  39. Timer1: TTimer;
  40. Viewer: TGLSceneViewer;
  41. GLCadencer: TGLCadencer;
  42. Mandelbrot: TGLDirectOpenGL;
  43. GLMatLib: TGLMaterialLibrary;
  44. GLCamera: TGLCamera;
  45. OpenDialog1: TOpenDialog;
  46. GLHUDText: TGLHUDText;
  47. GLWindowsBitmapFont: TGLWindowsBitmapFont;
  48. procedure FormCreate(Sender: TObject);
  49. procedure Timer1Timer(Sender: TObject);
  50. procedure GLCadencerProgress(Sender: TObject;
  51. const deltaTime, newTime: Double);
  52. procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
  53. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  54. procedure MandelbrotRender(Sender: TObject; var rci: TGLRenderContextInfo);
  55. public
  56. PathToAsset: TFileName;
  57. MandelbrotProgram: TGLProgramHandle;
  58. end;
  59. const
  60. HELP_TEXT = '+: Zoom in'#13#10 + '-: Zoom out'#13#10 +
  61. 'Arrow keys: Move around'#13#10 + 'F3: Load colormap';
  62. var
  63. FormMandelbrot: TFormMandelbrot;
  64. PositionX, PositionY, Scale: Single;
  65. implementation //=============================================================
  66. {$R *.dfm}
  67. //----------------------------------------------------------------------------
  68. procedure TFormMandelbrot.FormCreate(Sender: TObject);
  69. begin
  70. // SetCurrentDir(ExtractFilePath(ParamStr(0)));
  71. PathToAsset := GetCurrentAssetPath();
  72. SetCurrentDir(PathToAsset + '\texture');
  73. GLMatLib.TexturePaths := PathToAsset;
  74. GLMatLib.Materials[0].Material.Texture.Image.LoadFromFile('hot_metal.bmp');
  75. PositionX := -0.5;
  76. PositionY := 0.0;
  77. Scale := 1.0;
  78. GLHUDText.Text := HELP_TEXT;
  79. end;
  80. //----------------------------------------------------------------------------
  81. procedure TFormMandelbrot.Timer1Timer(Sender: TObject);
  82. begin
  83. Caption := Format('Mandelbrot %.1f FPS', [Viewer.FramesPerSecond]);
  84. Viewer.ResetPerformanceMonitor;
  85. end;
  86. //----------------------------------------------------------------------------
  87. procedure TFormMandelbrot.GLCadencerProgress(Sender: TObject;
  88. const deltaTime, newTime: Double);
  89. var
  90. deltax, deltay: Single;
  91. pt: TPoint;
  92. begin
  93. if IsKeyDown(VK_F3) then
  94. if OpenDialog1.Execute then
  95. GLMatLib.Materials[0].Material.Texture.Image.LoadFromFile
  96. (OpenDialog1.FileName);
  97. if IsKeyDown('+') or IsKeyDown(VK_ADD) then
  98. Scale := Scale * 1.0 / (1.0 + deltaTime * 0.5);
  99. if IsKeyDown('-') or IsKeyDown(VK_SUBTRACT) then
  100. Scale := Scale * (1.0 + deltaTime * 0.5);
  101. if IsKeyDown(VK_DOWN) or IsKeyDown(VK_NUMPAD8) then
  102. PositionY := PositionY + deltaTime * Scale * 0.5;
  103. if IsKeyDown(VK_UP) or IsKeyDown(VK_NUMPAD2) then
  104. PositionY := PositionY - deltaTime * Scale * 0.5;
  105. if IsKeyDown(VK_LEFT) or IsKeyDown(VK_NUMPAD6) then
  106. PositionX := PositionX + deltaTime * Scale * 0.5;
  107. if IsKeyDown(VK_RIGHT) or IsKeyDown(VK_NUMPAD4) then
  108. PositionX := PositionX - deltaTime * Scale * 0.5;
  109. Viewer.Invalidate;
  110. end;
  111. //----------------------------------------------------------------------------
  112. procedure TFormMandelbrot.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  113. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  114. var
  115. DistDelta: Single;
  116. begin
  117. end;
  118. //----------------------------------------------------------------------------
  119. procedure TFormMandelbrot.MandelbrotRender(Sender: TObject;
  120. var rci: TGLRenderContextInfo);
  121. begin
  122. // shader init
  123. if not Assigned(MandelbrotProgram) then
  124. begin
  125. SetCurrentDir(PathToAsset + '\shader');
  126. MandelbrotProgram := TGLProgramHandle.CreateAndAllocate;
  127. MandelbrotProgram.AddShader(TGLFragmentShaderHandle,
  128. String(LoadAnsiStringFromFile('Mandelbrot.frag')), True);
  129. MandelbrotProgram.AddShader(TGLVertexShaderHandle,
  130. String(LoadAnsiStringFromFile('Mandelbrot.vert')), True);
  131. if not MandelbrotProgram.LinkProgram then
  132. raise Exception.Create(MandelbrotProgram.InfoLog);
  133. if not MandelbrotProgram.ValidateProgram then
  134. raise Exception.Create(MandelbrotProgram.InfoLog);
  135. end;
  136. glPushAttrib(GL_ALL_ATTRIB_BITS);
  137. glMatrixMode(GL_MODELVIEW);
  138. glPushMatrix;
  139. glLoadIdentity;
  140. glMatrixMode(GL_PROJECTION);
  141. glPushMatrix;
  142. glLoadIdentity;
  143. MandelbrotProgram.UseProgramObject;
  144. MandelbrotProgram.Uniform1f['positionX'] := PositionX;
  145. MandelbrotProgram.Uniform1f['positionY'] := PositionY;
  146. MandelbrotProgram.Uniform1f['scale'] := Scale;
  147. glEnable(GL_TEXTURE_2D);
  148. glBindTexture(GL_TEXTURE_2D, GLMatLib.Materials[0].Material.Texture.Handle);
  149. MandelbrotProgram.Uniform1i['colorMap'] := 0;
  150. // drawing rectangle over screen
  151. glDisable(GL_DEPTH_TEST);
  152. glDisable(GL_LIGHTING);
  153. glBegin(GL_QUADS);
  154. glTexCoord2f(0.0, 0.0);
  155. glVertex2f(-1.0, -1.0);
  156. glTexCoord2f(1.0, 0.0);
  157. glVertex2f(1.0, -1.0);
  158. glTexCoord2f(1.0, 1.0);
  159. glVertex2f(1.0, 1.0);
  160. glTexCoord2f(0.0, 1.0);
  161. glVertex2f(-1.0, 1.0);
  162. glEnd;
  163. MandelbrotProgram.EndUseProgramObject;
  164. glPopMatrix;
  165. glMatrixMode(GL_MODELVIEW);
  166. glPopMatrix;
  167. glPopAttrib;
  168. /// -CheckOpenGLError;
  169. end;
  170. end.