  #compact
  $ title     "Shaders and Index Buffer Objects"
  $ FileName  "t.exe"
  'uses RTL64
  %ExplicitMain

  uses OpenglSceneFrame
  uses glo2/ShaderSupport
  uses glo2/shaders
  uses glo2/shapes
  uses Sierpinski

  'types
  '====
  '
  type vert float x,y,z
  type tex  float u,v
  type rgba byte  r,g,b,a
  '
  '

  'globals
  '=====
  '
  indexbase 1
  int  ShaderShn,ShaderSky,ShaderRfl
  int  VBOs 'flag VBOs in use
  int  vbo[16]
  int  VertBuf,NormBuf,TexBuf,IndexBuf
  int  VertCount
  '
  int    cube,sphere,cylinder,tors,helix,vessel
  int    TexSky
  int    ShnUL[4]
  int    SkyUL[4]
  int    RflUL[4]
  float  cameraPosition[3]
  float  NormalMatrix[9]
  float  ModelMatrix[16]
  float  ModelMatrixInverse[16]
  float  Tint
  '
  string glExt
  '
  '
  sub BuildVertexArrays()
  =======================
   '
  indexbase 1
  '
  'CREATE DATA BUFFERS
  '
  VertCount=4
  sys n=100
  '
  VertBuf=getmemory n*sizeof vert
  NormBuf=getmemory n*sizeof vert
  TexBuf=getmemory n*sizeof tex
  IndexBuf=getmemory n*sizeof int
  '
  vert v at VertBuf
  v={-1.0,-1.0,0.0, 1.0, 0.-1,0.0,  1.0,1.0,0.0, -1.0,1.0,0.0}
  vert v at NormBuf
  v={0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0, 0.0,0.0,1.0}
  tex v at Texbuf
  v={ 0.0,0.0,  1.0, 0.0,  1.0,1.0,  0.0,1.0}
  int i at IndexBuf
  i={0,1,2,3}
  '
  if VBOs
    '
    glGenBuffers( 4, vbo )
    '
    macro setup(i,n,type,buf,m)
      glBindBuffer m, vbo[i]
      glBufferData m, n*sizeof(type), buf, GL_STATIC_DRAW
    end macro
    '
    n=VertCount
    setup 1,n,Vert,VertBuf,GL_ARRAY_BUFFER
    setup 2,n,Vert,NormBuf,GL_ARRAY_BUFFER
    setup 3,n,Tex,TexBuf,GL_ARRAY_BUFFER
    setup 4,n,Int,IndexBuf,GL_ELEMENT_ARRAY_BUFFER
    '
    freememory VertBuf
    freememory NormBuf
    freememory TexBuf
    freememory IndexBuf
  end if
  end sub


  sub DrawVertexArrays(optional int m)
  ====================================
  '
  sys ib 'index buffer
  glClientActiveTexture(GL_TEXTURE0)
  '
  glEnableClientState( GL_VERTEX_ARRAY )						// Enable Vertex Arrays
  glEnableClientState( GL_NORMAL_ARRAY )						// Enable Vertex Arrays
  glEnableClientState( GL_TEXTURE_COORD_ARRAY )
  '
  if VBOs
    static int loaded
    if m then loaded=0 'reload buffers
    if not loaded
      glBindBuffer( GL_ARRAY_BUFFER, vbo[1] )
      glVertexPointer( 3, GL_FLOAT, 0, null )
      '
      glBindBuffer( GL_ARRAY_BUFFER, vbo[2] )
      glNormalPointer( GL_FLOAT, 0, null )
      '
      glBindBuffer( GL_ARRAY_BUFFER, vbo[3] )
      glTexCoordPointer( 2, GL_FLOAT, 0, null )
      '
      glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vbo[4] )
      loaded=1
    end if
    ib=0
    '
  else
    glVertexPointer  ( 3, GL_FLOAT, 0, VertBuf )
    glNormalPointer  (    GL_FLOAT, 0, NormBuf )
    glTexCoordPointer( 2, GL_FLOAT, 0, TexBuf )
    ib=IndexBuf
  end if
  'glDrawArrays( GL_QUADS, 0, VertCount )
  glDrawElements( GL_QUADS, VertCount, GL_UNSIGNED_INT, ib )
  'Disable Pointers
  glDisableClientState( GL_VERTEX_ARRAY )
  glDisableClientState( GL_NORMAL_ARRAY )						// Enable Vertex Arrays
  glClientActiveTexture(GL_TEXTURE0)
  glDisableClientState( GL_TEXTURE_COORD_ARRAY )
  end sub



  sub initialize(sys hWnd)
  '=======================
  '
  finit
  int a
  SetupExtFunctions
  '
  GDIplus 1
  '
  glClientActiveTexture(GL_TEXTURE0)
  '
  LoadCubicTextures (
  "..\..\images\SkyBox\left.jpg",
  "..\..\images\SkyBox\right.jpg",
  "..\..\images\SkyBox\bottom.jpg",
  "..\..\images\SkyBox\top.jpg",
  "..\..\images\SkyBox\front.jpg",
  "..\..\images\SkyBox\back.jpg",
  TexSkY
  )
  'COMPILED GEOMETRY LISTS
  cube=CompileList   : CubeForm 1      : glEndList
  sphere=CompileList : Spheric 1,1,6 : glEndList
  cylinder = CompileList
  'glRotatef 180,1,0,0
  'Conefaces  18,0,0,1 'BASE CAP 
  'glRotatef 180,1,0,0
  Conefaces  18,1,1,1,1 'SIDE
  'glTranslatef 0,1,0 
  'Conefaces  18,0,0,1 'TOP CAP 
  'glTranslatef 0,-1,0 
  glEndList
  tors=CompileList   : torus 1.,.20  : glEndList
  helix=CompileList : toroid 1.,.25,.8,.16,5.,6. : glEndList
  vessel = CompileList
  glRotatef 180,1,0,0
  Conefaces  32,0,0.5,1,1 'BASE CAP 
  glRotatef 180,1,0,0
  Conefaces  32,1,1,1,1   'SIDE
  glTranslatef 0,1,0 
  Conefaces  18,0,1,1,1   'TOP CAP 
  glTranslatef 0,-1,0 
  glEndList
  '
  zstring z at glGetString GL_EXTENSIONS
  glExt=replace(z, chr(32),chr(13,10))
  'putfile "s.txt", glExt
  '
  shaders()
  '1  'MINIMAL
  '2  'PER PIXEL
  '3  'PHONG
  '4  'MULTIPLE LIGHTS 
  '5  'MULTIPLE LIGHTS AND TEXTURING
  '6  'SWAP COLORS
  '7  'COMBINED MULTIPLE LIGHTS AND TEXTURING AND REFLECTION
  '8  'SKY BOX
  '9  'CUBIC REFLECTION 1
  '10 'CUBIC REFLECTION 2
  '11 'CUBIC REFLECTION 3
  '12 '3.3 LIGHT MATERIAL AND CUBIC REFLECTION ALPHA SHADER
  '
  CreateShaderProg ps[1]
  CreateShaderProg ps[4]
  CreateShaderProg ps[5]
  CreateShaderProg ps[7]
  CreateShaderProg ps[8]
  CreateShaderProg ps[9]
  CreateShaderProg ps[10]
  CreateShaderProg ps[11]
  CreateShaderProg ps[12]
  '
  ShaderShn=ps[5].ph
  ShaderSky=ps[8].ph
  ShaderRfl=ps[11].ph
  '
  '
  SkyUL[4] = glGetUniformLocation(ps[8].ph, "CubeMap")
  '
  'RflUL[1] = glGetUniformLocation(ps[9].ph, "CameraPosition") 
  'RflUL[2] = glGetUniformLocation(ps[9].ph, "NormalMatrix")
  'RflUL[3] = glGetUniformLocation(ps[9].ph, "ModelMatrix")
  'RflUL[4] = glGetUniformLocation(ps[9].ph, "CubeMap")
  '
  RflUL[1] = glGetUniformLocation(ps[11].ph, "CameraPosition") 
  RflUL[2] = glGetUniformLocation(ps[11].ph, "ModelMatrix")
  RflUL[3] = glGetUniformLocation(ps[11].ph, "ModelMatrixInverse")
  RflUL[4] = glGetUniformLocation(ps[11].ph, "CubeMap")
  '
  VBOs=instrword glExt, "GL_ARB_vertex_buffer_object"
  'itr GL_ARB_half_float_pixel
  'itr GL_ARB_half_float_vertex

  'BuildVertexArrays()
  BuildSkyBox()
  '
  end sub


  sub Release(sys hwnd)
  '====================
  sys i
  DeleteAllGlCompiled
  Gdiplus 0
  glDeleteTextures 1,TexSky
  glDeleteBuffers  2, SkyBoxVBO
  if VBOs
    glDeleteBuffers  4, vbo 
  else
    freememory VertBuf
    freememory NormBuf
    freememory TexBuf
    freememory IndexBuf
  end if
  for i=1 to 32
    ReleaseShaderProg ps[i]
  next
  end sub


  sub scene(sys hWnd)
  '==================
  '
  static float s1,s2,ang1,angi1=.5
  '
  ActiveFrame
  '
  sys sky=1, rfl=1, shn=1 'SELECTOR
  '
  if ShaderError then exit sub
  '
  'SKY BOX RENDER
  '==============
  '
  if sky
  '
  'SKY BOX RENDER
  '==============
  '
  glPushMatrix
  glLoadIdentity
  glRotatef 30,-1,0,0 'tilt
  glRotatef Ang1*.4,0,1,0
  glScalef 1000,1000,1000
  DrawSkyBox(TexSky,ShaderSky)
  glPopMatrix
/*
  'UPPER RIGHT SPHERE
  '==================

  glUseProgram -1 'ShaderSky
  'glBindTexture(GL_TEXTURE_CUBE_MAP, TexSky)
  glpushmatrix
  glLoadIdentity
  gltranslatef 3,3,-10
 'glRotatef 30,-1,0,0
  glRotatef Ang1*.4,0,1,0
  'glEnable GL_TEXTURE_2D
  glscalef 2,2,2
  go sphere
  glpopmatrix
*/

  'glBindTexture(GL_TEXTURE_CUBE_MAP, 0)
  '
  end if 'sky
  '
  '
/*
  'REFLECTION RENDER
  '=================
  '
  if rfl
  '
  glLoadIdentity
  glTranslatef 0.0, 0.0, -3.0
  '
  'TUMBLER ROTATION
  glrotatef  -20, 1,0,0
  glrotatef ang1*.12, 0,0,1
  glrotatef ang1*.2, 0,1,0
  float s=.3
  glscalef s,s,s
  '
  '
  CameraPosition={0,0,0}
  '
  'glClientActiveTexture(GL_TEXTURE0)
  glBindTexture(GL_TEXTURE_CUBE_MAP, TexSky)
  glUseProgram ps[11].ph
  glUniform3fv(RflUL[1], 1, CameraPosition)
  go cube
  'go sphere
  'go tors
  'go cylinder
  'go vessel
  'DrawVertexArrays()
  glUseProgram -1
  end if
*/
  '
  '
  'SHINY RENDER
  '============
  '
  static float tint1={.2,.8,.0,1.}
  static float tint2={.0,.4,.2,1.}
  static float tint3={.0,.0,.0,1.}
  static float tint4={.0,.5,.7,1.}
  static float tint5={.3,.5,.3,.6}
  '
  if shn
  '
  int slTint,slTex,slCam,slCube,slCubeMap
  int sh=12 '5 7 or 12
  glUseProgram ps[sh].ph 'MATERIAL AND TEXTURE
  '
  slTint = glGetUniformLocation ps[sh].ph, "Tint"
  slTex  = glGetUniformLocation ps[sh].ph, "TextureUnit"
  slCam  = glGetUniformLocation ps[sh].ph, "CameraPosition"
  slCube = glGetUniformLocation ps[sh].ph, "CubeMap"
  '
  glClientActiveTexture GL_TEXTURE0+0
  glBindTexture GL_TEXTURE_CUBE_MAP, TexSky
  '
  '
  CameraPosition={0,0,0}
  '
  glUniform4fv slCam,  1, CameraPosition
  glUniform1i  slTex,  0  'TEXTURE UNIT
 'glUniform1i slCube,  0  'TEXTURE UNIT

  float a=.5

/*
  'CENTRAL OBJECT
  '--------------
  glPushMatrix
  glLoadIdentity
  glTranslatef 0,0,-3
  glScalef a,a,a
  glUniform4fv slTint, 1, tint4
  'glrotatef ang1*1, 0,1,0
  'go sphere
  glPopMatrix
*/

  'TUMBLING OBJECT
  '---------------
  glPushMatrix
  glLoadIdentity
  glTranslatef 0.0, 0, -3.0
  glrotatef ang1*.1, 0,0,1
  glrotatef ang1*.2, 0,1,0
  glrotatef ang1*.1, 1,0,0
  glUniform4fv slTint, 1, tint2
  a=.8
  glScalef a,a,a
 'go cylinder
 'go vessel
 'go cube
 'go tors
 'go helix
 'DrawVertexArrays()
  Sierpinski3d(cylinder,sphere)
  glPopMatrix
  '
  '
  glUseProgram -1
  end if 'shn

  '
  'UPDATE ROTATION ANGLES
  '----------------------
  ang1+=.4
  'if ang1>360 then ang1-=360
  sleep 10
  '
  end sub
  MainWindow width,height,WS_OVERLAPPEDWINDOW
