龙书笔记(5)

今天说下颜色和光照...

一、颜色


1.颜色表示: RGB数据可用2种不同的结构表示:

(1) D3DCOLOR

		//eg:
		 D3DCOLOR brightRed = D3DCOLOR_ARGB(255, 255, 0, 0);		//四个参数的顺序是(Alpha,r,g,b)

(2)D3DCOLORVALUE/D3DXCOLOR,后者更为方便(是对象,前者是结构),因为他提供了很多操作符,而且由于和前者的类型都一致,所以可以直接类型转换。

		//eg:
		 D3DXCOLOR WHITE( D3DCOLOR_XRGB(255,255,255) );	//三个参数的顺序是(r,g,b)
		 D3DXCOLOR redAmbient(1.0f, 0.0f, 0.0f, 1.0f);	//四个参数的顺序是(r,g,b,Alpha)

上面这两种结构仅仅指出了声明形式,对他们的具体设定还要用D3DCOLOR_ARGB和D3DCOLOR_XRGB,或者直接D3DXCOLOR(,,,)也行,还有0xffffffff这种形式也是描述颜色的


2.顶点颜色: 

图元的颜色由构成该图元的顶点的颜色决定,所以还要为顶点数据结构添加一个表示颜色的数据成员

	struct ColorVertex
	{
		ColorVertex(){}
		ColorVertex(float x, float y, float z, D3DCOLOR c)
		{
			_x = x;	 _y = y;  _z = z;  _color = c;
		}

		float _x, _y, _z;
		D3DCOLOR _color;

		static const DWORD FVF;
	};
	const DWORD ColorVertex::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;

3.着色: 

在光栅化的过程中,需要对多边形进行着色,着色规定了利用顶点的颜色来计算构成图元的像素的颜色
2种着色方式: 平面着色和Gouraud着色(也称为平滑着色), 
平面着色: 每个图元的每个像素都被一致地赋予该图元的 第一个 顶点指定的颜色,也就是说其他顶点即使给了颜色,也要被忽略,这种着色容易出现“块状”
Gouraud着色: 图元中各像素的颜色值由 各顶点的颜色 经 线性插值 得到
在Direct3D中,着色模式由SetRenderState函数控制:
		device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);//平面着色
		device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);//Gouraud着色


4.着色实例:

在开始绘制之前先设置清楚着色模式
		D3DXMatrixTranslation(&WorldMatrix, -1.25f, 0.0f, 0.0f);
		Device->SetTransform(D3DTS_WORLD, &WorldMatrix);

		Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);

		Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
		//其余部分略过...
		//注:显示颜色其实很简单,就是调用一个着色的状态而已,但是还需要事先为每个顶点设置好颜色


请注意,下面两行代码并没有出现,
		Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);	//设置线框模式的时候就不是对这个面着色了,是只对边着色。	
		Device->SetRenderState(D3DRS_LIGHTING, false);		//由于我们自己设置了颜色,所以不需要光照给予颜色。



二、光照

使用光照时,无需自行指定顶点的颜色值,因为光本来就是有颜色的


1.光照的组成: 

环境光(ambient):这种光经其他表面反射到物体表面,并照亮整个场景
漫射光(diffuse):无论从哪个方位观察,表面的亮度均相同
镜面光(specular):模拟物体上的高光点

镜面光的计算量更大,默认状态下是关闭的,若想启用,可借助绘制状态: 

		SetRenderState(D3DRS_SPECULARENABLE, true);

描述光的颜色:用D3DCOLORVAlUE或D3DXCOLOR,

		//eg:
		D3DXCOLOR redAmbient(1.0f, 0.0f, 0.0f, 1.0f);//描述光线的颜色时,Alpha中的值都将被忽略
		D3DXCOLOR blueDiffuse(0.0f, 0.0f, 1.0f, 1.0f);


2.材质:定义物体表面对各种颜色光的反射比例

Direct3D提供了D3DMATERIAL9 来创建材质。(可以对他的具体属性填充值)
		//eg:
		D3DMATERIAL9 red;
		::ZeroMemory(&red, sizeof(red));//先清空内存
		red.Diffuse = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f);
		red.Ambient = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f);
		red.Specular = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f);
		red.Emissive = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);//不增加自身的亮度
		red.Power = 5.0f;//提高镜面高光点的锐度


创建材质完了以后就要使用他了,顶点的结构中是不含材质属性的,但我们又必须对材质进行设定,所以有这样的解决办法: 
		IDirect3DDevice9::SetMaterial(const D3DMATERIAL9 * pMaterial);	
		//eg:
		D3DMATERIAL9 blueM;
		Device->SetMaterial(&blueM);
		Device->DrawPrimitive(...);


3.顶点法线
设置顶点法线的目的:确定光线到达平面的入射角。
为了求出顶点v的法向量vn,需要求出共享该点的所有三角形面的法向量,vn可由这些法向量取均值得到。

还要注意,变换后的向量通常不是标准化的,所以还需要:

	SetRenderState(D3DRS_NORMALIZENORMALS,true);


4.光源

Direct3D支持3种光:
点光源(point)
方向光(Directional)
聚光灯(Spot)
Direct中提供了创建光源的类型:D3DLIGHT9
与D3DMATERIAL9类似,创建好后,还需要对具体的属性值填充
	//eg:
	D3DLIGHT9 light;
	light.Type = D3DLIGHT_DIRECTIONAL;
	light.Ambient = WHITE * 0.4f;//WHITE为已经建立好的D3DXCOLOR全局变量
	light.Diffuse = HWITE;
	light.Specular = WHITE * 0.6f;
	light.Direction = dir;//D3DXVECTOR3 dir(1.0f, 0.0f, 0.0f);


当D3DLIGHT9实例初始化完毕之后,要对所使用的光源注册:Device->SetLight(0, &light);

注册成功后,便可以对开关进行控制:Device->LightEnable(0, true);


5.例程分析
Display里面重要的部分:
	for(int i = 0; i < 4; i++)//书上的例子里面绘制了4个模型
	{
		Device->SetMaterial(&Mtrls[i]);
		Device->SetTransform(D3DTS_WORLD, &Worlds[i]);
		Objects[i]->DrawSubset(0);
	} 
	//材质和世界位置对于不同的模型是不一样的(纹理也是,后面会说到),所以要分开设定,而灯光是“全局的”,所以在Setup里面先设置好了

Setup的主要改变如下:

	Device->SetRenderState(D3DRS_LIGHTING, true);//开启灯光
	//创建顶点缓存并设置,省略...
	//创建D3DMATERIAL9对象
	D3DMATERIAL9 mtrl;
	//设置D3DMATERIAL9对象
	mtrl.Ambient = d3d::WHITE; 
	mtrl.Diffuse = d3d::WHITE;
	mtrl.Specular = d3d::WHITE;
	mtrl.Emissive = d3d::WHITE;
	mtrl.Power = 5.0f;
	//启用刚才设置好的材质
	Device->SetMaterial(&mtrl);
	 //创建D3DLIGHT9对象
	D3DLIGHT9 dir;
	//设置D3DLIGHT9对象
	::ZeroMemory(&dir, sizeof(dir));
	dir.Type = D3DLIGHT_DIRECTIONAL;
	dir.Diffuse = d3d::WHITE;
	dir.Specular = d3d::WHITE;
	dor.Ambient = d3d::WHITE;
	dir.Direction = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
	//注册Light对象并打开灯的开关
	Device->SetLight(0,&dir);
	Device->LightEnable(0, true);

	Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);//规范化所有顶点法向量
	Device->SetRenderState(D3DRS_SPECULARENABLE, true);//启用镜面光
	//设置观察矩阵和投影矩阵,省略...

:注1:如果D3DRS_LIGHTING为true,却没有设定某种有颜色的灯光,就会出现全部黑色的情况哦...

注2:这个例子只使用了D3DLIGHT_DIRECTIONAL类型的光,也就是方向光,书中还有point光和spot光的例子...


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的高校科研信息管理系统实现了操作日志管理、字典管理、反馈管理、公告管理、科研成果管理、科研项目管理、通知管理、学术活动管理、学院部门管理、科研人员管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让高校科研信息管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值