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é)過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ù)加載一個正方形,效果如下

- 第一步.先定義一下幾個坐標和視圖顏色
/// 創(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)老板了!