计算机图形学常用算法实现11 扫描线z-buffer算法

本文介绍了如何实现计算机图形学中的扫描线Z-Buffer算法,包括创建数据结构、读取obj文件、处理坐标、设置颜色、绘图函数及主函数的详细步骤。通过该算法,可以对3D图形进行精确的二维投影,并处理深度信息,最终得到具有立体感的图像效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

图形学作业要到deadline了,赶紧写一个
这个算法比之前的算法的工作量都要大,但是只要思路清晰,也不是很难。
1.创建各种需要的数据结构类

//点的类
class Point
{
   
public:
	float x;
	float y;
	float z;
	Point();
	~Point();
};
//y表
class YTable
{
   
public:
	int m_IndexOfPolygon;
	float m_Ymax;
	YTable * next;
	YTable();
	YTable(int IndexOfPolygon,float Ymax);
	~YTable();
};
//边表
class ET
{
   
public:
	float m_Ymax;
	float m_Yminx;
	float m_Yminz;
	float m_DeltaX;
	ET *next;
	ET();
	~ET();
};
//活性边对表
class AET
{
   
public:
	float m_XL;
	float m_DeltaXL;
	float m_Lmax;
	float m_XR;
	float m_DeltaXR;
	float m_Rmax;
	float m_ZL;
	int m_PolygonIndex;
	float m_DeltaZA;
	float m_DettaZB;
	AET *next;
	AET();
	~AET();
};

2.定义我们的扫描线算法的主类

class ScanLine
{
   
public:
	Point pt[MAX_POINT];//存储所有点的信息
	int polygon[MAX_POINT][3];//我们的图形是由三角形组成的,保存三角形的顶点编号
	int currentPoint;//当前的点的数量
	int currentPolygon;//当前三角形的数量
	int m_Ymin;//最大的y值
	int m_Ymax;//最小的y值
	int m_Map[MAX_WIDTH][MAX_LENGTH];//帧缓存
	int m_ZB[MAX_WIDTH];//深度缓存
	Point color[MAX_POINT];
	ScanLine();
	~ScanLine();
	YTable *m_YTable[MAX_WIDTH];//多边形y表
	YTable *m_APT;//活化多边形表
	ET *m_ET[MAX_POINT][MAX_LENGTH];//边表
	AET *m_AET;//活化边对表
	void Draw();
	void InitData();//初始化信息,在这里读取我们的点和多边形
	void LoadObj();

private:
	void CreatYTable();//创建y表
	void FindYminAndYmax();//设置m_Ymin和m_Ymax的值
	void CalculateNormal(int cntOfPolygon,float normal[]);
};

3.接下来就是按顺序执行我们的算法流程,首先读取obj文件到点和多边形里面
这里我的obj的读法比较简单,只考虑了点和面,发现和纹理等我都没有考虑。
值得注意的是,我们需要的坐标范围是1024*768
因此,当obj文件中的文件坐标过于小或者存在负的时候,需要自行对坐标进行方法以及平移处理
下面是放大100倍的情况,用于绘制后面的球,完整代码是不放大的情况,用来绘制海豚

if (cnt == 0)
	pt[currentPoint].x = (atof(strTemp))*100+1024/2;
else if (cnt == 1)
	pt[currentPoint].y = (atof(strTemp))*100+768/2;
void ScanLine::LoadObj()
{
   
	FILE *fp;
	int index;
	printf("请输入绘制的图形序号1:茶壶 2:海豚 3:球 4:花环\n");
	scanf("%d", &index);
	if(index == 1)
		fp = fopen("teapot.obj","r");
	else if(index ==2)
		fp = fopen("dolphins.obj", "r");
	else if (index == 3)
		fp = fopen("sphere.obj", "r");
	else if (index == 4)
		fp = fopen("torus.obj", "r");
	char str[100];
	char strTemp[100];
	int cnt;
	int indexOfstrTemp;
	if (!fp)
		printf("ERROR");
	else
	{
   
		while (fgets(str, 999, fp) != NULL)
		{
   
			cnt = 0;
			indexOfstrTemp = 0;
			if (str[0] == 'v'&&str[1]!='n'&&str[1]!='t')
			{
   
				int i = 2;
				if (str[i] == ' ')
					i = 3;
				for (; ;i++)
					if (str[i] == ' '|| str[i]=='\0')
					{
   
						strTemp[indexOfstrTemp] = '\0';
						indexOfstrTemp = 0;
						if (cnt == 0)
							pt[currentPoint].x = (atof(strTemp))+1024/2;
						else if (cnt == 1)
							pt[currentPoint].y = (atof(strTemp))+768/2;
						else
						{
   
							pt[currentPoint].z = atof(strTemp);
							currentPoint++;
						}
						cnt = (cnt + 1) % 3;		
						if (str
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值