OpenGL EXC_BAD_ACCESS when calling glDrawElements in Swift but not in Objective-C

I am working on an OpenGL tutorial for iOS from Ray Wenderlich to convert its code from Objective-C to Swift.

I am very new to OpenGL and Swift and believe that my problem is how I translated Objective-C. That's why:

In my quick file for setting up my view containing the contents of OpenGL, at the last logical step (calling glDrawElements), the application crashes with the warning EXC_BAD_ACCESS. If, however, I move this part of the code to an Objective-C file, the application works as expected.

Quick 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) 

And here is the version of 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); 

As you can see, Swift is much more verbose ... I'm new to this, like everyone else. :)

One more note. In the Swift version, you will see several class method calls in the VertexDataSource class. Essentially, I could not determine in my life how to convert some parts of Objective-C to swift, so I decided (FOR NOW) to create a small class in Objective-C that could provide Swift code with these attributes. These methods are 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); } 

Any help translating these lines into Swift would be awesome.

EDIT NO. 1

As Reto Coradi noted, Swift code is above self.positionSlot links twice, rather than using colorSlot. It was a mistake I made while posting the code here, and not really a mistake in my code.

So the problem still exists.

Updated 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) 

EDIT # 2: Allowed

I decided to solve it. The problem in my case was that my conversion of Objective-C to Swift was incorrect in several cases. For brevity, I will post the final version of the Swift code for the part that I originally worried about, but you can view the full source code of the work result here in this GitHub repo example .

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) 

I am going to go further and agree with Reto Coradi's answer, as it certainly led me on the right track.

+5
source share
2 answers

I don't know languages, but one obvious difference is that the Objective-C version sets two different vertex attributes, and the Swift version sets 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 specifying the location of the attribute is the same in both cases.

It also seems strange to me that you pass what looks like the address of the variable as the last argument to glVertexAttribPointer() in the second call, and as the last argument to glDrawElements() . But perhaps the & operator means something different in Swift than in the languages ​​I'm used to.

+1
source

For people using Swift 2.1.1 with Xcode 7.2, like me, the pointer syntax has changed. Here is an example of how to use it.

https://github.com/asymptotik/asymptotik-rnd-scenekit-kaleidoscope/blob/master/Atk_Rnd_VisualToys/ScreenTextureQuad.swift

The related code is below:

 // bind VBOs for vertex array and index array // for vertex coordinates let ptr = UnsafePointer<GLfloat>(bitPattern: 0) glBindBuffer(GLenum(GL_ARRAY_BUFFER), self.vertexBufferObject) glEnableVertexAttribArray(self.positionIndex) glVertexAttribPointer(self.positionIndex, GLint(3), GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(sizeof(GLfloat) * 8), ptr) glEnableVertexAttribArray(self.textureCoordinateIndex) glVertexAttribPointer(self.textureCoordinateIndex, GLint(2), GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(sizeof(GLfloat) * 8), ptr.advancedBy(6)) 

Hope this helps. I also fixed the OP project github example in my fork here: https://github.com/zwang/iOSSwiftOpenGL

+2
source

Source: https://habr.com/ru/post/979946/


All Articles