查看原文
其他

骚操作!程序员用代码画个姑娘过情人节

程序人生 2020-02-17

The following article comes from 肖小的人儿 Author 肖哥

作者 | 肖哥

来源 | 肖小的人儿(ID:gh_8aa6fc238842)

情人节快乐!又到了一年一度的情人节,今年依然是 new 一个对象吗?太 low 了,来用代码画一个吧~

说搞就搞,Let's go ~


实现方案


基于 Android 平台,使用 Kotlin + C++ 的方式实现。

上层负责 UI 相关,以及监听用户交互事件,并通过 JNI 交给 Native 层做具体响应。

Native 层则负责模型的解析、视图变换、Shader 渲染等逻辑。


主要的 JNI 一览


// Surface 创建
external fun nativeSurfaceCreated(assertManager: AssetManager, modelDir: String, modelFile: String, animFile: String)
// Surface 调整
external fun nativeSurfaceChanged(width: Int, height: Int)
// Surface 绘制当前帧
external fun nativeDrawFrame()
// 通知触摸事件
external fun nativeTouchEvent(deltaX: Float, deltaY: Float)
// 相关生命周期事件
external fun nativeDestroy()
external fun nativePause()
external fun nativeResume()


3D 模型的解析


OpenGL 2.0 引入了管线的概念,从管线的流程来看,在栅格化之后,就变成了一个一个的点,然后通过 Fragment Shader 上色。

所以绘制复杂的 3D 模型,最终也是转成无数的点去渲染。事实上,点可以连成线,线可以连成面,面可以拼成一个完整的物体。

所以,我们需要把 3D 模型转成无数个点坐标才可以渲染。

Assimp(Open Asset Import Library)是一个很强大的开源库,支持把 40 多种格式的 3D 模型文件转成统一的格式,然后再按照再解析这个统一的格式即可。

https://3dtotal.com/,这个网站里也有很多比较简单有意思的3D模型。

Assimp 把模型文件转成了统一的格式,这个格式可以理解为是一颗二叉树,从 Root Node 开始,逐渐发散。假设 Root Node 在心脏的位置,那么就是从心脏遍布到全身。

通过对二叉树进行广度优先遍历,就可以拿到所有节点信息,进而拿到所有点的坐标信息。然后交给 OpenGL 进行渲染。


骨骼动画


3D 模型解析出坐标信息之后,结合纹理信息,就可以得到一个静态的图片。那么怎么做动画呢?

所谓动画,其实是各个点的一系列坐标点的有序变化,人眼看上去就是正常的动画了。

Assimp 解析出的统一格式,大致是一颗二叉树,二叉树的两个顶点之间的线,称为「骨骼」,做动画时,骨骼做仿射变换,带动附近的「肌肉」跟着联动,就像人做运动一样,骨骼带着肉体做运动。

类比骨骼带动肌肉群实现动画,谓之「骨骼动画」。


透视变换 与 Camera 视角变换


3D 效果的最直观的感觉就是「近大远小」。

Camera 视角变换,用来做旋转。

呐,给你画了个姑娘

经过上面一波处理,你有对象了!

情人节快乐!

热 文 推 荐

远程办公:我把会炒的菜,都炒了一遍.....

云蹦迪、云追星、云表白…疫情下的情人节怎么过?

2020年区块链领域最具影响力人物Top 20

我是如何用6个月,从0编程经验变成数据科学家的?

基于角色的访问控制(RBAC)

雷军谈小米10售价:不贵,交个朋友;百度开源首个口罩人脸检测模型;优麒麟18.04.4 LTS发布 | 极客头条


你点的每个“在看”,我都认真当成了喜欢

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存