文档章节

D3D中的纹理映射(1)

rise-worlds
 rise-worlds
发布于 2016/06/20 13:35
字数 1770
阅读 4
收藏 0

纹理映射是一种允许我们为三角形赋予图象数据的技术;这让我们能够更细腻更真实地表现我们的场景。例如,我们能够创建一个立方体并且通过对它的每个面创建一个纹理来把它变成一个木箱(如图6.1)。

在Direct3D中一个纹理是通过IDirect3DTexture9接口来表现的。一个纹理是一个类似像素矩阵的表面它能够被映射到三角形上。

6.1 纹理坐标

Direct3D使用一个纹理坐标系统,它是由用水平方向的u轴和竖直方向v轴构成。由u,v坐标决定纹理上的元素,它被叫做texel。注意v轴是向下的(如图6.2)。

同样,注意规格化的坐标间隔,[0,1],它被使用是因为它给Direct3D一个固定的范围用于在不同尺寸的纹理上工作。

对每一个3D三角形,我们都希望在给它贴图的纹理上定义一个用相应的三角形。(如图6.3)。

我们再一次修改原来的顶点结构,添加一个用于在纹理上定位的纹理坐标。

struct Vertex

{

       float _x, _y, _z;

       float _nx, _ny, _nz;

       float _u, _v; // texture coordinates

       static const DWORD FVF;

};

const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;

我们在顶点格式中添加了一个D3DFVF_TEX1,它是说我们的顶点结构中包含了一个纹理坐标。

现在每个三角形都通过顶点的三个对象来建立,同时也通过纹理坐标定义了一个相应的纹理三角形。

6.2创建并赋予材质

纹理数据通常是从存储在磁盘中的图片文件中读取的,且被读进IDirect3DTexture9对象中。我们能够使用下面的D3DX函数完成这项工作:

Creates a texture from a file.

HRESULT D3DXCreateTextureFromFile(
LPDIRECT3DDEVICE9 pDevice,
LPCTSTR pSrcFile,
LPDIRECT3DTEXTURE9 * ppTexture
);
Parameters
pDevice
[in] Pointer to an IDirect3DDevice9 interface, representing the device to be associated with the texture.
pSrcFile
[in] Pointer to a string that specifies the filename. If the compiler settings require Unicode, the data type LPCTSTR resolves to LPCWSTR. Otherwise, the string data type resolves to LPCSTR. See Remarks.
ppTexture
[out] Address of a pointer to an IDirect3DTexture9 interface, representing the created texture object.
Return Values

If the function succeeds, the return value is D3D_OK. If the function fails, the return value can be one of the following:

D3DERR_NOTAVAILABLED3DERR_OUTOFVIDEOMEMORYD3DERR_INVALIDCALLD3DXERR_INVALIDDATAE_OUTOFMEMORY

Remarks

The compiler setting also determines the function version. If Unicode is defined, the function call resolves to D3DXCreateTextureFromFileW. Otherwise, the function call resolves to D3DXCreateTextureFromFileA because ANSI strings are being used.

This function supports the following file formats: .bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, and .tga. See D3DXIMAGE_FILEFORMAT.

The function is equivalent to D3DXCreateTextureFromFileEx(pDevice, pSrcFile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, ppTexture).

Mipmapped textures automatically have each level filled with the loaded texture.

When loading images into mipmapped textures, some devices are unable to go to a 1x1 image and this function will fail. If this happens, the images need to be loaded manually.

Note that a resource created with this function will be placed in the memory class denoted by D3DPOOL_MANAGED.

Filtering is automatically applied to a texture created using this method. The filtering is equivalent to D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER in D3DX_FILTER.

For the best performance when using D3DXCreateTextureFromFile:

  1. Doing image scaling and format conversion at load time can be slow. Store images in the format and resolution they will be used. If the target hardware requires power of two dimensions, create and store images using power of two dimensions.
  2. Consider using DirectDraw surface (DDS) files. Because DDS files can be used to represent any Direct3D 9 texture format, they are very easy for D3DX to read. Also, they can store mipmaps, so any mipmap-generation algorithms can be used to author the images.

这个函数能够读取下面图片格式中的任意一种:BMP,DDS,DIB,JPG,PNG,TGA。

例如,用一个名为stonewall.bmp的图片创建一个纹理,我们将按照下面的例子来写:

IDirect3Dtexture9* _stonewall;

D3DXCreateTextureFromFile(_device, "stonewall.bmp", &_stonewall);

设置当前纹理,我们使用下面的方法:

Assigns a texture to a stage for a device.

HRESULT SetTexture(
DWORD Sampler,
IDirect3DBaseTexture9 * pTexture
);
Parameters
Sampler

Zero based sampler number. Textures are bound to samplers; samplers define sampling state such as the filtering mode and the address wrapping mode. Textures are referenced differently by the programmable and the fixed function pipeline:

  • Programmable shaders reference textures using the sampler number. The number of samplers available to a programmable shader is dependent on the shader version. .
  • The fixed function pipeline on the other hand, references textures by texture stage number. The maximum number of samplers is determined from two caps: MaxSimultaneousTextures and MaxTextureBlendStages of the D3DCAPS9 structure.
[in] There are two other special cases for stage/sampler numbers.
  • A special number called D3DDMAPSAMPLER is used for Displacement Mapping (Direct3D 9).
  • A programmable vertex shader uses a special number defined by a D3DVERTEXTEXTURESAMPLER when accessing Vertex Textures in vs_3_0 (Direct3D 9).

pTexture
[in] Pointer to an IDirect3DBaseTexture9 interface, representing the texture being set.
Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be D3DERR_INVALIDCALL.

Remarks

IDirect3DDevice9::SetTexture is not allowed if the texture is created with a pool type of D3DPOOL_SCRATCH. IDirect3DDevice9::SetTexture is not allowed with a pool type of D3DPOOL_SYSTEMMEM texture unless DevCaps is set with D3DDEVCAPS_TEXTURESYSTEMMEMORY.

例子:

Device->SetTexture(0, _stonewall);

注意:在Direct3D中,你能够设置八个纹理,它们能够组合起来创建更多细节的图象。这又被叫做多重纹理。

为了销毁一个纹理,我们设置pTexture为0。例如,假如不想用一个纹理来渲染物体,那么我们就这样写:

Device->SetTexture(0, 0);

renderObjectWithoutTexture();

假如场景中有使用不同纹理的三角形,我们就必须添加与下面类似的一些代码:

Device->SetTexture(0, _tex0);

drawTrisUsingTex0();

Device->SetTexture(0, _tex1);

drawTrisUsingTex1();

6.3过滤器

       就象以前提及的,纹理被映射到屏幕中的三角形上。通常纹理三角形和屏幕三角形是不一样大的。当纹理三角形比屏幕三角形小时,纹理三角形会被适当放大。当纹理三角形比屏幕三角形大时,纹理三角形会被适当缩小。这两种情况,变形都将会出现。过滤(Filtering)是一种Direct3D用它来帮助这些变形变的平滑的技术。

       Direct3D提供了三种不同的过滤器;每种都提供了一个不同的品质级别。越好的品质越慢,因此你必须在品质与速度之间取得一个平衡。纹理过滤器是用IDirect3DDevice9::SetSamplerState方法来设置的。

Sets the sampler state value.

HRESULT SetSamplerState(
DWORD Sampler,
D3DSAMPLERSTATETYPE Type,
DWORD Value
);
Parameters
Sampler
[in] The sampler stage index.
Type
[in] This parameter can be any member of the D3DSAMPLERSTATETYPE enumerated type.
Value
[in] State value to set. The meaning of this value is determined by the Type parameter.
Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be D3DERR_INVALIDCALL.

  • Nearest point sampling——这是默认的过滤方法且返回最差的效果,但是它的计算是最快的。下面的代码就是设置Nearest point sampling作为缩小放大的过滤器:

Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);

Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);

  • Linear filtering——这种过滤产生还算比较好的效果,在今天的硬件上处理它还是非常快的。它是被推荐使用的。下面的代码就是设置Linear filtering作为缩小放大的过滤器。

Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

  • Anisotropic filtering——这种过滤产生最好的效果,但是处理时间也是最长的。下面的代码就是设置Anisotropic filtering作为缩小放大的过滤器。

Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC);

Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);

当使用Anisotropic filtering时,我们必须设置D3DSAMP_MAXANISOTROPY等级,它决定处理的质量。该值越高处理的效果越好。检查D3DCAPS9结构确认你的显卡是否支持此功能。下面的代码设置该值为4:

Device->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 4);

本文转载自:http://www.cnblogs.com/flying_bat/archive/2008/03/20/1115370.html

rise-worlds

rise-worlds

粉丝 3
博文 1755
码字总数 0
作品 0
深圳
程序员
私信 提问
Nebula3绘制2D纹理

上次已经绘制过基本图元了, 这次只不过要贴张图而已..... 本来我想用Graphics的Model渲染流程来做, 不过这一层太高级了, 都是什么场景管理资源映射之类的 做低级的事情, 就要用低级的API嘛 ...

长平狐
2012/11/12
87
0
SDL2源代码分析6:复制到渲染器(SDL_RenderCopy())

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leixiaohua1020/article/details/40895593 ===================================================== SDL源代码......

雷霄骅
2014/11/08
0
0
HLSL 研究学习之五章六节

注:所有代码均由红孩儿编写或以Microsoft DX9 SDK Sample 代码修改而成,转载请注明. (5_6)3D三角形双纹理(外部设纹理,不用PS)) hlsl.fx: //(5_6)3D三角形双纹理(外部设纹理,不用PS)) // ---...

长平狐
2013/03/19
139
0
HLSL 研究学习之六章六节

HLSL 研究学习之六章六节 注:所有代码均由红孩儿编写或以Microsoft DX9 SDK Sample 代码修改而成,转载请注明. (6_6)3D三角形双纹理与色彩混合(fx中单一色,不用PS) hlsl.fx: // -------------...

长平狐
2013/03/19
36
0
HLSL 研究学习之六章六节

HLSL 研究学习之六章六节 注:所有代码均由红孩儿编写或以Microsoft DX9 SDK Sample 代码修改而成,转载请注明. (6_6)3D三角形双纹理与色彩混合(fx中单一色,不用PS) hlsl.fx: // -------------...

长平狐
2012/11/19
27
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 如果是个帅小伙你愿意和他出去吗

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 小小编辑推荐:《Ghost 》游戏《死亡搁浅》原声 《Ghost 》游戏(《死亡搁浅》原声) - Au/Ra / Alan Walker 手机党少年们想听歌,请使劲儿戳...

小小编辑
今天
117
5
java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
16
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部