Application showing OpenGL lit surface which can be rotated and zoomed using GINO & GINOSURF

unit surflightpas;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ginolib, surflib, ComCtrls, Math, surflight2,
  Menus;
    procedure DrawSurface();
    procedure ReadData();
    procedure StartGino();
type
  TForm1 = class(TForm)
    Image1: TImage;
    ScrollBar1: TScrollBar;
    Label1: TLabel;
    ScrollBar2: TScrollBar;
    Label2: TLabel;
    Label3: TLabel;
    Button5: TButton;
    ScrollBar3: TScrollBar;
    Label4: TLabel;
    ScrollBar4: TScrollBar;
    Label5: TLabel;
    Button6: TButton;
    ComboBox1: TComboBox;
    Label6: TLabel;
    ComboBox2: TComboBox;
    Label7: TLabel;
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Exit1: TMenuItem;
    Help1: TMenuItem;
    About1: TMenuItem;
    procedure FormPaint(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ScrollBar1Change(Sender: TObject);
    procedure ScrollBar2Change(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure ScrollBar3Change(Sender: TObject);
    procedure ScrollBar4Change(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure ComboBox1Change(Sender: TObject);
    procedure ComboBox2Change(Sender: TObject);
    procedure Exit1Click(Sender: TObject);
    procedure About1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  NUMX : Integer =251;
  NUMY : Integer =251;
  drawcont : Integer = 0;
  Form1: TForm1;
  Bitmap : Tbitmap;
  mynewHdc,ip,it, myHdc: Integer;
  paper: GDIM;
  lastpos : Single = 0.0;
  lastxrot : Single = 0.0;
  lastyrot : Single = 0.0;
  lastzrot : Single = 0.0;
  xcentre,ycentre : Single;
  rotation,viewplane,dist : Single;
  work : GWORKSPACE;
  gridz : array[0..400,0..400] of Single;
  grid : array[0..400,0..400] of Single;
  grid3D : array[0..160800] of GPOINT3;
  index : array[0..399,0..399] of GFILL;
  data : array of GPOINT3;
  data_limit : GLIMIT = (xmin: 999.0; xmax: -999.0; ymin: 999.0; ymax: -999.0);
viewport : GLIMIT;
picture3D : GLIMIT3 = (xmin: 0.0; xmax: 400.0; ymin: 0.0; ymax: 400.0; zmin: -2000.0; zmax: 2000.0);
implementation
uses surflight3;
{$R *.dfm}
procedure ReadData();
var
F : Textfile;
ii,jj : Integer;
begin
AssignFile(F,'snowdon.dat');
reset(F);
for ii:=0 to 400 do
begin
  for jj:=0 to 400 do
  begin
    read(F,grid[ii,jj]);
    grid[ii,jj]:=grid[ii,jj]/20.0;
    grid3D[ii*401+jj].x:=ii;
    grid3d[ii*401+jj].y:=jj;
    grid3d[ii*401+jj].z:=grid[ii,jj];
  end;
end;
closefile(F);
data_limit.xmin:=0.0;
data_limit.xmax:=400.0;
data_limit.ymin:=0.0;
data_limit.ymax:=400.0;
      xcentre:=(data_limit.xmax-data_limit.xmin)/2.0+data_limit.xmin;
      ycentre:=(data_limit.ymax-data_limit.ymin)/2.0+data_limit.ymin;
end;
procedure StartGino();
begin
        gOpenGino;
  myHdc:=Integer(Form1.Image1.Canvas.Handle);
  gWogldc( GNULL, myHdc);
//
//
// Set up viewport
      gDefineRGB(0,212/255,208/255,200/255);
   gEnqDrawingLimits(paper,ip);
   viewport.xmax:=paper.xpap;
   viewport.ymax:=paper.ypap;
   gSetViewport3D(picture3D,viewport);
//
// Set up initial view
//
      gSetViewAxis(GXAXIS,GZAXIS);
      gShift3D(-xcentre,-ycentre,0.0);
      gDefinePerspView(0.0,100.0,300.0,0.0,-1.0,-3.0,200.0);
      gUpdateView;
      DrawSurface();
end;
procedure DrawSurface();
var
state : GSURF3D;
radius,theta,phi : Single;
npts,i,j : Integer;
begin
      gsOpenSurf;
      state.hard:=GON;
      state.proj:=GON;
      gsSetSurf3DState(state);
      dist:=200.0;
//
//  Use gsGenerateRandomGrid to give finer/coarser mesh
//
      gsGenerateRandomGrid(160801,grid3D[0],data_limit,numx,numy,gridz[0,0],work);
//
// Set up smooth 3D shading
//
         case drawcont of
           0,2: gSetFacetFillStyle(GSOLID);
           1,3: gSetFacetFillStyle(GHOLLOW);
         end;
         gSetShadingMode(GGOURAUD,GBACK,GOFF,GANTICLOCKWISE);
         gSetLightSwitch(1,GON);
         gSetMaterialIndex(1,0);
//
//  Fill index array with single colour
//
         for i:=0 to 399 do
         begin
           for j:=0 to 399 do
           begin
             index[i,j].fill := GSOLID;
             if drawcont < 2 then
                index[i,j].line := GGREEN
             else
                index[i,j].line:=j;
           end;
         end;
//
//  Draw perspective surface
//
      gsSetSurfaceBaseType(GBOTHSURFACES);
      gsSetSurfaceGridInterval(numx-1,numy-1);
      gOpenSeg(1);
      if drawcont < 2 then
      gsFillSurface(data_limit,numx,numy,gridz[0,0],radius,theta,phi,index[0,0],work)
      else
      gsFillContourSurface3D(data_limit,numx,numy,gridz[0,0],radius,theta,phi,10,index[0,0],GOFF,work);
      gCloseSeg();
      gsCloseSurf();
end;
procedure TForm1.ScrollBar3Change(Sender: TObject);
begin
//
// Rotate about X axis
//
   gNewDrawing();
   rotation:=ScrollBar3.Position-lastxrot;
   gViewRotate(GYZPLANE,rotation,dist);
   lastxrot:=ScrollBar3.Position;
   gUpdateView;
   gDrawSeg(1);
   Invalidate;
end;
procedure TForm1.ScrollBar1Change(Sender: TObject);
begin
//
// Rotate about Y axis
//
   gNewDrawing();
   rotation:=ScrollBar1.Position-lastyrot;
   gViewRotate(GXZPLANE,rotation,dist);
   lastyrot:=ScrollBar1.Position;
   gUpdateView;
   gDrawSeg(1);
   Invalidate;
end;
procedure TForm1.ScrollBar4Change(Sender: TObject);
begin
//
// Rotate about Z axis
//
   gNewDrawing();
   rotation:=ScrollBar4.Position-lastzrot;
   gViewRotate(GXYPLANE,rotation,dist);
   lastzrot:=ScrollBar4.Position;
   gUpdateView;
   gDrawSeg(1);
   Invalidate;
end;
procedure TForm1.ScrollBar2Change(Sender: TObject);
begin
//
//  Zoom in/out
//
   gNewDrawing();
   viewplane:=ScrollBar2.Position-lastpos;
   gMoveViewCentre(viewplane);
   lastpos:=ScrollBar2.Position;
   gUpdateView;
   gDrawSeg(1);
   Invalidate;
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
//
//  Reset
//
   gSetTransform(GRESET);
//
// Set up initial view
//
      gSetViewAxis(GXAXIS,GZAXIS);
      gShift3D(-xcentre,-ycentre,0.0);
      gDefinePerspView(0.0,100.0,300.0,0.0,-1.0,-3.0,200.0);
      gUpdateView;
   gDrawSeg(1);
   lastpos:=0.0;
   lastxrot:=0.0;
   lastyrot:=0.0;
   lastzrot:=0.0;
   ScrollBar1.Position:=0;
   ScrollBar2.Position:=0;
   ScrollBar3.Position:=0;
   ScrollBar4.Position:=0;
   Invalidate;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//
//  Deallocate workspace and data array and close down GINOSURF
//
      gsFreeWorkspace(work);
      gsCloseSurf;
      gCloseGino();
end;
procedure TForm1.FormPaint(Sender: TObject);
var
mynewHdc: Integer;
begin
   ControlStyle:=ControlStyle+ [csOpaque];
   mynewHdc:=Integer(Image1.Canvas.Handle);
   gFlushGraphics;
   gWoglUpdateDC(mynewHdc);
end;
procedure TForm1.Button6Click(Sender: TObject);
begin
  Application.Terminate;
end;
procedure TForm1.ComboBox1Change(Sender: TObject);
//
// Change Grid dimensions
//
begin
  numx:=(ComboBox1.ItemIndex+1)*50+1;
  numy:=(ComboBox1.ItemIndex+1)*50+1;
  gNewDrawing;
  gDeleteSeg(1);
  Form2.Show;
  DrawSurface;
  Invalidate;
  Form2.Hide;
end;
procedure TForm1.ComboBox2Change(Sender: TObject);
//
// Flip between surface and contoured-surface
//
begin
drawcont:=ComboBox2.ItemIndex;
  gNewDrawing;
  gDeleteSeg(1);
  Form2.Show;
  DrawSurface;
  Invalidate;
  Form2.Hide;
end;
procedure TForm1.Exit1Click(Sender: TObject);
begin
  Application.Terminate;
end;
procedure TForm1.About1Click(Sender: TObject);
begin
Form3.Show;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
StartGino();
end;
end.