
  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
  glClearColor 0.5, 0.5, 0.7, 0.0
  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, ele
  sys    v_vertex, v_normal, v_texcor, v_color, v_matrix
  sys    ulProjection, ulModelView, ulTexture0
  shaderProg  Shader
  shaderProg  ShaderMin
  sys         ShaderM,ShaderP

  sub MakeShader
  ==============
  '
  '
  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, "texunit"), 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 texunit;
  in      vec3  normal;
  in      vec2  texcoord;
  out     vec4 color;

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


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

  out vData
  {
    vec4 position;
    vec3 normal;
    vec4 color;
  }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.color    = v_color;
  }
  "
  '
  'GEOMETRY SHADER
  '
  Shader.gsrc="
  #version 330
  #extension GL_ARB_geometry_shader4 : enable
  layout(triangles) in;
  layout(triangle_strip, max_vertices=16) out;
  int  i;
  in vData
  {
    vec4 position;
    vec3 normal;
    vec4 color;
  }vertex[];
  
  out fData
  {
    vec4 position;
    vec3 normal;
    vec4 color;
  }frag;
  
  
  void main()
  {
   for(i = 0; i < gl_VerticesIn; i++ )
   {
     gl_Position = vertex[i].position;
     frag.normal = vertex[i].normal;
     frag.color = vertex[i].color;
     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.color = 0.125 * vertex[i].color;
//     EmitVertex();
//   }
//   EndPrimitive();
  }
  "
  '
  'FRAGMENT SHADER
  '
  Shader.fsrc="
  #version 330
  in fData
  {
    vec4 position;
    vec3 normal;
    vec4 color;
  }frag;

  layout(location = 0) out vec4 color;

  void main(void) {
    // color = frag.color;
    float di = max(0.0, dot(normalize(frag.normal), vec3(0.0,0.0,1.0) ) );
    di=0.85*di+0.15; //diffuse with ambient
    //color = vec4(di,di,di,frag.color.a);
    color = vec4(frag.color.r*di, frag.color.g*di,  frag.color.b*di, frag.color.a);
  }
  "
  'COMPILE AND LINK
  '
  ShaderM = CreateShaderProg ShaderMin
  if ShaderError then exit sub
  ShaderP = CreateShaderProg Shader
  if ShaderError then exit sub
  ulProjection = glGetUniformLocation(ShaderP, "projection")
  ulModelView  = glGetUniformLocation(ShaderP, "modelView" )
  ulTexture0   = glGetUniformLocation(ShaderM, "texunit" )
  '
  '
  end sub

  sub MakeVBO
  ===========
  '
  if shaderError then exit sub
  '
  static float m={
  1,0,0,0,
  0,1,0,0,
  0,0,1,0,
  0,0,-1,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,-0,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
  }
  '
  '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, vbo
  glBindBuffer GL_ARRAY_BUFFER, vbo
  glBufferData GL_ARRAY_BUFFER, bytesof t, @t, GL_STATIC_DRAW
  '
  glGenBuffers  1, mat
  glBindBuffer GL_ARRAY_BUFFER, mat
  glBufferData GL_ARRAY_BUFFER, bytesof m, @m, GL_STATIC_DRAW
  '
  glGenBuffers  1, ele
  glBindBuffer GL_ELEMENT_ARRAY_BUFFER, ele
  glBufferData GL_ELEMENT_ARRAY_BUFFER, bytesof e, @e, GL_STATIC_DRAW
  '
  % vap   =  glVertexAttribPointer
  % f     =  GL_FLOAT
  % n     =% 12*sizeof float 'stride
  '
  glBindBuffer GL_ARRAY_BUFFER, vbo
  '
  '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
  glNormal3f  0,0,1
  glColor4f   1.0, 0.0, 0.0, 0.99 : glVertex3fv v[0] ' 0.0,  1.0, 0.0
  glColor4f   0.0, 1.0, 0.0, 0.99 : glVertex3fv v[3] '-1.0, -1.0, 0.0
  glColor4f   0.0, 0.0, 1.0, 0.99 : glVertex3fv v[6] ' 1.0, -1.0, 0.0
  glEnd
  end sub

  sub ColorQuad
  =============
  glBegin GL_QUADS
  glNormal3f  0,0,1
  glColor4f   1.0, 0.0, 0.0, 0.99 : glVertex3fv v[09] '-1.0, -1.0, 0.0
  glColor4f   0.0, 1.0, 0.0, 0.99 : glVertex3fv v[12] ' 1.0, -1.0, 0.0
  glColor4f   0.0, 0.0, 1.0, 0.99 : glVertex3fv v[15] ' 1.0,  1.0, 0.0
  glColor4f   0.5, 0.5, 0.5, 0.99 : glVertex3fv v[18] '-1.0,  1.0, 0.0
  glEnd
  end sub

  sub initialize(sys hWnd)
  '=======================
  SetupExtFunctions
  GDIplus 1
  v[0]={0,1,0,   -1,-1,0,  1,-1,0}         'Triangle
  v[9]={-1,-1,0,  1,-1,0,  1,1,0,  -1,1,0} 'Quad
  CopyVec v[100],v[0],7
  MakeShader
  MakeVBO
  GenTextures 32
  end sub

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