title: how to compile shader in swift, location always return -1
body: <p>
  I have written a piece of code to compile a shader.</p>
  
  
  
  <pre><code>class DFShader {
      let ID: GLuint
  
      init(vPath: String, fPath: String) {
          ID = glCreateProgram()
          let vertex = compile(type: GLenum(GL_VERTEX_SHADER), path: vPath)
          let fragment = compile(type: GLenum(GL_FRAGMENT_SHADER), path: fPath)
  
          var success: GLint = 1
          glAttachShader(ID, vertex)
          glAttachShader(ID, fragment)
          glLinkProgram(ID)
          glGetProgramiv(ID, GLenum(GL_LINK_STATUS), &amp;success)
          if success == GL_FALSE {
              let infoLog = UnsafeMutablePointer&lt;GLchar&gt;.allocate(capacity: 512)
              glGetProgramInfoLog(ID, 512, nil, infoLog)
              print("link program error. \(String.init(cString: infoLog))")
          }
          glDeleteShader(vertex)
          glDeleteShader(fragment)
  
          //log
          print("model", glGetUniformLocation(ID, "model")) // print 4
          print("projection", glGetUniformLocation(ID, "projection")) // print 0
          print(ID.description)
      }
  
      private func compile(type: GLenum, path: String) -&gt; GLuint {
          let shader = glCreateShader(type)
          var success: GLint = 1
          do {
              let source = try String.init(contentsOfFile: path, encoding: String.Encoding.utf8).cString(using: String.Encoding.utf8)
              var castSource = UnsafePointer&lt;GLchar&gt;(source)
              glShaderSource(shader, 1, &amp;castSource, nil)
              glCompileShader(shader)
              glGetShaderiv(shader, GLenum(GL_COMPILE_STATUS), &amp;success)
              if success == GL_FALSE {
                  let infoLog = UnsafeMutablePointer&lt;GLchar&gt;.allocate(capacity: 512)
                  glGetShaderInfoLog(shader, 512, nil, &amp;infoLog.pointee)
                  print("compile error. \(String.init(cString: infoLog))")
              }
          } catch {
              print("failed to read from shader source file.")
          }
          return shader
      }
  
      func use() {
          glUseProgram(ID)
      }
  }
  
  //vertex shader code
  #version 300 es
  layout(location = 0) in vec2 position;
  out vec4 VertexColor;
  uniform mat4 model;
  uniform mat4 projection;
  uniform float pointSize;
  uniform vec4 color;
  void main() {
      VertexColor = color;
      gl_Position = projection * model * vec4(position, 0.0, 1.0);
  gl_PointSize = 10.0f;
  }
  
  //fragment shader code
  #version 300 es
  precision mediump float;
  out vec4 FragColor;
  in vec4 VertexColor;
  void main() {
      FragColor = VertexColor;
  }
  
  //In the view
  ...
  func setupShaders() {
      shader.use()
      let projection = GLKMatrix4MakeOrtho(0, Float(width), 0, Float(height), -1, 1)
      shader.setMat4(name: "projection", value: projection)
      print("projection", glGetUniformLocation(shader.ID, "projection")) // print -1.
  
  ...
  }
  </code></pre>
  
  
  
  <p>I want to get the right location of all uniform and attribute value.</p>
  
  
  
  <p>But the uniform location I get from DFShader instance is -1. And I only get the right location in </p>
  
  <pre><code>init(vPath: String, fPath: String)
  </code></pre>
  
  <p>, which print 0 and 4 in the code above.
  However, when I get location in</p>
  
  <pre><code>setupShaders()
  </code></pre>
  
  <p>it return -1. I get location with shader.ID at any other place, I am also given -1.</p>