我正在研究Ray Wenderlich 的OpenGL for iOS教程,试图将他的代码从Objective-C转换为Swift.
我是OpenGL和Swift的新手,并且相信我的问题与我如何翻译Objective-C有关.原因如下:
在我的swift文件中设置包含OpenGL内容的视图,在最后的逻辑步骤(调用glDrawElements)上,应用程序将因EXC_BAD_ACCESS警报而崩溃.但是,如果我将此部分代码移动到Objective-C文件,则应用程序将按预期工作.
Swift版本的代码:
var positionDataOffset: Int = 0 glVertexAttribPointer(self.positionSlot, 3 as GLint, GL_FLOAT.asUnsigned(), GLboolean.convertFromIntegerLiteral(UInt8(GL_FALSE)), VertexDataSource.sizeOfVertex(), &positionDataOffset) var colorDataOffset = (sizeof(Float) * 3) as AnyObject glVertexAttribPointer(self.positionSlot, 4 as GLint, GL_FLOAT.asUnsigned(), GLboolean.convertFromIntegerLiteral(UInt8(GL_FALSE)), VertexDataSource.sizeOfVertex(), VertexDataSource.vertexBufferOffset()) var vertexOffset: Int = 0 glDrawElements(GL_TRIANGLES.asUnsigned(), VertexDataSource.vertexCount(), GL_UNSIGNED_BYTE.asUnsigned(), &vertexOffset)
这是Objective-C版本:
glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); glVertexAttribPointer(color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3)); glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);
正如你所看到的,Swift更加冗长......我和其他人一样都是新手.:)
另一个注意事项:在Swift版本中,您将看到对类的几个类方法的调用VertexDataSource
.从本质上讲,我无法决定如何将Objective-C的某些部分转换为swift,因此决定(现在)在Objective-C中创建一个可以为Swift代码提供这些属性的小类.以下是Objective-C中的那些方法:
+ (GLint)sizeOfVertex { return sizeof(Vertex); } + (GLint)sizeOfIndices { return sizeof(Indices); } + (GLint)sizeOfIndicesAtPositionZero { return sizeof(Indices[0]); } + (GLint)sizeOfVertices { return sizeof(Vertices); } + (GLvoid *)vertexBufferOffset { return (GLvoid *)(sizeof(float) * 3); } + (GLint)vertexCount { return self.sizeOfIndices / sizeof(GLubyte); }
将这些行转换为Swift的任何帮助都会令人惊叹.
编辑#1
正如Reto Koradi指出的那样,上面的Swift代码引用了self.positionSlot
两次而不是使用colorSlot.这是我在这里发布代码时犯的错误,而不是我的代码中的错误.
所以问题依然存在.
更新了Swift:
var positionDataOffset: Int = 0 glVertexAttribPointer(self.positionSlot, 3 as GLint, GL_FLOAT.asUnsigned(), GLboolean.convertFromIntegerLiteral(UInt8(GL_FALSE)), VertexDataSource.sizeOfVertex(), &positionDataOffset) var colorDataOffset = (sizeof(Float) * 3) as AnyObject glVertexAttribPointer(self.colorSlot, 4 as GLint, GL_FLOAT.asUnsigned(), GLboolean.convertFromIntegerLiteral(UInt8(GL_FALSE)), VertexDataSource.sizeOfVertex(), VertexDataSource.vertexBufferOffset()) var vertexOffset: Int = 0 glDrawElements(GL_TRIANGLES.asUnsigned(), VertexDataSource.vertexCount(), GL_UNSIGNED_BYTE.asUnsigned(), &vertexOffset)
编辑#2:解决了
我最终解决了这个问题.我的问题是在几种情况下我将Objective-C转换为Swift是不正确的.为简洁起见,我将为我最初关注的部分发布Swift代码的最终版本,但是您可以在此示例GitHub repo中查看工作结果的完整源代码.
最终的Swift代码:
let positionSlotFirstComponent: CConstVoidPointer = COpaquePointer(UnsafePointer(0)) glVertexAttribPointer(self.positionSlot, 3 as GLint, GL_FLOAT.asUnsigned(), GLboolean.convertFromIntegerLiteral(UInt8(GL_FALSE)), Int32(sizeof(Vertex)), positionSlotFirstComponent) let colorSlotFirstComponent: CConstVoidPointer = COpaquePointer(UnsafePointer (sizeof(Float) * 3)) glVertexAttribPointer(self.colorSlot, 4 as GLint, GL_FLOAT.asUnsigned(), GLboolean.convertFromIntegerLiteral(UInt8(GL_FALSE)), Int32(sizeof(Vertex)), colorSlotFirstComponent) let vertextBufferOffset: CConstVoidPointer = COpaquePointer(UnsafePointer (0)) glDrawElements(GL_TRIANGLES.asUnsigned(), Int32(GLfloat(sizeofValue(Indices)) / GLfloat(sizeofValue(Indices.0))), GL_UNSIGNED_BYTE.asUnsigned(), vertextBufferOffset)
我将继续接受Reto Koradi的回答,因为它确实让我走上正轨.