您的位置:首页 > 其它

软件渲染笔记 03 模型线框

2018-02-16 18:38 204 查看

软件渲染笔记 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;i<model->nfaces();i++)
{
vector<int>face=model->face(i);
for(int j=0;j<face.size();j++)
{
Vec3f vertexFrom= model->vert(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值.

效果图如下:



点击这里下载完整代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: