1 unit ex1; 2 3 {$mode objfpc}{$H+} 4 5 interface 6 7 { This is a simple 3D objet, a pyramid with a hexagonal base. The object is designed in the constructor. 8 The CreateObject method returns an interface to an empty object. An interface is similar to a class 9 except you don't have to call Free. 10 11 A 3D object has a MainPart property, which contains the vertices describing the objet. It can contains subparts, 12 but here it is not the case. Parts can be rotated and scaled relative to their container. The MainPart is rotated 13 and scaled relative to the whole scene. 14 15 Faces are created using vertices, so that they will follow the movements of these vertices. Here the default color 16 SandColor is defined for the whole object. 17 18 In order to make it attractive, a lighting is defined. The simplest way is to use a directional light, so that 19 you don't have to bother with the coordinates of the light source. 20 21 The background is filled with a gradient. Note that it is a vertical gradient which is very fast to draw, because 22 each scanline is filled with one color. } 23 24 uses 25 Classes, SysUtils, BGRAScene3D, BGRABitmapTypes 26 {$IFNDEF NO_OPENGL_SURFACE}, BGRAOpenGL, BGRAOpenGL3D{$ENDIF}; 27 28 type 29 30 { TExample1 } 31 32 TExample1 = class({$IFNDEF NO_OPENGL_SURFACE}TBGLScene3D{$ELSE}TBGRAScene3D{$ENDIF}) 33 SandColor: TBGRAPixel; 34 constructor Create; 35 procedure Render; override; 36 {$IFNDEF NO_OPENGL_SURFACE} 37 procedure RenderGL(ACanvas: TBGLCustomCanvas; AMaxZ: single=1000); override; 38 {$ENDIF} 39 end; 40 41 implementation 42 43 { TExample1 } 44 45 constructor TExample1.Create; 46 var 47 base: array of IBGRAVertex3D; 48 top: IBGRAVertex3D; 49 begin 50 inherited Create; 51 52 SandColor := BGRA(255,240,128); 53 54 //create a pyramid 55 with CreateObject(SandColor) do 56 begin 57 top := MainPart.Add(0,-15,0); 58 //pyramid base is in a clockwise order if we look the pyramid from under 59 base := MainPart.Add([-20,15,-20, 0,15,-30, 20,15,-20, 20,15,20, 0,15,30, -20,15,20]); 60 AddFace(base); 61 //add four faces, the three vertices are in a clockwise order 62 AddFace([base[0],top,base[1]]); 63 AddFace([base[1],top,base[2]]); 64 AddFace([base[2],top,base[3]]); 65 AddFace([base[3],top,base[4]]); 66 AddFace([base[4],top,base[5]]); 67 AddFace([base[5],top,base[0]]); 68 69 MainPart.Scale(1.3); 70 MainPart.RotateYDeg(30); 71 MainPart.RotateXDeg(20); 72 MainPart.Translate(0,-5,0); 73 end; 74 75 //set ambiant lightness to dark (1 is normal lightness, 2 is complete whiteness) 76 AmbiantLightness := 0.5; 77 //add a directional light from top-left, maximum lightness will be 0.5 + 1 = 1.5 78 AddDirectionalLight(Point3D(1,1,1),0.5); 79 80 //we can have high quality antialiasing because it is a simple scene 81 RenderingOptions.PerspectiveMode := pmLinearMapping; 82 end; 83 84 procedure TExample1.Render; 85 begin 86 //fill background 87 Surface.GradientFill(0,0,Surface.Width,Surface.Height, 88 MergeBGRA(SandColor,1,BGRABlack,1), 89 MergeBGRA(SandColor,1,BGRABlack,2), 90 gtLinear,PointF(0,0),PointF(0,Surface.Height),dmSet); 91 92 inherited Render; 93 end; 94 95 {$IFNDEF NO_OPENGL_SURFACE} 96 procedure TExample1.RenderGL(ACanvas: TBGLCustomCanvas; AMaxZ: single); 97 begin 98 //fill background 99 ACanvas.FillRectLinearColor(0,0,BGLCanvas.Width,BGLCanvas.Height, 100 MergeBGRA(SandColor,1,BGRABlack,1),MergeBGRA(SandColor,1,BGRABlack,1), 101 MergeBGRA(SandColor,1,BGRABlack,2),MergeBGRA(SandColor,1,BGRABlack,2), 102 False); 103 104 inherited RenderGL(ACanvas, AMaxZ); 105 end; 106 {$ENDIF} 107 108 end. 109 110