TMesh – generate 3d shape and calculate normals

  

i try to understand how 3d works and i have created 3d shape e.g. cube.
I fill mesh.data.VertexBuffer.Vertices and mesh.data.IndexBuffer.
All looks ok on the screen but not the shadows.
I do not understand how i can provide normals for vertices? I can think about normals for triangles but i cannot imagine for single vertices. One verticle can be shared by multiple triangles, yes or not? E.g. for the cube one corner verticle can be shared by 3 walls.
Maybe my understanding is wrong.
The question is:

Should i have for the cube only 8 points as i have now? And use them in indexbuffer.
Or i should have separate points for every triangles even if they have same coordinates as other triangles points have, to be able to calculate normals? E.g. for the cube i should have:
6 walls * 4 points = 24 points instead of my current 8 only?

UPDATE

unit UnitMain;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Viewport3D, System.Math.Vectors, FMX.Types3D,
FMX.Controls3D, FMX.Objects3D, FMX.MaterialSources;

type
TFormCube = class(TForm)
Viewport3D1: TViewport3D;
Camera1: TCamera;
Light1: TLight;
Mesh1: TMesh;
LightMaterialSource1: TLightMaterialSource;
LightMaterialSource2: TLightMaterialSource;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
FormCube: TFormCube;

implementation

{$R *.fmx}

procedure TFormCube.FormCreate(Sender: TObject);
Var idx: Integer;
begin
Mesh1.Data.VertexBuffer.Length:= 8;

Mesh1.Data.VertexBuffer.Vertices[0]:= Point3d(1, 1, 1);
Mesh1.Data.VertexBuffer.Vertices[1]:= Point3d(1, -1, 1);
Mesh1.Data.VertexBuffer.Vertices[2]:= Point3d(-1, -1, 1);
Mesh1.Data.VertexBuffer.Vertices[3]:= Point3d(-1, 1, 1);

Mesh1.Data.VertexBuffer.Vertices[4]:= Point3d(1, 1, -1);
Mesh1.Data.VertexBuffer.Vertices[5]:= Point3d(1, -1, -1);
Mesh1.Data.VertexBuffer.Vertices[6]:= Point3d(-1, -1, -1);
Mesh1.Data.VertexBuffer.Vertices[7]:= Point3d(-1, 1, -1);

Mesh1.Data.IndexBuffer.Length:= 8*2*3;

//front
idx:= 0;
Mesh1.Data.IndexBuffer[idx + 0]:= 0;
Mesh1.Data.IndexBuffer[idx + 1]:= 3;
Mesh1.Data.IndexBuffer[idx + 2]:= 2;

inc(idx, 3);
Mesh1.Data.IndexBuffer[idx + 0]:= 0;
Mesh1.Data.IndexBuffer[idx + 1]:= 2;
Mesh1.Data.IndexBuffer[idx + 2]:= 1;

//right
inc(idx, 3);
Mesh1.Data.IndexBuffer[idx + 0]:= 4;
Mesh1.Data.IndexBuffer[idx + 1]:= 0;
Mesh1.Data.IndexBuffer[idx + 2]:= 1;

inc(idx, 3);
Mesh1.Data.IndexBuffer[idx + 0]:= 4;
Mesh1.Data.IndexBuffer[idx + 1]:= 1;
Mesh1.Data.IndexBuffer[idx + 2]:= 5;

//back
inc(idx, 3);
Mesh1.Data.IndexBuffer[idx + 0]:= 7;
Mesh1.Data.IndexBuffer[idx + 1]:= 4;
Mesh1.Data.IndexBuffer[idx + 2]:= 5;

inc(idx, 3);
Mesh1.Data.IndexBuffer[idx + 0]:= 7;
Mesh1.Data.IndexBuffer[idx + 1]:= 5;
Mesh1.Data.IndexBuffer[idx + 2]:= 6;

//left
inc(idx, 3);
Mesh1.Data.IndexBuffer[idx + 0]:= 3;
Mesh1.Data.IndexBuffer[idx + 1]:= 7;
Mesh1.Data.IndexBuffer[idx + 2]:= 6;

inc(idx, 3);
Mesh1.Data.IndexBuffer[idx + 0]:= 3;
Mesh1.Data.IndexBuffer[idx + 1]:= 6;
Mesh1.Data.IndexBuffer[idx + 2]:= 2;

//top
inc(idx, 3);
Mesh1.Data.IndexBuffer[idx + 0]:= 4;
Mesh1.Data.IndexBuffer[idx + 1]:= 7;
Mesh1.Data.IndexBuffer[idx + 2]:= 3;

inc(idx, 3);
Mesh1.Data.IndexBuffer[idx + 0]:= 4;
Mesh1.Data.IndexBuffer[idx + 1]:= 3;
Mesh1.Data.IndexBuffer[idx + 2]:= 0;

//bottom
inc(idx, 3);
Mesh1.Data.IndexBuffer[idx + 0]:= 1;
Mesh1.Data.IndexBuffer[idx + 1]:= 2;
Mesh1.Data.IndexBuffer[idx + 2]:= 6;

inc(idx, 3);
Mesh1.Data.IndexBuffer[idx + 0]:= 1;
Mesh1.Data.IndexBuffer[idx + 1]:= 6;
Mesh1.Data.IndexBuffer[idx + 2]:= 5;
end;

end.

and the dfm
object FormCube: TFormCube
Left = 0
Top = 0
Caption = ‘Cube’
ClientHeight = 823
ClientWidth = 1166
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
OnCreate = FormCreate
DesignerMasterStyle = 0
object Viewport3D1: TViewport3D
Align = Client
Camera = Camera1
Color = claBlack
Size.Width = 1166.000000000000000000
Size.Height = 823.000000000000000000
Size.PlatformDefault = False
UsingDesignCamera = False
object Camera1: TCamera
AngleOfView = 45.000000000000000000
Position.X = -2.000000000000000000
Position.Y = -2.000000000000000000
Position.Z = -10.000000000000000000
Width = 1.000000000000000000
Height = 1.000000000000000000
Depth = 1.000000000000000000
end
object Light1: TLight
Color = claWhite
LightType = Directional
SpotCutOff = 180.000000000000000000
Position.X = -9.222618103027344000
Position.Y = 2.758471012115479000
RotationAngle.Y = 21.211906433105470000
Width = 1.000000000000000000
Height = 1.000000000000000000
Depth = 1.000000000000000000
Quanternion = ‘(0,-0.184053480625153,0,-0.982916116714478)’
end
object Mesh1: TMesh
Width = 1.000000000000000000
Height = 1.000000000000000000
Depth = 1.000000000000000000
TwoSide = True
MaterialSource = LightMaterialSource2
end
object LightMaterialSource1: TLightMaterialSource
Diffuse = claRed
Ambient = claBlue
Emissive = claGreen
Specular = claWhite
Shininess = 30
Left = 280
Top = 168
end
end
object LightMaterialSource2: TLightMaterialSource
Diffuse = claWhite
Ambient = xFF202020
Emissive = claNull
Specular = xFF606060
Shininess = 30
Left = 248
Top = 256
end
end

Comments are closed.