如何在Swift 3中使用glVertexAttribPointer函数?

时间:2016-10-26 08:49:33

标签: ios opengl-es swift3

在OpenGL ES(3.0)和Objective-C中使用缓冲区和顶点属性时,我使用

glBufferData(GL_ARRAY_BUFFER, sizeof(attributes), attributes, GL_DYNAMIC_DRAW);

将一些顶点数据(属性)加载到缓冲区中,然后

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, sizeof(VertexCoordinatesStruct) / sizeof(GLfloat), GL_FLOAT, GL_FALSE, sizeof(VertexAttributesStruct), 0);

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, sizeof(TextureCoordinatesStruct) / sizeof(GLfloat), GL_FLOAT, GL_FALSE, sizeof(VertexAttributesStruct), (void *)sizeof(VertexCoordinatesStruct));

为顶点着色器指定缓冲区中的顶点数据内存布局。请注意我是如何在第二次glVertexAttribPointer调用中将 sizeof(OGLVertexCoordinates)转换为Void * 的。如果GL_ARRAY_BUFFER中有一个与TextureCoordinatesStruct数据相关的偏移量。

然后我试图在Swift 3中实现相同类型的代码。但glVertexAttribPointer函数将UnsafeRawPointer作为最后一个参数,而不是void *。

这是我无法解决的问题:我无法在Objc中创建具有某些特定值(内存偏移)的UnsafeRawPointer。

我已经研究了我能找到的所有Q / A,但是它们都不适合我的情况,或者根本不适用于Swift 3。

2 个答案:

答案 0 :(得分:8)

你检查过Xcode的OpenGL ES游戏模板吗?

(在Xcode 8.1 GM种子中测试。)

在GameViewController.swift中,您可以找到:

    glEnableVertexAttribArray(GLuint(GLKVertexAttrib.position.rawValue))
    glVertexAttribPointer(GLuint(GLKVertexAttrib.position.rawValue), 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 24, BUFFER_OFFSET(0))
    glEnableVertexAttribArray(GLuint(GLKVertexAttrib.normal.rawValue))
    glVertexAttribPointer(GLuint(GLKVertexAttrib.normal.rawValue), 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 24, BUFFER_OFFSET(12))

BUFFER_OFFSET(_:)(在Objective-C模板中,它是一个宏)被定义为:

func BUFFER_OFFSET(_ i: Int) -> UnsafeRawPointer {
    return UnsafeRawPointer(bitPattern: i)!
}

不幸的是,这是错误的并导致运行时崩溃。您需要将其修复为:

func BUFFER_OFFSET(_ i: Int) -> UnsafeRawPointer? {
    return UnsafeRawPointer(bitPattern: i)
}

使用此BUFFER_OFFSET(_:),您可以创建具有特定值的UnsafeRawPointer

答案 1 :(得分:1)

虽然感觉不对,但无论如何,我这样做......

let ptr = UnsafePointer<UInt8>(bitPattern: UInt(offsetInBytes))
glVertexAttribPointer(indx, size, type, GLboolean(GL_FALSE), stride, ptr)
如果ptr,则{p> nil变为offsetInBytes == 0,因为nil是带有值0(=空指针)的指针的表示... IMO。