• 纹理


    借助纹理映射技术,我们可以将图像数据映射到三角形图元中。在Direct3D中,纹理用接口IDirect3DTexture9来表示。

    1.纹理坐标

    Direct3D使用的纹理坐标,由沿水平方向的u轴和沿垂直方向的v轴构成。用坐标对(u,v)标示的纹理元素称为纹理元。为了能处理不同尺寸的纹理,Direct3D将纹理坐标做了规范处理,使之限定在区间[0,1]内。纹理的FVF标记:D3DFVF_TEX1.

    2.创建并启用纹理

    纹理数据通常从磁盘的图像文件读入,然后再加载到IDirect3DTexture9对象中。使用的函数如下:

    HRESULT D3DXCreateTextureFromFile(
      LPDIRECT3DDEVICE9 pDevice, //创建纹理的设备
      LPCTSTR pSrcFile,   //要加载的文件
      LPDIRECT3DTEXTURE9 * ppTexture //要创建的纹理
    );
    设置为当前纹理,用如下函数:
    HRESULT IDirect3DDevice9::SetTexture(
      DWORD Sampler,  //第几层纹理,最多8层,(0-7).
      IDirect3DBaseTexture9 * pTexture //要设置的纹理
    );
    若禁用某一层纹理,将pTexture置为0。Device->SetTexture(0,0);
    3.纹理过滤器

    有时纹理三角形为了适应屏幕三角形,会进行相应的放大或缩小。这样会产生纹理畸变,为了克服这种畸变,Direct3D采用了纹理过滤技术。

    Direct3D提供了3种类型的纹理过滤器,纹理过滤方式可用Device->SetSamplerState方法。

    3.1最近点采样

    3.2线性纹理过滤

    3.3各向异性纹理过滤

    4.多级渐进纹理

    由某一纹理创建一系列分辨率逐渐减小的纹理图像,并对每种分辨率下的纹理所采用的过滤方式进行定制,保留那些重要的细节。这一系列的纹理图像称为多级渐进纹理链。

    4.1多级渐进纹理过滤器

    Device->SetSamplerState(0,D3DSAMP_MIPFILTER,Fliter)

    Fliter取值:

    D3DTEXF_NONE,禁用多级渐进纹理过滤器

    D3DTEXF_POINT,Direct3D将选择尺寸与屏幕三角形最接近的那一级纹理。一旦选择了某一级纹理,Direct3D就会用指定的放大过滤器和缩小过滤器对该级纹理进行过滤。

    D3DTEXF_LINEAR, Direct3D将选择尺寸与屏幕三角形最接近的两个纹理。用指定的过滤器对每级纹理进行过滤。然后将这两级纹理进行线性组合,形成最终的颜色。

    4.2使用多级渐进纹理

    如果硬件支持多级渐进纹理,D3DXCreateTextureFromFile函数将创建一个多级渐进纹理链。Direct3D还将自动选择与屏幕三角形最接近的那一级纹理。

    5.寻址模式

    纹理坐标必须限制在[0,1]。从技术上讲是有问题的,因为坐标有可能超出这个范围。Direct3D定义了4种用来处理纹理坐标超出[0,1]范围的纹理映射模式。分别是:重复寻址模式,边界颜色寻址模式,箝位寻址模式,镜像寻址模式。

    同样用SetSamplerState设定。

    #include "d3dUtility.h"
    
    IDirect3DDevice9* Device = 0;  //设备
     
    const int Width  = 640;
    const int Height = 480;
    
    IDirect3DVertexBuffer9* vb = 0; 
    IDirect3DTexture9 * tex=0;  //纹理
    
    struct Vertex //顶点结构:位置、顶点法线和纹理
    {
        Vertex(){}
    
        Vertex(float x, float y, float z,float nx,float ny,float nz,float u,float v)
        {
            _x = x;     _y = y;  _z = z;
            _nx=nx;_ny=ny;_nz=nz;
            _u=u;_v=v;
        }
    
        float _x, _y, _z;
        float _nx,_ny,_nz;
        float _u,_v;
    
        static const DWORD FVF;
    };
    const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
    
    //
    // Framework Functions
    //
    bool Setup()
    {
        Device->CreateVertexBuffer(               //创建顶点缓存
            12 * sizeof(Vertex), // size in bytes
            D3DUSAGE_WRITEONLY, // flags
            Vertex::FVF,        // vertex format
            D3DPOOL_MANAGED,    // managed memory pool
            &vb,          // return create vertex buffer
            0);                 // not used - set to 0
    
        Vertex* vertices;
        vb->Lock(0, 0, (void**)&vertices, 0);        //获取指向顶点缓存内容的指针
    
        vertices[0] = Vertex(-1.0f, -1.0f,1.25f,0.0f,0.0f,-1.0f,0.0f,5.0f);
        vertices[1] = Vertex( -1.0f, 1.0f,1.25f,0.0f,0.0f,-1.0f,0.0f,0.0f);
        vertices[2] = Vertex( 1.0f, 1.0f,  1.25f,0.0f,0.0f,-1.0f,5.0f,0.0f);
    
        vertices[3] = Vertex(-1.0f, -1.0f,  1.25f,0.0f,0.0f,-1.0f,0.0f,5.0f);
        vertices[4] = Vertex( 1.0f, 1.0f,  1.25f,0.0f,0.0f,-1.0f,5.0f,0.0f);
        vertices[5] = Vertex( 1.0f, -1.0f,  1.25f,0.0f,0.0f,-1.0f,5.0f,5.0f);
    
        vb->Unlock();
    
        D3DXCreateTextureFromFile(Device,"dx5_logo.bmp",&tex); //加载纹理图像,
        Device->SetTexture(0,tex);          //设置当前纹理
        Device->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR); //线性纹理过滤器设置为放大过滤器
        Device->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR); //线性纹理过滤器设置为缩小过滤器
        Device->SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_POINT);  //多级渐进纹理过滤器,选择与屏幕尺寸最接近的那一级纹理
    
        Device->SetRenderState(D3DRS_LIGHTING, false);  //设置光照不可用
    
        D3DXMATRIX proj;
        D3DXMatrixPerspectiveFovLH(   //投影矩阵
                &proj,
                D3DX_PI * 0.5f, // 90 - degree
                (float)Width / (float)Height,
                1.0f,
                1000.0f);
        Device->SetTransform(D3DTS_PROJECTION, &proj); //投影
        return true;
    }
    void Cleanup()
    {
        d3d::Release<IDirect3DVertexBuffer9*>(vb);
    }
    
    bool Display(float timeDelta)
    {
        if( Device )
        {
            Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
            Device->BeginScene();
    
            Device->SetStreamSource(0, vb, 0, sizeof(Vertex));
            Device->SetFVF(Vertex::FVF);
            Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); //画出顶点缓存中的三角形图元
            Device->SetFVF(Vertex::FVF); 
    
            Device->EndScene();
            Device->Present(0, 0, 0, 0);
        }
        return true;
    }
    
    
    //
    // WndProc
    //
    LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch( msg )
        {
        case WM_DESTROY:
            ::PostQuitMessage(0);
            break;
            
        case WM_KEYDOWN:
            if( wParam == VK_ESCAPE )
                ::DestroyWindow(hwnd);
            break;
        }
        return ::DefWindowProc(hwnd, msg, wParam, lParam);
    }
    
    //
    // WinMain
    //
    int WINAPI WinMain(HINSTANCE hinstance,
                       HINSTANCE prevInstance, 
                       PSTR cmdLine,
                       int showCmd)
    {
        if(!d3d::InitD3D(hinstance,
            Width, Height, true, D3DDEVTYPE_HAL, &Device))
        {
            ::MessageBox(0, "InitD3D() - FAILED", 0, 0);
            return 0;
        }
            
        if(!Setup())
        {
            ::MessageBox(0, "Setup() - FAILED", 0, 0);
            return 0;
        }
    
        d3d::EnterMsgLoop( Display );
    
        Cleanup();
    
        Device->Release();
    
        return 0;
    }
    Main.cpp
  • 相关阅读:
    一些python练习题
    爬取某房源网数据
    练习1:定义 is_Even 函数,传一 int 参数,判断是否是偶数,return True;不是,return False
    pycharm中tkinter 不显示窗口
    保护眼睛颜色的RGB数值
    Python study----------class的实例化
    HTML----------STUDY
    Python study----------字典 popitem()
    Python study----------Python搜索路径
    Python study----------第三方module-----chardet(识别编码)
  • 原文地址:https://www.cnblogs.com/hometown/p/3656710.html
Copyright © 2020-2023  润新知