2017-12-08 12 views
-1

쉐이더 컴파일을위한 코드를 작성했습니다. 신속하게 쉐이더를 컴파일하는 방법, 위치는 항상 -1을 반환합니다.

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), &success) 
     if success == GL_FALSE { 
      let infoLog = UnsafeMutablePointer<GLchar>.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) -> 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<GLchar>(source) 
      glShaderSource(shader, 1, &castSource, nil) 
      glCompileShader(shader) 
      glGetShaderiv(shader, GLenum(GL_COMPILE_STATUS), &success) 
      if success == GL_FALSE { 
       let infoLog = UnsafeMutablePointer<GLchar>.allocate(capacity: 512) 
       glGetShaderInfoLog(shader, 512, nil, &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. 

... 
} 

나는 모든 유니폼의 오른쪽 위치를 얻기 위해 원하는 속성 값을.

그러나 DFShader 인스턴스에서 얻는 균일 한 위치는 -1입니다. 그리고 나는 단지 위의 코드에서 0과 4를 인쇄

init(vPath: String, fPath: String) 

에서 올바른 위치를 얻을. 그러나 내가 위치를 얻을 때

setupShaders() 

-1을 반환합니다. 나는 셰이더로 위치를 얻는다. 다른 어느 곳에서나, 나는 또한 -1을 받는다.

+0

균일 변수의 위치를 ​​얻으려면 프로그램을 링크해야합니다. 이것은'glGetUniformLocation'이'glLinkProgram' 다음에 호출되어야한다는 것을 의미합니다. – Rabbid76

답변

1

셰이더 개체의 위치가 동일하지 않습니다. 프로그램에만 개체가 있습니다.

shader object은 텍스트 쉐이더와 최종 프로그램 간의 매개체에 지나지 않습니다. 그들은 실제로 을 수행하지 않습니다. 많이. 쿼리 할 상태가 없습니다.

+0

감사합니다. 실수를했습니다. 그러나 프로그램을 링크 한 후에도 일정한 위치를 얻을 수 없습니다. 질문이 위에서 수정되었습니다. –