D3D学习笔记之九---纹理过滤方式。

 

这次我们就讨论一下怎么去设置纹理的过滤方式

我们先来讨论一下纹理的过滤方式的实现,下面是实现的代码,(其实很简单的)

下面是代码:

//=============================================================================

// Desc: 最近点采样和线性纹理过滤方式

//=============================================================================

 

#include <d3dx9.h>

 

//-----------------------------------------------------------------------------

// Desc: 全局变量

//-----------------------------------------------------------------------------

LPDIRECT3D9             g_pD3D       = NULL;    //Direct3D对象

LPDIRECT3DDEVICE9       g_pd3dDevice = NULL;    //Direct3D设备对象

LPDIRECT3DVERTEXBUFFER9 g_pVB        = NULL;    //顶点缓冲区对象

LPDIRECT3DTEXTURE9      g_pTexture   = NULL;    //纹理对象

 

 

//-----------------------------------------------------------------------------

// Desc: 顶点结构

//-----------------------------------------------------------------------------

struct CUSTOMVERTEX

{   FLOAT x, y, z;    //顶点位置

     FLOAT u,v ;          //顶点纹理坐标

};

#define D3DFVF_CUSTOMVERTEX   (D3DFVF_XYZ|D3DFVF_TEX1)

 

 

//-----------------------------------------------------------------------------

// Desc: 设置变换矩阵

//-----------------------------------------------------------------------------

VOID SetupMatrices()

{

      //创建并设置世界矩阵

    D3DXMATRIXA16 matWorld;

    D3DXMatrixIdentity( &matWorld );

    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

 

     //创建并设置观察矩阵

    D3DXVECTOR3 vEyePt( 0.0f, 0.0f, -8 );

    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );

    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );

    D3DXMATRIXA16 matView;

    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );

    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

 

     //创建并设置投影矩阵

    D3DXMATRIXA16 matProj;

    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );

    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

}

 

 

//-----------------------------------------------------------------------------

// Desc: 初始化Direct3D

//-----------------------------------------------------------------------------

HRESULT InitD3D( HWND hWnd )

{

     //创建Direct3D对象, 该对象用于创建Direct3D设备对象

    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )

        return E_FAIL;

 

     //设置D3DPRESENT_PARAMETERS结构, 准备创建Direct3D设备对象

    D3DPRESENT_PARAMETERS d3dpp;

    ZeroMemory( &d3dpp, sizeof(d3dpp) );

    d3dpp.Windowed = TRUE;

    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

 

     //创建Direct3D设备对象

    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,

                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,

                                      &d3dpp, &g_pd3dDevice ) ) )

    {

        return E_FAIL;

    }

 

     //禁用照明效果

     g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

   

     //设置变换矩阵

     SetupMatrices();

    

    return S_OK;

}

 

 

//-----------------------------------------------------------------------------

// Desc: 创建场景图形

//-----------------------------------------------------------------------------

HRESULT InitGriphics()

{

     //创建纹理对象

     if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"texture.jpg", &g_pTexture ) ) )

    {

       MessageBox(NULL, L"创建纹理失败", L"Texture.exe", MB_OK);

       return E_FAIL;

    }

 

     //顶点数据

    CUSTOMVERTEX g_Vertices[] =

    {

         { -3,   -3,  0.0f,  0.0f, 1.0f},  

         { -3,    3,  0.0f,  0.0f, 0.0f},

         {  3,   -3,  0.0f,  1.0f, 1.0f},

         {  3,    3,  0.0f,  1.0f, 0.0f }

 

    };

    

     //创建顶点缓冲区

    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX),

                                                 0, D3DFVF_CUSTOMVERTEX,

                                                 D3DPOOL_MANAGED, &g_pVB,NULL ) ) )

    {

        return E_FAIL;

    }

 

    //填充顶点缓冲区

    VOID* pVertices;

    if( FAILED( g_pVB->Lock( 0, sizeof(g_Vertices), (void**)&pVertices, 0 ) ) )

        return E_FAIL;

    memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );

    g_pVB->Unlock();

 

    return S_OK;

}

 

 

//-----------------------------------------------------------------------------

// Desc: 释放创建的对象

//-----------------------------------------------------------------------------

VOID Cleanup()

{

     //释放纹理对象

     if( g_pTexture != NULL )

        g_pTexture->Release();

 

    //释放顶点缓冲区对象

    if( g_pVB != NULL )       

        g_pVB->Release();

 

     //释放Direct3D设备对象

    if( g_pd3dDevice != NULL )

        g_pd3dDevice->Release();

 

     //释放Direct3D对象

    if( g_pD3D != NULL )      

        g_pD3D->Release();

}

 

 

//-----------------------------------------------------------------------------

// Desc: 渲染图形

//-----------------------------------------------------------------------------

VOID Render()

{

     //清空后台缓冲区

    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(45, 50, 170), 1.0f, 0 );

    

     //开始在后台缓冲区绘制图形

     if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )

     {

         g_pd3dDevice->SetTexture( 0, g_pTexture ); //设置纹理

         g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );

         g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );

         g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2);

 

         //结束在后台缓冲区绘制图形

         g_pd3dDevice->EndScene();

     }

 

     //将在后台缓冲区绘制的图形提交到前台缓冲区显示

    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );

}

 

 

//-----------------------------------------------------------------------------

// Desc: 消息处理

//-----------------------------------------------------------------------------

LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )

{

     switch( msg )

     {

     case WM_DESTROY:

         Cleanup();

         PostQuitMessage( 0 );

         return 0;

 

     case WM_KEYDOWN:

         switch(wParam)

         {

         case 49:    //“”键, 使用最近点采样纹理过滤

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

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

              break;

 

         case 50:    //“”键, 使用线性纹理过滤

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

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

              break;

         }

          return 0;

     }

 

    return DefWindowProc( hWnd, msg, wParam, lParam );

}

 

 

 

//-----------------------------------------------------------------------------

// Desc: 入口函数

//-----------------------------------------------------------------------------

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )

{

 

    //注册窗口类

    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,

                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,

                       L"ClassName", NULL };

    RegisterClassEx( &wc );

 

    //创建窗口

    HWND hWnd = CreateWindow(  L"ClassName", L"纹理过滤方式",

                              WS_OVERLAPPEDWINDOW, 200, 100, 400, 360,

                              GetDesktopWindow(), NULL, wc.hInstance, NULL );

 

     //初始化Direct3D

    if( SUCCEEDED( InitD3D( hWnd ) ) )

    {

         //创建场景图形

        if( SUCCEEDED( InitGriphics() ) )

        {

            //显示窗口

            ShowWindow( hWnd, SW_SHOWDEFAULT );

            UpdateWindow( hWnd );

 

            //进入消息循环

            MSG msg;

            ZeroMemory( &msg, sizeof(msg) );

            while( msg.message!=WM_QUIT )

            {

                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )

                {

                    TranslateMessage( &msg );

                    DispatchMessage( &msg );

                }

                else

                   {

                    Render();  //渲染图形

                   }

            }

        }

    }

 

    UnregisterClass(  L"ClassName", wc.hInstance );

    return 0;

}

仔细看下上面的代码,没有什么难的地方,大部分的代码,我们都见过,而且很熟悉,唯一的差别是:

case WM_KEYDOWN:

         switch(wParam)

         {

         case 49:    //“”键, 使用最近点采样纹理过滤

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

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

              break;

 

         case 50:    //“”键, 使用线性纹理过滤

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

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

              break;

         }

这里对纹理的过滤方式进行了设置。设置的方式很简单,但是纹理的过滤方式有必要简单的说一下。

纹理的过滤方式有以下几种:最近点采样,线性纹理过滤,各项异性纹理过滤,多级渐进纹理。

有人就要问了,纹理过滤是个什么东西?貌似挺复杂的,其实说明白了,也就是把纹理图片贴到3D的图元上的时候由于很可能遇到大小不同的情况,这时就需要把图片进行放缩,这个放缩的过程也就是所谓的过滤。这些放缩就需要采取一些的算法,这几种的方式就是不同的算法。这几种算法的具体实现我们就不讨论了,因为自己也不是很懂,呵呵,但是这几种算法的效果我们可以看一下:

 

最近点采样:运算速度最快,效果最差。

 

使用方法:

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

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

函数的第一个参数是指对哪一层的纹理进行设置,D3D可以管理八层纹理,取值0-7

第二个参数是标志哪个滤镜,

这里设置的是一个放大滤镜,和一个缩小滤镜,为何有一个放大滤镜和缩小滤镜呢,仔细想想,真实的图片和渲染图元之间的大小是不确定的,将图片贴到图元上的时候,可能会把图片进行放大处理,也可能进行缩小处理,所以要有这两个滤镜。

这个函数就设置里放大滤镜为最近点采样,缩小滤镜也是最近点采样。

 

线性纹理过滤:运算速度较快,效果较好。

使用方法:

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

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

这个和上面的很相似,同样是设置了放大滤镜和缩小滤镜,都设置成线性纹理过滤。

 

在这个程序里面我们就用到了这两个纹理过滤方法,到这里,大家应该明白了代码的意思,就是改变了一下纹理过滤的设置。

 

运行一下,看看这两个纹理过滤的效果吧,值得一说的是,现在大部分的纹理用的都是线性过滤,因为性能上不会很低,而且效果上要好很多。

 

 

下面再来一段代码,让我们讨论一下其它的纹理过滤:

//=============================================================================

// Desc: 多级渐进纹理

//=============================================================================

 

#include <d3dx9.h>

 

//-----------------------------------------------------------------------------

// Desc: 全局变量

//-----------------------------------------------------------------------------

LPDIRECT3D9             g_pD3D       = NULL;    //Direct3D对象

LPDIRECT3DDEVICE9       g_pd3dDevice = NULL;    //Direct3D设备对象

LPDIRECT3DVERTEXBUFFER9 g_pVB        = NULL;    //顶点缓冲区对象

LPDIRECT3DTEXTURE9      g_pMipTex    = NULL;    //多级渐进纹理

LPDIRECT3DTEXTURE9      g_pTexture   = NULL;    //非多级渐进纹理

float                   g_fDistance  = -10;     //摄影机距图形的距离

bool                    g_bUseMipTex = true;    //标志是否使用多级渐进纹理

 

 

//-----------------------------------------------------------------------------

// Desc: 顶点结构

//-----------------------------------------------------------------------------

struct CUSTOMVERTEX

{

     FLOAT x, y, z;    //顶点位置

     FLOAT u,v ;          //顶点纹理坐标

};

#define D3DFVF_CUSTOMVERTEX   (D3DFVF_XYZ | D3DFVF_TEX1)

 

 

//-----------------------------------------------------------------------------

// Desc: 初始化Direct3D

//-----------------------------------------------------------------------------

HRESULT InitD3D( HWND hWnd )

{

     //创建Direct3D对象, 该对象用于创建Direct3D设备对象

    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )

        return E_FAIL;

 

     //设置D3DPRESENT_PARAMETERS结构, 准备创建Direct3D设备对象

    D3DPRESENT_PARAMETERS d3dpp;

    ZeroMemory( &d3dpp, sizeof(d3dpp) );

    d3dpp.Windowed = TRUE;

    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

 

     //创建Direct3D设备对象

    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,

                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,

                                      &d3dpp, &g_pd3dDevice ) ) )

    {

        return E_FAIL;

    }

 

     //禁用照明效果

     g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

 

    

     //设置纹理过滤方式

     g_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

 

    return S_OK;

}

 

 

//-----------------------------------------------------------------------------

// Desc: 创建场景图形

//-----------------------------------------------------------------------------

HRESULT InitGriphics()

{

     //创建多级渐进纹理

    if( FAILED( D3DXCreateTextureFromFileEx( g_pd3dDevice,

                                             L"texture.jpg",

                                                    0, 0,             //纹理宽度和高度, "0"表示以图形文件的宽度和高度作为纹理的宽度和高度

                                                   0,                //渐进纹理序列级数

                                                    0,                //纹理使用方式, 一般为

                                                    D3DFMT_X8R8G8B8,  //纹理图形格式

                                                    D3DPOOL_MANAGED,  //纹理资源的内存类型

                                                    D3DX_DEFAULT,   

                                                    D3DX_DEFAULT,

                                                   0xFF000000,0,0,

                                                   &g_pMipTex ) ) )

    {

         return E_FAIL;

    }

 

     //创建非多级渐进纹理纹理

    if( FAILED( D3DXCreateTextureFromFileEx( g_pd3dDevice,

                                             L"texture.jpg",

                                                    0, 0,             //纹理宽度和高度, "0"表示以图形文件的宽度和高度作为纹理的宽度和高度

                                                   1,                //渐进纹理序列级数

                                                    0,                //纹理使用方式, 一般为

                                                    D3DFMT_X8R8G8B8,  //纹理图形格式

                                                    D3DPOOL_MANAGED,  //纹理资源的内存类型

                                                    D3DX_DEFAULT,   

                                                    D3DX_DEFAULT,

                                                   0xFF000000,0,0,

                                                   &g_pTexture ) ) )

    {

         return E_FAIL;

    }

 

     //顶点数据

    CUSTOMVERTEX g_Vertices[] =

    {

        #define fdiv 80.f

         { -3,   -3,  0.0f, 0.0f, 1.0f},  

         { -3,    3,  0.0f, 0.0f, 0.0f}, 

         {  3,   -3,  0.0f, 1.0f, 1.0f}, 

         {  3,    3,  0.0f, 1.0f, 0.0f }

 

    };

    

     //创建顶点缓冲区

    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX),

                                                 0, D3DFVF_CUSTOMVERTEX,

                                                 D3DPOOL_MANAGED, &g_pVB,NULL ) ) )

    {

        return E_FAIL;

    }

 

    //填充顶点缓冲区

    VOID* pVertices;

    if( FAILED( g_pVB->Lock( 0, sizeof(g_Vertices), (void**)&pVertices, 0 ) ) )

        return E_FAIL;

    memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );

    g_pVB->Unlock();

 

    return S_OK;

}

 

 

//-----------------------------------------------------------------------------

// Desc: 释放创建的对象

//-----------------------------------------------------------------------------

VOID Cleanup()

{

     //释放多级渐进纹理对象

     if( g_pMipTex != NULL )

        g_pMipTex->Release();

 

     //释放多级渐进纹理对象

     if( g_pTexture != NULL )

        g_pTexture->Release();

 

    //释放顶点缓冲区对象

    if( g_pVB != NULL )       

        g_pVB->Release();

 

     //释放Direct3D设备对象

    if( g_pd3dDevice != NULL )

        g_pd3dDevice->Release();

 

     //释放Direct3D对象

    if( g_pD3D != NULL )      

        g_pD3D->Release();

}

 

 

//-----------------------------------------------------------------------------

// Desc: 设置变换矩阵

//-----------------------------------------------------------------------------

VOID SetupMatrices()

{

    //世界矩阵

    D3DXMATRIXA16 matWorld;

    D3DXMatrixIdentity( &matWorld );

    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

 

     //观察矩阵, 观察点根据输入逐渐拉近或变远

    D3DXVECTOR3 vEyePt( 0.0f, 0.0f, g_fDistance );

    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );

    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );

    D3DXMATRIXA16 matView;

    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );

    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

 

     //投影矩阵

    D3DXMATRIXA16 matProj;

    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );

    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

}

 

 

//-----------------------------------------------------------------------------

// Desc: 渲染图形

//-----------------------------------------------------------------------------

VOID Render()

{

     //清空后台缓冲区

    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(45, 50, 170), 1.0f, 0 );

     SetupMatrices();  //设置变换矩阵,

 

     //开始在后台缓冲区绘制图形

     if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )

     {

         //在后台缓冲区绘制图形

         if(g_bUseMipTex==true)

              g_pd3dDevice->SetTexture( 0, g_pMipTex );  //使用多级渐进纹理

         else

              g_pd3dDevice->SetTexture( 0, g_pTexture ); //使用普通纹理

        

         g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );

         g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );

         g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2);

 

         //结束在后台缓冲区绘制图形

         g_pd3dDevice->EndScene();

    }

 

     //将在后台缓冲区绘制的图形提交到前台缓冲区显示

    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );

}

 

 

//-----------------------------------------------------------------------------

// Desc: 消息处理

//-----------------------------------------------------------------------------

LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )

{

     switch( msg )

     {

     case WM_DESTROY:

         Cleanup();

         PostQuitMessage( 0 );

         return 0;

 

     case WM_KEYDOWN:

         switch(wParam)

         {

         case 49:    //“”键, 使用多级渐进纹理

              g_bUseMipTex = true;

              break;

 

         case 50:    //“”键, 不使用多级渐进纹理

              g_bUseMipTex = false;

              break;

 

         case VK_DOWN:

              g_fDistance -= 0.1f;

              break;

 

         case VK_UP:

              g_fDistance += 0.1f;

              break;

         }

         return 0;

     }

 

    return DefWindowProc( hWnd, msg, wParam, lParam );

}

 

 

 

//-----------------------------------------------------------------------------

// Desc: 入口函数

//-----------------------------------------------------------------------------

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )

{

 

    //注册窗口类

    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,

                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,

                       L"ClassName", NULL };

    RegisterClassEx( &wc );

 

    //创建窗口

    HWND hWnd = CreateWindow(  L"ClassName", L"多级渐进纹理",

                              WS_OVERLAPPEDWINDOW, 200, 100, 600, 500,

                              GetDesktopWindow(), NULL, wc.hInstance, NULL );

 

     //初始化Direct3D

    if( SUCCEEDED( InitD3D( hWnd ) ) )

    {

         //创建场景图形

        if( SUCCEEDED( InitGriphics() ) )

        {

            //显示窗口

            ShowWindow( hWnd, SW_SHOWDEFAULT );

            UpdateWindow( hWnd );

 

            //进入消息循环

            MSG msg;

            ZeroMemory( &msg, sizeof(msg) );

            while( msg.message!=WM_QUIT )

            {

                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )

                {

                    TranslateMessage( &msg );

                    DispatchMessage( &msg );

                }

                else

                   {

                    Render();  //渲染图形

                   }

            }

        }

    }

 

    UnregisterClass(  L"ClassName", wc.hInstance );

    return 0;

}

 

 

上面这些代码演示的是多级渐进纹理过滤,这个名字听着挺吓人的,其实一点也不难,可以说,在我们前面所用的默认纹理就是多级渐进纹理,这里我们看一下它究竟是什么。

 

多级渐进纹理是由一组分辨率逐渐降低的纹理序列组成的,每一级纹理的宽度和高度都是上一级的一半。但用到纹理的时候,程序会自动选取和图元大小最相近的纹理进行变换,这样就能使纹理更加逼真,也能节省内存。

下面介绍一下使用方法:

1.      首先要先生成多级渐进纹理。

我们调用D3DXCreateTextureFromFileEx函数来生成多级渐进纹理序列。先让我们仔细的认识一下这个函数:

HRESULT D3DXCreateTextureFromFileEx(

  LPDIRECT3DDEVICE9 pDevice,

  LPCTSTR pSrcFile,

  UINT Width,

  UINT Height,

  UINT MipLevels,

  DWORD Usage,

  D3DFORMAT Format,

  D3DPOOL Pool,

  DWORD Filter,

  DWORD MipFilter,

  D3DCOLOR ColorKey,

  D3DXIMAGE_INFO * pSrcInfo,

  PALETTEENTRY * pPalette,

  LPDIRECT3DTEXTURE9 * ppTexture

);

Parameters

pDevice

这个用的多了,就不用多介绍了,就是D3D环境指针

pSrcFile

纹理文件。

Width

生成纹理的宽度,如果设置为0表示取原图形文件的宽度作为纹理宽度

Height

同上,只不过这个事高度

MipLevels

指定生成的多级渐进纹理序列的级数,设为0,表示尽可能多的生成纹理序列,直至最小级的纹理宽度或高度为1.

Usage

纹理使用方式,一般为0

Format

指定纹理图形的格式,还可以生成压缩纹理,以节省内存空间。

Pool

纹理存放的内存类型,一般为0

Filter

纹理过滤方式。

MipFilter

自动生成的纹理序列过滤方式,通常设置为D3D_FILTER_BOX,表示通过原图2*2的矩形区域计算纹理序列,我们设置为默认值D3DX_DEFAULT,相当于上面的常用值。

ColorKey

表示被设置成透明的颜色,就是说,指定一个颜色,在渲染的时候会把这个颜色换成透明色

pSrcInfo

图形文件信息存放的地址

pPalette

调色板存储地址

ppTexture

我们要得到的纹理指针。

这里我们的参数都是:

D3DXCreateTextureFromFileEx( g_pd3dDevice,

                             L"texture.jpg",

                             0,

 0, //纹理宽度和高度, "0"表示以图形文件的宽度和高度作为纹理的宽度和高度

                             0,                //渐进纹理序列级数

                             0,                //纹理使用方式, 一般为0

                             D3DFMT_X8R8G8B8,  //纹理图形格式

                             D3DPOOL_MANAGED,  //纹理资源的内存类型

                             D3DX_DEFAULT,   

                             D3DX_DEFAULT,

                             0xFF000000,0,0,

                             &g_pMipTex )

这样的参数我们就得到了尽可能多的纹理渐进序列。

前面我们用到的D3DXCreateTextureFromFile函数,取的全部是默认值,因此会生成尽可能多的渐进序列,所以我说我们前面用的就是多级渐进纹理。

2.      设置多级渐进纹理

创建多级渐进纹理之后我们要设置多级渐进纹理,怎么去设置多级渐进纹理呢?

 

     //设置纹理过滤方式

     g_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

就这么简单,这样我们的多级渐进纹理就完成了,生成以下,看看效果,其实在没有对比的情况下也看不出来什么,呵呵,反正我没看出来。

关于纹理我们就先讨论到这里,下面我们就有好玩的喽,下面就是去载入模型,我们该丰富一下我们的世界了,呵呵。

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值