Sto lavorando attraverso il tutorial OpenGL for iOS di Ray Wenderlich nel tentativo di convertire il suo codice da Objective-C a Swift.OpenGL EXC_BAD_ACCESS quando si chiama glDrawElements in Swift ma non in Objective-C
Sono molto nuovo a OpenGL e a Swift e credo che il mio problema abbia a che fare con il modo in cui ho tradotto l'Objective-C. Ecco perché:
Nel mio file rapido per impostare la mia vista che contiene contenuto OpenGL, sul passo logico finale (chiamando glDrawElements) l'applicazione si bloccherà con un avviso EXC_BAD_ACCESS. Se, tuttavia, sposto questa parte del codice in un file Objective-C, l'app funziona come previsto.
versione Swift di questo codice:
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)
Ed ecco la versione 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);
Come si può vedere, la Swift è molto più verboso ... Sono nuovo a questo come tutti gli altri. :)
Un'altra nota: nella versione Swift, vedrete diverse chiamate ai metodi di classe sulla classe VertexDataSource
. Essenzialmente, non potevo per la vita di me determinare come convertire alcune parti dell'Obiettivo-C in modo rapido, così ho deciso di (PER ORA) creare una piccola classe in Objective-C che potesse fornire il codice Swift con quegli attributi. Ecco quei metodi 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);
}
Qualsiasi aiuto nella traduzione di queste righe in Swift sarebbe sorprendente.
EDIT # 1
Come Reto Koradi ha sottolineato, il codice Swift sopra riferimenti self.positionSlot
due volte, piuttosto che utilizzare il colorSlot. Questo è stato un errore che ho fatto durante la pubblicazione del codice qui e non in realtà un errore nel mio codice.
Quindi il problema esiste ancora.
Aggiornato 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: Risolto
ho finito per la soluzione di questo. Il problema nel mio caso era che la mia conversione da Objective-C a Swift era errata in molti casi. Per brevità pubblicherò la versione finale del codice Swift per la parte di cui ero originariamente interessato, ma è possibile visualizzare il codice sorgente completo del risultato di lavoro qui in this example GitHub repo.
Il codice Swift finale:
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)
ho intenzione di andare avanti e accettare la risposta di Reto Koradi, come certamente mi ha fatto sulla strada giusta.
Ciao, 'let vertextBufferOffset: CConstVoidPointer = COpaquePointer (UnsafePointer (0)') non sembra funzionare più. Ti piacerebbe conoscere altre alternative? Grazie in anticipo. –
Unheilig
invece di quelle lunghe funzioni 'convertFrom ...', prova solo 'GLboolean (GL_FALSE)' – Jarsen
anche 'GLenum (GL_TRIANGLES)' – Jarsen