Z buffer这个算法比较简单,基本就照教材上写的,省去了活化多边形链表,感觉没必要。就核心代码,有位师兄用一个晚上就写好了,我比较挫用了一天时间。为了添加一些一般3D SDK(e.g. D3D OpenGL)的简单绘制功能,如局部光照模型、逐像素光照计算(Per Pixel Lighting)等,重新整理了程序架构和算法。
主要功能
- obj文件载入,只用到顶点位置和法向量信息,没有法向的根据模型计算法向,取差角小于90度的邻面共点平均。
- Gouraud和Phong绘制模型,即对颜色的双线性插值(Gouraud Shading or Per Vertex Shading)和对法向量的双线性插值(Phong Shading or Per Pixel Shading)。
- 光照计算,Phong光照模型,已实现点光源和方向光。
- 正交投影(Orthogonal Projection)和透视投影(Perspective Projection)。
数据结构是仿D3D的,接口是仿OpenGL的,依照OpenCV代码学用template,界面是Qt的,没有使用第三方3D库。
class CScanLine
{
public:
CScanLine(int w, int h, QImage *img);
void setRenderTarget(int w, int h, QImage *img);
// start create target
void begin(TargetType type);
void end();
// 数据输入
void vertex3d(double x, double y, double z);
void color3f(float r, float g, float b);
// 清空缓存
void clear(int target, const Color4u & c = Color4u(0,0,0,255), double depth = 1.0);
// 相机相关, facade design model
void lookAt(const Vec3d & eye, const Vec3d & at, const Vec3d & up);
void perspective(double fovy, double aspect, double zNear, double zFar);
void frustum(double left, double right, double bottom, double top, double near, double far);
void ortho(double left, double right, double bottom, double top, double near, double far);
void setRenderState(int state, int val);
};
存在问题
多边形边沿部分有锯齿,主要是因为相邻多边形在这里深度都一样,反复覆盖。
截图
PREVIOUSCMakefile for OGRE