  function QuadShadow(float x,y,w,a)
  ==================================
  float u,v
  float b=0.0
  u=x+w
  v=y+w
  glbegin GL_TRIANGLE_STRIP
  glcolor4f b,b,b,a
  glvertex2f -x,-y
  glcolor4f b,b,b,b
  glvertex2f -u,-v
  glcolor4f b,b,b,a
  glvertex2f  x,-y
  glcolor4f b,b,b,b
  glvertex2f  u,-v
  glcolor4f b,b,b,a
  glvertex2f  x,y
  glcolor4f b,b,b,b
  glvertex2f  u,v
  glcolor4f b,b,b,a
  glvertex2f  -x,y
  glcolor4f b,b,b,b
  glvertex2f  -u,v
  glcolor4f b,b,b,a
  glvertex2f  -x,-y
  glcolor4f b,b,b,b
  glvertex2f  -u,-v
  glend
  end function
  '

  function MakePolygon(float s,n,l) as sys
  ========================================
  int Shape,i
  float an,ai,ca,sa
  ai=2*pi/n
  an=rad(s) 'starting angle
  BeginGlCompile Shape
  glBegin GL_TRIANGLE_FAN
  glTexCoord2f 0.0, 0.0 : glVertex3f  0.0, 0.0, 0.0000
  for i=0 to n
    ca=cos(an)
    sa=sin(an)
    glTexCoord2f .5*(1.0+ca), .5*(1.0+sa)
    glVertex3f  ca, sa, 0.0
    an+=ai
  next
  glEnd
  if l
    glHint GL_LINE_SMOOTH_HINT, GL_NICEST
    glEnable GL_LINE_SMOOTH
    glLineWidth l
    glColor4f .0,.0,.0,.4
    an=rad(s) 'starting angle
    glBegin GL_LINE_STRIP
    for i=0 to n
      ca=cos(an)
      sa=sin(an)
      glVertex3f  ca, sa, 0.0001
      an+=ai
    next
    'glDisable GL_LINE_SMOOTH
    glEnd
  end if
  EndGlCompile
  return shape
  end function


  function drag(float*dx,*dy,sci)
  ===============================
  'adjusted for perspective distance
  sys a=crect.bottom
  float f=1.0/(a*sci) 'assume z=approx -1.0
  dx=f*(mposx-sposx)
  dy=f*(sposy-mposy)
  end function


  class FixedControl 'base for 3d controls
  ========================================
  float  x,y,z       'location
  float  sc          'scale
  int    sh          'shape of knob etc
  int    shb         'shape of static body
  int    tex         'texture
  int    id          'id number
  int    lock        'fix position
  bstring label      'descriptive
  =========================================
  method destructor
    del label
  end method
  end class


  class AdjustableControl
  ========================================
  FixedControl       'inherit
  float  vx,vy,vz    'values
  float  dx,dy,dz    'move displacement
  float  xx,yy,zz    'anchors
  float  scp         'scale of parent
  ========================================
  end class
  '

  class LightButtons
  ==================
  FixedControl
  int    lit,tog     'state and toggle
  '
  method Render()
  glPushMatrix
  gltranslatef  x,y,.0001 'z microplane
  glscalef sc,sc,sc
  if pick
    PickLabel id
  else
    if tex
      glBindTexture GL_TEXTURE_2D,tex
    endif
    if lit
      glColor3f .9,.9,.0
    else
      glColor3f .2,.2,.0
    endif
  endif
  '
  if sh
    glCallList sh
  else
    QuadTex 1.0,1.0,0
    if not pick
      QuadShadow  1.0,1.00,.2,.4
    endif
  endif
  glPopMatrix
  end method

  '
  method act(float sci, int ii,*oo) as int
  if not pick
    if bleft
      if picked=id
        if tog
          lit=1-lit
        endif
        tog=0 'one go until bleft is released
        method=id
        oo=ii
      endif 'picked=id
    else
      tog=1 'allow state change
    endif 'bleft or not
  endif 'not pick
  render
  end method

  end class


  class knobs
  ===========
  AdjustableControl
  float r,g,b,a
  float va
  '
  method Render()
  glPushMatrix
  gltranslatef  x,y,.0001
  glscalef      .25*sc,.25*sc,1.0
  if pick
    PickLabel id+1
  else
    if tex then glBindTexture GL_TEXTURE_2D,tex
    if a=0 then r=0.7 : g=0.6 : b=0.8 : a=1.0
    glColor4fv  byval @r
  endif
  if sh then glCallList sh
  renderM 'moveable components
  glPopMatrix
  end method
  '
  method renderM()
  if not pick
    glcolor4f .33,.0,.0,.6
    glbegin GL_LINES
    glEnable GL_LINE_SMOOTH
    glVertex3f 0.0,0.0,.0001
    float m=1.2 - 5.6*va
    glVertex3f cos(m),sin(m),.0001
    glEnd
  endif
  end method
  '
  method get() as float
  return .5*limit(0.0,1.0+vx-vy,2.0) 'range 0..1
  end method
  '
  method set(float v) '0..1
  vx=v*2-1.0
  vy=0
  end method
  '
  method act(float sci, int ii,*oo) as sys
  if bleft
    if picked=id+1
      drag(dx,dy,sc*sci*.5)
      vx=limit(-1.0,xx+dx,1.0)
      vy=limit(-1.0,yy+dy,1.0)
      method=id
      oo=ii
    end if
  else
    xx=vx : yy=vy : zz=vz 'ANCHOR
  end if
  render
  va=get
  end method
  '
  end class


  class joysticks
  ===============
  AdjustableControl
  '
  method Render()
  if tex then glBindTexture GL_TEXTURE_2D,tex
  glPushMatrix
  gltranslatef  x,y,.0001
  glscalef      sc,sc,sc
  if pick
    PickLabel id
  else
    glColor4f   .70,.60,.80,.70
  endif
  QuadTex     .99,.99,.00
  if not picked
    QuadShadow  .99,.99,.05,.4
    glColor4f   .6,.6,.0,1.0
  endif
  QuadTex     .99,.025,.0001
  if not pick
    glColor4f   .30,.30,.60,.99
  endif
  QuadTex     .025,.99,.0001
  renderM 'moveable components
  glPopMatrix
  end method
  '
  method renderM()
  gltranslatef .0,.0,.0002
  if sh then
    glScalef .25,.25,1.0
    glcolor4f .60,.60,.0,0.6
    go sh
    glScalef 4.0,4.0,1.0
  end if
  gltranslatef vx*.8,vy*.8,.0003
  if pick
    PickLabel id+1
  else
    glcolor4f .70,.0,.0,1.0
  endif
  if sh then
    glScalef .25,.25,1.0
    go sh 'KNOB 
    'STICK
    if not pick
      glcolor4f .20,.20,.60,1.0
    endif
    glLineWidth 5  
    glBegin GL_LINES
    glVertex3f 0.0,0.0,-.0001
    glVertex3f -vx*3.0,-vy*3.0,-.0001
    glEnd
    glLineWidth 1
    glPointSize 9
    glbegin GL_POINTS
    glVertex3f -vx*3.0,-vy*3.0,-.0001
    glEnd
    glPointSize 1
  else
    QuadTex .25,.25,.0000 
    'glcolor4f .66,.0,.0,1.0
    'QuadTex .25,.01,.0000
  end if
  end method
  '
  method act(float sci, int ii,*oo) as sys
  if bleft
    if picked=id+1
      drag(dx,dy,sc*sci)
      vx=limit(-1.0,xx+dx,1.0)
      vy=limit(-1.0,yy+dy,1.0)
      method=id
      oo=ii
    end if
  else
    xx=vx : yy=vy : zz=vz 'ANCHOR
  end if
  render
  end method
  '
  end class

  class sliders
  =============
  AdjustableControl
  '
  method Render()
  if tex then glBindTexture GL_TEXTURE_2D,tex
  glPushMatrix
  gltranslatef  x,y,.0001
  glscalef      sc,sc,sc
  if pick
    PickLabel id
  else
    glColor4f   .7,.6,.8,.7
  endif
  QuadTex     .25,.99,0
  if not pick
    QuadShadow  .25,.99,.05,.4
    glColor3f   .3,.0,.0
  endif
  QuadTex     .025,.8,.0001
  renderM 'moveable components
  glPopMatrix
  end method
  '
  method renderM()
  gltranslatef vx*.8,vy*.8,.0002
  if pick
    PickLabel id+1
  else
    glcolor4f .33,.0,.0,1.0
  endif
  if sh then
    glScalef .25,.20,1.0
    go sh
  else
    QuadTex .25,.10,.0001
    if not pick 
      glcolor4f .66,.0,.0,1.0
    endif
    QuadTex .25,.01,.0002
  end if
  end method
  '
  '
  method act(float sci, int ii,*oo) as sys
  if bleft
    if picked=id+1
      drag(dx,dy,sc*sci)
      'vx=limit(-1.0,xx+dx,1.0)
      vy=limit(-1.0,yy+dy,1.0)
      method=id
      oo=ii
    end if
  else
    xx=vx : yy=vy : zz=vz 'ANCHOR
  end if
  render
  end method
  '
  '
  end class
