如何在swift中编译着色器,位置总是返回-1

时间:2017-12-08 17:22:21

标签: swift opengl-es-3.0

我编写了一段代码来编译着色器。

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。我只能在

中找到合适的位置
init(vPath: String, fPath: String)

,在上面的代码中打印0和4。 但是,当我到达

setupShaders()

它返回-1。我在任何其他地方使用shader.ID获取位置,我也被给予-1。

1 个答案:

答案 0 :(得分:1)

着色器对象没有统一的位置。只有程序对象可以。

shader object只不过是文本着色器和最终程序之间的中介。他们实际上并没有。他们没有要查询的状态。