软件渲染笔记 03 模型线框

2019-04-14 08:16发布

软件渲染笔记 03 模型线框

在上篇文章中,我们已经掌握了如何画线. 这次我们将基于画线函数来画模型线框.

伪代码

不同格式的模型文件,数据多多少少都有些不同.我们这里不考虑模型的存储方式,先以直观感受来写伪代码. for face in facesOfModel: for i to numOfVerticesInFace: draw(vertexi,(vertexi+1)%numOfVerticesInFace) 简单解释下上述伪码的含义:我们首先遍历模型中所有的面.然后遍历模型中的点,把相邻的点都连成线.

waveobj格式

完整的waveobj格式描述可以看waveobj wiki.
由于我们只绘制线框,所以只看对我们有用的信息.

关于面:

有三种表达面的方式:
1. f v/vt
2. f v//vn
3. f v/vt/vn 其中,f是面的意思.v是顶点坐标索引.vt是纹理坐标索引.vn是顶点法向量索引.

关于顶点:

顶点的表示方式为:
v x y z (w) 其中,w可以省略. 到此为止,需要画模型线框的数据格式我们已经掌握.

源码分析

首先,按照上述wavefront obj的格式说明来解析文件读入内存.然后,直接翻译伪码即可. 代码如下: Model *model= new Model("model/african_head.obj"); for(int i=0;infaces();i++) { vector<int>face=model->face(i); for(int j=0;jvert(face[j]); Vec3f vertexTo=model->vert(face[(j+1)%face.size()]); line(image,green, (1+vertexFrom.x)*0.5*CANVAS_WIDTH, (1+vertexFrom.y)*0.5*CANVAS_HEIGHT, (1+vertexTo.x)*0.5*CANVAS_WIDTH, (1+vertexTo.y)*0.5*CANVAS_HEIGHT); } } 需要额外注意的是,代码里的顶点坐标范围为[-1,1].所以乘以了CANVAS尺寸的一半.默认原点为左下角,所以加上了半屏的偏移值.忽略z值. 效果图如下: african head 点击这里下载完整代码