2015-01-17 17 views
5

Tôi đang theo dõi this tutorial về OpenGL/GLKit dành cho iOS nhưng cố gắng triển khai nó trong Swift. Nó sẽ tốt cho đến khi tôi nhận được cho phần này:Làm cách nào để chuyển đổi phép toán con trỏ OpenGL thành 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 

tôi có một tài sản self.quad đó là một Swift struct như thế này:

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

struct TexturedQuad { 

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

Đó là một cấu trúc khá đơn giản, nhưng Tôi không biết làm thế nào để chuyển nó đến đối số cuối cùng của glVertexAttribPointer. Bất kỳ sự giúp đỡ nào sẽ trở nên xuất sắc!

Trả lời

10

Trong Swift, bạn có thể sử dụng cấu trúc chung UnsafePointer để thực hiện số học con trỏ và truyền. Swift không có offsetof, nhưng bạn có thể làm việc xung quanh một cách rõ ràng bằng cách lấy trực tiếp UnsafePointer s trong số geometryVertextextureVertex phần tử.

Mã sau đây biên dịch trong một sân chơi iOS. Tôi đã không kiểm tra nó vượt ra ngoài đó nhưng tôi nghĩ rằng nó sẽ làm việc:

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

Bằng cách này, sử dụng CGPoint cách bạn đã làm trong câu hỏi của bạn là nguy hiểm, vì CGFloat thay đổi kích thước tùy thuộc vào mục tiêu của bạn (32 bit hoặc 64 bit), nhưng GL_FLOAT luôn có nghĩa là 32 bit. Hướng dẫn bạn đang theo dõi được viết trước khi iOS 64 bit xuất hiện.

+0

Tuyệt vời! Tôi cũng sẽ thêm vấn đề tiếp theo trong hướng dẫn này là phần lớn GLKit bị bẻ khóa trong Swift vì Swift thiếu 'union'. Mã bit này xung quanh vấn đề mặc dù https://github.com/programmingthomas/OpenGL.swift – jbrennan

+0

Ngoài ra, yeah, 'CGPoint' không hoạt động vì các phao nổi quá lớn. Bạn phải sử dụng 32 bit 'GL_FLOAT'. – jbrennan

Các vấn đề liên quan