unit menu;


interface

uses
  SysUtils,
  System.Drawing,
  System.Windows.Forms,
  Microsoft.DirectX,
  Microsoft.DirectX.DirectInput,
  Microsoft.DirectX.Direct3D;

type
  TEventHandler      = System.EventHandler;
  TEventArgs         = System.EventArgs;
  TKeyEventArgs      = System.Windows.Forms.KeyEventArgs;
  TMouseEventArgs    = System.Windows.Forms.MouseEventArgs;
  TPaintEventArgs    = System.Windows.Forms.PaintEventArgs;
  TKeys              = System.Windows.Forms.Keys;
  TForm              = System.Windows.Forms.Form;
  TColor             = System.Drawing.Color;
  TIcon              = System.Drawing.Icon;

  TMenu = class( TForm )
  strict private
    // Our rendering device
    FDevice : Device;
    FVertexBuffer : VertexBuffer;
    FPause : boolean;
    FPresentParams: PresentParameters;
    clavier : Microsoft.DirectX.DirectInput.Device;
    i:integer;
    FTexture:texture;
    ArrayTexture: array[0..0] of string;
    procedure SetupMatrices;
  public
    constructor Create;
    function InitializeGraphics: Boolean;
    procedure InitializeTexture;
    procedure Initialise_clavier;
    procedure Render;
    procedure main;
    procedure OnCreateDevice(sender: TObject; e: TEventArgs);
    procedure OnCreateVertexBuffer(sender: TObject; e: TEventArgs);
    procedure OnResetDevice(sender: TObject; e: TEventArgs);
    procedure Lire_clavier(sender : Tobject ; e:TEventArgs);
  strict protected
    procedure OnPaint(e: TPaintEventArgs); override;
    procedure OnKeyDown( E: TKeyEventArgs ); override;
    procedure OnResize(e: TEventArgs); override;
  end;



implementation


constructor TMenu.Create;
begin
  inherited;
  // Set the initial size of our form
  Self.ClientSize := System.Drawing.Size.Create(640, 480);
  // And it's caption
  Self.Text := 'Delphi for .NET : Direct3D Tutorial 3 - Matrices';
  // Load our icon from the resources of the .exe
  //Self.Icon := TIcon.Create( Self.GetType, 'directx.ico');
end;

function TMenu.InitializeGraphics: Boolean;
begin
  try
    // Now let's setup our D3D stuff
    Self.FPresentParams := PresentParameters.Create;
    // We don't want to run fullscreen
    Self.FPresentParams.Windowed := True;
    // Discard the frames
    Self.FPresentParams.SwapEffect := SwapEffect.Discard;

    Self.FPresentParams.EnableAutoDepthStencil := true;
    Self.FPresentParams.AutoDepthStencilFormat := DepthFormat.D16;
    //Create a device
    Self.FDevice := Device.Create( 0, DeviceType.Hardware, Self, CreateFlags.SoftwareVertexProcessing, [Self.FPresentParams] );
    //Include(Self.FDevice.DeviceCreated, Self.OnCreateDevice);
    //Include(Self.FDevice.DeviceReset, Self.OnResetDevice);
    Self.OnCreateDevice(Self.FDevice, nil);
    Self.OnResetDevice(Self.FDevice, nil);
    Self.FPause := False;
    i:=0;
    Result := True;
    Initialise_clavier;
    Exit;
  except
    on E : DirectXException do
      begin
        Result := False;
        Exit;
      end;
  end;
end;


procedure TMenu.InitializeTexture;
begin
ArrayTexture[0]:='menu1.bmp';
//ArrayTexture[1]:='menu2.bmp';
//ArrayTexture[2]:='menu3.bmp';
//ArrayTexture[3]:='menu4.bmp';
//ArrayTexture[4]:='menu5.bmp';

 end;




procedure TMenu.OnCreateDevice(sender: TObject; e: TEventArgs);
var
  dev: Device;
begin
  dev := Device(sender);
  // Now Create the VB
  Self.FVertexBuffer := VertexBuffer.Create( TypeOf( CustomVertex.Positiontextured ), 36, dev, Usage( 0 ), CustomVertex.Positiontextured.Format, Pool.Default );
  //Include( Self.FVertexBuffer.Created, Self.OnCreateVertexBuffer );
  Self.OnCreateVertexBuffer( Self.FVertexBuffer, nil );
end;

procedure TMenu.OnCreateVertexBuffer(sender: TObject; e: TEventArgs);
var
  verts: array[ 0..35 ]  of CustomVertex.Positiontextured;
  stm: GraphicsStream;
  vb: VertexBuffer;
begin
  vb := VertexBuffer( sender ) ;
  stm := vb.Lock( 0, 0, LockFlags(0) );

  // FACE DE DEVANT

  verts[ 0 ] := CustomVertex.Positiontextured.Create( -1, -1, -1, 0 ,1 );
  verts[ 1 ] := CustomVertex.Positiontextured.Create(  1, -1, -1, 1 , 1 );
  verts[ 2 ] := CustomVertex.Positiontextured.Create( -1,  1, -1, 0 , 0 );
  verts[ 3 ] := verts [ 2 ];
  verts[ 4 ] := verts [ 1 ];
  verts[ 5 ] := CustomVertex.Positiontextured.Create(  1,  1, -1, 1 , 0);

  // FACE DE DERRIERE

  verts[ 6 ] := CustomVertex.Positiontextured.Create( -1, -1, 1, 0 , 1 );
  verts[ 7 ] := CustomVertex.Positiontextured.Create(  1, -1, 1, 1 , 1 );
  verts[ 8 ] := CustomVertex.Positiontextured.Create( -1,  1, 1, 0 , 0 );
  verts[ 9 ] :=  verts [ 8];
  verts[ 10 ] := verts [ 7 ];
  verts[ 11 ] := CustomVertex.Positiontextured.Create( 1, 1, 1, 1 , 0 );

  // FACE DU DESSUS

  verts[ 12 ] := CustomVertex.Positiontextured.Create( -1, 1, -1, 0 , 1 );
  verts[ 13 ] := CustomVertex.Positiontextured.Create( 1,  1, -1, 1 , 1 );
  verts[ 14 ] := CustomVertex.Positiontextured.Create( -1, 1, 1, 0 , 0 );
  verts[ 15 ] :=  verts [ 14 ];
  verts[ 16 ] :=  verts [ 13 ];
  verts[ 17 ] := CustomVertex.Positiontextured.Create(  1, 1, 1, 1 , 0 );

    // FACE DU DESSOUS

  verts[ 18 ] := CustomVertex.Positiontextured.Create( -1, -1, -1, 0 , 1 );
  verts[ 19 ] := CustomVertex.Positiontextured.Create(  1, -1, -1, 1 , 1 );
  verts[ 20 ] := CustomVertex.Positiontextured.Create( -1, -1,  1, 0 , 0 );
  verts[ 21 ] := verts [ 20 ];
  verts[ 22 ] := verts [ 19 ];
  verts[ 23 ] := CustomVertex.Positiontextured.Create(  1, -1,  1, 1 , 0 );

    // FACE DE GAUCHE

  verts[ 24 ] := CustomVertex.Positiontextured.Create(  1,  -1, -1, 0 , 1 );
  verts[ 25 ] := CustomVertex.Positiontextured.Create(  1,   1, -1, 1 , 1 );
  verts[ 26 ] := CustomVertex.Positiontextured.Create(  1,  -1,  1, 0 , 0 );
  verts[ 27 ] := verts [ 26 ];
  verts[ 28 ] := verts [ 25 ];
  verts[ 29 ] := CustomVertex.Positiontextured.Create(  1,   1,  1, 1 , 0 );

    // FACE DE DROITE

  verts[ 30 ] := CustomVertex.Positiontextured.Create(  -1,  -1, -1, 0 , 1 );
  verts[ 31 ] := CustomVertex.Positiontextured.Create(  -1,   1, -1, 1 , 1 );
  verts[ 32 ] := CustomVertex.Positiontextured.Create(  -1,  -1,  1, 0 , 0 );
  verts[ 33 ] := verts [ 32 ];
  verts[ 34 ] := verts [ 31 ];
  verts[ 35 ] := CustomVertex.Positiontextured.Create(  -1,   1,  1, 1 , 0 );

  stm.Write( verts );
  vb.Unlock;
end;

procedure TMenu.OnResetDevice(sender: TObject; e: TEventArgs);
var
  dev: Device;
begin
  dev := Device( sender );
  // Turn off culling, so we see the front and back of the triangle
  dev.RenderState.CullMode := Cull.None;
  // Turn off D3D lighting, since we are providing our own vertex colors
  dev.RenderState.Lighting := False;

  Ftexture:= TextureLoader.FromFile( dev, 'menu1.bmp' );
end;

procedure TMenu.Render;
begin
  if ( Self.FDevice = nil ) then
    Exit;
  if ( Self.FPause ) then
    Exit;
  //Clear the backbuffer to a blue color
  Self.FDevice.Clear( ClearFlags.Target , TColor.White, 1.0, 0 );
  Self.FDevice.Clear( ClearFlags.ZBuffer , TColor.White, 1.0, 0 );

  //Begin the scene
  Self.FDevice.BeginScene;
  // Setup the world, view, and projection matrices
  Lire_clavier(Fdevice , nil);
  SetupMatrices;

  self.Fdevice.SetTexture(0, Ftexture);
  Self.FDevice.SetStreamSource( 0, Self.FVertexBuffer, 0 );
  Self.FDevice.VertexFormat := CustomVertex.Positiontextured.Format;
  Self.FDevice.DrawPrimitives( PrimitiveType.TriangleList, 0, 12 );
  
  //End the scene
  Self.FDevice.EndScene;
  Self.FDevice.Present;
end;

procedure TMenu.OnPaint( e: TPaintEventArgs );
begin
  // Render on painting
  Self.Render;
end;

procedure TMenu.OnKeyDown( E: TKeyEventArgs );
begin
  inherited;
  // Esc was pressed
  if ( e.KeyCode = TKeys.Escape ) then
    Self.Close;
end;

procedure TMenu.OnResize(e: TEventArgs);
begin
  FPause := ( ( Self.WindowState = FormWindowState.Minimized ) or ( not Self.Visible ) );
end;

procedure TMenu.SetupMatrices;
var
  iTime: Integer;
begin
  // For our world matrix, we will just rotate the object about the y-axis.

  // Set up the rotation matrix to generate 1 full rotation (2*PI radians)
  // every 1000 ms. To avoid the loss of precision inherent in very high
  // floating point numbers, the system time is modulated by the rotation
  // period before conversion to a radian angle.

  Self.FDevice.Transform.World := Matrix.Translation(0 ,0,  0) ;

  // Set up our view matrix. A view matrix can be defined given an eye point,
  // a point to lookat, and a direction for which way is up. Here, we set the
  // eye five units back along the z-axis and up three units, look at the
  // origin, and define "up" to be in the y-direction.
  Self.FDevice.Transform.View := Matrix.LookAtLH( Vector3.Create( 0, 0, -3.41 ), Vector3.Create( 0.0, 0.0, 0.0 ), Vector3.Create( 0, 1, 0 ) );
  // For the projection matrix, we set up a perspective transform (which
  // transforms geometry from 3D view space to 2D viewport space, with
  // a perspective divide making objects smaller in the distance). To build
  // a perpsective transform, we need the field of view (1/4 pi is common),
  // the aspect ratio, and the near and far clipping planes (which define at
  // what distances geometry should be no longer be rendered).
  Self.FDevice.Transform.Projection := Matrix.PerspectiveFovLH( ( ( Math.PI / 4 ) ), 1.0, 1.0, 100.0 );
end;

procedure TMenu.Initialise_clavier;
begin
  clavier := Microsoft.DirectX.DirectInput.Device.Create(SystemGuid.keyboard);
  clavier.SetCooperativeLevel(Self, (CooperativeLevelFlags.Background
                                      or CooperativeLevelFlags.NonExclusive));
  clavier.Acquire;

end;

procedure TMenu.Lire_clavier (sender : Tobject ; e:TEventArgs);
var
  keys: KeyboardState;
  dev : device;
begin
  keys := clavier.GetCurrentKeyboardState;
  dev := Device( sender );
  if keys[Key.up] then
  begin
    if i=0 then
    i:= 4
    else
    i:=(i-1);


    if i=0 then

     Ftexture:= TextureLoader.FromFile( dev, 'menu1.bmp' );

    if i=1 then
     Ftexture:= TextureLoader.FromFile( dev, 'menu2.bmp' );

    if i=2 then
     Ftexture:= TextureLoader.FromFile( dev, 'menu3.bmp' );

    if i=3 then
     Ftexture:= TextureLoader.FromFile( dev, 'menu4.bmp' );

    if i=4 then
     Ftexture:= TextureLoader.FromFile( dev, 'menu5.bmp' );

    sleep(200);
  end;

  if keys[Key.down] then
  begin
  if i = 4 then
    i:= 0
  else
    i:=i+1;

    if i=0 then

     Ftexture:= TextureLoader.FromFile( dev, 'menu1.bmp' );

    if i=1 then
     Ftexture:= TextureLoader.FromFile( dev, 'menu2.bmp' );

    if i=2 then
     Ftexture:= TextureLoader.FromFile( dev, 'menu3.bmp' );

    if i=3 then
     Ftexture:= TextureLoader.FromFile( dev, 'menu4.bmp' );

    if i=4 then
     Ftexture:= TextureLoader.FromFile( dev, 'menu5.bmp' );

    sleep(200);
  end;

  if keys[Key.return] then
    if i=0 then
      Tgame.create;
    

  
end;


procedure TMenu.main;

begin

  render;
end;

end.

