2015-01-17 19 views
5

Sto seguendo this tutorial su OpenGL/GLKit per iOS ma sto provando a implementarlo in Swift. Sta andando bene fino a quando ottengo a questa parte:Come posso convertire questo matematico del puntatore OpenGL in Swift?

- (void)render { 

// 1 
self.effect.texture2d0.name = self.textureInfo.name; 
self.effect.texture2d0.enabled = YES; 

// 2  
[self.effect prepareToDraw]; 

// 3 
glEnableVertexAttribArray(GLKVertexAttribPosition); 
glEnableVertexAttribArray(GLKVertexAttribTexCoord0); 

//---------------- This is where things break down... 
long offset = (long)&_quad;   
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, geometryVertex))); 
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, textureVertex))); 

// 5  
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

} 

@end 

Ho un immobile self.quad che è uno Swift struct come questo:

struct TexturedVertex { 
let geometryVertex: CGPoint 
let textureVertex: CGPoint 
} 

struct TexturedQuad { 

let bottomLeft: TexturedVertex 
let bottomRight: TexturedVertex 
let topLeft: TexturedVertex 
let topRight: TexturedVertex 
} 

E 'una struttura abbastanza semplice, ma io non so come per passarlo all'ultimo argomento di glVertexAttribPointer. Qualsiasi aiuto sarebbe stellare!

risposta

10

In Swift, è possibile utilizzare la struttura generica UnsafePointer per eseguire l'aritmetica del puntatore e il cast. Swift non ha offsetof, ma puoi ovviare a questo in modo pulito prendendo gli UnsafePointer s degli elementi geometryVertex e textureVertex direttamente.

Il seguente codice viene compilato in un parco giochi iOS. Non ho provato al di là di questo, ma penso che funzionerà:

import OpenGLES 
import GLKit 

struct TexturedVertex { 
    var geometryVertex = GLKVector2() 
    var textureVertex = GLKVector2() 
} 

struct TexturedQuad { 
    var bl = TexturedVertex() 
    var br = TexturedVertex() 
    var tl = TexturedVertex() 
    var tr = TexturedVertex() 
    init() { } 
} 

var _quad = TexturedQuad() 
withUnsafePointer(&_quad.bl.geometryVertex) { (pointer) -> Void in 
    glVertexAttribPointer(GLuint(GLKVertexAttrib.Position.rawValue), 
     2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 
     GLsizei(sizeof(TexturedVertex)), pointer) 
} 
withUnsafePointer(&_quad.bl.textureVertex) { (pointer) -> Void in 
    glVertexAttribPointer(GLuint(GLKVertexAttrib.TexCoord0.rawValue), 
     2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 
     GLsizei(sizeof(TexturedVertex)), pointer) 
} 

Tra l'altro, utilizzando CGPoint il modo che hai fatto nella tua domanda è pericoloso, perché CGFloat modifiche di dimensione a seconda della destinazione (32- bit o 64 bit), ma GL_FLOAT significa sempre 32 bit. Il tutorial che stai seguendo è stato scritto prima che uscisse iOS a 64 bit.

+0

Eccellente! Aggiungerò anche il prossimo problema nel tutorial è che la maggior parte di GLKit viene sballato in Swift perché Swift manca 'union'. Questo bit di codice risolve il problema anche se https://github.com/programmingthomas/OpenGL.swift – jbrennan

+0

Inoltre, sì, 'CGPoint' non funziona perché i float sono troppo grandi. Devi usare "GL_FLOAT" a 32 bit. – jbrennan