ios - 将4x4矩阵传递给glUniformMatrix4fv

Gui*_*uig 3 shader opengl-es ios swift

我试图传递一个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)
Run Code Online (Sandbox Code Playgroud)

第一次尝试:

glUniformMatrix4fv(loc, 1, f, proj.m)
Run Code Online (Sandbox Code Playgroud)

加薪

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>!'
Run Code Online (Sandbox Code Playgroud)

第二次尝试:

glUniformMatrix4fv(loc, 1, f, &proj.m)
Run Code Online (Sandbox Code Playgroud)

加薪

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')
Run Code Online (Sandbox Code Playgroud)

第三次尝试

glUniformMatrix4fv(loc, 1, f, &proj)
Run Code Online (Sandbox Code Playgroud)

加薪

Cannot convert value of type 'GLKMatrix4' (aka '_GLKMatrix4') to expected argument type 'GLfloat' (aka 'Float')
Run Code Online (Sandbox Code Playgroud)

最后

glUniformMatrix4fv(loc, 1, f, proj)
Run Code Online (Sandbox Code Playgroud)

加薪

Cannot convert value of type 'GLKMatrix4' (aka '_GLKMatrix4') to expected argument type 'UnsafePointer<GLfloat>!'
Run Code Online (Sandbox Code Playgroud)

任何的想法?

Mar*_*n R 9

"问题"是C阵列喜欢的

float m[16];
Run Code Online (Sandbox Code Playgroud)

in struct _GLKMatrix4映射到Swift作为元组:

public var m: (Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float)
Run Code Online (Sandbox Code Playgroud)

但是glUniformMatrix4fv()函数期望UnsafePointer<GLfloat> (float *在C中)作为最后一个参数.

在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)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Fonix:我添加了相应的Swift 3代码. (2认同)