2
0

fdIntensityMesh.pas 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. unit fdIntensityMesh;
  2. interface
  3. uses
  4. Winapi.OpenGL,
  5. System.SysUtils,
  6. System.Classes,
  7. System.Types,
  8. System.Math,
  9. Vcl.Graphics,
  10. Vcl.Controls,
  11. Vcl.Forms,
  12. Vcl.ComCtrls,
  13. Vcl.StdCtrls,
  14. Vcl.ExtCtrls,
  15. Stage.VectorTypes,
  16. Stage.VectorGeometry,
  17. Stage.TextureFormat,
  18. Stage.Utils,
  19. GLS.Scene,
  20. GLS.VectorFileObjects,
  21. GLS.VectorLists,
  22. GLS.SceneViewer,
  23. GLS.Mesh,
  24. GLS.Texture,
  25. GLSL.UserShader,
  26. GLS.HUDObjects,
  27. GLS.Context,
  28. GLS.Objects,
  29. GLS.BitmapFont,
  30. GLS.WindowsFont,
  31. GLS.Material,
  32. GLS.Coordinates,
  33. GLS.BaseClasses,
  34. GLS.RenderContextInfo,
  35. GLS.Graphics,
  36. GLS.State;
  37. type
  38. TFormIntensutyMesh = class(TForm)
  39. GLScene1: TGLScene;
  40. GLSceneViewer1: TGLSceneViewer;
  41. GLCamera: TGLCamera;
  42. DCTarget: TGLDummyCube;
  43. GLFreeForm: TGLFreeForm;
  44. GLMaterialLibrary1: TGLMaterialLibrary;
  45. GLUserShader: TGLUserShader;
  46. HSPalette: TGLHUDSprite;
  47. GLWindowsBitmapFont: TGLWindowsBitmapFont;
  48. HTPaletteLeft: TGLHUDText;
  49. HTPaletteRight: TGLHUDText;
  50. Panel1: TPanel;
  51. CBWireFrame: TCheckBox;
  52. CBSmooth: TCheckBox;
  53. TBScale: TTrackBar;
  54. Label1: TLabel;
  55. procedure FormCreate(Sender: TObject);
  56. procedure GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
  57. Shift: TShiftState; X, Y: Integer);
  58. procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
  59. X, Y: Integer);
  60. procedure GLUserShaderDoUnApply(Sender: TObject; Pass: Integer;
  61. var rci: TGLRenderContextInfo; var Continue: Boolean);
  62. procedure CBSmoothClick(Sender: TObject);
  63. procedure CBWireFrameClick(Sender: TObject);
  64. procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
  65. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  66. procedure TBScaleChange(Sender: TObject);
  67. private
  68. mx, my: Integer;
  69. public
  70. end;
  71. var
  72. FormIntensutyMesh: TFormIntensutyMesh;
  73. implementation //=============================================================
  74. {$R *.dfm}
  75. type
  76. // Structures used in our binary file
  77. // The structure is quite simplified here, original data came from a FEM
  78. // package and was in (huge) text files, and parsing text files is not the
  79. // purpose of this demo, so data was simplified ;)
  80. TDataNode = record
  81. X, Y, Z: Single;
  82. Intensity: Single;
  83. end;
  84. TDataPrimitive = record
  85. Node1, Node2, Node3, Node4: Word; // if Node4 is $FFFF, codes a triangle
  86. end;
  87. var
  88. DataNodes: array of TDataNode;
  89. DataPrimitives: array of TDataPrimitive;
  90. //----------------------------------------------------------------------------
  91. procedure TFormIntensutyMesh.FormCreate(Sender: TObject);
  92. var
  93. mo: TGLMeshObject;
  94. fgQuads, fgTris: TFGVertexIndexList;
  95. i: Integer;
  96. str: TFileStream;
  97. begin
  98. // load our raw data
  99. str := TFileStream.Create('IntensityMesh.data', fmOpenRead);
  100. str.Read(i, 4);
  101. SetLength(DataNodes, i);
  102. str.Read(i, 4);
  103. SetLength(DataPrimitives, i);
  104. str.Read(DataNodes[0], Length(DataNodes) * SizeOf(TDataNode));
  105. str.Read(DataPrimitives[0], Length(DataPrimitives) * SizeOf(TDataPrimitive));
  106. str.Free;
  107. // fill the freeform with our data
  108. // first create a mesh object
  109. mo := TGLMeshObject.CreateOwned(GLFreeForm.MeshObjects);
  110. mo.Mode := momFaceGroups;
  111. // Specify vertex and texcoords data (intensity is stored a texcoord)
  112. for i := 0 to High(DataNodes) do
  113. begin
  114. mo.Vertices.Add(DataNodes[i].X, DataNodes[i].Y, DataNodes[i].Z);
  115. mo.TexCoords.Add(DataNodes[i].Intensity * 0.001, 0);
  116. end;
  117. // Then create the facegroups that will hold our quads and triangles
  118. fgQuads := TFGVertexIndexList.CreateOwned(mo.FaceGroups);
  119. fgQuads.Mode := fgmmQuads;
  120. fgTris := TFGVertexIndexList.CreateOwned(mo.FaceGroups);
  121. fgTris.Mode := fgmmTriangles;
  122. // and fill them with our primitives
  123. for i := 1 to High(DataPrimitives) do
  124. with DataPrimitives[i] do
  125. begin
  126. if Node4 <> $FFFF then
  127. begin
  128. fgQuads.VertexIndices.Add(Node1, Node2);
  129. fgQuads.VertexIndices.Add(Node4, Node3);
  130. end
  131. else
  132. begin
  133. fgTris.VertexIndices.Add(Node1, Node2, Node3);
  134. end;
  135. end;
  136. // auto center
  137. GLFreeForm.PerformAutoCentering;
  138. // and initialize scale
  139. TBScaleChange(Self);
  140. end;
  141. //----------------------------------------------------------------------------
  142. procedure TFormIntensutyMesh.GLUserShaderDoUnApply(Sender: TObject; Pass: Integer;
  143. var rci: TGLRenderContextInfo; var Continue: Boolean);
  144. begin
  145. if not CBWireFrame.Checked then
  146. Pass := 2; // skip wireframe pass
  147. case Pass of
  148. 1:
  149. begin
  150. // 2nd pass is a wireframe pass (two-sided)
  151. rci.GLStates.ActiveTextureEnabled[ttTexture2D] := False;
  152. rci.GLStates.Enable(stLineSmooth);
  153. rci.GLStates.Enable(stBlend);
  154. rci.GLStates.SetBlendFunc(bfSrcAlpha, bfOneMinusSrcAlpha);
  155. rci.GLStates.LineWidth := 0.5;
  156. rci.GLStates.PolygonMode := pmLines;
  157. rci.GLStates.PolygonOffsetFactor := -1;
  158. rci.GLStates.PolygonOffsetUnits := -1;
  159. rci.GLStates.Enable(stPolygonOffsetLine);
  160. gl.Color3f(0, 0, 0);
  161. Continue := True;
  162. end;
  163. else
  164. // restore states or mark them dirty
  165. if CBWireFrame.Checked then
  166. begin
  167. rci.GLStates.Disable(stPolygonOffsetLine);
  168. end;
  169. Continue := False;
  170. end;
  171. end;
  172. //----------------------------------------------------------------------------
  173. procedure TFormIntensutyMesh.CBSmoothClick(Sender: TObject);
  174. var
  175. tex: TGLTexture;
  176. begin
  177. // switch between linear and nearest filtering
  178. tex := GLMaterialLibrary1.Materials[0].Material.Texture;
  179. if CBSmooth.Checked then
  180. begin
  181. tex.MagFilter := maLinear;
  182. tex.MinFilter := miLinear;
  183. end
  184. else
  185. begin
  186. tex.MagFilter := maNearest;
  187. tex.MinFilter := miNearest;
  188. end;
  189. end;
  190. //----------------------------------------------------------------------------
  191. procedure TFormIntensutyMesh.GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
  192. Shift: TShiftState; X, Y: Integer);
  193. begin
  194. mx := X;
  195. my := Y;
  196. GLSceneViewer1.SetFocus;
  197. end;
  198. //----------------------------------------------------------------------------
  199. procedure TFormIntensutyMesh.GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
  200. X, Y: Integer);
  201. begin
  202. if ssLeft in Shift then
  203. GLCamera.MoveAroundTarget(my - Y, mx - X);
  204. if ssRight in Shift then
  205. begin
  206. DCTarget.Position.AddScaledVector((mx - X) / 30,
  207. GLCamera.AbsoluteRightVectorToTarget);
  208. DCTarget.Position.AddScaledVector((Y - my) / 30,
  209. GLCamera.AbsoluteUpVectorToTarget);
  210. end;
  211. mx := X;
  212. my := Y;
  213. end;
  214. //----------------------------------------------------------------------------
  215. procedure TFormIntensutyMesh.TBScaleChange(Sender: TObject);
  216. begin
  217. with GLMaterialLibrary1.Materials[0] do
  218. TextureScale.X := TBScale.Position / 100;
  219. HTPaletteRight.Text := Format('%d', [TBScale.Position * 10]);
  220. GLSceneViewer1.Invalidate;
  221. end;
  222. //----------------------------------------------------------------------------
  223. procedure TFormIntensutyMesh.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  224. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  225. begin
  226. GLCamera.AdjustDistanceToTarget(Power(1.03, WheelDelta / 120));
  227. end;
  228. //----------------------------------------------------------------------------
  229. procedure TFormIntensutyMesh.CBWireFrameClick(Sender: TObject);
  230. begin
  231. GLSceneViewer1.Invalidate;
  232. end;
  233. end.