GXS.InitOpenGL.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. //
  2. // The graphics engine GLXEngine. The unit of GXScene for Delphi
  3. //
  4. unit GXS.InitOpenGL;
  5. (* OpenGL for Initialization in FMX *)
  6. interface
  7. uses
  8. Winapi.OpenGL,
  9. Winapi.OpenGLext,
  10. Winapi.Windows,
  11. FMX.Forms;
  12. type
  13. TgxOpenGL = class
  14. private
  15. CommonCustomForm: TCommonCustomForm;
  16. _WND: HWND;
  17. _DC: HDC;
  18. protected
  19. _PFD: TPixelFormatDescriptor;
  20. _PFI: Integer;
  21. _RC: HGLRC;
  22. procedure SetPFD(const PFD_: TPixelFormatDescriptor);
  23. procedure SetPFI(const PFI_: Integer);
  24. procedure CreateWindow;
  25. procedure DestroyWindow;
  26. procedure ValidatePFD(const PFD_: TPixelFormatDescriptor);
  27. procedure ValidatePFI(const PFI_: Integer);
  28. procedure CreateDC;
  29. procedure DestroyDC;
  30. procedure CreateRC;
  31. procedure DestroyRC;
  32. public
  33. constructor Create;
  34. destructor Destroy; override;
  35. property PFD: TPixelFormatDescriptor read _PFD write SetPFD;
  36. property PFI: Integer read _PFI write SetPFI;
  37. property RC: HGLRC read _RC;
  38. class function DefaultPFD: TPixelFormatDescriptor;
  39. procedure BeginGL;
  40. procedure EndGL;
  41. procedure InitOpenGL;
  42. procedure ApplyPixelFormat(const DC_: HDC);
  43. end;
  44. //-----------------------------------------------------------------------
  45. TgxShader = class
  46. private
  47. protected
  48. _ID: GLuint;
  49. public
  50. constructor Create(const Kind_: GLenum);
  51. destructor Destroy; override;
  52. property ID: GLuint read _ID;
  53. procedure SetSource(const Source_: String);
  54. end;
  55. //-----------------------------------------------------------------------
  56. TgxShaderV = class(TgxShader)
  57. private
  58. protected
  59. public
  60. constructor Create;
  61. destructor Destroy; override;
  62. end;
  63. //-----------------------------------------------------------------------
  64. TgxShaderG = class(TgxShader)
  65. private
  66. protected
  67. public
  68. constructor Create;
  69. destructor Destroy; override;
  70. end;
  71. //-----------------------------------------------------------------------
  72. TgxShaderF = class(TgxShader)
  73. private
  74. protected
  75. public
  76. constructor Create;
  77. destructor Destroy; override;
  78. end;
  79. //-----------------------------------------------------------------------
  80. TgxProgram = class
  81. private
  82. protected
  83. _ID: GLuint;
  84. public
  85. constructor Create;
  86. destructor Destroy; override;
  87. procedure Attach(const Shader_: TgxShader);
  88. procedure Detach(const Shader_: TgxShader);
  89. procedure Link;
  90. procedure Use;
  91. end;
  92. //-----------------------------------------------------------------------
  93. TgxBuffer<_TYPE_: record > = class
  94. public type
  95. _PValue_ = ^_TYPE_;
  96. private
  97. protected
  98. _ID: GLuint;
  99. _Kind: GLenum;
  100. _Count: Integer;
  101. _Head: _PValue_;
  102. procedure SetCount(const Count_: Integer);
  103. public
  104. constructor Create(const Kind_: GLenum);
  105. destructor Destroy; override;
  106. property ID: GLuint read _ID;
  107. property Count: Integer read _Count write SetCount;
  108. procedure Bind;
  109. procedure Unbind;
  110. procedure Map;
  111. procedure Unmap;
  112. end;
  113. //-----------------------------------------------------------------------
  114. TgxBufferV<_TYPE_: record > = class(TgxBuffer<_TYPE_>)
  115. private
  116. protected
  117. public
  118. constructor Create;
  119. destructor Destroy; override;
  120. end;
  121. //-----------------------------------------------------------------------
  122. TgxBufferI<_TYPE_: record > = class(TgxBuffer<_TYPE_>)
  123. private
  124. protected
  125. public
  126. constructor Create;
  127. destructor Destroy; override;
  128. end;
  129. //-----------------------------------------------------------------------
  130. TgxBufferU<_TYPE_: record > = class(TgxBuffer<_TYPE_>)
  131. private
  132. protected
  133. public
  134. constructor Create;
  135. destructor Destroy; override;
  136. end;
  137. //-----------------------------------------------------------------------
  138. TgxArray = class
  139. private
  140. protected
  141. _ID: GLuint;
  142. public
  143. constructor Create;
  144. destructor Destroy; override;
  145. property ID: GLuint read _ID;
  146. procedure BeginBind;
  147. procedure EndBind;
  148. end;
  149. var
  150. GXOpenGL: TgxOpenGL;
  151. //-----------------------------------------------------------------------
  152. implementation
  153. //-----------------------------------------------------------------------
  154. uses
  155. System.SysUtils,
  156. FMX.Platform.Win;
  157. procedure TgxOpenGL.SetPFD(const PFD_: TPixelFormatDescriptor);
  158. begin
  159. DestroyRC;
  160. DestroyDC;
  161. CreateDC;
  162. ValidatePFD(PFD_);
  163. CreateRC;
  164. end;
  165. procedure TgxOpenGL.SetPFI(const PFI_: Integer);
  166. begin
  167. DestroyRC;
  168. DestroyDC;
  169. CreateDC;
  170. ValidatePFI(PFI_);
  171. CreateRC;
  172. end;
  173. // ------------------------------------------------------------------------------
  174. procedure TgxOpenGL.CreateWindow;
  175. begin
  176. CommonCustomForm := TCommonCustomForm.Create(nil);
  177. _WND := WindowHandleToPlatform(CommonCustomForm.Handle).Wnd;
  178. end;
  179. procedure TgxOpenGL.DestroyWindow;
  180. begin
  181. CommonCustomForm.Free;
  182. end;
  183. // ------------------------------------------------------------------------------
  184. procedure TgxOpenGL.ValidatePFD(const PFD_: TPixelFormatDescriptor);
  185. var
  186. I: Integer;
  187. begin
  188. _PFD := PFD_;
  189. I := ChoosePixelFormat(_DC, @_PFD);
  190. Assert(I > 0, 'Not found the PixelFormat with a close setting!');
  191. ValidatePFI(I);
  192. end;
  193. procedure TgxOpenGL.ValidatePFI(const PFI_: Integer);
  194. begin
  195. _PFI := PFI_;
  196. Assert(DescribePixelFormat(_DC, _PFI, SizeOf(TPixelFormatDescriptor), _PFD),
  197. 'Not found the PixelFormat of the index!');
  198. end;
  199. // ------------------------------------------------------------------------------
  200. procedure TgxOpenGL.CreateDC;
  201. begin
  202. _DC := GetDC(_WND);
  203. end;
  204. procedure TgxOpenGL.DestroyDC;
  205. begin
  206. ReleaseDC(0, _DC);
  207. end;
  208. // ------------------------------------------------------------------------------
  209. procedure TgxOpenGL.CreateRC;
  210. begin
  211. ApplyPixelFormat(_DC);
  212. _RC := wglCreateContext(_DC);
  213. end;
  214. procedure TgxOpenGL.DestroyRC;
  215. begin
  216. wglDeleteContext(_RC);
  217. end;
  218. constructor TgxOpenGL.Create;
  219. begin
  220. inherited;
  221. CreateWindow;
  222. CreateDC;
  223. ValidatePFD(DefaultPFD);
  224. CreateRC;
  225. InitOpenGL;
  226. end;
  227. destructor TgxOpenGL.Destroy;
  228. begin
  229. DestroyRC;
  230. DestroyDC;
  231. DestroyWindow;
  232. inherited;
  233. end;
  234. // ------------------------------------------------------------------------------
  235. class function TgxOpenGL.DefaultPFD: TPixelFormatDescriptor;
  236. begin
  237. with Result do
  238. begin
  239. nSize := SizeOf(TPixelFormatDescriptor);
  240. nVersion := 1;
  241. dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
  242. iPixelType := PFD_TYPE_RGBA;
  243. cColorBits := 24;
  244. cRedBits := 0;
  245. cRedShift := 0;
  246. cGreenBits := 0;
  247. cGreenShift := 0;
  248. cBlueBits := 0;
  249. cBlueShift := 0;
  250. cAlphaBits := 0;
  251. cAlphaShift := 0;
  252. cAccumBits := 0;
  253. cAccumRedBits := 0;
  254. cAccumGreenBits := 0;
  255. cAccumBlueBits := 0;
  256. cAccumAlphaBits := 0;
  257. cDepthBits := 32;
  258. cStencilBits := 0;
  259. cAuxBuffers := 0;
  260. iLayerType := PFD_MAIN_PLANE;
  261. bReserved := 0;
  262. dwLayerMask := 0;
  263. dwVisibleMask := 0;
  264. dwDamageMask := 0;
  265. end;
  266. end;
  267. // ------------------------------------------------------------------------------
  268. procedure TgxOpenGL.BeginGL;
  269. begin
  270. wglMakeCurrent(_DC, _RC);
  271. end;
  272. procedure TgxOpenGL.EndGL;
  273. begin
  274. wglMakeCurrent(_DC, 0);
  275. end;
  276. // ------------------------------------------------------------------------------
  277. procedure TgxOpenGL.InitOpenGL;
  278. begin
  279. BeginGL;
  280. glEnable(GL_DEPTH_TEST);
  281. glEnable(GL_CULL_FACE);
  282. EndGL;
  283. end;
  284. // ------------------------------------------------------------------------------
  285. procedure TgxOpenGL.ApplyPixelFormat(const DC_: HDC);
  286. begin
  287. Assert(SetPixelFormat(DC_, _PFI, @_PFD), 'SetPixelFormat() is failed!');
  288. end;
  289. // ------------------------------------------------------------------------------
  290. constructor TgxShader.Create(const Kind_: GLenum);
  291. begin
  292. inherited Create;
  293. _ID := glCreateShader(Kind_);
  294. end;
  295. destructor TgxShader.Destroy;
  296. begin
  297. glDeleteShader(_ID);
  298. inherited;
  299. end;
  300. // ------------------------------------------------------------------------------
  301. procedure TgxShader.SetSource(const Source_: String);
  302. var
  303. P: PAnsiChar;
  304. N: GLint;
  305. E: GLint;
  306. Cs: array of PGLchar;
  307. CsN: GLsizei;
  308. begin
  309. P := PAnsiChar(AnsiString(Source_));
  310. N := Length(Source_);
  311. glShaderSource(_ID, 1, @P, @N);
  312. glCompileShader(_ID);
  313. glGetShaderiv(_ID, GL_COMPILE_STATUS, @E);
  314. if E = GL_FALSE then
  315. begin
  316. glGetShaderiv(_ID, GL_INFO_LOG_LENGTH, @N);
  317. SetLength(Cs, N);
  318. glGetShaderInfoLog(_ID, N, @CsN, @Cs[0]);
  319. Assert(False, AnsiString(Cs));
  320. end;
  321. end;
  322. // ------------------------------------------------------------------------------
  323. constructor TgxShaderV.Create;
  324. begin
  325. inherited Create(GL_VERTEX_SHADER);
  326. end;
  327. destructor TgxShaderV.Destroy;
  328. begin
  329. inherited;
  330. end;
  331. // ------------------------------------------------------------------------------
  332. constructor TgxShaderG.Create;
  333. begin
  334. inherited Create(GL_GEOMETRY_SHADER);
  335. end;
  336. destructor TgxShaderG.Destroy;
  337. begin
  338. inherited;
  339. end;
  340. // ------------------------------------------------------------------------------
  341. constructor TgxShaderF.Create;
  342. begin
  343. inherited Create(GL_FRAGMENT_SHADER);
  344. end;
  345. destructor TgxShaderF.Destroy;
  346. begin
  347. inherited;
  348. end;
  349. // ------------------------------------------------------------------------------
  350. constructor TgxProgram.Create;
  351. begin
  352. inherited;
  353. _ID := glCreateProgram;
  354. end;
  355. destructor TgxProgram.Destroy;
  356. begin
  357. glDeleteProgram(_ID);
  358. inherited;
  359. end;
  360. // ------------------------------------------------------------------------------
  361. procedure TgxProgram.Attach(const Shader_: TgxShader);
  362. begin
  363. glAttachShader(_ID, Shader_.ID);
  364. end;
  365. procedure TgxProgram.Detach(const Shader_: TgxShader);
  366. begin
  367. glDetachShader(_ID, Shader_.ID);
  368. end;
  369. // ------------------------------------------------------------------------------
  370. procedure TgxProgram.Link;
  371. begin
  372. glLinkProgram(_ID);
  373. end;
  374. // ------------------------------------------------------------------------------
  375. procedure TgxProgram.Use;
  376. begin
  377. glUseProgram(_ID);
  378. end;
  379. // ------------------------------------------------------------------------------
  380. procedure TgxBuffer<_TYPE_>.SetCount(const Count_: Integer);
  381. begin
  382. _Count := Count_;
  383. Bind;
  384. glBufferData(_Kind, SizeOf(_TYPE_) * _Count, nil, GL_DYNAMIC_DRAW);
  385. Unbind;
  386. end;
  387. // ------------------------------------------------------------------------------
  388. constructor TgxBuffer<_TYPE_>.Create(const Kind_: GLenum);
  389. begin
  390. inherited Create;
  391. glGenBuffers(1, @_ID);
  392. _Kind := Kind_;
  393. Count := 0;
  394. end;
  395. // ------------------------------------------------------------------------------
  396. destructor TgxBuffer<_TYPE_>.Destroy;
  397. begin
  398. glDeleteBuffers(1, @_ID);
  399. inherited;
  400. end;
  401. // ------------------------------------------------------------------------------
  402. procedure TgxBuffer<_TYPE_>.Bind;
  403. begin
  404. glBindBuffer(_Kind, _ID);
  405. end;
  406. procedure TgxBuffer<_TYPE_>.Unbind;
  407. begin
  408. glBindBuffer(_Kind, 0);
  409. end;
  410. // ------------------------------------------------------------------------------
  411. procedure TgxBuffer<_TYPE_>.Map;
  412. begin
  413. Bind;
  414. _Head := glMapBuffer(_Kind, GL_READ_WRITE);
  415. end;
  416. procedure TgxBuffer<_TYPE_>.Unmap;
  417. begin
  418. glUnmapBuffer(_Kind);
  419. Unbind;
  420. end;
  421. constructor TgxBufferV<_TYPE_>.Create;
  422. begin
  423. inherited Create(GL_ARRAY_BUFFER);
  424. end;
  425. destructor TgxBufferV<_TYPE_>.Destroy;
  426. begin
  427. inherited;
  428. end;
  429. // ------------------------------------------------------------------------------
  430. constructor TgxBufferI<_TYPE_>.Create;
  431. begin
  432. inherited Create(GL_ELEMENT_ARRAY_BUFFER);
  433. end;
  434. destructor TgxBufferI<_TYPE_>.Destroy;
  435. begin
  436. inherited;
  437. end;
  438. // ------------------------------------------------------------------------------
  439. constructor TgxBufferU<_TYPE_>.Create;
  440. begin
  441. inherited Create(GL_UNIFORM_BUFFER);
  442. end;
  443. destructor TgxBufferU<_TYPE_>.Destroy;
  444. begin
  445. inherited;
  446. end;
  447. // ------------------------------------------------------------------------------
  448. constructor TgxArray.Create;
  449. begin
  450. inherited Create;
  451. glGenVertexArrays(1, @_ID);
  452. end;
  453. destructor TgxArray.Destroy;
  454. begin
  455. glDeleteVertexArrays(1, @_ID);
  456. inherited;
  457. end;
  458. // ------------------------------------------------------------------------------
  459. procedure TgxArray.BeginBind;
  460. begin
  461. glBindVertexArray(_ID);
  462. end;
  463. procedure TgxArray.EndBind;
  464. begin
  465. glBindVertexArray(0);
  466. end;
  467. //==========================================================================
  468. initialization
  469. //==========================================================================
  470. GXOpenGL := TgxOpenGL.Create;
  471. GXOpenGL.BeginGL;
  472. InitOpenGLext;
  473. finalization
  474. GXOpenGL.EndGL;
  475. GXOpenGL.Free;
  476. end.