前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SceneKit_高级06_加载顶点、纹理、法线坐标

SceneKit_高级06_加载顶点、纹理、法线坐标

作者头像
酷走天涯
发布2022-05-13 16:10:37
8680
发布2022-05-13 16:10:37
举报

SceneKit_入门01_旋转人物

SceneKit_入门02_如何创建工程

SceneKit_入门03_节点

SceneKit_入门04_灯光

SceneKit_入门05_照相机

SceneKit_入门06_行为动画

SceneKit_入门07_几何体

SceneKit_入门08_材质

SceneKit_入门09_物理身体

SceneKit_入门10_物理世界

SceneKit_入门11_粒子系统

SceneKit_入门12_物理行为

SceneKit_入门13_骨骼动画

SceneKit_中级01_模型之间的过渡动画

SceneKit_中级02_SCNView 详细讲解

SceneKit_中级03_切换照相机视角

SceneKit_中级04_约束的使用

SceneKit_中级05_力的使用

SceneKit_中级06_场景的切换

SceneKit_中级07_动态修改属性

SceneKit_中级08_阴影详解

SceneKit_中级09_碰撞检测

SceneKit_中级10_滤镜效果制作

SceneKit_中级11_动画事件

SceneKit_高级01_GLSL

SceneKit_高级02_粒子系统深入研究

SceneKit_高级03_自定义力

SceneKit_高级04_自定义场景过渡效果

SceneKit_高级05 检测手势点击到节点

SceneKit_高级06_加载顶点、纹理、法线坐标

SceneKit_高级07_SCNProgram用法探究

SceneKit_高级08_天空盒子制作

SceneKit_高级09_雾效果

SceneKit_大神01_掉落的文字

SceneKit_大神02_弹幕来袭

SceneKit_大神03_navigationbar上的3D文字

让学习成为一种习惯

和你聊聊

学过OpenGL 的同学们,都知道几个名字顶点坐标,纹理坐标,法线坐标,索引,颜色数据,我们通过相应的api 可以把这些数据加入到GPU 中去,我们知道SceneKit 是封装了OpenGL 和Metal ,在这里不得不说苹果公司很人性化,开放给我们的接口还是比较多的,我们经常有一些需求,尤其是3D 开发,后台会把一些模型数据流传给前端,前端需要解析出来,然后显示到页面上,这个就需要用到今天我们讲的技术。

让人激动不已的两个类
  • SCNGeometrySource

负责加载顶点数据,纹理数据,颜色数据,纹理坐标

  • SCNGeometryElement

负责加载索引数据,相信学习过OpenGL 的同学对 Element 这个单词很熟悉吧。

核心技术实战

今天就是用这个技术加载一个正方形,效果如下

让学习成为一种习惯

  • 第一步.先定义一下几个坐标和视图颜色
代码语言:javascript
复制
    /// 创建顶点坐标
    let vertex:[Float] = [-1,1,-5,
                          1,1,-5,
                          1,-1,-5,
                          -1,-1,-5]
    /// 创建纹理坐标
    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]
    /// 创建顶点索引
    let indices:[GLint] = [0,1,2,0,2,3]
  • 第二步 导入游戏框架
代码语言:javascript
复制
 import SceneKit
  • 第三步 创建视图
代码语言:javascript
复制
  let scnView = SCNView(frame: self.view.bounds)
  self.view.addSubview(scnView)
  scnView.backgroundColor = UIColor.black
  • 第四步 创建场景
代码语言:javascript
复制
  let scene = SCNScene()
  scnView.scene = scene
  • 第五步 创建一个照相机
代码语言:javascript
复制
  let cameraNode  = SCNNode()
  cameraNode.camera = SCNCamera()
  cameraNode.position = SCNVector3(x:0,y:0,z:0)
  scene.rootNode.addChildNode(cameraNode)
  • 第六步 创建一个没有绑定几何体的节点
代码语言:javascript
复制
  let bindNode = SCNNode()
  scene.rootNode.addChildNode(bindNode)

注意了,前方高能,打点鸡血,抖擞精神。

我们在加载上面的数据之前,要将其转换为NSData 类型或者Data 类型,所以我们写个函数统一处理一下

代码语言:javascript
复制
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
}

提示:

我们定义为泛型接口,因为数组中的值类型不一样,MemoryLayout<T>.size 这个swift 里面获取数据占用内存字节的写法,ObjectC 是sizeof(T) 的写法

我们创建SCNGeometrySource 和 SCNGeometryElement 对象

代码语言:javascript
复制
  /// 创建接受顶点的对象
  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)
  /// 创建纹理坐标对象
  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)

上面就完成了对应对象的创建,接下来创建几何对象

代码语言:javascript
复制
 let geometry = SCNGeometry(sources: [vertexSource,textureSource,normalSource,colorSource], elements: [indicesElement])

绑定这个几何对象,到我们对应的节点上去

代码语言:javascript
复制
bindNode.geometry = geometry

总结

本节的内容,教会大家如何动态的加载顶点,纹理,法线,颜色,索引数组,是不是比OpenGL ES 简单很多,后面还有更神奇的东西要公布出来,敬请期待!


代码库,听说经常给人点赞都当老板了!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 和你聊聊
  • 让人激动不已的两个类
  • 核心技术实战
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档