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.

255 lines
9.2 KiB

  1. unit uglcCamera;
  2. { Package: OpenGLCore
  3. Prefix: glc - OpenGL Core
  4. Beschreibung: diese Unit enthält eine Klassen-Kapselung für OpenGL Frustum und Kamera }
  5. {$mode objfpc}{$H+}
  6. interface
  7. uses
  8. Classes, SysUtils,
  9. ugluVector, ugluMatrix;
  10. type
  11. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  12. TglcFrustum = class(TObject)
  13. private
  14. function GetWidth: Single;
  15. function GetHeight: Single;
  16. function GetFOVAngle: Single;
  17. function GetAspectRatio: Single;
  18. protected
  19. fIsOrthogonal: Boolean;
  20. fTop, fBottom, fLeft, fRight, fNear, fFar: Single;
  21. public
  22. property Top : Single read fTop;
  23. property Bottom : Single read fBottom;
  24. property Left : Single read fLeft;
  25. property Right : Single read fRight;
  26. property Near : Single read fNear;
  27. property Far : Single read fFar;
  28. property Width : Single read GetWidth;
  29. property Height : Single read GetHeight;
  30. property FOVAngle : Single read GetFOVAngle;
  31. property AspectRatio : Single read GetAspectRatio;
  32. property IsOrthogonal: Boolean read fIsOrthogonal;
  33. procedure Frustum(const aLeft, aRight, aBottom, aTop, aNear, aFar: Single);
  34. procedure Perspective(const aFOVAngle, aAspectRatio, aNear, aFar: Single);
  35. procedure Ortho(const aLeft, aRight, aBottom, aTop, aNear, aFar: Single);
  36. procedure Activate;
  37. procedure Render;
  38. constructor Create;
  39. end;
  40. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  41. TglcCamera = class(TglcFrustum)
  42. private
  43. fPosition: TgluMatrix4f;
  44. public
  45. property Position: TgluMatrix4f read fPosition write fPosition;
  46. procedure Move(const aVec: TgluVector3f);
  47. procedure Tilt(const aAngle: Single);
  48. procedure Turn(const aAngle: Single);
  49. procedure Roll(const aAngle: Single);
  50. procedure Activate;
  51. function GetRay(const aPos: TgluVector2f): TgluRayf;
  52. constructor Create;
  53. end;
  54. implementation
  55. uses
  56. Math, dglOpenGL;
  57. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  58. //TglcFrustum///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  59. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  60. function TglcFrustum.GetWidth: Single;
  61. begin
  62. result := (fRight - fLeft);
  63. end;
  64. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  65. function TglcFrustum.GetHeight: Single;
  66. begin
  67. result := (fTop - fBottom);
  68. end;
  69. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  70. function TglcFrustum.GetFOVAngle: Single;
  71. begin
  72. result := arctan2(Height/2, fNear)/Pi*360;
  73. end;
  74. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  75. function TglcFrustum.GetAspectRatio: Single;
  76. begin
  77. result := Height / Width;
  78. end;
  79. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  80. procedure TglcFrustum.Frustum(const aLeft, aRight, aBottom, aTop, aNear, aFar: Single);
  81. begin
  82. fIsOrthogonal := false;
  83. fTop := aRight;
  84. fBottom := aLeft;
  85. fLeft := aBottom;
  86. fRight := aTop;
  87. fNear := aNear;
  88. fFar := aFar;
  89. end;
  90. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  91. procedure TglcFrustum.Perspective(const aFOVAngle, aAspectRatio, aNear, aFar: Single);
  92. begin
  93. fIsOrthogonal := false;
  94. fNear := aNear;
  95. fFar := aFar;
  96. fTop := fNear * tan(aFOVAngle / 360 * Pi);
  97. fBottom := -fTop;
  98. fRight := aAspectRatio * fTop;
  99. fLeft := -fRight;
  100. end;
  101. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  102. procedure TglcFrustum.Ortho(const aLeft, aRight, aBottom, aTop, aNear, aFar: Single);
  103. begin
  104. fIsOrthogonal := true;
  105. fLeft := aLeft;
  106. fRight := aRight;
  107. fTop := aTop;
  108. fBottom := aBottom;
  109. fNear := aNear;
  110. fFar := aFar;
  111. end;
  112. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  113. procedure TglcFrustum.Activate;
  114. begin
  115. glMatrixMode(GL_PROJECTION);
  116. glLoadIdentity;
  117. if fIsOrthogonal then
  118. glOrtho(fLeft, fRight, fBottom, fTop, fNear, fFar)
  119. else
  120. glFrustum(fLeft, fRight, fBottom, fTop, fNear, fFar);
  121. glMatrixMode(GL_MODELVIEW);
  122. end;
  123. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  124. procedure TglcFrustum.Render;
  125. var
  126. min, max: TgluVector2f;
  127. begin
  128. min[0] := fLeft / fNear * fFar;
  129. min[1] := fBottom / fNear * fFar;
  130. max[0] := fRight / fNear * fFar;
  131. max[1] := fTop / fNear * fFar;
  132. glBegin(GL_LINE_LOOP);
  133. glVertex3f(fLeft, fTop, -fNear);
  134. glVertex3f(fLeft, fBottom, -fNear);
  135. glVertex3f(fRight, fBottom, -fNear);
  136. glVertex3f(fRight, fTop, -fNear);
  137. glEnd;
  138. glBegin(GL_LINE_LOOP);
  139. glVertex3f(min[0], min[0], -fFar);
  140. glVertex3f(min[0], max[0], -fFar);
  141. glVertex3f(max[0], max[0], -fFar);
  142. glVertex3f(max[0], min[0], -fFar);
  143. glEnd;
  144. glBegin(GL_LINES);
  145. glVertex3f(0, 0, 0); glVertex3f(min[0], min[0], -fFar);
  146. glVertex3f(0, 0, 0); glVertex3f(min[0], max[0], -fFar);
  147. glVertex3f(0, 0, 0); glVertex3f(max[0], max[0], -fFar);
  148. glVertex3f(0, 0, 0); glVertex3f(max[0], min[0], -fFar);
  149. glEnd;
  150. end;
  151. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  152. constructor TglcFrustum.Create;
  153. begin
  154. inherited Create;
  155. fTop := 0;
  156. fBottom := 0;
  157. fLeft := 0;
  158. fRight := 0;
  159. fNear := 0;
  160. fFar := 0;
  161. end;
  162. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  163. //TglcCamera////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  164. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  165. procedure TglcCamera.Move(const aVec: TgluVector3f);
  166. begin
  167. fPosition := gluMatrixMult(gluMatrixTranslate(aVec), fPosition);
  168. end;
  169. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  170. procedure TglcCamera.Tilt(const aAngle: Single);
  171. begin
  172. fPosition := gluMatrixMult(gluMatrixRotate(gluVector3f(1,0,0), aAngle), fPosition);
  173. end;
  174. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  175. procedure TglcCamera.Turn(const aAngle: Single);
  176. begin
  177. fPosition := gluMatrixMult(gluMatrixRotate(gluVector3f(0,1,0), aAngle), fPosition);
  178. end;
  179. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  180. procedure TglcCamera.Roll(const aAngle: Single);
  181. begin
  182. fPosition := gluMatrixMult(gluMatrixRotate(gluVector3f(0,0,1), aAngle), fPosition);
  183. end;
  184. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  185. procedure TglcCamera.Activate;
  186. begin
  187. inherited Activate;
  188. glLoadMatrixf(@fPosition[0, 0]);
  189. end;
  190. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  191. function TglcCamera.GetRay(const aPos: TgluVector2f): TgluRayf;
  192. var
  193. p: TgluVector3f;
  194. begin
  195. if (aPos[0] < 0) then
  196. p[0] := -aPos[0] * fLeft
  197. else
  198. p[0] := aPos[0] * fRight;
  199. if (aPos[1] < 0) then
  200. p[1] := -aPos[1] * fBottom
  201. else
  202. p[1] := aPos[1] * fTop;
  203. if (fIsOrthogonal) then begin
  204. p[2] := 0;
  205. result.p := fPosition * p;
  206. result.v := fPosition * gluVector3f(0, 0, -1);
  207. end else begin
  208. p[2] := -fNear;
  209. result.p := gluVector3f(0, 0, 0);
  210. result.v := fPosition * p;
  211. end;
  212. result := gluRayNormalize(result);
  213. end;
  214. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  215. constructor TglcCamera.Create;
  216. begin
  217. inherited Create;
  218. fPosition := gluMatrixIdentity;
  219. end;
  220. end.