问题
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