ios - pass a 4x4 matrix to glUniformMatrix4fv

╄→гoц情女王★ 提交于 2019-12-10 18:24:12

问题


I'm trying to pass a 4x4 matrix to glUniformMatrix4fv but can't figure out the last bit. I create a 4x4 by directly inputing 16 values. glUniformMatrix4fv excepts an UnsafePointer<GLfloat>! as its last argument

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)

First try:

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

raises

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>!'

second try:

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

raises

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

third try

glUniformMatrix4fv(loc, 1, f, &proj)

raises

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

and finally

glUniformMatrix4fv(loc, 1, f, proj)

raises

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

Any idea?


回答1:


The "problem" is that C arrays like the

float m[16];

in struct _GLKMatrix4 are mapped to Swift as a tuple:

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

but the glUniformMatrix4fv() function expects UnsafePointer<GLfloat> (float * in C) as the last argument.

In C, an array "decays" to a pointer to the first element when passed to a function, but not in Swift. But Swift preserves the memory layout of imported C structures, therefore you can pass a pointer to the tuple, converted to a pointer to 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)
    }
}


来源:https://stackoverflow.com/questions/38261094/ios-pass-a-4x4-matrix-to-gluniformmatrix4fv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!