ArenaZ
499 строк · 14.2 Кб
1unit Main;
2
3{$mode objfpc}{$H+}
4
5interface
6
7uses
8{$IFDEF WINDOWS} Windows, {$ENDIF}
9SysUtils, Classes, Math,
10Graphics, Controls, Forms, Dialogs, Buttons,
11StdCtrls, ComCtrls, ExtCtrls,
12
13{GLWin32Viewer,} GLCrossPlatform, GLBaseClasses, GLScene, GLGeomObjects,
14GLObjects, GLCoordinates, GLGraph, GLVectorLists, OpenGLTokens,
15GLMesh, GLHUDObjects, GLBitmapFont, GLWindowsFont,
16GLVectorGeometry, GLColor, GLTexture, GLContext, GLCadencer, GLLCLViewer;
17
18
19type
20TMainForm = class(TForm)
21StatusBar: TStatusBar;
22GLScene1: TGLScene;
23GLSceneViewer1: TGLSceneViewer;
24CameraCube: TGLDummyCube;
25Camera: TGLCamera;
26ObjectsCube: TGLDummyCube;
27ArrowZ: TGLArrowLine;
28ArrowY: TGLArrowLine;
29ArrowX: TGLArrowLine;
30
31GLLightSource1: TGLLightSource;
32Panel1: TPanel;
33Label1: TLabel;
34Label2: TLabel;
35Label3: TLabel;
36Label4: TLabel;
37Label5: TLabel;
38Label6: TLabel;
39Label7: TLabel;
40Label8: TLabel;
41Label9: TLabel;
42Label10: TLabel;
43Label12: TLabel;
44
45xRadiusTrackBar: TTrackBar;
46yRadiusTrackBar: TTrackBar;
47zRadiusTrackBar: TTrackBar;
48
49VCurveTrackBar: TTrackBar;
50HCurveTrackBar: TTrackBar;
51GridCheckBox: TCheckBox;
52ArrowsCheckBox: TCheckBox;
53SlicesTrackBar: TTrackBar;
54StacksTrackBar: TTrackBar;
55TopCapRadioGroup: TRadioGroup;
56BottomTrackBar: TTrackBar;
57TopTrackBar: TTrackBar;
58StartTrackBar: TTrackBar;
59StopTrackBar: TTrackBar;
60
61BottomCapRadioGroup: TRadioGroup;
62Button1: TButton;
63GLXYZGridXZ: TGLXYZGrid;
64GLWindowsBitmapFont1: TGLWindowsBitmapFont;
65GLHUDText: TGLHUDText;
66Button2: TButton;
67GLCadencer1: TGLCadencer;
68GLLightSource: TGLLightSource;
69GLSuperellipsoid: TGLSuperellipsoid;
70GLMesh: TGLMesh;
71
72procedure FormShow(Sender: TObject);
73procedure FormCreate(Sender: TObject);
74procedure GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
75Shift: TShiftState; X, Y: Integer);
76procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
77X, Y: Integer);
78procedure GLSceneViewer1MouseUp(Sender: TObject; Button: TMouseButton;
79Shift: TShiftState; X, Y: Integer);
80
81procedure RadiusTrackBarChange(Sender: TObject);
82procedure VCurveTrackBarChange(Sender: TObject);
83procedure HCurveTrackBarChange(Sender: TObject);
84procedure SlicesTrackBarChange(Sender: TObject);
85procedure StacksTrackBarChange(Sender: TObject);
86procedure GridCheckBoxClick(Sender: TObject);
87procedure ArrowsCheckBoxClick(Sender: TObject);
88procedure TopTrackBarChange(Sender: TObject);
89procedure BottomTrackBarChange(Sender: TObject);
90procedure TopCapRadioGroupClick(Sender: TObject);
91procedure BottomCapRadioGroupClick(Sender: TObject);
92procedure StartTrackBarChange(Sender: TObject);
93procedure StopTrackBarChange(Sender: TObject);
94procedure Button1Click(Sender: TObject);
95procedure checkclick(Sender: TObject);
96procedure CheckBoxClick(Sender: TObject);
97procedure Button2Click(Sender: TObject);
98private
99
100MousePoint: TPoint;
101Superellipsoids: array[0..5, 0..5] of TGLSuperellipsoid;
102procedure ShowCameraLocation;
103procedure ShowFocalLength;
104procedure ShowDisplacement;
105procedure ShowSuperellipsoid;
106public
107
108end;
109
110var
111MainForm: TMainForm;
112
113implementation
114
115{$R *.lfm}
116{$R CURSORS.RES}
117
118const
119crLightxz = 1;
120crLightyz = 2;
121crLightxy = 3;
122crSlidexy = 4;
123crSlideyz = 5;
124crSlidexz = 6;
125crRotate = 7;
126crZoom = 8;
127crHandMove = 9;
128
129procedure TMainForm.ArrowsCheckBoxClick(Sender: TObject);
130begin
131ArrowX.Visible := not ArrowsCheckBox.Checked;
132ArrowY.Visible := ArrowX.Visible;
133ArrowZ.Visible := ArrowX.Visible;
134end;
135
136procedure TMainForm.FormCreate(Sender: TObject);
137begin
138Screen.Cursors[crSlidexy] := LoadCursor(HInstance, 'SLIDEXY');
139Screen.Cursors[crRotate] := LoadCursor(HInstance, 'ROTATE');
140Screen.Cursors[crZoom] := LoadCursor(HInstance, 'ZOOM');
141
142Randomize;
143GLSuperellipsoid := TGLSuperellipsoid(GLScene1.Objects.AddNewChild(TGLSuperellipsoid));
144GLSuperellipsoid.Direction.SetVector(0, 0, 1);
145GLSuperellipsoid.Up.SetVector(0, 1, 0);
146GLSuperellipsoid.Position.SetPoint(0, 1, 0);
147GLSuperellipsoid.Material.FrontProperties.Ambient.RandomColor;
148GLSuperellipsoid.Material.FrontProperties.Diffuse.RandomColor;
149GLSuperellipsoid.Material.FrontProperties.Shininess := 100;
150
151end;
152
153procedure TMainForm.FormShow(Sender: TObject);
154begin
155ShowCameraLocation;
156{ focallength: right mouse drag up/down }
157ShowFocalLength;
158{ displace origin: x axis: ctrl/left mouse drag left/right
159y axis: ctrl/left mouse drag up/down }
160ShowDisplacement;
161{ move light: x axis: ctrl right mouse drag left/right
162y axis: ctrl right mouse drag up/down
163z axis: shift right mouse drag up/down }
164ShowSuperellipsoid;
165end;
166
167procedure TMainForm.GLSceneViewer1MouseDown(Sender: TObject;
168Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
169begin
170MousePoint.X := X;
171MousePoint.Y := Y;
172if ssShift in Shift then
173begin
174if ssLeft in Shift then
175Screen.Cursor := crZoom
176else if ssRight in Shift then
177Screen.Cursor := crLightxz;
178end
179else if ssCtrl in Shift then
180begin
181if ssLeft in Shift then
182Screen.Cursor := crSlidexy
183else if ssRight in Shift then
184Screen.Cursor := crLightxy;
185end
186else { no shift or ctrl key }
187begin
188if Shift = [ssLeft] then
189Screen.Cursor := crRotate
190else if Shift = [ssRight] then
191Screen.Cursor := crZoom;
192end;
193end;
194
195procedure TMainForm.GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
196X, Y: Integer);
197var
198dx, dy: Integer;
199nx, nz, d: TGLFloat;
200
201begin { refer GLScene\Demos\interface\camera\Camera.dpr }
202dx := MousePoint.X - X;
203dy := MousePoint.Y - Y;
204if ssShift in Shift then { shift key down }
205begin
206if ssLeft in Shift then { left mouse button }
207begin
208{ dy = a step which adjusts target distance by 1.25%; zoom in or out }
209with Camera do
210AdjustDistanceToTarget(Power(1.0125, dy));
211ShowCameraLocation;
212end
213end
214else if ssCtrl in Shift then { Ctrl key down }
215begin
216if ssLeft in Shift then { left mouse button }
217begin
218nz := Camera.Position.Z * dy;
219nx := Camera.Position.Z * dx;
220d := 5 * Camera.FocalLength;
221with CameraCube.Position do
222begin
223Z := Z - nz / d;
224X := X - nx / d;
225end;
226ShowDisplacement;
227end
228end
229else { no shift key }
230begin
231if Shift = [ssLeft] then
232{ Left mouse button changes camera angle by moving around target }
233begin
234Camera.MoveAroundTarget(dy, dx);
235ShowCameraLocation;
236end;
237if Shift = [ssRight] then
238begin
239{ Right mouse button alters the camera's focal length;
240zoom out or in by moving cursor up or down }
241with Camera do
242begin
243FocalLength := FocalLength - dy;
244if FocalLength > 1000 then
245FocalLength := 1000; { max focal length }
246if FocalLength < 20 then
247FocalLength := 20; { min focal length }
248end;
249ShowFocalLength; { display in statusbar palel }
250end;
251end;
252MousePoint.X := X; { update mouse position }
253MousePoint.Y := Y;
254end;
255
256procedure TMainForm.GLSceneViewer1MouseUp(Sender: TObject; Button: TMouseButton;
257Shift: TShiftState; X, Y: Integer);
258begin
259Screen.Cursor := crDefault;
260end;
261
262procedure TMainForm.GridCheckBoxClick(Sender: TObject);
263begin
264GLXYZGridXZ.Visible := not GridCheckBox.Checked;
265end;
266
267procedure TMainForm.CheckBoxClick(Sender: TObject);
268begin
269ShowSuperellipsoid;
270end;
271
272procedure TMainForm.VCurveTrackBarChange(Sender: TObject);
273var
274n: TGLFloat;
275
276begin
277n := VCurveTrackBar.Position / 10;
278GLSuperellipsoid.XYCurve := n;
279ShowSuperellipsoid;
280end;
281
282procedure TMainForm.HCurveTrackBarChange(Sender: TObject);
283var
284n: TGLFloat;
285
286begin
287n := HCurveTrackBar.Position / 10;
288GLSuperellipsoid.XYCurve := n;
289ShowSuperellipsoid;
290end;
291
292procedure TMainForm.ShowCameraLocation;
293begin
294with Camera.Position do
295StatusBar.Panels[0].Text := 'Camera: ' + FloatToStrF(X, ffNumber, 5, 2) +
296', ' + FloatToStrF(Y, ffNumber, 5, 2) + ', ' +
297FloatToStrF(Z, ffNumber, 5, 2);
298end;
299
300procedure TMainForm.ShowFocalLength;
301begin
302with Camera do
303StatusBar.Panels[1].Text := 'f = ' + FloatToStrF(FocalLength,
304ffNumber, 5, 2);
305end;
306
307procedure TMainForm.ShowDisplacement;
308begin
309with CameraCube.Position do
310StatusBar.Panels[2].Text := 'Displaced: ' + FloatToStrF(-X, ffNumber, 5, 2)
311+ ', ' + FloatToStrF(-Y, ffNumber, 5, 2);
312end;
313
314procedure TMainForm.ShowSuperellipsoid;
315begin
316// Superellipsoid.NormalDirection := ndInside;
317// Superellipsoid.Normals :=
318{ Determines how and if normals are smoothed.<p>
319- nsFlat : facetted look<br>
320- nsSmooth : smooth look<br>
321- nsNone : unlighted rendering, usefull for decla texturing }
322GLSuperellipsoid.Scale.SetVector(xRadiusTrackBar.Position,
323yRadiusTrackBar.Position, zRadiusTrackBar.Position);
324GLSuperellipsoid.Slices := SlicesTrackBar.Position;
325GLSuperellipsoid.Stacks := StacksTrackBar.Position;
326GLSuperellipsoid.Top := TopTrackBar.Position;
327
328case TopCapRadioGroup.ItemIndex of
3290: GLSuperellipsoid.TopCap := ctNone;
3301: GLSuperellipsoid.TopCap := ctCenter;
3312: GLSuperellipsoid.TopCap := ctFlat;
332end;
333
334GLSuperellipsoid.Bottom := -BottomTrackBar.Position;
335
336case BottomCapRadioGroup.ItemIndex of
3370: GLSuperellipsoid.BottomCap := ctNone;
3381: GLSuperellipsoid.BottomCap := ctCenter;
3392: GLSuperellipsoid.BottomCap := ctFlat;
340end;
341
342if (StartTrackBar.Position <= StopTrackBar.Position) and
343(StartTrackBar.Position < 360) then
344begin
345GLSuperellipsoid.Start := StartTrackBar.Position;
346GLSuperellipsoid.Stop := StopTrackBar.Position;
347end;
348GLSuperellipsoid.Normals := nsNone;
349GLHUDText.Text := 'Scale:' + FloatToStrF(xRadiusTrackBar.Position / 10,
350ffNumber, 6, 2) + ', ' + FloatToStrF(yRadiusTrackBar.Position / 10,
351ffNumber, 6, 2) + ', ' + FloatToStrF(zRadiusTrackBar.Position / 10,
352ffNumber, 6, 2) + #13#10'VCurve:' +
353FloatToStrF(VCurveTrackBar.Position / 10, ffNumber, 6, 2) + #13#10'HCurve:'
354+ FloatToStrF(HCurveTrackBar.Position / 10, ffNumber, 6, 2) +
355#13#10'Slices:' + IntToStr(SlicesTrackBar.Position) + #13#10'Stacks:' +
356IntToStr(StacksTrackBar.Position) + #13#10'Top:' +
357IntToStr(TopTrackBar.Position) + '°' + #13#10'Bottom:' +
358IntToStr(BottomTrackBar.Position) + '°' + #13#10'Start:' +
359IntToStr(StartTrackBar.Position) + '°' + #13#10'Stop:' +
360IntToStr(StopTrackBar.Position) + '°';
361end;
362
363procedure TMainForm.SlicesTrackBarChange(Sender: TObject);
364begin
365ShowSuperellipsoid;
366end;
367
368procedure TMainForm.StacksTrackBarChange(Sender: TObject);
369begin
370ShowSuperellipsoid;
371end;
372
373procedure TMainForm.StartTrackBarChange(Sender: TObject);
374begin
375if (StartTrackBar.Position >= StopTrackBar.Position) then
376StartTrackBar.Position := StopTrackBar.Position;
377ShowSuperellipsoid;
378end;
379
380procedure TMainForm.TopCapRadioGroupClick(Sender: TObject);
381begin
382ShowSuperellipsoid;
383end;
384
385procedure TMainForm.TopTrackBarChange(Sender: TObject);
386begin
387ShowSuperellipsoid;
388end;
389
390procedure TMainForm.StopTrackBarChange(Sender: TObject);
391begin
392if (StopTrackBar.Position <= StartTrackBar.Position) then
393StopTrackBar.Position := StartTrackBar.Position;
394ShowSuperellipsoid;
395end;
396
397procedure TMainForm.BottomCapRadioGroupClick(Sender: TObject);
398begin
399ShowSuperellipsoid;
400end;
401
402procedure TMainForm.BottomTrackBarChange(Sender: TObject);
403begin
404ShowSuperellipsoid;
405end;
406
407procedure TMainForm.Button1Click(Sender: TObject);
408begin
409with GLSuperellipsoid.Material.Texture do
410begin
411// We need a CubeMapImage, which unlike the "regular Images" stores
412// multiple images.
413ImageClassName := TGLCubeMapImage.ClassName;
414with Image as TGLCubeMapImage do
415begin
416// Load all 6 texture map components of the cube map
417// The 'PX', 'NX', etc. refer to 'positive X', 'negative X', etc.
418// and follow the RenderMan specs/conventions
419Picture[cmtNX].LoadFromFile('cm_left.png');
420Picture[cmtPX].LoadFromFile('cm_right.png');
421Picture[cmtNY].LoadFromFile('cm_top.png');
422Picture[cmtPY].LoadFromFile('cm_bottom.png');
423Picture[cmtPZ].LoadFromFile('cm_back.png');
424Picture[cmtNZ].LoadFromFile('cm_front.png');
425end;
426// Select reflection cube map environment mapping
427// This is the mode you'll most commonly use with cube maps, normal cube
428// map generation is also supported (used for diffuse environment lighting)
429MappingMode := tmmCubeMapReflection;
430// That's all folks, let us see the thing!
431Disabled := False;
432end;
433Button1.Visible := False;
434end;
435
436procedure TMainForm.Button2Click(Sender: TObject);
437var
438i, j: integer;
439x, y, d: single;
440
441begin
442
443d := 6;
444Randomize;
445for j := 0 to 5 do
446for i := 0 to 5 do
447begin
448x := -d*2.5 + d*i;
449y := d*2.5 - d*j;
450Superellipsoids[i, j] :=
451TGLSuperellipsoid(GLScene1.Objects.AddNewChild(TGLSuperellipsoid));
452
453with Superellipsoids[i, j] do
454begin
455Slices := 32;
456Stacks := 32;
457Scale.SetVector(5, 5, 5);
458Position.SetPoint(x, y, 0);
459Direction.SetVector(0, 1, 0);
460Up.SetVector(0, 0, 1);
461case i of
4620:XYCurve := 0.2;
4631:XYCurve := 0.8;
4642:XYCurve := 1.0;
4653:XYCurve := 1.5;
4664:XYCurve := 2.0;
4675:XYCurve := 3.0;
468end;
469case j of
4700:XYCurve := 0.2;
4711:XYCurve := 0.8;
4722:XYCurve := 1.0;
4733:XYCurve := 1.5;
4744:XYCurve := 2.0;
4755:XYCurve := 3.0;
476end;
477with Material.FrontProperties do
478begin
479Ambient.RandomColor;
480Diffuse.RandomColor;
481Specular.RandomColor;
482Shininess := 125;
483end;
484end;
485end;
486Button2.Visible := False;
487end;
488
489procedure TMainForm.checkclick(Sender: TObject);
490begin
491ShowSuperellipsoid;
492end;
493
494procedure TMainForm.RadiusTrackBarChange(Sender: TObject);
495begin
496ShowSuperellipsoid;
497end;
498
499end.
500