unit Shapes;

interface

uses
  sysutils,
  OpenGL;

type
  PHit=^THit;
  THit=packed record
    ncount,
    dnear,
    dfar: GLuint;
    names: array[1..32] of GLuint;
  end; {THit}

procedure Pyramid;
procedure Cube;
procedure CylinderBase;
procedure Cylinder;
procedure Cone;
procedure Dome;
procedure Selection(px,py:GLdouble);
function SelectionDone:GLint;

var
  PickBuffer: array[1..256] of GLuint;
  circleX,
  circleY,
  circleZ: array[0..35] of glFloat;

implementation

procedure Pyramid;
begin
  glBegin(GL_TRIANGLE_FAN);
    glVertex3f(+0.0,+0.0,+0.0);
    glVertex3f(-0.3,+0.3,-0.4);
    glVertex3f(+0.3,+0.3,-0.4);
    glVertex3f(+0.0,-0.3,-0.4);
    glVertex3f(-0.3,+0.3,-0.4);
  glEnd;
end;

procedure Cube;
begin
  glBegin(GL_TRIANGLE_STRIP);
    glVertex3f(-0.4,+0.4,+0.4);
    glVertex3f(-0.4,-0.4,+0.4);
    glVertex3f(+0.4,+0.4,+0.4);
    glVertex3f(+0.4,-0.4,+0.4);
    glVertex3f(+0.4,+0.4,-0.4);
    glVertex3f(+0.4,-0.4,-0.4);
    glVertex3f(-0.4,+0.4,-0.4);
    glVertex3f(-0.4,-0.4,-0.4);
    glVertex3f(-0.4,+0.4,+0.4);
    glVertex3f(-0.4,-0.4,+0.4);
  glEnd;
end;

procedure CylinderBase;
var
  around: integer;
  pi18: double;
begin
  pi18 := pi/18.0;
  for around := 0 to 35 do
  begin
    circleX[around] := 0.4*sin(around*pi18);
    circleY[around] := 0.4*cos(around*pi18);
  end;
end;

procedure Cylinder;
var
  around: integer;
begin
  glBegin(GL_TRIANGLE_STRIP);
    for around := 0 to 35 do
    begin
      glVertex3f(circleX[around],circleY[around],-0.4);
      glVertex3f(circleX[around],circleY[around],+0.4);
    end; {for}
    glVertex3f(circleX[0],circleY[0],-0.4);
    glVertex3f(circleX[0],circleY[0],+0.4);
  glEnd;
end;

procedure Cone;
var
  around: integer;
begin
  glBegin(GL_TRIANGLE_FAN);
    glVertex3f(0.0,0.0,0.4);
    for around := 35 downto 0 do
      glVertex3f(circleX[around],circleY[around],0.0);
    glVertex3f(circleX[35],circleY[35],0.0);
  glEnd;
end;

procedure Dome; 
var
  olddiam,
  oldlayer,
  diam,
  layer: double;
  place,
  around: integer;
begin
  for place := 1 to 9 do
  begin
    layer := circleY[place];
    diam := circleX[place]*2.5;
    if place=1 then
    begin
      glFrontFace(GL_CCW);
      glBegin(GL_TRIANGLE_FAN);
        glVertex3f(0.0,0.0,0.4);
        for around := 35 downto 0 do
          glVertex3f(circleX[around]*diam,circleY[around]*diam,layer);
        glVertex3f(circleX[35]*diam,circleY[35]*diam,layer);
    end else begin
      glFrontFace(GL_CW);
      glBegin(GL_TRIANGLE_STRIP);
        for around := 0 to 35 do
        begin
          glVertex3f(circleX[around]*olddiam,circleY[around]*olddiam,
            oldlayer);
          glVertex3f(circleX[around]*diam,circleY[around]*diam,layer);
        end; {for}
        glVertex3f(circleX[0]*olddiam,circleY[0]*olddiam,oldlayer);
        glVertex3f(circleX[0]*diam,circleY[0]*diam,layer);
    end;
    glEnd;
    olddiam := diam;
    oldlayer := layer;
  end; {for}
end;

procedure Selection(px,py:GLdouble);
type
  TViewPort=packed record
    left,bottom,width,height: GLint;
  end;
var
  viewport: TViewPort;
begin
  glRenderMode(GL_SELECT);
  glInitNames;
  glPushName(0);
  glMatrixMode(GL_PROJECTION);
  glPushMatrix;
  glLoadIdentity;
  glGetIntegerv(GL_VIEWPORT,@viewport);
  py := viewport.height-py;
  gluPickMatrix(px,py,2.0,2.0,@viewport);
end;

function SelectionDone:GLint;
begin
  glMatrixMode(GL_PROJECTION);
  glPopMatrix;
  result := glRenderMode(GL_RENDER);
end;

end.
