2016-07-08 10 views
3

Ich versuche, eine 4x4-Matrix an glUniformMatrix4fv übergeben, aber das letzte Bit nicht herausfinden. Ich erstelle ein 4x4 durch direkte Eingabe von 16 Werten. glUniformMatrix4fv excepts ein UnsafePointer<GLfloat>! als letztes Argumentios - eine 4x4-Matrix an glUniformMatrix4fv übergeben

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) 

Erster Versuch:

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

wirft

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

zweiter Versuch:

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

wirft

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

dritten Versuch

glUniformMatrix4fv(loc, 1, f, &proj) 

wirft

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

und schließlich

glUniformMatrix4fv(loc, 1, f, proj) 

wirft

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

Irgendeine Idee?

+1

ich in schnellen bin nicht gut, aber sind Sie sicher, dass die Matrixinitialisierung ist korrekt? Sie versuchen, ein Array (das m-Mitglied) mit einem Tupel zu initialisieren. Das m-Mitglied selbst sollte das sein, was du an "glUniformMatrix4fv" wie bei deinem ersten Versuch weitergeben musst. – BDL

+0

@BDL: Das Problem ist, dass Swift C-Arrays zu einem Swift-Tupel abbildet. Die Initialisierung von GLKMatrix4 ist korrekt. –

Antwort

8

Das "Problem" ist, dass C-Arrays wie die

float m[16]; 

in struct _GLKMatrix4 zu Swift als Tupel zugeordnet sind:

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

aber die glUniformMatrix4fv() Funktion erwartet UnsafePointer<GLfloat> (float * in C) als letztes Argument.

In C "zerfällt" ein Array zu einem Zeiger auf das erste Element, wenn an eine Funktion übergeben wird, aber nicht in Swift. Aber Swift bewahrt die Erinnerung Layout importierter C Strukturen, daher können Sie einen Zeiger auf das Tupel passieren kann, umgewandelt auf einen Zeiger auf 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) 
    } 
} 
+0

Super! Ich beginne mit Swift (ohne Hintergrund in Objective C) und das hätte ich selbst nicht herausgefunden! – Guig

+2

@Fonix: Ich habe den entsprechenden Swift 3 Code hinzugefügt. –

+1

@MartinR ehrfürchtigen Dank, Art von Zähler intuitiv, dass sie es noch ausführlicher gemacht, dachte, Swift 3 war über die Dinge prägnanter zu bekommen: P denke, es muss ein notwendiges Übel gewesen sein – Fonix