以文本方式查看主题 - 中文XML论坛 - 专业的XML技术讨论区 (http://bbs.xml.org.cn/index.asp) -- 『 C/C++编程思想 』 (http://bbs.xml.org.cn/list.asp?boardid=61) ---- 纹理映射基础(1) (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=69917) |
-- 作者:卷积内核 -- 发布时间:11/28/2008 10:51:00 AM -- 纹理映射基础(1) 为了使渲染的图形看起来更真实,Direct3D提供了在物体表面绘制纹理的功能。一般说来,纹理是表示物体表面细节的一幅或几幅二维图形,也称纹理贴图(texture)。当把纹理按照特定的方式映射到物体表面的时候,能使物体看上去更加真实。当前流行的图形系统中,纹理绘制已经成为一种必不可少的渲染方法。在理解纹理映射时,可以将纹理看作应用程序在物体表面的像素颜色。在真实世界中,纹理表示一个对象的颜色、图案以及触觉特征。但在Direct3D中,纹理只表示对象表面的彩色图案,它不能改变对象的几何形式。更进一步说,它只是一种高强度计算行为。
纹理位图 Direct3D纹理位图是用来表示物体表面图案的二维数组,数组的每一个元素都存储有一个颜色值,称为纹理元素(texel)。经常见到的后缀名为bmp、jpg、tga的图形文件都可以作为纹理位图。
纹理对象 在Direct3D中,纹理是以COM对象的形式存在的,要对物体表面进行纹理映射,首先需要创建纹理对象,创建时需要指定纹理的宽度、高度、格式等属性,然后还需要将图形文件加载到纹理对象中,整个过程比较复杂,为此,Direct3D提供了一个辅助函数D3DXCreateTextureFromFile(),可以直接方便地从磁盘上的图形文件中创建纹理对象,并使用默认设置。如果从文件创建纹理时不想使用各种默认设置,还可以使用另外一个辅助函数D3DXCreateTextureFromFileEx(),该函数也可以直接从磁盘上的图形文件中创建纹理对象,而且还可以指定创建的纹理对象的宽度、高度、格式等。
纹理坐标与纹理元素 纹理相当于一幅位图,在使用时贴到物体表面上。纹理位图是一个二维数组,数组的每一个元素称为纹理元素,它存储有一个颜色值。 纹理元素在表示纹理的数组中的二维下标(即它在位图中的二维坐标)称为纹理坐标。一般以字母(u, v)表示,可以想象成纹理元素所对应的行数和列数,也称实际纹理坐标。假设位图的宽、高分别为w、h,显然 0 ≤ u ≤ w, 0 ≤ v ≤ h 纹理坐标是指纹理空间坐标,即纹理坐标是相对于纹理空间原点而言的。 由于在一个图形显示系统中往往存在多幅不同的纹理,它们的宽、高也不尽相同,用实际纹理坐标表示纹理元素的位置在计算上很难统一,例如在同一个物体表面应用两幅大小不同的纹理。所以经常使用相对纹理坐标(u', v')代替实际纹理坐标(在下文中如无特别说明,纹理坐标就是指相对纹理坐标),u'、v'分别表示u、v所占宽、高的百分比: u' = u/w, v' = v/h 一般情况下,所有的纹理元素相对坐标的地址都在[0.0, 1.0]范围内,当然从技术上讲,可以使用[0.0, 1.0]范围之外的纹理坐标实现特殊效果。 Direct3D将纹理空间中的纹理元素映射到屏幕空间像素的映射过程常常是一个反映射。也就是说,对于屏幕空间的每个像素,计算其中纹理空间中相应的纹理元素的位置,然后采样该点或该点附近的纹理颜色。这个映射过程称为纹理过滤。 为了将纹理映射到物体表面,需要为物体顶点指定纹理坐标。
创建纹理对象 图形显示的纹理大都存储在磁盘图形文件中(诸如.bmp、.tga、.jpg文件),要想使用它们,必须创建Direct3D纹理对象,并载入图形文件内容。 函数IDirect3DDevice9::CreateTexture()用来创建一个Direct3D纹理对象,该函数声明如下: Creates a texture resource. HRESULT CreateTexture( UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle); Remarks
|
-- 作者:卷积内核 -- 发布时间:11/28/2008 10:52:00 AM -- Usages The following table summarizes the available usage options. #define Description D3DUSAGE_DYNAMIC and D3DPOOL_MANAGED are incompatible and should not be used together. See D3DPOOL. Textures can specify D3DUSAGE_DYNAMIC. However, managed textures cannot use D3DUSAGE_DYNAMIC. For more information about dynamic textures, see Using Dynamic Textures. D3DUSAGE_SOFTWAREPROCESSING is used with IDirect3D9::CheckDeviceFormat to find out if a particular texture format can be used as a vertex texture during software vertex processing. If it can, the texture must be created in D3DPOOL_SCRATCH. |
-- 作者:卷积内核 -- 发布时间:11/28/2008 10:53:00 AM -- 纹理映射基础(2) Direct3D纹理对象生成后,纹理对象指针指向的纹理资源指针还没有被有效赋值,如果想要通过磁盘图形文件载入纹理,那么必须将磁盘图形文件的内容载入Direct3D纹理资源,因为不同的文件具有不同的格式,所以为了将文件内容载入到Direct3D纹理资源,就要了解各种图形文件的格式,并针对不同的格式编写不同的代码将文件内容载入到纹理资源中。 从磁盘文件生成并载入纹理相当繁琐,它涉及到各种图形文件的存储格式。幸运的是,Direct3D扩展实用库函数D3DXCreateTextureFromFile()为我们提供了从磁盘图形文件创建纹理并载入纹理内容的快捷方法,该函数声明如下: Creates a texture from a file. HRESULT D3DXCreateTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, LPDIRECT3DTEXTURE9 * ppTexture); D3DERR_NOTAVAILABLED3DERR_OUTOFVIDEOMEMORYD3DERR_INVALIDCALLD3DXERR_INVALIDDATAE_OUTOFMEMORY 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: 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. 设置当前渲染纹理 Direct3D设备接口函数IDirect3DDevice9::SetTexture()将Direct3D纹理与指定的纹理层关联,该函数的声明如下: Assigns a texture to a stage for a device. HRESULT SetTexture( DWORD Sampler, IDirect3DBaseTexture9 * pTexture); Programmable shaders reference textures using the sampler number. The number of samplers available to a programmable shader is dependent on the shader version. For vertex shaders, see Sampler (Direct3D 9 asm-vs). For pixel shaders see Sampler (Direct3D 9 asm-ps). pTexture Remarks
|
-- 作者:卷积内核 -- 发布时间:11/28/2008 10:53:00 AM -- 设置纹理相关状态 纹理相关状态包括纹理过滤方式、纹理寻址模式、纹理阶段混合状态。因为Direct3D 9.0最多支持8层纹理贴图,所以最多存在8个纹理阶段,这些纹理相关状态需要针对每个纹理阶段分别进行设置,用于控制每个阶段纹理的相关操作。
示例程序: #pragma warning(disable : 4127) #define CLASS_NAME "GameApp" #define release_com(p) do { if(p) { (p)->Release(); (p) = NULL; } } while(0) IDirect3D9* g_d3d; struct sCustomVertex #define D3DFVF_CUSTOM_VERTEX (D3DFVF_XYZ | D3DFVF_TEX1) void setup_matrices() // setup view matrix D3DXVECTOR3 eye(0.0f, 0.0f, -10.0f); D3DXMATRIX mat_view; // setup projection matrix D3DXMATRIX mat_proj; bool init_graphics() sCustomVertex vertices[] = }; g_device->CreateVertexBuffer(sizeof(vertices), 0, D3DFVF_CUSTOM_VERTEX, D3DPOOL_MANAGED, &g_vertex_buffer, NULL); void* ptr; g_vertex_buffer->Lock(0, 0, (void**)&ptr, 0); return true; bool init_d3d(HWND hwnd) if(g_d3d == NULL) D3DPRESENT_PARAMETERS d3dpp; d3dpp.Windowed = TRUE; if(FAILED(g_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, setup_matrices(); g_device->SetRenderState(D3DRS_LIGHTING, FALSE); void cleanup() void render() g_device->BeginScene(); g_device->SetTexture(0, g_texture); g_device->SetStreamSource(0, g_vertex_buffer, 0, sizeof(sCustomVertex)); g_device->EndScene(); g_device->Present(NULL, NULL, NULL, NULL); LRESULT WINAPI WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_DESTROY: return DefWindowProc(hwnd, msg, wParam, lParam); int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR, INT) wc.cbSize = sizeof(WNDCLASSEX); if(! RegisterClassEx(&wc)) HWND hwnd = CreateWindow(CLASS_NAME, "Direct3D App", WS_OVERLAPPEDWINDOW, 200, 100, 640, 480, if(hwnd == NULL) if(init_d3d(hwnd)) MSG msg; while(msg.message != WM_QUIT) cleanup(); return 0; |
-- 作者:卷积内核 -- 发布时间:11/28/2008 10:54:00 AM -- 纹理映射基础(3) 当Direct3D渲染一个图元时,必须将它通过坐标变换映射到二维屏幕上。如果图元有纹理,Direct3D就需要用纹理来产生图元的二维渲染图像上每个像素的颜色。对于图元在二维屏幕上图像的每个像素来说,都必须从纹理中获得一个颜色,从纹理中为每个像素获取颜色的过程称为纹理过滤(texture filtering)。 大多数情况下,屏幕显示的图形大小与纹理贴图大小不相同,换句话说,这个纹理将被映射到一个比它大或小的图元的图像上,这样纹理常常会被放大或缩小。对纹理的放大会造成许多像素被映射到同一个纹理元素,图形渲染结果会有色块的感觉。缩小一个纹理意味着一个像素被映射到许多纹理元素,图形看上去会闪烁失真或有锯齿。为了解决这些问题,可以将相关纹理元素的颜色融合到一个像素上,如何将多个纹理元素的颜色融合到一个像素上取决于纹理过滤方式。 Direct3D支持4种纹理过滤方式,分别是:最近点采样(nearest-point sampling)、线性纹理过滤(linear texture filtering)、各向异性纹理过滤(anisotropic texture filtering)和多级渐进纹理过滤(texture filtering with mipmaps)。不同的纹理过滤方式产生的图像效果差别可能很大。 4种纹理过滤方法各有优缺点。例如,线性过滤生成的图像较粗糙,但计算量小。多级渐进纹理过滤的效果通常最好,特别是和各项异性过滤联合使用时效果更好,但是它需要Direct3D提供的内存空间最多,计算量也最大。 纹理采样属性设置函数IDirect3DDevice9::SetSamplerState()可以用来设置纹理过滤方式。该函数的声明如下: Sets the sampler state value. HRESULT SetSamplerState( DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value); 参数Type属于D3DSAMPLERSTATETYPE类型,用来指定对哪种纹理采样属性赋值。 D3DSAMPLERSTATETYPE typedef enum D3DSAMPLERSTATETYPE{ D3DSAMP_ADDRESSU = 1, D3DSAMP_ADDRESSV = 2, D3DSAMP_ADDRESSW = 3, D3DSAMP_BORDERCOLOR = 4, D3DSAMP_MAGFILTER = 5, D3DSAMP_MINFILTER = 6, D3DSAMP_MIPFILTER = 7, D3DSAMP_MIPMAPLODBIAS = 8, D3DSAMP_MAXMIPLEVEL = 9, D3DSAMP_MAXANISOTROPY = 10, D3DSAMP_SRGBTEXTURE = 11, D3DSAMP_ELEMENTINDEX = 12, D3DSAMP_DMAPOFFSET = 13, D3DSAMP_FORCE_DWORD = 0x7fffffff,} D3DSAMPLERSTATETYPE, *LPD3DSAMPLERSTATETYPE; D3DTEXTUREFILTERTYPE typedef enum D3DTEXTUREFILTERTYPE{ D3DTEXF_NONE = 0, D3DTEXF_POINT = 1, D3DTEXF_LINEAR = 2, D3DTEXF_ANISOTROPIC = 3, D3DTEXF_PYRAMIDALQUAD = 6, D3DTEXF_GAUSSIANQUAD = 7, D3DTEXF_CONVOLUTIONMONO = 8, D3DTEXF_FORCE_DWORD = 0x7fffffff,} D3DTEXTUREFILTERTYPE, *LPD3DTEXTUREFILTERTYPE; D3DTEXF_FORCE_DWORD Set a texture stage's magnification filter by calling IDirect3DDevice9::SetSamplerState with the D3DSAMP_MAGFILTER value as the second parameter and one member of this enumeration as the third parameter. Set a texture stage's minification filter by calling IDirect3DDevice9::SetSamplerState with the D3DSAMP_MINFILTER value as the second parameter and one member of this enumeration as the third parameter. Set the texture filter to use between-mipmap levels by calling IDirect3DDevice9::SetSamplerState with the D3DSAMP_MIPFILTER value as the second parameter and one member of this enumeration as the third parameter. Not all valid filtering modes for a device will apply to volume maps. In general, D3DTEXF_POINT and D3DTEXF_LINEAR magnification filters will be supported for volume maps. If D3DPTEXTURECAPS_MIPVOLUMEMAP is set, then the D3DTEXF_POINT mipmap filter and D3DTEXF_POINT and D3DTEXF_LINEAR minification filters will be supported for volume maps. The device may or may not support the D3DTEXF_LINEAR mipmap filter for volume maps. Devices that support anisotropic filtering for 2D maps do not necessarily support anisotropic filtering for volume maps. However, applications that enable anisotropic filtering will receive the best available filtering (probably linear) if anisotropic filtering is not supported. Unsigned Formats Unsigned format flags Value Format |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
109.375ms |