在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。
答案 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。