2
0

fGLSViewer.pas 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175
  1. unit fGLSViewer;
  2. interface
  3. uses
  4. Winapi.Windows,
  5. Winapi.Messages,
  6. Winapi.OpenGL,
  7. Winapi.ShellAPI,
  8. System.SysUtils,
  9. System.Classes,
  10. System.IniFiles,
  11. System.Win.Registry,
  12. System.ImageList,
  13. System.Math,
  14. System.Actions,
  15. System.Types,
  16. Vcl.Graphics,
  17. Vcl.Controls,
  18. Vcl.Forms,
  19. Vcl.Dialogs,
  20. Vcl.ActnList,
  21. Vcl.Menus,
  22. Vcl.ImgList,
  23. Vcl.ToolWin,
  24. Vcl.ComCtrls,
  25. Vcl.ExtDlgs,
  26. Vcl.ExtCtrls,
  27. Vcl.ActnMan,
  28. Vcl.ActnCtrls,
  29. Vcl.ActnMenus,
  30. Vcl.StdActns,
  31. Vcl.BandActn,
  32. Vcl.StdStyleActnCtrls,
  33. Vcl.VirtualImageList,
  34. Vcl.BaseImageCollection,
  35. Vcl.ImageCollection,
  36. GLS.Material,
  37. GLS.Scene,
  38. GLS.SceneViewer,
  39. GLS.VectorFileObjects,
  40. GLS.Objects,
  41. GLS.VectorGeometry,
  42. GLS.Texture,
  43. GLS.Context,
  44. GLS.VectorLists,
  45. GLS.Cadencer,
  46. GLS.Coordinates,
  47. GLS.BaseClasses,
  48. GLS.State,
  49. GLS.RenderContextInfo,
  50. GLS.TextureFormat,
  51. GLS.Color,
  52. GLS.Keyboard,
  53. GLS.Graphics,
  54. GLS.PersistentClasses,
  55. GLS.MeshUtils,
  56. GLS.VectorTypes,
  57. GnuGettext,
  58. GLS.AsyncTimer,
  59. GLS.Graph,
  60. GLS.MeshBuilder,
  61. GLS.Navigator,
  62. GLS.Utils,
  63. GLS.SimpleNavigation,
  64. fGLForm,
  65. fGLAbout,
  66. fGLOptions,
  67. fGLDialog,
  68. dImages,
  69. dDialogs;
  70. type
  71. TFormGLSViewer = class(TGLForm)
  72. StatusBar: TStatusBar;
  73. Scene: TGLScene;
  74. ffObject: TGLFreeForm;
  75. LightSource: TGLLightSource;
  76. MaterialLib: TGLMaterialLibrary;
  77. CubeLines: TGLCube;
  78. dcObject: TGLDummyCube;
  79. Camera: TGLCamera;
  80. dcAxis: TGLDummyCube;
  81. Cadencer: TGLCadencer;
  82. Timer: TTimer;
  83. snViewer: TGLSceneViewer;
  84. ActionManager: TActionManager;
  85. acOptimizeMesh: TAction;
  86. acProcessInvertNormals: TAction;
  87. acReverseRendering: TAction;
  88. acConvertToTriangles: TAction;
  89. acProcessStripify: TAction;
  90. acToolsOptions: TAction;
  91. acToolsFaceCulling: TAction;
  92. acToolsTexturing: TAction;
  93. acToolsLighting: TAction;
  94. acToolsCustomize: TCustomizeActionBars;
  95. acToolsShowFPS: TAction;
  96. acViewSmoothShading: TAction;
  97. acViewFlatShading: TAction;
  98. acViewFlatLines: TAction;
  99. acViewHiddenLines: TAction;
  100. acViewWireFrame: TAction;
  101. acViewZoomIn: TAction;
  102. acViewZoomOut: TAction;
  103. acViewReset: TAction;
  104. acFileOpen: TAction;
  105. acFilePick: TAction;
  106. acFileOpenTexLib: TAction;
  107. acFileSaveAs: TAction;
  108. acFileSaveTextures: TAction;
  109. acFileExit: TAction;
  110. acHelpContents: THelpContents;
  111. acHelpTopicSearch: THelpTopicSearch;
  112. acHelpGLSHomePage: TAction;
  113. acHelpAbout: TAction;
  114. acAADefault: TAction;
  115. acAA2X: TAction;
  116. acAA4X: TAction;
  117. acEditUndo: TEditUndo;
  118. acEditCut: TEditCut;
  119. acEditCopy: TEditCopy;
  120. acEditPaste: TEditPaste;
  121. acEditSelectAll: TEditSelectAll;
  122. acEditDelete: TEditDelete;
  123. ImageListMenu: TImageList;
  124. ControlBar: TControlBar;
  125. amMenuBar: TActionMainMenuBar;
  126. acAA8X: TAction;
  127. acAA16X: TAction;
  128. acCSA8X: TAction;
  129. acCSA16X: TAction;
  130. atbTools: TActionToolBar;
  131. atbView: TActionToolBar;
  132. atbFile: TActionToolBar;
  133. acPoints: TAction;
  134. AsyncTimer: TGLAsyncTimer;
  135. dcWorld: TGLDummyCube;
  136. XYZGrid: TGLXYZGrid;
  137. acToolsNaviCube: TAction;
  138. GLPoints: TGLPoints;
  139. acToolsInfo: TAction;
  140. GLSimpleNavigation: TGLSimpleNavigation;
  141. acSpheres: TAction;
  142. PanelLeft: TPanel;
  143. tvScene: TTreeView;
  144. ImageListObjects: TImageList;
  145. acSaveTreeView: TAction;
  146. acLoadTreeView: TAction;
  147. OpenDialog: TOpenDialog;
  148. SaveDialog: TSaveDialog;
  149. procedure FormCreate(Sender: TObject);
  150. procedure snViewerMouseDown(Sender: TObject; Button: TMouseButton;
  151. Shift: TShiftState; X, Y: Integer);
  152. procedure snViewerMouseMove(Sender: TObject; Shift: TShiftState;
  153. X, Y: Integer);
  154. procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
  155. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  156. procedure snViewerMouseUp(Sender: TObject; Button: TMouseButton;
  157. Shift: TShiftState; X, Y: Integer);
  158. procedure snViewerBeforeRender(Sender: TObject);
  159. procedure snViewerAfterRender(Sender: TObject);
  160. procedure FormShow(Sender: TObject);
  161. procedure MaterialLibTextureNeeded(Sender: TObject;
  162. var textureFileName: String);
  163. procedure acInvertNormalsExecute(Sender: TObject);
  164. procedure acSaveAsUpdate(Sender: TObject);
  165. procedure acReverseRenderingOrderExecute(Sender: TObject);
  166. procedure acConvertToIndexedTrianglesExecute(Sender: TObject);
  167. procedure CadencerProgress(Sender: TObject;
  168. const deltaTime, newTime: Double);
  169. procedure TimerTimer(Sender: TObject);
  170. procedure acOptimizeExecute(Sender: TObject);
  171. procedure acStripifyExecute(Sender: TObject);
  172. procedure acHelpAboutExecute(Sender: TObject);
  173. procedure acFilePickExecute(Sender: TObject);
  174. procedure acFileOpenTexLibExecute(Sender: TObject);
  175. procedure acFileOpenExecute(Sender: TObject);
  176. procedure acFileSaveAsExecute(Sender: TObject);
  177. procedure acFileSaveTexturesExecute(Sender: TObject);
  178. procedure acFileExitExecute(Sender: TObject);
  179. procedure acToolsOptionsExecute(Sender: TObject);
  180. procedure acToolsTexturingExecute(Sender: TObject);
  181. procedure acToolsFaceCullingExecute(Sender: TObject);
  182. procedure acToolsLightingExecute(Sender: TObject);
  183. procedure acToolsShowFPSExecute(Sender: TObject);
  184. procedure acAADefaultExecute(Sender: TObject);
  185. procedure acViewSmoothShadingExecute(Sender: TObject);
  186. procedure acViewFlatShadingExecute(Sender: TObject);
  187. procedure acViewFlatLinesExecute(Sender: TObject);
  188. procedure acViewHiddenLinesExecute(Sender: TObject);
  189. procedure acViewWireFrameExecute(Sender: TObject);
  190. procedure acViewResetExecute(Sender: TObject);
  191. procedure acViewZoomOutExecute(Sender: TObject);
  192. procedure acViewZoomInExecute(Sender: TObject);
  193. procedure acPointsExecute(Sender: TObject);
  194. procedure AsyncTimerTimer(Sender: TObject);
  195. procedure acToolsNaviCubeExecute(Sender: TObject);
  196. procedure acToolsInfoExecute(Sender: TObject);
  197. procedure snViewerMouseLeave(Sender: TObject);
  198. procedure tvSceneCheckStateChanged(Sender: TCustomTreeView; Node: TTreeNode;
  199. CheckState: TNodeCheckState);
  200. procedure acHelpGLSHomePageExecute(Sender: TObject);
  201. procedure acHelpContentsExecute(Sender: TObject);
  202. procedure acHelpTopicSearchExecute(Sender: TObject);
  203. procedure acSaveTreeViewExecute(Sender: TObject);
  204. procedure acLoadTreeViewExecute(Sender: TObject);
  205. procedure tvSceneClick(Sender: TObject);
  206. procedure acSpheresExecute(Sender: TObject);
  207. private
  208. AssetPath: TFileName;
  209. procedure DoResetCamera;
  210. procedure SetupFreeFormShading;
  211. procedure ApplyShadeModeToMaterial(aMaterial: TGLMaterial);
  212. procedure ApplyShadeMode;
  213. procedure ApplyFSAA;
  214. procedure ApplyFaceCull;
  215. procedure ApplyTexturing;
  216. procedure ApplyFPS;
  217. procedure DoOpen(const FileName: String);
  218. public
  219. md, nthShow: Boolean;
  220. mx, my: Integer;
  221. hlShader: TGLShader;
  222. lastFileName: String;
  223. lastLoadWithTextures: Boolean;
  224. Points: TGLPoints;
  225. procedure ApplyBgColor;
  226. procedure ReadIniFile; override;
  227. procedure WriteIniFile; override;
  228. end;
  229. var
  230. FormGLSViewer: TFormGLSViewer;
  231. NaviCube: TGLNaviCube;
  232. //=======================================================================
  233. implementation
  234. //=======================================================================
  235. {$R *.dfm}
  236. uses
  237. GLS.FileOBJ,
  238. GLS.FileSTL,
  239. GLS.FileLWO,
  240. GLS.FileQ3BSP,
  241. GLS.FileOCT,
  242. GLS.FileMS3D,
  243. GLS.FileNMF,
  244. GLS.FileMD3,
  245. GLS.File3DS,
  246. GLS.FileMD2,
  247. GLS.FileSMD,
  248. GLS.FilePLY,
  249. GLS.FileGTS,
  250. GLS.FileVRML,
  251. GLS.FileMD5,
  252. GLS.FileTIN,
  253. GLS.FileDXF,
  254. GLS.FileGRD,
  255. GLS.FileX,
  256. GLS.FileGLTF;
  257. type
  258. // Hidden line shader (specific implem for the viewer, *not* generic)
  259. THiddenLineShader = class(TGLShader)
  260. private
  261. LinesColor: TGLColorVector;
  262. BackgroundColor: TGLColorVector;
  263. PassCount: Integer;
  264. public
  265. procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
  266. function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
  267. end;
  268. //---------------------------------------------------------------------------
  269. procedure THiddenLineShader.DoApply(var rci: TGLRenderContextInfo;
  270. Sender: TObject);
  271. begin
  272. PassCount := 1;
  273. with rci.GLStates do
  274. begin
  275. PolygonMode := pmFill;
  276. gl.Color3fv(@BackgroundColor);
  277. ActiveTextureEnabled[ttTexture2D] := False;
  278. Enable(stPolygonOffsetFill);
  279. PolygonOffsetFactor := 1;
  280. PolygonOffsetUnits := 2;
  281. end;
  282. end;
  283. function THiddenLineShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
  284. begin
  285. case PassCount of
  286. 1:
  287. with rci.GLStates do
  288. begin
  289. PassCount := 2;
  290. PolygonMode := pmLines;
  291. glColor3fv(@LinesColor);
  292. Disable(stLighting);
  293. Result := True;
  294. end;
  295. 2:
  296. begin
  297. rci.GLStates.Disable(stPolygonOffsetFill);
  298. Result := False;
  299. end;
  300. else
  301. // doesn't hurt to be cautious
  302. Assert(False);
  303. Result := False;
  304. end;
  305. end;
  306. //---------------------------------------------------------------------------
  307. procedure TFormGLSViewer.FormCreate(Sender: TObject);
  308. begin
  309. inherited;
  310. AssetPath := GetCurrentAssetPath();
  311. NaviCube := TGLNaviCube.CreateAsChild(Scene.Objects);
  312. NaviCube.SceneViewer := snViewer;
  313. NaviCube.FPS := 30;
  314. // instantiate our specific hidden-lines shader
  315. hlShader := THiddenLineShader.Create(Self);
  316. ffObject.IgnoreMissingTextures := True;
  317. end;
  318. procedure TFormGLSViewer.FormShow(Sender: TObject);
  319. begin
  320. if not nthShow then
  321. begin
  322. // using formats supported by gls
  323. dmDialogs.OpenDialog.InitialDir := AssetPath + '\model';;
  324. dmDialogs.OpenDialog.Filter := VectorFileFormatsFilter;
  325. dmDialogs.SaveDialog.Filter := VectorFileFormatsSaveFilter;
  326. ApplyFSAA;
  327. ApplyFaceCull;
  328. ApplyFPS;
  329. if ParamCount > 0 then
  330. DoOpen(ParamStr(0));
  331. nthShow := True;
  332. end;
  333. end;
  334. //---------------------------------------------------------------------------
  335. // OpenDialog
  336. //---------------------------------------------------------------------------
  337. procedure TFormGLSViewer.acFileOpenExecute(Sender: TObject);
  338. begin
  339. NaviCube.ActiveMouse := False;
  340. if dmDialogs.OpenDialog.Execute then
  341. DoOpen(dmDialogs.OpenDialog.FileName);
  342. end;
  343. procedure TFormGLSViewer.acFileOpenTexLibExecute(Sender: TObject);
  344. var
  345. I: Integer;
  346. begin
  347. dmDialogs.ODTextures.InitialDir := AssetPath + '\texture';;
  348. if dmDialogs.ODTextures.Execute then
  349. with MaterialLib do
  350. begin
  351. LoadFromFile(dmDialogs.ODTextures.FileName);
  352. for I := 0 to Materials.Count - 1 do
  353. with Materials[I].Material do
  354. BackProperties.Assign(FrontProperties);
  355. ApplyShadeMode;
  356. ApplyTexturing;
  357. end;
  358. end;
  359. procedure TFormGLSViewer.acFilePickExecute(Sender: TObject);
  360. begin
  361. dmDialogs.ODTextures.InitialDir := AssetPath + '\texture';;
  362. if dmDialogs.opDialog.Execute then
  363. begin
  364. with MaterialLib.Materials do
  365. begin
  366. with Items[Count - 1] do
  367. begin
  368. Tag := 1;
  369. Material.Texture.Image.LoadFromFile(dmDialogs.opDialog.FileName);
  370. Material.Texture.Enabled := True;
  371. end;
  372. end;
  373. ApplyTexturing;
  374. end;
  375. end;
  376. procedure TFormGLSViewer.acFileSaveAsExecute(Sender: TObject);
  377. var
  378. ext: String;
  379. begin
  380. if dmDialogs.SaveDialog.Execute then
  381. begin
  382. ext := ExtractFileExt(dmDialogs.SaveDialog.FileName);
  383. if ext = '' then
  384. dmDialogs.SaveDialog.FileName :=
  385. ChangeFileExt(dmDialogs.SaveDialog.FileName,
  386. '.' + GetVectorFileFormats.FindExtByIndex
  387. (dmDialogs.SaveDialog.FilterIndex, False, True));
  388. if GetVectorFileFormats.FindFromFileName(dmDialogs.SaveDialog.FileName) = nil
  389. then
  390. ShowMessage(_('Unsupported or unspecified file extension.'))
  391. else
  392. ffObject.SaveToFile(dmDialogs.SaveDialog.FileName);
  393. end;
  394. end;
  395. procedure TFormGLSViewer.acFileSaveTexturesExecute(Sender: TObject);
  396. begin
  397. if dmDialogs.SDTextures.Execute then
  398. MaterialLib.SaveToFile(dmDialogs.SDTextures.FileName);
  399. end;
  400. procedure TFormGLSViewer.snViewerBeforeRender(Sender: TObject);
  401. begin
  402. THiddenLineShader(hlShader).LinesColor := VectorMake(107 / 256, 123 / 256,
  403. 173 / 256, 1);
  404. THiddenLineShader(hlShader).BackgroundColor :=
  405. ConvertWinColor(snViewer.Buffer.BackgroundColor);
  406. if not gl.ARB_multisample then
  407. begin
  408. acAADefault.Checked := True;
  409. acAA2X.Enabled := False;
  410. acAA4X.Enabled := False;
  411. acAA8X.Enabled := False;
  412. acAA16X.Enabled := False;
  413. acCSA8X.Enabled := False;
  414. acCSA16X.Enabled := False;
  415. end;
  416. end;
  417. procedure TFormGLSViewer.snViewerAfterRender(Sender: TObject);
  418. begin
  419. ApplyFSAA;
  420. Screen.Cursor := crDefault;
  421. end;
  422. procedure TFormGLSViewer.DoResetCamera;
  423. var
  424. objSize: Single;
  425. begin
  426. dcObject.Position.AsVector := NullHmgPoint;
  427. Camera.Position.SetPoint(0, 4, 5);
  428. ffObject.Position.AsVector := NullHmgPoint;
  429. ffObject.Up.Assign(dcAxis.Up);
  430. ffObject.Direction.Assign(dcAxis.Direction);
  431. objSize := ffObject.BoundingSphereRadius;
  432. if objSize > 0 then
  433. begin
  434. if objSize < 1 then
  435. begin
  436. Camera.SceneScale := 1 / objSize;
  437. objSize := 1;
  438. end
  439. else
  440. Camera.SceneScale := 1;
  441. Camera.AdjustDistanceToTarget(objSize * 0.27);
  442. Camera.DepthOfView := 1.5 * Camera.DistanceToTarget + 2 * objSize;
  443. end;
  444. end;
  445. procedure TFormGLSViewer.ApplyShadeModeToMaterial(aMaterial: TGLMaterial);
  446. begin
  447. if acViewSmoothShading.Checked then
  448. begin
  449. snViewer.Buffer.Lighting := True;
  450. snViewer.Buffer.ShadeModel := smSmooth;
  451. aMaterial.PolygonMode := pmFill;
  452. end
  453. else if acViewFlatShading.Checked then
  454. begin
  455. snViewer.Buffer.Lighting := True;
  456. snViewer.Buffer.ShadeModel := smFlat;
  457. aMaterial.PolygonMode := pmFill;
  458. end
  459. else if acViewFlatLines.Checked then
  460. begin
  461. snViewer.Buffer.Lighting := True;
  462. snViewer.Buffer.ShadeModel := smFlat;
  463. aMaterial.PolygonMode := pmLines;
  464. end
  465. else if acViewHiddenLines.Checked then
  466. begin
  467. snViewer.Buffer.Lighting := False;
  468. snViewer.Buffer.ShadeModel := smSmooth;
  469. aMaterial.PolygonMode := pmLines;
  470. end
  471. else if acViewWireFrame.Checked then
  472. begin
  473. snViewer.Buffer.Lighting := False;
  474. snViewer.Buffer.ShadeModel := smSmooth;
  475. aMaterial.PolygonMode := pmLines;
  476. end;
  477. end;
  478. procedure TFormGLSViewer.ApplyShadeMode;
  479. var
  480. I: Integer;
  481. begin
  482. with MaterialLib.Materials do
  483. for I := 0 to Count - 1 do
  484. begin
  485. ApplyShadeModeToMaterial(Items[I].Material);
  486. if (acViewHiddenLines.Checked) or (acViewFlatLines.Checked) then
  487. Items[I].Shader := hlShader
  488. else
  489. Items[I].Shader := nil;
  490. end;
  491. snViewer.Buffer.Lighting := acToolsLighting.Checked;
  492. ffObject.StructureChanged;
  493. end;
  494. procedure TFormGLSViewer.ApplyFSAA;
  495. begin
  496. with snViewer.Buffer do
  497. begin
  498. if acAADefault.Checked then
  499. AntiAliasing := aaDefault
  500. else if acAA2X.Checked then
  501. AntiAliasing := aa2x
  502. else if acAA4X.Checked then
  503. AntiAliasing := aa4x
  504. else if acAA8X.Checked then
  505. AntiAliasing := aa8x
  506. else if acAA16X.Checked then
  507. AntiAliasing := aa16x
  508. else if acCSA8X.Checked then
  509. AntiAliasing := csa8x
  510. else if acCSA16X.Checked then
  511. AntiAliasing := csa16x;
  512. end;
  513. end;
  514. procedure TFormGLSViewer.ApplyFaceCull;
  515. begin
  516. with snViewer.Buffer do
  517. begin
  518. if acToolsFaceCulling.Checked then
  519. begin
  520. FaceCulling := True;
  521. ContextOptions := ContextOptions - [roTwoSideLighting];
  522. end
  523. else
  524. begin
  525. FaceCulling := False;
  526. ContextOptions := ContextOptions + [roTwoSideLighting];
  527. end;
  528. end;
  529. end;
  530. procedure TFormGLSViewer.ApplyBgColor;
  531. var
  532. bmp: TBitmap;
  533. col: TColor;
  534. begin
  535. bmp := TBitmap.Create;
  536. try
  537. bmp.Width := 16;
  538. bmp.Height := 16;
  539. col := ColorToRGB(dmDialogs.ColorDialog.Color);
  540. snViewer.Buffer.BackgroundColor := col;
  541. bmp.Canvas.Pen.Color := col xor $FFFFFF;
  542. bmp.Canvas.Rectangle(0, 0, 16, 16);
  543. bmp.Canvas.Brush.Color := col;
  544. finally
  545. bmp.Free;
  546. end;
  547. end;
  548. procedure TFormGLSViewer.ApplyTexturing;
  549. var
  550. I: Integer;
  551. begin
  552. with MaterialLib.Materials do
  553. for I := 0 to Count - 1 do
  554. begin
  555. with Items[I].Material.Texture do
  556. begin
  557. if Enabled then
  558. Items[I].Tag := Integer(True);
  559. Enabled := Boolean(Items[I].Tag) and acToolsTexturing.Checked;
  560. end;
  561. end;
  562. ffObject.StructureChanged;
  563. end;
  564. //--------------------------------------------------------------------------
  565. procedure TFormGLSViewer.AsyncTimerTimer(Sender: TObject);
  566. begin
  567. snViewer.ResetPerformanceMonitor;
  568. end;
  569. procedure TFormGLSViewer.ApplyFPS;
  570. begin
  571. if acToolsShowFPS.Checked then
  572. begin
  573. Timer.Enabled := True;
  574. Cadencer.Enabled := True;
  575. end
  576. else
  577. begin
  578. Timer.Enabled := False;
  579. Cadencer.Enabled := False;
  580. // StatusBar.Panels[3].Text := ' FPS';
  581. end;
  582. end;
  583. procedure TFormGLSViewer.SetupFreeFormShading;
  584. var
  585. I: Integer;
  586. LibMat: TGLLibMaterial;
  587. begin
  588. if MaterialLib.Materials.Count = 0 then
  589. begin
  590. ffObject.Material.MaterialLibrary := MaterialLib;
  591. LibMat := MaterialLib.Materials.Add;
  592. ffObject.Material.LibMaterialName := LibMat.Name;
  593. LibMat.Material.FrontProperties.Diffuse.Red := 0;
  594. end;
  595. for I := 0 to MaterialLib.Materials.Count - 1 do
  596. with MaterialLib.Materials[I].Material do
  597. BackProperties.Assign(FrontProperties);
  598. ApplyShadeMode;
  599. ApplyTexturing;
  600. ApplyFPS;
  601. end;
  602. procedure TFormGLSViewer.DoOpen(const FileName: String);
  603. var
  604. min, max: TAffineVector;
  605. Name: TFileName;
  606. begin
  607. if not FileExists(FileName) then
  608. Exit;
  609. Screen.Cursor := crHourGlass;
  610. FormGLSViewer.Caption := 'GLSViewer - ' + FileName;
  611. MaterialLib.Materials.Clear;
  612. ffObject.MeshObjects.Clear;
  613. ffObject.LoadFromFile(FileName);
  614. SetupFreeFormShading;
  615. acFileSaveTextures.Enabled := (MaterialLib.Materials.Count > 0);
  616. acFileOpenTexLib.Enabled := (MaterialLib.Materials.Count > 0);
  617. lastFileName := FileName;
  618. lastLoadWithTextures := acToolsTexturing.Enabled;
  619. ffObject.GetExtents(min, max);
  620. CubeLines.CubeWidth := max.X - min.X;
  621. CubeLines.CubeHeight := max.Y - min.Y;
  622. CubeLines.CubeDepth := max.Z - min.Z;
  623. CubeLines.Position.AsAffineVector := VectorLerp(min, max, 0.5);
  624. StatusBar.Panels[0].Text := 'X: ' + ' ';
  625. StatusBar.Panels[1].Text := 'Y: ' + ' ';
  626. StatusBar.Panels[2].Text := 'Z: ' + ' ';
  627. Name := ExtractFileName(FileName);
  628. StatusBar.Panels[3].Text := Name;
  629. DoResetCamera;
  630. end;
  631. procedure TFormGLSViewer.snViewerMouseDown(Sender: TObject; Button: TMouseButton;
  632. Shift: TShiftState; X, Y: Integer);
  633. begin
  634. mx := X;
  635. my := Y;
  636. md := True;
  637. end;
  638. procedure TFormGLSViewer.snViewerMouseLeave(Sender: TObject);
  639. begin
  640. Cadencer.Enabled := False;
  641. end;
  642. procedure TFormGLSViewer.snViewerMouseMove(Sender: TObject; Shift: TShiftState;
  643. X, Y: Integer);
  644. var
  645. d: Single;
  646. begin
  647. if md and (Shift <> []) then
  648. begin
  649. if ssLeft in Shift then
  650. if ssShift in Shift then
  651. Camera.MoveAroundTarget((my - Y) * 0.1, (mx - X) * 0.1)
  652. else
  653. Camera.MoveAroundTarget(my - Y, mx - X)
  654. else if ssRight in Shift then
  655. begin
  656. d := Camera.DistanceToTarget * 0.01 * (X - mx + Y - my);
  657. if IsKeyDown('x') then
  658. ffObject.Translate(d, 0, 0)
  659. else if IsKeyDown('y') then
  660. ffObject.Translate(0, d, 0)
  661. else if IsKeyDown('z') then
  662. ffObject.Translate(0, 0, d)
  663. else
  664. begin
  665. if ssShift in Shift then
  666. Camera.RotateObject(ffObject, (my - Y) * 0.1, (mx - X) * 0.1)
  667. else
  668. Camera.RotateObject(ffObject, my - Y, mx - X);
  669. end;
  670. end;
  671. mx := X;
  672. my := Y;
  673. end;
  674. end;
  675. procedure TFormGLSViewer.snViewerMouseUp(Sender: TObject; Button: TMouseButton;
  676. Shift: TShiftState; X, Y: Integer);
  677. begin
  678. md := False;
  679. end;
  680. procedure TFormGLSViewer.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  681. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  682. begin
  683. if ffObject.MeshObjects.Count > 0 then
  684. begin
  685. Camera.AdjustDistanceToTarget(Power(1.05, WheelDelta / 120));
  686. Camera.DepthOfView := 2 * Camera.DistanceToTarget + 2 *
  687. ffObject.BoundingSphereRadius;
  688. end;
  689. Handled := True;
  690. end;
  691. procedure TFormGLSViewer.MaterialLibTextureNeeded(Sender: TObject;
  692. var textureFileName: String);
  693. begin
  694. if not acToolsTexturing.Enabled then
  695. textureFileName := '';
  696. end;
  697. procedure TFormGLSViewer.acInvertNormalsExecute(Sender: TObject);
  698. var
  699. I: Integer;
  700. begin
  701. with ffObject.MeshObjects do
  702. for I := 0 to Count - 1 do
  703. Items[I].Normals.Scale(-1);
  704. ffObject.StructureChanged;
  705. end;
  706. procedure TFormGLSViewer.acReverseRenderingOrderExecute(Sender: TObject);
  707. var
  708. I, j, n: Integer;
  709. fg: TGLFaceGroup;
  710. begin
  711. with ffObject.MeshObjects do
  712. begin
  713. // invert meshobjects order
  714. for I := 0 to (Count div 2) do
  715. Exchange(I, Count - 1 - I);
  716. // for each mesh object
  717. for I := 0 to Count - 1 do
  718. with Items[I] do
  719. begin
  720. // invert facegroups order
  721. n := FaceGroups.Count;
  722. for j := 0 to (n div 2) do
  723. Exchange(j, n - 1 - j);
  724. // for each facegroup
  725. for j := 0 to n - 1 do
  726. begin
  727. fg := FaceGroups[j];
  728. fg.Reverse;
  729. end;
  730. end;
  731. end;
  732. ffObject.StructureChanged;
  733. end;
  734. procedure TFormGLSViewer.acSaveAsUpdate(Sender: TObject);
  735. begin
  736. acFileSaveAs.Enabled := (ffObject.MeshObjects.Count > 0);
  737. end;
  738. procedure TFormGLSViewer.acHelpAboutExecute(Sender: TObject);
  739. begin
  740. with TGLAbout.Create(Self) do
  741. try
  742. ShowModal;
  743. finally
  744. Free;
  745. end;
  746. end;
  747. procedure TFormGLSViewer.acHelpContentsExecute(Sender: TObject);
  748. begin
  749. inherited;
  750. ShellExecute(0, 'open', 'https://en.wikipedia.org/wiki/GLScene', '', '', SW_SHOW);
  751. end;
  752. procedure TFormGLSViewer.acHelpTopicSearchExecute(Sender: TObject);
  753. begin
  754. inherited;
  755. ShellExecute(0, 'open', 'https://glscene.org', '', '', SW_SHOW);
  756. end;
  757. procedure TFormGLSViewer.acHelpGLSHomePageExecute(Sender: TObject);
  758. begin
  759. inherited;
  760. ShellExecute(0, 'open','https://github.com/glscene', '', '', SW_SHOW);
  761. end;
  762. procedure TFormGLSViewer.acAADefaultExecute(Sender: TObject);
  763. begin
  764. (Sender as TAction).Checked := True;
  765. ApplyFSAA;
  766. end;
  767. procedure TFormGLSViewer.acConvertToIndexedTrianglesExecute(Sender: TObject);
  768. var
  769. v: TGLAffineVectorList;
  770. I: TGLIntegerList;
  771. m: TGLMeshObject;
  772. fg: TFGVertexIndexList;
  773. begin
  774. v := ffObject.MeshObjects.ExtractTriangles;
  775. try
  776. I := BuildVectorCountOptimizedIndices(v);
  777. try
  778. RemapAndCleanupReferences(v, I);
  779. IncreaseCoherency(I, 12);
  780. I.Capacity := I.Count;
  781. ffObject.MeshObjects.Clean;
  782. m := TGLMeshObject.CreateOwned(ffObject.MeshObjects);
  783. m.Vertices := v;
  784. m.BuildNormals(I, momTriangles);
  785. m.Mode := momFaceGroups;
  786. fg := TFGVertexIndexList.CreateOwned(m.FaceGroups);
  787. fg.VertexIndices := I;
  788. fg.Mode := fgmmTriangles;
  789. ffObject.StructureChanged;
  790. finally
  791. I.Free;
  792. end;
  793. finally
  794. v.Free;
  795. end;
  796. MaterialLib.Materials.Clear;
  797. SetupFreeFormShading;
  798. end;
  799. procedure TFormGLSViewer.acStripifyExecute(Sender: TObject);
  800. var
  801. I: Integer;
  802. mo: TGLMeshObject;
  803. fg: TFGVertexIndexList;
  804. strips: TGLPersistentObjectList;
  805. begin
  806. acConvertToTriangles.Execute;
  807. mo := ffObject.MeshObjects[0];
  808. fg := (mo.FaceGroups[0] as TFGVertexIndexList);
  809. strips := StripifyMesh(fg.VertexIndices, mo.Vertices.Count, True);
  810. try
  811. fg.Free;
  812. for I := 0 to strips.Count - 1 do
  813. begin
  814. fg := TFGVertexIndexList.CreateOwned(mo.FaceGroups);
  815. fg.VertexIndices := (strips[I] as TGLIntegerList);
  816. if I = 0 then
  817. fg.Mode := fgmmTriangles
  818. else
  819. fg.Mode := fgmmTriangleStrip;
  820. end;
  821. finally
  822. strips.Free;
  823. end;
  824. end;
  825. procedure TFormGLSViewer.acSaveTreeViewExecute(Sender: TObject);
  826. begin
  827. if SaveDialog.Execute then
  828. begin
  829. tvScene.SaveToFile(SaveDialog.FileName);
  830. // CurrentStar := GetCurrentDir();
  831. end;
  832. end;
  833. procedure TFormGLSViewer.acSpheresExecute(Sender: TObject);
  834. begin
  835. inherited;
  836. // random spheres
  837. end;
  838. procedure TFormGLSViewer.acLoadTreeViewExecute(Sender: TObject);
  839. begin
  840. inherited;
  841. //
  842. end;
  843. procedure TFormGLSViewer.acViewFlatShadingExecute(Sender: TObject);
  844. begin
  845. ApplyShadeMode;
  846. end;
  847. procedure TFormGLSViewer.acViewHiddenLinesExecute(Sender: TObject);
  848. begin
  849. ApplyShadeMode;
  850. end;
  851. procedure TFormGLSViewer.acViewResetExecute(Sender: TObject);
  852. begin
  853. DoResetCamera;
  854. end;
  855. procedure TFormGLSViewer.acViewFlatLinesExecute(Sender: TObject);
  856. begin
  857. ApplyShadeMode;
  858. end;
  859. procedure TFormGLSViewer.acViewSmoothShadingExecute(Sender: TObject);
  860. begin
  861. ApplyShadeMode;
  862. end;
  863. procedure TFormGLSViewer.acViewWireFrameExecute(Sender: TObject);
  864. begin
  865. ApplyShadeMode;
  866. end;
  867. procedure TFormGLSViewer.acViewZoomInExecute(Sender: TObject);
  868. var
  869. h: Boolean;
  870. begin
  871. FormMouseWheel(Self, [], -120 * 4, Point(0, 0), h);
  872. end;
  873. procedure TFormGLSViewer.acViewZoomOutExecute(Sender: TObject);
  874. var
  875. h: Boolean;
  876. begin
  877. FormMouseWheel(Self, [], 120 * 4, Point(0, 0), h);
  878. end;
  879. procedure TFormGLSViewer.acOptimizeExecute(Sender: TObject);
  880. begin
  881. OptimizeMesh(ffObject.MeshObjects, [mooVertexCache, mooSortByMaterials]);
  882. ffObject.StructureChanged;
  883. SetupFreeFormShading;
  884. end;
  885. procedure TFormGLSViewer.acToolsOptionsExecute(Sender: TObject);
  886. begin
  887. with TGLOptions.Create(Self) do
  888. try
  889. ShowModal;
  890. finally
  891. Free;
  892. end;
  893. end;
  894. procedure TFormGLSViewer.acToolsFaceCullingExecute(Sender: TObject);
  895. begin
  896. acToolsFaceCulling.Checked := not acToolsFaceCulling.Checked;
  897. ApplyFaceCull;
  898. end;
  899. procedure TFormGLSViewer.acToolsInfoExecute(Sender: TObject);
  900. begin
  901. with TGLDialog.Create(Self) do
  902. try
  903. Memo.Lines[0] := 'Triangles: ' +
  904. IntToStr(ffObject.MeshObjects.TriangleCount);
  905. Memo.Lines[1] := 'Area: ' + FloatToStr(ffObject.MeshObjects.Area);
  906. Memo.Lines[2] := 'Volume: ' + FloatToStr(ffObject.MeshObjects.Volume);
  907. ShowModal;
  908. finally
  909. Free;
  910. end;
  911. end;
  912. procedure TFormGLSViewer.acToolsLightingExecute(Sender: TObject);
  913. begin
  914. acToolsLighting.Checked := not acToolsLighting.Checked;
  915. // TBLighting
  916. ApplyShadeMode;
  917. end;
  918. procedure TFormGLSViewer.acToolsShowFPSExecute(Sender: TObject);
  919. begin
  920. acToolsShowFPS.Checked := not acToolsShowFPS.Checked;
  921. ApplyFPS;
  922. end;
  923. procedure TFormGLSViewer.acToolsTexturingExecute(Sender: TObject);
  924. begin
  925. acToolsTexturing.Checked := not acToolsTexturing.Checked;
  926. if acToolsTexturing.Checked then
  927. if lastLoadWithTextures then
  928. ApplyTexturing
  929. else
  930. begin
  931. DoOpen(lastFileName);
  932. end
  933. else
  934. ApplyTexturing;
  935. end;
  936. procedure TFormGLSViewer.acToolsNaviCubeExecute(Sender: TObject);
  937. begin
  938. acToolsNaviCube.Checked := not acToolsNaviCube.Checked;
  939. if acToolsNaviCube.Checked = True then
  940. begin
  941. NaviCube.Visible := True;
  942. Cadencer.Enabled := True;
  943. end
  944. else
  945. begin
  946. NaviCube.Visible := False;
  947. Cadencer.Enabled := False;
  948. end;
  949. snViewer.Invalidate;
  950. end;
  951. // Show Base and Additional Objects
  952. procedure TFormGLSViewer.acPointsExecute(Sender: TObject);
  953. var
  954. I: Integer;
  955. Color: TVector3f;
  956. NumPoints: Integer;
  957. X, Y, Z: Single;
  958. begin
  959. NumPoints := 10000;
  960. GLPoints := TGLPoints(dcWorld.AddNewChild(TGLPoints));
  961. GLPoints.Size := 5.0;
  962. GLPoints.Style := psSmooth;
  963. for I := 0 to NumPoints - 1 do
  964. begin
  965. Color.X := Random();
  966. Color.Y := Random();
  967. Color.Z := Random();
  968. X := Random(10) - 5;
  969. Y := Random(10) - 5;
  970. Z := Random(10) - 5;
  971. GLPoints.Positions.Add(X * 0.05, Y * 0.05, Z * 0.05);
  972. // Fill array of GLPoints
  973. GLPoints.Colors.AddPoint(Color);
  974. end;
  975. // dcWorld.Remove(GLPoints, False);
  976. // GLPoints := TGLPoints(dcWorld.AddNewChild(TGLPoints));
  977. end;
  978. (*
  979. procedure TMainForm.acDeletePoints(Sender: TObject);
  980. var
  981. I: Integer;
  982. Color: TVector3f;
  983. NumPoints: Integer;
  984. X, Y, Z: Single;
  985. begin
  986. NumPoints := 10000;
  987. GLPoints := TGLPoints(dcWorld.AddNewChild(TGLPoints));
  988. for I := 0 to NumPoints - 1 do
  989. begin
  990. Color.X := Random();
  991. Color.Y := Random();
  992. Color.Z := Random();
  993. X := Random(100) - 50;
  994. Y := Random(100) - 50;
  995. Z := Random(100) - 50;
  996. GLPoints.Positions.Add(X * 0.05, Y * 0.05, Z * 0.05);
  997. // Fill array of GLPoints
  998. end;
  999. end;
  1000. *)
  1001. procedure TFormGLSViewer.acFileExitExecute(Sender: TObject);
  1002. begin
  1003. Close;
  1004. end;
  1005. procedure TFormGLSViewer.CadencerProgress(Sender: TObject;
  1006. const deltaTime, newTime: Double);
  1007. begin
  1008. if NaviCube.InactiveTime > 5 then
  1009. begin
  1010. if NaviCube.InactiveTime < 8 then
  1011. Camera.TurnAngle := Camera.TurnAngle + (NaviCube.InactiveTime - 5) *
  1012. deltaTime * 2
  1013. else
  1014. Camera.TurnAngle := Camera.TurnAngle + deltaTime * 6;
  1015. end;
  1016. snViewer.Refresh;
  1017. if Self.Focused then
  1018. snViewer.Invalidate;
  1019. end;
  1020. procedure TFormGLSViewer.TimerTimer(Sender: TObject);
  1021. begin
  1022. // StatusBar.Panels[3].Text := Format('%.1f FPS', [snViewer.FramesPerSecond]);
  1023. snViewer.ResetPerformanceMonitor;
  1024. end;
  1025. //---------------------------------------------------------------------------
  1026. procedure TFormGLSViewer.tvSceneCheckStateChanged(Sender: TCustomTreeView;
  1027. Node: TTreeNode; CheckState: TNodeCheckState);
  1028. begin
  1029. inherited;
  1030. // Add or removed scene's objects
  1031. end;
  1032. //---------------------------------------------------------------------------
  1033. procedure TFormGLSViewer.tvSceneClick(Sender: TObject);
  1034. var
  1035. ObjectName: String;
  1036. Cube: TGLCube;
  1037. begin
  1038. ObjectName := tvScene.Selected.Text;
  1039. case tvScene.Selected.SelectedIndex of
  1040. 4: acPointsExecute(Sender); //Points
  1041. 5: ; //Lines
  1042. 8: // Create GLCube
  1043. begin
  1044. // Scene.FindSceneObject(Cube);
  1045. dcObject.ClearStructureChanged;
  1046. Cube := TGLCube.CreateAsChild(dcObject);
  1047. Cube.CubeDepth := 0.8;
  1048. Cube.CubeHeight := 0.8;
  1049. Cube.CubeWidth := 0.8;
  1050. Cube.Position.SetPoint(1, 0.2, 0);
  1051. Cube.Material.FrontProperties.Diffuse.SetColor(1.0,0.5,0.0);
  1052. end;
  1053. 9: ; //Frustum
  1054. 10: ; //Sphere
  1055. end;
  1056. // ase True of
  1057. //
  1058. // end;
  1059. end;
  1060. procedure TFormGLSViewer.ReadIniFile;
  1061. begin
  1062. inherited;
  1063. IniFile := TIniFile.Create(ChangeFileExt(ParamStr(0), '.ini'));
  1064. try
  1065. Top := IniFile.ReadInteger(Name, 'Top', 100);
  1066. Left := IniFile.ReadInteger(Name, 'Left', 200);
  1067. finally
  1068. IniFile.Free;
  1069. end;
  1070. end;
  1071. procedure TFormGLSViewer.WriteIniFile;
  1072. begin
  1073. IniFile := TIniFile.Create(ChangeFileExt(ParamStr(0), '.ini'));
  1074. with IniFile do
  1075. try
  1076. WriteInteger(Name, 'Top', Top);
  1077. WriteInteger(Name, 'Left', Left);
  1078. // WriteBool(Name, 'InitMax', WindowState = wsMaximized);
  1079. finally
  1080. IniFile.Free;
  1081. end;
  1082. inherited;
  1083. end;
  1084. end.