You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

428 lines
19 KiB

  1. unit uglcLight;
  2. { Package: OpenGLCore
  3. Prefix: glc - OpenGL Core
  4. Beschreibung: diese Unit enthält eine Klassen-Kapselung der OpenGL Licht- und Material-Objekte }
  5. {$mode objfpc}{$H+}
  6. interface
  7. uses
  8. Classes, SysUtils, {$IFNDEF OPENGL_ES}dglOpenGl{$ELSE}dglOpenGLES{$ENDIF}, ugluVector, uglcTypes;
  9. type
  10. TglcMaterialRec = packed record
  11. Ambient: TgluVector4f;
  12. Diffuse: TgluVector4f;
  13. Specular: TgluVector4f;
  14. Emission: TgluVector4f;
  15. Shininess: GLfloat;
  16. end;
  17. PglcMaterialRec = ^TglcMaterialRec;
  18. TglcLightType = (
  19. ltGlobal = 0,
  20. ltPoint = 1,
  21. ltSpot = 2);
  22. TglcLightRec = packed record
  23. Ambient: TgluVector4f;
  24. Diffuse: TgluVector4f;
  25. Specular: TgluVector4f;
  26. Position: TgluVector4f;
  27. SpotDirection: TgluVector3f;
  28. SpotExponent: GLfloat;
  29. SpotCutoff: GLfloat;
  30. ConstantAtt: GLfloat;
  31. LinearAtt: GLfloat;
  32. QuadraticAtt: GLfloat;
  33. end;
  34. PglcLightRec = ^TglcLightRec;
  35. const
  36. MAT_DEFAULT_AMBIENT: TgluVector4f = (0.2, 0.2, 0.2, 1.0);
  37. MAT_DEFAULT_DIFFUSE: TgluVector4f = (0.8, 0.8, 0.8, 1.0);
  38. MAT_DEFAULT_SPECULAR: TgluVector4f = (0.5, 0.5, 0.5, 1.0);
  39. MAT_DEFAULT_EMISSION: TgluVector4f = (0.0, 0.0, 0.0, 1.0);
  40. MAT_DEFAULT_SHININESS: GLfloat = 50.0;
  41. LIGHT_DEFAULT_AMBIENT: TgluVector4f = (0.4, 0.4, 0.4, 1.0);
  42. LIGHT_DEFAULT_DIFFUSE: TgluVector4f = (0.7, 0.7, 0.7, 1.0);
  43. LIGHT_DEFAULT_SPECULAR: TgluVector4f = (0.9, 0.9, 0.9, 1.0);
  44. LIGHT_DEFAULT_POSITION: TgluVector4f = (0.0, 0.0, 1.0, 0.0);
  45. LIGHT_DEFAULT_SPOT_DIRECTION: TgluVector3f = (0.0, 0.0, -1.0);
  46. LIGHT_DEFAULT_SPOT_EXPONENT: GLfloat = 0.0;
  47. LIGHT_DEFAULT_SPOT_CUTOFF: GLfloat = 180.0;
  48. LIGHT_DEFAULT_CONSTANT_ATT: GLfloat = 1.0;
  49. LIGHT_DEFAULT_LINEAR_ATT: GLfloat = 0.0;
  50. LIGHT_DEFAULT_QUADRATIC_ATT: GLfloat = 0.0;
  51. type
  52. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  53. TglcMaterial = class(TObject)
  54. private
  55. fData: TglcMaterialRec;
  56. public
  57. property Diffuse: TgluVector4f read fData.Diffuse write fData.Diffuse;
  58. property Ambient: TgluVector4f read fData.Ambient write fData.Ambient;
  59. property Specular: TgluVector4f read fData.Specular write fData.Specular;
  60. property Emission: TgluVector4f read fData.Emission write fData.Emission;
  61. property Shininess: GLfloat read fData.Shininess write fData.Shininess;
  62. property Data: TglcMaterialRec read fData write fData;
  63. procedure Bind(const aFace: TglcFace);
  64. class procedure Bind(const aFace: TglcFace; const aMaterial: TglcMaterialRec);
  65. class function DefaultValues: TglcMaterialRec;
  66. constructor Create;
  67. end;
  68. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  69. EglcLight = class(Exception);
  70. TglcLight = class(TObject)
  71. private
  72. function GetDataPtr: PglcLightRec;
  73. protected
  74. fData: TglcLightRec;
  75. procedure SetAmbient (const aValue: TgluVector4f); virtual;
  76. procedure SetDiffuse (const aValue: TgluVector4f); virtual;
  77. procedure SetSpecular (const aValue: TgluVector4f); virtual;
  78. procedure SetPosition4f (const aValue: TgluVector4f); virtual;
  79. procedure SetSpotDirection(const aValue: TgluVector3f); virtual;
  80. procedure SetSpotExponent (const aValue: GLfloat); virtual;
  81. procedure SetSpotCutoff (const aValue: GLfloat); virtual;
  82. procedure SetConstantAtt (const aValue: GLfloat); virtual;
  83. procedure SetLinearAtt (const aValue: GLfloat); virtual;
  84. procedure SetQuadraticAtt (const aValue: GLfloat); virtual;
  85. procedure SetData (const aValue: TglcLightRec); virtual;
  86. property Ambient: TgluVector4f read fData.Ambient write SetAmbient;
  87. property Diffuse: TgluVector4f read fData.Diffuse write SetDiffuse;
  88. property Specular: TgluVector4f read fData.Specular write SetSpecular;
  89. property Position4f: TgluVector4f read fData.Position write SetPosition4f;
  90. property SpotDirection: TgluVector3f read fData.SpotDirection write SetSpotDirection;
  91. property SpotExponent: GLfloat read fData.SpotExponent write SetSpotExponent;
  92. property SpotCutoff: GLfloat read fData.SpotCutoff write SetSpotCutoff;
  93. property ConstantAtt: GLfloat read fData.ConstantAtt write SetConstantAtt;
  94. property LinearAtt: GLfloat read fData.LinearAtt write SetLinearAtt;
  95. property QuadraticAtt: GLfloat read fData.QuadraticAtt write SetQuadraticAtt;
  96. public
  97. property Data: TglcLightRec read fData write SetData;
  98. property DataPtr: PglcLightRec read GetDataPtr;
  99. procedure Bind(const aLightID: GLenum; const aEnableLighting: Boolean = false); virtual; abstract;
  100. class procedure Bind(const aLightID: GLenum; const aLight: TglcLightRec;
  101. const aEnableLighting: Boolean; const aLightType: TglcLightType);
  102. class procedure Unbind(const aLightID: GLenum; const aDisableLighting: Boolean = true);
  103. class function DefaultValues: TglcLightRec; virtual;
  104. constructor Create;
  105. end;
  106. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  107. TglcLightGlobal = class(TglcLight)
  108. private
  109. function GetDirection: TgluVector3f;
  110. procedure SetDirection(aValue: TgluVector3f);
  111. public
  112. property Ambient;
  113. property Diffuse;
  114. property Specular;
  115. property Direction: TgluVector3f read GetDirection write SetDirection;
  116. procedure Bind(const aLightID: GLenum; const aEnableLighting: Boolean = false); override;
  117. end;
  118. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  119. TglcLightPoint = class(TglcLight)
  120. private
  121. fMaxSize: Single;
  122. fSizeFactor: Single;
  123. function GetPosition: TgluVector3f;
  124. procedure SetPosition(const aValue: TgluVector3f);
  125. protected
  126. procedure SetMaxSize (const aValue: Single); virtual;
  127. procedure SetSizeFactor(const aValue: Single); virtual;
  128. public
  129. property Ambient;
  130. property Diffuse;
  131. property Specular;
  132. property ConstantAtt;
  133. property LinearAtt;
  134. property QuadraticAtt;
  135. property MaxSize: Single read fMaxSize write SetMaxSize;
  136. property SizeFactor: Single read fSizeFactor write SetSizeFactor;
  137. property Position: TgluVector3f read GetPosition write SetPosition;
  138. procedure Bind(const aLightID: GLenum; const aEnableLighting: Boolean = false); override;
  139. constructor Create;
  140. end;
  141. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  142. TglcLightSpot = class(TglcLightPoint)
  143. public
  144. property SpotCutoff;
  145. property SpotDirection;
  146. property SpotExponent;
  147. procedure Bind(const aLightID: GLenum; const aEnableLighting: Boolean = false); override;
  148. end;
  149. implementation
  150. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  151. //TglcMaterial//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  152. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  153. procedure TglcMaterial.Bind(const aFace: TglcFace);
  154. begin
  155. Bind(aFace, fData);
  156. end;
  157. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  158. class procedure TglcMaterial.Bind(const aFace: TglcFace; const aMaterial: TglcMaterialRec);
  159. begin
  160. glMaterialfv(GLenum(aFace), GL_AMBIENT, @aMaterial.Ambient[0]);
  161. glMaterialfv(GLenum(aFace), GL_DIFFUSE, @aMaterial.Diffuse[0]);
  162. glMaterialfv(GLenum(aFace), GL_EMISSION, @aMaterial.Emission[0]);
  163. glMaterialfv(GLenum(aFace), GL_SPECULAR, @aMaterial.Specular[0]);
  164. glMaterialfv(GLenum(aFace), GL_SHININESS, @aMaterial.Shininess);
  165. end;
  166. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  167. class function TglcMaterial.DefaultValues: TglcMaterialRec;
  168. begin
  169. result.Ambient := MAT_DEFAULT_AMBIENT;
  170. result.Diffuse := MAT_DEFAULT_DIFFUSE;
  171. result.Specular := MAT_DEFAULT_SPECULAR;
  172. result.Emission := MAT_DEFAULT_EMISSION;
  173. result.Shininess := MAT_DEFAULT_SHININESS;
  174. end;
  175. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  176. constructor TglcMaterial.Create;
  177. begin
  178. inherited Create;
  179. fData := DefaultValues;
  180. end;
  181. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  182. //TglcLight/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  183. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  184. function TglcLight.GetDataPtr: PglcLightRec;
  185. begin
  186. result := @fData;
  187. end;
  188. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  189. procedure TglcLight.SetAmbient(const aValue: TgluVector4f);
  190. begin
  191. fData.Ambient := aValue;
  192. end;
  193. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  194. procedure TglcLight.SetDiffuse(const aValue: TgluVector4f);
  195. begin
  196. fData.Diffuse := aValue;
  197. end;
  198. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  199. procedure TglcLight.SetSpecular(const aValue: TgluVector4f);
  200. begin
  201. fData.Specular := aValue;
  202. end;
  203. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  204. procedure TglcLight.SetPosition4f(const aValue: TgluVector4f);
  205. begin
  206. fData.Position := aValue;
  207. end;
  208. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  209. procedure TglcLight.SetConstantAtt(const aValue: GLfloat);
  210. begin
  211. fData.ConstantAtt := aValue;
  212. end;
  213. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  214. procedure TglcLight.SetLinearAtt(const aValue: GLfloat);
  215. begin
  216. fData.LinearAtt := aValue;
  217. end;
  218. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  219. procedure TglcLight.SetQuadraticAtt(const aValue: GLfloat);
  220. begin
  221. fData.QuadraticAtt := aValue;
  222. end;
  223. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  224. procedure TglcLight.SetSpotDirection(const aValue: TgluVector3f);
  225. begin
  226. fData.SpotDirection := aValue;
  227. end;
  228. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  229. procedure TglcLight.SetSpotExponent(const aValue: GLfloat);
  230. begin
  231. fData.SpotExponent := aValue;
  232. end;
  233. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  234. procedure TglcLight.SetSpotCutoff(const aValue: GLfloat);
  235. begin
  236. fData.SpotCutoff := aValue;
  237. end;
  238. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  239. procedure TglcLight.SetData(const aValue: TglcLightRec);
  240. begin
  241. fData := aValue;
  242. end;
  243. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  244. class procedure TglcLight.Bind(const aLightID: GLenum; const aLight: TglcLightRec;
  245. const aEnableLighting: Boolean; const aLightType: TglcLightType);
  246. begin
  247. glEnable(aLightID);
  248. if (aEnableLighting) then
  249. glEnable(GL_LIGHTING);
  250. if (aLightType in [ltGlobal, ltPoint, ltSpot]) then begin
  251. glLightfv(aLightID, GL_AMBIENT, @aLight.Ambient[0]);
  252. glLightfv(aLightID, GL_DIFFUSE, @aLight.Diffuse[0]);
  253. glLightfv(aLightID, GL_SPECULAR, @aLight.Specular[0]);
  254. glLightfv(aLightID, GL_POSITION, @aLight.Position[0]);
  255. end else begin
  256. glLightfv(aLightID, GL_AMBIENT, @LIGHT_DEFAULT_AMBIENT[0]);
  257. glLightfv(aLightID, GL_DIFFUSE, @LIGHT_DEFAULT_DIFFUSE[0]);
  258. glLightfv(aLightID, GL_SPECULAR, @LIGHT_DEFAULT_SPECULAR[0]);
  259. glLightfv(aLightID, GL_POSITION, @LIGHT_DEFAULT_POSITION[0]);
  260. end;
  261. if (aLightType in [ltPoint, ltSpot]) then begin
  262. glLightfv(aLightID, GL_CONSTANT_ATTENUATION, @aLight.ConstantAtt);
  263. glLightfv(aLightID, GL_LINEAR_ATTENUATION, @aLight.LinearAtt);
  264. glLightfv(aLightID, GL_QUADRATIC_ATTENUATION, @aLight.QuadraticAtt);
  265. end else begin
  266. glLightfv(aLightID, GL_CONSTANT_ATTENUATION, @LIGHT_DEFAULT_CONSTANT_ATT);
  267. glLightfv(aLightID, GL_LINEAR_ATTENUATION, @LIGHT_DEFAULT_LINEAR_ATT);
  268. glLightfv(aLightID, GL_QUADRATIC_ATTENUATION, @LIGHT_DEFAULT_QUADRATIC_ATT);
  269. end;
  270. if (aLightType in [ltSpot]) then begin
  271. glLightfv(aLightID, GL_SPOT_DIRECTION, @aLight.SpotDirection[0]);
  272. glLightfv(aLightID, GL_SPOT_EXPONENT, @aLight.SpotExponent);
  273. glLightfv(aLightID, GL_SPOT_CUTOFF, @aLight.SpotCutoff);
  274. end else begin
  275. glLightfv(aLightID, GL_SPOT_DIRECTION, @LIGHT_DEFAULT_SPOT_DIRECTION[0]);
  276. glLightfv(aLightID, GL_SPOT_EXPONENT, @LIGHT_DEFAULT_SPOT_EXPONENT);
  277. glLightfv(aLightID, GL_SPOT_CUTOFF, @LIGHT_DEFAULT_SPOT_CUTOFF);
  278. end;
  279. end;
  280. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  281. class procedure TglcLight.Unbind(const aLightID: GLenum; const aDisableLighting: Boolean);
  282. begin
  283. glDisable(aLightID);
  284. if aDisableLighting then
  285. glDisable(GL_LIGHTING);
  286. end;
  287. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  288. class function TglcLight.DefaultValues: TglcLightRec;
  289. begin
  290. result.Ambient := LIGHT_DEFAULT_AMBIENT;
  291. result.Diffuse := LIGHT_DEFAULT_DIFFUSE;
  292. result.Specular := LIGHT_DEFAULT_SPECULAR;
  293. result.Position := LIGHT_DEFAULT_POSITION;
  294. result.SpotDirection := LIGHT_DEFAULT_SPOT_DIRECTION;
  295. result.SpotExponent := LIGHT_DEFAULT_SPOT_EXPONENT;
  296. result.SpotCutoff := LIGHT_DEFAULT_SPOT_CUTOFF;
  297. result.ConstantAtt := LIGHT_DEFAULT_CONSTANT_ATT;
  298. result.LinearAtt := LIGHT_DEFAULT_LINEAR_ATT;
  299. result.QuadraticAtt := LIGHT_DEFAULT_QUADRATIC_ATT;
  300. end;
  301. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  302. constructor TglcLight.Create;
  303. begin
  304. inherited Create;
  305. fData := DefaultValues;
  306. end;
  307. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  308. //TglcLightGlobal///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  309. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  310. function TglcLightGlobal.GetDirection: TgluVector3f;
  311. begin
  312. result := gluVector3f(Position4f);
  313. end;
  314. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  315. procedure TglcLightGlobal.SetDirection(aValue: TgluVector3f);
  316. begin
  317. Position4f := gluVector4f(aValue, 0.0);
  318. end;
  319. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  320. procedure TglcLightGlobal.Bind(const aLightID: GLenum; const aEnableLighting: Boolean);
  321. begin
  322. TglcLight.Bind(aLightID, fData, aEnableLighting, ltGlobal);
  323. end;
  324. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  325. //TglcLightPoint////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  326. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  327. function TglcLightPoint.GetPosition: TgluVector3f;
  328. begin
  329. result := gluVector3f(fData.Position);
  330. end;
  331. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  332. procedure TglcLightPoint.SetPosition(const aValue: TgluVector3f);
  333. begin
  334. SetPosition4f(gluVector4f(aValue, 1.0));
  335. end;
  336. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  337. procedure TglcLightPoint.SetMaxSize(const aValue: Single);
  338. begin
  339. fMaxSize := aValue;
  340. end;
  341. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  342. procedure TglcLightPoint.SetSizeFactor(const aValue: Single);
  343. begin
  344. fSizeFactor := aValue;
  345. end;
  346. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  347. procedure TglcLightPoint.Bind(const aLightID: GLenum; const aEnableLighting: Boolean);
  348. begin
  349. TglcLight.Bind(aLightID, fData, aEnableLighting, ltPoint);
  350. end;
  351. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  352. constructor TglcLightPoint.Create;
  353. begin
  354. inherited Create;
  355. Position := gluVector3f(0.0, 0.0, 0.0);
  356. fMaxSize := 0;
  357. fSizeFactor := 1.0;
  358. end;
  359. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  360. //TglcLightSpot/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  361. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  362. procedure TglcLightSpot.Bind(const aLightID: GLenum; const aEnableLighting: Boolean);
  363. begin
  364. TglcLight.Bind(aLightID, fData, aEnableLighting, ltSpot);
  365. end;
  366. end.