SceneKit_高級06_加載頂點、紋理、法線坐標

SceneKit_入門01_旋轉(zhuǎn)人物
SceneKit_入門02_如何創(chuàng)建工程
SceneKit_入門03_節(jié)點
SceneKit_入門04_燈光
SceneKit_入門05_照相機
SceneKit_入門06_行為動畫
SceneKit_入門07_幾何體
SceneKit_入門08_材質(zhì)
SceneKit_入門09_物理身體
SceneKit_入門10_物理世界
SceneKit_入門11_粒子系統(tǒng)
SceneKit_入門12_物理行為
SceneKit_入門13_骨骼動畫
SceneKit_中級01_模型之間的過渡動畫
SceneKit_中級02_SCNView 詳細講解
SceneKit_中級03_切換照相機視角
SceneKit_中級04_約束的使用
SceneKit_中級05_力的使用
SceneKit_中級06_場景的切換
SceneKit_中級07_動態(tài)修改屬性
SceneKit_中級08_陰影詳解
SceneKit_中級09_碰撞檢測
SceneKit_中級10_濾鏡效果制作
SceneKit_中級11_動畫事件
SceneKit_高級01_GLSL
SceneKit_高級02_粒子系統(tǒng)深入研究
SceneKit_高級03_自定義力
SceneKit_高級04_自定義場景過渡效果
SceneKit_高級05 檢測手勢點擊到節(jié)點
SceneKit_高級06_加載頂點、紋理、法線坐標
SceneKit_高級07_SCNProgram用法探究
SceneKit_高級08_天空盒子制作
SceneKit_高級09_霧效果
SceneKit_大神01_掉落的文字
SceneKit_大神02_彈幕來襲
SceneKit_大神03_navigationbar上的3D文字

讓學(xué)習(xí)成為一種習(xí)慣

和你聊聊

學(xué)過OpenGL 的同學(xué)們,都知道幾個名字頂點坐標,紋理坐標,法線坐標,索引,顏色數(shù)據(jù),我們通過相應(yīng)的api 可以把這些數(shù)據(jù)加入到GPU 中去,我們知道SceneKit 是封裝了OpenGL 和Metal ,在這里不得不說蘋果公司很人性化,開放給我們的接口還是比較多的,我們經(jīng)常有一些需求,尤其是3D 開發(fā),后臺會把一些模型數(shù)據(jù)流傳給前端,前端需要解析出來,然后顯示到頁面上,這個就需要用到今天我們講的技術(shù)。

讓人激動不已的兩個類

  • SCNGeometrySource

負責(zé)加載頂點數(shù)據(jù),紋理數(shù)據(jù),顏色數(shù)據(jù),紋理坐標

  • SCNGeometryElement

負責(zé)加載索引數(shù)據(jù),相信學(xué)習(xí)過OpenGL 的同學(xué)對 Element 這個單詞很熟悉吧。

核心技術(shù)實戰(zhàn)

今天就是用這個技術(shù)加載一個正方形,效果如下

讓學(xué)習(xí)成為一種習(xí)慣
  • 第一步.先定義一下幾個坐標和視圖顏色
    /// 創(chuàng)建頂點坐標
    let vertex:[Float] = [-1,1,-5,
                          1,1,-5,
                          1,-1,-5,
                          -1,-1,-5]
    /// 創(chuàng)建紋理坐標
    let texture:[Float] = [0,0,
                         1,0,
                         1,1,
                         0,1]
    /// 法線索引
    let normal:[Float] = [0,0,1,
                          0,0,1,
                          0,0,1,
                          0,0,1]
    /// 顏色坐標 
    let color:[Float] = [1,0,0,
                         0,1,0,
                         0,0,1,
                         1,1,1]
    /// 創(chuàng)建頂點索引
    let indices:[GLint] = [0,1,2,0,2,3]
  • 第二步 導(dǎo)入游戲框架
 import SceneKit
  • 第三步 創(chuàng)建視圖
  let scnView = SCNView(frame: self.view.bounds)
  self.view.addSubview(scnView)
  scnView.backgroundColor = UIColor.black
  • 第四步 創(chuàng)建場景
  let scene = SCNScene()
  scnView.scene = scene
  • 第五步 創(chuàng)建一個照相機
  let cameraNode  = SCNNode()
  cameraNode.camera = SCNCamera()
  cameraNode.position = SCNVector3(x:0,y:0,z:0)
  scene.rootNode.addChildNode(cameraNode)
  • 第六步 創(chuàng)建一個沒有綁定幾何體的節(jié)點
  let bindNode = SCNNode()
  scene.rootNode.addChildNode(bindNode)

注意了,前方高能,打點雞血,抖擻精神。

我們在加載上面的數(shù)據(jù)之前,要將其轉(zhuǎn)換為NSData 類型或者Data 類型,所以我們寫個函數(shù)統(tǒng)一處理一下

func getData<T>(array:[T])->Data{
    let data:UnsafeMutableRawPointer = malloc(MemoryLayout<T>.size*array.count)
    data.initializeMemory(as: T.self, from:  array)
    return  NSData(bytesNoCopy: data, length: MemoryLayout<T>.size*array.count, freeWhenDone: true) as Data
}

提示:

我們定義為泛型接口,因為數(shù)組中的值類型不一樣,MemoryLayout<T>.size 這個swift 里面獲取數(shù)據(jù)占用內(nèi)存字節(jié)的寫法,ObjectC 是sizeof(T) 的寫法

我們創(chuàng)建SCNGeometrySource 和 SCNGeometryElement 對象

  /// 創(chuàng)建接受頂點的對象
  let vertexSource = SCNGeometrySource(data: getData(array: vertex), semantic: SCNGeometrySource.Semantic.vertex, vectorCount: 4, usesFloatComponents: true, componentsPerVector: 3, bytesPerComponent: MemoryLayout<Float>.size, dataOffset: 0, dataStride: MemoryLayout<Float>.size*3)
  /// 創(chuàng)建紋理坐標對象
  let textureSource = SCNGeometrySource(data: getData(array: texture), semantic: SCNGeometrySource.Semantic.texcoord, vectorCount: 4, usesFloatComponents: true, componentsPerVector: 2, bytesPerComponent: MemoryLayout<Float>.size, dataOffset:0, dataStride: MemoryLayout<Float>.size*2)
  /// 法線坐標對象
  let normalSource = SCNGeometrySource(data: getData(array: normal), semantic: SCNGeometrySource.Semantic.normal, vectorCount: 4, usesFloatComponents: true, componentsPerVector: 3, bytesPerComponent: MemoryLayout<Float>.size, dataOffset: 0, dataStride: MemoryLayout<Float>.size*3)
  /// 顏色對象
let colorSource = SCNGeometrySource(data: getData(array: color), semantic: SCNGeometrySource.Semantic.color, vectorCount: 4, usesFloatComponents: true, componentsPerVector: 3, bytesPerComponent:  MemoryLayout<Float>.size, dataOffset: 0, dataStride: MemoryLayout<Float>.size*3)
  /// 頂點索引
 let indicesElement = SCNGeometryElement(data: getData(array: indices), primitiveType: SCNGeometryPrimitiveType.triangleStrip, primitiveCount: indices.count, bytesPerIndex: MemoryLayout<GLint>.size)

上面就完成了對應(yīng)對象的創(chuàng)建,接下來創(chuàng)建幾何對象

 let geometry = SCNGeometry(sources: [vertexSource,textureSource,normalSource,colorSource], elements: [indicesElement])

綁定這個幾何對象,到我們對應(yīng)的節(jié)點上去

bindNode.geometry = geometry

總結(jié)

本節(jié)的內(nèi)容,教會大家如何動態(tài)的加載頂點,紋理,法線,顏色,索引數(shù)組,是不是比OpenGL ES 簡單很多,后面還有更神奇的東西要公布出來,敬請期待!


代碼庫,聽說經(jīng)常給人點贊都當(dāng)老板了!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容