107 lines
3.0 KiB
ObjectPascal

unit ex3;
{$mode objfpc}{$H+}
interface
{ This example is a cylinder. It aims at showing the difference
between lighting normals modes.
The lighting normals are the direction considered to be orthogonal
to the surface. The box uses lnFace, which means that each face is
considered to be flat. On the contrary, lamps are rounded, so
their lighting normals are lnVertex, which means that the surface
is considered to be rounded between faces, using vertices as a
reference.
Depending on the value of DefaultLightingNormal, the cylinder will
look polygonal or rounded. The value lnFaceVertexMix is an
intermediate between Face and Vertex, which allows to have some
light diffusion effect while keeping an angle between faces.
The SaturationLow and SaturationHigh properties of the material allows
to create a shiny effect without actually computing reflected light.
Simply when a pixel is very bright, it turns into white, as if we
could see the reflection of some white beam. }
uses
Classes, SysUtils, BGRAScene3D, BGRABitmapTypes
{$IFNDEF NO_OPENGL_SURFACE}, BGRAOpenGL3D{$ENDIF};
type
{ TExample3 }
TExample3 = class({$IFNDEF NO_OPENGL_SURFACE}TBGLScene3D{$ELSE}TBGRAScene3D{$ENDIF})
constructor Create;
end;
implementation
uses BGRAMatrix3D;
{ TExample3 }
constructor TExample3.Create;
const
radius = 20;
topY = -20;
bottomY = 20;
precision = 40;
var
bottom,top: array[1..precision] of IBGRAVertex3D;
topCoord,bottomCoord: TPoint3D;
rotateMatrix: TMatrix3D;
i,j: Integer;
begin
inherited Create;
DefaultMaterial.SpecularIndex := 50;
DefaultMaterial.AutoSpecularColor:= true;
//create a cylinder
with CreateObject(BGRA(0,0,255)) do
begin
for j := 1 to 2 do
begin
//top and bottom coordinates
topCoord := Point3D(radius,topY,0);
bottomCoord := Point3D(radius,bottomY,0);
//rotating around the Y axis
rotateMatrix := MatrixRotateY(2*Pi/precision);
//create the vertices
for i := 1 to precision do
begin
//store in reverse order the second time
if j = 2 then
begin
top[precision+1-i] := MainPart.Add(topCoord);
bottom[precision+1-i] := MainPart.Add(bottomCoord);
end
else
begin
top[i] := MainPart.Add(topCoord);
bottom[i] := MainPart.Add(bottomCoord);
end;
topCoord := rotateMatrix*topCoord;
bottomCoord := rotateMatrix*bottomCoord;
end;
//add faces : the second time, there will be in the opposite direction because of the reverse order
for i := 1 to precision do
AddFace([top[i],top[(i mod precision)+1],bottom[(i mod precision)+1],bottom[i]]);
end;
//apply a rotation to show the top of the cylinder
MainPart.RotateXDeg(30);
end;
//set ambiant lightness to dark (1 is normal lightness, 2 is complete whiteness)
AmbiantLightness := 0.5;
//add a directional light from top-left, maximum lightness will be 0.5 + 1 = 1.5
AddDirectionalLight(Point3D(1,1,1),1,-0.5);
end;
end.