I’m following this tutorial about OpenGL / GLKit for iOS but trying to implement it in Swift. It’s going fine until I get to this part:
我正在学习关于iOS的OpenGL / GLKit的教程,但是我试图在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
I have a property self.quad
that’s a Swift struct like this:
我有自己的财产。这是一个快速的结构,像这样:
struct TexturedVertex {
let geometryVertex: CGPoint
let textureVertex: CGPoint
}
struct TexturedQuad {
let bottomLeft: TexturedVertex
let bottomRight: TexturedVertex
let topLeft: TexturedVertex
let topRight: TexturedVertex
}
It’s a fairly straightforward structure, but I don’t know how to pass it to the last argument of glVertexAttribPointer
. Any help would be stellar!
这是一个相当简单的结构,但是我不知道如何将它传递给glVertexAttribPointer的最后一个参数。任何帮助都将是一流的!
1 个解决方案
#1
10
In Swift, you can use the generic struct UnsafePointer
to perform pointer arithmetic and casting. Swift doesn't have offsetof
, but you can work around that cleanly by taking UnsafePointer
s of the geometryVertex
and textureVertex
elements directly.
在Swift中,可以使用通用的struct UnsafePointer执行指针算法和强制转换。Swift没有offsetof,但是您可以通过直接获取几何顶点和textureVertex元素的unsafepointer来轻松地解决这个问题。
The following code compiles in an iOS playground. I haven't tested it beyond that but I think it'll work:
下面的代码在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)
}
By the way, using CGPoint
the way you did in your question is dangerous, because CGFloat
changes size depending on your target (32-bit or 64-bit), but GL_FLOAT
always means 32-bit. The tutorial you're following was written before 64-bit iOS came out.
顺便说一下,像您在问题中所做的那样使用CGPoint是危险的,因为CGFloat会根据您的目标(32位或64位)改变大小,但是GL_FLOAT总是意味着32位。您所遵循的教程是在64位iOS发布之前编写的。
#1
10
In Swift, you can use the generic struct UnsafePointer
to perform pointer arithmetic and casting. Swift doesn't have offsetof
, but you can work around that cleanly by taking UnsafePointer
s of the geometryVertex
and textureVertex
elements directly.
在Swift中,可以使用通用的struct UnsafePointer执行指针算法和强制转换。Swift没有offsetof,但是您可以通过直接获取几何顶点和textureVertex元素的unsafepointer来轻松地解决这个问题。
The following code compiles in an iOS playground. I haven't tested it beyond that but I think it'll work:
下面的代码在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)
}
By the way, using CGPoint
the way you did in your question is dangerous, because CGFloat
changes size depending on your target (32-bit or 64-bit), but GL_FLOAT
always means 32-bit. The tutorial you're following was written before 64-bit iOS came out.
顺便说一下,像您在问题中所做的那样使用CGPoint是危险的,因为CGFloat会根据您的目标(32位或64位)改变大小,但是GL_FLOAT总是意味着32位。您所遵循的教程是在64位iOS发布之前编写的。