此处对Objective-C中我之前的问题的后续跟进(具体来说,我试图将我在Objective-C中提供的答案翻译成Swift):
Drawing a line between two points using SceneKit
问题:SceneKit统计信息显示正在绘制线条,但它不会出现在屏幕上。
最小例子:
let scene = SCNScene()
代替SCNScene(named: "art.scnassets/ship.dae")!
let ship = ...
和ship.runAction(...)
scnView.backgroundColor = UIColor.blackColor()
更改为scnView.backgroundColor = UIColor.grayColor()
(我原本以为黑色背景上的线条可能只是黑色,所以相应地更改了背景颜色)添加以下代码:
var positions: [SCNVector3] = [SCNVector3Make(0.0,0.0,0.0),SCNVector3Make(10.0,10.0,10.0)]
// using Swift's Int gives an error with unsupported "SceneKit: error, C3DRendererContextBindMeshElement unsupported byte per index (8)"
// when constructing element: SCNGeometryElement below, so switched to CInt
var indicies: [CInt] = [0,1]
// for whatever reason, the following doesn't work on iOS:
// let vertexSource = SCNGeometrySource(vertices: &positions, count: positions.count)
// see https://stackoverflow.com/questions/26890739/how-to-solve-scenekit-double-not-supported-error
// so using more complex SCNGeometrySource() initializer instead
let vertexData = NSData(bytes: &positions, length: positions.count)
let vertexSource = SCNGeometrySource(data: vertexData, semantic: SCNGeometrySourceSemanticVertex,
vectorCount: positions.count, floatComponents: true, componentsPerVector: 3,
bytesPerComponent: sizeof(Float), dataOffset: 0, dataStride: sizeof(SCNVector3))
let indexData = NSData(bytes: &indicies, length: indicies.count)
let element = SCNGeometryElement(data: indexData, primitiveType: SCNGeometryPrimitiveType.Line,
primitiveCount: indicies.count, bytesPerIndex: sizeof(CInt))
let lines = SCNGeometry(sources: [vertexSource], elements: [element])
let cellNode = SCNNode(geometry: lines)
scene.rootNode.addChildNode(cellNode)
如上所述,SceneKit统计信息表明 行已被绘制,但它似乎没有出现,并且没有编译或运行时错误,这使得它有点棘手追查。
编辑:使用GPU'分析'调试导航器中的工具出现以下错误:
Draw call exceeded element array buffer bounds
Draw call exceeded array buffer bounds
glDrawElements(GL_LINES, 4, GL_UNSIGNED_INT, NULL)
中的表明我的SCNGeometryElement构造出现了问题?
答案 0 :(得分:3)
我没有机会直接调试代码,但很可能这些代码就是你的问题:
let vertexData = NSData(bytes: &positions, length: positions.count)
// ...
let indexData = NSData(bytes: &indicies, length: indicies.count)
数据的长度是每个条目的大小(以字节为单位)的条目数。 positions
中的每个元素都是SCNVector3
,iOS上有三个Float
,因此每个位置都是3 * sizeof(Float)
或12个字节。 indicies
(sic)中的每个元素都是CInt
,我相信它是一个32位整数。因此,您的数据缓冲区比SCNGeometrySource
和SCNGeometryElement
构造函数声称的要短得多,这意味着在渲染时,SceneKit要求OpenGL进行长 walk 绘制一个短的码头缓冲区。
通常,如果您从数组构造NSData
,则希望 length 参数是数组计数乘以数组元素类型的sizeof
。< / p>