107 lines
3.0 KiB
ObjectPascal
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.
|
|
|