TIT 计算机图形学 期末课设-青花瓷坛的实体模型

这篇博客介绍了使用双三次贝塞尔曲线和计算机图形学技术,通过C++实现青花瓷坛的实体模型。内容包括原理、相关算法如纹理映射、背面剔除,以及部分代码实现,如位图导入、纹理绑定和ZBuffer算法。项目设计中应用了光照、材质和纹理,以模拟三维效果。
摘要由CSDN通过智能技术生成

TIT 计算机图形学 期末课设-青花瓷坛的实体模型

前言

  • 实验中用到了很多知识点,这里只讲解其中的一部分,仅供参考.详细讲解可以看孔老师的视频课,具体学习程序中的类
  • 参考视频计算机图形学全套算法讲解和C++编码实现(共23讲配套源码)计算机图形学案例视频讲解以及主页相关算法。孔老师是我的代课老师,孔教授有十多年教学经验,视频课很不错,所有的源程序都基于他写的函数,并非小张写的。所有源程序都基于C+编译
  • 参考教材《计算机图形学-理论与实践项目化教程》 孔令德著,大家多多支持哇
  • 实验源码很多,没有传CSDN因为小张认为源码并不是我开的,只是拿老师的程序做了一些东西,拿这个赚积分和马内未免有点!这里直接放了青花瓷源程序。孔老师的视频课讲的很清楚,大家去B站就可以看啦!

一、项目描述

使用双三次贝塞尔曲线绘制青花瓷坛的线框模型,通过增加光照、材质、纹理,实现线框模型变为实体模型,达到模拟三维青花瓷坛的效果

在这里插入图片描述

image-20211222004728058

二、项目设计

1.原理

映射原理: 双三次Bezier曲面的各处都具有了(u,v)值。将纹理uv与曲面uv同时规范化到[0,1]区间内,当查找到曲面纹理时,先将曲面uv放大到和纹理位图一样大小的尺寸,然后获取对应纹理图像上的颜色作为曲面上该点的漫反射率系数

image-20211222004836832

image-20211222004913153

2.背面剔除算法原理:

视矢量与小平面法矢量的点积大于等于零(n·v>=0),cosα>0,表面可见

1.使用四边形网格的顶点计算面矢量并归一化

2.使用四边形网格的第一顶点与视点,计算矢量并归一化

3.计算法矢量与视矢量的点积,如果其值大于等于零,则绘制该网格,否则剔除该网格

3.球体图像纹理映射原理

3.1读入位图

纹理来自于位图,将位图作为资源导入,位图由DIB格式自动转换为DDB格式,每行存储4个字节的颜色数据,将位图转储到一维颜色数组中,就可以根据曲面网格点与位图去查询位图像素点的颜色,并将其作为材质的漫反射率和环境反射率,从而实现了将位图绑定到物体表面上

image-20211215193043390

4.算法步骤

1.将图像纹理加载到资源标签页中,将位图数据保存到一维数组中

2.定义revolution回转类,读入顶点表和表面表,圆环面全部细分为四边形网格

3.将位图绑定到回转体的顶点上

4.根据光源的位置,数量,视点的位置,材质属性,构造三维光照场景

5.使用画家算法,剔除回转体的不可见网格

6.使用三维透视投影算法,将回转体三维多边形投影为屏幕三维四边形

7.根据网格点的法矢量,插值计算小面内每一点的法矢量,将纹理作为该点的材质,调用光照模型计算小面内该点的光强

8.使用定时器改变圆环的转角生成旋转动画

2.相关算法

PhongShader算法: 对顶点的法矢量进行插值,得到小面内每一点的法矢量。对小面内的每一点都调用光照模型计算光强。计算光强需要四个参数,视点位置、当前点三维坐标、当前点法矢量、当前点的材质属性。如果当前点的材质的漫反射率取自一幅图像的相应点,这就为该物体添加了纹理。

向量线性插值计算:

v(t)=(tEnd-t)/(tEnd-tStart)*vStart+(t-tStart)/(tEnd-tStart)*vEnd;

t表示第一个向量的x(y)方向单位向量,tStart表示第一个点的x(y)方向单位向量,tEnd表示第二个点的x(y)方向单位向量,vStart起点的法向量,vEnd表示第二个点的法向量。

计算光强公式:

I=Ie +Id+Is =kaIa+f(d)[KdIpmax(N·L,0)+ksIpmax(N·H)n]

计算物体表面上任意一点P的光强I时,必须确定物体表面的单位矢量L、单位中分矢量H、单位法矢量N以及材质的漫反射率kd。当光源位置和视点位置不变时,光矢量L和中分矢量H是一个定值。影响光强的只有漫反射率kd和单位法矢量N。

Zbuffer算法:通过使用处理深度缓冲器,若当前点的深度值小于缓冲器中的深度值,则说明当前点离视点近,使用SetPixelV函数绘制当前点,否则放弃当前点。

当前像素点的深度值:z(x,y)=-z(x,y)=- A x + B y + D C \frac{Ax+By+D}{C} CAx+By+D,C≠0,C≠0;

A,B,C代表法向量的坐标

3.模型

image-20220103234134907

三、部分代码

1.导入位图,格式为bmp

2.Texture类

class CTexture
{
   
public:
	CTexture(void);
	virtual~CTexture(void);
	void PrepareBitmap(UINT nIDResource);//准备位图
	void DeleteObject(void);//释放位图
public:
	BYTE* image;//存储位图一维数组
	BITMAP bmp;//BITMAP结构体变量
};

CTexture::CTexture(void)//数组初始化为空
{
   
	image = NULL;
}

CTexture::~CTexture(void)
{
   
}

void CTexture::PrepareBitmap(UINT nIDResource)//准备位图
{
   
	CBitmap NewBitmap;//DDB
	NewBitmap.LoadBitmap(nIDResource);//从资源视图中读入位图存储到Newbitmap中
	NewBitmap.GetBitmap(&bmp);//将CBitmap的信息保存到Bitmap结构体中,目的是为了得到图像的高度和宽度
	int nbytesize = bmp.bmWidthBytes * bmp.bmHeight;//计算位图字节数
	image = new BYTE[nbytesize];
	NewBitmap.GetBitmapBits(nbytesize, (LPVOID)image);//将位图数据赋值到一维数组image中
}

void CTexture::DeleteObject(void)//释放位图
{
   
	if(NULL != image)
		delete []image;
}

3.在贝塞尔曲线类中绑定纹理对象

void CBezierPatch::Tessellation(CMesh Mesh)//细分曲面函数
{
   
	double M[4][4];//系数矩阵M
	M[0][0] = -1, M[0][1] = 3,  M[0][2] = -3, M[0][3] = 1;
	M[1][0] = 3,  M[1][1] = -6, M[1][2] = 3,  M[1][3] = 0;
	M[2][0] = -3, M[2][1] = 3,  M[2][2] = 0,  M[2][3] = 0;
	M[3][0] = 1,  M[3][1] = 0,  M[3][2] = 0,  M[3][3]
  • 9
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值