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.

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