unit _MeshRenderer;

interface
uses
  OpenGL,
  _Scene,
  _OpenGL,
  _Forms,
  _Geometry;

const
  MAX_VERTICLES = 23;
  MAX_FACES = 5;

type
TMeshRenderer = class(TRender)
  private
    Vertex: array [0..MAX_VERTICLES] of TVector3;  
    Normals: array [0..MAX_VERTICLES] of TVector3;
    Textures: array [0..MAX_VERTICLES] of TVector2;
    Material: TBasicMaterial;
    procedure CreateCubeMesh;
  public
    constructor Create; overload;
    constructor Create(UsedMaterial: TBasicMaterial); overload;
    procedure Render; override;   
    procedure Control; override;
end;

implementation

{$REGION 'SkyBox'}
{$REGION 'Cube'}
procedure TMeshRenderer.CreateCubeMesh;
var
  S: Single;
begin
  S:= 0.5;
  Vertex[0 ] := Vector3( S, -S,  S); //up
  Vertex[1 ] := Vector3( S,  S,  S);
  Vertex[2 ] := Vector3(-S,  S,  S);
  Vertex[3 ] := Vector3(-S, -S,  S);
  Vertex[4 ] := Vector3( S,  S, -S); //down
  Vertex[5 ] := Vector3( S, -S, -S);
  Vertex[6 ] := Vector3(-S, -S, -S);
  Vertex[7 ] := Vector3(-S,  S, -S);
  Vertex[8 ] := Vector3( S,  S,  S); //forward
  Vertex[9 ] := Vector3( S,  S, -S);
  Vertex[10] := Vector3(-S,  S, -S);
  Vertex[11] := Vector3(-S,  S,  S);
  Vertex[12] := Vector3( S, -S, -S); //backward
  Vertex[13] := Vector3( S, -S,  S);
  Vertex[14] := Vector3(-S, -S,  S);
  Vertex[15] := Vector3(-S, -S, -S);
  Vertex[16] := Vector3( S,  S, -S); //left
  Vertex[17] := Vector3( S,  S,  S);
  Vertex[18] := Vector3( S, -S,  S);
  Vertex[19] := Vector3( S, -S, -S);
  Vertex[20] := Vector3(-S,  S,  S); //right
  Vertex[21] := Vector3(-S,  S, -S);
  Vertex[22] := Vector3(-S, -S, -S);
  Vertex[23] := Vector3(-S, -S,  S);

  Normals[0 ].Vector3( 0,  0,  1); //up
  Normals[1 ].Vector3( 0,  0,  1);
  Normals[2 ].Vector3( 0,  0,  1);
  Normals[3 ].Vector3( 0,  0,  1);
  Normals[4 ].Vector3( 0,  0, -1); //down
  Normals[5 ].Vector3( 0,  0, -1);
  Normals[6 ].Vector3( 0,  0, -1);
  Normals[7 ].Vector3( 0,  0, -1);
  Normals[8 ].Vector3( 0,  1,  0); //forward
  Normals[9 ].Vector3( 0,  1,  0);
  Normals[10].Vector3( 0,  1,  0);
  Normals[11].Vector3( 0,  1,  0);
  Normals[12].Vector3( 0, -1,  0); //backward
  Normals[13].Vector3( 0, -1,  0);
  Normals[14].Vector3( 0, -1,  0);
  Normals[15].Vector3( 0, -1,  0);
  Normals[16].Vector3( 1,  0,  0); //left
  Normals[17].Vector3( 1,  0,  0);
  Normals[18].Vector3( 1,  0,  0);
  Normals[19].Vector3( 1,  0,  0);
  Normals[20].Vector3(-1,  0,  0); //right
  Normals[21].Vector3(-1,  0,  0);
  Normals[22].Vector3(-1,  0,  0);
  Normals[23].Vector3(-1,  0,  0);

  Textures[0 ].Vector2(0, 0); //up
  Textures[1 ].Vector2(1, 0);
  Textures[2 ].Vector2(1, 1);
  Textures[3 ].Vector2(0, 1);
  Textures[4 ].Vector2(0, 0); //down
  Textures[5 ].Vector2(1, 0);
  Textures[6 ].Vector2(1, 1);
  Textures[7 ].Vector2(0, 1);
  Textures[8 ].Vector2(1, 0); //forward
  Textures[9 ].Vector2(0, 0);
  Textures[10].Vector2(0, 1);
  Textures[11].Vector2(1, 1);
  Textures[12].Vector2(1, 0);
  Textures[13].Vector2(0, 0); //backward
  Textures[14].Vector2(0, 1);
  Textures[15].Vector2(1, 1);
  Textures[16].Vector2(0, 0); //left
  Textures[17].Vector2(1, 0);
  Textures[18].Vector2(1, 1);
  Textures[19].Vector2(0, 1);
  Textures[20].Vector2(0, 0); //right
  Textures[21].Vector2(1, 0);
  Textures[22].Vector2(1, 1);
  Textures[23].Vector2(0, 1);
end;
{$ENDREGION}

constructor TMeshRenderer.Create;
var
  Shift: TVector3;
  i: Byte;
begin
  Shift.Create(Random(100) - 50, Random(100) - 50, Random(100) - 50);
  CreateCubeMesh;              
  Material:= TDummyMaterial.Create;
  for i:=0 to MAX_VERTICLES do
    Vertex[i]:= Vertex[i] + Shift;
end;

constructor TMeshRenderer.Create(UsedMaterial: TBasicMaterial);
var
  Shift: TVector3;
  i: Byte;
begin
  Material:= UsedMaterial;
  Shift.Create(Random(100) - 50, Random(100) - 50, Random(100) - 50);
  CreateCubeMesh;
  for i:=0 to MAX_VERTICLES do
    Vertex[i]:= Vertex[i] + Shift;
end;

procedure TMeshRenderer.Render;
begin
  if Material<>nil then
    Material.Use;  
  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_NORMAL_ARRAY);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);

  glNormalPointer(GL_FLOAT, 0, @Normals[0]);
  glTexCoordPointer(2, GL_FLOAT, 0, @Textures[0]);
  glVertexPointer(3, GL_FLOAT, 0, @Vertex[0]);

//  glDrawElements(GL_QUADS, (MAX_VERTICLES)*4, GL_UNSIGNED_INT, @Fp[0]);
  glDrawArrays(GL_QUADS, 0, MAX_FACES * 4 + 4);

  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  glDisableClientState(GL_NORMAL_ARRAY);
  glDisableClientState(GL_VERTEX_ARRAY);
end;            

procedure TMeshRenderer.Control;
{var
  i, j: Byte;
  Mouse: TPoint;
  Sides: array [0..3] of TVector2;     }
begin
{  Mouse.Vector2i(Window.Mouse.X, Window.Height - Window.Mouse.Y);
  for j:=0 to MAX_FACES do
    begin
      for i:= 0 to 3 do
        Sides[i]:= TOpenGL.Point_To_Coord(Vertex[i + j * 4]);
      if (TVector2(Mouse).InTriangle(Sides[0], Sides[1], Sides[2])) or
         (TVector2(Mouse).InTriangle(Sides[2], Sides[3], Sides[0])) then
        Color.Create(Random(5), Random(5), Random(5));
    end;  }
end;
{$ENDREGION}

end.
