
  includepath "$\inc\"
  $ title     "gl Transforms"
  % ExplicitMain
  include     "OpenglSceneFrame.inc"
  include     "glo2\ShaderSupport.inc"
  includepath ""


  macro TranslucentMaterial(ma,alpha)
  ===================================
  static float ma={
  0.7, 0.70, 0.70, alpha, 'diffuse
  .15, 0.15, 0.15, alpha, 'ambient
  0.1, 0.10, 0.10, alpha, 'specular  
  0.                      'shininess
  }
  Material ma
  end macro


  macro PrepareSceneFrame
  =======================
  static float ang1,angi1=1
  '
  ActiveFrame
  %% BackGroundColor 0.5, 0.5, 0.7, 0.0
  glClearColor BackGroundColor 
 'Fog          0.5, 0.5, 0.7, 0.1 'rgb and density
  ang1+=angi1
  if ang1>360 then ang1-=360
  if ShaderError then exit sub
  '
  end macro

  float v[0x400]

  indexbase 0

  sys         vbo, mat, mathole,vbohole,ele
  sys         v_vertex, v_normal, v_texcor, v_color, v_matrix
  shaderProg  ShaderMaj
  shaderProg  ShaderMin

  sub MakeShaders
  ===============
  '
  '
  ShaderMin.vsrc=
  "
  #version 330 compatibility
  out vec3 normal;
  out vec2 texcoord;
  void main()
  {
    normal = normalize(gl_NormalMatrix * gl_Normal);
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    //gl_TexCoord[0] = gl_MultiTexCoord0;
    texcoord = gl_MultiTexCoord0.st;
  }
  "
  /*
  glUniform1i(glGetUniformLocation(ShaderM, "texUnit0"), 0);
  glActiveTexture(GL_TEXTURE0);
  texture imgn
  */
  /*
  'Pass multiple texture coordinates to my shader 
  'https://www.opengl.org/discussion_boards/showthread.php/176738-Pass-multiple-texture-coordinates-to-my-shader
  glMultiTexCoord2f( GL_TEXTURE0, s1, t1);
  glMultiTexCoord2f( GL_TEXTURE1, s2, t2);
  */
  '
  ShaderMin.fsrc=
  "
  #version 330 compatibility

  uniform sampler2D texUnit0;
  in      vec3  normal;
  in      vec2  texcoord;
  out     vec4 color;

  void main ()
  
{
     //color = vec4(0.75, 0.5, 0.0, 1.0);
     color = texture2D(texUnit0, texcoord)*vec4(1.0, 1.0, 1.0, 0.6);
  
}


  "
  '
  'VERTEX SHADER
  '
  ShaderMaj.vsrc="
  #version 330
  uniform mat4 modelView;
  uniform mat4 projection;
  layout (location = 0) in   vec3 v_vertex;
  layout (location = 1) in   vec3 v_normal;
  layout (location = 2) in   vec2 v_texcor;
  layout (location = 5) in   mat4 v_matrix;

  out vData
  {
    vec4 position;
    vec3 normal;
    vec2 texcor;
  } vertex;

  void main(void) {
    mat4 m=modelView * v_matrix;
    vertex.position = projection * m * vec4(v_vertex, 1.0);
    vertex.normal   = normalize ( transpose ( inverse ( mat3 ( m ) ) ) * v_normal );
    vertex.texcor    = v_texcor;
  }
  "
  '
  'GEOMETRY SHADER
  '
  'http://www.informit.com/articles/article.aspx?p=2120983&seqNum=2
  'https://www.opengl.org/wiki/Geometry_Shader_Examples
  '
  ShaderMaj.gsrc="
  #version 330
  #extension GL_ARB_geometry_shader4 : enable
  uniform sampler2D texUnit0;
  layout(triangles) in;
  layout(triangle_strip, max_vertices=6) out;
  int  i;
  in vData
  {
    vec4 position;
    vec3 normal;
    vec2 texcor;
  } vertex[];
  
  out fData
  {
    vec4 position;
    vec3 normal;
    vec2 texcor;
  } frag;
  
  
  void main()
  {
   for(i = 0; i < gl_VerticesIn; i++ )
   {
     frag.texcor = vertex[i].texcor;
     frag.position = vertex[i].position;
     //+texture2D(texUnit0, frag.texcor);
     frag.normal = vertex[i].normal;
     gl_Position = frag.position;
     EmitVertex();
   }
   EndPrimitive();

   ////New piece of geometry!
   //vec4 v;
   //for(i = 0; i < gl_VerticesIn; i++)
   //{
   //  v = vertex[i].position;
   //  //displace along the normal
   //  v = v + 0.5 * vec4(vertex[i].normal,0.0);
   //  gl_Position = v;
   //  frag.normal = vertex[i].normal;
   //  frag.texcor = vertex[i].texcor;
   //  EmitVertex();
   //}
   //EndPrimitive();
  }
  "
  'ShaderMaj.gsrc="" 'no extra geometry!
  '
  'FRAGMENT SHADER
  '
  ShaderMaj.fsrc="
  #version 330
  uniform sampler2D texUnit0;
  uniform vec4      tint0;
  uniform vec4[4]   light0;
  uniform vec4      direction0 ;
  in fData
  {
    vec4 position;
    vec3 normal;
    vec2 texcor;
  } frag;

  layout(location = 0) out vec4 color;

  void main(void) {
    float di = max(0.0, dot(normalize(frag.normal), vec3(direction0) ) );
    float si = clamp(pow(di,0.3*light0[3].r), 0.0, 1.0); //specular with shiny term
    vec4 light=light0[0]+light0[1]*di+light0[2]*si; //ambient diffuse specular
    color = texture2D(texUnit0, frag.texcor)*light*tint0;
    if (color.a > tint0.a) {color.a = tint0.a;}
  }
  "
  'COMPILE AND LINK
  '
  CreateShaderProg ShaderMin : if ShaderError then exit sub
  ShaderMin.t0  = glGetUniformLocation(ShaderMin.ph, "texUnit0"    )

  CreateShaderProg ShaderMaj : if ShaderError then exit sub
  ShaderMaj.m0  = glGetUniformLocation(ShaderMaj.ph, "projection"  )
  ShaderMaj.m1  = glGetUniformLocation(ShaderMaj.ph, "modelView"   )
 'ShaderMaj.n0  = glGetUniformLocation(ShaderMaj.ph, "normalMatrix")
  ShaderMaj.t0  = glGetUniformLocation(ShaderMaj.ph, "texUnit0"    )
 'ShaderMaj.t1  = glGetUniformLocation(ShaderMaj.ph, "texUnit1"    )
 'ShaderMaj.t2  = glGetUniformLocation(ShaderMaj.ph, "texUnit2"    )
 'ShaderMaj.t3  = glGetUniformLocation(ShaderMaj.ph, "texUnit3"    )
  ShaderMaj.v0  = glGetUniformLocation(ShaderMaj.ph, "tint0"       )
  ShaderMaj.v1  = glGetUniformLocation(ShaderMaj.ph, "light0"      )
  ShaderMaj.v2  = glGetUniformLocation(ShaderMaj.ph, "direction0"  )
  '
  'UNIFORM DATA
  'glUniformMatrix4fv(ShaderMaj.m0, 1, GL_FALSE, Projection   )
  'glUniformMatrix4fv(ShaderMaj.m1, 1, GL_FALSE, MatStack     )
  'glUniformMatrix3fv(ShaderMaj.n0, 1, GL_FALSE, NormalMatrix )
  '
  end sub


  sub MakeVBOColTri
  =================
  '
  if shaderError then exit sub
  '
  static float m={
  1,0,0,0,
  0,1,0,0,
  0,0,1,0,
  0,0,0,1,
  ----------
  .5,0,0,0,
  0,.5,0,0,
  0,0,.5,0,
  0,0,-.5,1,
  ----------
  .25,0,0,0,
  0,.25,0,0,
  0,0,.25,0,
  0,0,-1,1
  }
  '
  static float t={
   'vertex   normal  texcor color
   '-------------------------------
    0, 1,0,  0,0,1,  .0,1,  1,0,0,1,
   -1,-1,0,  0,0,1, -.5,0,  0,1,0,1,
    1,-1,0,  0,0,1,  .5,0,  0,0,1,1
   '-------------------------------
  }
  static int e={
  0,1,2
  }
  glGenBuffers  1, ele
  glBindBuffer GL_ELEMENT_ARRAY_BUFFER, ele
  glBufferData GL_ELEMENT_ARRAY_BUFFER, bytesof e, @e, GL_STATIC_DRAW
  '
  '
  'ATTRIBUTE LOCATION NAMES
  v_vertex = 0
  v_normal = 1
  v_texcor = 2
  v_color  = 3
  v_matrix = 4
  '
  sys i
  for i= 0 to 7 : glEnableVertexAttribArray i : next
  '
  glGenBuffers  1, mat
  glBindBuffer GL_ARRAY_BUFFER, mat
  glBufferData GL_ARRAY_BUFFER, bytesof m, @m, GL_STATIC_DRAW
  '
  glGenBuffers  1, vbo
  glBindBuffer GL_ARRAY_BUFFER, vbo
  glBufferData GL_ARRAY_BUFFER, bytesof t, @t, GL_STATIC_DRAW
  '
  % vap   =  glVertexAttribPointer
  % f     =  GL_FLOAT
  % n     =% 12*sizeof float 'stride
  '
  'call attribute    n  type nrm stride offset
  '-------------------------------------------
  vap   v_vertex   , 3, f,   0,  48,    00 '0
  vap   v_normal   , 3, f,   0,  48,    12 '3
  vap   v_texcor   , 2, f,   0,  48,    24 '6
  vap   v_color    , 4, f,   0,  48,    32 '8
  '-------------------------------------------

  glBindBuffer GL_ARRAY_BUFFER, mat
  '
  'call attribute    n  type nrm stride offset
  '-------------------------------------------
  vap   v_matrix+0 , 4, f,   0,  64,    00 '0
  vap   v_matrix+1 , 4, f,   0,  64,    16 '4
  vap   v_matrix+2 , 4, f,   0,  64,    32 '8
  vap   v_matrix+3 , 4, f,   0,  64,    48 '12
  '-------------------------------------------
  '
  glVertexAttribDivisor(v_matrix+0, 1)
  glVertexAttribDivisor(v_matrix+1, 1)
  glVertexAttribDivisor(v_matrix+2, 1)
  glVertexAttribDivisor(v_matrix+3, 1)
  '
  glBindBuffer GL_ARRAY_BUFFER, 0
  end sub


  sub ColorTriangle
  =================
  glBegin GL_TRIANGLES
  glNormal3fv v[9]
  glColor4f   1.0, 0.0, 0.0, 0.99 : glTexCoord2f 0.0,0.0 : glVertex3fv v[0] ' 0.0,  1.0, 0.0
  glColor4f   0.0, 1.0, 0.0, 0.99 : glTexCoord2f 0.5,1.0 : glVertex3fv v[3] '-1.0, -1.0, 0.0
  glColor4f   0.0, 0.0, 1.0, 0.99 : glTexCoord2f 1.0,0.0 : glVertex3fv v[6] ' 1.0, -1.0, 0.0
  glEnd
  end sub

  sub ColorQuad
  =============
  glBegin GL_QUADS
  glNormal3fv v[24]
  glColor4f   1.0, 0.0, 0.0, 0.99 : glTexCoord2f 0.0,0.0 : glVertex3fv v[12] '-1.0, -1.0, 0.0
  glColor4f   0.0, 1.0, 0.0, 0.99 : glTexCoord2f 1.0,0.0 : glVertex3fv v[15] ' 1.0, -1.0, 0.0
  glColor4f   0.0, 0.0, 1.0, 0.99 : glTexCoord2f 1.0,1.0 : glVertex3fv v[18] ' 1.0,  1.0, 0.0
  glColor4f   0.5, 0.5, 0.5, 0.99 : glTexCoord2f 0.0,1.0 : glVertex3fv v[21] '-1.0,  1.0, 0.0
  glEnd
  end sub

  sub MakeVBOHole
  ===============
  '
  if shaderError then exit sub
  '
  float h=0.5, q=0.25, q0=.25, q1=.75
  '
  float m={
  1,0,0,0,
  0,1,0,0,
  0,0,1,0,
  0,0,0,1,
  ----------
  h,0,0,0,
  0,h,0,0,
  0,0,h,0,
  0,0,-h,1,
  ----------
  q,0,0,0,
  0,q,0,0,
  0,0,q,0,
  0,0,-1,1
  }
  '
  '
  float t={
   'vertex   normal  texcor
   '-----------------------
   -1,-1,0,  0,0,1,   0, 0,
    1,-1,0,  0,0,1,   1, 0,
    1, 1,0,  0,0,1,   1, 1,
   -1, 1,0,  0,0,1,   0, 1,
   -h,-h,0,  0,0,1,  q0,q0,
    h,-h,0,  0,0,1,  q1,q0,
    h, h,0,  0,0,1,  q1,q1,
   -h, h,0,  0,0,1,  q0,q1
   '-------------------------------
  }
  'quad strip
  int e={
  4,0, 5,1, 6,2, 7,3, 4,0
  }
  glGenBuffers  1, ele
  glBindBuffer GL_ELEMENT_ARRAY_BUFFER, ele
  glBufferData GL_ELEMENT_ARRAY_BUFFER, bytesof e, @e, GL_STATIC_DRAW
  '
  '
  'ATTRIBUTE LOCATION NAMES
  v_vertex = 0
  v_normal = 1
  v_texcor = 2
  v_matrix = 3
  '
  sys i
  for i= 0 to 7 : glEnableVertexAttribArray i : next
  '
  glGenBuffers  1, matHole
  glBindBuffer GL_ARRAY_BUFFER, matHole
  glBufferData GL_ARRAY_BUFFER, bytesof m, @m, GL_STATIC_DRAW
  '
  glGenBuffers  1, vboHole
  glBindBuffer GL_ARRAY_BUFFER, vboHole
  glBufferData GL_ARRAY_BUFFER, bytesof t, @t, GL_STATIC_DRAW
  '
  % vap   =  glVertexAttribPointer
  % f     =  GL_FLOAT
  % n     =% 8*sizeof float 'stride
  '
  'call attribute    n  type nrm stride offset
  '-------------------------------------------
  vap   v_vertex   , 3, f,   0,  32,    00 '0
  vap   v_normal   , 3, f,   0,  32,    12 '3
  vap   v_texcor   , 2, f,   0,  32,    24 '6
  '-------------------------------------------

  glBindBuffer GL_ARRAY_BUFFER, mat
  '
  'call attribute    n  type nrm stride offset
  '-------------------------------------------
  vap   v_matrix+0 , 4, f,   0,  64,    00 '0
  vap   v_matrix+1 , 4, f,   0,  64,    16 '4
  vap   v_matrix+2 , 4, f,   0,  64,    32 '8
  vap   v_matrix+3 , 4, f,   0,  64,    48 '12
  '-------------------------------------------
  '
  glVertexAttribDivisor(v_matrix+0, 1)
  glVertexAttribDivisor(v_matrix+1, 1)
  glVertexAttribDivisor(v_matrix+2, 1)
  glVertexAttribDivisor(v_matrix+3, 1)
  '
  glBindBuffer GL_ARRAY_BUFFER, 0
  end sub






  sub initialize(sys hWnd)
  '=======================
  SetupExtFunctions
  GDIplus 1
  GenTextures 32
  v[0]={0,1,0,   -1,-1,0,  1,-1,0,   0,0,1}         'Triangle
  v[12]={-1,-1,0,  1,-1,0,  1,1,0,  -1,1,0,  0,0,1} 'Quad
  CopyVec v[100],v[0],9
  MakeShaders
  MakeVBOColTri
  'MakeVBOhole
  end sub

  sub Release(sys hwnd)
  '====================
  'print ShowMat MatStack
  
  def disable glDisableVertexAttribArray
  '
  disable v_vertex
  disable v_normal
  disable v_texcor
  disable v_color
  '
  DeleteTextures 32
  GDIplus 0
  '
  ReleaseShaderProg ShaderMin
  ReleaseShaderProg ShaderMaj
  glDeleteBuffers  1, vbo 
  glDeleteBuffers  1, mat
  glDeleteBuffers  1, ele
  end sub


