Ich arbeite über das OpenGL for iOS Tutorial von Ray Wenderlich in dem Versuch, seinen Code von Objective-C nach Swift zu konvertieren.OpenGL EXC_BAD_ACCESS beim Aufruf von glDrawElements in Swift, aber nicht in Objective-C
Ich bin sehr neu zu OpenGL und zu Swift und glaube, dass mein Problem damit zu tun hat, wie ich das Objective-C übersetzt habe. Hier ist warum:
In meiner schnellen Datei zum Einrichten meiner Ansicht, die OpenGL-Inhalt enthält, stürzt die App im letzten logischen Schritt (Aufruf von glDrawElements) mit einer EXC_BAD_ACCESS-Warnung ab. Wenn ich jedoch diesen Teil des Codes in eine Objective-C-Datei verschiebe, funktioniert die App wie erwartet.
Swift-Version dieser 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)
Und hier ist die 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);
Wie Sie sehen können, die Swift ist viel ausführlicher ... Ich bin neu dazu wie alle anderen auch. :)
Noch eine Anmerkung: In der Swift-Version werden mehrere Aufrufe von Klassenmethoden in der Klasse VertexDataSource
angezeigt. Im Wesentlichen konnte ich nicht für das Leben von mir bestimmen, wie einige Teile des Objective-C in swift umgewandelt werden, so dass (FOR NOW) eine kleine Klasse in Objective-C erstellt wurde, die den Swift-Code mit diesen Attributen versehen könnte. Hier sind die Methoden 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);
}
Jegliche Hilfe, diese Zeilen zu Swift zu übersetzen wäre erstaunlich.
EDIT # 1
Wie Reto Koradi wies darauf hin, self.positionSlot
der Swift-Code über Referenzen zweimal anstatt die colorSlot verwenden. Das war ein Fehler, den ich gemacht habe, als ich den Code hier postete und nicht wirklich einen Fehler in meinem Code.
Also das Problem besteht immer noch.
Aktualisiert 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: Gelöst
landete ich diese Lösung. Das Problem in meinem Fall war, dass meine Konvertierung von Objective-C nach Swift in mehreren Fällen falsch war. Der Kürze halber werde ich die endgültige Version des Swift-Codes für den Teil veröffentlichen, über den ich ursprünglich besorgt war, aber Sie können den vollständigen Quellcode des Arbeitsergebnisses hier in this example GitHub repo ansehen.
Der letzte 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)
Ich werde weitermachen und Reto Koradi Antwort zu akzeptieren, wie es mir sicherlich auf dem richtigen Weg bekam.
Hallo, 'lassen vertextBufferOffset: CConstVoidPointer = COpaquePointer (UnsafePointer (0)') scheint nicht mehr zu funktionieren. Würdest du zufällig andere Alternativen kennen? Danke im Voraus. –
Unheilig
anstelle dieser langen 'convertFrom ...' Funktionen, versuche nur 'GLboolean (GL_FALSE)' – Jarsen
auch 'GLenum (GL_TRIANGLES)' – Jarsen