如何将OpenGL指针数学转换为Swift?

时间:2022-09-07 09:29:46

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 UnsafePointers 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 UnsafePointers 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发布之前编写的。