zoukankan      html  css  js  c++  java
  • (转)纹理坐标变换

    Direct3D提供了对生成的纹理坐标进行坐标变换的功能,与顶点坐标变换相类似,可以指定一个4x4的纹理坐标变换矩阵,把它与生成的纹理坐标相乘,然后将变换之后的纹理坐标输出至Direct3D渲染流水线。使用纹理坐标变换可以对纹理坐标进行诸如平移、旋转和缩放等三维变换。纹理坐标变换对于生成一些特殊效果是非常有用的,它不用直接修改顶点的纹理坐标。例如可以通过一个简单的平移矩阵对纹理坐标进行变换,从而使物体表面上的纹理不断变换位置,产生动画效果。纹理坐标自动生成在三维图形程序中最广泛的应用是环境映射。

    可通过函数IDirect3DDevice9::SetTransform()来设置4x4的纹理坐标变换矩阵,它以D3DTS_TEXTURE0~ D3DTS_TEXTURE7作为第一个参数,表示设置纹理层0~7的纹理矩阵。下列代码对纹理层0设置了一个将纹理坐标u、v缩小到原来一半的纹理矩阵:

    D3DXMATRIX mat;
    D3DXMatrixIdentity(&mat);
    mat._11 = 0.5f;
    mat._22 = 0.5f;
    pd3dDevice->SetTransform(D3DTS_TEXTURE0, &mat);

    下面的代码将原来的纹理坐标平移(1.0, 1.0, 0)个单位。

    D3DXMATRIX mat;
    D3DXMatrixIdentity(&mat);
    mat._41 = 1.0f;
    mat._42 = 1.0f;
    mat._43 = 0.0f;
    pd3dDevice->SetTransform(D3DTS_TEXTURE0, &mat);

    示例程序通过下列代码对自动生成的纹理坐标进行变换:

    // texture coordinate transform

    D3DXMATRIX mat_texture, mat_scale, mat_trans;

    D3DXMatrixIdentity(&mat_texture);
    D3DXMatrixScaling(&mat_scale, 0.5f, -0.5f, 1.0f);
    D3DXMatrixTranslation(&mat_trans, 0.5f, 0.5f, 1.0f);

    mat_texture = mat_texture * mat_scale * mat_trans;
    pd3dDevice->SetTransform(D3DTS_TEXTURE0, &mat_texture);


    运行效果图:

    主程序:

    #include "dxstdafx.h"
    #include 
    "resource.h"

    #pragma warning(disable : 
    4127 4995 4996)

    #define release_com(p)    do { if(p) { (p)->Release(); (p) = NULL; } } while(0)

    #define IDC_TOGGLE_FULLSCREEN        1
    #define IDC_TOGGLE_REF                2
    #define IDC_CHANGE_DEVICE            3

    struct sCustomVertex
    {
        
    float x, y, z;
        D3DCOLOR color;
    };

    #define D3DFVF_CUSTOM_VERTEX    (D3DFVF_XYZ | D3DFVF_DIFFUSE)

    const D3DXCOLOR FONT_COLOR(1.0f0.5f0.25f1.0f);

    CDXUTDialogResourceManager    g_dlg_resource_manager;
    CD3DSettingsDlg                g_settings_dlg;
    CDXUTDialog                    g_button_dlg;

    IDirect3DVertexBuffer9
    *        g_vertex_buffer;
    IDirect3DTexture9
    *            g_texture;

    ID3DXFont
    *        g_font;
    ID3DXSprite
    *    g_text_sprite;
    bool            g_show_help;

    //--------------------------------------------------------------------------------------
    // Rejects any devices that aren't acceptable by returning false
    //--------------------------------------------------------------------------------------
    bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 
                                      D3DFORMAT BackBufferFormat, 
    bool bWindowed, void* pUserContext )
    {
        
    // Typically want to skip backbuffer formats that don't support alpha blending

        IDirect3D9
    * pD3D = DXUTGetD3DObject(); 

        
    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat, 
                        D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
            
    return false;

        
    return true;
    }


    //--------------------------------------------------------------------------------------
    // Before a device is created, modify the device settings as needed.
    //--------------------------------------------------------------------------------------
    bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
    {
        
    // If video card does not support hardware vertex processing, then uses sofaware vertex processing.
        if((pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0)
            pDeviceSettings
    ->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

        
    static bool is_first_time = true;

        
    if(is_first_time)
        {
            is_first_time 
    = false;

            
    // if using reference device, then pop a warning message box.
            if(pDeviceSettings->DeviceType == D3DDEVTYPE_REF)
                DXUTDisplaySwitchingToREFWarning();
        }

        
    return true;
    }


    //--------------------------------------------------------------------------------------
    // Create any D3DPOOL_MANAGED resources here 
    //--------------------------------------------------------------------------------------
    HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, 
                                     
    const D3DSURFACE_DESC* pBackBufferSurfaceDesc, 
                                     
    void* pUserContext )
    {
        HRESULT    hr;

        V_RETURN(g_dlg_resource_manager.OnCreateDevice(pd3dDevice));
        V_RETURN(g_settings_dlg.OnCreateDevice(pd3dDevice));

        D3DXCreateFont(pd3dDevice, 
    180, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
                       DEFAULT_PITCH 
    | FF_DONTCARE, L"Arial"&g_font);

        V_RETURN(D3DXCreateTextureFromFile(pd3dDevice, L
    "texture.jpg"&g_texture));
        
        
    // create vertex buffer and fill data

        sCustomVertex vertices[] 
    =     
        {
            { 
    -1.0f-1.0f,  0.0f,  0xFFFFFFFF},
            { 
    -1.0f,  1.0f,  0.0f,  0xFFFFFFFF},
            {  
    1.0f-1.0f,  0.0f,  0xFFFFFFFF},
            {  
    1.0f,  1.0f,  0.0f,  0xFFFFFFFF}
        };

        pd3dDevice
    ->CreateVertexBuffer(sizeof(vertices), 0, D3DFVF_CUSTOM_VERTEX, D3DPOOL_MANAGED, &g_vertex_buffer, NULL);

        
    void* ptr;
        g_vertex_buffer
    ->Lock(0sizeof(vertices), (void**)&ptr, 0);
        memcpy(ptr, vertices, 
    sizeof(vertices));
        g_vertex_buffer
    ->Unlock();

        
    return S_OK;
    }


    //--------------------------------------------------------------------------------------
    // Create any D3DPOOL_DEFAULT resources here 
    //--------------------------------------------------------------------------------------
    HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                    
    const D3DSURFACE_DESC* pBackBufferSurfaceDesc, 
                                    
    void* pUserContext )
    {
        HRESULT hr;

        V_RETURN(g_dlg_resource_manager.OnResetDevice());
        V_RETURN(g_settings_dlg.OnResetDevice());
        V_RETURN(g_font
    ->OnResetDevice());
        V_RETURN(D3DXCreateSprite(pd3dDevice, 
    &g_text_sprite));

        
    // set dialog position and size

        g_button_dlg.SetLocation(pBackBufferSurfaceDesc
    ->Width - 1700);
        g_button_dlg.SetSize(
    170170);

        
    // setup world matrix
        D3DXMATRIX mat_world;
        D3DXMatrixIdentity(
    &mat_world);
        pd3dDevice
    ->SetTransform(D3DTS_WORLD, &mat_world);

        
    // setup view matrix

        D3DXMATRIX mat_view;
        D3DXVECTOR3 eye(
    0.0f0.0f-3.0f);
        D3DXVECTOR3  at(
    0.0f0.0f,  0.0f);
        D3DXVECTOR3  up(
    0.0f1.0f,  0.0f);

        D3DXMatrixLookAtLH(
    &mat_view, &eye, &at, &up);
        pd3dDevice
    ->SetTransform(D3DTS_VIEW, &mat_view);

        
    // set projection matrix
        D3DXMATRIX mat_proj;
        
    float aspect = (float)pBackBufferSurfaceDesc->Width / pBackBufferSurfaceDesc->Height;
        D3DXMatrixPerspectiveFovLH(
    &mat_proj, D3DX_PI/4, aspect, 1.0f100.0f);
        pd3dDevice
    ->SetTransform(D3DTS_PROJECTION, &mat_proj);

        pd3dDevice
    ->SetRenderState(D3DRS_LIGHTING, FALSE);

        
    // set texture color blend method, disalbe alpha blend.

        pd3dDevice
    ->SetTexture(0, g_texture);    
        pd3dDevice
    ->SetTextureStageState(0, D3DTSS_COLORARG1,        D3DTA_TEXTURE);    
        pd3dDevice
    ->SetTextureStageState(0, D3DTSS_COLORARG2,        D3DTA_DIFFUSE);    
        pd3dDevice
    ->SetTextureStageState(0, D3DTSS_COLOROP,            D3DTOP_MODULATE);    
        pd3dDevice
    ->SetTextureStageState(0, D3DTSS_ALPHAOP,            D3DTOP_DISABLE);

        
    // create texture coordinate using vertex position in camera space 
        pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX,            D3DTSS_TCI_CAMERASPACEPOSITION);    
        pd3dDevice
    ->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS,    D3DTTFF_COUNT2);

        
    // texture coordinate transform

        D3DXMATRIX mat_texture, mat_scale, mat_trans;

        D3DXMatrixIdentity(
    &mat_texture);
        D3DXMatrixScaling(
    &mat_scale, 0.5f-0.5f1.0f);
        D3DXMatrixTranslation(
    &mat_trans, 0.5f0.5f1.0f);

        mat_texture 
    = mat_texture * mat_scale * mat_trans;
        pd3dDevice
    ->SetTransform(D3DTS_TEXTURE0, &mat_texture);

        
    return S_OK;
    }

    //--------------------------------------------------------------------------------------
    // Release resources created in the OnResetDevice callback here 
    //--------------------------------------------------------------------------------------
    void CALLBACK OnLostDevice( void* pUserContext )
    {
        g_dlg_resource_manager.OnLostDevice();
        g_settings_dlg.OnLostDevice();
        g_font
    ->OnLostDevice();

        release_com(g_text_sprite);
    }


    //--------------------------------------------------------------------------------------
    // Release resources created in the OnCreateDevice callback here
    //--------------------------------------------------------------------------------------
    void CALLBACK OnDestroyDevice( void* pUserContext )
    {
        g_dlg_resource_manager.OnDestroyDevice();
        g_settings_dlg.OnDestroyDevice();    

        release_com(g_font);
        release_com(g_vertex_buffer);
        release_com(g_texture);
    }

    //--------------------------------------------------------------------------------------
    // Handle updates to the scene
    //--------------------------------------------------------------------------------------
    void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
    {
    }

    //--------------------------------------------------------------------------------------
    // Render the helper information
    //--------------------------------------------------------------------------------------
    void RenderText()
    {
        CDXUTTextHelper text_helper(g_font, g_text_sprite, 
    20);
        
        text_helper.Begin();

        
    // show frame and device states
        text_helper.SetInsertionPos(55);
        text_helper.SetForegroundColor(FONT_COLOR);
        text_helper.DrawTextLine( DXUTGetFrameStats(
    true) );
        text_helper.DrawTextLine( DXUTGetDeviceStats() );

        
    // show other simple information
        
    //text_helper.SetForegroundColor( D3DXCOLOR(0.2f, 0.5f, 0.8f, 1.0f) );
        
    //text_helper.DrawTextLine(L"Texture Coordinate Transform");

        
    // show helper information
        
        
    const D3DSURFACE_DESC* surface_desc = DXUTGetBackBufferSurfaceDesc();

        
    if(g_show_help)
        {
            text_helper.SetInsertionPos(
    10, surface_desc->Height - 18 * 5);
            text_helper.SetForegroundColor(FONT_COLOR);
            text_helper.DrawTextLine(L
    "Controls (F1 to hide):");
            
            text_helper.SetInsertionPos(
    40, surface_desc->Height - 18 * 4);
            text_helper.DrawTextLine(L
    "Quit: ESC");
        }
        
    else
        {
            text_helper.SetInsertionPos(
    10, surface_desc->Height - 15 * 4);
            text_helper.SetForegroundColor( D3DXCOLOR(
    1.0f1.0f1.0f1.0f) );
            text_helper.DrawTextLine(L
    "Press F1 for help");
        }

        text_helper.End();
    }

    //--------------------------------------------------------------------------------------
    // Render the scene 
    //--------------------------------------------------------------------------------------
    void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
    {
        HRESULT hr;

        
    if(g_settings_dlg.IsActive())
        {
            g_settings_dlg.OnRender(fElapsedTime);
            
    return;
        }

        
    // Clear the render target and the zbuffer 
        V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0000), 1.0f0) );

        
    // Render the scene
        if( SUCCEEDED( pd3dDevice->BeginScene() ) )
        {
            pd3dDevice
    ->SetStreamSource(0, g_vertex_buffer, 0sizeof(sCustomVertex));
            pd3dDevice
    ->SetFVF(D3DFVF_CUSTOM_VERTEX);
            pd3dDevice
    ->DrawPrimitive(D3DPT_TRIANGLESTRIP, 02);

            RenderText();

            V(g_button_dlg.OnRender(fElapsedTime));

            V( pd3dDevice
    ->EndScene() );
        }
    }


    //--------------------------------------------------------------------------------------
    // Handle messages to the application 
    //--------------------------------------------------------------------------------------
    LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                              
    bool* pbNoFurtherProcessing, void* pUserContext )
    {
        
    *pbNoFurtherProcessing = g_dlg_resource_manager.MsgProc(hWnd, uMsg, wParam, lParam);
        
    if(*pbNoFurtherProcessing)
            
    return 0;

        
    if(g_settings_dlg.IsActive())
        {
            g_settings_dlg.MsgProc(hWnd, uMsg, wParam, lParam);
            
    return 0;
        }

        
    *pbNoFurtherProcessing = g_button_dlg.MsgProc(hWnd, uMsg, wParam, lParam);
        
    if(*pbNoFurtherProcessing)
            
    return 0;

        
    return 0;
    }


    //--------------------------------------------------------------------------------------
    // Handle keybaord event
    //--------------------------------------------------------------------------------------
    void CALLBACK OnKeyboardProc(UINT charater, bool is_key_down, bool is_alt_down, void* user_context)
    {
        
    if(is_key_down)
        {
            
    switch(charater)
            {
            
    case VK_F1:
                g_show_help 
    = !g_show_help;
                
    break;
            }
        }
    }

    //--------------------------------------------------------------------------------------
    // Handle events for controls
    //--------------------------------------------------------------------------------------
    void CALLBACK OnGUIEvent(UINT eventint control_id, CDXUTControl* control, void* user_context)
    {
        
    switch(control_id)
        {
        
    case IDC_TOGGLE_FULLSCREEN:
            DXUTToggleFullScreen();
            
    break;

        
    case IDC_TOGGLE_REF:
            DXUTToggleREF();
            
    break;

        
    case IDC_CHANGE_DEVICE:
            g_settings_dlg.SetActive(
    true);
            
    break;
        }
    }

    //--------------------------------------------------------------------------------------
    // Initialize dialogs
    //--------------------------------------------------------------------------------------
    void InitDialogs()
    {
        g_settings_dlg.Init(
    &g_dlg_resource_manager);
        g_button_dlg.Init(
    &g_dlg_resource_manager);

        g_button_dlg.SetCallback(OnGUIEvent);

        
    int x = 35, y = 10, width = 125, height = 22;

        g_button_dlg.AddButton(IDC_TOGGLE_FULLSCREEN, L
    "Toggle full screen", x, y,         width, height);
        g_button_dlg.AddButton(IDC_TOGGLE_REF,          L
    "Toggle REF (F3)",     x, y += 24, width, height);
        g_button_dlg.AddButton(IDC_CHANGE_DEVICE,      L
    "Change device (F2)", x, y += 24, width, height, VK_F2);    
    }

    //--------------------------------------------------------------------------------------
    // Initialize everything and go into a render loop
    //--------------------------------------------------------------------------------------
    INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
    {
        
    // Enable run-time memory check for debug builds.
    #if defined(DEBUG) | defined(_DEBUG)
        _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF 
    | _CRTDBG_LEAK_CHECK_DF );
    #endif

        
    // Set the callback functions
        DXUTSetCallbackDeviceCreated( OnCreateDevice );
        DXUTSetCallbackDeviceReset( OnResetDevice );
        DXUTSetCallbackDeviceLost( OnLostDevice );
        DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
        DXUTSetCallbackMsgProc( MsgProc );
        DXUTSetCallbackFrameRender( OnFrameRender );
        DXUTSetCallbackFrameMove( OnFrameMove );
        DXUTSetCallbackKeyboard(OnKeyboardProc);
       
        
    // TODO: Perform any application-level initialization here
        InitDialogs();

        
    // Initialize DXUT and create the desired Win32 window and Direct3D device for the application
        DXUTInit( truetruetrue ); // Parse the command line, handle the default hotkeys, and show msgboxes
        DXUTSetCursorSettings( truetrue ); // Show the cursor and clip it when in full screen
        DXUTCreateWindow( L"Texture Coordinate Transform" );
        DXUTCreateDevice( D3DADAPTER_DEFAULT, 
    true640480, IsDeviceAcceptable, ModifyDeviceSettings );

        
    // Start the render loop
        DXUTMainLoop();

        
    // TODO: Perform any application-level cleanup here

        
    return DXUTGetExitCode();
    }
  • 相关阅读:
    标签的讲解
    属性分类
    LeetCode 003. 无重复字符的最长子串 双指针
    Leetcode 136. 只出现一次的数字 异或性质
    Leetcode 231. 2的幂 数学
    LeetCode 21. 合并两个有序链表
    象棋博弈资源
    acwing 343. 排序 topsort floyd 传播闭包
    Leetcode 945 使数组唯一的最小增量 贪心
    Leetcode 785 判断二分图 BFS 二分染色
  • 原文地址:https://www.cnblogs.com/lancidie/p/1870028.html
Copyright © 2011-2022 走看看