4

有谁知道如何在 GLKit 中使用自定义着色器?不使用 GLBaseEffect。

此致,

4

2 回答 2

3

据我所知,您可以像在非 GLKit OpenGL ES 2.0 应用程序中一样设置和使用着色器程序。我目前更喜欢使用 Jeff LaMarche 的 GLProgram 包装类,他在本教程中提供了该类(代码应该链接在该页面的顶部),而不是每次都重写所有样板代码来编译和链接着色器。

我在这个答案中展示了一些标准用法。你仍然需要设置你的属性和制服,但是一旦你这样做了,你只需使用程序并在你的 GLKView 中绘制你的几何图形。

GLKit 基本效果似乎以类似的方式作为包装器提供给某些标准着色器程序。

于 2012-05-09T15:36:40.873 回答
1

不是我的代码,但我发现这很有帮助。它甚至打印出着色器的错误。

func compileShader(shaderName: String?, shaderType: GLenum) -> GLuint {

    let shaderPath = NSBundle.mainBundle().pathForResource(shaderName!, ofType: "glsl")
    var error: NSError? = nil
    var shaderString: NSString?
    do {
        shaderString = try NSString(contentsOfFile: shaderPath!, encoding: NSUTF8StringEncoding)
    } catch let error1 as NSError {
        error = error1
        shaderString = nil
    }
    var shaderS = shaderString! as String
    shaderS += "\n"
    shaderString = shaderS as NSString

    if shaderString == nil {
        print("Failed to set contents shader of shader file!")
    }

    let shaderHandle: GLuint = glCreateShader(shaderType)

    //var shaderStringUTF8 = shaderString!.utf8
    var shaderStringUTF8 = shaderString!.UTF8String
    //var shaderStringLength: GLint = GLint() // LOL
    var shaderStringLength: GLint = GLint(shaderString!.length)
    glShaderSource(shaderHandle, 1, &shaderStringUTF8, &shaderStringLength)
    //the 2 is number of uniforms
    glCompileShader(shaderHandle)

    var compileSuccess: GLint = GLint()

    glGetShaderiv(shaderHandle, GLenum(GL_COMPILE_STATUS), &compileSuccess)

    if compileSuccess == GL_FALSE {
        print("Failed to compile shader \(shaderName!)!")
        var value: GLint = 0
        glGetShaderiv(shaderHandle, GLenum(GL_INFO_LOG_LENGTH), &value)
        var infoLog: [GLchar] = [GLchar](count: Int(value), repeatedValue: 0)
        var infoLogLength: GLsizei = 0
        glGetShaderInfoLog(shaderHandle, value, &infoLogLength, &infoLog)
        let s = NSString(bytes: infoLog, length: Int(infoLogLength), encoding: NSASCIIStringEncoding)
        print(s)

        exit(1)
    }


    return shaderHandle

}

// function compiles vertex and fragment shaders into program. Returns program handle
func compileShaders() -> GLuint {

    let vertexShader: GLuint = self.compileShader("SimpleVertex", shaderType: GLenum(GL_VERTEX_SHADER))
    let fragmentShader: GLuint = self.compileShader("SimpleFragment", shaderType: GLenum(GL_FRAGMENT_SHADER))

    let programHandle: GLuint = glCreateProgram()
    glAttachShader(programHandle, vertexShader)
    glAttachShader(programHandle, fragmentShader)
    glLinkProgram(programHandle)

    var linkSuccess: GLint = GLint()
    glGetProgramiv(programHandle, GLenum(GL_LINK_STATUS), &linkSuccess)
    if linkSuccess == GL_FALSE {
        print("Failed to create shader program!")

        var value: GLint = 0
        glGetProgramiv(programHandle, GLenum(GL_INFO_LOG_LENGTH), &value)
        var infoLog: [GLchar] = [GLchar](count: Int(value), repeatedValue: 0)
        var infoLogLength: GLsizei = 0
        glGetProgramInfoLog(programHandle, value, &infoLogLength, &infoLog)
        let s = NSString(bytes: infoLog, length: Int(infoLogLength), encoding: NSASCIIStringEncoding)
        print(s)

        exit(1)
    }

    glUseProgram(programHandle)

    self.positionSlot = GLuint(glGetAttribLocation(programHandle, "aVertexPosition"))
    //self.colorSlot =    GLuint(glGetAttribLocation(programHandle, "SourceColor"))
    self.normalSlot =   GLuint(glGetAttribLocation(programHandle, "aVertexNormal"))
    glEnableVertexAttribArray(self.positionSlot)
   // glEnableVertexAttribArray(self.colorSlot)
    glEnableVertexAttribArray(self.normalSlot)

    return programHandle
}
于 2016-03-08T03:52:25.353 回答