在Swift中调用glDrawElements而在Objective-C中调用时,OpenGL EXC_BAD_ACCESS [英] OpenGL EXC_BAD_ACCESS when calling glDrawElements in Swift but not in Objective-C
问题描述
我正在通过由Ray Wenderlich撰写的OpenGL for iOS 教程,试图将他的代码从Objective-C转换为Swift。
I'm working through the OpenGL for iOS tutorial by Ray Wenderlich in an attempt to convert his code from Objective-C to Swift.
我是OpenGL和Swift的新手相信我的问题与我如何翻译Objective-C有关。原因如下:
I am very new to OpenGL and to Swift and believe my problem has to do with how I have translated the Objective-C. Here's why:
在我的swift文件中设置包含OpenGL内容的视图,在最后的逻辑步骤(调用glDrawElements)上,应用程序将因EXC_BAD_ACCESS警报而崩溃。 但是,如果我将此部分代码移动到Objective-C文件,应用程序将按预期工作。
In my swift file for setting up my view that contains OpenGL content, on the final logical step (calling glDrawElements) the app will crash with a EXC_BAD_ACCESS alert. If, however, I move this portion of the code to an Objective-C file, the app works as expected.
此版本的Swift版本代码:
Swift version of this code:
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版本:
And here is the Objective-C version:
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更加冗长......我是新手其他所有人。 :)
As you can see, the Swift is much more verbose... I'm new to this like everyone else. :)
另一个注意事项:在Swift版本中,你会看到几个类上的类方法调用 VertexDataSource
。从本质上讲,我无法决定如何将Objective-C的某些部分转换为swift,因此决定(现在)在Objective-C中创建一个可以为Swift代码提供这些属性的小类。以下是Objective-C中的方法:
One other note: In the Swift version, youll see several calls to class methods on the class VertexDataSource
. Essentially, I couldn't for the life of me determine how to convert some portions of the Objective-C to swift, so decided to (FOR NOW) create a small class in Objective-C that could supply the Swift code with those attributes. Here are those methods in 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的任何帮助都会很棒。
Any help translating those lines to Swift would be amazing.
编辑#1
正如Reto Koradi指出的那样,上面的Swift代码引用 self.positionSlot
两次而不是使用colorSlot。这是我在这里发布代码时犯的错误,而不是我的代码中的错误。
As Reto Koradi pointed out, the Swift code above references self.positionSlot
twice rather than using the colorSlot. This was a mistake I made when posting the code here and not actually a mistake in my code.
所以问题仍然存在。
更新了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回购。
I ended up solving this. The problem in my case was that my conversion of the Objective-C to Swift was incorrect in several cases. For brevity I'll post the final version of the Swift code for the portion I was originally concerned about, but you can view the full source code of the working result here in this example GitHub repo.
最终的Swift代码:
The final Swift code:
let positionSlotFirstComponent: CConstVoidPointer = COpaquePointer(UnsafePointer<Int>(0))
glVertexAttribPointer(self.positionSlot, 3 as GLint, GL_FLOAT.asUnsigned(),
GLboolean.convertFromIntegerLiteral(UInt8(GL_FALSE)), Int32(sizeof(Vertex)),
positionSlotFirstComponent)
let colorSlotFirstComponent: CConstVoidPointer = COpaquePointer(UnsafePointer<Int>(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<Int>(0))
glDrawElements(GL_TRIANGLES.asUnsigned(), Int32(GLfloat(sizeofValue(Indices)) /
GLfloat(sizeofValue(Indices.0))), GL_UNSIGNED_BYTE.asUnsigned(), vertextBufferOffset)
我将继续接受Reto Koradi的回答,如同它确实让我走上正轨。
I'm going to go ahead and accept Reto Koradi's answer, as it certainly got me on the right track.
推荐答案
我真的不懂语言,但一个明显的区别是, Objective-C版本设置两个不同的顶点属性,而Swift版本设置两次相同的属性:
I don't really know the languages, but one obvious difference is that the Objective-C version sets up two different vertex attributes, while the Swift version sets up the same attribute twice:
glVertexAttribPointer(self.positionSlot, 3 as GLint, GL_FLOAT.asUnsigned(), ...)
glVertexAttribPointer(self.positionSlot, 4 as GLint, GL_FLOAT.asUnsigned(), ...)
确定属性位置的第一个参数在两种情况下都是相同的。
The first argument, which determines the attribute location, is the same in both cases.
对我来说,这对我来说也很奇怪你在第二次调用中将看起来像变量地址的内容作为 glVertexAttribPointer()
的最后一个参数传递,并作为的最后一个参数glDrawElements()
。但也许&
运算符在Swift中意味着与我习惯的语言不同。
It also looks kind of odd to me that you're passing what looks like the address of a variable as the last argument of glVertexAttribPointer()
in the second call, and as the last argument of glDrawElements()
. But maybe the &
operator means something different in Swift than in the languages I'm used to.
这篇关于在Swift中调用glDrawElements而在Objective-C中调用时,OpenGL EXC_BAD_ACCESS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!