How can I pass a mat4 type shape to a custom shader (SCNProgram) in Swift?

I am trying to install a single mat4 that I want to use in a custom shader program in SceneKit on iOS (Xcode 6 beta 6). And I am trying to do this in Swift.

    let myMatrix: Array<GLfloat> = [1, 0, 0 , 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1]

    var material = SCNMaterial()
    var program = SCNProgram()

    // setup of vertex/fragment shader goes here
    program.vertexShader = ...
    program.fragmentShader = ...

    material.program = program

    // I want to initialize the variable declared as "uniform mat4 u_matrix" in the vertex shader with "myMatrix"
    material.handleBindingOfSymbol("u_matrix"){
        programID, location, renderedNode, renderer in

        let numberOfMatrices = 1
        let needToBeTransposed = false
        glUniformMatrix4fv(GLint(location), GLsizei(numberOfMatrices), GLboolean(needToBeTransposed), myMatrix)
    }

      

Using this code, I have the following compilation error: Cannot invoke 'init' with an argument list of type (GLint, GLsizei, GLboolean, Array<GLfloat>)

. However, from this documentation here ( https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html , Constants Pointers section), I understand that we can pass an array to a function which takes an UnsafePointer argument.

Then I tried to pass UnsafePointer directly by doing the following:

        let testPtr: UnsafePointer<GLfloat> = nil
        glUniformMatrix4fv(GLint(location), GLsizei(numberOfMatrices), GLboolean(needToBeTransposed), testPtr)

      

And I got the error Cannot invoke 'init' with an argument list of type '(GLint, GLsizei, GLboolean, UnsafePointer<GLfloat>)'

However, the glUniformMatrix4fv prototype is exactly like this: func glUniformMatrix4fv(location: GLint, count: GLsizei, transpose: GLboolean, value: UnsafePointer<GLfloat>)

Any idea what I am doing wrong? How are we supposed to skip mat4 as a uniform if we are using a custom shader?

Note1: I first tried to use SCNMatrix4 for myMatrix, but got the error "SCNMatrix4 does not convert to UnsafePointer".

Note2: I was thinking about using GLKMatrix4, but this type is not recognized in Swift.

+3


source to share


1 answer


I have found that compiler error messages can provide more misdirection than help in determining how to call the C API. My troubleshooting technique was to declare each parameter as a local variable and see which one gets the red flag. In this case, it is not the last parameter to cause problems, it is GLboolean

.

let aTranspose = GLboolean(needToBeTransposed)
// Cannot invoke 'init' with an argument of type 'Bool'

      

It turns out GLboolean is defined like this:



typealias GLboolean = UInt8

      

So this is the code we need:

material.handleBindingOfSymbol("u_matrix") {
    programID, location, renderedNode, renderer in

    let numberOfMatrices = 1
    let needToBeTransposed = false

    let aLoc = GLint(location)
    let aCount = GLsizei(numberOfMatrices)
    let aTranspose = GLboolean(needToBeTransposed ? 1 : 0)
    glUniformMatrix4fv(aLoc, aCount, aTranspose, myMatrix)
}

      

+1


source







All Articles