  function PixelColor(float fr,fg,fb,fa=1.0) as dword
  ====================================================
  dword ir=fr*0xff, ig=fg*0xff, ib=fb*0xff, ia=fa*0xff
  return ir+(ig<<8)+(ib<<16)+(ia<<24)
  end function


  function CreateTexture2D(int width, height, sys pImg, int *texture)
  ==================================================================
  glGenTextures(1, Texture)
  glBindTexture(GL_TEXTURE_2D, Texture);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4)
  glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE)
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pImg)
  glBindTexture(GL_TEXTURE_2D, 0)
  end function


  function CreateTextureCubic(int width, height, sys pImg, int *texture)
  ======================================================================
  glGenTextures(1, Texture)
  glBindTexture(GL_TEXTURE_CUBE_MAP, Texture)
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4)
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE)
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_SEAMLESS, GL_TRUE)
  sys i
  '% GL_TEXTURE_CUBE_MAP_POSITIVE_X    0x8515
  '% GL_TEXTURE_CUBE_MAP_NEGATIVE_X    0x8516
  '% GL_TEXTURE_CUBE_MAP_POSITIVE_Y    0x8517
  '% GL_TEXTURE_CUBE_MAP_NEGATIVE_Y    0x8518
  '% GL_TEXTURE_CUBE_MAP_POSITIVE_Z    0x8519
  '% GL_TEXTURE_CUBE_MAP_NEGATIVE_Z    0x851A
  for i=1 to 6
    glTexImage2D(GL_TEXTURE_BINDING_CUBE_MAP + i, 0, GL_RGBA8, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pImg )
  next
  glBindTexture(GL_TEXTURE_CUBE_MAP, 0)
  end function




  sub LoadCubicTextures(string left,right,bottom,top,front,back, int *Texture)
  ============================================================================
  sys i,wi,ht,p
  string tx[6]
  '1 for no-flip
  LoadPixImage left,   0,tx[2], wi,ht,0 'left
  LoadPixImage right,  0,tx[1], wi,ht,0 'right
  LoadPixImage bottom, 0,tx[4], wi,ht,0 'bottom
  LoadPixImage top,    0,tx[3], wi,ht,0 'top
  LoadPixImage front,  0,tx[5], wi,ht,0 'front
  LoadPixImage back,   0,tx[6], wi,ht,0 'back
'tx[1]=nuls 256*256*4
  '
  'right   pos x
  'left    neg x
  'top     pos y
  'bottom  neg y
  'front   pos z
  'back    neg z
  '
  glGenTextures(1, Texture)
  glBindTexture(GL_TEXTURE_CUBE_MAP, Texture)
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4)
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE)
  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_SEAMLESS, GL_TRUE)
  '
  for i=1 to 6
    p = strptr tx[i]
    glTexImage2D(GL_TEXTURE_BINDING_CUBE_MAP + i, 0, GL_RGBA8, wi, ht, 0, GL_RGBA, GL_UNSIGNED_BYTE, p )
  next
  glBindTexture(GL_TEXTURE_CUBE_MAP, 0)
  end sub



  int    SkyBoxVBO[2]
  '
  sub BuildSkyBox()
  =================
  indexbase 1
  '24 vertics == 72 floats == 288 bytes
  float l=1.0, o=0.0, m=-1.0
  float Vertices[72] = {
    'x,y,z, ...
     '=====  ======  ======  ======  =====
     l,m,m,  l,m,l,  l,l,l,  l,l,m, ' +X
     m,m,l,  m,m,m,  m,l,m,  m,l,l, ' -X
     m,l,m,  l,l,m,  l,l,l,  m,l,l, ' +Y
     m,m,l,  l,m,l,  l,m,m,  m,m,m, ' -Y
     m,m,l,  l,m,l,  l,l,l,  m,l,l, ' +Z
     m,m,m,  l,m,m,  l,l,m,  m,l,m  ' -Z
  }
  '  l,m,m,  m,m,m,  m,l,l,  l,l,m  ' -Z

  '
  glGenBuffers(1, SkyBoxVBO)
  glBindBuffer(GL_ARRAY_BUFFER, SkyBoxVBO[1])
  glBufferData(GL_ARRAY_BUFFER, 288, @Vertices, GL_STATIC_DRAW)
  'glBindBuffer(GL_ARRAY_BUFFER, SkyBoxVBO[2])
  'glBufferData(GL_ARRAY_BUFFER, 288, @Normals, GL_STATIC_DRAW)
  glBindBuffer(GL_ARRAY_BUFFER, 0)
  end sub

  sub DrawSkyBox(int SkyTexture, SkyShader)
  =========================================
  '
  glDisable(GL_DEPTH_TEST)
  glDisable(GL_CULL_FACE)
  glBindTexture(GL_TEXTURE_CUBE_MAP, SkyTexture)
  '
  glUseProgram SkyShader
  '
  glBindBuffer(GL_ARRAY_BUFFER, SkyBoxVBO)
  glEnableClientState(GL_VERTEX_ARRAY)
  glVertexPointer(3, GL_FLOAT, 0, null)
  glDrawArrays(GL_QUADS, 0, 24)
  glDisableClientState(GL_VERTEX_ARRAY)
  glBindBuffer(GL_ARRAY_BUFFER, 0)
  'glUseProgram -1
  glEnable(GL_DEPTH_TEST)
  'glBindTexture(GL_TEXTURE_CUBE_MAP, 0)
  end sub

