  '
  'OPENGLSCENEUTIL.INC
  '
  'excluded from openglES
  '
  GLYPHMETRICSFLOAT gmf[1024] 'support 4 fonts

  sub setPerspective()
  ====================
  glMatrixMode GL_PROJECTION
  glLoadIdentity
  'gluPerspective 45.0, aspect, 1.0, 1.0e6 'viewAngle,aspect,near,far
  static single znear=1,zfar=1.0e5,fovy=45.0
  static single y = zNear * tan(rad(fovy/2))
  single x = y * aspect
  glFrustum -x, x, -y, y, zNear, zFar
  glMatrixMode GL_MODELVIEW
  end sub




  'http://www.opengl.org/sdk/docs/man2/xhtml/glFog.xml

  macro Fog(r,g,b,d)
  ==================
  float FogColor[4]={r,g,b, .99}
  glfogi   GL_FOG_MODE,    GL_EXP
  glfogf   GL_FOG_DENSITY, d
  glfogfv  GL_FOG_COLOR,   FogColor
  glfogf   GL_FOG_INDEX,   0
  glfogf   GL_FOG_START,  -1.0
  glfogf   GL_FOG_END,    -100.0
  glEnable GL_FOG
  end macro



  macro shading() if not pick then glEnable GL_LIGHTING

  macro flat()    glDisable GL_LIGHTING


  'OBJECT SELECTING SYSTEM
  '=======================
  '

  #ifdef ColorCodedPick
  =====================

  macro PickSetup()
  =================
  if pick
    glDisable GL_FOG
    glDisable GL_TEXTURE_2D
    flat
    glcolor4f 0,0,0,1
    static float bkx=1.0e7,bky=1.0e7,bkz=-9.9e5
    QuadTex bkx,bky,bkz 'BACKDROP (itr glClearColor flickering)
  end if
  end macro

  macro BeginPick()
  =================
  if bLeft+bMid+bWheel+bRight then
    if picking=0 then
      pick=1
    end if
    picking=1 'inhibit further picks till buttons released
  else
    picking=0
  end if
  RebuildFrame:
  end macro

  macro EndPick()
  ===============
  if pick then
    glReadpixels mposx-lpane, crect.bottom-mposy, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, @pickpix
    picked=pickpix and 0xffffff
    pick=0
    goto RebuildFrame 'FULL RENDER
  end if
  end macro

  macro picklabel() glcolor3ubv

  def label picklabel

  #endif
  ====================


  =====================================================
  #ifndef ColorCodedPick 'GL_SELECT RENDERING TECHNIQUE
  =====================================================

  macro PickSetup()
  =================
  end macro

  macro PickPrep
  ==============
  glInitNames()
  glSelectBuffer SelectBufSize, selectBuf
  glRenderMode GL_SELECT
  glPushName 0 'an arbitrary value
  picked=0
  pick=1
  '2 x 2 pixel viewport at mouse position
  glMatrixMode GL_PROJECTION
  glLoadIdentity
  gluPickMatrix( mposx-lpane, crect.bottom-mposy, 2.0, 2.0, byval @crect) 'pixel selection zone
  gluPerspective 45.0, aspect, 1.0, 1.0e6 'viewAngle,aspect,near,far
  glMatrixMode GL_MODELVIEW
  end macro
  '
  macro BeginPick()
  ===================
  if bleft+bmid+bWheel+bright<>0 and pick+picking=0
    PickPrep
    picking=1
  elseif bleft+bmid+bWheel+bright+pick=0
    picking=0
  end if
  RebuildFrame:
  '
  end macro
  '
  macro PickResult
  ================
  scope
  indexbase 1
  glPopName()
  int hits,c,i
  dword w,v,u
  hits=glRenderMode(GL_RENDER)
  i=1
  c=hits*4
  v=SelectBuf(i+1)
  while i<c
    u=SelectBuf(i+1) 'min
    if u<=v
      w=SelectBuf(i+3) 'last stacked name
      v=u
    end if
    i+=3+SelectBuf(i) 'skip number of names on stack
  wend
  pick=0
  setPerspective
  picked=w
  end scope
  end macro
  '
  macro EndPick
  =============
  if pick
    PickResult
    goto RebuildFrame
  end if
  end macro
  '
  sub PickLabel(int n)
  ====================
  if pick then glLoadName n
  end sub
  '
  macro label() PickLabel
  '
  ====================
  #endif 'PICK SYSTEMS
  ====================
  '
  '
  sub Lighting(float*li)
  ======================
  glLightfv GL_LIGHT1, GL_POSITION, li[1]
  glLightfv GL_LIGHT1, GL_DIFFUSE,  li[5]
  glLightfv GL_LIGHT1, GL_AMBIENT,  li[9]
  glLightfv GL_LIGHT1, GL_SPECULAR, li[13]
  glEnable GL_LIGHT1
  end sub
  '
  macro StandardLighting(li)
  ==========================
  static float li={
  0.0, 8.0, 8.0, 0.0,  'position / w=0 parallel or w=1 for directional
  1.0, 1.0, 1.0, 1.0,  'diffuse 
  1.0, 1.0, 1.0, 1.0,  'ambient
  1.0, 1.0, 1.0, 1.0   'specular
  }
  Lighting li
  glEnable GL_LIGHTING
  end macro
  '
  sub Material(float* ma)
  =======================
  if pick then exit sub
  if not @ma then exit sub
  glMaterialfv GL_FRONT, GL_DIFFUSE,   ma[1]
  glMaterialfv GL_FRONT, GL_AMBIENT,   ma[5]
  glMaterialfv GL_FRONT, GL_SPECULAR,  ma[9]
  glMaterialf  GL_FRONT, GL_SHININESS, ma[13] '0..1000 -> smallest
  end sub
  '
  macro StandardMaterial(ma)
  ==========================
  static float ma={
  0.7, 0.70, 0.70, 1.0, 'diffuse
  .15, 0.15, 0.15, 1.0, 'ambient
  0.1, 0.10, 0.10, 1.0, 'specular  
  0.0                   'shininess
  }
  Material ma
  end macro



  sub QuadTex(float x,y,z)
  =================================
  glBegin GL_TRIANGLE_STRIP
  glTexCoord2f 0.0,0.0 : glNormal3f 0.0,0.0,1.0 : glVertex3f -x,-y, z
  glTexCoord2f 1.0,0.0 : glNormal3f 0.0,0.0,1.0 : glVertex3f  x,-y, z
  glTexCoord2f 0.0,1.0 : glNormal3f 0.0,0.0,1.0 : glVertex3f -x, y, z    
  glTexCoord2f 1.0,1.0 : glNormal3f 0.0,0.0,1.0 : glVertex3f  x, y, z
  glend
  end sub

  sub QuadNorm(optional float x,y,z, int m=0)
  ===========================================
  'Configured As Front Face
  int mo=1
  if @m then mo=m
  if not x then x=1.0
  if not y then y=x
  glBegin GL_TRIANGLE_STRIP
  glNormal3f   0.0 , 0.0  , 1.0
  if m=0 then glTexCoord2f 0.0 , 0.0
  glVertex3f -x , -y , z  
  if m=0 then glTexCoord2f 1.0 , 0.0
  glVertex3f  x , -y , z  
  if m=0 then glTexCoord2f 0.0 , 1.0
  glVertex3f -x ,  y , z  
  if m=0 then glTexCoord2f 1.0 , 1.0
  glVertex3f  x ,  y , z  
  glEnd
  end sub

  function CompileList(int list=0) as int
  =======================================
  indexbase 1
  if not list then
    function = glGenLists 1
    lisn[++lisi]=function 'LOG FOR DELETION AT END
  else
    function = list
  end if
  glNewList function, GL_COMPILE
  end function
  '
  macro BeginGlCompile(n)
  =======================
  #ifndef n
  static int n
  #endif
  if n=0 then
  n=CompileList
  end macro
  '
  macro EndGlCompile()
  ====================
  glEndList
  end if
  end macro
  '

  macro go(n)
  ===========
  if n then glCallList n
  end macro
  '
  macro DeleteAllGlCompiled
  =========================
  scope
  indexbase 1
  int i,a
  for i=1 to lisi
    a=lisn[i]
    if a then glDeleteLists a,1
  next
  end scope
  end macro


  sub Sides(int n,float x,y, optional int m)
  ==========================================
  float r=1.0
  float w=tan(pi/n)
  float a=360/n
  int i
  for i=1 to n
  QuadNorm x*w,y*w,r,m : glRotatef a,0,1,0 'anticlockwise: front right.back,left
  next
  end sub

  function CubeForm(optional int m) as int
  ========================================
  glPushMatrix
  Sides 4,1,1,m
  glRotatef 90.0,1,0,0 'bottom
  QuadNorm 1.0,1.0,1.0,m
  glRotatef 180.0,1,0,0 'top
  QuadNorm 1.0,1.0,1.0,m
  glPopMatrix
  end function



  '% ANSI_CHARSET        = 0
  '% DEFAULT_CHARSET     = 1
  '% SYMBOL_CHARSET      = 2

  sub BuildFont (sys hWnd,hDC,hRC, int base=1024, string name="Arial", int weight=FW_NORMAL, charset=DEFAULT_CHARSET)
  ===================================================================================================================
  indexbase 0
  LOGFONT   glFont
  sys       glFontHandle
  '
  glFont.lfHeight         = 1                             'Height Of Font
  glFont.lfWeight         = weight                        'Font Weight FW_BOLD etc
  glFont.lfCharSet        = charset                       'Character Set Identifier
  glFont.lfOutPrecision   = OUT_TT_PRECIS                 'Output Precision
  glFont.lfClipPrecision  = CLIP_DEFAULT_PRECIS           'Clipping Precision
  glFont.lfQuality        = ANTIALIASED_QUALITY           'Output Quality
  glFont.lfPitchAndFamily = FF_DONTCARE or DEFAULT_PITCH  'Family And Pitch
  glFont.lfFaceName       = name    ' "Arial" "Lucida Console" "Consolas" ' "Courier New"    'Font Name
  '
  glFontHandle = CreateFontIndirect(@glFont)
  glFontHandle = SelectObject(hDC, glFontHandle)
  wglUseFontOutlinesA (hDC, 0, 256, base, 0.0, .25, WGL_FONT_POLYGONS, @gmf[base-1024])
  DeleteObject(glFontHandle)
  end sub

  function GetCharArea(int c, single *x,*y, optional int fnt)
  ==============================================================
  '
  'TYPE POINTFLOAT
  '  x AS SINGLE
  '  y AS SINGLE
  'END TYPE
  '
  'TYPE GLYPHMETRICSFLOAT
  '  gmfBlackBoxX AS SINGLE
  '  gmfBlackBoxY AS SINGLE
  '  gmfptGlyphOrigin AS POINTFLOAT
  '  gmfCellIncX AS SINGLE
  '  gmfCellIncY AS SINGLE
  'END TYPE
  '
  indexbase 0
  int v
  v=77+fnt*0x100 '77=='M'
  'y=gmf[v].gmfCellIncY
  y=gmf[v].gmfBlackBoxY
  int a
  a=c+fnt*0x100
  x=gmf[a].gmfCellIncX
  end function

  function GetWordArea(string s, single *x,*y, optional int fnt)
  ==============================================================
  '
  indexbase 0
  int v
  x=0
  v=77+fnt*256 '77=='M'
  'y=gmf[v].gmfCellIncY
  y=gmf[v].gmfBlackBoxY
  int a,b,e=len s
  for b=1 to e
    a=asc(s,b)+fnt*256
    x+=gmf[a].gmfCellIncX
  next
  end function

  function PutBoxArea(single x,y,z=0.0)
  =====================================
  glbegin GL_TRIANGLE_STRIP
  glvertex3f 0,0,z
  glvertex3f x,0,z
  glvertex3f 0,y,z
  glvertex3f x,y,z
  glend
  end function

  '% ANSI_CHARSET        = 0
  '% DEFAULT_CHARSET     = 1
  '% SYMBOL_CHARSET      = 2

  function print3D(optional string s, float lf, int fnt)
  ======================================================
  float x,y
  if lf
    glPushMatrix
  end if
  if s
    int le=len s
    if pick then
      int i,c
      for i=1 to le 'render each char box
        c=asc s,i
        GetCharArea c,x,y,fnt
        picklabel picktext+i 'char pos offset
        PutBoxArea  x,y
        glTranslatef x,0,0
      next
    else 'not pick mode
      'print whole string
      glPushAttrib GL_LIST_BIT
      glListBase   1024+fnt*256
      glCallLists le, GL_UNSIGNED_BYTE, strptr s
      glPopAttrib
    end if
  end if
  if lf
    glPopMatrix
    glTranslatef .0,-lf,.0 'line feed
  end if
  end function
  '
  '
  function gprint(optional string s, float lf, int fnt)
  =====================================================
  glScalef 1.,1.,.001
  print3D s,lf,fnt
  glScalef 1.,1.,1000
  end function

   
   
