fRayCastD.pas 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. unit fRayCastD;
  2. interface
  3. uses
  4. Winapi.OpenGL,
  5. System.SysUtils,
  6. System.Classes,
  7. Vcl.Graphics,
  8. Vcl.Controls,
  9. Vcl.Forms,
  10. Vcl.Dialogs,
  11. Vcl.StdCtrls,
  12. Vcl.ExtCtrls,
  13. Vcl.ComCtrls,
  14. GLS.Scene,
  15. GLS.Objects,
  16. GLScene.VectorTypes,
  17. GLScene.VectorGeometry,
  18. GLS.BaseClasses,
  19. GLS.Polynomials,
  20. GLS.Texture,
  21. GLS.Cadencer,
  22. GLS.SceneViewer,
  23. GLS.GeomObjects,
  24. GLS.Color,
  25. GLS.Coordinates,
  26. GLScene.Utils;
  27. type
  28. TFormRayCast = class(TForm)
  29. GLSceneViewer1: TGLSceneViewer;
  30. GLScene1: TGLScene;
  31. Sphere1: TGLSphere;
  32. GLLightSource1: TGLLightSource;
  33. GLCamera1: TGLCamera;
  34. BUCast: TButton;
  35. Bevel1: TBevel;
  36. Bevel2: TBevel;
  37. GLCadencer1: TGLCadencer;
  38. DummyCube1: TGLDummyCube;
  39. Panel1: TPanel;
  40. Label1: TLabel;
  41. Label2: TLabel;
  42. Label3: TLabel;
  43. Torus1: TGLTorus;
  44. PaintBox1: TPaintBox;
  45. Plane1: TGLPlane;
  46. Cylinder1: TGLCylinder;
  47. GLCube1: TGLCube;
  48. GLAnnulus1: TGLAnnulus;
  49. procedure BUCastClick(Sender: TObject);
  50. procedure GLCadencer1Progress(Sender: TObject;
  51. const deltaTime, newTime: Double);
  52. private
  53. end;
  54. var
  55. FormRayCast: TFormRayCast;
  56. implementation
  57. {$R *.DFM}
  58. procedure TFormRayCast.BUCastClick(Sender: TObject);
  59. var
  60. o, v, vLight, light, iPoint, iNormal: TGLVector;
  61. up, right, dir: TGLVector;
  62. x, y, dx, dy: Integer;
  63. f, d: Single;
  64. color: TColor;
  65. iObj: TGLBaseSceneObject;
  66. t: Int64;
  67. begin
  68. Screen.Cursor := crHourGlass;
  69. t := StartPrecisionTimer;
  70. // First we extract/prepare the vector we will use during our raycasting
  71. // the origin is the camera position, and factor was grossly adjusted so
  72. // that both view look grossly similar
  73. MakePoint(o, GLCamera1.AbsolutePosition);
  74. MakeVector(dir, GLCamera1.AbsoluteDirection);
  75. MakeVector(up, GLCamera1.AbsoluteUp);
  76. MakePoint(light, GLLightSource1.AbsolutePosition);
  77. right := VectorCrossProduct(dir, up);
  78. f := 1 / 300;
  79. dx := (PaintBox1.Width div 2);
  80. dy := (PaintBox1.Height div 2);
  81. // Cover a square area
  82. for y := 0 to PaintBox1.Height - 1 do
  83. begin
  84. for x := 0 to PaintBox1.Width - 1 do
  85. begin
  86. // Calculate our ray vector for current pixel
  87. v := VectorCombine3(dir, right, up, 1, (x - dx) * f, (dy - y) * f);
  88. // ray vectors must be of unit length!
  89. NormalizeVector(v);
  90. // ray cast
  91. iObj := GLScene1.RayCastIntersect(o, v, @iPoint, @iNormal);
  92. if Assigned(iObj) then
  93. begin
  94. // if something found, calculate vector to light source
  95. vLight := VectorSubtract(light, iPoint);
  96. NormalizeVector(vLight);
  97. // color is given by the normal/lightsource vectors dot-product
  98. // and this intensity is composited with the object's diffuse color
  99. NormalizeVector(iNormal);
  100. d := VectorDotProduct(iNormal, vLight);
  101. if d < 0 then
  102. d := 0;
  103. with (iObj as TGLCustomSceneObject).Material.FrontProperties do
  104. color := ConvertColorVector(Diffuse.color, d);
  105. end
  106. else
  107. color := clGray;
  108. // plot our point
  109. PaintBox1.Canvas.Pixels[x, y] := color;
  110. end;
  111. end;
  112. Caption := Format('RayCast in %.1f ms', [StopPrecisionTimer(t) * 1000]);
  113. Screen.Cursor := crDefault;
  114. end;
  115. procedure TFormRayCast.GLCadencer1Progress(Sender: TObject;
  116. const deltaTime, newTime: Double);
  117. begin
  118. DummyCube1.TurnAngle := newTime * 50;
  119. end;
  120. end.