会员: 密码:  免费注册 | 忘记密码 | 会员登录 网页功能: 加入收藏 设为首页 网站搜索  
游戏开发 > 程序设计 > 3D图形
DirectX 3D编程入门教程二 介绍材质和纹理
发表日期:2007-01-24 17:26:20作者: 出处:  

前言:
应几个网友的要求,利用工作之余,写了一篇DirectX 3D(简称D3D)编程入门教程。该教程适用于一些刚刚涉及D3D编程的朋友,读者必须有一定的C++ 和Win32的编程知识。在教程的最后,会给出一个完整的实例,让你显示一个活生生的三位物体。对一些大虾级的高手,这只能使班门弄斧了,同时也非常欢迎爱好D3D编程的朋友和我联系和交流,并提出宝贵意见。
该教程基于DirectX 8.0 Graphics, 一部分内容由DirectX 8.0 SDK 英文文档翻译而来,一部分是自己工作经验的总结,作者对此享有著作权,读者可任意拷贝和传播,但不包含商业的用途,转贴请注明出处。
作者联系方式: jockey8888@sina.com



主要内容:

1. 材质(Material)
1.1 材质基本概念
1.2 在Direct3D中的材质
1.3 在Direct3D中使用材质
2. 纹理(Texture)
2.1 纹理的基本概念以及限制
2.2 在DirectX3D中使用纹理


1. 材质(Material)

1.1 材质基本概念

通俗的讲,材质是指构成现实中物体的材料,它使一个物体看上去更象金属做的,陶瓷做的,还是塑料的。
在现实生活中,当我们看一个铅球,凭眼睛的观察,手的触摸,还有保存在我们头脑里的一些生活的常识,我们很容易判别该球是金属做的,同样看到一只足球,我们也很容易知道他是橡胶做的。
这样就会产生一个问题,对显示屏中虚拟的物体,光凭眼睛我们怎样辨别它使金属的,还是塑料的呢?或者说,在电脑上我们怎样表示一个物体材质属性呢?

1.2 在Direct3D中的材质

在微软Direct3D中, 是用物体对光的反射属性来表达一个物体的材质的,很显然,金属的物体和塑料的物体对光的反射会有不同的反射效果。这样做虽然有时会产生失真,但对于屏幕渲染来说也是足够了。
在D3D中,用下列属性来表示一个物体的材质:

a. 物体对环境光(Ambient Light) 和漫射光(Diffuse Light)是怎样反射的?
b. 是否会产生高亮光( Specular Light)?(一般用来表示具有高反射属性的物体,比如,镜子)
c. 是否具有光的放射光(Emissive Light)属性?(可用来描述灯泡,太阳等光源物体)

并且在D3D中定义了如下的结构,来描述一个物体的材质:

typedef struct _D3DMATERIAL8 {
    D3DCOLORVALUE Diffuse; // 对漫射光的反射
    D3DCOLORVALUE Ambient; // 对环境光的反射
    D3DCOLORVALUE Specular; // 顶点高光
    D3DCOLORVALUE Emissive; // 顶点放射光
    float Power; // 描述顶点高光亮的程度
} D3DMATERIAL8;

1.3 在Direct3D中使用材质

用如下的代码可以设置材质:

HRESULT hr;
D3DMATERIAL8 material;

// Set the RGBA for diffuse reflection.
material.Diffuse.r = 0.5f;
material.Diffuse.g = 0.0f;
material.Diffuse.b = 0.5f;
material.Diffuse.a = 1.0f;

// Set the RGBA for ambient reflection.
material.Ambient.r = 0.5f;
material.Ambient.g = 0.0f;
material.Ambient.b = 0.5f;
material.Ambient.a = 1.0f;

// Set the color and sharpness of specular highlights.
material.Specular.r = 1.0f;
material.Specular.g = 1.0f;
material.Specular.b = 1.0f;
material.Specular.a = 1.0f;
material.Power = 50.0f;

// 设置材质调用该函数
hr = pd3dDev->SetMaterial( &material );
if( FAILED(hr) )
{
    // Code to handle the error goes here.
}


对材质更多的了解,请看D3D8.0 SDK的文档。


2. 纹理(Texture)

2.1 纹理的基本概念以及限制

纹理可以理解为是物体的外表图案。在3D场景中,它极大的增加了物体的真实性。例如,我们可以在显示屏上画上一系列组合的矩形来表示一堵墙,但这样的墙看起来光秃秃的,颜色也不真实。如果我们再在上面加上一些划痕,磨损,苔迹,还有标语,使它看起来更象一堵真实的墙,这就是纹理。
在D3D中,物体的这些外表图案是存储在一些二维的图片中的,纹理也即是指这些二维的图片,它一般采用bmp或 ppm的图片格式。纹理上的每一个像素称为纹理像素(Texel).当然在DirectX 8.0中,它支持很多种的图片格式。

也不是所有的位图都可以用来作纹理的,在DirectX 8.0中,对用来做纹理的位图有一些具体的要求:
a. 位图的尺寸(长和宽)必须是2的幂,例如 1,2,4,8...。
b. 不同的显卡对纹理的最大尺寸有不同的要求,有的支持1204x1204,有的仅支持256x256。对纹理的最小尺寸也有限制,我就有一款显卡,支持的纹理最小尺寸是8x8。
c. 有的显卡不支持不同长宽的纹理位图。


2.2 在DirectX中使用纹理

a. DirectX 8.0 定义了DIRECT3DTEXTURE8接口来管理纹理,声明一个纹理指针我们可用如下语句:

LPDIRECT3DTEXTURE8 lpD3DTexture = NULL;

b. 在DirectX 8.0中,从位图中建立一幅纹理,我们调用D3DX中为我们提供的一个函数,函数原型如下:

HRESULT D3DXCreateTextureFromFileA(
    LPDIRECT3DDEVICE8 pDevice, // 指向D3D设备的指针
    LPCSTR pSrcFile, // 作为纹理的位图文件名
    LPDIRECT3DTEXTURE8* ppTexture // 指向一个纹理地址的指针
);


c. 纹理建立后,我们可用以下函数来设置纹理:

HRESULT SetTexture(
    DWORD Stage, // 纹理的入口索引号,D3D8.0最多支持8幅纹理,所以该值范围是[0,7]
    IDirect3DBaseTexture8* pTexture // 要设置的纹理指针
);

d. 以下是建立和设置纹理的代码实例

HRESULT hr = 0;
LPDIRECT3DTEXTURE8 lpD3DTexture = NULL;
char strTextureFile[] = "tiger.bmp";

// Create the texture
hr = D3DXCreateTextureFromFile( g_pd3dDevice,
                strTextureFile,
                &g_pMeshTextures[i] )
if( FAILED(hr) )
{
    // Code to handle the error goes here.
}

// Set the texture
g_pd3dDevice->SetTexture( 0, lpD3DTexture );

在D3D编程中,纹理毫无疑问是一个非常重要而又复杂的概念。对于纹理,还有很多重要的概念我们没有涉及到,例如,纹理的地址模式,纹理混合,纹理过滤,MipMap纹理等等。建议初学者开始还是不要涉及到这些复杂的概念,等到学习加深后再去看SDK的文档。

下一节讲述网格和X文件格式的问题. (未完待续)
返回顶部】 【打印本页】 【关闭窗口

关于我们 / 给我留言 / 版权举报 / 意见建议 / 网站编程QQ群   
Copyright ©2003- 2024 Lihuasoft.net webmaster(at)lihuasoft.net 加载时间 0.0033