ios - 将4x4矩阵传递给glUniformMatrix4fv

时间:2016-07-08 07:25:34

标签: ios swift opengl-es shader

我正在尝试将4x4矩阵传递给glUniformMatrix4fv,但无法弄清楚最后一位。我通过直接输入16个值来创建一个4x4。 glUniformMatrix4fv除了UnsafePointer<GLfloat>!作为其最后一个参数

var proj = GLKMatrix4(m: (
    -1.1269710063934326,
    0.0,
    -1.380141455272968e-16,
    0.0,
    0.0,
    0.800000011920929,
    0.0,
    0.0,
    0.0,
    -0.0,
    0.0,
    -4.950000286102295,
    -1.2246468525851679e-16,
    0.0,
    1.0,
    5.050000190734863)
)
var loc = GLint(_locations.uniforms.projection)
var f = GLboolean(GL_FALSE)

首先尝试:

glUniformMatrix4fv(loc, 1, f, proj.m)

加注

Cannot convert value of type '(Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float)' to expected argument type 'UnsafePointer<GLfloat>!'

第二次尝试:

glUniformMatrix4fv(loc, 1, f, &proj.m)

加注

Cannot convert value of type '(Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float)' to expected argument type 'GLfloat' (aka 'Float')

第三次尝试

glUniformMatrix4fv(loc, 1, f, &proj)

加注

Cannot convert value of type 'GLKMatrix4' (aka '_GLKMatrix4') to expected argument type 'GLfloat' (aka 'Float')

最后

glUniformMatrix4fv(loc, 1, f, proj)

加注

Cannot convert value of type 'GLKMatrix4' (aka '_GLKMatrix4') to expected argument type 'UnsafePointer<GLfloat>!'

有什么想法吗?

1 个答案:

答案 0 :(得分:8)

“问题”是C阵列像

float m[16];
struct _GLKMatrix4中的

被映射到Swift作为元组:

public var m: (Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float)

glUniformMatrix4fv()函数需要UnsafePointer<GLfloat> (C中的float *)作为最后一个参数。

在C中,数组在传递时“衰减”为指向第一个元素的指针 一个函数,但不是在Swift中。但是Swift保留了内存布局 导入的C结构,因此你可以传递一个指向元组的指针, 转换为指向GLfloat的指针:

// Swift 2:
withUnsafePointer(&proj.m) {
    glUniformMatrix4fv(loc, 1, f, UnsafePointer($0))
}

// Swift 3/4:
let components = MemoryLayout.size(ofValue: proj.m)/MemoryLayout.size(ofValue: proj.m.0)
withUnsafePointer(to: &proj.m) {
    $0.withMemoryRebound(to: GLfloat.self, capacity: components) {
        glUniformMatrix4fv(loc, 1, f, $0)
    }
}