• DirectX 基础学习系列5 纹理映射


    1 纹理坐标

    类似BMP图像坐标系,左上为原点

    纹理坐标为了规范化,范围限定在[0,1]之间,使用纹理的时候,需要修改顶点结构

    struct ColorVetex

    {

        float x, y,z;

        float _nx,_ny,_nz ;

        float _u,_y ;

        static const DWORD FVF;

    }

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

    2创建并启用纹理

    从文件中加载纹理数据

    HRESULT D3DXCreateTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, LPDIRECT3DTEXTURE9 * ppTexture );

    从内存中加载

    HRESULT D3DXCreateTextureFromFileInMemory( LPDIRECT3DDEVICE9 pDevice, LPCVOID pSrcData, UINT SrcDataSize, LPDIRECT3DTEXTURE9 * ppTexture);

    从资源加载

    HRESULT D3DXCreateTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule, LPCTSTR pSrcResource, LPDIRECT3DTEXTURE9 * ppTexture);

    设置问题。,DX最多可以设置8层纹理,从而组合得到更细致的图片

    SetTexture(0,&_stonewall);

    禁用纹理

    SetTexture(0,0);

    3 纹理过滤器

    纹理三角形和屏幕三角形大小不适合的时候,通过这项技术,让二者适应

    DX提供三种纹理过滤器:

    最近点采样:默认情况,速度快,效果差

    setsamplerstate(0,D3DSAMP_MAGFILTER,D3DTEXT_POINT);

    setsamplerstate(0,D3DSAMP_MINFILTER,D3DTEXT_POINT);

    线性纹理过滤器:线性插值,可以分为 放大和缩小

    SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXT_LINEAR);

    SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXT_LINEAR);

    各向异性纹理过滤器:多线条采样技术,

    setsamplerstate(0,D3DSAMP_MAGFILTER,D3DTEXT_ANISOTROPIC);

    setsamplerstate(0,D3DSAMP_MINFILTER, D3DTEXT_ANISOTROPIC);

    使用anisotropic filter时,需要对D3DSAMP_MAXANISOTROPIC 水平进行设置

    4 多级渐进纹理

    消除纹理和三角尺寸不一致的问题,创建多级渐进纹理,

    多级渐进纹理过滤器:

    Device->SetSamplerState(0,D3D_MIPFILTER,flag);

    flag:D3DTEXT_NONE  :不适用

    D3DTEXF_POINT 选族最近接的一级纹理,选择后使用指定的纹理过滤器进行处理 D3DTEXF_LINEAR 选择最近的两极纹理,用指定纹理过滤器过滤后,再对两极纹理进行线性融合

    使用多级渐进纹理之后 DX会自动选用合适的尺寸纹理

    5 寻址模式 :处理纹理坐标超过[0,1]范围的问题

    有四种扩展模式:

    重复寻址模式

    Device->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_WRAP);

    Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);

    边界颜色模式

    Device->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_BORDER);

    Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);

    Device->SetSamplerState(0, D3DSAMP_BORDERCOLOR,0x000000FF);

    嵌位寻址模式

    Device->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_CLAMP);

    Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);

    镜像寻址模式

    Device->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_MIRROR);

    Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);

    6纹理映射的过程

    (1)构建具有纹理坐标的顶点

    (2)读取纹理数据

    (3)设置 缩小 放大过滤器,多级渐进纹理过滤器

    (4)将纹理与物体关

    下列代码为《directx9.0c游戏开发基础教程》第六章的代码:配合光源 纹理 ,物理的旋转采用更改观察者视角

     
     
    #include "d3dUtility.h"
    #include "cube.h"
    #include "vertex.h"
     
    //
    // Globals
    //
     
    IDirect3DDevice9*     Device = 0; 
     
    const int Width  = 640;
    const int Height = 480;
     
    Cube*              Box = 0;
    IDirect3DTexture9* Tex = 0;
     
    //
    // Framework Functions
    //
    bool Setup()
    {
        //
        // Create the cube.
        //
     
        Box = new Cube(Device);
     
        //
        // Set a directional light.
        //
     
        D3DLIGHT9 light;
        ::ZeroMemory(&light, sizeof(light));
        light.Type      = D3DLIGHT_DIRECTIONAL;
        light.Ambient   = D3DXCOLOR(0.1f, 0.8f, 0.8f, 1.0f);
        light.Diffuse   = D3DXCOLOR(0.9f, 1.0f, 1.0f, 1.0f);
        light.Specular  = D3DXCOLOR(0.0f, 0.2f, 1.0f, 1.0f);
        light.Direction = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
        Device->SetLight(0, &light);
        Device->LightEnable(0, true);
     
        Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
        Device->SetRenderState(D3DRS_SPECULARENABLE, true);
     
        //
        // Create texture.
        //
        D3DXCreateTextureFromFile(
            Device,
            "crate.jpg",
            &Tex);
     
        // 
        // Set Texture Filter States.
        //
     
        Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
        Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
        Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
     
        //
        // Set the projection matrix.
        //
     
        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::Delete<Cube*>(Box);
        d3d::Release<IDirect3DTexture9*>(Tex);
    }
     
    bool Display(float timeDelta)
    {
        if( Device )
        {
            // 
            // Update the scene: update camera position.
            //
     
            static float angle  = (3.0f * D3DX_PI) / 2.0f;
            static float height = 2.0f;
        
            if( ::GetAsyncKeyState(VK_LEFT) & 0x8000f )
                angle -= 0.5f * timeDelta;
     
            if( ::GetAsyncKeyState(VK_RIGHT) & 0x8000f )
                angle += 0.5f * timeDelta;
     
            if( ::GetAsyncKeyState(VK_UP) & 0x8000f )
                height += 5.0f * timeDelta;
     
            if( ::GetAsyncKeyState(VK_DOWN) & 0x8000f )
                height -= 5.0f * timeDelta;
     
            D3DXVECTOR3 position( cosf(angle) * 3.0f, height, sinf(angle) * 3.0f );
            D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
            D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
            D3DXMATRIX V;
            D3DXMatrixLookAtLH(&V, &position, &target, &up);
     
            Device->SetTransform(D3DTS_VIEW, &V);
     
            //
            // Draw the scene:
            //
     
            Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
            Device->BeginScene();
     
            Device->SetMaterial(&d3d::RED_MTRL);
            Device->SetTexture(0, Tex);
     
            Box->draw(0, 0, 0);
     
            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;
    }
  • 相关阅读:
    socketpair + signal + select 的套路
    java 远程调用 RPC
    Java 序列化
    Java Socket 编程
    云计算 IaaS,SaaS,PaaS的区别?一个通俗易懂的吃货文章
    如何应对网站反爬虫策略?如何高效地爬大量数据?
    java NIO详解
    LigerUI LigerGrid getSelectedRows() 多选顺序 不是从上到下修改方法
    JSON风格指南
    Json 工具介绍 fastjson gson jackson
  • 原文地址:https://www.cnblogs.com/zsb517/p/3384373.html
Copyright © 2020-2023  润新知