文档章节

D3D中的纹理映射(2)

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

6.4 Mipmaps

就象6.3节所说的,在屏幕上的三角形和纹理三角形通常是不一样大的。为了使这个大小差异变小,我们为纹理创建mipmaps链。也就是说将一个纹理创建成连续的变小的纹理,但是对它们等级进行定制过滤,因此对我们来说保存细节是很重要的(如图6.4)。

6.4.1 Mipmaps过滤器

       mipmap过滤器是被用来控制Direct3D使用mipmaps的。设置mipmap过滤器,你可以这样写:

Device->SetSamplerState(0, D3DSAMP_MIPFILTER, Filter);

在Filter处你能用下面三个选项中的一个:

D3DTEXF_NONE——不使用mipmap。

D3DTEXF_POINT——通过使用这个过滤器,Direct3D将选择与屏幕三角形大小最接近的mipmap等级。一旦等级选定了,Direct3D就将按照指定的过滤器进行缩小和放大过滤。

D3DTEXF_LINEAR­­——通过使用这个过滤器,Direct3D将选择两个最接近的mipmap等级,缩小和放大过滤每个等级,然后线性联合计算它们两个等级来得到最终的颜色值。

6.5 寻址模式

       以前,我们规定纹理坐标必须指定在[0,1]之间。从技术上来说这是不正确的;他们能够超出这个范围。纹理坐标也可以在[0,1]的范围之外,它通过Direct3D的寻址模式来定义。这里有四种寻址模式:环绕纹理寻址模式、边框颜色纹理寻址模式、截取纹理寻址模式、镜像纹理寻址模式,这里分别给出了它们的示意图6.5,6.6,6.7,6.8。

在这些图片中,纹理坐标通过(0,0)(0,3)(3,0)(3,3)顶点来定义。在u轴和v轴上方块又被分成子块放进3×3的矩阵中。假如,你想让纹理按5×5的方格来平铺,你就应该指定环绕纹理寻址模式并且纹理坐标应该设置为(0,0)(0,5)(5,0)(5,5)。

Sampler states define texture sampling operations such as texture addressing and texture filtering. Some sampler states set-up vertex processing, and some set-up pixel processing. Sampler states can be saved and restored using stateblocks (see State Blocks Save and Restore State (Direct3D 9)).

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;
Constants
D3DSAMP_ADDRESSU
Texture-address mode for the u coordinate. The default is D3DTADDRESS_WRAP. For more information, see D3DTEXTUREADDRESS.
D3DSAMP_ADDRESSV
Texture-address mode for the v coordinate. The default is D3DTADDRESS_WRAP. For more information, see D3DTEXTUREADDRESS.
D3DSAMP_ADDRESSW
Texture-address mode for the w coordinate. The default is D3DTADDRESS_WRAP. For more information, see D3DTEXTUREADDRESS.
D3DSAMP_BORDERCOLOR
Border color or type D3DCOLOR. The default color is 0x00000000.
D3DSAMP_MAGFILTER
Magnification filter of type D3DTEXTUREFILTERTYPE. The default value is D3DTEXF_POINT.
D3DSAMP_MINFILTER
Minification filter of type D3DTEXTUREFILTERTYPE. The default value is D3DTEXF_POINT.
D3DSAMP_MIPFILTER
Mipmap filter to use during minification. See D3DTEXTUREFILTERTYPE. The default value is D3DTEXF_NONE.
D3DSAMP_MIPMAPLODBIAS
Mipmap level-of-detail bias. The default value is zero.
D3DSAMP_MAXMIPLEVEL
level-of-detail index of largest map to use. Values range from 0 to (n - 1) where 0 is the largest. The default value is zero.
D3DSAMP_MAXANISOTROPY
DWORD maximum anisotropy. The default value is 1.
D3DSAMP_SRGBTEXTURE
Gamma correction value. The default value is 0, which means gamma is 1.0 and no correction is required. Otherwise, this value means that the sampler should assume gamma of 2.2 on the content and convert it to linear (gamma 1.0) before presenting it to the pixel shader.
D3DSAMP_ELEMENTINDEX
When a multielement texture is assigned to the sampler, this indicates which element index to use. The default value is 0.
D3DSAMP_DMAPOFFSET
Vertex offset in the presampled displacement map. This is a constant used by the tessellator, its default value is 0.
D3DSAMP_FORCE_DWORD
Forces this enumeration to compile to 32 bits in size. Without this value, some compilers would allow this enumeration to compile to a size other than 32 bits. This value is not used.

       下面的代码片段列举的是怎样设置这四种寻址模式:

// set wrap address mode
if( ::GetAsyncKeyState('W') & 0x8000f )
{
       Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
       Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
}
// set border color address mode
if( ::GetAsyncKeyState('B') & 0x8000f )
{
       Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
       Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
       Device->SetSamplerState(0, D3DSAMP_BORDERCOLOR, 0x000000ff);
}
// set clamp address mode
if( ::GetAsyncKeyState('C') & 0x8000f )
{
       Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
       Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
}
// set mirror address mode
if( ::GetAsyncKeyState('M') & 0x8000f )
{
       Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
       Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
}

6.6实例程序:有纹理的方块

       这个例子演示怎样为方块加上纹理以及设置一个纹理过滤器(如图6.9)。假如你的显卡支持,通过D3DXCreateTextureFromFile函数一个mipmap链将被自动创建。

   图6.9

为一个场景增加纹理的必要步骤是:

1. 构造物体的顶点并指定纹理坐标。

2. 用D3DXCreateTextureFromFile函数读取一个纹理到IDirect3DTexture9接口中。

3. 设置缩小倍数,放大倍数以及mipmap过滤器。

4. 在你绘制一个物体前,用IDirect3DDevice9::SetTexture设置与物体关联的纹理。

源程序:

/**************************************************************************************
  Renders a textured quad.  Demonstrates creating a texture, setting texture filters,
  enabling a texture, and texture coordinates.  
**************************************************************************************/
#include "d3dUtility.h"
#pragma warning(disable : 4100)
const int WIDTH  = 640;
const int HEIGHT = 480;
IDirect3DDevice9*        g_d3d_device;
IDirect3DVertexBuffer9* g_quad_vb;
IDirect3DTexture9*        g_d3d_texture;
class cTextureVertex
{
public:
float m_x,  m_y,  m_z;
float m_nx, m_ny, m_nz;
float m_u, m_v; // texture coordinates   
    cTextureVertex() { }
    cTextureVertex(float x,  float y,  float z,
float nx, float ny, float nz,
float u,  float v)
    {
        m_x  = x;  m_y  = y;  m_z  = z;
        m_nx = nx; m_ny = ny; m_nz = nz;
        m_u  = u;  m_v  = v;
    }   
};
const DWORD TEXTURE_VERTEX_FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
////////////////////////////////////////////////////////////////////////////////////////////////////
bool setup()
{   
// create the quad vertex buffer and fill it with the quad geometry
    g_d3d_device->CreateVertexBuffer(6 * sizeof(cTextureVertex), D3DUSAGE_WRITEONLY, TEXTURE_VERTEX_FVF,
                                     D3DPOOL_MANAGED, &g_quad_vb, NULL);
    cTextureVertex* vertices;
    g_quad_vb->Lock(0, 0, (void**)&vertices, 0);
// quad built from two triangles, note texture coordinate.
    vertices[0] = cTextureVertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
    vertices[1] = cTextureVertex(-1.0f,  1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
    vertices[2] = cTextureVertex( 1.0f,  1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
    vertices[3] = cTextureVertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
    vertices[4] = cTextureVertex( 1.0f,  1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
    vertices[5] = cTextureVertex( 1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);
    g_quad_vb->Unlock();
// create the texture and set filters
    D3DXCreateTextureFromFile(g_d3d_device, "dx5_logo.bmp", &g_d3d_texture);
    g_d3d_device->SetTexture(0, g_d3d_texture);
    g_d3d_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    g_d3d_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    g_d3d_device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
// don't use lighting for this sample
    g_d3d_device->SetRenderState(D3DRS_LIGHTING, FALSE);
// set the projection matrix
    D3DXMATRIX proj;
    D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI * 0.5f, (float)WIDTH/HEIGHT, 1.0f, 1000.0f);
    g_d3d_device->SetTransform(D3DTS_PROJECTION, &proj);
return true;
}
void cleanup()
{   
    safe_release<IDirect3DVertexBuffer9*>(g_quad_vb);
    safe_release<IDirect3DTexture9*>(g_d3d_texture);
}
bool display(float time_delta)
{
    g_d3d_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
    g_d3d_device->BeginScene();
    g_d3d_device->SetStreamSource(0, g_quad_vb, 0, sizeof(cTextureVertex));
    g_d3d_device->SetFVF(TEXTURE_VERTEX_FVF);
    g_d3d_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
    g_d3d_device->EndScene();
    g_d3d_device->Present(NULL, NULL, NULL, NULL);
return true;
}
LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM word_param, LPARAM long_param)
{
switch(msg)
    {
case WM_DESTROY:
        PostQuitMessage(0);
break;
case WM_KEYDOWN:
if(word_param == VK_ESCAPE)
            DestroyWindow(hwnd);
break;
    }
return DefWindowProc(hwnd, msg, word_param, long_param);
}
int WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line, int cmd_show)
{
if(! init_d3d(inst, WIDTH, HEIGHT, true, D3DDEVTYPE_HAL, &g_d3d_device))
    {
        MessageBox(NULL, "init_d3d() - failed.", 0, MB_OK);
return 0;
    }
if(! setup())
    {
        MessageBox(NULL, "Steup() - failed.", 0, MB_OK);
return 0;
    }
    enter_msg_loop(display);
    cleanup();
    g_d3d_device->Release();
return 0;
}

setup程序是很容易读懂的;我们用已经定义了纹理坐标的两个三角形创建一个方块。然后把文件dx5_logo.bmp读进IDirect3DTexture9接口中。接着使用SetTexture方法赋予纹理,最后设置缩小和放大过滤器进行线性过滤,我们也可以设置mipmap过滤器来进行D3DTEXF_POINT。

下载源程序

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

上一篇: TinyXML应用例子
下一篇: 失眠的调养
rise-worlds

rise-worlds

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

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

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

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

雷霄骅
2014/11/08
0
0
SDL2源代码分析5:更新纹理(SDL_UpdateTexture())

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

雷霄骅
2014/11/07
0
0
HLSL 研究学习之第七章第二节

注:所有代码均由红孩儿编写或以Microsoft DX9 SDK Sample 代码修改而成,转载请注明. (7_2)3D三角形纹理与色彩混合(用原来色彩,不用PS) // ------------------------------------------------...

长平狐
2013/03/19
6
0
HLSL 研究学习之五章三节

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

长平狐
2013/03/19
42
0

没有更多内容

加载失败,请刷新页面

加载更多

使用kubeadm 搭建K8s集群

1. 参考官网 https://kubernetes.io/docs/setup/independent/install-kubeadm/

whhbb
28分钟前
2
0
Dubbo 3.0 !提升不止一点点!

Dubbo 自 2011 年 10 月 27 日开源后,已被许多非阿里系的公司使用,其中既有当当网、网易考拉等互联网公司,也不乏中国人寿、青岛海尔等大型传统企业。 自去年 12 月开始,Dubbo 3.0 便已正...

编程SHA
29分钟前
2
0
提升不止一点点,Dubbo 3.0 预览版详细解读

Dubbo 自 2011 年 10 月 27 日开源后,已被许多非阿里系的公司使用,其中既有当当网、网易考拉等互联网公司,也不乏中国人寿、青岛海尔等大型传统企业。更多用户信息,可以访问Dubbo @GitHub...

阿里云云栖社区
32分钟前
13
0
HanLP Analysis for Elasticsearch

基于 HanLP 的 Elasticsearch 中文分词插件,核心功能: 兼容 ES 5.x-7.x; 内置词典,无需额外配置即可使用; 支持用户自定义词典; 支持远程词典热更新(待开发); 内置多种分词模式,适合...

左手的倒影
54分钟前
1
0
spark部署之yarn模式

spark部署之yarn模式 hadoop-3.0.0集群搭建 配置相应环境 java环境 scala(可配可不配) hadoop环境 从官网下载spark 解压 配置 /conf/spark-env.sh export JAVA_HOME=/usr/java/jdk1.8.0_4...

jackmanwu
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部