在iOS上使用Swift在SceneKit上绘制一条线:画线但不可见?

时间:2015-01-15 19:02:00

标签: ios swift scenekit

此处对Objective-C中我之前的问题的后续跟进(具体来说,我试图将我在Objective-C中提供的答案翻译成Swift):

Drawing a line between two points using SceneKit

问题:SceneKit统计信息显示正在绘制线条,但它不会出现在屏幕上。

最小例子:

  • 使用Swift和SceneKit在Xcode中开始一个新的游戏项目。
  • 删除样板:
    • 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构造出现了问题?

1 个答案:

答案 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位整数。因此,您的数据缓冲区比SCNGeometrySourceSCNGeometryElement构造函数声称的要短得多,这意味着在渲染时,SceneKit要求OpenGL进行长 walk 绘制一个短的码头缓冲区。

通常,如果您从数组构造NSData,则希望 length 参数是数组计数乘以数组元素类型的sizeof。< / p>