ios - SCNProgram – 如何将类型为 "mat4"的制服传递给自定义着色器?

标签 ios opengl-es swift scenekit

我正在尝试设置一个统一的 mat4,我想在 iOS 上的 SceneKit 的自定义着色器程序中使用它(Xcode 6 beta 6)。我正尝试在 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)
}

使用这段代码,我有以下编译错误:Cannot invoke 'init' with an argument list of type (GLint, GLsizei, GLboolean, Array<GLfloat>) .但是,根据此处的文档 (section "Constant pointers"),我的理解是我们可以将数组传递给以 UnsafePointer 作为参数的函数。

然后我尝试通过执行以下操作直接传递 UnsafePointer:

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

我得到了错误 Cannot invoke 'init' with an argument list of type '(GLint, GLsizei, GLboolean, UnsafePointer<GLfloat>)'

然而,glUniformMatrix4fv 的原型(prototype)正是这样的:

func glUniformMatrix4fv(location: GLint, count: GLsizei, transpose: GLboolean, value: UnsafePointer<GLfloat>)

知道我做错了什么吗?如果我们使用自定义着色器,我们应该如何将 mat4 作为制服传递?

注意 1:我首先尝试将 SCNMatrix4 用于 myMatrix,但出现错误“SCNMatrix4 不可转换为 UnsafePointer”。

注意 2:我想过使用 GLKMatrix4,但这种类型在 Swift 中无法识别。

最佳答案

我发现在弄清楚如何调用 C API 时,编译器的错误消息提供的误导多于帮助。我的故障排除技术是将每个参数声明为局部变量并查看哪个参数出现危险信号。在这种情况下,导致问题的不是最后一个参数,而是 GLboolean

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

原来 GLboolean 是这样定义的:

typealias GLboolean = UInt8

所以这是我们需要的代码:

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)
}

关于ios - SCNProgram – 如何将类型为 "mat4"的制服传递给自定义着色器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25493045/

相关文章:

ios - 当我尝试使用我的 Json 时,它只显示第一个值(标题)Objective c

iphone - OpenGL ES iPhone - 绘制抗锯齿线

android - eglGetError() 报告错误成功

ios - 滚动后表格 View 单元格困惑

ios - 添加 subview 后,Swift Playground UITable View Cell 未调整大小

ios - 应用仅在特定设备上崩溃

ios - 如何在 UIView 和 UIImageView 中重用相同的 IBDesignable 代码

ios - 区域监控及后台

iphone - EAGLView 到 UIImage 颜色转换问题

swift - DDXMLElement 的奇怪问题