2
0

OpenGL.InitVCL.pas 9.9 KB

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