2015-01-17 3 views
5

Я следую this tutorial о OpenGL/GLKit для iOS, но пытаюсь реализовать его в Swift. Это будет хорошо, пока я не дойду до этой части:Как преобразовать этот указатель OpenGL в 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 

У меня есть свойство self.quad это Свифт структуры, как это:

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

struct TexturedQuad { 

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

Это довольно простая структура, но я не знаю, как передать его последнему аргументу glVertexAttribPointer. Любая помощь будет звездной!

ответ

10

В Swift вы можете использовать общую структуру UnsafePointer для выполнения арифметики и литья указателя. Swift не имеет offsetof, но вы можете обойти это чисто, взяв UnsafePointer s из geometryVertex и textureVertex элементов непосредственно.

Следующий код компилируется на игровой площадке iOS. Я не проверял его за это, но я думаю, что это будет работать:

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

Кстати, используя CGPoint так, как вы делали в вашем вопросе опасно, так как CGFloat изменения размера в зависимости от вашей цели (32- бит или 64-бит), но GL_FLOAT всегда означает 32-разрядный. Учебник, за которым вы следуете, был написан до выхода 64-разрядного iOS.

+0

Отлично! Я также добавлю следующую проблему в учебник: большая часть GLKit находится в Swift, потому что Swift не имеет 'union'. Этот бит кода затрагивает проблему, хотя https://github.com/programmingthomas/OpenGL.swift – jbrennan

+0

Кроме того, да, 'CGPoint' не работает, потому что поплавки слишком велики. Вы должны использовать 32-битный 'GL_FLOAT'. – jbrennan